X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/025875980c7fbde1d555bff245053241951e6909..18c26d81cde21b841a8f5f81b81118e5f8c6b07d:/lisp/frame.el diff --git a/lisp/frame.el b/lisp/frame.el index 4bf885b27b..a37d118955 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -655,9 +655,8 @@ the new frame according to its own rules." (error "Don't know how to create a frame on window system %s" w)) (unless (get w 'window-system-initialized) - (unless x-display-name - (setq x-display-name display)) - (funcall (cdr (assq w window-system-initialization-alist))) + (funcall (cdr (assq w window-system-initialization-alist)) display) + (setq x-display-name display) (put w 'window-system-initialized t)) ;; Add parameters from `window-system-default-frame-alist'. @@ -1257,6 +1256,23 @@ bars (top, bottom, or nil)." (unless (memq vert '(left right nil)) (setq vert default-frame-scroll-bars)) (cons vert hor))) + +(defun frame-monitor-attributes (&optional frame) + "Return the attributes of the physical monitor dominating FRAME. +If FRAME is omitted, describe the currently selected frame. + +A frame is dominated by a physical monitor when either the +largest area of the frame resides in the monitor, or the monitor +is the closest to the frame if the frame does not intersect any +physical monitors. + +See `display-monitor-attributes-list' for the list of attribute +keys and their meanings." + (or frame (setq frame (selected-frame))) + (cl-loop for attributes in (display-monitor-attributes-list frame) + for frames = (cdr (assq 'frames attributes)) + if (memq frame frames) return attributes)) + ;;;; Frame/display capabilities. (defun selected-terminal () @@ -1349,7 +1365,11 @@ frame's display)." (defun display-pixel-height (&optional display) "Return the height of DISPLAY's screen in pixels. -For character terminals, each character counts as a single pixel." +For character terminals, each character counts as a single pixel. +For graphical terminals, note that on \"multi-monitor\" setups this +refers to the pixel height for all physical monitors associated +with DISPLAY. To get information for each physical monitor, use +`display-monitor-attributes-list'." (let ((frame-type (framep-on-display display))) (cond ((memq frame-type '(x w32 ns)) @@ -1361,7 +1381,11 @@ For character terminals, each character counts as a single pixel." (defun display-pixel-width (&optional display) "Return the width of DISPLAY's screen in pixels. -For character terminals, each character counts as a single pixel." +For character terminals, each character counts as a single pixel. +For graphical terminals, note that on \"multi-monitor\" setups this +refers to the pixel width for all physical monitors associated +with DISPLAY. To get information for each physical monitor, use +`display-monitor-attributes-list'." (let ((frame-type (framep-on-display display))) (cond ((memq frame-type '(x w32 ns)) @@ -1392,7 +1416,11 @@ displays not explicitly specified." (defun display-mm-height (&optional display) "Return the height of DISPLAY's screen in millimeters. System values can be overridden by `display-mm-dimensions-alist'. -If the information is unavailable, value is nil." +If the information is unavailable, value is nil. +For graphical terminals, note that on \"multi-monitor\" setups this +refers to the height in millimeters for all physical monitors +associated with DISPLAY. To get information for each physical +monitor, use `display-monitor-attributes-list'." (and (memq (framep-on-display display) '(x w32 ns)) (or (cddr (assoc (or display (frame-parameter nil 'display)) display-mm-dimensions-alist)) @@ -1404,7 +1432,11 @@ If the information is unavailable, value is nil." (defun display-mm-width (&optional display) "Return the width of DISPLAY's screen in millimeters. System values can be overridden by `display-mm-dimensions-alist'. -If the information is unavailable, value is nil." +If the information is unavailable, value is nil. +For graphical terminals, note that on \"multi-monitor\" setups this +refers to the width in millimeters for all physical monitors +associated with DISPLAY. To get information for each physical +monitor, use `display-monitor-attributes-list'." (and (memq (framep-on-display display) '(x w32 ns)) (or (cadr (assoc (or display (frame-parameter nil 'display)) display-mm-dimensions-alist)) @@ -1477,6 +1509,58 @@ The value is one of the symbols `static-gray', `gray-scale', (t 'static-gray)))) +(declare-function x-display-monitor-attributes-list "xfns.c" + (&optional terminal)) +(declare-function w32-display-monitor-attributes-list "w32fns.c" + (&optional display)) +(declare-function ns-display-monitor-attributes-list "nsfns.m" + (&optional terminal)) + +(defun display-monitor-attributes-list (&optional display) + "Return a list of physical monitor attributes on DISPLAY. +Each element of the list represents the attributes of each +physical monitor. The first element corresponds to the primary +monitor. + +Attributes for a physical monitor is represented as an alist of +attribute keys and values as follows: + + geometry -- Position and size in pixels in the form of + (X Y WIDTH HEIGHT) + workarea -- Position and size of the workarea in pixels in the + form of (X Y WIDTH HEIGHT) + mm-size -- Width and height in millimeters in the form of + (WIDTH HEIGHT) + frames -- List of frames dominated by the physical monitor + name (*) -- Name of the physical monitor as a string + +where X, Y, WIDTH, and HEIGHT are integers. Keys labeled +with (*) are optional. + +A frame is dominated by a physical monitor when either the +largest area of the frame resides in the monitor, or the monitor +is the closest to the frame if the frame does not intersect any +physical monitors. Every non-tip frame (including invisible one) +in a graphical display is dominated by exactly one physical +monitor at a time, though it can span multiple (or no) physical +monitors." + (let ((frame-type (framep-on-display display))) + (cond + ((eq frame-type 'x) + (x-display-monitor-attributes-list display)) + ((eq frame-type 'w32) + (w32-display-monitor-attributes-list display)) + ((eq frame-type 'ns) + (ns-display-monitor-attributes-list display)) + (t + (let ((geometry (list 0 0 (display-pixel-width display) + (display-pixel-height display)))) + `(((geometry . ,geometry) + (workarea . ,geometry) + (mm-size . (,(display-mm-width display) + ,(display-mm-height display))) + (frames . ,(frames-on-display-list display))))))))) + ;;;; Frame geometry values @@ -1587,6 +1671,16 @@ left untouched. FRAME nil or omitted means use the selected frame." :type 'number :group 'cursor) +(defcustom blink-cursor-blinks 10 + "How many times to blink before using a solid cursor on NS and X. +Use 0 or negative value to blink forever." + :version "24.4" + :type 'integer + :group 'cursor) + +(defvar blink-cursor-blinks-done 1 + "Number of blinks done since we started blinking on NS and X") + (defvar blink-cursor-idle-timer nil "Timer started after `blink-cursor-delay' seconds of Emacs idle time. The function `blink-cursor-start' is called when the timer fires.") @@ -1604,6 +1698,7 @@ command starts, by installing a pre-command hook." (when (null blink-cursor-timer) ;; Set up the timer first, so that if this signals an error, ;; blink-cursor-end is not added to pre-command-hook. + (setq blink-cursor-blinks-done 1) (setq blink-cursor-timer (run-with-timer blink-cursor-interval blink-cursor-interval 'blink-cursor-timer-function)) @@ -1612,7 +1707,15 @@ command starts, by installing a pre-command hook." (defun blink-cursor-timer-function () "Timer function of timer `blink-cursor-timer'." - (internal-show-cursor nil (not (internal-show-cursor-p)))) + (internal-show-cursor nil (not (internal-show-cursor-p))) + ;; Each blink is two calls to this function. + (when (memq window-system '(x ns)) + (setq blink-cursor-blinks-done (1+ blink-cursor-blinks-done)) + (when (and (> blink-cursor-blinks 0) + (<= (* 2 blink-cursor-blinks) blink-cursor-blinks-done)) + (blink-cursor-suspend) + (add-hook 'post-command-hook 'blink-cursor-check)))) + (defun blink-cursor-end () "Stop cursor blinking. @@ -1625,6 +1728,29 @@ itself as a pre-command hook." (cancel-timer blink-cursor-timer) (setq blink-cursor-timer nil))) +(defun blink-cursor-suspend () + "Suspend cursor blinking on NS and X. +This is called when no frame has focus and timers can be suspended. +Timers are restarted by `blink-cursor-check', which is called when a +frame receives focus." + (when (memq window-system '(x ns)) + (blink-cursor-end) + (when blink-cursor-idle-timer + (cancel-timer blink-cursor-idle-timer) + (setq blink-cursor-idle-timer nil)))) + +(defun blink-cursor-check () + "Check if cursot blinking shall be restarted. +This is done when a frame gets focus. Blink timers may be stopped by +`blink-cursor-suspend'." + (when (and blink-cursor-mode + (not blink-cursor-idle-timer)) + (remove-hook 'post-command-hook 'blink-cursor-check) + (setq blink-cursor-idle-timer + (run-with-idle-timer blink-cursor-delay + blink-cursor-delay + 'blink-cursor-start)))) + (define-obsolete-variable-alias 'blink-cursor 'blink-cursor-mode "22.1") (define-minor-mode blink-cursor-mode