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