frame.el 11.3 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

Eric S. Raymond's avatar
Eric S. Raymond committed
3 4 5
;; Maintainer: FSF
;; Last-Modified: 09 Jul 92

Jim Blandy's avatar
Jim Blandy committed
6
;;;; Copyright (C) 1990, 1992 Free Software Foundation, Inc.
Jim Blandy's avatar
Jim Blandy committed
7 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 34 35
;;; 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 . nil))
  "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 116
(defun frame-notice-user-settings ()
  (if frame-initial-frame
Jim Blandy's avatar
Jim Blandy committed
117 118
      (progn
	
Jim Blandy's avatar
Jim Blandy committed
119
	;; If the user wants a minibuffer-only frame, we'll have to
Jim Blandy's avatar
Jim Blandy committed
120
	;; make a new one; you can't remove or add a root window to/from
Jim Blandy's avatar
Jim Blandy committed
121 122
	;; an existing frame.
	(if (eq (cdr (or (assq 'minibuffer initial-frame-alist)
Jim Blandy's avatar
Jim Blandy committed
123 124 125
			 '(minibuffer . t)))
		     'only)
	    (progn
Jim Blandy's avatar
Jim Blandy committed
126 127 128 129 130 131 132
	      (setq default-minibuffer-frame
		    (new-frame
		     (append initial-frame-alist
			     (frame-parameters frame-initial-frame))))
	      (delete-frame frame-initial-frame))
	  (modify-frame-parameters frame-initial-frame
				    initial-frame-alist))))
Jim Blandy's avatar
Jim Blandy committed
133

Jim Blandy's avatar
Jim Blandy committed
134 135
  ;; 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
136 137


Jim Blandy's avatar
Jim Blandy committed
138 139 140 141 142 143 144 145 146
;;;; 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).
(defun get-frame ()
  (let ((s (if (equal (next-frame (selected-frame)) (selected-frame))
	       (new-frame)
	     (next-frame (selected-frame)))))
Jim Blandy's avatar
Jim Blandy committed
147 148
    s))

Jim Blandy's avatar
Jim Blandy committed
149 150
(defun next-multiframe-window ()
  "Select the next window, regardless of which frame it is on."
Jim Blandy's avatar
Jim Blandy committed
151 152 153 154 155
  (interactive)
  (select-window (next-window (selected-window)
			      (> (minibuffer-depth) 0)
			      t)))

Jim Blandy's avatar
Jim Blandy committed
156 157
(defun previous-multiframe-window ()
  "Select the previous window, regardless of which frame it is on."
Jim Blandy's avatar
Jim Blandy committed
158 159 160 161 162
  (interactive)
  (select-window (previous-window (selected-window)
				  (> (minibuffer-depth) 0)
				  t)))

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

Jim Blandy's avatar
Jim Blandy committed
166
Optional argument PARAMETERS is an alist of parameters for the new
Jim Blandy's avatar
Jim Blandy committed
167
frame.  Specifically, PARAMETERS is a list of pairs, each having one
Jim Blandy's avatar
Jim Blandy committed
168 169
of the following forms:

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

Jim Blandy's avatar
Jim Blandy committed
172
(height . NUMBER) - The frame should be NUMBER text lines high.  If
Jim Blandy's avatar
Jim Blandy committed
173 174 175
	this parameter is present, the width parameter must also be
	given.

Jim Blandy's avatar
Jim Blandy committed
176
(width . NUMBER) - The frame should be NUMBER characters in width.
Jim Blandy's avatar
Jim Blandy committed
177 178 179
	If this parameter is present, the height parameter must also
	be given.

Jim Blandy's avatar
Jim Blandy committed
180 181 182 183
(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
184 185 186 187 188

(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
189 190
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
191
under the X Window System."
Jim Blandy's avatar
Jim Blandy committed
192
  (interactive)
Jim Blandy's avatar
Jim Blandy committed
193
  (funcall frame-creation-function parameters))
Jim Blandy's avatar
Jim Blandy committed
194 195 196 197 198


;;;; Iconification

;;; A possible enhancement for the below: if you iconify a surrogate
Jim Blandy's avatar
Jim Blandy committed
199 200
;;; minibuffer frame, iconify all of its minibuffer's users too; 
;;; de-iconify them as a group.  This will need to wait until frames
Jim Blandy's avatar
Jim Blandy committed
201 202 203
;;; have mapping and unmapping hooks.

(defun iconify ()
Jim Blandy's avatar
Jim Blandy committed
204
  "Iconify or deiconify the selected frame."
Jim Blandy's avatar
Jim Blandy committed
205
  (interactive)
Jim Blandy's avatar
Jim Blandy committed
206 207 208 209
  (let ((frame (selected-frame)))
    (if (eq (frame-visible-p frame) t)
	(iconify-frame frame)
      (make-frame-visible frame))))
Jim Blandy's avatar
Jim Blandy committed
210 211


Jim Blandy's avatar
Jim Blandy committed
212 213 214 215 216 217 218 219
;;;; 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
220
  (mapcar (function
Jim Blandy's avatar
Jim Blandy committed
221 222 223 224 225 226 227 228 229
	   (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
230
configuration, and other parameters set as specified in CONFIGURATION."
Jim Blandy's avatar
Jim Blandy committed
231
  (let (frames-to-delete)
Jim Blandy's avatar
Jim Blandy committed
232
    (mapcar (function
Jim Blandy's avatar
Jim Blandy committed
233 234
	     (lambda (frame)
	       (let ((parameters (assq frame configuration)))
Jim Blandy's avatar
Jim Blandy committed
235 236
		 (if parameters
		     (progn
Jim Blandy's avatar
Jim Blandy committed
237
		       (modify-frame-parameters frame (nth 1 parameters))
Jim Blandy's avatar
Jim Blandy committed
238
		       (set-window-configuration (nth 2 parameters)))
Jim Blandy's avatar
Jim Blandy committed
239 240 241
		   (setq frames-to-delete (cons frame frames-to-delete))))))
	    (frame-list))
    (mapcar 'delete-frame frames-to-delete)))
Jim Blandy's avatar
Jim Blandy committed
242 243


Jim Blandy's avatar
Jim Blandy committed
244 245
;;;; Convenience functions for accessing and interactively changing
;;;; frame parameters.
Jim Blandy's avatar
Jim Blandy committed
246

Jim Blandy's avatar
Jim Blandy committed
247 248 249 250 251 252 253 254 255 256 257
(defun frame-width (&optional frame)
  "Return number of lines available for display on FRAME.
If FRAME is omitted, describe the currently selected frame."
  (cdr (assq 'width (frame-parameters frame))))

(defun frame-width (&optional frame)
  "Return number of columns available for display on FRAME.
If FRAME is omitted, describe the currently selected frame."
  (cdr (assq 'height (frame-parameters frame))))

(defun set-frame-height (h)
Jim Blandy's avatar
Jim Blandy committed
258
  (interactive "NHeight: ")
Jim Blandy's avatar
Jim Blandy committed
259 260 261
  (let* ((frame (selected-frame))
	 (width (cdr (assoc 'width (frame-parameters (selected-frame))))))
    (set-frame-size (selected-frame) width h)))
Jim Blandy's avatar
Jim Blandy committed
262

Jim Blandy's avatar
Jim Blandy committed
263
(defun set-frame-width (w)
Jim Blandy's avatar
Jim Blandy committed
264
  (interactive "NWidth: ")
Jim Blandy's avatar
Jim Blandy committed
265 266 267
  (let* ((frame (selected-frame))
	 (height (cdr (assoc 'height (frame-parameters (selected-frame))))))
    (set-frame-size (selected-frame) w height)))
Jim Blandy's avatar
Jim Blandy committed
268 269 270

(defun set-default-font (font-name)
  (interactive "sFont name: ")
Jim Blandy's avatar
Jim Blandy committed
271
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
272 273
			    (list (cons 'font font-name))))

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

Jim Blandy's avatar
Jim Blandy committed
279
(defun set-frame-foreground (color-name)
Jim Blandy's avatar
Jim Blandy committed
280
  (interactive "sColor: ")
Jim Blandy's avatar
Jim Blandy committed
281
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
282 283 284 285
			    (list (cons 'foreground-color color-name))))

(defun set-cursor-color (color-name)
  (interactive "sColor: ")
Jim Blandy's avatar
Jim Blandy committed
286
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
287 288 289 290
			    (list (cons 'cursor-color color-name))))

(defun set-pointer-color (color-name)
  (interactive "sColor: ")
Jim Blandy's avatar
Jim Blandy committed
291
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
292 293 294 295
			    (list (cons 'mouse-color color-name))))

(defun set-auto-raise (toggle)
  (interactive "xt or nil? ")
Jim Blandy's avatar
Jim Blandy committed
296
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
297 298 299 300
			    (list (cons 'auto-raise toggle))))

(defun set-auto-lower (toggle)
  (interactive "xt or nil? ")
Jim Blandy's avatar
Jim Blandy committed
301
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
302 303 304 305
			    (list (cons 'auto-lower toggle))))

(defun set-vertical-bar (toggle)
  (interactive "xt or nil? ")
Jim Blandy's avatar
Jim Blandy committed
306
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
307 308 309 310
			    (list (cons 'vertical-scroll-bar toggle))))

(defun set-horizontal-bar (toggle)
  (interactive "xt or nil? ")
Jim Blandy's avatar
Jim Blandy committed
311
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
312
			    (list (cons 'horizontal-scroll-bar toggle))))
Jim Blandy's avatar
Jim Blandy committed
313 314 315 316 317 318 319

;;;; Aliases for backward compatibility with Emacs 18.
(fset 'screen-height 'frame-height)
(fset 'screen-width 'frame-width)
(fset 'set-screen-width 'set-frame-width)
(fset 'set-screen-height 'set-frame-height)

Jim Blandy's avatar
Jim Blandy committed
320 321

;;;; Key bindings
Jim Blandy's avatar
Jim Blandy committed
322
(defvar ctl-x-5-map (make-sparse-keymap)
Jim Blandy's avatar
Jim Blandy committed
323
  "Keymap for frame commands.")
Jim Blandy's avatar
Jim Blandy committed
324 325
(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
326

Jim Blandy's avatar
Jim Blandy committed
327 328
(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
329

Jim Blandy's avatar
Jim Blandy committed
330
(provide 'frame)
Eric S. Raymond's avatar
Eric S. Raymond committed
331

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