Subject: Re: bug#34516: Multi-monitor frame sets

From: Juri Linkov <[email-masked]>
Date: Sat, 23 Feb 2019 22:48:25 +0200

> You should always use the workarea values for displaying emacs frames.

Ok, this patch uses the workarea instead:

diff --git a/lisp/frame.el b/lisp/frame.el
index dc81302939..648944952f 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -644,9 +644,43 @@ window-system-for-display
 (defun make-frame-on-display (display &optional parameters)
   "Make a frame on display DISPLAY.
 The optional argument PARAMETERS specifies additional frame parameters."
-  (interactive "sMake frame on display: ")
+  (interactive (list (completing-read
+                      (format "Make frame on display: ")
+                      (delete-dups
+                       (mapcar (lambda (frame)
+                                 (frame-parameter frame 'display))
+                               (frame-list))))))
   (make-frame (cons (cons 'display display) parameters)))
 
+(defun make-frame-on-monitor (monitor &optional display parameters)
+  "Make a frame on monitor MONITOR.
+The optional argument DISPLAY can be a display name, and the optional
+argument PARAMETERS specifies additional frame parameters."
+  (interactive (list (completing-read
+                      (format "Make frame on monitor: ")
+                      (mapcar (lambda (a)
+                                (cdr (assq 'name a)))
+                              (display-monitor-attributes-list)))))
+  (let* ((monitor-geometry
+          (car (delq nil (mapcar (lambda (a)
+                                   (when (equal (cdr (assq 'name a)) monitor)
+                                     (cdr (assq 'workarea a))))
+                                 (display-monitor-attributes-list display)))))
+         (frame-geometry
+          (when monitor-geometry
+            (x-parse-geometry (format "%dx%d+%d+%d"
+                                      (nth 2 monitor-geometry)
+                                      (nth 3 monitor-geometry)
+                                      (nth 0 monitor-geometry)
+                                      (nth 1 monitor-geometry)))))
+         (frame-geometry-in-pixels
+          (when frame-geometry
+            `((top . ,(cdr (assq 'top frame-geometry)))
+              (left . ,(cdr (assq 'left frame-geometry)))
+              (height . (text-pixels . ,(cdr (assq 'height frame-geometry))))
+              (width . (text-pixels . ,(cdr (assq 'width frame-geometry))))))))
+    (make-frame (append frame-geometry-in-pixels parameters))))
+
 (declare-function x-close-connection "xfns.c" (terminal))
 
 (defun close-display-connection (display)