frame.el 11.9 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1
;;; frame.el --- multi-frame management independent of window systems.
Eric S. Raymond's avatar
Eric S. Raymond committed
2

3
;;;; Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc.
Eric S. Raymond's avatar
Eric S. Raymond committed
4

Eric S. Raymond's avatar
Eric S. Raymond committed
5
;; Maintainer: FSF
Eric S. Raymond's avatar
Eric S. Raymond committed
6
;; Keywords: internal
Eric S. Raymond's avatar
Eric S. Raymond committed
7

Jim Blandy's avatar
Jim Blandy committed
8 9 10 11
;;; This file is part of GNU Emacs.
;;;
;;; 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
Jim Blandy's avatar
Jim Blandy committed
12
;;; the Free Software Foundation; either version 2, or (at your option)
Jim Blandy's avatar
Jim Blandy committed
13 14 15 16 17 18 19 20 21 22 23
;;; 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
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; 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, 675 Mass Ave, Cambridge, MA 02139, USA.

Eric S. Raymond's avatar
Eric S. Raymond committed
24 25
;;; Code:

Jim Blandy's avatar
Jim Blandy committed
26 27 28
(defvar frame-creation-function nil
  "Window-system dependent function to call to create a new frame.
The window system startup file should set this to its frame creation
Jim Blandy's avatar
Jim Blandy committed
29 30 31
function, which should take an alist of parameters as its argument.")

;;; The default value for this must ask for a minibuffer.  There must
Jim Blandy's avatar
Jim Blandy committed
32 33
;;; always exist a frame with a minibuffer, and after we delete the
;;; terminal frame, this will be the only frame.
Jim Blandy's avatar
Jim Blandy committed
34
(defvar initial-frame-alist '((minibuffer . t))
Jim Blandy's avatar
Jim Blandy committed
35
  "Alist of values used when creating the initial emacs text frame.
Jim Blandy's avatar
Jim Blandy committed
36
These may be set in your init file, like this:
Jim Blandy's avatar
Jim Blandy committed
37 38
 (setq initial-frame-alist '((top . 1) (left . 1) (width . 80) (height . 55)))
These supercede the values given in frame-default-alist.")
Jim Blandy's avatar
Jim Blandy committed
39

Jim Blandy's avatar
Jim Blandy committed
40 41
(defvar minibuffer-frame-alist nil
  "Alist of values to apply to a minibuffer frame.
Jim Blandy's avatar
Jim Blandy committed
42
These may be set in your init file, like this:
Jim Blandy's avatar
Jim Blandy committed
43
 (setq minibuffer-frame-alist
Jim Blandy's avatar
Jim Blandy committed
44
   '((top . 1) (left . 1) (width . 80) (height . 1)))
Jim Blandy's avatar
Jim Blandy committed
45
These supercede the values given in default-frame-alist.")
Jim Blandy's avatar
Jim Blandy committed
46

Jim Blandy's avatar
Jim Blandy committed
47 48 49
(defvar pop-up-frame-alist nil
  "Alist of values used when creating pop-up frames.
Pop-up frames are used for completions, help, and the like.
Jim Blandy's avatar
Jim Blandy committed
50
This variable can be set in your init file, like this:
Jim Blandy's avatar
Jim Blandy committed
51 52
  (setq pop-up-frame-alist '((width . 80) (height . 20)))
These supercede the values given in default-frame-alist.")
Jim Blandy's avatar
Jim Blandy committed
53

Jim Blandy's avatar
Jim Blandy committed
54
(setq pop-up-frame-function
Jim Blandy's avatar
Jim Blandy committed
55
      (function (lambda ()
Jim Blandy's avatar
Jim Blandy committed
56
		  (new-frame pop-up-frame-alist))))
Jim Blandy's avatar
Jim Blandy committed
57 58


Jim Blandy's avatar
Jim Blandy committed
59
;;;; Arrangement of frames at startup
Jim Blandy's avatar
Jim Blandy committed
60 61 62

;;; 1) Load the window system startup file from the lisp library and read the
;;; high-priority arguments (-q and the like).  The window system startup
Jim Blandy's avatar
Jim Blandy committed
63
;;; file should create any frames specified in the window system defaults.
Jim Blandy's avatar
Jim Blandy committed
64
;;; 
Jim Blandy's avatar
Jim Blandy committed
65
;;; 2) If no frames have been opened, we open an initial text frame.
Jim Blandy's avatar
Jim Blandy committed
66 67
;;;
;;; 3) Once the init file is done, we apply any newly set parameters
Jim Blandy's avatar
Jim Blandy committed
68
;;; in initial-frame-alist to the frame.
Jim Blandy's avatar
Jim Blandy committed
69

Jim Blandy's avatar
Jim Blandy committed
70 71
(add-hook 'before-init-hook 'frame-initialize)
(add-hook 'window-setup-hook 'frame-notice-user-settings)
Jim Blandy's avatar
Jim Blandy committed
72

Jim Blandy's avatar
Jim Blandy committed
73 74
;;; If we create the initial frame, this is it.
(defvar frame-initial-frame nil)
Jim Blandy's avatar
Jim Blandy committed
75 76

;;; startup.el calls this function before loading the user's init
Jim Blandy's avatar
Jim Blandy committed
77
;;; file - if there is no frame with a minibuffer open now, create
Jim Blandy's avatar
Jim Blandy committed
78
;;; one to display messages while loading the init file.
Jim Blandy's avatar
Jim Blandy committed
79
(defun frame-initialize ()
Jim Blandy's avatar
Jim Blandy committed
80 81 82
  
  ;; Are we actually running under a window system at all?
  (if (and window-system (not noninteractive))
Jim Blandy's avatar
Jim Blandy committed
83
      (let ((frames (frame-list)))
Jim Blandy's avatar
Jim Blandy committed
84
    
Jim Blandy's avatar
Jim Blandy committed
85 86 87
	;; Look for a frame that has a minibuffer.
	(while (and frames
		    (or (eq (car frames) terminal-frame)
Jim Blandy's avatar
Jim Blandy committed
88
			(not (cdr (assq 'minibuffer
Jim Blandy's avatar
Jim Blandy committed
89 90 91 92 93 94 95 96 97
					(frame-parameters
					 (car frames)))))))
	  (setq frames (cdr frames)))

	;; If there was none, then we need to create the opening frame.
	(or frames
	    (setq default-minibuffer-frame
		  (setq frame-initial-frame
			(new-frame initial-frame-alist))))
Jim Blandy's avatar
Jim Blandy committed
98
    
Jim Blandy's avatar
Jim Blandy committed
99 100 101 102
	;; At this point, we know that we have a frame open, so we 
	;; can delete the terminal frame.
	(delete-frame terminal-frame)
	(setq terminal-frame nil))
Jim Blandy's avatar
Jim Blandy committed
103 104
    
    ;; No, we're not running a window system.  Arrange to cause errors.
Jim Blandy's avatar
Jim Blandy committed
105
    (setq frame-creation-function
106 107 108
	  (function
	   (lambda (parameters)
	     (error
Jim Blandy's avatar
Jim Blandy committed
109
	      "Can't create multiple frames without a window system."))))))
Jim Blandy's avatar
Jim Blandy committed
110 111 112
					
;;; startup.el calls this function after loading the user's init file.
;;; If we created a minibuffer before knowing if we had permission, we
Jim Blandy's avatar
Jim Blandy committed
113
;;; need to see if it should go away or change.  Create a text frame
Jim Blandy's avatar
Jim Blandy committed
114
;;; here.
Jim Blandy's avatar
Jim Blandy committed
115
(defun frame-notice-user-settings ()
Jim Blandy's avatar
Jim Blandy committed
116
  (if (frame-live-p frame-initial-frame)
Jim Blandy's avatar
Jim Blandy committed
117
      (progn
Jim Blandy's avatar
Jim Blandy committed
118
	;; If the user wants a minibuffer-only frame, we'll have to
Jim Blandy's avatar
Jim Blandy committed
119
	;; make a new one; you can't remove or add a root window to/from
Jim Blandy's avatar
Jim Blandy committed
120
	;; an existing frame.
Jim Blandy's avatar
Jim Blandy committed
121 122 123 124 125
	;; 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.
Jim Blandy's avatar
Jim Blandy committed
126
	(if (eq (cdr (or (assq 'minibuffer initial-frame-alist)
Jim Blandy's avatar
Jim Blandy committed
127 128 129
			 '(minibuffer . t)))
		     'only)
	    (progn
Jim Blandy's avatar
Jim Blandy committed
130 131 132
	      (setq default-minibuffer-frame
		    (new-frame
		     (append initial-frame-alist
Jim Blandy's avatar
Jim Blandy committed
133
			     default-frame-alist
Jim Blandy's avatar
Jim Blandy committed
134
			     (frame-parameters frame-initial-frame))))
Jim Blandy's avatar
Jim Blandy committed
135 136 137 138 139 140

	      ;; Redirect events enqueued at this frame to the new frame.
	      ;; Is this a good idea?
	      (redirect-frame-focus frame-initial-frame
				    default-minibuffer-frame)

Jim Blandy's avatar
Jim Blandy committed
141 142
	      (delete-frame frame-initial-frame))
	  (modify-frame-parameters frame-initial-frame
Jim Blandy's avatar
Jim Blandy committed
143 144
				   (append initial-frame-alist
					   default-frame-alist)))))
Jim Blandy's avatar
Jim Blandy committed
145

Jim Blandy's avatar
Jim Blandy committed
146 147
  ;; Make sure the initial frame can be GC'd if it is ever deleted.
  (makunbound 'frame-initial-frame))
Jim Blandy's avatar
Jim Blandy committed
148 149


Jim Blandy's avatar
Jim Blandy committed
150 151 152 153 154
;;;; Creation of additional frames

;;; 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).
Jim Blandy's avatar
Jim Blandy committed
155
(defun get-other-frame ()
Jim Blandy's avatar
Jim Blandy committed
156 157 158
  (let ((s (if (equal (next-frame (selected-frame)) (selected-frame))
	       (new-frame)
	     (next-frame (selected-frame)))))
Jim Blandy's avatar
Jim Blandy committed
159 160
    s))

Jim Blandy's avatar
Jim Blandy committed
161 162
(defun next-multiframe-window ()
  "Select the next window, regardless of which frame it is on."
Jim Blandy's avatar
Jim Blandy committed
163 164 165 166 167
  (interactive)
  (select-window (next-window (selected-window)
			      (> (minibuffer-depth) 0)
			      t)))

Jim Blandy's avatar
Jim Blandy committed
168 169
(defun previous-multiframe-window ()
  "Select the previous window, regardless of which frame it is on."
Jim Blandy's avatar
Jim Blandy committed
170 171 172 173 174
  (interactive)
  (select-window (previous-window (selected-window)
				  (> (minibuffer-depth) 0)
				  t)))

Jim Blandy's avatar
Jim Blandy committed
175 176
(defun new-frame (&optional parameters)
  "Create a new frame, displaying the current buffer.
Jim Blandy's avatar
Jim Blandy committed
177

Jim Blandy's avatar
Jim Blandy committed
178
Optional argument PARAMETERS is an alist of parameters for the new
Jim Blandy's avatar
Jim Blandy committed
179
frame.  Specifically, PARAMETERS is a list of pairs, each having one
Jim Blandy's avatar
Jim Blandy committed
180 181
of the following forms:

Jim Blandy's avatar
Jim Blandy committed
182
(name . STRING)	- The frame should be named STRING.
Jim Blandy's avatar
Jim Blandy committed
183

Jim Blandy's avatar
Jim Blandy committed
184
(height . NUMBER) - The frame should be NUMBER text lines high.  If
Jim Blandy's avatar
Jim Blandy committed
185 186 187
	this parameter is present, the width parameter must also be
	given.

Jim Blandy's avatar
Jim Blandy committed
188
(width . NUMBER) - The frame should be NUMBER characters in width.
Jim Blandy's avatar
Jim Blandy committed
189 190 191
	If this parameter is present, the height parameter must also
	be given.

Jim Blandy's avatar
Jim Blandy committed
192 193 194 195
(minibuffer . t) - the frame should have a minibuffer
(minibuffer . none) - the frame should have no minibuffer
(minibuffer . only) - the frame should contain only a minibuffer
(minibuffer . WINDOW) - the frame should use WINDOW as its minibuffer window.
Jim Blandy's avatar
Jim Blandy committed
196 197 198 199 200

(NAME . VALUE), specifying the parameter and the value it should have.
NAME should be one of the following symbols:
  name		VALUE 

Jim Blandy's avatar
Jim Blandy committed
201 202
The documentation for the function x-create-frame describes
additional frame parameters that Emacs will recognize when running
Jim Blandy's avatar
Jim Blandy committed
203
under the X Window System."
Jim Blandy's avatar
Jim Blandy committed
204
  (interactive)
Jim Blandy's avatar
Jim Blandy committed
205
  (funcall frame-creation-function parameters))
Jim Blandy's avatar
Jim Blandy committed
206

Jim Blandy's avatar
Jim Blandy committed
207

Jim Blandy's avatar
Jim Blandy committed
208 209 210 211 212 213 214 215
;;;; Frame configurations

(defun current-frame-configuration ()
  "Return a list describing the positions and states of all frames.
Each element is a list of the form (FRAME ALIST WINDOW-CONFIG), where
FRAME is a frame object, ALIST is an association list specifying
some of FRAME's parameters, and WINDOW-CONFIG is a window
configuration object for FRAME."
Jim Blandy's avatar
Jim Blandy committed
216
  (mapcar (function
Jim Blandy's avatar
Jim Blandy committed
217 218 219 220 221 222 223 224 225
	   (lambda (frame)
	     (list frame
		   (frame-parameters frame)
		   (current-window-configuration frame))))
	  (frame-list)))

(defun set-frame-configuration (configuration)
  "Restore the frames to the state described by CONFIGURATION.
Each frame listed in CONFIGURATION has its position, size, window
Jim Blandy's avatar
Jim Blandy committed
226
configuration, and other parameters set as specified in CONFIGURATION."
Jim Blandy's avatar
Jim Blandy committed
227
  (let (frames-to-delete)
Jim Blandy's avatar
Jim Blandy committed
228
    (mapcar (function
Jim Blandy's avatar
Jim Blandy committed
229 230
	     (lambda (frame)
	       (let ((parameters (assq frame configuration)))
Jim Blandy's avatar
Jim Blandy committed
231 232
		 (if parameters
		     (progn
Jim Blandy's avatar
Jim Blandy committed
233
		       (modify-frame-parameters frame (nth 1 parameters))
Jim Blandy's avatar
Jim Blandy committed
234
		       (set-window-configuration (nth 2 parameters)))
Jim Blandy's avatar
Jim Blandy committed
235 236 237
		   (setq frames-to-delete (cons frame frames-to-delete))))))
	    (frame-list))
    (mapcar 'delete-frame frames-to-delete)))
Jim Blandy's avatar
Jim Blandy committed
238 239


Jim Blandy's avatar
Jim Blandy committed
240 241
;;;; Convenience functions for accessing and interactively changing
;;;; frame parameters.
Jim Blandy's avatar
Jim Blandy committed
242

Jim Blandy's avatar
Jim Blandy committed
243
(defun frame-height (&optional frame)
Jim Blandy's avatar
Jim Blandy committed
244 245
  "Return number of lines available for display on FRAME.
If FRAME is omitted, describe the currently selected frame."
Jim Blandy's avatar
Jim Blandy committed
246
  (cdr (assq 'height (frame-parameters frame))))
Jim Blandy's avatar
Jim Blandy committed
247 248 249 250

(defun frame-width (&optional frame)
  "Return number of columns available for display on FRAME.
If FRAME is omitted, describe the currently selected frame."
Jim Blandy's avatar
Jim Blandy committed
251
  (cdr (assq 'width (frame-parameters frame))))
Jim Blandy's avatar
Jim Blandy committed
252

Jim Blandy's avatar
Jim Blandy committed
253 254
(defun set-default-font (font-name)
  (interactive "sFont name: ")
Jim Blandy's avatar
Jim Blandy committed
255
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
256 257
			    (list (cons 'font font-name))))

Jim Blandy's avatar
Jim Blandy committed
258
(defun set-frame-background (color-name)
Jim Blandy's avatar
Jim Blandy committed
259
  (interactive "sColor: ")
Jim Blandy's avatar
Jim Blandy committed
260
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
261 262
			    (list (cons 'background-color color-name))))

Jim Blandy's avatar
Jim Blandy committed
263
(defun set-frame-foreground (color-name)
Jim Blandy's avatar
Jim Blandy committed
264
  (interactive "sColor: ")
Jim Blandy's avatar
Jim Blandy committed
265
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
266 267 268 269
			    (list (cons 'foreground-color color-name))))

(defun set-cursor-color (color-name)
  (interactive "sColor: ")
Jim Blandy's avatar
Jim Blandy committed
270
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
271 272 273 274
			    (list (cons 'cursor-color color-name))))

(defun set-pointer-color (color-name)
  (interactive "sColor: ")
Jim Blandy's avatar
Jim Blandy committed
275
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
276 277 278 279
			    (list (cons 'mouse-color color-name))))

(defun set-auto-raise (toggle)
  (interactive "xt or nil? ")
Jim Blandy's avatar
Jim Blandy committed
280
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
281 282 283 284
			    (list (cons 'auto-raise toggle))))

(defun set-auto-lower (toggle)
  (interactive "xt or nil? ")
Jim Blandy's avatar
Jim Blandy committed
285
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
286 287 288 289
			    (list (cons 'auto-lower toggle))))

(defun set-vertical-bar (toggle)
  (interactive "xt or nil? ")
Jim Blandy's avatar
Jim Blandy committed
290
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
291 292 293 294
			    (list (cons 'vertical-scroll-bar toggle))))

(defun set-horizontal-bar (toggle)
  (interactive "xt or nil? ")
Jim Blandy's avatar
Jim Blandy committed
295
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
296
			    (list (cons 'horizontal-scroll-bar toggle))))
Jim Blandy's avatar
Jim Blandy committed
297 298 299 300

;;;; Aliases for backward compatibility with Emacs 18.
(fset 'screen-height 'frame-height)
(fset 'screen-width 'frame-width)
Jim Blandy's avatar
Jim Blandy committed
301 302 303 304 305 306

(defun set-screen-width (cols &optional pretend)
  "Obsolete function to change the size of the screen to COLS columns.\n\
Optional second arg non-nil means that redisplay should use COLS columns\n\
but that the idea of the actual width of the frame should not be changed.\n\
This function is provided only for compatibility with Emacs 18; new code\n\
Christopher Zaborsky's avatar
Christopher Zaborsky committed
307
should use `set-frame-width instead'."
Jim Blandy's avatar
Jim Blandy committed
308 309 310 311 312 313 314
  (set-frame-width (selected-frame) cols pretend))

(defun set-screen-height (lines &optional pretend)
  "Obsolete function to change the height of the screen to LINES lines.\n\
Optional second arg non-nil means that redisplay should use LINES lines\n\
but that the idea of the actual height of the screen should not be changed.\n\
This function is provided only for compatibility with Emacs 18; new code\n\
Christopher Zaborsky's avatar
Christopher Zaborsky committed
315
should use `set-frame-width' instead."
Jim Blandy's avatar
Jim Blandy committed
316 317 318 319 320 321
  (set-frame-height (selected-frame) lines pretend))

(make-obsolete 'screen-height 'frame-height)
(make-obsolete 'screen-width  'frame-width)
(make-obsolete 'set-screen-width 'set-frame-width)
(make-obsolete 'set-screen-height 'set-frame-height)
Jim Blandy's avatar
Jim Blandy committed
322

Jim Blandy's avatar
Jim Blandy committed
323 324

;;;; Key bindings
Jim Blandy's avatar
Jim Blandy committed
325
(defvar ctl-x-5-map (make-sparse-keymap)
Jim Blandy's avatar
Jim Blandy committed
326
  "Keymap for frame commands.")
Jim Blandy's avatar
Jim Blandy committed
327 328
(fset 'ctl-x-5-prefix ctl-x-5-map)
(define-key ctl-x-map "5" 'ctl-x-5-prefix)
Jim Blandy's avatar
Jim Blandy committed
329

Jim Blandy's avatar
Jim Blandy committed
330 331
(define-key ctl-x-5-map "2" 'new-frame)
(define-key ctl-x-5-map "0" 'delete-frame)
Jim Blandy's avatar
Jim Blandy committed
332

Jim Blandy's avatar
Jim Blandy committed
333
(provide 'frame)
Eric S. Raymond's avatar
Eric S. Raymond committed
334

Jim Blandy's avatar
Jim Blandy committed
335
;;; frame.el ends here