]> code.delx.au - gnu-emacs/blobdiff - lisp/frame.el
* completion.el (add-completion-to-head, add-completion): Doc fixes.
[gnu-emacs] / lisp / frame.el
index df3ed16f57432c62b36b23a7ab8873a58b3df7a3..ae0803d6a8db7d906d74f9a96c9fbba9360f49bc 100644 (file)
@@ -1,17 +1,17 @@
 ;;; frame.el --- multi-frame management independent of window systems
 
 ;; Copyright (C) 1993, 1994, 1996, 1997, 2000, 2001, 2002, 2003,
-;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+;;   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: internal
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,9 +19,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
@@ -101,10 +99,12 @@ for pop-up frames."
                       (sexp :tag "Value")))
   :group 'frames)
 
-(setq pop-up-frame-function
-      ;; Using `function' here caused some sort of problem.
-      '(lambda ()
-        (make-frame pop-up-frame-alist)))
+(defcustom pop-up-frame-function
+  (lambda () (make-frame pop-up-frame-alist))
+  "Function to call to handle automatic new frame creation.
+It is called with no arguments and should return a newly created frame."
+  :type '(choice (const nil) (function :tag "function"))
+  :group 'frames)
 
 (defcustom special-display-frame-alist
   '((height . 14) (width . 80) (unsplittable . t))
@@ -210,9 +210,6 @@ Pass it BUFFER as first arg, and (cdr ARGS) gives the rest of the args."
           (not noninteractive)
           (not (eq initial-window-system 'pc)))
       (progn
-       ;; Turn on special-display processing only if there's a window system.
-       (setq special-display-function 'special-display-popup-frame)
-
        ;; If there is no frame with a minibuffer besides the terminal
        ;; frame, then we need to create the opening frame.  Make sure
        ;; it has a minibuffer, but let initial-frame-alist omit the
@@ -248,6 +245,8 @@ Pass it BUFFER as first arg, and (cdr ARGS) gives the rest of the args."
 (defvar frame-notice-user-settings t
   "Non-nil means function `frame-notice-user-settings' wasn't run yet.")
 
+(declare-function tool-bar-mode "tool-bar" (&optional arg))
+
 ;; 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.
@@ -417,6 +416,9 @@ there (in decreasing order of priority)."
             ;; Get rid of `name' unless it was specified explicitly before.
            (or (assq 'name frame-initial-frame-alist)
                (setq parms (delq (assq 'name parms) parms)))
+           ;; An explicit parent-id is a request to XEmbed the frame.
+           (or (assq 'parent-id frame-initial-frame-alist)
+                (setq parms (delq (assq 'parent-id parms) parms)))
 
            (setq parms (append initial-frame-alist
                                window-system-frame-alist
@@ -601,17 +603,26 @@ is not considered (see `next-frame')."
   (select-frame-set-input-focus (selected-frame)))
 
 (declare-function x-initialize-window-system "term/x-win" ())
+(declare-function ns-initialize-window-system "term/ns-win" ())
+(defvar x-display-name)                 ; term/x-win
 
 (defun make-frame-on-display (display &optional parameters)
   "Make a frame on X display DISPLAY.
 The optional second argument PARAMETERS specifies additional frame parameters."
   (interactive "sMake frame on display: ")
-  (or (string-match "\\`[^:]*:[0-9]+\\(\\.[0-9]+\\)?\\'" display)
-      (error "Invalid display, not HOST:SERVER or HOST:SERVER.SCREEN"))
-  (when (and (boundp 'x-initialized) (not x-initialized))
-    (setq x-display-name display)
-    (x-initialize-window-system))
-  (make-frame `((window-system . x) (display . ,display) . ,parameters)))
+  (if (featurep 'ns)
+      (progn
+       (when (and (boundp 'ns-initialized) (not ns-initialized))
+         (setq x-display-name display)
+         (ns-initialize-window-system))
+       (make-frame `((window-system . ns) (display . ,display) . ,parameters)))
+    (progn
+      (unless (string-match "\\`[^:]*:[0-9]+\\(\\.[0-9]+\\)?\\'" display)
+       (error "Invalid display, not HOST:SERVER or HOST:SERVER.SCREEN"))
+      (when (and (boundp 'x-initialized) (not x-initialized))
+       (setq x-display-name display)
+       (x-initialize-window-system))
+      (make-frame `((window-system . x) (display . ,display) . ,parameters)))))
 
 (defun make-frame-on-tty (tty type &optional parameters)
   "Make a frame on terminal device TTY.
@@ -619,12 +630,18 @@ TTY should be the file name of the tty device to use.  TYPE
 should be the terminal type string of TTY, for example \"xterm\"
 or \"vt100\".  The optional third argument PARAMETERS specifies
 additional frame parameters."
-  (interactive "fOpen frame on tty device: \nsTerminal type of %s: ")
+  ;; Use "F" rather than "f", in case the device does not exist, as
+  ;; far as the filesystem is concerned.
+  (interactive "FOpen frame on tty device: \nsTerminal type of %s: ")
   (unless tty
     (error "Invalid terminal device"))
   (unless type
     (error "Invalid terminal type"))
-  (make-frame `((window-system . nil) (tty . ,tty) (tty-type . ,type) . ,parameters)))
+  (if (eq window-system 'pc)
+      (make-frame `((window-system . pc) (tty . ,tty) (tty-type . ,type) . ,parameters))
+    (make-frame `((window-system . nil) (tty . ,tty) (tty-type . ,type) . ,parameters))))
+
+(declare-function x-close-connection "xfns.c" (terminal))
 
 (defun close-display-connection (display)
   "Close the connection to a display, deleting all its associated frames.
@@ -657,9 +674,11 @@ If DISPLAY is nil, that stands for the selected frame's display."
       (x-close-connection display))))
 
 (defun make-frame-command ()
-  "Make a new frame, and select it if the terminal displays only one frame."
+  "Make a new frame, on the same terminal as the selected frame.
+If the terminal is a text-only terminal, this also selects the
+new frame."
   (interactive)
-  (if (and window-system (not (eq window-system 'pc)))
+  (if (display-graphic-p)
       (make-frame)
     (select-frame (make-frame))))
 
@@ -822,15 +841,29 @@ the user during startup."
        (nreverse frame-initial-geometry-arguments))
   (cdr param-list))
 
+(declare-function x-focus-frame "xfns.c" (frame))
+
 (defun select-frame-set-input-focus (frame)
-  "Select FRAME, raise it, and set input focus, if possible."
-    (select-frame frame)
-    (raise-frame frame)
-    ;; Ensure, if possible, that frame gets input focus.
-    (when (memq (window-system frame) '(x mac w32))
-      (x-focus-frame frame))
-    (when focus-follows-mouse
-      (set-mouse-position (selected-frame) (1- (frame-width)) 0)))
+  "Select FRAME, raise it, and set input focus, if possible.
+If `mouse-autoselect-window' is non-nil, also move mouse cursor
+to FRAME's selected window.  Otherwise, if `focus-follows-mouse'
+is non-nil, move mouse cursor to FRAME."
+  (select-frame frame)
+  (raise-frame frame)
+  ;; Ensure, if possible, that FRAME gets input focus.
+  (when (memq (window-system frame) '(x w32 ns))
+    (x-focus-frame frame))
+  ;; Move mouse cursor if necessary.
+  (cond
+   (mouse-autoselect-window
+    (let ((edges (window-inside-edges (frame-selected-window frame))))
+      ;; Move mouse cursor into FRAME's selected window to avoid that
+      ;; Emacs mouse-autoselects another window.
+      (set-mouse-position frame (nth 2 edges) (nth 1 edges))))
+   (focus-follows-mouse
+    ;; Move mouse cursor into FRAME to avoid that another frame gets
+    ;; selected by the window manager.
+    (set-mouse-position frame (1- (frame-width frame)) 0))))
 
 (defun other-frame (arg)
   "Select the ARGth different visible frame on current display, and raise it.
@@ -872,7 +905,7 @@ Calls `suspend-emacs' if invoked from the controlling tty device,
   (interactive)
   (let ((type (framep (selected-frame))))
     (cond
-     ((memq type '(x w32)) (iconify-or-deiconify-frame))
+     ((memq type '(x ns w32)) (iconify-or-deiconify-frame))
      ((eq type t)
       (if (controlling-tty-p)
          (suspend-emacs)
@@ -906,16 +939,9 @@ If there is no frame by that name, signal an error."
        (list input))))
   (let* ((frame-names-alist (make-frame-names-alist))
         (frame (cdr (assoc name frame-names-alist))))
-    (or frame
-       (error "There is no frame named `%s'" name))
-    (make-frame-visible frame)
-    (raise-frame frame)
-    (select-frame frame)
-    ;; Ensure, if possible, that frame gets input focus.
-    (cond ((memq (window-system frame) '(x w32))
-          (x-focus-frame frame)))
-    (when focus-follows-mouse
-      (set-mouse-position frame (1- (frame-width frame)) 0))))
+    (if frame
+       (select-frame-set-input-focus frame)
+      (error "There is no frame named `%s'" name))))
 \f
 ;;;; Frame configurations
 
@@ -991,7 +1017,10 @@ If FRAME is omitted, describe the currently selected frame."
 If FRAME is omitted, describe the currently selected frame."
   (cdr (assq 'width (frame-parameters frame))))
 
-(defalias 'set-default-font 'set-frame-font)
+(declare-function x-list-fonts "xfaces.c"
+                  (pattern &optional face frame maximum width))
+
+(define-obsolete-function-alias 'set-default-font 'set-frame-font "23.1")
 (defun set-frame-font (font-name &optional keep-size)
   "Set the font of the selected frame to FONT-NAME.
 When called interactively, prompt for the name of the font to use.
@@ -1146,8 +1175,8 @@ frame's display)."
      ((eq system-type 'windows-nt)
       (with-no-warnings
        (> w32-num-mouse-buttons 0)))
-     ((memq frame-type '(x mac))
-      t)    ;; We assume X and Mac *always* have a pointing device
+     ((memq frame-type '(x ns))
+      t)    ;; We assume X and NeXTstep *always* have a pointing device
      (t
       (or (and (featurep 'xt-mouse)
               xterm-mouse-mode)
@@ -1162,7 +1191,7 @@ 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 mac)))
+     (memq frame-type '(x w32 pc ns)))
    (display-mouse-p display)))
 
 (defun display-graphic-p (&optional display)
@@ -1172,7 +1201,7 @@ frames and several different fonts at once.  This is true for displays
 that use a window system such as X, and false for text-only terminals.
 DISPLAY can be a display name, a frame, or nil (meaning the selected
 frame's display)."
-  (not (null (memq (framep-on-display display) '(x w32 mac)))))
+  (not (null (memq (framep-on-display display) '(x w32 ns)))))
 
 (defun display-images-p (&optional display)
   "Return non-nil if DISPLAY can display images.
@@ -1200,36 +1229,42 @@ frame's display)."
       ;; the Windows' DOS Box.
       (with-no-warnings
        (not (null dos-windows-version))))
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 ns))
       t)    ;; FIXME?
      (t
       nil))))
 
+(declare-function x-display-screens "xfns.c" (&optional terminal))
+
 (defun display-screens (&optional display)
   "Return the number of screens associated with DISPLAY."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 ns))
       (x-display-screens display))
      (t
       1))))
 
+(declare-function x-display-pixel-height "xfns.c" (&optional terminal))
+
 (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."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 ns))
       (x-display-pixel-height display))
      (t
       (frame-height (if (framep display) display (selected-frame)))))))
 
+(declare-function x-display-pixel-width "xfns.c" (&optional terminal))
+
 (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."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 ns))
       (x-display-pixel-width display))
      (t
       (frame-width (if (framep display) display (selected-frame)))))))
@@ -1252,75 +1287,89 @@ displays not explicitely specified."
                                  (integer :tag "Height")))
   :group 'frames)
 
+(declare-function x-display-mm-height "xfns.c" (&optional terminal))
+
 (defun display-mm-height (&optional display)
   "Return the height of DISPLAY's screen in millimeters.
-System values can be overriden by `display-mm-dimensions-alist'.
+System values can be overridden by `display-mm-dimensions-alist'.
 If the information is unavailable, value is nil."
-  (and (memq (framep-on-display display) '(x w32 mac))
+  (and (memq (framep-on-display display) '(x w32 ns))
        (or (cddr (assoc (or display (frame-parameter nil 'display))
                        display-mm-dimensions-alist))
           (cddr (assoc t display-mm-dimensions-alist))
           (x-display-mm-height display))))
 
+(declare-function x-display-mm-width "xfns.c" (&optional terminal))
+
 (defun display-mm-width (&optional display)
   "Return the width of DISPLAY's screen in millimeters.
-System values can be overriden by `display-mm-dimensions-alist'.
+System values can be overridden by `display-mm-dimensions-alist'.
 If the information is unavailable, value is nil."
-  (and (memq (framep-on-display display) '(x w32 mac))
+  (and (memq (framep-on-display display) '(x w32 ns))
        (or (cadr (assoc (or display (frame-parameter nil 'display))
                        display-mm-dimensions-alist))
           (cadr (assoc t display-mm-dimensions-alist))
           (x-display-mm-width display))))
 
+(declare-function x-display-backing-store "xfns.c" (&optional terminal))
+
 (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."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 ns))
       (x-display-backing-store display))
      (t
       'not-useful))))
 
+(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."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 ns))
       (x-display-save-under display))
      (t
       'not-useful))))
 
+(declare-function x-display-planes "xfns.c" (&optional terminal))
+
 (defun display-planes (&optional display)
   "Return the number of planes supported by DISPLAY."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 ns))
       (x-display-planes display))
      ((eq frame-type 'pc)
       4)
      (t
       (truncate (log (length (tty-color-alist)) 2))))))
 
+(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."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 ns))
       (x-display-color-cells display))
      ((eq frame-type 'pc)
       16)
      (t
       (tty-display-color-cells display)))))
 
+(declare-function x-display-visual-class "xfns.c" (&optional terminal))
+
 (defun display-visual-class (&optional display)
   "Returns 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'."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 ns))
       (x-display-visual-class display))
      ((and (memq frame-type '(pc t))
           (tty-display-color-p display))
@@ -1329,9 +1378,71 @@ The value is one of the symbols `static-gray', `gray-scale',
       'static-gray))))
 
 \f
+;;;; Frame geometry values
+
+(defun frame-geom-value-cons (type value &optional frame)
+  "Return equivalent geometry value for FRAME as a cons with car `+'.
+A geometry value equivalent to VALUE for FRAME is returned,
+where the value is a cons with car `+', not numeric.
+TYPE is the car of the original geometry spec (TYPE . VALUE).
+   It is `top' or `left', depending on which edge VALUE is related to.
+VALUE is the cdr of a frame geometry spec: (left/top . VALUE).
+If VALUE is a number, then it is converted to a cons value, perhaps
+   relative to the opposite frame edge from that in the original spec.
+FRAME defaults to the selected frame.
+
+Examples (measures in pixels) -
+ Assuming display height/width=1024, frame height/width=600:
+ 300 inside display edge:                   300  => (+  300)
+                                        (+  300) => (+  300)
+ 300 inside opposite display edge:      (-  300) => (+  124)
+                                           -300  => (+  124)
+ 300 beyond display edge
+  (= 724 inside opposite display edge): (+ -300) => (+ -300)
+ 300 beyond display edge
+  (= 724 inside opposite display edge): (- -300) => (+  724)
+
+In the 3rd, 4th, and 6th examples, the returned value is relative to
+the opposite frame edge from the edge indicated in the input spec."
+  (cond ((and (consp value) (eq '+ (car value))) ; e.g. (+ 300), (+ -300)
+         value)
+        ((natnump value) (list '+ value)) ; e.g. 300 => (+ 300)
+        (t                              ; e.g. -300, (- 300), (- -300)
+         (list '+ (- (if (eq 'left type) ; => (+ 124), (+ 124), (+ 724)
+                         (x-display-pixel-width)
+                       (x-display-pixel-height))
+                     (if (integerp value) (- value) (cadr value))
+                     (if (eq 'left type)
+                         (frame-pixel-width frame)
+                       (frame-pixel-height frame)))))))
+
+(defun frame-geom-spec-cons (spec &optional frame)
+  "Return equivalent geometry spec for FRAME as a cons with car `+'.
+A geometry specification equivalent to SPEC for FRAME is returned,
+where the value is a cons with car `+', not numeric.
+SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE).
+If VALUE is a number, then it is converted to a cons value, perhaps
+   relative to the opposite frame edge from that in the original spec.
+FRAME defaults to the selected frame.
+
+Examples (measures in pixels) -
+ Assuming display height=1024, frame height=600:
+ top 300 below display top:               (top .  300) => (top +  300)
+                                          (top +  300) => (top +  300)
+ bottom 300 above display bottom:         (top -  300) => (top +  124)
+                                          (top . -300) => (top +  124)
+ top 300 above display top
+  (= bottom 724 above display bottom):    (top + -300) => (top + -300)
+ bottom 300 below display bottom
+  (= top 724 below display top):          (top - -300) => (top +  724)
+
+In the 3rd, 4th, and 6th examples, the returned value is relative to
+the opposite frame edge from the edge indicated in the input spec."
+  (cons (car spec) (frame-geom-value-cons (car spec) (cdr spec))))
+\f
 ;;;; Aliases for backward compatibility with Emacs 18.
-(define-obsolete-function-alias 'screen-height 'frame-height) ;before 19.15
-(define-obsolete-function-alias 'screen-width 'frame-width) ;before 19.15
+(define-obsolete-function-alias 'screen-height 'frame-height "19.7")
+(define-obsolete-function-alias 'screen-width 'frame-width "19.7")
 
 (defun set-screen-width (cols &optional pretend)
   "Change the size of the screen to COLS columns.
@@ -1367,8 +1478,8 @@ left untouched.  FRAME nil or omitted means use the selected frame."
       (when (eq (frame-parameter frame 'minibuffer) 'only)
        (delete-frame frame)))))
 
-(make-obsolete 'set-screen-width 'set-frame-width) ;before 19.15
-(make-obsolete 'set-screen-height 'set-frame-height) ;before 19.15
+(make-obsolete 'set-screen-width 'set-frame-width "19.7")
+(make-obsolete 'set-screen-height 'set-frame-height "19.7")
 
 ;; miscellaneous obsolescence declarations
 (define-obsolete-variable-alias 'delete-frame-hook
@@ -1471,7 +1582,7 @@ cursor display.  On a text-only terminal, this is not implemented."
   :init-value (not (or noninteractive
                       no-blinking-cursor
                       (eq system-type 'ms-dos)
-                      (not (memq window-system '(x w32 mac)))))
+                      (not (memq window-system '(x w32)))))
   :initialize 'custom-initialize-safe-default
   :group 'cursor
   :global t