9

I have a multi-monitor setup, in which a specific monitor has a dedicated Emacs frame in full screen which shows compiler errors (from Compilation Mode or SBT Mode). I'd like to preserve the setup automatically, even if I click on an error location in that frame. Specifically, if the dedicated “error” frame is selected, display-buffer should show an buffer in the “main frame” where I do my editing.

The “main frame” is the one on my primary monitor, which stands in the center of my desk. It's also the “official” primary monitor as per global display settings in the OS X system configuration.

To make sure that buffers are shown at the right place, I need to find out whether a certain frame is on the primary display or not. Is that possible, and if so, how?

A platform independent approach would be great, but if that is not possible, a solution for OS X is also fine.

  • One idea would be to get the frame coordinates and determine if those points fall within the boundaries of the main frame in the center of the the desk. I opened a suggestion a year or two ago to permit Emacs to accept applescript, but there was never any response -- by enabling applescripting in the plist of the Emacs.app bundle, it is possible to get desktop frame coordinates using the applescript. In terms of targeting a specific frame with `dispay-buffer`, here is an example: http://stackoverflow.com/questions/18346785/how-to-intercept-a-file-before-it-opens-and-decide-which-frame – lawlist Aug 10 '15 at 07:40
  • Here is a link to the feature request, which contains an example of how to enable applescripting: https://lists.gnu.org/archive/html/bug-gnu-emacs/2014-08/msg00487.html Here is a related snippet to get bounds with an applescript: `(let ((script (concat "tell front window of application \"Emacs\"\n" "get bounds\n" "end tell"))) (start-process "maximize" nil "osascript" "-e" script) (set-process-filter (get-process "maximize") (lambda (proc string) (message (propertize (format "Bounds of Frame: %s" (car (split-string string "\n"))) 'face 'font-lock-warning-face)))))` – lawlist Aug 10 '15 at 07:47
  • I hope that there's an easier way to do that. I'm inclined to believe that this functionality is present in Emacs itself, because Desktop Save Mode restores frames on their original displays… –  Aug 10 '15 at 12:38
  • A brief look at `desktop.el` reveals that it uses `frameset-save` to record the frame-related data -- e.g., `(frameset-save (frame-list))`. The cons cells of `(left . ...)` and `(top . ...)` may be helpful to determine if a frame falls within the boundaries of the primary display. My guess is that `desktop.el` doesn't identify particular displays *per se*, but instead creates new frames (based upon the stored data) when Emacs restarts -- similar to setting the `frame-parameters` (top/left controls the x/y coordinates of the upper left-hand corner of each frame). – lawlist Aug 10 '15 at 18:25

2 Answers2

9

Function display-monitor-attributes-list gives you a list of the physical monitor attributes. This includes the display name (e.g., ".DISPLAY1"), which might be all you need. Dunno.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • Awesome, thank you very much! I didn't know that this function existed. I'll try and see how it works out for my purpose. –  Dec 04 '15 at 18:36
  • It's fairly new - Emacs 24, I think. I don't have more than one monitor, so I haven't used it, but I use it in some of my code (with the help/suggestions of users). – Drew Dec 04 '15 at 18:47
  • 1
    Doesn't have `name` for me on Mac. :/ – Keith Pinson Oct 23 '20 at 16:28
  • 1
    @KeithPinson: Hm. Dunno whether that's a bug or not. Maybe report it, to see what Emacs developers think? `M-x report-emacs-bug` – Drew Oct 23 '20 at 16:50
1

The following works for me on OS X:

(defun frame-on-primary-monitor-p (frame)
  (let* ((monitors (display-monitor-attributes-list))
         (primary-monitor (car monitors))
         (frame-monitor (frame-monitor-attributes frame)))
    (equal primary-monitor frame-monitor)))

For example, the following determines whether the active frame is on the primary monitor:

(frame-on-primary-monitor-p (selected-frame))