* src/ChangeLog: Formatting fixes.
[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,
114f9c96 4;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 1029 "Return number of lines available for display on FRAME.
4619ff5e
GM
1030If FRAME is omitted, describe the currently selected frame.
1031Exactly what is included in the return value depends on the
1032window-system and toolkit in use - see `frame-pixel-height' for
1033more details. The lines are in units of the default font height.
1034
1035The result is roughly related to the frame pixel height via
1036height in pixels = height in lines * `frame-char-height'.
1037However, this is only approximate, and is complicated e.g. by the
1038fact that individual window lines and menu bar lines can have
1039differing font heights."
151bdc83 1040 (cdr (assq 'height (frame-parameters frame))))
dc6d9681
JB
1041
1042(defun frame-width (&optional frame)
1043 "Return number of columns available for display on FRAME.
1044If FRAME is omitted, describe the currently selected frame."
151bdc83 1045 (cdr (assq 'width (frame-parameters frame))))
dc6d9681 1046
aa360da1
GM
1047(declare-function x-list-fonts "xfaces.c"
1048 (pattern &optional face frame maximum width))
1049
52ef9375 1050(define-obsolete-function-alias 'set-default-font 'set-frame-font "23.1")
1cef6541 1051(defun set-frame-font (font-name &optional keep-size)
40d34803 1052 "Set the font of the selected frame to FONT-NAME.
61298010 1053When called interactively, prompt for the name of the font to use.
1cef6541
JB
1054To get the frame's current default font, use `frame-parameters'.
1055
1056The default behavior is to keep the numbers of lines and columns in
84ed1560 1057the frame, thus may change its pixel size. If optional KEEP-SIZE is
1cef6541
JB
1058non-nil (interactively, prefix argument) the current frame size (in
1059pixels) is kept by adjusting the numbers of the lines and columns."
f39784dd 1060 (interactive
1cef6541
JB
1061 (let* ((completion-ignore-case t)
1062 (font (completing-read "Font name: "
1cef6541
JB
1063 ;; x-list-fonts will fail with an error
1064 ;; if this frame doesn't support fonts.
b7de6024
SM
1065 (x-list-fonts "*" nil (selected-frame))
1066 nil nil nil nil
1067 (frame-parameter nil 'font))))
1cef6541
JB
1068 (list font current-prefix-arg)))
1069 (let (fht fwd)
1070 (if keep-size
1071 (setq fht (* (frame-parameter nil 'height) (frame-char-height))
1072 fwd (* (frame-parameter nil 'width) (frame-char-width))))
1073 (modify-frame-parameters (selected-frame)
1074 (list (cons 'font font-name)))
1075 (if keep-size
1076 (modify-frame-parameters
1077 (selected-frame)
1078 (list (cons 'height (round fht (frame-char-height)))
1079 (cons 'width (round fwd (frame-char-width)))))))
72bf1a8b 1080 (run-hooks 'after-setting-font-hook 'after-setting-font-hooks))
64c669bc 1081
7e573c4a 1082(defun set-frame-parameter (frame parameter value)
0dac35b8
KL
1083 "Set frame parameter PARAMETER to VALUE on FRAME.
1084If FRAME is nil, it defaults to the selected frame.
c2c93894 1085See `modify-frame-parameters'."
7e573c4a
SM
1086 (modify-frame-parameters frame (list (cons parameter value))))
1087
8290babd 1088(defun set-background-color (color-name)
40d34803 1089 "Set the background color of the selected frame to COLOR-NAME.
61298010
RS
1090When called interactively, prompt for the name of the color to use.
1091To get the frame's current background color, use `frame-parameters'."
63ec4f94 1092 (interactive (list (facemenu-read-color "Background color: ")))
dc6d9681 1093 (modify-frame-parameters (selected-frame)
528e1416
EZ
1094 (list (cons 'background-color color-name)))
1095 (or window-system
1096 (face-set-after-frame-default (selected-frame))))
64c669bc 1097
8290babd 1098(defun set-foreground-color (color-name)
40d34803 1099 "Set the foreground color of the selected frame to COLOR-NAME.
61298010
RS
1100When called interactively, prompt for the name of the color to use.
1101To get the frame's current foreground color, use `frame-parameters'."
63ec4f94 1102 (interactive (list (facemenu-read-color "Foreground color: ")))
dc6d9681 1103 (modify-frame-parameters (selected-frame)
528e1416
EZ
1104 (list (cons 'foreground-color color-name)))
1105 (or window-system
1106 (face-set-after-frame-default (selected-frame))))
64c669bc
JB
1107
1108(defun set-cursor-color (color-name)
40d34803 1109 "Set the text cursor color of the selected frame to COLOR-NAME.
61298010
RS
1110When called interactively, prompt for the name of the color to use.
1111To get the frame's current cursor color, use `frame-parameters'."
63ec4f94 1112 (interactive (list (facemenu-read-color "Cursor color: ")))
dc6d9681 1113 (modify-frame-parameters (selected-frame)
7eadab74 1114 (list (cons 'cursor-color color-name))))
64c669bc 1115
eaa974e1 1116(defun set-mouse-color (color-name)
40d34803 1117 "Set the color of the mouse pointer of the selected frame to COLOR-NAME.
61298010
RS
1118When called interactively, prompt for the name of the color to use.
1119To get the frame's current mouse color, use `frame-parameters'."
63ec4f94 1120 (interactive (list (facemenu-read-color "Mouse color: ")))
dc6d9681 1121 (modify-frame-parameters (selected-frame)
ec6d4463
KH
1122 (list (cons 'mouse-color
1123 (or color-name
1124 (cdr (assq 'mouse-color
1125 (frame-parameters))))))))
7eadab74 1126
eaa974e1 1127(defun set-border-color (color-name)
40d34803 1128 "Set the color of the border of the selected frame to COLOR-NAME.
61298010
RS
1129When called interactively, prompt for the name of the color to use.
1130To get the frame's current border color, use `frame-parameters'."
63ec4f94 1131 (interactive (list (facemenu-read-color "Border color: ")))
eaa974e1
JB
1132 (modify-frame-parameters (selected-frame)
1133 (list (cons 'border-color color-name))))
1134
1135(defun auto-raise-mode (arg)
7eadab74 1136 "Toggle whether or not the selected frame should auto-raise.
6cda144f 1137With ARG, turn auto-raise mode on if and only if ARG is positive.
79e6ae33
RS
1138Note that this controls Emacs's own auto-raise feature.
1139Some window managers allow you to enable auto-raise for certain windows.
1140You can use that for Emacs windows if you wish, but if you do,
1141that is beyond the control of Emacs and this command has no effect on it."
7eadab74
JB
1142 (interactive "P")
1143 (if (null arg)
1144 (setq arg
1145 (if (cdr (assq 'auto-raise (frame-parameters (selected-frame))))
1146 -1 1)))
9626b928
GM
1147 (if (> arg 0)
1148 (raise-frame (selected-frame)))
dc6d9681 1149 (modify-frame-parameters (selected-frame)
7eadab74
JB
1150 (list (cons 'auto-raise (> arg 0)))))
1151
eaa974e1 1152(defun auto-lower-mode (arg)
7eadab74 1153 "Toggle whether or not the selected frame should auto-lower.
6cda144f 1154With ARG, turn auto-lower mode on if and only if ARG is positive.
79e6ae33
RS
1155Note that this controls Emacs's own auto-lower feature.
1156Some window managers allow you to enable auto-lower for certain windows.
1157You can use that for Emacs windows if you wish, but if you do,
1158that is beyond the control of Emacs and this command has no effect on it."
7eadab74
JB
1159 (interactive "P")
1160 (if (null arg)
1161 (setq arg
1162 (if (cdr (assq 'auto-lower (frame-parameters (selected-frame))))
1163 -1 1)))
dc6d9681 1164 (modify-frame-parameters (selected-frame)
7eadab74 1165 (list (cons 'auto-lower (> arg 0)))))
7777d03b
EZ
1166(defun set-frame-name (name)
1167 "Set the name of the selected frame to NAME.
1168When called interactively, prompt for the name of the frame.
1169The frame name is displayed on the modeline if the terminal displays only
1170one frame, otherwise the name is displayed on the frame's caption bar."
1171 (interactive "sFrame name: ")
1172 (modify-frame-parameters (selected-frame)
1173 (list (cons 'name name))))
56cfea72
KS
1174
1175(defun frame-current-scroll-bars (&optional frame)
1176 "Return the current scroll-bar settings in frame FRAME.
1cecf04d 1177Value is a cons (VERTICAL . HORIZ0NTAL) where VERTICAL specifies the
56cfea72 1178current location of the vertical scroll-bars (left, right, or nil),
1cecf04d 1179and HORIZONTAL specifies the current location of the horizontal scroll
56cfea72
KS
1180bars (top, bottom, or nil)."
1181 (let ((vert (frame-parameter frame 'vertical-scroll-bars))
1182 (hor nil))
1183 (unless (memq vert '(left right nil))
1184 (setq vert default-frame-scroll-bars))
1185 (cons vert hor)))
64c669bc 1186\f
9911648b 1187;;;; Frame/display capabilities.
6ed8eeff
KL
1188(defun selected-terminal ()
1189 "Return the terminal that is now selected."
1190 (frame-terminal (selected-frame)))
b6660415 1191
73e6adaa
DN
1192(declare-function msdos-mouse-p "dosfns.c")
1193
9911648b
EZ
1194(defun display-mouse-p (&optional display)
1195 "Return non-nil if DISPLAY has a mouse available.
1196DISPLAY can be a display name, a frame, or nil (meaning the selected
1197frame's display)."
1198 (let ((frame-type (framep-on-display display)))
1199 (cond
1200 ((eq frame-type 'pc)
1201 (msdos-mouse-p))
1202 ((eq system-type 'windows-nt)
9fa5bb32
RS
1203 (with-no-warnings
1204 (> w32-num-mouse-buttons 0)))
9e2a2647
DN
1205 ((memq frame-type '(x ns))
1206 t) ;; We assume X and NeXTstep *always* have a pointing device
9911648b 1207 (t
7565ee93
DL
1208 (or (and (featurep 'xt-mouse)
1209 xterm-mouse-mode)
1210 ;; t-mouse is distributed with the GPM package. It doesn't have
1211 ;; a toggle.
1212 (featurep 't-mouse))))))
9911648b
EZ
1213
1214(defun display-popup-menus-p (&optional display)
1215 "Return non-nil if popup menus are supported on DISPLAY.
1216DISPLAY can be a display name, a frame, or nil (meaning the selected
1217frame's display).
1218Support for popup menus requires that the mouse be available."
1219 (and
1220 (let ((frame-type (framep-on-display display)))
9e2a2647 1221 (memq frame-type '(x w32 pc ns)))
9911648b
EZ
1222 (display-mouse-p display)))
1223
1224(defun display-graphic-p (&optional display)
1225 "Return non-nil if DISPLAY is a graphic display.
1226Graphical displays are those which are capable of displaying several
1227frames and several different fonts at once. This is true for displays
1228that use a window system such as X, and false for text-only terminals.
1229DISPLAY can be a display name, a frame, or nil (meaning the selected
1230frame's display)."
9e2a2647 1231 (not (null (memq (framep-on-display display) '(x w32 ns)))))
9911648b 1232
ddc456e4
EZ
1233(defun display-images-p (&optional display)
1234 "Return non-nil if DISPLAY can display images.
1235
1236DISPLAY can be a display name, a frame, or nil (meaning the selected
1237frame's display)."
1238 (and (display-graphic-p display)
1239 (fboundp 'image-mask-p)
fcc6f5cc 1240 (fboundp 'image-size)))
ddc456e4 1241
6693b279
EZ
1242(defalias 'display-multi-frame-p 'display-graphic-p)
1243(defalias 'display-multi-font-p 'display-graphic-p)
1244
9911648b
EZ
1245(defun display-selections-p (&optional display)
1246 "Return non-nil if DISPLAY supports selections.
1247A selection is a way to transfer text or other data between programs
1248via special system buffers called `selection' or `cut buffer' or
1249`clipboard'.
1250DISPLAY can be a display name, a frame, or nil (meaning the selected
1251frame's display)."
1252 (let ((frame-type (framep-on-display display)))
1253 (cond
1254 ((eq frame-type 'pc)
1255 ;; MS-DOG frames support selections when Emacs runs inside
1256 ;; the Windows' DOS Box.
9fa5bb32
RS
1257 (with-no-warnings
1258 (not (null dos-windows-version))))
9e2a2647 1259 ((memq frame-type '(x w32 ns))
9911648b
EZ
1260 t) ;; FIXME?
1261 (t
1262 nil))))
1263
aa360da1
GM
1264(declare-function x-display-screens "xfns.c" (&optional terminal))
1265
9911648b
EZ
1266(defun display-screens (&optional display)
1267 "Return the number of screens associated with DISPLAY."
1268 (let ((frame-type (framep-on-display display)))
1269 (cond
9e2a2647 1270 ((memq frame-type '(x w32 ns))
9911648b 1271 (x-display-screens display))
bb9404d6 1272 (t
9911648b
EZ
1273 1))))
1274
aa360da1
GM
1275(declare-function x-display-pixel-height "xfns.c" (&optional terminal))
1276
9911648b
EZ
1277(defun display-pixel-height (&optional display)
1278 "Return the height of DISPLAY's screen in pixels.
1279For character terminals, each character counts as a single pixel."
1280 (let ((frame-type (framep-on-display display)))
1281 (cond
9e2a2647 1282 ((memq frame-type '(x w32 ns))
9911648b
EZ
1283 (x-display-pixel-height display))
1284 (t
1285 (frame-height (if (framep display) display (selected-frame)))))))
1286
aa360da1
GM
1287(declare-function x-display-pixel-width "xfns.c" (&optional terminal))
1288
9911648b
EZ
1289(defun display-pixel-width (&optional display)
1290 "Return the width of DISPLAY's screen in pixels.
1291For character terminals, each character counts as a single pixel."
1292 (let ((frame-type (framep-on-display display)))
1293 (cond
9e2a2647 1294 ((memq frame-type '(x w32 ns))
9911648b
EZ
1295 (x-display-pixel-width display))
1296 (t
1297 (frame-width (if (framep display) display (selected-frame)))))))
1298
51e39dfc
KS
1299(defcustom display-mm-dimensions-alist nil
1300 "Alist for specifying screen dimensions in millimeters.
1301The dimensions will be used for `display-mm-height' and
1302`display-mm-width' if defined for the respective display.
1303
1304Each element of the alist has the form (display . (width . height)),
1305e.g. (\":0.0\" . (287 . 215)).
1306
1307If `display' equals t, it specifies dimensions for all graphical
1308displays not explicitely specified."
1309 :version "22.1"
1310 :type '(alist :key-type (choice (string :tag "Display name")
1311 (const :tag "Default" t))
1312 :value-type (cons :tag "Dimensions"
1313 (integer :tag "Width")
1314 (integer :tag "Height")))
1315 :group 'frames)
1316
aa360da1
GM
1317(declare-function x-display-mm-height "xfns.c" (&optional terminal))
1318
9911648b
EZ
1319(defun display-mm-height (&optional display)
1320 "Return the height of DISPLAY's screen in millimeters.
d7cd2d8b 1321System values can be overridden by `display-mm-dimensions-alist'.
9911648b 1322If the information is unavailable, value is nil."
9e2a2647 1323 (and (memq (framep-on-display display) '(x w32 ns))
51e39dfc
KS
1324 (or (cddr (assoc (or display (frame-parameter nil 'display))
1325 display-mm-dimensions-alist))
1326 (cddr (assoc t display-mm-dimensions-alist))
1327 (x-display-mm-height display))))
9911648b 1328
aa360da1
GM
1329(declare-function x-display-mm-width "xfns.c" (&optional terminal))
1330
9911648b
EZ
1331(defun display-mm-width (&optional display)
1332 "Return the width of DISPLAY's screen in millimeters.
d7cd2d8b 1333System values can be overridden by `display-mm-dimensions-alist'.
9911648b 1334If the information is unavailable, value is nil."
9e2a2647 1335 (and (memq (framep-on-display display) '(x w32 ns))
51e39dfc
KS
1336 (or (cadr (assoc (or display (frame-parameter nil 'display))
1337 display-mm-dimensions-alist))
1338 (cadr (assoc t display-mm-dimensions-alist))
1339 (x-display-mm-width display))))
9911648b 1340
aa360da1
GM
1341(declare-function x-display-backing-store "xfns.c" (&optional terminal))
1342
9911648b
EZ
1343(defun display-backing-store (&optional display)
1344 "Return the backing store capability of DISPLAY's screen.
1345The value may be `always', `when-mapped', `not-useful', or nil if
1346the question is inapplicable to a certain kind of display."
1347 (let ((frame-type (framep-on-display display)))
1348 (cond
9e2a2647 1349 ((memq frame-type '(x w32 ns))
9911648b
EZ
1350 (x-display-backing-store display))
1351 (t
1352 'not-useful))))
1353
aa360da1
GM
1354(declare-function x-display-save-under "xfns.c" (&optional terminal))
1355
9911648b
EZ
1356(defun display-save-under (&optional display)
1357 "Return non-nil if DISPLAY's screen supports the SaveUnder feature."
1358 (let ((frame-type (framep-on-display display)))
1359 (cond
9e2a2647 1360 ((memq frame-type '(x w32 ns))
9911648b
EZ
1361 (x-display-save-under display))
1362 (t
1363 'not-useful))))
1364
aa360da1
GM
1365(declare-function x-display-planes "xfns.c" (&optional terminal))
1366
9911648b
EZ
1367(defun display-planes (&optional display)
1368 "Return the number of planes supported by DISPLAY."
1369 (let ((frame-type (framep-on-display display)))
1370 (cond
9e2a2647 1371 ((memq frame-type '(x w32 ns))
9911648b
EZ
1372 (x-display-planes display))
1373 ((eq frame-type 'pc)
1374 4)
1375 (t
1376 (truncate (log (length (tty-color-alist)) 2))))))
1377
aa360da1
GM
1378(declare-function x-display-color-cells "xfns.c" (&optional terminal))
1379
9911648b
EZ
1380(defun display-color-cells (&optional display)
1381 "Return the number of color cells supported by DISPLAY."
1382 (let ((frame-type (framep-on-display display)))
1383 (cond
9e2a2647 1384 ((memq frame-type '(x w32 ns))
9911648b
EZ
1385 (x-display-color-cells display))
1386 ((eq frame-type 'pc)
1387 16)
1388 (t
3224dac1 1389 (tty-display-color-cells display)))))
9911648b 1390
aa360da1
GM
1391(declare-function x-display-visual-class "xfns.c" (&optional terminal))
1392
9911648b 1393(defun display-visual-class (&optional display)
6cda144f 1394 "Return the visual class of DISPLAY.
9911648b
EZ
1395The value is one of the symbols `static-gray', `gray-scale',
1396`static-color', `pseudo-color', `true-color', or `direct-color'."
1397 (let ((frame-type (framep-on-display display)))
1398 (cond
9e2a2647 1399 ((memq frame-type '(x w32 ns))
9911648b
EZ
1400 (x-display-visual-class display))
1401 ((and (memq frame-type '(pc t))
1402 (tty-display-color-p display))
1403 'static-color)
1404 (t
1405 'static-gray))))
1406
1407\f
a32c1804
RS
1408;;;; Frame geometry values
1409
1410(defun frame-geom-value-cons (type value &optional frame)
1411 "Return equivalent geometry value for FRAME as a cons with car `+'.
1412A geometry value equivalent to VALUE for FRAME is returned,
1413where the value is a cons with car `+', not numeric.
1414TYPE is the car of the original geometry spec (TYPE . VALUE).
1415 It is `top' or `left', depending on which edge VALUE is related to.
1416VALUE is the cdr of a frame geometry spec: (left/top . VALUE).
1417If VALUE is a number, then it is converted to a cons value, perhaps
1418 relative to the opposite frame edge from that in the original spec.
1419FRAME defaults to the selected frame.
1420
1421Examples (measures in pixels) -
1422 Assuming display height/width=1024, frame height/width=600:
1423 300 inside display edge: 300 => (+ 300)
1424 (+ 300) => (+ 300)
1425 300 inside opposite display edge: (- 300) => (+ 124)
1426 -300 => (+ 124)
1427 300 beyond display edge
1428 (= 724 inside opposite display edge): (+ -300) => (+ -300)
1429 300 beyond display edge
1430 (= 724 inside opposite display edge): (- -300) => (+ 724)
1431
1432In the 3rd, 4th, and 6th examples, the returned value is relative to
1433the opposite frame edge from the edge indicated in the input spec."
1434 (cond ((and (consp value) (eq '+ (car value))) ; e.g. (+ 300), (+ -300)
1435 value)
1436 ((natnump value) (list '+ value)) ; e.g. 300 => (+ 300)
1437 (t ; e.g. -300, (- 300), (- -300)
1438 (list '+ (- (if (eq 'left type) ; => (+ 124), (+ 124), (+ 724)
1439 (x-display-pixel-width)
1440 (x-display-pixel-height))
1441 (if (integerp value) (- value) (cadr value))
1442 (if (eq 'left type)
1443 (frame-pixel-width frame)
1444 (frame-pixel-height frame)))))))
1445
1446(defun frame-geom-spec-cons (spec &optional frame)
1447 "Return equivalent geometry spec for FRAME as a cons with car `+'.
1448A geometry specification equivalent to SPEC for FRAME is returned,
1449where the value is a cons with car `+', not numeric.
1450SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE).
1451If VALUE is a number, then it is converted to a cons value, perhaps
1452 relative to the opposite frame edge from that in the original spec.
1453FRAME defaults to the selected frame.
1454
1455Examples (measures in pixels) -
1456 Assuming display height=1024, frame height=600:
1457 top 300 below display top: (top . 300) => (top + 300)
1458 (top + 300) => (top + 300)
1459 bottom 300 above display bottom: (top - 300) => (top + 124)
1460 (top . -300) => (top + 124)
1461 top 300 above display top
1462 (= bottom 724 above display bottom): (top + -300) => (top + -300)
1463 bottom 300 below display bottom
1464 (= top 724 below display top): (top - -300) => (top + 724)
1465
1466In the 3rd, 4th, and 6th examples, the returned value is relative to
1467the opposite frame edge from the edge indicated in the input spec."
1468 (cons (car spec) (frame-geom-value-cons (car spec) (cdr spec))))
1469\f
dc6d9681 1470;;;; Aliases for backward compatibility with Emacs 18.
8d91bd0a
JB
1471(define-obsolete-function-alias 'screen-height 'frame-height "19.7")
1472(define-obsolete-function-alias 'screen-width 'frame-width "19.7")
9e2b097b
JB
1473
1474(defun set-screen-width (cols &optional pretend)
84ed1560 1475 "Change the size of the screen to COLS columns.
40d34803
DL
1476Optional second arg non-nil means that redisplay should use COLS columns
1477but that the idea of the actual width of the frame should not be changed.
84ed1560 1478This function is provided only for compatibility with Emacs 18."
9e2b097b
JB
1479 (set-frame-width (selected-frame) cols pretend))
1480
1481(defun set-screen-height (lines &optional pretend)
84ed1560 1482 "Change the height of the screen to LINES lines.
40d34803
DL
1483Optional second arg non-nil means that redisplay should use LINES lines
1484but that the idea of the actual height of the screen should not be changed.
84ed1560 1485This function is provided only for compatibility with Emacs 18."
9e2b097b
JB
1486 (set-frame-height (selected-frame) lines pretend))
1487
154a757e
GM
1488(defun delete-other-frames (&optional frame)
1489 "Delete all frames except FRAME.
a2125918
GM
1490If FRAME uses another frame's minibuffer, the minibuffer frame is
1491left untouched. FRAME nil or omitted means use the selected frame."
154a757e
GM
1492 (interactive)
1493 (unless frame
1494 (setq frame (selected-frame)))
a2125918
GM
1495 (let* ((mini-frame (window-frame (minibuffer-window frame)))
1496 (frames (delq mini-frame (delq frame (frame-list)))))
5e5ae184
SM
1497 ;; Only consider frames on the same terminal.
1498 (dolist (frame (prog1 frames (setq frames nil)))
1499 (if (eq (frame-terminal) (frame-terminal frame))
1500 (push frame frames)))
a2125918
GM
1501 ;; Delete mon-minibuffer-only frames first, because `delete-frame'
1502 ;; signals an error when trying to delete a mini-frame that's
1503 ;; still in use by another frame.
1504 (dolist (frame frames)
1505 (unless (eq (frame-parameter frame 'minibuffer) 'only)
1506 (delete-frame frame)))
1507 ;; Delete minibuffer-only frames.
1508 (dolist (frame frames)
1509 (when (eq (frame-parameter frame 'minibuffer) 'only)
1510 (delete-frame frame)))))
154a757e 1511
8d91bd0a
JB
1512(make-obsolete 'set-screen-width 'set-frame-width "19.7")
1513(make-obsolete 'set-screen-height 'set-frame-height "19.7")
dc6d9681 1514
da7829a3 1515;; miscellaneous obsolescence declarations
84ed1560
JB
1516(define-obsolete-variable-alias 'delete-frame-hook
1517 'delete-frame-functions "22.1")
da7829a3 1518
dc6d9681 1519\f
7e573c4a 1520;; Highlighting trailing whitespace.
81b99826
GM
1521
1522(make-variable-buffer-local 'show-trailing-whitespace)
1523
1524(defcustom show-trailing-whitespace nil
6cda144f 1525 "Non-nil means highlight trailing whitespace.
e6c45c29 1526This is done in the face `trailing-whitespace'."
81b99826 1527 :type 'boolean
3a4f3a3b 1528 :safe 'booleanp
b4aefb19 1529 :group 'whitespace-faces)
81b99826
GM
1530
1531
1532\f
7e573c4a 1533;; Scrolling
79b14b94
GM
1534
1535(defgroup scrolling nil
1536 "Scrolling windows."
1537 :version "21.1"
1538 :group 'frames)
1539
968ecc28 1540(defcustom auto-hscroll-mode t
6cda144f 1541 "Allow or disallow automatic scrolling windows horizontally.
9ea60c46 1542If non-nil, windows are automatically scrolled horizontally to make
79b14b94
GM
1543point visible."
1544 :version "21.1"
1545 :type 'boolean
1546 :group 'scrolling)
968ecc28 1547(defvaralias 'automatic-hscrolling 'auto-hscroll-mode)
79b14b94
GM
1548
1549\f
7e573c4a 1550;; Blinking cursor
81b99826
GM
1551
1552(defgroup cursor nil
ca693be8 1553 "Displaying text cursors."
40d34803 1554 :version "21.1"
81b99826
GM
1555 :group 'frames)
1556
1557(defcustom blink-cursor-delay 0.5
6cda144f 1558 "Seconds of idle time after which cursor starts to blink."
81b99826
GM
1559 :type 'number
1560 :group 'cursor)
1561
1562(defcustom blink-cursor-interval 0.5
6cda144f 1563 "Length of cursor blink interval in seconds."
81b99826
GM
1564 :type 'number
1565 :group 'cursor)
1566
1567(defvar blink-cursor-idle-timer nil
ca693be8
GM
1568 "Timer started after `blink-cursor-delay' seconds of Emacs idle time.
1569The function `blink-cursor-start' is called when the timer fires.")
81b99826
GM
1570
1571(defvar blink-cursor-timer nil
ca693be8 1572 "Timer started from `blink-cursor-start'.
a795e09a
LT
1573This timer calls `blink-cursor-timer-function' every
1574`blink-cursor-interval' seconds.")
1575
81b99826 1576(defun blink-cursor-start ()
ca693be8
GM
1577 "Timer function called from the timer `blink-cursor-idle-timer'.
1578This starts the timer `blink-cursor-timer', which makes the cursor blink
1579if appropriate. It also arranges to cancel that timer when the next
1580command starts, by installing a pre-command hook."
81b99826 1581 (when (null blink-cursor-timer)
f9ac92c5
CY
1582 ;; Set up the timer first, so that if this signals an error,
1583 ;; blink-cursor-end is not added to pre-command-hook.
81b99826
GM
1584 (setq blink-cursor-timer
1585 (run-with-timer blink-cursor-interval blink-cursor-interval
f9ac92c5
CY
1586 'blink-cursor-timer-function))
1587 (add-hook 'pre-command-hook 'blink-cursor-end)
1588 (internal-show-cursor nil nil)))
0a5ebe4b
GM
1589
1590(defun blink-cursor-timer-function ()
1591 "Timer function of timer `blink-cursor-timer'."
1592 (internal-show-cursor nil (not (internal-show-cursor-p))))
81b99826
GM
1593
1594(defun blink-cursor-end ()
1595 "Stop cursor blinking.
ca693be8 1596This is installed as a pre-command hook by `blink-cursor-start'.
f39784dd 1597When run, it cancels the timer `blink-cursor-timer' and removes
ca693be8 1598itself as a pre-command hook."
81b99826 1599 (remove-hook 'pre-command-hook 'blink-cursor-end)
0a5ebe4b 1600 (internal-show-cursor nil t)
8ec94c16
SM
1601 (when blink-cursor-timer
1602 (cancel-timer blink-cursor-timer)
1603 (setq blink-cursor-timer nil)))
81b99826 1604
8ec94c16
SM
1605(define-minor-mode blink-cursor-mode
1606 "Toggle blinking cursor mode.
4837b516
GM
1607With a numeric argument, turn blinking cursor mode on if ARG is positive,
1608otherwise turn it off. When blinking cursor mode is enabled, the
1609cursor of the selected window blinks.
81b99826 1610
8ec94c16
SM
1611Note that this command is effective only when Emacs
1612displays through a window system, because then Emacs does its own
1613cursor display. On a text-only terminal, this is not implemented."
1614 :init-value (not (or noninteractive
1615 no-blinking-cursor
1616 (eq system-type 'ms-dos)
9e2a2647 1617 (not (memq window-system '(x w32)))))
adba8116 1618 :initialize 'custom-initialize-delay
8ec94c16
SM
1619 :group 'cursor
1620 :global t
1621 (if blink-cursor-idle-timer (cancel-timer blink-cursor-idle-timer))
1622 (setq blink-cursor-idle-timer nil)
1623 (blink-cursor-end)
1624 (when blink-cursor-mode
1625 ;; Hide the cursor.
1626 ;;(internal-show-cursor nil nil)
1627 (setq blink-cursor-idle-timer
1628 (run-with-idle-timer blink-cursor-delay
1629 blink-cursor-delay
1630 'blink-cursor-start))))
81b99826 1631
8ec94c16 1632(define-obsolete-variable-alias 'blink-cursor 'blink-cursor-mode "22.1")
81b99826 1633\f
7e573c4a 1634;; Hourglass pointer
81b99826 1635
a6c411ff 1636(defcustom display-hourglass t
6cda144f 1637 "Non-nil means show an hourglass pointer, when Emacs is busy.
088e75cc
RS
1638This feature only works when on a window system that can change
1639cursor shapes."
81b99826 1640 :type 'boolean
a6c411ff 1641 :group 'cursor)
81b99826 1642
a6c411ff 1643(defcustom hourglass-delay 1
6cda144f 1644 "Seconds to wait before displaying an hourglass pointer when Emacs is busy."
0a86e779 1645 :type 'number
a6c411ff 1646 :group 'cursor)
1d0a3ef4 1647
5b2c5477 1648\f
c0eb3c10 1649(defcustom cursor-in-non-selected-windows t
6cda144f 1650 "Non-nil means show a hollow box cursor in non-selected windows.
e053c60f 1651If nil, don't show a cursor except in the selected window.
772e490c
RS
1652If t, display a cursor related to the usual cursor type
1653 \(a solid box becomes hollow, a bar becomes a narrower bar).
1654You can also specify the cursor type as in the `cursor-type' variable.
f39784dd 1655Use Custom to set this variable to get the display updated."
63ec4f94 1656 :tag "Cursor In Non-selected Windows"
5b2c5477
GM
1657 :type 'boolean
1658 :group 'cursor
5b2c5477
GM
1659 :set #'(lambda (symbol value)
1660 (set-default symbol value)
5b2c5477 1661 (force-mode-line-update t)))
f39784dd 1662
81b99826 1663\f
64c669bc 1664;;;; Key bindings
64c669bc 1665
6238bfaf 1666(define-key ctl-x-5-map "2" 'make-frame-command)
154a757e 1667(define-key ctl-x-5-map "1" 'delete-other-frames)
dc6d9681 1668(define-key ctl-x-5-map "0" 'delete-frame)
ceab6935 1669(define-key ctl-x-5-map "o" 'other-frame)
49116ac0 1670
dc6d9681 1671(provide 'frame)
c88ab9ce 1672
485464c4 1673;; arch-tag: 82979c70-b8f2-4306-b2ad-ddbd6b328b56
dc6d9681 1674;;; frame.el ends here