(delete-frame frame t)
;; Gildea@x.org says it is ok to ask questions before terminating.
(save-buffers-kill-emacs))))
+
+(defun handle-focus-in (_event)
+ "Handle a focus-in event.
+Focus-in events are usually bound to this function.
+Focus-in events occur when a frame has focus, but a switch-frame event
+is not generated.
+This function runs the hook `focus-in-hook'."
+ (interactive "e")
+ (run-hooks 'focus-in-hook))
+
+(defun handle-focus-out (_event)
+ "Handle a focus-out event.
+Focus-out events are usually bound to this function.
+Focus-out events occur when no frame has focus.
+This function runs the hook `focus-out-hook'."
+ (interactive "e")
+ (run-hooks 'focus-out-hook))
\f
;;;; Arrangement of frames at startup
(declare-function tool-bar-mode "tool-bar" (&optional arg))
+(defalias 'tool-bar-lines-needed 'tool-bar-height)
+
;; startup.el calls this function after loading the user's init
;; file. Now default-frame-alist and initial-frame-alist contain
;; information to which we must react; do what needs to be done.
t))
;; Create the new frame.
(let (parms new)
+ ;; MS-Windows needs this to avoid inflooping below.
+ (if (eq system-type 'windows-nt)
+ (sit-for 0 t))
;; If the frame isn't visible yet, wait till it is.
;; If the user has to position the window,
;; Emacs doesn't know its real position until
"Return some frame other than the current frame.
Create one if necessary. Note that the minibuffer frame, if separate,
is not considered (see `next-frame')."
- (let ((s (if (equal (next-frame (selected-frame)) (selected-frame))
- (make-frame)
- (next-frame (selected-frame)))))
- s))
+ (if (equal (next-frame) (selected-frame)) (make-frame) (next-frame)))
(defun next-multiframe-window ()
"Select the next window, regardless of which frame it is on."
;; FIXME: Shouldn't we add `font' here as well?
"Parameters `make-frame' copies from the `selected-frame' to the new frame.")
+(defvar x-display-name)
+
(defun make-frame (&optional parameters)
"Return a newly created frame displaying the current buffer.
Optional argument PARAMETERS is an alist of frame parameters for
(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'.
(nreverse frame-initial-geometry-arguments))
(cdr param-list))
-(declare-function x-focus-frame "xfns.c" (frame))
+(declare-function x-focus-frame "frame.c" (frame))
(defun select-frame-set-input-focus (frame &optional norecord)
"Select FRAME, raise it, and set input focus, if possible.
"The brightness of the background.
Set this to the symbol `dark' if your background color is dark,
`light' if your background is light, or nil (automatic by default)
-if you want Emacs to examine the brightness for you. Don't set this
-variable with `setq'; this won't have the expected effect."
+if you want Emacs to examine the brightness for you.
+
+If you change this without using customize, you should use
+`frame-set-background-mode' to update existing frames;
+e.g. (mapc 'frame-set-background-mode (frame-list))."
:group 'faces
:set #'(lambda (var value)
(set-default var value)
(declare-function x-get-resource "frame.c"
(attribute class &optional component subclass))
+;; Only used if window-system is not null.
+(declare-function x-display-grayscale-p "xfns.c" (&optional terminal))
+
(defvar inhibit-frame-set-background-mode nil)
(defun frame-set-background-mode (frame &optional keep-face-specs)
(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))
+
\f
;;;; Frame/display capabilities.
-(defun selected-terminal ()
- "Return the terminal that is now selected."
- (frame-terminal (selected-frame)))
(declare-function msdos-mouse-p "dosfns.c")
xterm-mouse-mode)
;; t-mouse is distributed with the GPM package. It doesn't have
;; a toggle.
- (featurep 't-mouse))))))
+ (featurep 't-mouse)
+ ;; No way to check whether a w32 console has a mouse, assume
+ ;; it always does.
+ (boundp 'w32-use-full-screen-buffer))))))
(defun display-popup-menus-p (&optional display)
"Return non-nil if popup menus are supported on DISPLAY.
DISPLAY can be a display name, a frame, or nil (meaning the selected
frame's display).
Support for popup menus requires that the mouse be available."
- (and
- (let ((frame-type (framep-on-display display)))
- (memq frame-type '(x w32 pc ns)))
- (display-mouse-p display)))
+ (display-mouse-p display))
(defun display-graphic-p (&optional display)
"Return non-nil if DISPLAY is a graphic display.
(declare-function x-display-screens "xfns.c" (&optional terminal))
(defun display-screens (&optional display)
- "Return the number of screens associated with DISPLAY."
+ "Return the number of screens associated with DISPLAY.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
((memq frame-type '(x w32 ns))
(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'.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
((memq frame-type '(x w32 ns))
(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'.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
((memq frame-type '(x w32 ns))
(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'.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(and (memq (framep-on-display display) '(x w32 ns))
(or (cddr (assoc (or display (frame-parameter nil 'display))
display-mm-dimensions-alist))
(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'.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(and (memq (framep-on-display display) '(x w32 ns))
(or (cadr (assoc (or display (frame-parameter nil 'display))
display-mm-dimensions-alist))
(declare-function x-display-backing-store "xfns.c" (&optional terminal))
+;; In NS port, the return value may be `buffered', `retained', or
+;; `non-retained'. See src/nsfns.m.
(defun display-backing-store (&optional display)
"Return the backing store capability of DISPLAY's screen.
The value may be `always', `when-mapped', `not-useful', or nil if
-the question is inapplicable to a certain kind of display."
+the question is inapplicable to a certain kind of display.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
((memq frame-type '(x w32 ns))
(declare-function x-display-save-under "xfns.c" (&optional terminal))
(defun display-save-under (&optional display)
- "Return non-nil if DISPLAY's screen supports the SaveUnder feature."
+ "Return non-nil if DISPLAY's screen supports the SaveUnder feature.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
((memq frame-type '(x w32 ns))
(declare-function x-display-planes "xfns.c" (&optional terminal))
(defun display-planes (&optional display)
- "Return the number of planes supported by DISPLAY."
+ "Return the number of planes supported by DISPLAY.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
((memq frame-type '(x w32 ns))
(declare-function x-display-color-cells "xfns.c" (&optional terminal))
(defun display-color-cells (&optional display)
- "Return the number of color cells supported by DISPLAY."
+ "Return the number of color cells supported by DISPLAY.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
((memq frame-type '(x w32 ns))
(defun display-visual-class (&optional display)
"Return the visual class of DISPLAY.
The value is one of the symbols `static-gray', `gray-scale',
-`static-color', `pseudo-color', `true-color', or `direct-color'."
+`static-color', `pseudo-color', `true-color', or `direct-color'.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
((memq frame-type '(x w32 ns))
(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.
+If DISPLAY is omitted or nil, it defaults to the selected frame's display."
+ (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)))))))))
+
\f
;;;; Frame geometry values
: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.")
(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))
(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.
+ (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.
(cancel-timer blink-cursor-timer)
(setq blink-cursor-timer nil)))
+(defun blink-cursor-suspend ()
+ "Suspend cursor blinking.
+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."
+ (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 cursor 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
(if blink-cursor-idle-timer (cancel-timer blink-cursor-idle-timer))
(setq blink-cursor-idle-timer nil)
(blink-cursor-end)
+ (remove-hook 'focus-in-hook #'blink-cursor-check)
+ (remove-hook 'focus-out-hook #'blink-cursor-suspend)
(when blink-cursor-mode
- ;; Hide the cursor.
- ;;(internal-show-cursor nil nil)
+ (add-hook 'focus-in-hook #'blink-cursor-check)
+ (add-hook 'focus-out-hook #'blink-cursor-suspend)
(setq blink-cursor-idle-timer
(run-with-idle-timer blink-cursor-delay
blink-cursor-delay
- 'blink-cursor-start))))
+ #'blink-cursor-start))))
\f
;; Frame maximization/fullscreen