]> code.delx.au - gnu-emacs/blobdiff - lisp/frame.el
(other-frame): Skip iconified and invisible frames.
[gnu-emacs] / lisp / frame.el
index 6abf81260324234cc5e88bb2d4b472bf63859d45..b915f945b97c21c172154ba79101a799d33e049b 100644 (file)
@@ -81,6 +81,9 @@ These supersede the values given in `default-frame-alist'.")
 ;;; If we create the initial frame, this is it.
 (defvar frame-initial-frame nil)
 
+;; Record the parameters used in frame-initialize to make the initial frame.
+(defvar frame-initial-frame-alist)
+
 ;;; startup.el calls this function before loading the user's init
 ;;; file - if there is no frame with a minibuffer open now, create
 ;;; one to display messages while loading the init file.
@@ -95,6 +98,8 @@ These supersede the values given in `default-frame-alist'.")
        ;; minibuffer spec.
        (or (delq terminal-frame (minibuffer-frame-list))
            (progn
+             (setq frame-initial-frame-alist
+                   (append initial-frame-alist default-frame-alist))
              (setq default-minibuffer-frame
                    (setq frame-initial-frame
                          (new-frame initial-frame-alist)))
@@ -102,18 +107,11 @@ These supersede the values given in `default-frame-alist'.")
              ;; so that we won't reapply them in frame-notice-user-settings.
              ;; It would be wrong to reapply them then,
              ;; because that would override explicit user resizing.
-             ;; Remember that they may occur more than once.
-             (let ((tail initial-frame-alist))
-               (while (consp tail)
-                 (if (and (consp (car tail))
-                          (memq (car (car tail)) '(height width top left)))
-                     (setq initial-frame-alist
-                           (delq tail initial-frame-alist)))))
+             (setq initial-frame-alist
+                   (frame-remove-geometry-params initial-frame-alist))
              ;; Handle `reverse' as a parameter.
              (if (cdr (or (assq 'reverse initial-frame-alist)
-                          (assq 'reverse default-frame-alist)
-                          (cons nil
-                                (x-get-resource "reverseVideo" "ReverseVideo"))))
+                          (assq 'reverse default-frame-alist)))
                  (let ((params (frame-parameters frame-initial-frame)))
                    (modify-frame-parameters
                     frame-initial-frame
@@ -231,13 +229,32 @@ These supersede the values given in `default-frame-alist'.")
              (redirect-frame-focus frame-initial-frame new)
 
              ;; Finally, get rid of the old frame.
-             (delete-frame frame-initial-frame))
+             (delete-frame frame-initial-frame t))
 
          ;; Otherwise, we don't need all that rigamarole; just apply
          ;; the new parameters.
-         (modify-frame-parameters frame-initial-frame
-                                  (append initial-frame-alist
-                                          default-frame-alist))))
+         (let (newparms allparms tail)
+           (setq allparms (append initial-frame-alist
+                                  default-frame-alist))
+           (setq tail allparms)
+           ;; Find just the parms that have changed since we first
+           ;; made this frame.  Those are the ones actually set by
+           ;; the init file.  For those parms whose values we already knew
+           ;; (such as those spec'd by command line options)
+           ;; it is undesirable to specify the parm again
+           ;; once the user has seen the frame and been able to alter it
+           ;; manually.
+           (while tail
+             (let (newval oldval)
+               (setq oldval (cdr (assq (car (car tail))
+                                       frame-initial-frame-alist)))
+               (setq newval (cdr (assq (car (car tail)) allparms)))
+               (or (eq oldval newval)
+                   (setq newparms
+                         (cons (cons (car (car tail)) newval) newparms))))
+             (setq tail (cdr tail)))
+           (modify-frame-parameters frame-initial-frame
+                                    (nreverse newparms)))))
 
     ;; Restore the original buffer.
     (set-buffer old-buffer)
@@ -317,6 +334,41 @@ additional frame parameters that Emacs recognizes for X window frames."
    (function (lambda (frame)
               (eq frame (window-frame (minibuffer-window frame)))))))
 
+(defun frame-remove-geometry-params (param-list)
+  "Return the parameter list PARAM-LIST, but with geometry specs removed.
+This deletes all bindings in PARAM-LIST for `top', `left', `width',
+and `height' parameters.
+Emacs uses this to avoid overriding explicit moves and resizings from
+the user during startup."
+  (setq param-list (cons nil param-list))
+  (let ((tail param-list))
+    (while (consp (cdr tail))
+      (if (and (consp (car (cdr tail)))
+              (memq (car (car (cdr tail))) '(height width top left)))
+         (setcdr tail (cdr (cdr tail)))
+       (setq tail (cdr tail)))))
+  (cdr param-list))
+
+
+(defun other-frame (arg)
+  "Select the ARG'th different visible frame, and raise it.
+All frames are arranged in a cyclic order.
+This command selects the frame ARG steps away in that order.
+A negative ARG moves in the opposite order."
+  (interactive "p")
+  (let ((frame (selected-frame)))
+    (while (> arg 0)
+      (setq frame (next-frame frame))
+      (while (not (eq (frame-visible-p frame) t))
+       (setq frame (next-frame frame)))
+      (setq arg (1- arg)))
+    (while (< arg 0)
+      (setq frame (previous-frame frame))
+      (while (not (eq (frame-visible-p frame) t))
+       (setq frame (previous-frame frame)))
+      (setq arg (1- arg)))
+    (raise-frame frame)
+    (select-frame frame)))
 \f
 ;;;; Frame configurations
 
@@ -350,7 +402,14 @@ configuration, and other parameters set as specified in CONFIGURATION."
               (let ((parameters (assq frame config-alist)))
                 (if parameters
                     (progn
-                      (modify-frame-parameters frame (nth 1 parameters))
+                      (modify-frame-parameters
+                       frame
+                       ;; Since we can't set a frame's minibuffer status, 
+                       ;; we might as well omit the parameter altogether.
+                       (let* ((parms (nth 1 parameters))
+                              (mini (assq 'minibuffer parms)))
+                         (if mini (setq parms (delq mini parms)))
+                         parms))
                       (set-window-configuration (nth 2 parameters)))
                   (setq frames-to-delete (cons frame frames-to-delete))))))
            (frame-list))
@@ -495,6 +554,7 @@ should use `set-frame-width' instead."
 
 (define-key ctl-x-5-map "2" 'new-frame)
 (define-key ctl-x-5-map "0" 'delete-frame)
+(define-key ctl-x-5-map "o" 'other-frame)
 
 (provide 'frame)