(elint-init-env): Skip non-list forms.
[bpt/emacs.git] / lisp / frame.el
CommitLineData
55535639 1;;; frame.el --- multi-frame management independent of window systems
c88ab9ce 2
0d30b337 3;; Copyright (C) 1993, 1994, 1996, 1997, 2000, 2001, 2002, 2003,
ae940284 4;; 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
3a801d0c 5
fc68affa 6;; Maintainer: FSF
fd7fa35a 7;; Keywords: internal
fc68affa 8
b578f267
EN
9;; This file is part of GNU Emacs.
10
eb3fa2cf 11;; GNU Emacs is free software: you can redistribute it and/or modify
b578f267 12;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
13;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) any later version.
b578f267
EN
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
eb3fa2cf 22;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
64c669bc 23
55535639
PJ
24;;; Commentary:
25
fc68affa
ER
26;;; Code:
27
2246281f
KL
28(defvar frame-creation-function-alist
29 (list (cons nil
30 (if (fboundp 'tty-create-frame-with-faces)
31 'tty-create-frame-with-faces
371fed4e
SM
32 (lambda (parameters)
33 (error "Can't create multiple frames without a window system")))))
2246281f
KL
34 "Alist of window-system dependent functions to call to create a new frame.
35The window system startup file should add its frame creation
36function to this list, which should take an alist of parameters
37as its argument.")
114a8b8c 38
bf1ba39f
KL
39(defvar window-system-default-frame-alist nil
40 "Alist of window-system dependent default frame parameters.
dca6c418 41You can set this in your init file; for example,
bf1ba39f 42
dca6c418
MR
43 ;; Disable menubar and toolbar on the console, but enable them under X.
44 (setq window-system-default-frame-alist
45 '((x (menu-bar-lines . 1) (tool-bar-lines . 1))
46 (nil (menu-bar-lines . 0) (tool-bar-lines . 0))))
bf1ba39f 47
dca6c418
MR
48Parameters specified here supersede the values given in
49`default-frame-alist'.")
bf1ba39f 50
7e573c4a
SM
51;; The initial value given here used to ask for a minibuffer.
52;; But that's not necessary, because the default is to have one.
53;; By not specifying it here, we let an X resource specify it.
0c966f88 54(defcustom initial-frame-alist nil
dca6c418
MR
55 "Alist of parameters for the initial X window frame.
56You can set this in your init file; for example,
57
58 (setq initial-frame-alist
59 '((top . 1) (left . 1) (width . 80) (height . 55)))
60
61Parameters specified here supersede the values given in
62`default-frame-alist'.
63
64If the value calls for a frame without a minibuffer, and you have
65not created a minibuffer frame on your own, a minibuffer frame is
66created according to `minibuffer-frame-alist'.
67
68You can specify geometry-related options for just the initial
69frame by setting this variable in your init file; however, they
70won't take effect until Emacs reads your init file, which happens
71after creating the initial frame. If you want the initial frame
72to have the proper geometry as soon as it appears, you need to
73use this three-step process:
de17da15
RS
74* Specify X resources to give the geometry you want.
75* Set `default-frame-alist' to override these options so that they
76 don't affect subsequent frames.
77* Set `initial-frame-alist' in a way that matches the X resources,
0c966f88
RS
78 to override what you put in `default-frame-alist'."
79 :type '(repeat (cons :format "%v"
80 (symbol :tag "Parameter")
81 (sexp :tag "Value")))
82 :group 'frames)
64c669bc 83
0b9d32af 84(defcustom minibuffer-frame-alist '((width . 80) (height . 2))
92e02072
CY
85 "Alist of parameters for the initial minibuffer frame.
86This is the minibuffer frame created if `initial-frame-alist'
87calls for a frame without a minibuffer. The parameters specified
88here supersede those given in `default-frame-alist', for the
89initial minibuffer frame.
90
dca6c418
MR
91You can set this in your init file; for example,
92
dc6d9681 93 (setq minibuffer-frame-alist
dca6c418
MR
94 '((top . 1) (left . 1) (width . 80) (height . 2)))
95
92e02072
CY
96It is not necessary to include (minibuffer . only); that is
97appended when the minibuffer frame is created."
0b9d32af
RS
98 :type '(repeat (cons :format "%v"
99 (symbol :tag "Parameter")
100 (sexp :tag "Value")))
101 :group 'frames)
64c669bc 102
0b9d32af 103(defcustom pop-up-frame-alist nil
dca6c418
MR
104 "Alist of parameters for automatically generated new frames.
105You can set this in your init file; for example,
106
dc6d9681 107 (setq pop-up-frame-alist '((width . 80) (height . 20)))
dca6c418
MR
108
109If non-nil, the value you specify here is used by the default
110`pop-up-frame-function' for the creation of new frames.
111
112Since `pop-up-frame-function' is used by `display-buffer' for
60898913 113making new frames, any value specified here by default affects
dca6c418
MR
114the automatic generation of new frames via `display-buffer' and
115all functions based on it. The behavior of `make-frame' is not
116affected by this variable."
0b9d32af
RS
117 :type '(repeat (cons :format "%v"
118 (symbol :tag "Parameter")
119 (sexp :tag "Value")))
120 :group 'frames)
64c669bc 121
25831d66
MR
122(defcustom pop-up-frame-function
123 (lambda () (make-frame pop-up-frame-alist))
dca6c418
MR
124 "Function used by `display-buffer' for creating a new frame.
125This function is called with no arguments and should return a new
126frame. The default value calls `make-frame' with the argument
127`pop-up-frame-alist'."
36fc0932 128 :type 'function
25831d66 129 :group 'frames)
64c669bc 130
30e19aee 131(defcustom special-display-frame-alist
8a9e86e6 132 '((height . 14) (width . 80) (unsplittable . t))
dca6c418 133 "Alist of parameters for special frames.
60898913 134Special frames are used for buffers whose names are listed in
8a9e86e6
RS
135`special-display-buffer-names' and for buffers whose names match
136one of the regular expressions in `special-display-regexps'.
dca6c418 137
8a9e86e6 138This variable can be set in your init file, like this:
dca6c418 139
8a9e86e6 140 (setq special-display-frame-alist '((width . 80) (height . 20)))
dca6c418 141
30e19aee
RS
142These supersede the values given in `default-frame-alist'."
143 :type '(repeat (cons :format "%v"
144 (symbol :tag "Parameter")
145 (sexp :tag "Value")))
146 :group 'frames)
8a9e86e6 147
95e6cf39 148(defun special-display-popup-frame (buffer &optional args)
60898913
MR
149 "Display BUFFER and return the window chosen.
150If BUFFER is already displayed in a visible or iconified frame,
151raise that frame. Otherwise, display BUFFER in a new frame.
152
153Optional argument ARGS is a list specifying additional
154information.
155
156If ARGS is an alist, use it as a list of frame parameters. If
157these parameters contain \(same-window . t), display BUFFER in
158the selected window. If they contain \(same-frame . t), display
159BUFFER in a window of the selected frame.
160
161If ARGS is a list whose car is a symbol, use (car ARGS) as a
162function to do the work. Pass it BUFFER as first argument,
163and (cdr ARGS) as second."
95e6cf39
RS
164 (if (and args (symbolp (car args)))
165 (apply (car args) buffer (cdr args))
bb2c34b1 166 (let ((window (get-buffer-window buffer 0)))
7e573c4a
SM
167 (or
168 ;; If we have a window already, make it visible.
169 (when window
170 (let ((frame (window-frame window)))
171 (make-frame-visible frame)
172 (raise-frame frame)
173 window))
174 ;; Reuse the current window if the user requested it.
175 (when (cdr (assq 'same-window args))
176 (condition-case nil
177 (progn (switch-to-buffer buffer) (selected-window))
178 (error nil)))
179 ;; Stay on the same frame if requested.
180 (when (or (cdr (assq 'same-frame args)) (cdr (assq 'same-window args)))
60898913
MR
181 (let* ((pop-up-windows t)
182 pop-up-frames
183 special-display-buffer-names special-display-regexps)
184 (display-buffer buffer)))
7e573c4a 185 ;; If no window yet, make one in a new frame.
bf247b6e 186 (let ((frame
86bd482f
RS
187 (with-current-buffer buffer
188 (make-frame (append args special-display-frame-alist)))))
7e573c4a
SM
189 (set-window-buffer (frame-selected-window frame) buffer)
190 (set-window-dedicated-p (frame-selected-window frame) t)
191 (frame-selected-window frame))))))
8a9e86e6 192
924be53a 193(defun handle-delete-frame (event)
40d34803 194 "Handle delete-frame events from the X server."
924be53a
RS
195 (interactive "e")
196 (let ((frame (posn-window (event-start event)))
197 (i 0)
198 (tail (frame-list)))
199 (while tail
200 (and (frame-visible-p (car tail))
201 (not (eq (car tail) frame))
202 (setq i (1+ i)))
203 (setq tail (cdr tail)))
204 (if (> i 0)
205 (delete-frame frame t)
a9562d19
RS
206 ;; Gildea@x.org says it is ok to ask questions before terminating.
207 (save-buffers-kill-emacs))))
64c669bc 208\f
dc6d9681 209;;;; Arrangement of frames at startup
64c669bc 210
7e573c4a
SM
211;; 1) Load the window system startup file from the lisp library and read the
212;; high-priority arguments (-q and the like). The window system startup
213;; file should create any frames specified in the window system defaults.
214;;
215;; 2) If no frames have been opened, we open an initial text frame.
216;;
217;; 3) Once the init file is done, we apply any newly set parameters
218;; in initial-frame-alist to the frame.
64c669bc 219
85557d7e 220;; These are now called explicitly at the proper times,
fc4d4afb
RS
221;; since that is easier to understand.
222;; Actually using hooks within Emacs is bad for future maintenance. --rms.
223;; (add-hook 'before-init-hook 'frame-initialize)
224;; (add-hook 'window-setup-hook 'frame-notice-user-settings)
64c669bc 225
7e573c4a 226;; If we create the initial frame, this is it.
dc6d9681 227(defvar frame-initial-frame nil)
64c669bc 228
3f2f8c83
RS
229;; Record the parameters used in frame-initialize to make the initial frame.
230(defvar frame-initial-frame-alist)
231
791e09d8
RS
232(defvar frame-initial-geometry-arguments nil)
233
7e573c4a
SM
234;; startup.el calls this function before loading the user's init
235;; file - if there is no frame with a minibuffer open now, create
236;; one to display messages while loading the init file.
dc6d9681 237(defun frame-initialize ()
ff2a1c79 238 "Create an initial frame if necessary."
64c669bc 239 ;; Are we actually running under a window system at all?
2246281f
KL
240 (if (and initial-window-system
241 (not noninteractive)
242 (not (eq initial-window-system 'pc)))
7eadab74
JB
243 (progn
244 ;; If there is no frame with a minibuffer besides the terminal
245 ;; frame, then we need to create the opening frame. Make sure
246 ;; it has a minibuffer, but let initial-frame-alist omit the
247 ;; minibuffer spec.
248 (or (delq terminal-frame (minibuffer-frame-list))
36fc9c9f 249 (progn
3f2f8c83 250 (setq frame-initial-frame-alist
9688894d 251 (append initial-frame-alist default-frame-alist nil))
a8bb5882
RS
252 (or (assq 'horizontal-scroll-bars frame-initial-frame-alist)
253 (setq frame-initial-frame-alist
254 (cons '(horizontal-scroll-bars . t)
255 frame-initial-frame-alist)))
2246281f
KL
256 (setq frame-initial-frame-alist
257 (cons (cons 'window-system initial-window-system)
258 frame-initial-frame-alist))
36fc9c9f
RS
259 (setq default-minibuffer-frame
260 (setq frame-initial-frame
96a84970 261 (make-frame frame-initial-frame-alist)))
11281034
RS
262 ;; Delete any specifications for window geometry parameters
263 ;; so that we won't reapply them in frame-notice-user-settings.
264 ;; It would be wrong to reapply them then,
265 ;; because that would override explicit user resizing.
58bf6042 266 (setq initial-frame-alist
c2079f0a 267 (frame-remove-geometry-params initial-frame-alist))))
a13f8f50
KL
268 ;; Copy the environment of the Emacs process into the new frame.
269 (set-frame-parameter frame-initial-frame 'environment
270 (frame-parameter terminal-frame 'environment))
85557d7e 271 ;; At this point, we know that we have a frame open, so we
dc6d9681
JB
272 ;; can delete the terminal frame.
273 (delete-frame terminal-frame)
2246281f 274 (setq terminal-frame nil))))
85557d7e 275
8f2a992b
GM
276(defvar frame-notice-user-settings t
277 "Non-nil means function `frame-notice-user-settings' wasn't run yet.")
278
aa360da1
GM
279(declare-function tool-bar-mode "tool-bar" (&optional arg))
280
7e573c4a
SM
281;; startup.el calls this function after loading the user's init
282;; file. Now default-frame-alist and initial-frame-alist contain
283;; information to which we must react; do what needs to be done.
dc6d9681 284(defun frame-notice-user-settings ()
40d34803 285 "Act on user's init file settings of frame parameters.
0e1bfc78
KL
286React to settings of `initial-frame-alist',
287`window-system-default-frame-alist' and `default-frame-alist'
288there (in decreasing order of priority)."
2ffa6186 289 ;; Make menu-bar-mode and default-frame-alist consistent.
61f2bcd7
GM
290 (when (boundp 'menu-bar-mode)
291 (let ((default (assq 'menu-bar-lines default-frame-alist)))
292 (if default
293 (setq menu-bar-mode (not (eq (cdr default) 0)))
294 (setq default-frame-alist
295 (cons (cons 'menu-bar-lines (if menu-bar-mode 1 0))
296 default-frame-alist)))))
f39784dd 297
33a33c06
GM
298 ;; Make tool-bar-mode and default-frame-alist consistent. Don't do
299 ;; it in batch mode since that would leave a tool-bar-lines
300 ;; parameter in default-frame-alist in a dumped Emacs, which is not
9688894d 301 ;; what we want.
33a33c06 302 (when (and (boundp 'tool-bar-mode)
095fe281 303 (not noninteractive))
61f2bcd7
GM
304 (let ((default (assq 'tool-bar-lines default-frame-alist)))
305 (if default
095fe281
KL
306 (setq tool-bar-mode (not (eq (cdr default) 0)))
307 ;; If Emacs was started on a tty, changing default-frame-alist
308 ;; would disable the toolbar on X frames created later. We
309 ;; want to keep the default of showing a toolbar under X even
310 ;; in this case.
311 ;;
312 ;; If the user explicitly called `tool-bar-mode' in .emacs,
313 ;; then default-frame-alist is already changed anyway.
314 (when initial-window-system
315 (setq default-frame-alist
316 (cons (cons 'tool-bar-lines (if tool-bar-mode 1 0))
317 default-frame-alist))))))
2ffa6186 318
7eadab74
JB
319 ;; Creating and deleting frames may shift the selected frame around,
320 ;; and thus the current buffer. Protect against that. We don't
321 ;; want to use save-excursion here, because that may also try to set
322 ;; the buffer of the selected window, which fails when the selected
323 ;; window is the minibuffer.
0e1bfc78 324 (let ((old-buffer (current-buffer))
cb01ce3f
SM
325 (window-system-frame-alist
326 (cdr (assq initial-window-system
327 window-system-default-frame-alist))))
7eadab74 328
8f2a992b
GM
329 (when (and frame-notice-user-settings
330 (null frame-initial-frame))
42002db5
EZ
331 ;; This case happens when we don't have a window system, and
332 ;; also for MS-DOS frames.
8f2a992b
GM
333 (let ((parms (frame-parameters frame-initial-frame)))
334 ;; Don't change the frame names.
335 (setq parms (delq (assq 'name parms) parms))
336 ;; Can't modify the minibuffer parameter, so don't try.
337 (setq parms (delq (assq 'minibuffer parms) parms))
338 (modify-frame-parameters nil
2246281f 339 (if (null initial-window-system)
42002db5 340 (append initial-frame-alist
0e1bfc78 341 window-system-frame-alist
42002db5
EZ
342 default-frame-alist
343 parms
344 nil)
345 ;; initial-frame-alist and
346 ;; default-frame-alist were already
347 ;; applied in pc-win.el.
348 parms))
2246281f 349 (if (null initial-window-system) ;; MS-DOS does this differently in pc-win.el
42002db5
EZ
350 (let ((newparms (frame-parameters))
351 (frame (selected-frame)))
352 (tty-handle-reverse-video frame newparms)
353 ;; If we changed the background color, we need to update
354 ;; the background-mode parameter, and maybe some faces,
355 ;; too.
356 (when (assq 'background-color newparms)
357 (unless (or (assq 'background-mode initial-frame-alist)
358 (assq 'background-mode default-frame-alist))
359 (frame-set-background-mode frame))
360 (face-set-after-frame-default frame))))))
8f2a992b 361
7eadab74
JB
362 ;; If the initial frame is still around, apply initial-frame-alist
363 ;; and default-frame-alist to it.
9688894d
GM
364 (when (frame-live-p frame-initial-frame)
365
366 ;; When tool-bar has been switched off, correct the frame size
367 ;; by the lines added in x-create-frame for the tool-bar and
368 ;; switch `tool-bar-mode' off.
085ef9b3
GM
369 (when (display-graphic-p)
370 (let ((tool-bar-lines (or (assq 'tool-bar-lines initial-frame-alist)
0e1bfc78 371 (assq 'tool-bar-lines window-system-frame-alist)
085ef9b3 372 (assq 'tool-bar-lines default-frame-alist))))
5c39a60f
JR
373 (when (and tool-bar-originally-present
374 (or (null tool-bar-lines)
375 (null (cdr tool-bar-lines))
376 (eq 0 (cdr tool-bar-lines))))
085ef9b3 377 (let* ((char-height (frame-char-height frame-initial-frame))
5c39a60f 378 (image-height tool-bar-images-pixel-height)
085ef9b3
GM
379 (margin (cond ((and (consp tool-bar-button-margin)
380 (integerp (cdr tool-bar-button-margin))
381 (> tool-bar-button-margin 0))
382 (cdr tool-bar-button-margin))
383 ((and (integerp tool-bar-button-margin)
384 (> tool-bar-button-margin 0))
385 tool-bar-button-margin)
386 (t 0)))
387 (relief (if (and (integerp tool-bar-button-relief)
388 (> tool-bar-button-relief 0))
389 tool-bar-button-relief 3))
f39784dd 390 (lines (/ (+ image-height
085ef9b3
GM
391 (* 2 margin)
392 (* 2 relief)
393 (1- char-height))
394 char-height))
395 (height (frame-parameter frame-initial-frame 'height))
396 (newparms (list (cons 'height (- height lines))))
f39784dd 397 (initial-top (cdr (assq 'top
085ef9b3
GM
398 frame-initial-geometry-arguments)))
399 (top (frame-parameter frame-initial-frame 'top)))
400 (when (and (consp initial-top) (eq '- (car initial-top)))
7f18ce22
RS
401 (let ((adjusted-top
402 (cond ((and (consp top)
403 (eq '+ (car top)))
404 (list '+
405 (+ (cadr top)
406 (* lines char-height))))
407 ((and (consp top)
408 (eq '- (car top)))
409 (list '-
410 (- (cadr top)
411 (* lines char-height))))
412 (t (+ top (* lines char-height))))))
413 (setq newparms
414 (append newparms
415 `((top . ,adjusted-top))
416 nil))))
085ef9b3
GM
417 (modify-frame-parameters frame-initial-frame newparms)
418 (tool-bar-mode -1)))))
9688894d
GM
419
420 ;; The initial frame we create above always has a minibuffer.
421 ;; If the user wants to remove it, or make it a minibuffer-only
422 ;; frame, then we'll have to delete the current frame and make a
423 ;; new one; you can't remove or add a root window to/from an
424 ;; existing frame.
425 ;;
426 ;; NOTE: default-frame-alist was nil when we created the
427 ;; existing frame. We need to explicitly include
428 ;; default-frame-alist in the parameters of the screen we
429 ;; create here, so that its new value, gleaned from the user's
430 ;; .emacs file, will be applied to the existing screen.
de2f5dbe 431 (if (not (eq (cdr (or (assq 'minibuffer initial-frame-alist)
0e1bfc78 432 (assq 'minibuffer window-system-frame-alist)
de2f5dbe
GM
433 (assq 'minibuffer default-frame-alist)
434 '(minibuffer . t)))
435 t))
436 ;; Create the new frame.
437 (let (parms new)
438 ;; If the frame isn't visible yet, wait till it is.
439 ;; If the user has to position the window,
440 ;; Emacs doesn't know its real position until
441 ;; the frame is seen to be visible.
442 (while (not (cdr (assq 'visibility
443 (frame-parameters frame-initial-frame))))
444 (sleep-for 1))
445 (setq parms (frame-parameters frame-initial-frame))
9688894d 446
f39784dd 447 ;; Get rid of `name' unless it was specified explicitly before.
de2f5dbe
GM
448 (or (assq 'name frame-initial-frame-alist)
449 (setq parms (delq (assq 'name parms) parms)))
2f5bb432
SM
450 ;; An explicit parent-id is a request to XEmbed the frame.
451 (or (assq 'parent-id frame-initial-frame-alist)
452 (setq parms (delq (assq 'parent-id parms) parms)))
de2f5dbe
GM
453
454 (setq parms (append initial-frame-alist
0e1bfc78 455 window-system-frame-alist
de2f5dbe
GM
456 default-frame-alist
457 parms
458 nil))
459
460 ;; Get rid of `reverse', because that was handled
461 ;; when we first made the frame.
462 (setq parms (cons '(reverse) (delq (assq 'reverse parms) parms)))
463
464 (if (assq 'height frame-initial-geometry-arguments)
465 (setq parms (assq-delete-all 'height parms)))
466 (if (assq 'width frame-initial-geometry-arguments)
467 (setq parms (assq-delete-all 'width parms)))
468 (if (assq 'left frame-initial-geometry-arguments)
469 (setq parms (assq-delete-all 'left parms)))
470 (if (assq 'top frame-initial-geometry-arguments)
471 (setq parms (assq-delete-all 'top parms)))
472 (setq new
473 (make-frame
474 ;; Use the geometry args that created the existing
475 ;; frame, rather than the parms we get for it.
476 (append frame-initial-geometry-arguments
477 '((user-size . t) (user-position . t))
478 parms)))
479 ;; The initial frame, which we are about to delete, may be
480 ;; the only frame with a minibuffer. If it is, create a
481 ;; new one.
482 (or (delq frame-initial-frame (minibuffer-frame-list))
483 (make-initial-minibuffer-frame nil))
484
485 ;; If the initial frame is serving as a surrogate
486 ;; minibuffer frame for any frames, we need to wean them
487 ;; onto a new frame. The default-minibuffer-frame
488 ;; variable must be handled similarly.
489 (let ((users-of-initial
490 (filtered-frame-list
b7de6024
SM
491 (lambda (frame)
492 (and (not (eq frame frame-initial-frame))
493 (eq (window-frame
494 (minibuffer-window frame))
495 frame-initial-frame))))))
496 (if (or users-of-initial
de2f5dbe
GM
497 (eq default-minibuffer-frame frame-initial-frame))
498
499 ;; Choose an appropriate frame. Prefer frames which
500 ;; are only minibuffers.
501 (let* ((new-surrogate
502 (car
503 (or (filtered-frame-list
b7de6024
SM
504 (lambda (frame)
505 (eq (cdr (assq 'minibuffer
506 (frame-parameters frame)))
507 'only)))
de2f5dbe
GM
508 (minibuffer-frame-list))))
509 (new-minibuffer (minibuffer-window new-surrogate)))
510
511 (if (eq default-minibuffer-frame frame-initial-frame)
512 (setq default-minibuffer-frame new-surrogate))
513
514 ;; Wean the frames using frame-initial-frame as
515 ;; their minibuffer frame.
b7de6024
SM
516 (dolist (frame users-of-initial)
517 (modify-frame-parameters
518 frame (list (cons 'minibuffer new-minibuffer)))))))
519
520 ;; Redirect events enqueued at this frame to the new frame.
de2f5dbe
GM
521 ;; Is this a good idea?
522 (redirect-frame-focus frame-initial-frame new)
523
524 ;; Finally, get rid of the old frame.
525 (delete-frame frame-initial-frame t))
9688894d
GM
526
527 ;; Otherwise, we don't need all that rigamarole; just apply
528 ;; the new parameters.
529 (let (newparms allparms tail)
530 (setq allparms (append initial-frame-alist
0e1bfc78 531 window-system-frame-alist
9688894d
GM
532 default-frame-alist nil))
533 (if (assq 'height frame-initial-geometry-arguments)
534 (setq allparms (assq-delete-all 'height allparms)))
535 (if (assq 'width frame-initial-geometry-arguments)
536 (setq allparms (assq-delete-all 'width allparms)))
537 (if (assq 'left frame-initial-geometry-arguments)
538 (setq allparms (assq-delete-all 'left allparms)))
539 (if (assq 'top frame-initial-geometry-arguments)
540 (setq allparms (assq-delete-all 'top allparms)))
541 (setq tail allparms)
542 ;; Find just the parms that have changed since we first
543 ;; made this frame. Those are the ones actually set by
f39784dd 544 ;; the init file. For those parms whose values we already knew
9688894d
GM
545 ;; (such as those spec'd by command line options)
546 ;; it is undesirable to specify the parm again
f39784dd 547 ;; once the user has seen the frame and been able to alter it
9688894d
GM
548 ;; manually.
549 (while tail
550 (let (newval oldval)
551 (setq oldval (assq (car (car tail))
552 frame-initial-frame-alist))
553 (setq newval (cdr (assq (car (car tail)) allparms)))
554 (or (and oldval (eq (cdr oldval) newval))
555 (setq newparms
556 (cons (cons (car (car tail)) newval) newparms))))
557 (setq tail (cdr tail)))
558 (setq newparms (nreverse newparms))
559 (modify-frame-parameters frame-initial-frame
560 newparms)
561 ;; If we changed the background color,
562 ;; we need to update the background-mode parameter
563 ;; and maybe some faces too.
564 (when (assq 'background-color newparms)
565 (unless (assq 'background-mode newparms)
566 (frame-set-background-mode frame-initial-frame))
567 (face-set-after-frame-default frame-initial-frame)))))
64c669bc 568
7eadab74
JB
569 ;; Restore the original buffer.
570 (set-buffer old-buffer)
571
572 ;; Make sure the initial frame can be GC'd if it is ever deleted.
d202f1f2 573 ;; Make sure frame-notice-user-settings does nothing if called twice.
8f2a992b 574 (setq frame-notice-user-settings nil)
d202f1f2 575 (setq frame-initial-frame nil)))
64c669bc 576
746bd265
KH
577(defun make-initial-minibuffer-frame (display)
578 (let ((parms (append minibuffer-frame-alist '((minibuffer . only)))))
579 (if display
580 (make-frame-on-display display parms)
581 (make-frame parms))))
582
7eadab74 583;;;; Creation of additional frames, and other frame miscellanea
dc6d9681 584
63019bad 585(defun modify-all-frames-parameters (alist)
d398de43 586 "Modify all current and future frames' parameters according to ALIST.
63019bad 587This changes `default-frame-alist' and possibly `initial-frame-alist'.
095fe281
KL
588Furthermore, this function removes all parameters in ALIST from
589`window-system-default-frame-alist'.
63019bad 590See help of `modify-frame-parameters' for more information."
095fe281
KL
591 (dolist (frame (frame-list))
592 (modify-frame-parameters frame alist))
593
594 (dolist (pair alist) ;; conses to add/replace
595 ;; initial-frame-alist needs setting only when
596 ;; frame-notice-user-settings is true.
597 (and frame-notice-user-settings
598 (setq initial-frame-alist
599 (assq-delete-all (car pair) initial-frame-alist)))
600 (setq default-frame-alist
601 (assq-delete-all (car pair) default-frame-alist))
602 ;; Remove any similar settings from the window-system specific
603 ;; parameters---they would override default-frame-alist.
604 (dolist (w window-system-default-frame-alist)
605 (setcdr w (assq-delete-all (car pair) (cdr w)))))
606
63019bad
JB
607 (and frame-notice-user-settings
608 (setq initial-frame-alist (append initial-frame-alist alist)))
609 (setq default-frame-alist (append default-frame-alist alist)))
610
7253d8e0 611(defun get-other-frame ()
40d34803
DL
612 "Return some frame other than the current frame.
613Create one if necessary. Note that the minibuffer frame, if separate,
614is not considered (see `next-frame')."
dc6d9681 615 (let ((s (if (equal (next-frame (selected-frame)) (selected-frame))
6eb018ba 616 (make-frame)
dc6d9681 617 (next-frame (selected-frame)))))
64c669bc
JB
618 s))
619
dc6d9681
JB
620(defun next-multiframe-window ()
621 "Select the next window, regardless of which frame it is on."
64c669bc
JB
622 (interactive)
623 (select-window (next-window (selected-window)
624 (> (minibuffer-depth) 0)
bb2c34b1 625 0))
030f4537 626 (select-frame-set-input-focus (selected-frame)))
64c669bc 627
dc6d9681
JB
628(defun previous-multiframe-window ()
629 "Select the previous window, regardless of which frame it is on."
64c669bc
JB
630 (interactive)
631 (select-window (previous-window (selected-window)
632 (> (minibuffer-depth) 0)
bb2c34b1 633 0))
030f4537 634 (select-frame-set-input-focus (selected-frame)))
64c669bc 635
bbf6ef44 636(declare-function x-initialize-window-system "term/x-win" ())
4c1863cd 637(declare-function ns-initialize-window-system "term/ns-win" ())
5f9214ee 638(defvar x-display-name) ; term/x-win
bbf6ef44 639
6d73e337 640(defun make-frame-on-display (display &optional parameters)
c5a8bc01
CY
641 "Make a frame on display DISPLAY.
642The optional argument PARAMETERS specifies additional frame parameters."
6d73e337 643 (interactive "sMake frame on display: ")
c5a8bc01
CY
644 (cond ((featurep 'ns)
645 (when (and (boundp 'ns-initialized) (not ns-initialized))
646 (setq x-display-name display)
647 (ns-initialize-window-system))
648 (make-frame `((window-system . ns)
649 (display . ,display) . ,parameters)))
650 ((eq system-type 'windows-nt)
651 ;; On Windows, ignore DISPLAY.
652 (make-frame parameters))
653 (t
69135f12 654 (unless (string-match-p "\\`[^:]*:[0-9]+\\(\\.[0-9]+\\)?\\'" display)
c5a8bc01
CY
655 (error "Invalid display, not HOST:SERVER or HOST:SERVER.SCREEN"))
656 (when (and (boundp 'x-initialized) (not x-initialized))
657 (setq x-display-name display)
658 (x-initialize-window-system))
659 (make-frame `((window-system . x)
660 (display . ,display) . ,parameters)))))
6d73e337 661
aa360da1
GM
662(declare-function x-close-connection "xfns.c" (terminal))
663
b7de6024
SM
664(defun close-display-connection (display)
665 "Close the connection to a display, deleting all its associated frames.
666For DISPLAY, specify either a frame or a display name (a string).
667If DISPLAY is nil, that stands for the selected frame's display."
668 (interactive
669 (list
670 (let* ((default (frame-parameter nil 'display))
671 (display (completing-read
672 (format "Close display (default %s): " default)
673 (delete-dups
674 (mapcar (lambda (frame)
675 (frame-parameter frame 'display))
676 (frame-list)))
677 nil t nil nil
678 default)))
679 (if (zerop (length display)) default display))))
680 (let ((frames (delq nil
681 (mapcar (lambda (frame)
682 (if (equal display
683 (frame-parameter frame 'display))
684 frame))
685 (frame-list)))))
686 (if (and (consp frames)
687 (not (y-or-n-p (if (cdr frames)
688 (format "Delete %s frames? " (length frames))
689 (format "Delete %s ? " (car frames))))))
690 (error "Abort!")
691 (mapc 'delete-frame frames)
692 (x-close-connection display))))
693
6238bfaf 694(defun make-frame-command ()
e9e6aee8
CY
695 "Make a new frame, on the same terminal as the selected frame.
696If the terminal is a text-only terminal, this also selects the
697new frame."
6238bfaf 698 (interactive)
e9e6aee8 699 (if (display-graphic-p)
6238bfaf
RS
700 (make-frame)
701 (select-frame (make-frame))))
702
45c4fdeb
SM
703(defvar before-make-frame-hook nil
704 "Functions to run before a frame is created.")
705
706(defvar after-make-frame-functions nil
707 "Functions to run after a frame is created.
708The functions are run with one arg, the newly created frame.")
709
72bf1a8b 710(defvar after-setting-font-hook nil
81b99826
GM
711 "Functions to run after a frame's font has been changed.")
712
92e443b1 713;; Alias, kept temporarily.
84ed1560 714(define-obsolete-function-alias 'new-frame 'make-frame "22.1")
bc93c097 715
9e483377 716(defvar frame-inherited-parameters '()
ab6198b2
SM
717 ;; FIXME: Shouldn't we add `font' here as well?
718 "Parameters `make-frame' copies from the `selected-frame' to the new frame.")
719
45c4fdeb
SM
720(defun make-frame (&optional parameters)
721 "Return a newly created frame displaying the current buffer.
722Optional argument PARAMETERS is an alist of parameters for the new frame.
723Each element of PARAMETERS should have the form (NAME . VALUE), for example:
a105105a 724
45c4fdeb 725 (name . STRING) The frame should be named STRING.
43a2e52c 726
45c4fdeb
SM
727 (width . NUMBER) The frame should be NUMBER characters in width.
728 (height . NUMBER) The frame should be NUMBER text lines high.
43a2e52c 729
45c4fdeb 730You cannot specify either `width' or `height', you must use neither or both.
43a2e52c 731
45c4fdeb
SM
732 (minibuffer . t) The frame should have a minibuffer.
733 (minibuffer . nil) The frame should have no minibuffer.
734 (minibuffer . only) The frame should contain only a minibuffer.
735 (minibuffer . WINDOW) The frame should use WINDOW as its minibuffer window.
43a2e52c 736
2246281f
KL
737 (window-system . nil) The frame should be displayed on a terminal device.
738 (window-system . x) The frame should be displayed in an X window.
739
d51f6378 740 (terminal . TERMINAL) The frame should use the terminal object TERMINAL.
b6660415 741
2246281f 742Before the frame is created (via `frame-creation-function-alist'), functions on the
45c4fdeb 743hook `before-make-frame-hook' are run. After the frame is created, functions
8de9d3f6
LT
744on `after-make-frame-functions' are run with one arg, the newly created frame.
745
746This function itself does not make the new frame the selected frame.
747The previously selected frame remains selected. However, the
748window system may select the new frame for its own reasons, for
749instance if the frame appears under the mouse pointer and your
750setup is for focus to follow the pointer."
64c669bc 751 (interactive)
b6660415 752 (let* ((w (cond
6ed8eeff
KL
753 ((assq 'terminal parameters)
754 (let ((type (terminal-live-p (cdr (assq 'terminal parameters)))))
b6660415
KL
755 (cond
756 ((eq type t) nil)
cb01ce3f
SM
757 ((eq type nil) (error "Terminal %s does not exist"
758 (cdr (assq 'terminal parameters))))
b6660415
KL
759 (t type))))
760 ((assq 'window-system parameters)
761 (cdr (assq 'window-system parameters)))
762 (t window-system)))
2246281f 763 (frame-creation-function (cdr (assq w frame-creation-function-alist)))
da8e8fc1 764 (oldframe (selected-frame))
2246281f
KL
765 frame)
766 (unless frame-creation-function
767 (error "Don't know how to create a frame on window system %s" w))
768 (run-hooks 'before-make-frame-hook)
cb01ce3f
SM
769 (setq frame
770 (funcall frame-creation-function
771 (append parameters
772 (cdr (assq w window-system-default-frame-alist)))))
30a2fded 773 (normal-erase-is-backspace-setup-frame frame)
ab6198b2
SM
774 ;; Inherit the original frame's parameters.
775 (dolist (param frame-inherited-parameters)
776 (unless (assq param parameters) ;Overridden by explicit parameters.
777 (let ((val (frame-parameter oldframe param)))
778 (when val (set-frame-parameter frame param val)))))
45c4fdeb
SM
779 (run-hook-with-args 'after-make-frame-functions frame)
780 frame))
64c669bc 781
7eadab74
JB
782(defun filtered-frame-list (predicate)
783 "Return a list of all live frames which satisfy PREDICATE."
047bc928
GM
784 (let* ((frames (frame-list))
785 (list frames))
7eadab74 786 (while (consp frames)
047bc928
GM
787 (unless (funcall predicate (car frames))
788 (setcar frames nil))
7eadab74 789 (setq frames (cdr frames)))
047bc928 790 (delq nil list)))
7eadab74
JB
791
792(defun minibuffer-frame-list ()
793 "Return a list of all frames with their own minibuffers."
794 (filtered-frame-list
b7de6024
SM
795 (lambda (frame)
796 (eq frame (window-frame (minibuffer-window frame))))))
7eadab74 797
371fed4e
SM
798;; Used to be called `terminal-id' in termdev.el.
799(defun get-device-terminal (device)
800 "Return the terminal corresponding to DEVICE.
801DEVICE can be a terminal, a frame, nil (meaning the selected frame's terminal),
802the name of an X display device (HOST.SERVER.SCREEN) or a tty device file."
803 (cond
804 ((or (null device) (framep device))
805 (frame-terminal device))
806 ((stringp device)
807 (let ((f (car (filtered-frame-list
808 (lambda (frame)
809 (or (equal (frame-parameter frame 'display) device)
810 (equal (frame-parameter frame 'tty) device)))))))
811 (or f (error "Display %s does not exist" device))
812 (frame-terminal f)))
813 ((terminal-live-p device) device)
814 (t
815 (error "Invalid argument %s in `get-device-terminal'" device))))
816
817(defun frames-on-display-list (&optional device)
818 "Return a list of all frames on DEVICE.
819
820DEVICE should be a terminal, a frame,
821or a name of an X display or tty (a string of the form
9684e4c9 822HOST:SERVER.SCREEN).
b6660415 823
371fed4e 824If DEVICE is omitted or nil, it defaults to the selected
9684e4c9 825frame's terminal device."
371fed4e 826 (let* ((terminal (get-device-terminal device))
047bc928 827 (func #'(lambda (frame)
6ed8eeff 828 (eq (frame-terminal frame) terminal))))
9911648b
EZ
829 (filtered-frame-list func)))
830
f35ca2fe
KL
831(defun framep-on-display (&optional terminal)
832 "Return the type of frames on TERMINAL.
833TERMINAL may be a terminal id, a display name or a frame. If it
834is a frame, its type is returned. If TERMINAL is omitted or nil,
835it defaults to the selected frame's terminal device. All frames
836on a given display are of the same type."
6ed8eeff 837 (or (terminal-live-p terminal)
f35ca2fe
KL
838 (framep terminal)
839 (framep (car (frames-on-display-list terminal)))))
9911648b 840
58bf6042
JB
841(defun frame-remove-geometry-params (param-list)
842 "Return the parameter list PARAM-LIST, but with geometry specs removed.
843This deletes all bindings in PARAM-LIST for `top', `left', `width',
791e09d8 844`height', `user-size' and `user-position' parameters.
58bf6042
JB
845Emacs uses this to avoid overriding explicit moves and resizings from
846the user during startup."
847 (setq param-list (cons nil param-list))
848 (let ((tail param-list))
849 (while (consp (cdr tail))
850 (if (and (consp (car (cdr tail)))
791e09d8
RS
851 (memq (car (car (cdr tail)))
852 '(height width top left user-position user-size)))
853 (progn
854 (setq frame-initial-geometry-arguments
855 (cons (car (cdr tail)) frame-initial-geometry-arguments))
856 (setcdr tail (cdr (cdr tail))))
58bf6042 857 (setq tail (cdr tail)))))
e11c3dc2
KH
858 (setq frame-initial-geometry-arguments
859 (nreverse frame-initial-geometry-arguments))
58bf6042
JB
860 (cdr param-list))
861
aa360da1
GM
862(declare-function x-focus-frame "xfns.c" (frame))
863
030f4537 864(defun select-frame-set-input-focus (frame)
bbca16d8 865 "Select FRAME, raise it, and set input focus, if possible.
e343066f 866If `mouse-autoselect-window' is non-nil, also move mouse pointer
bbca16d8
MR
867to FRAME's selected window. Otherwise, if `focus-follows-mouse'
868is non-nil, move mouse cursor to FRAME."
b0c7121c
MR
869 (select-frame frame)
870 (raise-frame frame)
bbca16d8 871 ;; Ensure, if possible, that FRAME gets input focus.
b0c7121c
MR
872 (when (memq (window-system frame) '(x w32 ns))
873 (x-focus-frame frame))
bbca16d8
MR
874 ;; Move mouse cursor if necessary.
875 (cond
876 (mouse-autoselect-window
877 (let ((edges (window-inside-edges (frame-selected-window frame))))
878 ;; Move mouse cursor into FRAME's selected window to avoid that
879 ;; Emacs mouse-autoselects another window.
880 (set-mouse-position frame (nth 2 edges) (nth 1 edges))))
881 (focus-follows-mouse
882 ;; Move mouse cursor into FRAME to avoid that another frame gets
883 ;; selected by the window manager.
884 (set-mouse-position frame (1- (frame-width frame)) 0))))
030f4537 885
ceab6935 886(defun other-frame (arg)
c2c93894 887 "Select the ARGth different visible frame on current display, and raise it.
ceab6935
RM
888All frames are arranged in a cyclic order.
889This command selects the frame ARG steps away in that order.
bb578a72
RS
890A negative ARG moves in the opposite order.
891
892To make this command work properly, you must tell Emacs
893how the system (or the window manager) generally handles
894focus-switching between windows. If moving the mouse onto a window
895selects it (gives it focus), set `focus-follows-mouse' to t.
896Otherwise, that variable should be nil."
ceab6935
RM
897 (interactive "p")
898 (let ((frame (selected-frame)))
899 (while (> arg 0)
a569dbc3
RM
900 (setq frame (next-frame frame))
901 (while (not (eq (frame-visible-p frame) t))
902 (setq frame (next-frame frame)))
903 (setq arg (1- arg)))
ceab6935 904 (while (< arg 0)
a569dbc3
RM
905 (setq frame (previous-frame frame))
906 (while (not (eq (frame-visible-p frame) t))
907 (setq frame (previous-frame frame)))
915cfd1f 908 (setq arg (1+ arg)))
030f4537 909 (select-frame-set-input-focus frame)))
845cde06 910
3db7df06
SM
911(defun iconify-or-deiconify-frame ()
912 "Iconify the selected frame, or deiconify if it's currently an icon."
913 (interactive)
914 (if (eq (cdr (assq 'visibility (frame-parameters))) t)
915 (iconify-frame)
916 (make-frame-visible)))
917
0b0d3e0b
KL
918(defun suspend-frame ()
919 "Do whatever is right to suspend the current frame.
f35ca2fe
KL
920Calls `suspend-emacs' if invoked from the controlling tty device,
921`suspend-tty' from a secondary tty device, and
0b0d3e0b
KL
922`iconify-or-deiconify-frame' from an X frame."
923 (interactive)
924 (let ((type (framep (selected-frame))))
925 (cond
edfda783 926 ((memq type '(x ns w32)) (iconify-or-deiconify-frame))
0b0d3e0b 927 ((eq type t)
6ed8eeff 928 (if (controlling-tty-p)
4a933ef8
KL
929 (suspend-emacs)
930 (suspend-tty)))
0b0d3e0b
KL
931 (t (suspend-emacs)))))
932
845cde06
EZ
933(defun make-frame-names-alist ()
934 (let* ((current-frame (selected-frame))
935 (falist
936 (cons
937 (cons (frame-parameter current-frame 'name) current-frame) nil))
938 (frame (next-frame nil t)))
939 (while (not (eq frame current-frame))
940 (progn
941 (setq falist (cons (cons (frame-parameter frame 'name) frame) falist))
942 (setq frame (next-frame frame t))))
943 falist))
944
945(defvar frame-name-history nil)
845cde06 946(defun select-frame-by-name (name)
563283b1 947 "Select the frame on the current terminal whose name is NAME and raise it.
845cde06
EZ
948If there is no frame by that name, signal an error."
949 (interactive
716ff1c9
RS
950 (let* ((frame-names-alist (make-frame-names-alist))
951 (default (car (car frame-names-alist)))
952 (input (completing-read
953 (format "Select Frame (default %s): " default)
954 frame-names-alist nil t nil 'frame-name-history)))
845cde06
EZ
955 (if (= (length input) 0)
956 (list default)
957 (list input))))
716ff1c9
RS
958 (let* ((frame-names-alist (make-frame-names-alist))
959 (frame (cdr (assoc name frame-names-alist))))
bbca16d8
MR
960 (if frame
961 (select-frame-set-input-focus frame)
962 (error "There is no frame named `%s'" name))))
64c669bc 963\f
dc6d9681
JB
964;;;; Frame configurations
965
966(defun current-frame-configuration ()
967 "Return a list describing the positions and states of all frames.
376a7584
JB
968Its car is `frame-configuration'.
969Each element of the cdr is a list of the form (FRAME ALIST WINDOW-CONFIG),
970where
971 FRAME is a frame object,
972 ALIST is an association list specifying some of FRAME's parameters, and
973 WINDOW-CONFIG is a window configuration object for FRAME."
974 (cons 'frame-configuration
b7de6024
SM
975 (mapcar (lambda (frame)
976 (list frame
977 (frame-parameters frame)
978 (current-window-configuration frame)))
376a7584 979 (frame-list))))
dc6d9681 980
68cd265f 981(defun set-frame-configuration (configuration &optional nodelete)
dc6d9681
JB
982 "Restore the frames to the state described by CONFIGURATION.
983Each frame listed in CONFIGURATION has its position, size, window
68cd265f 984configuration, and other parameters set as specified in CONFIGURATION.
d398de43
LT
985However, this function does not restore deleted frames.
986
a78db71c
RS
987Ordinarily, this function deletes all existing frames not
988listed in CONFIGURATION. But if optional second argument NODELETE
5da841d2 989is given and non-nil, the unwanted frames are iconified instead."
376a7584
JB
990 (or (frame-configuration-p configuration)
991 (signal 'wrong-type-argument
992 (list 'frame-configuration-p configuration)))
993 (let ((config-alist (cdr configuration))
994 frames-to-delete)
b7de6024
SM
995 (dolist (frame (frame-list))
996 (let ((parameters (assq frame config-alist)))
997 (if parameters
998 (progn
999 (modify-frame-parameters
1000 frame
1001 ;; Since we can't set a frame's minibuffer status,
1002 ;; we might as well omit the parameter altogether.
1003 (let* ((parms (nth 1 parameters))
b2529d56
MB
1004 (mini (assq 'minibuffer parms))
1005 (name (assq 'name parms))
1006 (explicit-name (cdr (assq 'explicit-name parms))))
1007 (when mini (setq parms (delq mini parms)))
1008 ;; Leave name in iff it was set explicitly.
1009 ;; This should fix the behavior reported in
1010 ;; http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg01632.html
1011 (when (and name (not explicit-name))
1012 (setq parms (delq name parms)))
b7de6024
SM
1013 parms))
1014 (set-window-configuration (nth 2 parameters)))
1015 (setq frames-to-delete (cons frame frames-to-delete)))))
1016 (mapc (if nodelete
1017 ;; Note: making frames invisible here was tried
1018 ;; but led to some strange behavior--each time the frame
1019 ;; was made visible again, the window manager asked afresh
1020 ;; for where to put it.
1021 'iconify-frame
1022 'delete-frame)
1023 frames-to-delete)))
64c669bc 1024\f
dc6d9681
JB
1025;;;; Convenience functions for accessing and interactively changing
1026;;;; frame parameters.
64c669bc 1027
151bdc83 1028(defun frame-height (&optional frame)
dc6d9681
JB
1029 "Return number of lines available for display on FRAME.
1030If FRAME is omitted, describe the currently selected frame."
151bdc83 1031 (cdr (assq 'height (frame-parameters frame))))
dc6d9681
JB
1032
1033(defun frame-width (&optional frame)
1034 "Return number of columns available for display on FRAME.
1035If FRAME is omitted, describe the currently selected frame."
151bdc83 1036 (cdr (assq 'width (frame-parameters frame))))
dc6d9681 1037
aa360da1
GM
1038(declare-function x-list-fonts "xfaces.c"
1039 (pattern &optional face frame maximum width))
1040
52ef9375 1041(define-obsolete-function-alias 'set-default-font 'set-frame-font "23.1")
1cef6541 1042(defun set-frame-font (font-name &optional keep-size)
40d34803 1043 "Set the font of the selected frame to FONT-NAME.
61298010 1044When called interactively, prompt for the name of the font to use.
1cef6541
JB
1045To get the frame's current default font, use `frame-parameters'.
1046
1047The default behavior is to keep the numbers of lines and columns in
84ed1560 1048the frame, thus may change its pixel size. If optional KEEP-SIZE is
1cef6541
JB
1049non-nil (interactively, prefix argument) the current frame size (in
1050pixels) is kept by adjusting the numbers of the lines and columns."
f39784dd 1051 (interactive
1cef6541
JB
1052 (let* ((completion-ignore-case t)
1053 (font (completing-read "Font name: "
1cef6541
JB
1054 ;; x-list-fonts will fail with an error
1055 ;; if this frame doesn't support fonts.
b7de6024
SM
1056 (x-list-fonts "*" nil (selected-frame))
1057 nil nil nil nil
1058 (frame-parameter nil 'font))))
1cef6541
JB
1059 (list font current-prefix-arg)))
1060 (let (fht fwd)
1061 (if keep-size
1062 (setq fht (* (frame-parameter nil 'height) (frame-char-height))
1063 fwd (* (frame-parameter nil 'width) (frame-char-width))))
1064 (modify-frame-parameters (selected-frame)
1065 (list (cons 'font font-name)))
1066 (if keep-size
1067 (modify-frame-parameters
1068 (selected-frame)
1069 (list (cons 'height (round fht (frame-char-height)))
1070 (cons 'width (round fwd (frame-char-width)))))))
72bf1a8b 1071 (run-hooks 'after-setting-font-hook 'after-setting-font-hooks))
64c669bc 1072
7e573c4a 1073(defun set-frame-parameter (frame parameter value)
0dac35b8
KL
1074 "Set frame parameter PARAMETER to VALUE on FRAME.
1075If FRAME is nil, it defaults to the selected frame.
c2c93894 1076See `modify-frame-parameters'."
7e573c4a
SM
1077 (modify-frame-parameters frame (list (cons parameter value))))
1078
8290babd 1079(defun set-background-color (color-name)
40d34803 1080 "Set the background color of the selected frame to COLOR-NAME.
61298010
RS
1081When called interactively, prompt for the name of the color to use.
1082To get the frame's current background color, use `frame-parameters'."
63ec4f94 1083 (interactive (list (facemenu-read-color "Background color: ")))
dc6d9681 1084 (modify-frame-parameters (selected-frame)
528e1416
EZ
1085 (list (cons 'background-color color-name)))
1086 (or window-system
1087 (face-set-after-frame-default (selected-frame))))
64c669bc 1088
8290babd 1089(defun set-foreground-color (color-name)
40d34803 1090 "Set the foreground color of the selected frame to COLOR-NAME.
61298010
RS
1091When called interactively, prompt for the name of the color to use.
1092To get the frame's current foreground color, use `frame-parameters'."
63ec4f94 1093 (interactive (list (facemenu-read-color "Foreground color: ")))
dc6d9681 1094 (modify-frame-parameters (selected-frame)
528e1416
EZ
1095 (list (cons 'foreground-color color-name)))
1096 (or window-system
1097 (face-set-after-frame-default (selected-frame))))
64c669bc
JB
1098
1099(defun set-cursor-color (color-name)
40d34803 1100 "Set the text cursor color of the selected frame to COLOR-NAME.
61298010
RS
1101When called interactively, prompt for the name of the color to use.
1102To get the frame's current cursor color, use `frame-parameters'."
63ec4f94 1103 (interactive (list (facemenu-read-color "Cursor color: ")))
dc6d9681 1104 (modify-frame-parameters (selected-frame)
7eadab74 1105 (list (cons 'cursor-color color-name))))
64c669bc 1106
eaa974e1 1107(defun set-mouse-color (color-name)
40d34803 1108 "Set the color of the mouse pointer of the selected frame to COLOR-NAME.
61298010
RS
1109When called interactively, prompt for the name of the color to use.
1110To get the frame's current mouse color, use `frame-parameters'."
63ec4f94 1111 (interactive (list (facemenu-read-color "Mouse color: ")))
dc6d9681 1112 (modify-frame-parameters (selected-frame)
ec6d4463
KH
1113 (list (cons 'mouse-color
1114 (or color-name
1115 (cdr (assq 'mouse-color
1116 (frame-parameters))))))))
7eadab74 1117
eaa974e1 1118(defun set-border-color (color-name)
40d34803 1119 "Set the color of the border of the selected frame to COLOR-NAME.
61298010
RS
1120When called interactively, prompt for the name of the color to use.
1121To get the frame's current border color, use `frame-parameters'."
63ec4f94 1122 (interactive (list (facemenu-read-color "Border color: ")))
eaa974e1
JB
1123 (modify-frame-parameters (selected-frame)
1124 (list (cons 'border-color color-name))))
1125
1126(defun auto-raise-mode (arg)
7eadab74 1127 "Toggle whether or not the selected frame should auto-raise.
6cda144f 1128With ARG, turn auto-raise mode on if and only if ARG is positive.
79e6ae33
RS
1129Note that this controls Emacs's own auto-raise feature.
1130Some window managers allow you to enable auto-raise for certain windows.
1131You can use that for Emacs windows if you wish, but if you do,
1132that is beyond the control of Emacs and this command has no effect on it."
7eadab74
JB
1133 (interactive "P")
1134 (if (null arg)
1135 (setq arg
1136 (if (cdr (assq 'auto-raise (frame-parameters (selected-frame))))
1137 -1 1)))
9626b928
GM
1138 (if (> arg 0)
1139 (raise-frame (selected-frame)))
dc6d9681 1140 (modify-frame-parameters (selected-frame)
7eadab74
JB
1141 (list (cons 'auto-raise (> arg 0)))))
1142
eaa974e1 1143(defun auto-lower-mode (arg)
7eadab74 1144 "Toggle whether or not the selected frame should auto-lower.
6cda144f 1145With ARG, turn auto-lower mode on if and only if ARG is positive.
79e6ae33
RS
1146Note that this controls Emacs's own auto-lower feature.
1147Some window managers allow you to enable auto-lower for certain windows.
1148You can use that for Emacs windows if you wish, but if you do,
1149that is beyond the control of Emacs and this command has no effect on it."
7eadab74
JB
1150 (interactive "P")
1151 (if (null arg)
1152 (setq arg
1153 (if (cdr (assq 'auto-lower (frame-parameters (selected-frame))))
1154 -1 1)))
dc6d9681 1155 (modify-frame-parameters (selected-frame)
7eadab74 1156 (list (cons 'auto-lower (> arg 0)))))
7777d03b
EZ
1157(defun set-frame-name (name)
1158 "Set the name of the selected frame to NAME.
1159When called interactively, prompt for the name of the frame.
1160The frame name is displayed on the modeline if the terminal displays only
1161one frame, otherwise the name is displayed on the frame's caption bar."
1162 (interactive "sFrame name: ")
1163 (modify-frame-parameters (selected-frame)
1164 (list (cons 'name name))))
56cfea72
KS
1165
1166(defun frame-current-scroll-bars (&optional frame)
1167 "Return the current scroll-bar settings in frame FRAME.
1cecf04d 1168Value is a cons (VERTICAL . HORIZ0NTAL) where VERTICAL specifies the
56cfea72 1169current location of the vertical scroll-bars (left, right, or nil),
1cecf04d 1170and HORIZONTAL specifies the current location of the horizontal scroll
56cfea72
KS
1171bars (top, bottom, or nil)."
1172 (let ((vert (frame-parameter frame 'vertical-scroll-bars))
1173 (hor nil))
1174 (unless (memq vert '(left right nil))
1175 (setq vert default-frame-scroll-bars))
1176 (cons vert hor)))
64c669bc 1177\f
9911648b 1178;;;; Frame/display capabilities.
6ed8eeff
KL
1179(defun selected-terminal ()
1180 "Return the terminal that is now selected."
1181 (frame-terminal (selected-frame)))
b6660415 1182
73e6adaa
DN
1183(declare-function msdos-mouse-p "dosfns.c")
1184
9911648b
EZ
1185(defun display-mouse-p (&optional display)
1186 "Return non-nil if DISPLAY has a mouse available.
1187DISPLAY can be a display name, a frame, or nil (meaning the selected
1188frame's display)."
1189 (let ((frame-type (framep-on-display display)))
1190 (cond
1191 ((eq frame-type 'pc)
1192 (msdos-mouse-p))
1193 ((eq system-type 'windows-nt)
9fa5bb32
RS
1194 (with-no-warnings
1195 (> w32-num-mouse-buttons 0)))
9e2a2647
DN
1196 ((memq frame-type '(x ns))
1197 t) ;; We assume X and NeXTstep *always* have a pointing device
9911648b 1198 (t
7565ee93
DL
1199 (or (and (featurep 'xt-mouse)
1200 xterm-mouse-mode)
1201 ;; t-mouse is distributed with the GPM package. It doesn't have
1202 ;; a toggle.
1203 (featurep 't-mouse))))))
9911648b
EZ
1204
1205(defun display-popup-menus-p (&optional display)
1206 "Return non-nil if popup menus are supported on DISPLAY.
1207DISPLAY can be a display name, a frame, or nil (meaning the selected
1208frame's display).
1209Support for popup menus requires that the mouse be available."
1210 (and
1211 (let ((frame-type (framep-on-display display)))
9e2a2647 1212 (memq frame-type '(x w32 pc ns)))
9911648b
EZ
1213 (display-mouse-p display)))
1214
1215(defun display-graphic-p (&optional display)
1216 "Return non-nil if DISPLAY is a graphic display.
1217Graphical displays are those which are capable of displaying several
1218frames and several different fonts at once. This is true for displays
1219that use a window system such as X, and false for text-only terminals.
1220DISPLAY can be a display name, a frame, or nil (meaning the selected
1221frame's display)."
9e2a2647 1222 (not (null (memq (framep-on-display display) '(x w32 ns)))))
9911648b 1223
ddc456e4
EZ
1224(defun display-images-p (&optional display)
1225 "Return non-nil if DISPLAY can display images.
1226
1227DISPLAY can be a display name, a frame, or nil (meaning the selected
1228frame's display)."
1229 (and (display-graphic-p display)
1230 (fboundp 'image-mask-p)
fcc6f5cc 1231 (fboundp 'image-size)))
ddc456e4 1232
6693b279
EZ
1233(defalias 'display-multi-frame-p 'display-graphic-p)
1234(defalias 'display-multi-font-p 'display-graphic-p)
1235
9911648b
EZ
1236(defun display-selections-p (&optional display)
1237 "Return non-nil if DISPLAY supports selections.
1238A selection is a way to transfer text or other data between programs
1239via special system buffers called `selection' or `cut buffer' or
1240`clipboard'.
1241DISPLAY can be a display name, a frame, or nil (meaning the selected
1242frame's display)."
1243 (let ((frame-type (framep-on-display display)))
1244 (cond
1245 ((eq frame-type 'pc)
1246 ;; MS-DOG frames support selections when Emacs runs inside
1247 ;; the Windows' DOS Box.
9fa5bb32
RS
1248 (with-no-warnings
1249 (not (null dos-windows-version))))
9e2a2647 1250 ((memq frame-type '(x w32 ns))
9911648b
EZ
1251 t) ;; FIXME?
1252 (t
1253 nil))))
1254
aa360da1
GM
1255(declare-function x-display-screens "xfns.c" (&optional terminal))
1256
9911648b
EZ
1257(defun display-screens (&optional display)
1258 "Return the number of screens associated with DISPLAY."
1259 (let ((frame-type (framep-on-display display)))
1260 (cond
9e2a2647 1261 ((memq frame-type '(x w32 ns))
9911648b 1262 (x-display-screens display))
bb9404d6 1263 (t
9911648b
EZ
1264 1))))
1265
aa360da1
GM
1266(declare-function x-display-pixel-height "xfns.c" (&optional terminal))
1267
9911648b
EZ
1268(defun display-pixel-height (&optional display)
1269 "Return the height of DISPLAY's screen in pixels.
1270For character terminals, each character counts as a single pixel."
1271 (let ((frame-type (framep-on-display display)))
1272 (cond
9e2a2647 1273 ((memq frame-type '(x w32 ns))
9911648b
EZ
1274 (x-display-pixel-height display))
1275 (t
1276 (frame-height (if (framep display) display (selected-frame)))))))
1277
aa360da1
GM
1278(declare-function x-display-pixel-width "xfns.c" (&optional terminal))
1279
9911648b
EZ
1280(defun display-pixel-width (&optional display)
1281 "Return the width of DISPLAY's screen in pixels.
1282For character terminals, each character counts as a single pixel."
1283 (let ((frame-type (framep-on-display display)))
1284 (cond
9e2a2647 1285 ((memq frame-type '(x w32 ns))
9911648b
EZ
1286 (x-display-pixel-width display))
1287 (t
1288 (frame-width (if (framep display) display (selected-frame)))))))
1289
51e39dfc
KS
1290(defcustom display-mm-dimensions-alist nil
1291 "Alist for specifying screen dimensions in millimeters.
1292The dimensions will be used for `display-mm-height' and
1293`display-mm-width' if defined for the respective display.
1294
1295Each element of the alist has the form (display . (width . height)),
1296e.g. (\":0.0\" . (287 . 215)).
1297
1298If `display' equals t, it specifies dimensions for all graphical
1299displays not explicitely specified."
1300 :version "22.1"
1301 :type '(alist :key-type (choice (string :tag "Display name")
1302 (const :tag "Default" t))
1303 :value-type (cons :tag "Dimensions"
1304 (integer :tag "Width")
1305 (integer :tag "Height")))
1306 :group 'frames)
1307
aa360da1
GM
1308(declare-function x-display-mm-height "xfns.c" (&optional terminal))
1309
9911648b
EZ
1310(defun display-mm-height (&optional display)
1311 "Return the height of DISPLAY's screen in millimeters.
d7cd2d8b 1312System values can be overridden by `display-mm-dimensions-alist'.
9911648b 1313If the information is unavailable, value is nil."
9e2a2647 1314 (and (memq (framep-on-display display) '(x w32 ns))
51e39dfc
KS
1315 (or (cddr (assoc (or display (frame-parameter nil 'display))
1316 display-mm-dimensions-alist))
1317 (cddr (assoc t display-mm-dimensions-alist))
1318 (x-display-mm-height display))))
9911648b 1319
aa360da1
GM
1320(declare-function x-display-mm-width "xfns.c" (&optional terminal))
1321
9911648b
EZ
1322(defun display-mm-width (&optional display)
1323 "Return the width of DISPLAY's screen in millimeters.
d7cd2d8b 1324System values can be overridden by `display-mm-dimensions-alist'.
9911648b 1325If the information is unavailable, value is nil."
9e2a2647 1326 (and (memq (framep-on-display display) '(x w32 ns))
51e39dfc
KS
1327 (or (cadr (assoc (or display (frame-parameter nil 'display))
1328 display-mm-dimensions-alist))
1329 (cadr (assoc t display-mm-dimensions-alist))
1330 (x-display-mm-width display))))
9911648b 1331
aa360da1
GM
1332(declare-function x-display-backing-store "xfns.c" (&optional terminal))
1333
9911648b
EZ
1334(defun display-backing-store (&optional display)
1335 "Return the backing store capability of DISPLAY's screen.
1336The value may be `always', `when-mapped', `not-useful', or nil if
1337the question is inapplicable to a certain kind of display."
1338 (let ((frame-type (framep-on-display display)))
1339 (cond
9e2a2647 1340 ((memq frame-type '(x w32 ns))
9911648b
EZ
1341 (x-display-backing-store display))
1342 (t
1343 'not-useful))))
1344
aa360da1
GM
1345(declare-function x-display-save-under "xfns.c" (&optional terminal))
1346
9911648b
EZ
1347(defun display-save-under (&optional display)
1348 "Return non-nil if DISPLAY's screen supports the SaveUnder feature."
1349 (let ((frame-type (framep-on-display display)))
1350 (cond
9e2a2647 1351 ((memq frame-type '(x w32 ns))
9911648b
EZ
1352 (x-display-save-under display))
1353 (t
1354 'not-useful))))
1355
aa360da1
GM
1356(declare-function x-display-planes "xfns.c" (&optional terminal))
1357
9911648b
EZ
1358(defun display-planes (&optional display)
1359 "Return the number of planes supported by DISPLAY."
1360 (let ((frame-type (framep-on-display display)))
1361 (cond
9e2a2647 1362 ((memq frame-type '(x w32 ns))
9911648b
EZ
1363 (x-display-planes display))
1364 ((eq frame-type 'pc)
1365 4)
1366 (t
1367 (truncate (log (length (tty-color-alist)) 2))))))
1368
aa360da1
GM
1369(declare-function x-display-color-cells "xfns.c" (&optional terminal))
1370
9911648b
EZ
1371(defun display-color-cells (&optional display)
1372 "Return the number of color cells supported by DISPLAY."
1373 (let ((frame-type (framep-on-display display)))
1374 (cond
9e2a2647 1375 ((memq frame-type '(x w32 ns))
9911648b
EZ
1376 (x-display-color-cells display))
1377 ((eq frame-type 'pc)
1378 16)
1379 (t
3224dac1 1380 (tty-display-color-cells display)))))
9911648b 1381
aa360da1
GM
1382(declare-function x-display-visual-class "xfns.c" (&optional terminal))
1383
9911648b 1384(defun display-visual-class (&optional display)
6cda144f 1385 "Return the visual class of DISPLAY.
9911648b
EZ
1386The value is one of the symbols `static-gray', `gray-scale',
1387`static-color', `pseudo-color', `true-color', or `direct-color'."
1388 (let ((frame-type (framep-on-display display)))
1389 (cond
9e2a2647 1390 ((memq frame-type '(x w32 ns))
9911648b
EZ
1391 (x-display-visual-class display))
1392 ((and (memq frame-type '(pc t))
1393 (tty-display-color-p display))
1394 'static-color)
1395 (t
1396 'static-gray))))
1397
1398\f
a32c1804
RS
1399;;;; Frame geometry values
1400
1401(defun frame-geom-value-cons (type value &optional frame)
1402 "Return equivalent geometry value for FRAME as a cons with car `+'.
1403A geometry value equivalent to VALUE for FRAME is returned,
1404where the value is a cons with car `+', not numeric.
1405TYPE is the car of the original geometry spec (TYPE . VALUE).
1406 It is `top' or `left', depending on which edge VALUE is related to.
1407VALUE is the cdr of a frame geometry spec: (left/top . VALUE).
1408If VALUE is a number, then it is converted to a cons value, perhaps
1409 relative to the opposite frame edge from that in the original spec.
1410FRAME defaults to the selected frame.
1411
1412Examples (measures in pixels) -
1413 Assuming display height/width=1024, frame height/width=600:
1414 300 inside display edge: 300 => (+ 300)
1415 (+ 300) => (+ 300)
1416 300 inside opposite display edge: (- 300) => (+ 124)
1417 -300 => (+ 124)
1418 300 beyond display edge
1419 (= 724 inside opposite display edge): (+ -300) => (+ -300)
1420 300 beyond display edge
1421 (= 724 inside opposite display edge): (- -300) => (+ 724)
1422
1423In the 3rd, 4th, and 6th examples, the returned value is relative to
1424the opposite frame edge from the edge indicated in the input spec."
1425 (cond ((and (consp value) (eq '+ (car value))) ; e.g. (+ 300), (+ -300)
1426 value)
1427 ((natnump value) (list '+ value)) ; e.g. 300 => (+ 300)
1428 (t ; e.g. -300, (- 300), (- -300)
1429 (list '+ (- (if (eq 'left type) ; => (+ 124), (+ 124), (+ 724)
1430 (x-display-pixel-width)
1431 (x-display-pixel-height))
1432 (if (integerp value) (- value) (cadr value))
1433 (if (eq 'left type)
1434 (frame-pixel-width frame)
1435 (frame-pixel-height frame)))))))
1436
1437(defun frame-geom-spec-cons (spec &optional frame)
1438 "Return equivalent geometry spec for FRAME as a cons with car `+'.
1439A geometry specification equivalent to SPEC for FRAME is returned,
1440where the value is a cons with car `+', not numeric.
1441SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE).
1442If VALUE is a number, then it is converted to a cons value, perhaps
1443 relative to the opposite frame edge from that in the original spec.
1444FRAME defaults to the selected frame.
1445
1446Examples (measures in pixels) -
1447 Assuming display height=1024, frame height=600:
1448 top 300 below display top: (top . 300) => (top + 300)
1449 (top + 300) => (top + 300)
1450 bottom 300 above display bottom: (top - 300) => (top + 124)
1451 (top . -300) => (top + 124)
1452 top 300 above display top
1453 (= bottom 724 above display bottom): (top + -300) => (top + -300)
1454 bottom 300 below display bottom
1455 (= top 724 below display top): (top - -300) => (top + 724)
1456
1457In the 3rd, 4th, and 6th examples, the returned value is relative to
1458the opposite frame edge from the edge indicated in the input spec."
1459 (cons (car spec) (frame-geom-value-cons (car spec) (cdr spec))))
1460\f
dc6d9681 1461;;;; Aliases for backward compatibility with Emacs 18.
8d91bd0a
JB
1462(define-obsolete-function-alias 'screen-height 'frame-height "19.7")
1463(define-obsolete-function-alias 'screen-width 'frame-width "19.7")
9e2b097b
JB
1464
1465(defun set-screen-width (cols &optional pretend)
84ed1560 1466 "Change the size of the screen to COLS columns.
40d34803
DL
1467Optional second arg non-nil means that redisplay should use COLS columns
1468but that the idea of the actual width of the frame should not be changed.
84ed1560 1469This function is provided only for compatibility with Emacs 18."
9e2b097b
JB
1470 (set-frame-width (selected-frame) cols pretend))
1471
1472(defun set-screen-height (lines &optional pretend)
84ed1560 1473 "Change the height of the screen to LINES lines.
40d34803
DL
1474Optional second arg non-nil means that redisplay should use LINES lines
1475but that the idea of the actual height of the screen should not be changed.
84ed1560 1476This function is provided only for compatibility with Emacs 18."
9e2b097b
JB
1477 (set-frame-height (selected-frame) lines pretend))
1478
154a757e
GM
1479(defun delete-other-frames (&optional frame)
1480 "Delete all frames except FRAME.
a2125918
GM
1481If FRAME uses another frame's minibuffer, the minibuffer frame is
1482left untouched. FRAME nil or omitted means use the selected frame."
154a757e
GM
1483 (interactive)
1484 (unless frame
1485 (setq frame (selected-frame)))
a2125918
GM
1486 (let* ((mini-frame (window-frame (minibuffer-window frame)))
1487 (frames (delq mini-frame (delq frame (frame-list)))))
5e5ae184
SM
1488 ;; Only consider frames on the same terminal.
1489 (dolist (frame (prog1 frames (setq frames nil)))
1490 (if (eq (frame-terminal) (frame-terminal frame))
1491 (push frame frames)))
a2125918
GM
1492 ;; Delete mon-minibuffer-only frames first, because `delete-frame'
1493 ;; signals an error when trying to delete a mini-frame that's
1494 ;; still in use by another frame.
1495 (dolist (frame frames)
1496 (unless (eq (frame-parameter frame 'minibuffer) 'only)
1497 (delete-frame frame)))
1498 ;; Delete minibuffer-only frames.
1499 (dolist (frame frames)
1500 (when (eq (frame-parameter frame 'minibuffer) 'only)
1501 (delete-frame frame)))))
154a757e 1502
8d91bd0a
JB
1503(make-obsolete 'set-screen-width 'set-frame-width "19.7")
1504(make-obsolete 'set-screen-height 'set-frame-height "19.7")
dc6d9681 1505
da7829a3 1506;; miscellaneous obsolescence declarations
84ed1560
JB
1507(define-obsolete-variable-alias 'delete-frame-hook
1508 'delete-frame-functions "22.1")
da7829a3 1509
dc6d9681 1510\f
7e573c4a 1511;; Highlighting trailing whitespace.
81b99826
GM
1512
1513(make-variable-buffer-local 'show-trailing-whitespace)
1514
1515(defcustom show-trailing-whitespace nil
6cda144f 1516 "Non-nil means highlight trailing whitespace.
e6c45c29 1517This is done in the face `trailing-whitespace'."
81b99826 1518 :type 'boolean
b4aefb19 1519 :group 'whitespace-faces)
81b99826
GM
1520
1521
1522\f
7e573c4a 1523;; Scrolling
79b14b94
GM
1524
1525(defgroup scrolling nil
1526 "Scrolling windows."
1527 :version "21.1"
1528 :group 'frames)
1529
968ecc28 1530(defcustom auto-hscroll-mode t
6cda144f 1531 "Allow or disallow automatic scrolling windows horizontally.
9ea60c46 1532If non-nil, windows are automatically scrolled horizontally to make
79b14b94
GM
1533point visible."
1534 :version "21.1"
1535 :type 'boolean
1536 :group 'scrolling)
968ecc28 1537(defvaralias 'automatic-hscrolling 'auto-hscroll-mode)
79b14b94
GM
1538
1539\f
7e573c4a 1540;; Blinking cursor
81b99826
GM
1541
1542(defgroup cursor nil
ca693be8 1543 "Displaying text cursors."
40d34803 1544 :version "21.1"
81b99826
GM
1545 :group 'frames)
1546
1547(defcustom blink-cursor-delay 0.5
6cda144f 1548 "Seconds of idle time after which cursor starts to blink."
81b99826
GM
1549 :type 'number
1550 :group 'cursor)
1551
1552(defcustom blink-cursor-interval 0.5
6cda144f 1553 "Length of cursor blink interval in seconds."
81b99826
GM
1554 :type 'number
1555 :group 'cursor)
1556
1557(defvar blink-cursor-idle-timer nil
ca693be8
GM
1558 "Timer started after `blink-cursor-delay' seconds of Emacs idle time.
1559The function `blink-cursor-start' is called when the timer fires.")
81b99826
GM
1560
1561(defvar blink-cursor-timer nil
ca693be8 1562 "Timer started from `blink-cursor-start'.
a795e09a
LT
1563This timer calls `blink-cursor-timer-function' every
1564`blink-cursor-interval' seconds.")
1565
81b99826 1566(defun blink-cursor-start ()
ca693be8
GM
1567 "Timer function called from the timer `blink-cursor-idle-timer'.
1568This starts the timer `blink-cursor-timer', which makes the cursor blink
1569if appropriate. It also arranges to cancel that timer when the next
1570command starts, by installing a pre-command hook."
81b99826 1571 (when (null blink-cursor-timer)
f9ac92c5
CY
1572 ;; Set up the timer first, so that if this signals an error,
1573 ;; blink-cursor-end is not added to pre-command-hook.
81b99826
GM
1574 (setq blink-cursor-timer
1575 (run-with-timer blink-cursor-interval blink-cursor-interval
f9ac92c5
CY
1576 'blink-cursor-timer-function))
1577 (add-hook 'pre-command-hook 'blink-cursor-end)
1578 (internal-show-cursor nil nil)))
0a5ebe4b
GM
1579
1580(defun blink-cursor-timer-function ()
1581 "Timer function of timer `blink-cursor-timer'."
1582 (internal-show-cursor nil (not (internal-show-cursor-p))))
81b99826
GM
1583
1584(defun blink-cursor-end ()
1585 "Stop cursor blinking.
ca693be8 1586This is installed as a pre-command hook by `blink-cursor-start'.
f39784dd 1587When run, it cancels the timer `blink-cursor-timer' and removes
ca693be8 1588itself as a pre-command hook."
81b99826 1589 (remove-hook 'pre-command-hook 'blink-cursor-end)
0a5ebe4b 1590 (internal-show-cursor nil t)
8ec94c16
SM
1591 (when blink-cursor-timer
1592 (cancel-timer blink-cursor-timer)
1593 (setq blink-cursor-timer nil)))
81b99826 1594
8ec94c16
SM
1595(define-minor-mode blink-cursor-mode
1596 "Toggle blinking cursor mode.
4837b516
GM
1597With a numeric argument, turn blinking cursor mode on if ARG is positive,
1598otherwise turn it off. When blinking cursor mode is enabled, the
1599cursor of the selected window blinks.
81b99826 1600
8ec94c16
SM
1601Note that this command is effective only when Emacs
1602displays through a window system, because then Emacs does its own
1603cursor display. On a text-only terminal, this is not implemented."
1604 :init-value (not (or noninteractive
1605 no-blinking-cursor
1606 (eq system-type 'ms-dos)
9e2a2647 1607 (not (memq window-system '(x w32)))))
8ec94c16
SM
1608 :initialize 'custom-initialize-safe-default
1609 :group 'cursor
1610 :global t
1611 (if blink-cursor-idle-timer (cancel-timer blink-cursor-idle-timer))
1612 (setq blink-cursor-idle-timer nil)
1613 (blink-cursor-end)
1614 (when blink-cursor-mode
1615 ;; Hide the cursor.
1616 ;;(internal-show-cursor nil nil)
1617 (setq blink-cursor-idle-timer
1618 (run-with-idle-timer blink-cursor-delay
1619 blink-cursor-delay
1620 'blink-cursor-start))))
81b99826 1621
8ec94c16 1622(define-obsolete-variable-alias 'blink-cursor 'blink-cursor-mode "22.1")
81b99826 1623\f
7e573c4a 1624;; Hourglass pointer
81b99826 1625
a6c411ff 1626(defcustom display-hourglass t
6cda144f 1627 "Non-nil means show an hourglass pointer, when Emacs is busy.
088e75cc
RS
1628This feature only works when on a window system that can change
1629cursor shapes."
81b99826 1630 :type 'boolean
a6c411ff 1631 :group 'cursor)
81b99826 1632
a6c411ff 1633(defcustom hourglass-delay 1
6cda144f 1634 "Seconds to wait before displaying an hourglass pointer when Emacs is busy."
0a86e779 1635 :type 'number
a6c411ff 1636 :group 'cursor)
1d0a3ef4 1637
5b2c5477 1638\f
c0eb3c10 1639(defcustom cursor-in-non-selected-windows t
6cda144f 1640 "Non-nil means show a hollow box cursor in non-selected windows.
e053c60f 1641If nil, don't show a cursor except in the selected window.
772e490c
RS
1642If t, display a cursor related to the usual cursor type
1643 \(a solid box becomes hollow, a bar becomes a narrower bar).
1644You can also specify the cursor type as in the `cursor-type' variable.
f39784dd 1645Use Custom to set this variable to get the display updated."
63ec4f94 1646 :tag "Cursor In Non-selected Windows"
5b2c5477
GM
1647 :type 'boolean
1648 :group 'cursor
5b2c5477
GM
1649 :set #'(lambda (symbol value)
1650 (set-default symbol value)
5b2c5477 1651 (force-mode-line-update t)))
f39784dd 1652
81b99826 1653\f
64c669bc 1654;;;; Key bindings
64c669bc 1655
6238bfaf 1656(define-key ctl-x-5-map "2" 'make-frame-command)
154a757e 1657(define-key ctl-x-5-map "1" 'delete-other-frames)
dc6d9681 1658(define-key ctl-x-5-map "0" 'delete-frame)
ceab6935 1659(define-key ctl-x-5-map "o" 'other-frame)
49116ac0 1660
dc6d9681 1661(provide 'frame)
c88ab9ce 1662
485464c4 1663;; arch-tag: 82979c70-b8f2-4306-b2ad-ddbd6b328b56
dc6d9681 1664;;; frame.el ends here