(frame-notice-user-settings): When replacing the first
[bpt/emacs.git] / lisp / frame.el
CommitLineData
dc6d9681 1;;; frame.el --- multi-frame management independent of window systems.
c88ab9ce 2
8f1204db 3;;;; Copyright (C) 1993, 1994 Free Software Foundation, Inc.
3a801d0c 4
fc68affa 5;; Maintainer: FSF
fd7fa35a 6;; Keywords: internal
fc68affa 7
64c669bc
JB
8;;; This file is part of GNU Emacs.
9;;;
10;;; GNU Emacs is free software; you can redistribute it and/or modify
11;;; it under the terms of the GNU General Public License as published by
de49a6d3 12;;; the Free Software Foundation; either version 2, or (at your option)
64c669bc
JB
13;;; any later version.
14;;;
15;;; GNU Emacs is distributed in the hope that it will be useful,
16;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;;; GNU General Public License for more details.
19;;;
20;;; You should have received a copy of the GNU General Public License
21;;; along with GNU Emacs; see the file COPYING. If not, write to
22;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
fc68affa
ER
24;;; Code:
25
dc6d9681
JB
26(defvar frame-creation-function nil
27 "Window-system dependent function to call to create a new frame.
28The window system startup file should set this to its frame creation
64c669bc
JB
29function, which should take an alist of parameters as its argument.")
30
7eadab74
JB
31;;; The initial value given here for this must ask for a minibuffer.
32;;; There must always exist a frame with a minibuffer, and after we
33;;; delete the terminal frame, this will be the only frame.
9e2b097b 34(defvar initial-frame-alist '((minibuffer . t))
eaa974e1
JB
35 "Alist of frame parameters for creating the initial X window frame.
36You can set this in your `.emacs' file; for example,
dc6d9681 37 (setq initial-frame-alist '((top . 1) (left . 1) (width . 80) (height . 55)))
eaa974e1
JB
38If the value calls for a frame without a minibuffer, and you do not create a
39minibuffer frame on your own, one is created according to
7eadab74 40`minibuffer-frame-alist'.
eaa974e1
JB
41Parameters specified here supersede the values given in
42`default-frame-alist'.")
64c669bc 43
7eadab74 44(defvar minibuffer-frame-alist '((width . 80) (height . 2))
eaa974e1
JB
45 "Alist of frame parameters for initially creating a minibuffer frame.
46You can set this in your `.emacs' file; for example,
dc6d9681 47 (setq minibuffer-frame-alist
7eadab74 48 '((top . 1) (left . 1) (width . 80) (height . 2)))
eaa974e1
JB
49Parameters specified here supersede the values given in
50`default-frame-alist'.")
64c669bc 51
dc6d9681 52(defvar pop-up-frame-alist nil
eaa974e1 53 "Alist of frame parameters used when creating pop-up frames.
dc6d9681 54Pop-up frames are used for completions, help, and the like.
64c669bc 55This variable can be set in your init file, like this:
dc6d9681 56 (setq pop-up-frame-alist '((width . 80) (height . 20)))
eb8c3be9 57These supersede the values given in `default-frame-alist'.")
64c669bc 58
dc6d9681 59(setq pop-up-frame-function
64c669bc 60 (function (lambda ()
6eb018ba 61 (make-frame pop-up-frame-alist))))
64c669bc 62
8a9e86e6
RS
63(defvar special-display-frame-alist
64 '((height . 14) (width . 80) (unsplittable . t))
65 "*Alist of frame parameters used when creating special frames.
66Special frames are used for buffers whose names are in
67`special-display-buffer-names' and for buffers whose names match
68one of the regular expressions in `special-display-regexps'.
69This variable can be set in your init file, like this:
70 (setq special-display-frame-alist '((width . 80) (height . 20)))
71These supersede the values given in `default-frame-alist'.")
72
73;; Display BUFFER in its own frame, reusing an existing window if any.
74;; Return the window chosen.
75;; Currently we do not insist on selecting the window within its frame.
76(defun special-display-popup-frame (buffer)
77 (let ((window (get-buffer-window buffer t)))
78 (if window
79 ;; If we have a window already, make it visible.
80 (let ((frame (window-frame window)))
81 (make-frame-visible frame)
82 (raise-frame frame)
83 window)
84 ;; If no window yet, make one in a new frame.
6eb018ba 85 (let ((frame (make-frame special-display-frame-alist)))
8a9e86e6
RS
86 (set-window-buffer (frame-selected-window frame) buffer)
87 (set-window-dedicated-p (frame-selected-window frame) t)
88 (frame-selected-window frame)))))
89
90(setq special-display-function 'special-display-popup-frame)
64c669bc 91\f
dc6d9681 92;;;; Arrangement of frames at startup
64c669bc
JB
93
94;;; 1) Load the window system startup file from the lisp library and read the
95;;; high-priority arguments (-q and the like). The window system startup
dc6d9681 96;;; file should create any frames specified in the window system defaults.
64c669bc 97;;;
dc6d9681 98;;; 2) If no frames have been opened, we open an initial text frame.
64c669bc
JB
99;;;
100;;; 3) Once the init file is done, we apply any newly set parameters
dc6d9681 101;;; in initial-frame-alist to the frame.
64c669bc 102
fc4d4afb
RS
103;; These are now called explicitly at the proper times,
104;; since that is easier to understand.
105;; Actually using hooks within Emacs is bad for future maintenance. --rms.
106;; (add-hook 'before-init-hook 'frame-initialize)
107;; (add-hook 'window-setup-hook 'frame-notice-user-settings)
64c669bc 108
dc6d9681
JB
109;;; If we create the initial frame, this is it.
110(defvar frame-initial-frame nil)
64c669bc 111
3f2f8c83
RS
112;; Record the parameters used in frame-initialize to make the initial frame.
113(defvar frame-initial-frame-alist)
114
791e09d8
RS
115(defvar frame-initial-geometry-arguments nil)
116
64c669bc 117;;; startup.el calls this function before loading the user's init
dc6d9681 118;;; file - if there is no frame with a minibuffer open now, create
64c669bc 119;;; one to display messages while loading the init file.
dc6d9681 120(defun frame-initialize ()
64c669bc
JB
121
122 ;; Are we actually running under a window system at all?
123 (if (and window-system (not noninteractive))
7eadab74
JB
124 (progn
125 ;; If there is no frame with a minibuffer besides the terminal
126 ;; frame, then we need to create the opening frame. Make sure
127 ;; it has a minibuffer, but let initial-frame-alist omit the
128 ;; minibuffer spec.
129 (or (delq terminal-frame (minibuffer-frame-list))
36fc9c9f 130 (progn
3f2f8c83
RS
131 (setq frame-initial-frame-alist
132 (append initial-frame-alist default-frame-alist))
36fc9c9f
RS
133 (setq default-minibuffer-frame
134 (setq frame-initial-frame
6eb018ba 135 (make-frame initial-frame-alist)))
11281034
RS
136 ;; Delete any specifications for window geometry parameters
137 ;; so that we won't reapply them in frame-notice-user-settings.
138 ;; It would be wrong to reapply them then,
139 ;; because that would override explicit user resizing.
58bf6042 140 (setq initial-frame-alist
c2079f0a 141 (frame-remove-geometry-params initial-frame-alist))))
dc6d9681
JB
142 ;; At this point, we know that we have a frame open, so we
143 ;; can delete the terminal frame.
144 (delete-frame terminal-frame)
145 (setq terminal-frame nil))
64c669bc
JB
146
147 ;; No, we're not running a window system. Arrange to cause errors.
dc6d9681 148 (setq frame-creation-function
9198945a
MB
149 (function
150 (lambda (parameters)
151 (error
8290babd 152 "Can't create multiple frames without a window system"))))))
64c669bc 153
7eadab74
JB
154;;; startup.el calls this function after loading the user's init
155;;; file. Now default-frame-alist and initial-frame-alist contain
156;;; information to which we must react; do what needs to be done.
dc6d9681 157(defun frame-notice-user-settings ()
7eadab74
JB
158
159 ;; Creating and deleting frames may shift the selected frame around,
160 ;; and thus the current buffer. Protect against that. We don't
161 ;; want to use save-excursion here, because that may also try to set
162 ;; the buffer of the selected window, which fails when the selected
163 ;; window is the minibuffer.
164 (let ((old-buffer (current-buffer)))
165
166 ;; If the initial frame is still around, apply initial-frame-alist
167 ;; and default-frame-alist to it.
168 (if (frame-live-p frame-initial-frame)
169
170 ;; The initial frame we create above always has a minibuffer.
171 ;; If the user wants to remove it, or make it a minibuffer-only
172 ;; frame, then we'll have to delete the current frame and make a
173 ;; new one; you can't remove or add a root window to/from an
174 ;; existing frame.
175 ;;
ec558adc
JB
176 ;; NOTE: default-frame-alist was nil when we created the
177 ;; existing frame. We need to explicitly include
178 ;; default-frame-alist in the parameters of the screen we
179 ;; create here, so that its new value, gleaned from the user's
180 ;; .emacs file, will be applied to the existing screen.
7eadab74
JB
181 (if (not (eq (cdr (or (assq 'minibuffer initial-frame-alist)
182 (assq 'minibuffer default-frame-alist)
183 '(minibuffer . t)))
184 t))
185 ;; Create the new frame.
6eb018ba
RS
186 (let* ((parms (append initial-frame-alist
187 default-frame-alist
188 (frame-parameters frame-initial-frame)
189 nil))
190 ;; Get rid of `reverse', because that was handled
191 ;; when we first made the frame.
791e09d8
RS
192 (new (make-frame
193 ;; Use the geometry args that created the existing
194 ;; frame, rather than the parms we get for it.q
195 (append frame-initial-geometry-arguments
196 (let (frame-initial-geometry-arguments)
197 (frame-remove-geometry-params
198 (cons '(reverse . nil)
199 (delq (assq 'reverse parms)
200 parms))))))))
7eadab74
JB
201 ;; The initial frame, which we are about to delete, may be
202 ;; the only frame with a minibuffer. If it is, create a
203 ;; new one.
204 (or (delq frame-initial-frame (minibuffer-frame-list))
6eb018ba 205 (make-frame (append minibuffer-frame-alist
7eadab74
JB
206 '((minibuffer . only)))))
207
208 ;; If the initial frame is serving as a surrogate
209 ;; minibuffer frame for any frames, we need to wean them
210 ;; onto a new frame. The default-minibuffer-frame
211 ;; variable must be handled similarly.
212 (let ((users-of-initial
213 (filtered-frame-list
214 (function (lambda (frame)
215 (and (not (eq frame frame-initial-frame))
216 (eq (window-frame
217 (minibuffer-window frame))
218 frame-initial-frame)))))))
219 (if (or users-of-initial
220 (eq default-minibuffer-frame frame-initial-frame))
221
222 ;; Choose an appropriate frame. Prefer frames which
223 ;; are only minibuffers.
224 (let* ((new-surrogate
225 (car
226 (or (filtered-frame-list
227 (function
228 (lambda (frame)
229 (eq (cdr (assq 'minibuffer
230 (frame-parameters frame)))
231 'only))))
232 (minibuffer-frame-list))))
233 (new-minibuffer (minibuffer-window new-surrogate)))
234
235 (if (eq default-minibuffer-frame frame-initial-frame)
236 (setq default-minibuffer-frame new-surrogate))
237
238 ;; Wean the frames using frame-initial-frame as
239 ;; their minibuffer frame.
240 (mapcar
241 (function
242 (lambda (frame)
243 (modify-frame-parameters
244 frame (list (cons 'minibuffer new-minibuffer)))))
245 users-of-initial))))
ec558adc
JB
246
247 ;; Redirect events enqueued at this frame to the new frame.
248 ;; Is this a good idea?
7eadab74 249 (redirect-frame-focus frame-initial-frame new)
ec558adc 250
7eadab74 251 ;; Finally, get rid of the old frame.
0cffbbb9 252 (delete-frame frame-initial-frame t))
7eadab74
JB
253
254 ;; Otherwise, we don't need all that rigamarole; just apply
255 ;; the new parameters.
3f2f8c83
RS
256 (let (newparms allparms tail)
257 (setq allparms (append initial-frame-alist
258 default-frame-alist))
259 (setq tail allparms)
260 ;; Find just the parms that have changed since we first
261 ;; made this frame. Those are the ones actually set by
262 ;; the init file. For those parms whose values we already knew
263 ;; (such as those spec'd by command line options)
264 ;; it is undesirable to specify the parm again
265 ;; once the user has seen the frame and been able to alter it
266 ;; manually.
267 (while tail
268 (let (newval oldval)
269 (setq oldval (cdr (assq (car (car tail))
270 frame-initial-frame-alist)))
271 (setq newval (cdr (assq (car (car tail)) allparms)))
272 (or (eq oldval newval)
273 (setq newparms
274 (cons (cons (car (car tail)) newval) newparms))))
275 (setq tail (cdr tail)))
276 (modify-frame-parameters frame-initial-frame
277 (nreverse newparms)))))
64c669bc 278
7eadab74
JB
279 ;; Restore the original buffer.
280 (set-buffer old-buffer)
281
282 ;; Make sure the initial frame can be GC'd if it is ever deleted.
d202f1f2
JB
283 ;; Make sure frame-notice-user-settings does nothing if called twice.
284 (setq frame-initial-frame nil)))
64c669bc
JB
285
286\f
7eadab74 287;;;; Creation of additional frames, and other frame miscellanea
dc6d9681 288
7eadab74 289;;; Return some frame other than the current frame, creating one if
eb8c3be9 290;;; necessary. Note that the minibuffer frame, if separate, is not
7eadab74 291;;; considered (see next-frame).
7253d8e0 292(defun get-other-frame ()
dc6d9681 293 (let ((s (if (equal (next-frame (selected-frame)) (selected-frame))
6eb018ba 294 (make-frame)
dc6d9681 295 (next-frame (selected-frame)))))
64c669bc
JB
296 s))
297
dc6d9681
JB
298(defun next-multiframe-window ()
299 "Select the next window, regardless of which frame it is on."
64c669bc
JB
300 (interactive)
301 (select-window (next-window (selected-window)
302 (> (minibuffer-depth) 0)
303 t)))
304
dc6d9681
JB
305(defun previous-multiframe-window ()
306 "Select the previous window, regardless of which frame it is on."
64c669bc
JB
307 (interactive)
308 (select-window (previous-window (selected-window)
309 (> (minibuffer-depth) 0)
310 t)))
311
92e443b1 312;; Alias, kept temporarily.
31e1d920 313(defalias 'new-frame 'make-frame)
92e443b1 314(defun make-frame (&optional parameters)
dc6d9681 315 "Create a new frame, displaying the current buffer.
bc93c097 316
43a2e52c 317Optional argument PARAMETERS is an alist of parameters for the new
dc6d9681 318frame. Specifically, PARAMETERS is a list of pairs, each having one
43a2e52c
JB
319of the following forms:
320
eaa974e1 321\(name . STRING) - The frame should be named STRING.
43a2e52c 322
eaa974e1 323\(height . NUMBER) - The frame should be NUMBER text lines high. If
43a2e52c
JB
324 this parameter is present, the width parameter must also be
325 given.
326
eaa974e1 327\(width . NUMBER) - The frame should be NUMBER characters in width.
43a2e52c
JB
328 If this parameter is present, the height parameter must also
329 be given.
330
eaa974e1 331\(minibuffer . t) - the frame should have a minibuffer
0ca90494 332\(minibuffer . nil) - the frame should have no minibuffer
eaa974e1
JB
333\(minibuffer . only) - the frame should contain only a minibuffer
334\(minibuffer . WINDOW) - the frame should use WINDOW as its minibuffer window.
43a2e52c 335
eaa974e1
JB
336The documentation for the function `x-create-frame' describes
337additional frame parameters that Emacs recognizes for X window frames."
64c669bc 338 (interactive)
4133ab49
RS
339 (let ((nframe))
340 (run-hooks 'before-make-frame-hook)
341 (setq nframe (funcall frame-creation-function parameters))
342 (run-hooks 'after-make-frame-hook)
343 nframe))
64c669bc 344
7eadab74
JB
345(defun filtered-frame-list (predicate)
346 "Return a list of all live frames which satisfy PREDICATE."
347 (let ((frames (frame-list))
348 good-frames)
349 (while (consp frames)
350 (if (funcall predicate (car frames))
351 (setq good-frames (cons (car frames) good-frames)))
352 (setq frames (cdr frames)))
353 good-frames))
354
355(defun minibuffer-frame-list ()
356 "Return a list of all frames with their own minibuffers."
357 (filtered-frame-list
358 (function (lambda (frame)
359 (eq frame (window-frame (minibuffer-window frame)))))))
360
58bf6042
JB
361(defun frame-remove-geometry-params (param-list)
362 "Return the parameter list PARAM-LIST, but with geometry specs removed.
363This deletes all bindings in PARAM-LIST for `top', `left', `width',
791e09d8 364`height', `user-size' and `user-position' parameters.
58bf6042
JB
365Emacs uses this to avoid overriding explicit moves and resizings from
366the user during startup."
367 (setq param-list (cons nil param-list))
368 (let ((tail param-list))
369 (while (consp (cdr tail))
370 (if (and (consp (car (cdr tail)))
791e09d8
RS
371 (memq (car (car (cdr tail)))
372 '(height width top left user-position user-size)))
373 (progn
374 (setq frame-initial-geometry-arguments
375 (cons (car (cdr tail)) frame-initial-geometry-arguments))
376 (setcdr tail (cdr (cdr tail))))
58bf6042
JB
377 (setq tail (cdr tail)))))
378 (cdr param-list))
379
380
ceab6935 381(defun other-frame (arg)
a569dbc3 382 "Select the ARG'th different visible frame, and raise it.
ceab6935
RM
383All frames are arranged in a cyclic order.
384This command selects the frame ARG steps away in that order.
385A negative ARG moves in the opposite order."
386 (interactive "p")
387 (let ((frame (selected-frame)))
388 (while (> arg 0)
a569dbc3
RM
389 (setq frame (next-frame frame))
390 (while (not (eq (frame-visible-p frame) t))
391 (setq frame (next-frame frame)))
392 (setq arg (1- arg)))
ceab6935 393 (while (< arg 0)
a569dbc3
RM
394 (setq frame (previous-frame frame))
395 (while (not (eq (frame-visible-p frame) t))
396 (setq frame (previous-frame frame)))
915cfd1f 397 (setq arg (1+ arg)))
ceab6935 398 (raise-frame frame)
699213bc 399 (select-frame frame)
2b88f7a0 400 (set-mouse-position (selected-frame) (1- (frame-width)) 0)
699213bc 401 (unfocus-frame)))
64c669bc 402\f
dc6d9681
JB
403;;;; Frame configurations
404
405(defun current-frame-configuration ()
406 "Return a list describing the positions and states of all frames.
376a7584
JB
407Its car is `frame-configuration'.
408Each element of the cdr is a list of the form (FRAME ALIST WINDOW-CONFIG),
409where
410 FRAME is a frame object,
411 ALIST is an association list specifying some of FRAME's parameters, and
412 WINDOW-CONFIG is a window configuration object for FRAME."
413 (cons 'frame-configuration
414 (mapcar (function
415 (lambda (frame)
416 (list frame
417 (frame-parameters frame)
418 (current-window-configuration frame))))
419 (frame-list))))
dc6d9681 420
68cd265f 421(defun set-frame-configuration (configuration &optional nodelete)
dc6d9681
JB
422 "Restore the frames to the state described by CONFIGURATION.
423Each frame listed in CONFIGURATION has its position, size, window
68cd265f 424configuration, and other parameters set as specified in CONFIGURATION.
a78db71c
RS
425Ordinarily, this function deletes all existing frames not
426listed in CONFIGURATION. But if optional second argument NODELETE
5da841d2 427is given and non-nil, the unwanted frames are iconified instead."
376a7584
JB
428 (or (frame-configuration-p configuration)
429 (signal 'wrong-type-argument
430 (list 'frame-configuration-p configuration)))
431 (let ((config-alist (cdr configuration))
432 frames-to-delete)
06b1a5ef 433 (mapcar (function
dc6d9681 434 (lambda (frame)
376a7584 435 (let ((parameters (assq frame config-alist)))
06b1a5ef
JB
436 (if parameters
437 (progn
98e9d14b
JB
438 (modify-frame-parameters
439 frame
440 ;; Since we can't set a frame's minibuffer status,
441 ;; we might as well omit the parameter altogether.
442 (let* ((parms (nth 1 parameters))
443 (mini (assq 'minibuffer parms)))
444 (if mini (setq parms (delq mini parms)))
445 parms))
06b1a5ef 446 (set-window-configuration (nth 2 parameters)))
dc6d9681
JB
447 (setq frames-to-delete (cons frame frames-to-delete))))))
448 (frame-list))
a78db71c 449 (if nodelete
5da841d2
RS
450 ;; Note: making frames invisible here was tried
451 ;; but led to some strange behavior--each time the frame
452 ;; was made visible again, the window manager asked afresh
453 ;; for where to put it.
454 (mapcar 'iconify-frame frames-to-delete)
a78db71c 455 (mapcar 'delete-frame frames-to-delete))))
64c669bc 456
376a7584
JB
457(defun frame-configuration-p (object)
458 "Return non-nil if OBJECT seems to be a frame configuration.
459Any list whose car is `frame-configuration' is assumed to be a frame
460configuration."
461 (and (consp object)
462 (eq (car object) 'frame-configuration)))
463
64c669bc 464\f
dc6d9681
JB
465;;;; Convenience functions for accessing and interactively changing
466;;;; frame parameters.
64c669bc 467
151bdc83 468(defun frame-height (&optional frame)
dc6d9681
JB
469 "Return number of lines available for display on FRAME.
470If FRAME is omitted, describe the currently selected frame."
151bdc83 471 (cdr (assq 'height (frame-parameters frame))))
dc6d9681
JB
472
473(defun frame-width (&optional frame)
474 "Return number of columns available for display on FRAME.
475If FRAME is omitted, describe the currently selected frame."
151bdc83 476 (cdr (assq 'width (frame-parameters frame))))
dc6d9681 477
64c669bc 478(defun set-default-font (font-name)
7eadab74
JB
479 "Set the font of the selected frame to FONT.
480When called interactively, prompt for the name of the font to use."
64c669bc 481 (interactive "sFont name: ")
dc6d9681 482 (modify-frame-parameters (selected-frame)
4033f46b
RS
483 (list (cons 'font font-name)))
484 ;; Update faces that want a bold or italic version of the default font.
485 (frame-update-faces (selected-frame)))
64c669bc 486
8290babd 487(defun set-background-color (color-name)
7eadab74
JB
488 "Set the background color of the selected frame to COLOR.
489When called interactively, prompt for the name of the color to use."
64c669bc 490 (interactive "sColor: ")
dc6d9681 491 (modify-frame-parameters (selected-frame)
7eadab74 492 (list (cons 'background-color color-name))))
64c669bc 493
8290babd 494(defun set-foreground-color (color-name)
7eadab74
JB
495 "Set the foreground color of the selected frame to COLOR.
496When called interactively, prompt for the name of the color to use."
64c669bc 497 (interactive "sColor: ")
dc6d9681 498 (modify-frame-parameters (selected-frame)
7eadab74 499 (list (cons 'foreground-color color-name))))
64c669bc
JB
500
501(defun set-cursor-color (color-name)
7eadab74
JB
502 "Set the text cursor color of the selected frame to COLOR.
503When called interactively, prompt for the name of the color to use."
64c669bc 504 (interactive "sColor: ")
dc6d9681 505 (modify-frame-parameters (selected-frame)
7eadab74 506 (list (cons 'cursor-color color-name))))
64c669bc 507
eaa974e1 508(defun set-mouse-color (color-name)
7eadab74
JB
509 "Set the color of the mouse pointer of the selected frame to COLOR.
510When called interactively, prompt for the name of the color to use."
64c669bc 511 (interactive "sColor: ")
dc6d9681 512 (modify-frame-parameters (selected-frame)
7eadab74
JB
513 (list (cons 'mouse-color color-name))))
514
eaa974e1
JB
515(defun set-border-color (color-name)
516 "Set the color of the border of the selected frame to COLOR.
517When called interactively, prompt for the name of the color to use."
518 (interactive "sColor: ")
519 (modify-frame-parameters (selected-frame)
520 (list (cons 'border-color color-name))))
521
522(defun auto-raise-mode (arg)
7eadab74
JB
523 "Toggle whether or not the selected frame should auto-raise.
524With arg, turn auto-raise mode on if and only if arg is positive."
525 (interactive "P")
526 (if (null arg)
527 (setq arg
528 (if (cdr (assq 'auto-raise (frame-parameters (selected-frame))))
529 -1 1)))
dc6d9681 530 (modify-frame-parameters (selected-frame)
7eadab74
JB
531 (list (cons 'auto-raise (> arg 0)))))
532
eaa974e1 533(defun auto-lower-mode (arg)
7eadab74
JB
534 "Toggle whether or not the selected frame should auto-lower.
535With arg, turn auto-lower mode on if and only if arg is positive."
536 (interactive "P")
537 (if (null arg)
538 (setq arg
539 (if (cdr (assq 'auto-lower (frame-parameters (selected-frame))))
540 -1 1)))
dc6d9681 541 (modify-frame-parameters (selected-frame)
7eadab74
JB
542 (list (cons 'auto-lower (> arg 0)))))
543
7e85c6b5 544(defun toggle-scroll-bar (arg)
0ca90494
JB
545 "Toggle whether or not the selected frame has vertical scroll bars.
546With arg, turn vertical scroll bars on if and only if arg is positive."
7eadab74
JB
547 (interactive "P")
548 (if (null arg)
549 (setq arg
0ca90494 550 (if (cdr (assq 'vertical-scroll-bars
7eadab74
JB
551 (frame-parameters (selected-frame))))
552 -1 1)))
dc6d9681 553 (modify-frame-parameters (selected-frame)
0ca90494 554 (list (cons 'vertical-scroll-bars (> arg 0)))))
7eadab74 555
8290babd 556(defun toggle-horizontal-scroll-bar (arg)
0ca90494
JB
557 "Toggle whether or not the selected frame has horizontal scroll bars.
558With arg, turn horizontal scroll bars on if and only if arg is positive.
559Horizontal scroll bars aren't implemented yet."
7eadab74 560 (interactive "P")
8290babd 561 (error "Horizontal scroll bars aren't implemented yet"))
64c669bc 562
64c669bc 563\f
dc6d9681 564;;;; Aliases for backward compatibility with Emacs 18.
31e1d920
ER
565(defalias 'screen-height 'frame-height)
566(defalias 'screen-width 'frame-width)
9e2b097b
JB
567
568(defun set-screen-width (cols &optional pretend)
569 "Obsolete function to change the size of the screen to COLS columns.\n\
570Optional second arg non-nil means that redisplay should use COLS columns\n\
571but that the idea of the actual width of the frame should not be changed.\n\
572This function is provided only for compatibility with Emacs 18; new code\n\
fe668515 573should use `set-frame-width instead'."
9e2b097b
JB
574 (set-frame-width (selected-frame) cols pretend))
575
576(defun set-screen-height (lines &optional pretend)
577 "Obsolete function to change the height of the screen to LINES lines.\n\
578Optional second arg non-nil means that redisplay should use LINES lines\n\
579but that the idea of the actual height of the screen should not be changed.\n\
580This function is provided only for compatibility with Emacs 18; new code\n\
fe668515 581should use `set-frame-width' instead."
9e2b097b
JB
582 (set-frame-height (selected-frame) lines pretend))
583
584(make-obsolete 'screen-height 'frame-height)
585(make-obsolete 'screen-width 'frame-width)
586(make-obsolete 'set-screen-width 'set-frame-width)
587(make-obsolete 'set-screen-height 'set-frame-height)
dc6d9681
JB
588
589\f
64c669bc 590;;;; Key bindings
daa37602 591(defvar ctl-x-5-map (make-sparse-keymap)
dc6d9681 592 "Keymap for frame commands.")
31e1d920 593(defalias 'ctl-x-5-prefix ctl-x-5-map)
daa37602 594(define-key ctl-x-map "5" 'ctl-x-5-prefix)
64c669bc 595
6eb018ba 596(define-key ctl-x-5-map "2" 'make-frame)
dc6d9681 597(define-key ctl-x-5-map "0" 'delete-frame)
ceab6935 598(define-key ctl-x-5-map "o" 'other-frame)
49116ac0 599
dc6d9681 600(provide 'frame)
c88ab9ce 601
dc6d9681 602;;; frame.el ends here