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
;; Maintainer: FSF
;; Last-Modified: 09 Jul 92
Eric S. Raymond's avatar
Eric S. Raymond committed
5
;; Keywords: internal
Eric S. Raymond's avatar
Eric S. Raymond committed
6

Jim Blandy's avatar
Jim Blandy committed
7
;;;; Copyright (C) 1990, 1992 Free Software Foundation, Inc.
Jim Blandy's avatar
Jim Blandy committed
8 9 10 11 12

;;; 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
13
;;; the Free Software Foundation; either version 2, or (at your option)
Jim Blandy's avatar
Jim Blandy committed
14 15 16 17 18 19 20 21 22 23 24
;;; 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
25 26
;;; Code:

Jim Blandy's avatar
Jim Blandy committed
27 28 29
(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
30 31 32
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
33 34 35 36
;;; 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
37
These may be set in your init file, like this:
Jim Blandy's avatar
Jim Blandy committed
38 39
 (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
40

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

Jim Blandy's avatar
Jim Blandy committed
48 49 50
(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
51
This variable can be set in your init file, like this:
Jim Blandy's avatar
Jim Blandy committed
52 53
  (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
54

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

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

;;; 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
64
;;; file should create any frames specified in the window system defaults.
Jim Blandy's avatar
Jim Blandy committed
65
;;; 
Jim Blandy's avatar
Jim Blandy committed
66
;;; 2) If no frames have been opened, we open an initial text frame.
Jim Blandy's avatar
Jim Blandy committed
67 68
;;;
;;; 3) Once the init file is done, we apply any newly set parameters
Jim Blandy's avatar
Jim Blandy committed
69
;;; in initial-frame-alist to the frame.
Jim Blandy's avatar
Jim Blandy committed
70

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

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

;;; startup.el calls this function before loading the user's init
Jim Blandy's avatar
Jim Blandy committed
78
;;; file - if there is no frame with a minibuffer open now, create
Jim Blandy's avatar
Jim Blandy committed
79
;;; one to display messages while loading the init file.
Jim Blandy's avatar
Jim Blandy committed
80
(defun frame-initialize ()
Jim Blandy's avatar
Jim Blandy committed
81 82 83
  
  ;; Are we actually running under a window system at all?
  (if (and window-system (not noninteractive))
Jim Blandy's avatar
Jim Blandy committed
84
      (let ((frames (frame-list)))
Jim Blandy's avatar
Jim Blandy committed
85
    
Jim Blandy's avatar
Jim Blandy committed
86 87 88
	;; Look for a frame that has a minibuffer.
	(while (and frames
		    (or (eq (car frames) terminal-frame)
Jim Blandy's avatar
Jim Blandy committed
89
			(not (cdr (assq 'minibuffer
Jim Blandy's avatar
Jim Blandy committed
90 91 92 93 94 95 96 97 98
					(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
99
    
Jim Blandy's avatar
Jim Blandy committed
100 101 102 103
	;; 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
104 105
    
    ;; No, we're not running a window system.  Arrange to cause errors.
Jim Blandy's avatar
Jim Blandy committed
106
    (setq frame-creation-function
107 108 109
	  (function
	   (lambda (parameters)
	     (error
Jim Blandy's avatar
Jim Blandy committed
110
	      "Can't create multiple frames without a window system."))))))
Jim Blandy's avatar
Jim Blandy committed
111 112 113
					
;;; 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
114
;;; need to see if it should go away or change.  Create a text frame
Jim Blandy's avatar
Jim Blandy committed
115
;;; here.
Jim Blandy's avatar
Jim Blandy committed
116 117
(defun frame-notice-user-settings ()
  (if frame-initial-frame
Jim Blandy's avatar
Jim Blandy committed
118 119
      (progn
	
Jim Blandy's avatar
Jim Blandy committed
120
	;; If the user wants a minibuffer-only frame, we'll have to
Jim Blandy's avatar
Jim Blandy committed
121
	;; make a new one; you can't remove or add a root window to/from
Jim Blandy's avatar
Jim Blandy committed
122 123
	;; an existing frame.
	(if (eq (cdr (or (assq 'minibuffer initial-frame-alist)
Jim Blandy's avatar
Jim Blandy committed
124 125 126
			 '(minibuffer . t)))
		     'only)
	    (progn
Jim Blandy's avatar
Jim Blandy committed
127 128 129 130 131 132 133
	      (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
134

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


Jim Blandy's avatar
Jim Blandy committed
139 140 141 142 143 144 145 146 147
;;;; 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
148 149
    s))

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

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

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

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

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

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

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

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

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


;;;; Iconification

;;; A possible enhancement for the below: if you iconify a surrogate
Jim Blandy's avatar
Jim Blandy committed
200 201
;;; 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
202 203 204
;;; have mapping and unmapping hooks.

(defun iconify ()
Jim Blandy's avatar
Jim Blandy committed
205
  "Iconify or deiconify the selected frame."
Jim Blandy's avatar
Jim Blandy committed
206
  (interactive)
Jim Blandy's avatar
Jim Blandy committed
207 208 209 210
  (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
211 212

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

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

Jim Blandy's avatar
Jim Blandy committed
248 249 250 251 252 253 254 255 256 257 258
(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
259
  (interactive "NHeight: ")
Jim Blandy's avatar
Jim Blandy committed
260 261 262
  (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
263

Jim Blandy's avatar
Jim Blandy committed
264
(defun set-frame-width (w)
Jim Blandy's avatar
Jim Blandy committed
265
  (interactive "NWidth: ")
Jim Blandy's avatar
Jim Blandy committed
266 267 268
  (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
269 270 271

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

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

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

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

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

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

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

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

(defun set-horizontal-bar (toggle)
  (interactive "xt or nil? ")
Jim Blandy's avatar
Jim Blandy committed
312
  (modify-frame-parameters (selected-frame)
Jim Blandy's avatar
Jim Blandy committed
313
			    (list (cons 'horizontal-scroll-bar toggle))))
Jim Blandy's avatar
Jim Blandy committed
314 315 316 317 318 319 320

;;;; 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
321 322

;;;; Key bindings
Jim Blandy's avatar
Jim Blandy committed
323
(defvar ctl-x-5-map (make-sparse-keymap)
Jim Blandy's avatar
Jim Blandy committed
324
  "Keymap for frame commands.")
Jim Blandy's avatar
Jim Blandy committed
325 326
(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
327

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

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

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