;;; frame.el --- multi-frame management independent of window systems -*- lexical-binding:t -*-
-;; Copyright (C) 1993-1994, 1996-1997, 2000-2015 Free Software
+;; Copyright (C) 1993-1994, 1996-1997, 2000-2016 Free Software
;; Foundation, Inc.
;; Maintainer: emacs-devel@gnu.org
function to this method, which should take an alist of parameters
as its argument.")
-(cl-defmethod frame-creation-function (params
- &context (window-system (eql nil)))
+(cl-generic-define-context-rewriter window-system (value)
+ ;; If `value' is a `consp', it's probably an old-style specializer,
+ ;; so just use it, and anyway `eql' isn't very useful on cons cells.
+ `(window-system ,(if (consp value) value `(eql ,value))))
+
+(cl-defmethod frame-creation-function (params &context (window-system nil))
;; It's tempting to get rid of tty-create-frame-with-faces and turn it into
;; this method (i.e. move this method to faces.el), but faces.el is loaded
;; much earlier from loadup.el (before cl-generic and even before
You can set this in your init file; for example,
(setq initial-frame-alist
- '((top . 1) (left . 1) (width . 80) (height . 55)))
+ \\='((top . 1) (left . 1) (width . 80) (height . 55)))
Parameters specified here supersede the values given in
`default-frame-alist'.
You can set this in your init file; for example,
(setq minibuffer-frame-alist
- '((top . 1) (left . 1) (width . 80) (height . 2)))
+ \\='((top . 1) (left . 1) (width . 80) (height . 2)))
It is not necessary to include (minibuffer . only); that is
appended when the minibuffer frame is created."
(cons (1- (car frame-size-history))
(cons
(list frame-initial-frame
- "frame-notice-user-settings"
+ "FRAME-NOTICE-USER"
nil newparms)
(cdr frame-size-history)))))
(when (numberp (car frame-size-history))
(setq frame-size-history
(cons (1- (car frame-size-history))
- (cons (list frame "make-frame")
+ (cons (list frame "MAKE-FRAME")
(cdr frame-size-history)))))
;; We can run `window-configuration-change-hook' for this frame now.
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))."
+e.g. (mapc \\='frame-set-background-mode (frame-list))."
:group 'faces
:set #'(lambda (var value)
(set-default var value)
(setq vertical default-frame-scroll-bars))
(cons vertical (and horizontal 'bottom))))
+(declare-function x-frame-geometry "xfns.c" (&optional frame))
+(declare-function w32-frame-geometry "w32fns.c" (&optional frame))
+(declare-function ns-frame-geometry "nsfns.m" (&optional frame))
+
+(defun frame-geometry (&optional frame)
+ "Return geometric attributes of FRAME.
+FRAME must be a live frame and defaults to the selected one. The return
+value is an association list of the attributes listed below. All height
+and width values are in pixels.
+
+`outer-position' is a cons of the outer left and top edges of FRAME
+ relative to the origin - the position (0, 0) - of FRAME's display.
+
+`outer-size' is a cons of the outer width and height of FRAME. The
+ outer size includes the title bar and the external borders as well as
+ any menu and/or tool bar of frame.
+
+`external-border-size' is a cons of the horizontal and vertical width of
+ FRAME's external borders as supplied by the window manager.
+
+`title-bar-size' is a cons of the width and height of the title bar of
+ FRAME as supplied by the window manager. If both of them are zero,
+ FRAME has no title bar. If only the width is zero, Emacs was not
+ able to retrieve the width information.
+
+`menu-bar-external', if non-nil, means the menu bar is external (never
+ included in the inner edges of FRAME).
+
+`menu-bar-size' is a cons of the width and height of the menu bar of
+ FRAME.
+
+`tool-bar-external', if non-nil, means the tool bar is external (never
+ included in the inner edges of FRAME).
+
+`tool-bar-position' tells on which side the tool bar on FRAME is and can
+ be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
+ has no tool bar.
+
+`tool-bar-size' is a cons of the width and height of the tool bar of
+ FRAME.
+
+`internal-border-width' is the width of the internal border of
+ FRAME."
+ (let* ((frame (window-normalize-frame frame))
+ (frame-type (framep-on-display frame)))
+ (cond
+ ((eq frame-type 'x)
+ (x-frame-geometry frame))
+ ((eq frame-type 'w32)
+ (w32-frame-geometry frame))
+ ((eq frame-type 'ns)
+ (ns-frame-geometry frame))
+ (t
+ (list
+ '(outer-position 0 . 0)
+ (cons 'outer-size (cons (frame-width frame) (frame-height frame)))
+ '(external-border-size 0 . 0)
+ '(title-bar-size 0 . 0)
+ '(menu-bar-external . nil)
+ (let ((menu-bar-lines (frame-parameter frame 'menu-bar-lines)))
+ (cons 'menu-bar-size
+ (if menu-bar-lines
+ (cons (frame-width frame) 1)
+ 1 0)))
+ '(tool-bar-external . nil)
+ '(tool-bar-position . nil)
+ '(tool-bar-size 0 . 0)
+ (cons 'internal-border-width
+ (frame-parameter frame 'internal-border-width)))))))
+
+(defun frame--size-history (&optional frame)
+ "Print history of resize operations for FRAME.
+Print prettified version of `frame-size-history' into a buffer
+called *frame-size-history*. Optional argument FRAME denotes the
+frame whose history will be printed. FRAME defaults to the
+selected frame."
+ (let ((history (reverse frame-size-history))
+ entry)
+ (setq frame (window-normalize-frame frame))
+ (with-current-buffer (get-buffer-create "*frame-size-history*")
+ (erase-buffer)
+ (insert (format "Frame size history of %s\n" frame))
+ (while (listp (setq entry (pop history)))
+ (when (eq (car entry) frame)
+ (pop entry)
+ (insert (format "%s" (pop entry)))
+ (move-to-column 24 t)
+ (while entry
+ (insert (format " %s" (pop entry))))
+ (insert "\n"))))))
+
+(declare-function x-frame-edges "xfns.c" (&optional frame type))
+(declare-function w32-frame-edges "w32fns.c" (&optional frame type))
+(declare-function ns-frame-edges "nsfns.m" (&optional frame type))
+
+(defun frame-edges (&optional frame type)
+ "Return coordinates of FRAME's edges.
+FRAME must be a live frame and defaults to the selected one. The
+list returned has the form (LEFT TOP RIGHT BOTTOM) where all
+values are in pixels relative to the origin - the position (0, 0)
+- of FRAME's display. For terminal frames all values are
+relative to LEFT and TOP which are both zero.
+
+Optional argument TYPE specifies the type of the edges. TYPE
+`outer-edges' means to return the outer edges of FRAME. TYPE
+`native-edges' (or nil) means to return the native edges of
+FRAME. TYPE `inner-edges' means to return the inner edges of
+FRAME."
+ (let* ((frame (window-normalize-frame frame))
+ (frame-type (framep-on-display frame)))
+ (cond
+ ((eq frame-type 'x)
+ (x-frame-edges frame type))
+ ((eq frame-type 'w32)
+ (w32-frame-edges frame type))
+ ((eq frame-type 'ns)
+ (ns-frame-edges frame type))
+ (t
+ (list 0 0 (frame-width frame) (frame-height frame))))))
+
+(declare-function w32-mouse-absolute-pixel-position "w32fns.c")
+(declare-function x-mouse-absolute-pixel-position "xfns.c")
+
+(defun mouse-absolute-pixel-position ()
+ "Return absolute position of mouse cursor in pixels.
+The position is returned as a cons cell (X . Y) of the
+coordinates of the mouse cursor position in pixels relative to a
+position (0, 0) of the selected frame's terminal."
+ (let ((frame-type (framep-on-display)))
+ (cond
+ ((eq frame-type 'x)
+ (x-mouse-absolute-pixel-position))
+ ((eq frame-type 'w32)
+ (w32-mouse-absolute-pixel-position))
+ (t
+ (cons 0 0)))))
+
+(declare-function w32-set-mouse-absolute-pixel-position "w32fns.c" (x y))
+(declare-function x-set-mouse-absolute-pixel-position "xfns.c" (x y))
+
+(defun set-mouse-absolute-pixel-position (x y)
+ "Move mouse pointer to absolute pixel position (X, Y).
+The coordinates X and Y are interpreted in pixels relative to a
+position (0, 0) of the selected frame's terminal."
+ (let ((frame-type (framep-on-display)))
+ (cond
+ ((eq frame-type 'x)
+ (x-set-mouse-absolute-pixel-position x y))
+ ((eq frame-type 'w32)
+ (w32-set-mouse-absolute-pixel-position x y)))))
+
(defun frame-monitor-attributes (&optional frame)
"Return the attributes of the physical monitor dominating FRAME.
If FRAME is omitted or nil, describe the currently selected frame.
(make-obsolete-variable
'window-system-version "it does not give useful information." "24.3")
+;; Variables which should trigger redisplay of the current buffer.
+(setq redisplay--variables (make-hash-table :test 'eq :size 10))
+(mapc (lambda (var)
+ (puthash var 1 redisplay--variables))
+ '(line-spacing
+ overline-margin
+ line-prefix
+ wrap-prefix
+ truncate-lines
+ bidi-paragraph-direction
+ bidi-display-reordering))
+
(provide 'frame)
;;; frame.el ends here