;;; 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.
;; 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)))
;; 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
(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)
(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
(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))
(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)