Mercurial > emacs
changeset 1863:6f55c76b5789
* frame.el: Clean up initialization code.
(initial-frame-alist): Doc fix.
(minibuffer-frame-alist): New default value, with a reasonable height.
(filtered-frame-list, minibuffer-frame-list): New functions.
(frame-initialize): Use minibuffer-frame-list, instead of writing
it out.
(frame-notice-user-settings): Thoroughly rearranged.
Notice changes to default-frame-alist as well as initial-frame-alist.
Properly handle requests to make the initial frame into a
minibufferless or minibuffer-only frame.
Create a minibuffer-only frame if the initial frame should lack a
minibuffer and there are no other minibuffer frames created by the
user's initialization file.
Fix any frames using the initial frame as a surrogate minibuffer
frame.
Restore the current buffer after creating and deleting all these
frames.
* frame.el (set-default-font, set-frame-background,
set-frame-foreground, set-cursor-color, set-pointer-color,
set-auto-raise, set-auto-lower, set-vertical-bar,
set-horizontal-bar): Give these docstrings.
(set-auto-raise, set-auto-lower, set-vertical-bar,
set-horizontal-bar): Make these toggle or look at the prefix
argument, like minor modes.
* frame.el (set-vertical-bar): Use the proper parameter symbol.
(set-horizontal-bar): Signal an error indicating that horizontal
scrollbars are not implemented.
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Sun, 14 Feb 1993 14:29:30 +0000 |
parents | f6a38dd2250b |
children | 1354a2911d11 |
files | lisp/frame.el |
diffstat | 1 files changed, 173 insertions(+), 63 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/frame.el Sun Feb 14 14:27:24 1993 +0000 +++ b/lisp/frame.el Sun Feb 14 14:29:30 1993 +0000 @@ -28,20 +28,23 @@ The window system startup file should set this to its frame creation function, which should take an alist of parameters as its argument.") -;;; The default value for this must ask for a minibuffer. There must -;;; always exist a frame with a minibuffer, and after we delete the -;;; terminal frame, this will be the only frame. +;;; The initial value given here for this must ask for a minibuffer. +;;; There must always exist a frame with a minibuffer, and after we +;;; delete the terminal frame, this will be the only frame. (defvar initial-frame-alist '((minibuffer . t)) "Alist of values used when creating the initial emacs text frame. These may be set in your init file, like this: (setq initial-frame-alist '((top . 1) (left . 1) (width . 80) (height . 55))) +If this requests a frame without a minibuffer, and you do not create a +minibuffer frame on your own, one will be created, according to +`minibuffer-frame-alist'. These supercede the values given in frame-default-alist.") -(defvar minibuffer-frame-alist nil +(defvar minibuffer-frame-alist '((width . 80) (height . 2)) "Alist of values to apply to a minibuffer frame. These may be set in your init file, like this: (setq minibuffer-frame-alist - '((top . 1) (left . 1) (width . 80) (height . 1))) + '((top . 1) (left . 1) (width . 80) (height . 2))) These supercede the values given in default-frame-alist.") (defvar pop-up-frame-alist nil @@ -80,22 +83,16 @@ ;; Are we actually running under a window system at all? (if (and window-system (not noninteractive)) - (let ((frames (frame-list))) - - ;; Look for a frame that has a minibuffer. - (while (and frames - (or (eq (car frames) terminal-frame) - (not (cdr (assq 'minibuffer - (frame-parameters - (car frames))))))) - (setq frames (cdr frames))) - - ;; If there was none, then we need to create the opening frame. - (or frames + (progn + ;; 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 + ;; minibuffer spec. + (or (delq terminal-frame (minibuffer-frame-list)) (setq default-minibuffer-frame (setq frame-initial-frame (new-frame initial-frame-alist)))) - + ;; At this point, we know that we have a frame open, so we ;; can delete the terminal frame. (delete-frame terminal-frame) @@ -108,50 +105,115 @@ (error "Can't create multiple frames without a window system.")))))) -;;; startup.el calls this function after loading the user's init file. -;;; If we created a minibuffer before knowing if we had permission, we -;;; need to see if it should go away or change. Create a text frame -;;; here. +;;; 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. (defun frame-notice-user-settings () - (if (frame-live-p frame-initial-frame) - (progn - ;; If the user wants a minibuffer-only frame, we'll have to - ;; make a new one; you can't remove or add a root window to/from - ;; an existing frame. + + ;; Creating and deleting frames may shift the selected frame around, + ;; and thus the current buffer. Protect against that. We don't + ;; want to use save-excursion here, because that may also try to set + ;; the buffer of the selected window, which fails when the selected + ;; window is the minibuffer. + (let ((old-buffer (current-buffer))) + + ;; If the initial frame is still around, apply initial-frame-alist + ;; and default-frame-alist to it. + (if (frame-live-p frame-initial-frame) + + ;; The initial frame we create above always has a minibuffer. + ;; If the user wants to remove it, or make it a minibuffer-only + ;; frame, then we'll have to delete the current frame and make a + ;; new one; you can't remove or add a root window to/from an + ;; existing frame. + ;; ;; NOTE: default-frame-alist was nil when we created the ;; existing frame. We need to explicitly include ;; default-frame-alist in the parameters of the screen we ;; create here, so that its new value, gleaned from the user's ;; .emacs file, will be applied to the existing screen. - (if (eq (cdr (or (assq 'minibuffer initial-frame-alist) - '(minibuffer . t))) - 'only) - (progn - (setq default-minibuffer-frame - (new-frame - (append initial-frame-alist - default-frame-alist - (frame-parameters frame-initial-frame)))) + (if (not (eq (cdr (or (assq 'minibuffer initial-frame-alist) + (assq 'minibuffer default-frame-alist) + '(minibuffer . t))) + t)) + ;; Create the new frame. + (let ((new + (new-frame + (append initial-frame-alist + default-frame-alist + (frame-parameters frame-initial-frame))))) + + ;; The initial frame, which we are about to delete, may be + ;; the only frame with a minibuffer. If it is, create a + ;; new one. + (or (delq frame-initial-frame (minibuffer-frame-list)) + (new-frame (append minibuffer-frame-alist + '((minibuffer . only))))) + + ;; If the initial frame is serving as a surrogate + ;; minibuffer frame for any frames, we need to wean them + ;; onto a new frame. The default-minibuffer-frame + ;; variable must be handled similarly. + (let ((users-of-initial + (filtered-frame-list + (function (lambda (frame) + (and (not (eq frame frame-initial-frame)) + (eq (window-frame + (minibuffer-window frame)) + frame-initial-frame))))))) + (if (or users-of-initial + (eq default-minibuffer-frame frame-initial-frame)) + + ;; Choose an appropriate frame. Prefer frames which + ;; are only minibuffers. + (let* ((new-surrogate + (car + (or (filtered-frame-list + (function + (lambda (frame) + (eq (cdr (assq 'minibuffer + (frame-parameters frame))) + 'only)))) + (minibuffer-frame-list)))) + (new-minibuffer (minibuffer-window new-surrogate))) + + (if (eq default-minibuffer-frame frame-initial-frame) + (setq default-minibuffer-frame new-surrogate)) + + ;; Wean the frames using frame-initial-frame as + ;; their minibuffer frame. + (mapcar + (function + (lambda (frame) + (modify-frame-parameters + frame (list (cons 'minibuffer new-minibuffer))))) + users-of-initial)))) ;; Redirect events enqueued at this frame to the new frame. ;; Is this a good idea? - (redirect-frame-focus frame-initial-frame - default-minibuffer-frame) + (redirect-frame-focus frame-initial-frame new) + ;; Finally, get rid of the old frame. (delete-frame frame-initial-frame)) + + ;; 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))))) + default-frame-alist)))) - ;; Make sure the initial frame can be GC'd if it is ever deleted. - (makunbound 'frame-initial-frame)) + ;; Restore the original buffer. + (set-buffer old-buffer) + + ;; Make sure the initial frame can be GC'd if it is ever deleted. + (makunbound 'frame-initial-frame))) -;;;; Creation of additional frames +;;;; Creation of additional frames, and other frame miscellanea -;;; Return some frame other than the current frame, -;;; creating one if neccessary. Note that the minibuffer frame, if -;;; separate, is not considered (see next-frame). +;;; Return some frame other than the current frame, creating one if +;;; neccessary. Note that the minibuffer frame, if separate, is not +;;; considered (see next-frame). (defun get-other-frame () (let ((s (if (equal (next-frame (selected-frame)) (selected-frame)) (new-frame) @@ -204,6 +266,22 @@ (interactive) (funcall frame-creation-function parameters)) +(defun filtered-frame-list (predicate) + "Return a list of all live frames which satisfy PREDICATE." + (let ((frames (frame-list)) + good-frames) + (while (consp frames) + (if (funcall predicate (car frames)) + (setq good-frames (cons (car frames) good-frames))) + (setq frames (cdr frames))) + good-frames)) + +(defun minibuffer-frame-list () + "Return a list of all frames with their own minibuffers." + (filtered-frame-list + (function (lambda (frame) + (eq frame (window-frame (minibuffer-window frame))))))) + ;;;; Frame configurations @@ -251,49 +329,81 @@ (cdr (assq 'width (frame-parameters frame)))) (defun set-default-font (font-name) + "Set the font of the selected frame to FONT. +When called interactively, prompt for the name of the font to use." (interactive "sFont name: ") (modify-frame-parameters (selected-frame) - (list (cons 'font font-name)))) + (list (cons 'font font-name)))) (defun set-frame-background (color-name) + "Set the background color of the selected frame to COLOR. +When called interactively, prompt for the name of the color to use." (interactive "sColor: ") (modify-frame-parameters (selected-frame) - (list (cons 'background-color color-name)))) + (list (cons 'background-color color-name)))) (defun set-frame-foreground (color-name) + "Set the foreground color of the selected frame to COLOR. +When called interactively, prompt for the name of the color to use." (interactive "sColor: ") (modify-frame-parameters (selected-frame) - (list (cons 'foreground-color color-name)))) + (list (cons 'foreground-color color-name)))) (defun set-cursor-color (color-name) + "Set the text cursor color of the selected frame to COLOR. +When called interactively, prompt for the name of the color to use." (interactive "sColor: ") (modify-frame-parameters (selected-frame) - (list (cons 'cursor-color color-name)))) + (list (cons 'cursor-color color-name)))) (defun set-pointer-color (color-name) + "Set the color of the mouse pointer of the selected frame to COLOR. +When called interactively, prompt for the name of the color to use." (interactive "sColor: ") (modify-frame-parameters (selected-frame) - (list (cons 'mouse-color color-name)))) + (list (cons 'mouse-color color-name)))) -(defun set-auto-raise (toggle) - (interactive "xt or nil? ") +(defun set-auto-raise (arg) + "Toggle whether or not the selected frame should auto-raise. +With arg, turn auto-raise mode on if and only if arg is positive." + (interactive "P") + (if (null arg) + (setq arg + (if (cdr (assq 'auto-raise (frame-parameters (selected-frame)))) + -1 1))) (modify-frame-parameters (selected-frame) - (list (cons 'auto-raise toggle)))) + (list (cons 'auto-raise (> arg 0))))) -(defun set-auto-lower (toggle) - (interactive "xt or nil? ") +(defun set-auto-lower (arg) + "Toggle whether or not the selected frame should auto-lower. +With arg, turn auto-lower mode on if and only if arg is positive." + (interactive "P") + (if (null arg) + (setq arg + (if (cdr (assq 'auto-lower (frame-parameters (selected-frame)))) + -1 1))) (modify-frame-parameters (selected-frame) - (list (cons 'auto-lower toggle)))) + (list (cons 'auto-lower (> arg 0))))) -(defun set-vertical-bar (toggle) - (interactive "xt or nil? ") +(defun set-vertical-bar (arg) + "Toggle whether or not the selected frame has vertical scrollbars. +With arg, turn vertical scrollbars on if and only if arg is positive." + (interactive "P") + (if (null arg) + (setq arg + (if (cdr (assq 'vertical-scrollbars + (frame-parameters (selected-frame)))) + -1 1))) (modify-frame-parameters (selected-frame) - (list (cons 'vertical-scroll-bar toggle)))) + (list (cons 'vertical-scrollbars (> arg 0))))) -(defun set-horizontal-bar (toggle) - (interactive "xt or nil? ") - (modify-frame-parameters (selected-frame) - (list (cons 'horizontal-scroll-bar toggle)))) +(defun set-horizontal-bar (arg) + "Toggle whether or not the selected frame has horizontal scrollbars. +With arg, turn horizontal scrollbars on if and only if arg is positive. +Horizontal scrollbars aren't implemented yet." + (interactive "P") + (error "Horizontal scrollbars aren't implemented yet.")) + ;;;; Aliases for backward compatibility with Emacs 18. (fset 'screen-height 'frame-height)