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