(Buffer-menu-mouse-select): Handle dedicated window.
[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.
b65e2f74
RS
186 (let (parms new)
187 ;; If the frame isn't visible yet, wait till it is.
188 ;; If the user has to position the window,
189 ;; Emacs doesn't know its real position until
190 ;; the frame is seen to be visible.
191 (while (not (cdr (assq 'visibility
192 (frame-parameters frame-initial-frame))))
193 (sleep-for 1))
194 (setq parms (append initial-frame-alist
6eb018ba
RS
195 default-frame-alist
196 (frame-parameters frame-initial-frame)
197 nil))
c1e67401
RS
198 ;; Get rid of `reverse', because that was handled
199 ;; when we first made the frame.
200 (setq parms (cons '(reverse) (delq (assq 'reverse parms) parms)))
201 (if (assq 'height frame-initial-geometry-arguments)
202 (setq parms (delq (assq 'height parms) parms)))
203 (if (assq 'width frame-initial-geometry-arguments)
204 (setq parms (delq (assq 'width parms) parms)))
205 (if (assq 'left frame-initial-geometry-arguments)
206 (setq parms (delq (assq 'left parms) parms)))
207 (if (assq 'top frame-initial-geometry-arguments)
208 (setq parms (delq (assq 'top parms) parms)))
209 (setq new
210 (make-frame
211 ;; Use the geometry args that created the existing
212 ;; frame, rather than the parms we get for it.
213 (append frame-initial-geometry-arguments parms)))
7eadab74
JB
214 ;; The initial frame, which we are about to delete, may be
215 ;; the only frame with a minibuffer. If it is, create a
216 ;; new one.
217 (or (delq frame-initial-frame (minibuffer-frame-list))
6eb018ba 218 (make-frame (append minibuffer-frame-alist
7eadab74
JB
219 '((minibuffer . only)))))
220
221 ;; If the initial frame is serving as a surrogate
222 ;; minibuffer frame for any frames, we need to wean them
223 ;; onto a new frame. The default-minibuffer-frame
224 ;; variable must be handled similarly.
225 (let ((users-of-initial
226 (filtered-frame-list
227 (function (lambda (frame)
228 (and (not (eq frame frame-initial-frame))
229 (eq (window-frame
230 (minibuffer-window frame))
231 frame-initial-frame)))))))
232 (if (or users-of-initial
233 (eq default-minibuffer-frame frame-initial-frame))
234
235 ;; Choose an appropriate frame. Prefer frames which
236 ;; are only minibuffers.
237 (let* ((new-surrogate
238 (car
239 (or (filtered-frame-list
240 (function
241 (lambda (frame)
242 (eq (cdr (assq 'minibuffer
243 (frame-parameters frame)))
244 'only))))
245 (minibuffer-frame-list))))
246 (new-minibuffer (minibuffer-window new-surrogate)))
247
248 (if (eq default-minibuffer-frame frame-initial-frame)
249 (setq default-minibuffer-frame new-surrogate))
250
251 ;; Wean the frames using frame-initial-frame as
252 ;; their minibuffer frame.
253 (mapcar
254 (function
255 (lambda (frame)
256 (modify-frame-parameters
257 frame (list (cons 'minibuffer new-minibuffer)))))
258 users-of-initial))))
ec558adc
JB
259
260 ;; Redirect events enqueued at this frame to the new frame.
261 ;; Is this a good idea?
7eadab74 262 (redirect-frame-focus frame-initial-frame new)
ec558adc 263
7eadab74 264 ;; Finally, get rid of the old frame.
0cffbbb9 265 (delete-frame frame-initial-frame t))
7eadab74
JB
266
267 ;; Otherwise, we don't need all that rigamarole; just apply
268 ;; the new parameters.
3f2f8c83
RS
269 (let (newparms allparms tail)
270 (setq allparms (append initial-frame-alist
271 default-frame-alist))
272 (setq tail allparms)
273 ;; Find just the parms that have changed since we first
274 ;; made this frame. Those are the ones actually set by
275 ;; the init file. For those parms whose values we already knew
276 ;; (such as those spec'd by command line options)
277 ;; it is undesirable to specify the parm again
278 ;; once the user has seen the frame and been able to alter it
279 ;; manually.
280 (while tail
281 (let (newval oldval)
282 (setq oldval (cdr (assq (car (car tail))
283 frame-initial-frame-alist)))
284 (setq newval (cdr (assq (car (car tail)) allparms)))
285 (or (eq oldval newval)
286 (setq newparms
287 (cons (cons (car (car tail)) newval) newparms))))
288 (setq tail (cdr tail)))
289 (modify-frame-parameters frame-initial-frame
290 (nreverse newparms)))))
64c669bc 291
7eadab74
JB
292 ;; Restore the original buffer.
293 (set-buffer old-buffer)
294
295 ;; Make sure the initial frame can be GC'd if it is ever deleted.
d202f1f2
JB
296 ;; Make sure frame-notice-user-settings does nothing if called twice.
297 (setq frame-initial-frame nil)))
64c669bc
JB
298
299\f
7eadab74 300;;;; Creation of additional frames, and other frame miscellanea
dc6d9681 301
7eadab74 302;;; Return some frame other than the current frame, creating one if
eb8c3be9 303;;; necessary. Note that the minibuffer frame, if separate, is not
7eadab74 304;;; considered (see next-frame).
7253d8e0 305(defun get-other-frame ()
dc6d9681 306 (let ((s (if (equal (next-frame (selected-frame)) (selected-frame))
6eb018ba 307 (make-frame)
dc6d9681 308 (next-frame (selected-frame)))))
64c669bc
JB
309 s))
310
dc6d9681
JB
311(defun next-multiframe-window ()
312 "Select the next window, regardless of which frame it is on."
64c669bc
JB
313 (interactive)
314 (select-window (next-window (selected-window)
315 (> (minibuffer-depth) 0)
316 t)))
317
dc6d9681
JB
318(defun previous-multiframe-window ()
319 "Select the previous window, regardless of which frame it is on."
64c669bc
JB
320 (interactive)
321 (select-window (previous-window (selected-window)
322 (> (minibuffer-depth) 0)
323 t)))
324
92e443b1 325;; Alias, kept temporarily.
31e1d920 326(defalias 'new-frame 'make-frame)
92e443b1 327(defun make-frame (&optional parameters)
dc6d9681 328 "Create a new frame, displaying the current buffer.
bc93c097 329
43a2e52c 330Optional argument PARAMETERS is an alist of parameters for the new
dc6d9681 331frame. Specifically, PARAMETERS is a list of pairs, each having one
43a2e52c
JB
332of the following forms:
333
eaa974e1 334\(name . STRING) - The frame should be named STRING.
43a2e52c 335
eaa974e1 336\(height . NUMBER) - The frame should be NUMBER text lines high. If
43a2e52c
JB
337 this parameter is present, the width parameter must also be
338 given.
339
eaa974e1 340\(width . NUMBER) - The frame should be NUMBER characters in width.
43a2e52c
JB
341 If this parameter is present, the height parameter must also
342 be given.
343
eaa974e1 344\(minibuffer . t) - the frame should have a minibuffer
0ca90494 345\(minibuffer . nil) - the frame should have no minibuffer
eaa974e1
JB
346\(minibuffer . only) - the frame should contain only a minibuffer
347\(minibuffer . WINDOW) - the frame should use WINDOW as its minibuffer window.
43a2e52c 348
eaa974e1
JB
349The documentation for the function `x-create-frame' describes
350additional frame parameters that Emacs recognizes for X window frames."
64c669bc 351 (interactive)
4133ab49
RS
352 (let ((nframe))
353 (run-hooks 'before-make-frame-hook)
354 (setq nframe (funcall frame-creation-function parameters))
355 (run-hooks 'after-make-frame-hook)
356 nframe))
64c669bc 357
7eadab74
JB
358(defun filtered-frame-list (predicate)
359 "Return a list of all live frames which satisfy PREDICATE."
360 (let ((frames (frame-list))
361 good-frames)
362 (while (consp frames)
363 (if (funcall predicate (car frames))
364 (setq good-frames (cons (car frames) good-frames)))
365 (setq frames (cdr frames)))
366 good-frames))
367
368(defun minibuffer-frame-list ()
369 "Return a list of all frames with their own minibuffers."
370 (filtered-frame-list
371 (function (lambda (frame)
372 (eq frame (window-frame (minibuffer-window frame)))))))
373
58bf6042
JB
374(defun frame-remove-geometry-params (param-list)
375 "Return the parameter list PARAM-LIST, but with geometry specs removed.
376This deletes all bindings in PARAM-LIST for `top', `left', `width',
791e09d8 377`height', `user-size' and `user-position' parameters.
58bf6042
JB
378Emacs uses this to avoid overriding explicit moves and resizings from
379the user during startup."
380 (setq param-list (cons nil param-list))
381 (let ((tail param-list))
382 (while (consp (cdr tail))
383 (if (and (consp (car (cdr tail)))
791e09d8
RS
384 (memq (car (car (cdr tail)))
385 '(height width top left user-position user-size)))
386 (progn
387 (setq frame-initial-geometry-arguments
388 (cons (car (cdr tail)) frame-initial-geometry-arguments))
389 (setcdr tail (cdr (cdr tail))))
58bf6042 390 (setq tail (cdr tail)))))
e11c3dc2
KH
391 (setq frame-initial-geometry-arguments
392 (nreverse frame-initial-geometry-arguments))
58bf6042
JB
393 (cdr param-list))
394
395
ceab6935 396(defun other-frame (arg)
a569dbc3 397 "Select the ARG'th different visible frame, and raise it.
ceab6935
RM
398All frames are arranged in a cyclic order.
399This command selects the frame ARG steps away in that order.
400A negative ARG moves in the opposite order."
401 (interactive "p")
402 (let ((frame (selected-frame)))
403 (while (> arg 0)
a569dbc3
RM
404 (setq frame (next-frame frame))
405 (while (not (eq (frame-visible-p frame) t))
406 (setq frame (next-frame frame)))
407 (setq arg (1- arg)))
ceab6935 408 (while (< arg 0)
a569dbc3
RM
409 (setq frame (previous-frame frame))
410 (while (not (eq (frame-visible-p frame) t))
411 (setq frame (previous-frame frame)))
915cfd1f 412 (setq arg (1+ arg)))
ceab6935 413 (raise-frame frame)
699213bc 414 (select-frame frame)
2b88f7a0 415 (set-mouse-position (selected-frame) (1- (frame-width)) 0)
699213bc 416 (unfocus-frame)))
64c669bc 417\f
dc6d9681
JB
418;;;; Frame configurations
419
420(defun current-frame-configuration ()
421 "Return a list describing the positions and states of all frames.
376a7584
JB
422Its car is `frame-configuration'.
423Each element of the cdr is a list of the form (FRAME ALIST WINDOW-CONFIG),
424where
425 FRAME is a frame object,
426 ALIST is an association list specifying some of FRAME's parameters, and
427 WINDOW-CONFIG is a window configuration object for FRAME."
428 (cons 'frame-configuration
429 (mapcar (function
430 (lambda (frame)
431 (list frame
432 (frame-parameters frame)
433 (current-window-configuration frame))))
434 (frame-list))))
dc6d9681 435
68cd265f 436(defun set-frame-configuration (configuration &optional nodelete)
dc6d9681
JB
437 "Restore the frames to the state described by CONFIGURATION.
438Each frame listed in CONFIGURATION has its position, size, window
68cd265f 439configuration, and other parameters set as specified in CONFIGURATION.
a78db71c
RS
440Ordinarily, this function deletes all existing frames not
441listed in CONFIGURATION. But if optional second argument NODELETE
5da841d2 442is given and non-nil, the unwanted frames are iconified instead."
376a7584
JB
443 (or (frame-configuration-p configuration)
444 (signal 'wrong-type-argument
445 (list 'frame-configuration-p configuration)))
446 (let ((config-alist (cdr configuration))
447 frames-to-delete)
06b1a5ef 448 (mapcar (function
dc6d9681 449 (lambda (frame)
376a7584 450 (let ((parameters (assq frame config-alist)))
06b1a5ef
JB
451 (if parameters
452 (progn
98e9d14b
JB
453 (modify-frame-parameters
454 frame
455 ;; Since we can't set a frame's minibuffer status,
456 ;; we might as well omit the parameter altogether.
457 (let* ((parms (nth 1 parameters))
458 (mini (assq 'minibuffer parms)))
459 (if mini (setq parms (delq mini parms)))
460 parms))
06b1a5ef 461 (set-window-configuration (nth 2 parameters)))
dc6d9681
JB
462 (setq frames-to-delete (cons frame frames-to-delete))))))
463 (frame-list))
a78db71c 464 (if nodelete
5da841d2
RS
465 ;; Note: making frames invisible here was tried
466 ;; but led to some strange behavior--each time the frame
467 ;; was made visible again, the window manager asked afresh
468 ;; for where to put it.
469 (mapcar 'iconify-frame frames-to-delete)
a78db71c 470 (mapcar 'delete-frame frames-to-delete))))
64c669bc 471
376a7584
JB
472(defun frame-configuration-p (object)
473 "Return non-nil if OBJECT seems to be a frame configuration.
474Any list whose car is `frame-configuration' is assumed to be a frame
475configuration."
476 (and (consp object)
477 (eq (car object) 'frame-configuration)))
478
64c669bc 479\f
dc6d9681
JB
480;;;; Convenience functions for accessing and interactively changing
481;;;; frame parameters.
64c669bc 482
151bdc83 483(defun frame-height (&optional frame)
dc6d9681
JB
484 "Return number of lines available for display on FRAME.
485If FRAME is omitted, describe the currently selected frame."
151bdc83 486 (cdr (assq 'height (frame-parameters frame))))
dc6d9681
JB
487
488(defun frame-width (&optional frame)
489 "Return number of columns available for display on FRAME.
490If FRAME is omitted, describe the currently selected frame."
151bdc83 491 (cdr (assq 'width (frame-parameters frame))))
dc6d9681 492
64c669bc 493(defun set-default-font (font-name)
7eadab74
JB
494 "Set the font of the selected frame to FONT.
495When called interactively, prompt for the name of the font to use."
64c669bc 496 (interactive "sFont name: ")
dc6d9681 497 (modify-frame-parameters (selected-frame)
4033f46b
RS
498 (list (cons 'font font-name)))
499 ;; Update faces that want a bold or italic version of the default font.
500 (frame-update-faces (selected-frame)))
64c669bc 501
8290babd 502(defun set-background-color (color-name)
7eadab74
JB
503 "Set the background color of the selected frame to COLOR.
504When called interactively, prompt for the name of the color to use."
64c669bc 505 (interactive "sColor: ")
dc6d9681 506 (modify-frame-parameters (selected-frame)
7eadab74 507 (list (cons 'background-color color-name))))
64c669bc 508
8290babd 509(defun set-foreground-color (color-name)
7eadab74
JB
510 "Set the foreground color of the selected frame to COLOR.
511When called interactively, prompt for the name of the color to use."
64c669bc 512 (interactive "sColor: ")
dc6d9681 513 (modify-frame-parameters (selected-frame)
7eadab74 514 (list (cons 'foreground-color color-name))))
64c669bc
JB
515
516(defun set-cursor-color (color-name)
7eadab74
JB
517 "Set the text cursor color of the selected frame to COLOR.
518When called interactively, prompt for the name of the color to use."
64c669bc 519 (interactive "sColor: ")
dc6d9681 520 (modify-frame-parameters (selected-frame)
7eadab74 521 (list (cons 'cursor-color color-name))))
64c669bc 522
eaa974e1 523(defun set-mouse-color (color-name)
7eadab74
JB
524 "Set the color of the mouse pointer of the selected frame to COLOR.
525When called interactively, prompt for the name of the color to use."
64c669bc 526 (interactive "sColor: ")
dc6d9681 527 (modify-frame-parameters (selected-frame)
7eadab74
JB
528 (list (cons 'mouse-color color-name))))
529
eaa974e1
JB
530(defun set-border-color (color-name)
531 "Set the color of the border of the selected frame to COLOR.
532When called interactively, prompt for the name of the color to use."
533 (interactive "sColor: ")
534 (modify-frame-parameters (selected-frame)
535 (list (cons 'border-color color-name))))
536
537(defun auto-raise-mode (arg)
7eadab74
JB
538 "Toggle whether or not the selected frame should auto-raise.
539With arg, turn auto-raise mode on if and only if arg is positive."
540 (interactive "P")
541 (if (null arg)
542 (setq arg
543 (if (cdr (assq 'auto-raise (frame-parameters (selected-frame))))
544 -1 1)))
dc6d9681 545 (modify-frame-parameters (selected-frame)
7eadab74
JB
546 (list (cons 'auto-raise (> arg 0)))))
547
eaa974e1 548(defun auto-lower-mode (arg)
7eadab74
JB
549 "Toggle whether or not the selected frame should auto-lower.
550With arg, turn auto-lower mode on if and only if arg is positive."
551 (interactive "P")
552 (if (null arg)
553 (setq arg
554 (if (cdr (assq 'auto-lower (frame-parameters (selected-frame))))
555 -1 1)))
dc6d9681 556 (modify-frame-parameters (selected-frame)
7eadab74
JB
557 (list (cons 'auto-lower (> arg 0)))))
558
7e85c6b5 559(defun toggle-scroll-bar (arg)
0ca90494
JB
560 "Toggle whether or not the selected frame has vertical scroll bars.
561With arg, turn vertical scroll bars on if and only if arg is positive."
7eadab74
JB
562 (interactive "P")
563 (if (null arg)
564 (setq arg
0ca90494 565 (if (cdr (assq 'vertical-scroll-bars
7eadab74
JB
566 (frame-parameters (selected-frame))))
567 -1 1)))
dc6d9681 568 (modify-frame-parameters (selected-frame)
0ca90494 569 (list (cons 'vertical-scroll-bars (> arg 0)))))
7eadab74 570
8290babd 571(defun toggle-horizontal-scroll-bar (arg)
0ca90494
JB
572 "Toggle whether or not the selected frame has horizontal scroll bars.
573With arg, turn horizontal scroll bars on if and only if arg is positive.
574Horizontal scroll bars aren't implemented yet."
7eadab74 575 (interactive "P")
8290babd 576 (error "Horizontal scroll bars aren't implemented yet"))
64c669bc 577
64c669bc 578\f
dc6d9681 579;;;; Aliases for backward compatibility with Emacs 18.
31e1d920
ER
580(defalias 'screen-height 'frame-height)
581(defalias 'screen-width 'frame-width)
9e2b097b
JB
582
583(defun set-screen-width (cols &optional pretend)
584 "Obsolete function to change the size of the screen to COLS columns.\n\
585Optional second arg non-nil means that redisplay should use COLS columns\n\
586but that the idea of the actual width of the frame should not be changed.\n\
587This function is provided only for compatibility with Emacs 18; new code\n\
fe668515 588should use `set-frame-width instead'."
9e2b097b
JB
589 (set-frame-width (selected-frame) cols pretend))
590
591(defun set-screen-height (lines &optional pretend)
592 "Obsolete function to change the height of the screen to LINES lines.\n\
593Optional second arg non-nil means that redisplay should use LINES lines\n\
594but that the idea of the actual height of the screen should not be changed.\n\
595This function is provided only for compatibility with Emacs 18; new code\n\
fe668515 596should use `set-frame-width' instead."
9e2b097b
JB
597 (set-frame-height (selected-frame) lines pretend))
598
599(make-obsolete 'screen-height 'frame-height)
600(make-obsolete 'screen-width 'frame-width)
601(make-obsolete 'set-screen-width 'set-frame-width)
602(make-obsolete 'set-screen-height 'set-frame-height)
dc6d9681
JB
603
604\f
64c669bc 605;;;; Key bindings
daa37602 606(defvar ctl-x-5-map (make-sparse-keymap)
dc6d9681 607 "Keymap for frame commands.")
31e1d920 608(defalias 'ctl-x-5-prefix ctl-x-5-map)
daa37602 609(define-key ctl-x-map "5" 'ctl-x-5-prefix)
64c669bc 610
6eb018ba 611(define-key ctl-x-5-map "2" 'make-frame)
dc6d9681 612(define-key ctl-x-5-map "0" 'delete-frame)
ceab6935 613(define-key ctl-x-5-map "o" 'other-frame)
49116ac0 614
dc6d9681 615(provide 'frame)
c88ab9ce 616
dc6d9681 617;;; frame.el ends here