diff options
| author | Martin Rudalics | 2017-04-12 10:38:25 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2017-04-12 10:38:25 +0200 |
| commit | 3fdd3bb56c006a2a24761b8fcea0cbd9b0cba422 (patch) | |
| tree | a0b8f5e431ba812b4fe69261a8515e973a3e7ed3 /lisp | |
| parent | 449bc49c768a4733411c7e05186be7efc163cd7c (diff) | |
| download | emacs-3fdd3bb56c006a2a24761b8fcea0cbd9b0cba422.tar.gz emacs-3fdd3bb56c006a2a24761b8fcea0cbd9b0cba422.zip | |
Add new frame parameters and associated functions
Add new frame parameters `undecorated', `override-redirect',
`parent-frame', `skip-taskbar', `no-focus-on-map',
`no-accept-focus', `z-group', `delete-before', `no-other-frame',
`mouse-wheel-frame', `min-width', `min-height'. Add new
functions `frame-restack' and `frame-list-z-order'.
* lisp/cus-start.el (focus-follows-mouse): Adapt customization
type.
* lisp/frame.el (handle-delete-frame): Handle child and
`delete-before' frames.
(other-frame): Stop looking for other frame after one round.
(frame-list-z-order, frame-restack): New functions.
(delete-other-frames): Handle child frames.
* lisp/frameset.el (frameset-persistent-filter-alist)
(frameset--record-relationships): Handle `delete-before',
`parent-frame' and `mouse-wheel-frame' parameters. Rename
latter from `frameset--record-minibuffer-relationships'.
(frameset--restore-frame): Handle ‘parent-frame’ parameter
specially.
(frameset-restore): Handle `delete-before', `parent-frame' and
`mouse-wheel-frame' parameters.
* lisp/mwheel.el (mwheel-scroll): Handle `mouse-wheel-frame'
parameter.
* lisp/window.el (window--min-size-ignore-p): Fix doc-string.
(mouse-autoselect-window-select, handle-select-window): Major
rewrite. Try to not ignore errors. Handle auto-selection of
child frames and different values of `focus-follows-mouse'.
* src/frame.c (frame_windows_min_size): Handle new `min-width'
and `min-height' frame parameters.
(make_frame): Initialize new frame structure members.
(do_switch_frame): Don't reset internal_last_event_frame for
descendant frames.
(Fframe_parent, frame_ancestor_p, Fframe_ancestor_p): New
functions.
(candidate_frame): Don't return `no-other-frame' frame.
(other_frames): New function replacing other_visible_frames.
(delete_frame): Rewrite. Handle child and `delete-before' frames.
(Fmake_frame_invisible): Call other_frames.
(store_frame_param): Check `delete-before' and `parent-frame'
parameters for circular dependencies.
(frame_parms, syms_of_frame): Add entries for and define new
frame parameters.
(focus_follows_mouse): New meaningful value `auto-raise'.
* src/frame.h (z_group): New enumeration type.
(frame): New slots parent_frame, undecorated, override_redirect,
skip_taskbar, no_focus_on_map, no_accept_focus, z_group.
(fset_parent_frame): New inlined function.
(FRAME_UNDECORATED, FRAME_OVERRIDE_REDIRECT)
(FRAME_PARENT_FRAME, FRAME_SKIP_TASKBAR, FRAME_NO_FOCUS_ON_MAP)
(FRAME_NO_ACCEPT_FOCUS, FRAME_Z_GROUP, FRAME_Z_GROUP_NONE)
(FRAME_Z_GROUP_ABOVE, FRAME_Z_GROUP_ABOVE_SUSPENDED)
(FRAME_Z_GROUP_BELOW): New macros.
(frame_ancestor_p): Add declaration.
* src/gtkutil.c (xg_create_frame_widgets): Handle
`undecorated' and `override-redirect' frame parameters.
(x_wm_set_size_hint): None for child frames.
(xg_set_undecorated, xg_frame_restack, xg_set_skip_taskbar)
(xg_set_no_focus_on_map, xg_set_no_accept_focus)
(xg_set_override_redirect): New functions.
(xg_update_scrollbar_pos, xg_update_horizontal_scrollbar_pos):
Don't let scrollbars obscure child frames.
* src/gtkutil.h: (xg_set_undecorated, xg_frame_restack)
(xg_set_skip_taskbar, xg_set_no_focus_on_map)
(xg_set_no_accept_focus, xg_set_override_redirect): Add extern
declarations.
* src/nsfns.m (ns_frame_parm_handlers): Add entries for new
frame parameters.
(Fx_create_frame): Install `min-width' and `min-height' frame
parameters.
* src/nsterm.m (mouseMoved:): Handle focus_follows_mouse change.
* src/w32fns.c (WS_EX_NOACTIVATE): Define if necessary.
(x_real_positions): Handle child frames.
(x_set_menu_bar_lines): Don't for child frames.
(x_set_undecorated, x_set_parent_frame, x_set_skip_taskbar)
(x_set_no_focus_on_map, x_set_no_accept_focus)
(x_set_z_group): New functions.
(w32_createvscrollbar, w32_createhscrollbar): Don't draw
scroll bars over child frames.
(w32_createwindow): Handle new frame parameters and child frames.
(w32_wnd_proc): Let mouse clicks into a child frame activate
the frame. Try to handle the `no-accept-focus' parameter. Do
SetFocus when our window is brought to top or becomes the
foreground window.
(w32_window): Don't initialize menu bar for child frames.
(Fx_create_frame): Handle new frame parameters.
(x_create_tip_frame): Set explicit_parent slot.
(w32_dialog_in_progress): New function.
(Fx_file_dialog): Handle `z-group-above' frames.
(w32_frame_list_z_order, Fw32_frame_list_z_order)
(w32_frame_restack, Fw32_frame_restack): New functions.
(w32_frame_parm_handlers): Add entries for new frame
parameters.
* src/w32font.c (Fx_select_font): Handle `z-group-above'
frames during font selection dialogue.
* src/w32term.c (construct_mouse_wheel): Construct mouse wheel
event from F's w32 window.
(w32_mouse_position): Handle child frames.
(w32_set_vertical_scroll_bar, w32_set_horizontal_scroll_bar):
Don't draw scroll bars over child frames.
(w32_read_socket): Always erase background of child frames.
When generating SELECT_WINDOW_EVENTs handle new value of
`focus-follows-mouse' and handle `no-accept-focus' parameter.
Handle `mouse-wheel-frame' parameter.
(x_calc_absolute_position, x_set_offset, x_set_window_size):
Handle child frames.
(x_make_frame_visible): Handle child frames specially. Handle
`no-focus-on-map' parameter.
* src/w32term.h (w32_dialog_in_progress): Add external
declaration.
* src/xdisp.c (x_consider_frame_title, prepare_menu_bars): Not
for child frames.
* src/xfns.c (Xm/MwmUtil.h): Include for WM hints.
(PropMotifWmHints, PROP_MOTIF_WM_HINTS_ELEMENTS): Define for
non-Motif, non-GTK case.
(x_real_pos_and_offsets): Handle child frames.
(x_set_undecorated, x_set_parent_frame)
(x_set_no_focus_on_map, x_set_no_accept_focus)
(x_set_override_redirect): New functions.
(x_set_menu_bar_lines): Not for child frames.
(x_window): Handle `undecorated' and `override_redirect' cases.
(Fx_create_frame): Handle new frame parameters.
(frame_geometry): Handle child frames and outer border.
(x_frame_list_z_order, Fx_frame_list_z_order)
(x_frame_restack, Fx_frame_restack): New functions.
(Fx_file_dialog, Fx_select_font): Set x_menu_set_in_use.
(x_frame_parm_handlers): Add entries for new frame parameters.
* src/xmenu.c (x_menu_set_in_use): Handle `z-group-above'
frames.
* src/xterm.c (x_set_frame_alpha): Don't set alpha of parent
for child frames.
(XTmouse_position): Handle child frames.
(x_scroll_bar_create, x_scroll_bar_expose): Don't let scroll
bars obscure child frames.
(handle_one_xevent): Handle child frame positions. If necessary
set `skip-taskbar' and reassign proper `z-group' when we are
mapped. When generating SELECT_WINDOW_EVENTs handle new value
of `focus-follows-mouse'. Handle `mouse-wheel-frame' parameter.
Let mouse clicks into a child frame activate the frame.
(x_calc_absolute_position, x_set_offset): Handle child frames
specially.
(x_set_skip_taskbar, x_set_z_group): New functions.
(x_make_frame_visible): Handle child frames.
(ATOM_REFS_INIT): Add entries for
Xatom_net_wm_state_skip_taskbar, Xatom_net_wm_state_above,
Xatom_net_wm_state_below.
* src/xterm.h (top-level): Declare Xatom_net_wm_state_above,
Xatom_net_wm_state_below and Xatom_net_wm_state_skip_taskbar.
(x_set_skip_taskbar, x_set_z_group): Add extern declarations.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/cus-start.el | 6 | ||||
| -rw-r--r-- | lisp/frame.el | 117 | ||||
| -rw-r--r-- | lisp/frameset.el | 100 | ||||
| -rw-r--r-- | lisp/mwheel.el | 59 | ||||
| -rw-r--r-- | lisp/window.el | 169 |
5 files changed, 313 insertions, 138 deletions
diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 51c43c7d21a..a507e30ca9c 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el | |||
| @@ -286,7 +286,11 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of | |||
| 286 | ;; fns.c | 286 | ;; fns.c |
| 287 | (use-dialog-box menu boolean "21.1") | 287 | (use-dialog-box menu boolean "21.1") |
| 288 | (use-file-dialog menu boolean "22.1") | 288 | (use-file-dialog menu boolean "22.1") |
| 289 | (focus-follows-mouse frames boolean "20.3") | 289 | (focus-follows-mouse |
| 290 | frames (choice | ||
| 291 | (const :tag "Off (nil)" :value nil) | ||
| 292 | (const :tag "On (t)" :value t) | ||
| 293 | (const :tag "Auto-raise" :value auto-raise)) "26.1") | ||
| 290 | ;; fontset.c | 294 | ;; fontset.c |
| 291 | ;; FIXME nil is the initial value, fontset.el setqs it. | 295 | ;; FIXME nil is the initial value, fontset.el setqs it. |
| 292 | (vertical-centering-font-regexp display | 296 | (vertical-centering-font-regexp display |
diff --git a/lisp/frame.el b/lisp/frame.el index 4768b5be002..86a0e26e393 100644 --- a/lisp/frame.el +++ b/lisp/frame.el | |||
| @@ -115,15 +115,19 @@ appended when the minibuffer frame is created." | |||
| 115 | (defun handle-delete-frame (event) | 115 | (defun handle-delete-frame (event) |
| 116 | "Handle delete-frame events from the X server." | 116 | "Handle delete-frame events from the X server." |
| 117 | (interactive "e") | 117 | (interactive "e") |
| 118 | (let ((frame (posn-window (event-start event))) | 118 | (let* ((frame (posn-window (event-start event)))) |
| 119 | (i 0) | 119 | (if (catch 'other-frame |
| 120 | (tail (frame-list))) | 120 | (dolist (frame-1 (frame-list)) |
| 121 | (while tail | 121 | ;; A valid "other" frame is visible, owns its minibuffer |
| 122 | (and (frame-visible-p (car tail)) | 122 | ;; window, has its `delete-before' parameter unset and is |
| 123 | (not (eq (car tail) frame)) | 123 | ;; not a child frame. |
| 124 | (setq i (1+ i))) | 124 | (when (and (not (eq frame-1 frame)) |
| 125 | (setq tail (cdr tail))) | 125 | (frame-visible-p frame-1) |
| 126 | (if (> i 0) | 126 | (window-live-p (minibuffer-window frame-1)) |
| 127 | (eq (window-frame (minibuffer-window frame-1)) frame-1) | ||
| 128 | (not (frame-parent frame-1)) | ||
| 129 | (not (frame-parameter frame-1 'delete-before))) | ||
| 130 | (throw 'other-frame t)))) | ||
| 127 | (delete-frame frame t) | 131 | (delete-frame frame t) |
| 128 | ;; Gildea@x.org says it is ok to ask questions before terminating. | 132 | ;; Gildea@x.org says it is ok to ask questions before terminating. |
| 129 | (save-buffers-kill-emacs)))) | 133 | (save-buffers-kill-emacs)))) |
| @@ -834,21 +838,24 @@ All frames are arranged in a cyclic order. | |||
| 834 | This command selects the frame ARG steps away in that order. | 838 | This command selects the frame ARG steps away in that order. |
| 835 | A negative ARG moves in the opposite order. | 839 | A negative ARG moves in the opposite order. |
| 836 | 840 | ||
| 837 | To make this command work properly, you must tell Emacs | 841 | To make this command work properly, you must tell Emacs how the |
| 838 | how the system (or the window manager) generally handles | 842 | system (or the window manager) generally handles focus-switching |
| 839 | focus-switching between windows. If moving the mouse onto a window | 843 | between windows. If moving the mouse onto a window selects |
| 840 | selects it (gives it focus), set `focus-follows-mouse' to t. | 844 | it (gives it focus), set `focus-follows-mouse' to t. Otherwise, |
| 841 | Otherwise, that variable should be nil." | 845 | that variable should be nil." |
| 842 | (interactive "p") | 846 | (interactive "p") |
| 843 | (let ((frame (selected-frame))) | 847 | (let ((sframe (selected-frame)) |
| 848 | (frame (selected-frame))) | ||
| 844 | (while (> arg 0) | 849 | (while (> arg 0) |
| 845 | (setq frame (next-frame frame)) | 850 | (setq frame (next-frame frame)) |
| 846 | (while (not (eq (frame-visible-p frame) t)) | 851 | (while (and (not (eq frame sframe)) |
| 852 | (not (eq (frame-visible-p frame) t))) | ||
| 847 | (setq frame (next-frame frame))) | 853 | (setq frame (next-frame frame))) |
| 848 | (setq arg (1- arg))) | 854 | (setq arg (1- arg))) |
| 849 | (while (< arg 0) | 855 | (while (< arg 0) |
| 850 | (setq frame (previous-frame frame)) | 856 | (setq frame (previous-frame frame)) |
| 851 | (while (not (eq (frame-visible-p frame) t)) | 857 | (while (and (not (eq frame sframe)) |
| 858 | (not (eq (frame-visible-p frame) t))) | ||
| 852 | (setq frame (previous-frame frame))) | 859 | (setq frame (previous-frame frame))) |
| 853 | (setq arg (1+ arg))) | 860 | (setq arg (1+ arg))) |
| 854 | (select-frame-set-input-focus frame))) | 861 | (select-frame-set-input-focus frame))) |
| @@ -1380,6 +1387,7 @@ and width values are in pixels. | |||
| 1380 | '(outer-position 0 . 0) | 1387 | '(outer-position 0 . 0) |
| 1381 | (cons 'outer-size (cons (frame-width frame) (frame-height frame))) | 1388 | (cons 'outer-size (cons (frame-width frame) (frame-height frame))) |
| 1382 | '(external-border-size 0 . 0) | 1389 | '(external-border-size 0 . 0) |
| 1390 | '(outer-border-width . 0) | ||
| 1383 | '(title-bar-size 0 . 0) | 1391 | '(title-bar-size 0 . 0) |
| 1384 | '(menu-bar-external . nil) | 1392 | '(menu-bar-external . nil) |
| 1385 | (let ((menu-bar-lines (frame-parameter frame 'menu-bar-lines))) | 1393 | (let ((menu-bar-lines (frame-parameter frame 'menu-bar-lines))) |
| @@ -1490,6 +1498,59 @@ keys and their meanings." | |||
| 1490 | for frames = (cdr (assq 'frames attributes)) | 1498 | for frames = (cdr (assq 'frames attributes)) |
| 1491 | if (memq frame frames) return attributes)) | 1499 | if (memq frame frames) return attributes)) |
| 1492 | 1500 | ||
| 1501 | (declare-function x-frame-list-z-order "xfns.c" (&optional display)) | ||
| 1502 | (declare-function w32-frame-list-z-order "w32fns.c" (&optional display)) | ||
| 1503 | |||
| 1504 | (defun frame-list-z-order (&optional display) | ||
| 1505 | "Return list of Emacs' frames, in Z (stacking) order. | ||
| 1506 | The optional argument DISPLAY specifies which display to poll. | ||
| 1507 | DISPLAY should be either a frame or a display name (a string). | ||
| 1508 | If omitted or nil, that stands for the selected frame's display. | ||
| 1509 | |||
| 1510 | Frames are listed from topmost (first) to bottommost (last). As | ||
| 1511 | a special case, if DISPLAY is non-nil and specifies a live frame, | ||
| 1512 | return the child frames of that frame in Z (stacking) order. | ||
| 1513 | |||
| 1514 | Return nil if DISPLAY contains no Emacs frame." | ||
| 1515 | (let ((frame-type (framep-on-display display))) | ||
| 1516 | (cond | ||
| 1517 | ((eq frame-type 'x) | ||
| 1518 | (x-frame-list-z-order display)) | ||
| 1519 | ((eq frame-type 'w32) | ||
| 1520 | (w32-frame-list-z-order display))))) | ||
| 1521 | |||
| 1522 | (declare-function x-frame-restack "xfns.c" (frame1 frame2 &optional above)) | ||
| 1523 | (declare-function w32-frame-restack "w32fns.c" (frame1 frame2 &optional above)) | ||
| 1524 | |||
| 1525 | (defun frame-restack (frame1 frame2 &optional above) | ||
| 1526 | "Restack FRAME1 below FRAME2. | ||
| 1527 | This implies that if both frames are visible and the display | ||
| 1528 | areas of these frames overlap, FRAME2 will (partially) obscure | ||
| 1529 | FRAME1. If the optional third argument ABOVE is non-nil, restack | ||
| 1530 | FRAME1 above FRAME2. This means that if both frames are visible | ||
| 1531 | and the display areas of these frames overlap, FRAME1 will | ||
| 1532 | \(partially) obscure FRAME2. | ||
| 1533 | |||
| 1534 | This may be thought of as an atomic action performed in two | ||
| 1535 | steps: The first step removes FRAME1's window-system window from | ||
| 1536 | the display. The second step reinserts FRAME1's window | ||
| 1537 | below (above if ABOVE is true) that of FRAME2. Hence the | ||
| 1538 | position of FRAME2 in its display's Z (stacking) order relative | ||
| 1539 | to all other frames excluding FRAME1 remains unaltered. | ||
| 1540 | |||
| 1541 | Some window managers may refuse to restack windows. " | ||
| 1542 | (if (and (frame-live-p frame1) | ||
| 1543 | (frame-live-p frame2) | ||
| 1544 | (equal (frame-parameter frame1 'display) | ||
| 1545 | (frame-parameter frame2 'display))) | ||
| 1546 | (let ((frame-type (framep-on-display frame1))) | ||
| 1547 | (cond | ||
| 1548 | ((eq frame-type 'x) | ||
| 1549 | (x-frame-restack frame1 frame2 above)) | ||
| 1550 | ((eq frame-type 'w32) | ||
| 1551 | (w32-frame-restack frame1 frame2 above)))) | ||
| 1552 | (error "Cannot restack frames"))) | ||
| 1553 | |||
| 1493 | (defun frame-size-changed-p (&optional frame) | 1554 | (defun frame-size-changed-p (&optional frame) |
| 1494 | "Return non-nil when the size of FRAME has changed. | 1555 | "Return non-nil when the size of FRAME has changed. |
| 1495 | More precisely, return non-nil when the inner width or height of | 1556 | More precisely, return non-nil when the inner width or height of |
| @@ -1886,7 +1947,7 @@ A geometry specification equivalent to SPEC for FRAME is returned, | |||
| 1886 | where the value is a cons with car `+', not numeric. | 1947 | where the value is a cons with car `+', not numeric. |
| 1887 | SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE). | 1948 | SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE). |
| 1888 | If VALUE is a number, then it is converted to a cons value, perhaps | 1949 | If VALUE is a number, then it is converted to a cons value, perhaps |
| 1889 | relative to the opposite frame edge from that in the original spec. | 1950 | relative to the opposite frame edge from that in the original spec. |
| 1890 | FRAME defaults to the selected frame. | 1951 | FRAME defaults to the selected frame. |
| 1891 | 1952 | ||
| 1892 | Examples (measures in pixels) - | 1953 | Examples (measures in pixels) - |
| @@ -1907,24 +1968,36 @@ the opposite frame edge from the edge indicated in the input spec." | |||
| 1907 | (defun delete-other-frames (&optional frame) | 1968 | (defun delete-other-frames (&optional frame) |
| 1908 | "Delete all frames on FRAME's terminal, except FRAME. | 1969 | "Delete all frames on FRAME's terminal, except FRAME. |
| 1909 | If FRAME uses another frame's minibuffer, the minibuffer frame is | 1970 | If FRAME uses another frame's minibuffer, the minibuffer frame is |
| 1910 | left untouched. FRAME must be a live frame and defaults to the | 1971 | left untouched. Do not delete any of FRAME's child frames. If |
| 1911 | selected one." | 1972 | FRAME is a child frame, delete its siblings only. FRAME must be |
| 1973 | a live frame and defaults to the selected one." | ||
| 1912 | (interactive) | 1974 | (interactive) |
| 1913 | (setq frame (window-normalize-frame frame)) | 1975 | (setq frame (window-normalize-frame frame)) |
| 1914 | (let ((minibuffer-frame (window-frame (minibuffer-window frame))) | 1976 | (let ((minibuffer-frame (window-frame (minibuffer-window frame))) |
| 1915 | (this (next-frame frame t)) | 1977 | (this (next-frame frame t)) |
| 1978 | (parent (frame-parent frame)) | ||
| 1916 | next) | 1979 | next) |
| 1917 | ;; In a first round consider minibuffer-less frames only. | 1980 | ;; In a first round consider minibuffer-less frames only. |
| 1918 | (while (not (eq this frame)) | 1981 | (while (not (eq this frame)) |
| 1919 | (setq next (next-frame this t)) | 1982 | (setq next (next-frame this t)) |
| 1920 | (unless (eq (window-frame (minibuffer-window this)) this) | 1983 | (unless (or (eq (window-frame (minibuffer-window this)) this) |
| 1984 | ;; When FRAME is a child frame, delete its siblings | ||
| 1985 | ;; only. | ||
| 1986 | (and parent (not (eq (frame-parent this) parent))) | ||
| 1987 | ;; Do not delete a child frame of FRAME. | ||
| 1988 | (eq (frame-parent this) frame)) | ||
| 1921 | (delete-frame this)) | 1989 | (delete-frame this)) |
| 1922 | (setq this next)) | 1990 | (setq this next)) |
| 1923 | ;; In a second round consider all remaining frames. | 1991 | ;; In a second round consider all remaining frames. |
| 1924 | (setq this (next-frame frame t)) | 1992 | (setq this (next-frame frame t)) |
| 1925 | (while (not (eq this frame)) | 1993 | (while (not (eq this frame)) |
| 1926 | (setq next (next-frame this t)) | 1994 | (setq next (next-frame this t)) |
| 1927 | (unless (eq this minibuffer-frame) | 1995 | (unless (or (eq this minibuffer-frame) |
| 1996 | ;; When FRAME is a child frame, delete its siblings | ||
| 1997 | ;; only. | ||
| 1998 | (and parent (not (eq (frame-parent this) parent))) | ||
| 1999 | ;; Do not delete a child frame of FRAME. | ||
| 2000 | (eq (frame-parent this) frame)) | ||
| 1928 | (delete-frame this)) | 2001 | (delete-frame this)) |
| 1929 | (setq this next)))) | 2002 | (setq this next)))) |
| 1930 | 2003 | ||
diff --git a/lisp/frameset.el b/lisp/frameset.el index 2dd3050ef76..ebf09d3ab5c 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el | |||
| @@ -446,6 +446,7 @@ DO NOT MODIFY. See `frameset-filter-alist' for a full description.") | |||
| 446 | (buffer-list . :never) | 446 | (buffer-list . :never) |
| 447 | (buffer-predicate . :never) | 447 | (buffer-predicate . :never) |
| 448 | (buried-buffer-list . :never) | 448 | (buried-buffer-list . :never) |
| 449 | (delete-before . :never) | ||
| 449 | (font . frameset-filter-shelve-param) | 450 | (font . frameset-filter-shelve-param) |
| 450 | (foreground-color . frameset-filter-sanitize-color) | 451 | (foreground-color . frameset-filter-sanitize-color) |
| 451 | (fullscreen . frameset-filter-shelve-param) | 452 | (fullscreen . frameset-filter-shelve-param) |
| @@ -455,7 +456,9 @@ DO NOT MODIFY. See `frameset-filter-alist' for a full description.") | |||
| 455 | (GUI:width . frameset-filter-unshelve-param) | 456 | (GUI:width . frameset-filter-unshelve-param) |
| 456 | (height . frameset-filter-shelve-param) | 457 | (height . frameset-filter-shelve-param) |
| 457 | (outer-window-id . :never) | 458 | (outer-window-id . :never) |
| 459 | (parent-frame . :never) | ||
| 458 | (parent-id . :never) | 460 | (parent-id . :never) |
| 461 | (mouse-wheel-frame . :never) | ||
| 459 | (tty . frameset-filter-tty-to-GUI) | 462 | (tty . frameset-filter-tty-to-GUI) |
| 460 | (tty-type . frameset-filter-tty-to-GUI) | 463 | (tty-type . frameset-filter-tty-to-GUI) |
| 461 | (width . frameset-filter-shelve-param) | 464 | (width . frameset-filter-shelve-param) |
| @@ -717,9 +720,18 @@ If nil, check all live frames." | |||
| 717 | 720 | ||
| 718 | ;; Saving framesets | 721 | ;; Saving framesets |
| 719 | 722 | ||
| 720 | (defun frameset--record-minibuffer-relationships (frame-list) | 723 | (defun frameset--record-relationships (frame-list) |
| 721 | "Process FRAME-LIST and record minibuffer relationships. | 724 | "Process FRAME-LIST and record relationships. |
| 722 | FRAME-LIST is a list of frames. Internal use only." | 725 | FRAME-LIST is a list of frames. |
| 726 | |||
| 727 | The relationships recorded for each frame are | ||
| 728 | |||
| 729 | - `minibuffer' via `frameset--mini' | ||
| 730 | - `delete-before' via `frameset--delete-before' | ||
| 731 | - `parent-frame' via `frameset--parent-frame' | ||
| 732 | - `mouse-wheel-frame' via `frameset--mouse-wheel-frame' | ||
| 733 | |||
| 734 | Internal use only." | ||
| 723 | ;; Record frames with their own minibuffer | 735 | ;; Record frames with their own minibuffer |
| 724 | (dolist (frame (minibuffer-frame-list)) | 736 | (dolist (frame (minibuffer-frame-list)) |
| 725 | (when (memq frame frame-list) | 737 | (when (memq frame frame-list) |
| @@ -730,22 +742,41 @@ FRAME-LIST is a list of frames. Internal use only." | |||
| 730 | (set-frame-parameter frame | 742 | (set-frame-parameter frame |
| 731 | 'frameset--mini | 743 | 'frameset--mini |
| 732 | (cons t (eq frame default-minibuffer-frame))))) | 744 | (cons t (eq frame default-minibuffer-frame))))) |
| 733 | ;; Now link minibufferless frames with their minibuffer frames | 745 | ;; Now link minibufferless frames with their minibuffer frames and |
| 746 | ;; store `parent-frame', `delete-before' and `mouse-wheel-frame' | ||
| 747 | ;; relationships in a similar way. | ||
| 734 | (dolist (frame frame-list) | 748 | (dolist (frame frame-list) |
| 735 | (unless (frame-parameter frame 'frameset--mini) | 749 | (let ((parent-frame (frame-parent frame)) |
| 736 | (frameset--set-id frame) | 750 | (delete-before (frame-parameter frame 'delete-before)) |
| 737 | (let ((mb-frame (window-frame (minibuffer-window frame)))) | 751 | (mouse-wheel-frame (frame-parameter frame 'mouse-wheel-frame)) |
| 738 | ;; For minibufferless frames, frameset--mini is a cons | 752 | (nomini (not (frame-parameter frame 'frameset--mini)))) |
| 739 | ;; (nil . FRAME-ID), where FRAME-ID is the frameset--id of | 753 | (when (or nomini parent-frame delete-before mouse-wheel-frame) |
| 740 | ;; the frame containing its minibuffer window. | 754 | (when nomini |
| 741 | ;; FRAME-ID can be set to nil, if FRAME-LIST doesn't contain | 755 | (frameset--set-id frame)) |
| 742 | ;; the minibuffer frame of a minibufferless frame; we allow | 756 | (when parent-frame |
| 743 | ;; it without trying to second-guess the user. | 757 | (set-frame-parameter |
| 744 | (set-frame-parameter frame | 758 | frame 'frameset--parent-frame (frameset-frame-id parent-frame))) |
| 745 | 'frameset--mini | 759 | (when delete-before |
| 746 | (cons nil | 760 | (set-frame-parameter |
| 747 | (and mb-frame | 761 | frame 'frameset--delete-before (frameset-frame-id delete-before))) |
| 748 | (frameset-frame-id mb-frame)))))))) | 762 | (when mouse-wheel-frame |
| 763 | (set-frame-parameter | ||
| 764 | frame 'frameset--mouse-wheel-frame | ||
| 765 | (frameset-frame-id mouse-wheel-frame))) | ||
| 766 | (when nomini | ||
| 767 | (let ((mb-frame (window-frame (minibuffer-window frame)))) | ||
| 768 | ;; For minibufferless frames, frameset--mini is a cons | ||
| 769 | ;; (nil . FRAME-ID), where FRAME-ID is the frameset--id of | ||
| 770 | ;; the frame containing its minibuffer window. | ||
| 771 | ;; FRAME-ID can be set to nil, if FRAME-LIST doesn't contain | ||
| 772 | ;; the minibuffer frame of a minibufferless frame; we allow | ||
| 773 | ;; it without trying to second-guess the user. | ||
| 774 | (set-frame-parameter | ||
| 775 | frame | ||
| 776 | 'frameset--mini | ||
| 777 | (cons nil | ||
| 778 | (and mb-frame | ||
| 779 | (frameset-frame-id mb-frame)))))))))) | ||
| 749 | 780 | ||
| 750 | ;;;###autoload | 781 | ;;;###autoload |
| 751 | (cl-defun frameset-save (frame-list | 782 | (cl-defun frameset-save (frame-list |
| @@ -768,7 +799,7 @@ PROPERTIES is a user-defined property list to add to the frameset." | |||
| 768 | (cl-delete-if-not predicate list) | 799 | (cl-delete-if-not predicate list) |
| 769 | list))) | 800 | list))) |
| 770 | fs) | 801 | fs) |
| 771 | (frameset--record-minibuffer-relationships frames) | 802 | (frameset--record-relationships frames) |
| 772 | (setq fs (frameset--make | 803 | (setq fs (frameset--make |
| 773 | :app app | 804 | :app app |
| 774 | :name name | 805 | :name name |
| @@ -993,6 +1024,14 @@ Internal use only." | |||
| 993 | (frameset--initial-params filtered-cfg)))) | 1024 | (frameset--initial-params filtered-cfg)))) |
| 994 | (puthash frame :created frameset--action-map)) | 1025 | (puthash frame :created frameset--action-map)) |
| 995 | 1026 | ||
| 1027 | ;; Try to assign parent-frame right here - it will improve things | ||
| 1028 | ;; for minibuffer-less child frames. | ||
| 1029 | (let* ((frame-id (frame-parameter frame 'frameset--parent-frame)) | ||
| 1030 | (parent-frame | ||
| 1031 | (and frame-id (frameset-frame-with-id frame-id)))) | ||
| 1032 | (when (frame-live-p parent-frame) | ||
| 1033 | (set-frame-parameter frame 'parent-frame parent-frame))) | ||
| 1034 | |||
| 996 | (modify-frame-parameters frame | 1035 | (modify-frame-parameters frame |
| 997 | (if (eq (frame-parameter frame 'fullscreen) fullscreen) | 1036 | (if (eq (frame-parameter frame 'fullscreen) fullscreen) |
| 998 | ;; Workaround for bug#14949 | 1037 | ;; Workaround for bug#14949 |
| @@ -1205,6 +1244,29 @@ All keyword parameters default to nil." | |||
| 1205 | (error | 1244 | (error |
| 1206 | (delay-warning 'frameset (error-message-string err) :error)))))) | 1245 | (delay-warning 'frameset (error-message-string err) :error)))))) |
| 1207 | 1246 | ||
| 1247 | ;; Setting the parent frame after the frame has been created is a | ||
| 1248 | ;; pain because one can see the frame move on the screen. Ideally, | ||
| 1249 | ;; we would restore minibuffer equipped child frames after their | ||
| 1250 | ;; respective parents have been made but this might interfere with | ||
| 1251 | ;; the reordering of minibuffer frames. Left to the experts ... | ||
| 1252 | (dolist (frame (frame-list)) | ||
| 1253 | (let* ((frame-id (frame-parameter frame 'frameset--parent-frame)) | ||
| 1254 | (parent-frame | ||
| 1255 | (and frame-id (frameset-frame-with-id frame-id)))) | ||
| 1256 | (when (and (not (eq (frame-parameter frame 'parent-frame) parent-frame)) | ||
| 1257 | (frame-live-p parent-frame)) | ||
| 1258 | (set-frame-parameter frame 'parent-frame parent-frame))) | ||
| 1259 | (let* ((frame-id (frame-parameter frame 'frameset--delete-before)) | ||
| 1260 | (delete-before | ||
| 1261 | (and frame-id (frameset-frame-with-id frame-id)))) | ||
| 1262 | (when (frame-live-p delete-before) | ||
| 1263 | (set-frame-parameter frame 'delete-before delete-before))) | ||
| 1264 | (let* ((frame-id (frame-parameter frame 'frameset--mouse-wheel-frame)) | ||
| 1265 | (mouse-wheel-frame | ||
| 1266 | (and frame-id (frameset-frame-with-id frame-id)))) | ||
| 1267 | (when (frame-live-p mouse-wheel-frame) | ||
| 1268 | (set-frame-parameter frame 'mouse-wheel-frame mouse-wheel-frame)))) | ||
| 1269 | |||
| 1208 | ;; In case we try to delete the initial frame, we want to make sure that | 1270 | ;; In case we try to delete the initial frame, we want to make sure that |
| 1209 | ;; other frames are already visible (discussed in thread for bug#14841). | 1271 | ;; other frames are already visible (discussed in thread for bug#14841). |
| 1210 | (sit-for 0 t) | 1272 | (sit-for 0 t) |
diff --git a/lisp/mwheel.el b/lisp/mwheel.el index eaeb831e844..958c6e831b7 100644 --- a/lisp/mwheel.el +++ b/lisp/mwheel.el | |||
| @@ -190,14 +190,33 @@ This can be slightly disconcerting, but some people prefer it." | |||
| 190 | This should be bound only to mouse buttons 4 and 5 on non-Windows | 190 | This should be bound only to mouse buttons 4 and 5 on non-Windows |
| 191 | systems." | 191 | systems." |
| 192 | (interactive (list last-input-event)) | 192 | (interactive (list last-input-event)) |
| 193 | (let* ((curwin (if mouse-wheel-follow-mouse | 193 | (let* ((selected-window (selected-window)) |
| 194 | (prog1 | 194 | (scroll-window |
| 195 | (selected-window) | 195 | (or (catch 'found |
| 196 | (select-window (mwheel-event-window event))))) | 196 | (let* ((window (if mouse-wheel-follow-mouse |
| 197 | (buffer (window-buffer curwin)) | 197 | (mwheel-event-window event) |
| 198 | (opoint (with-current-buffer buffer | 198 | (selected-window))) |
| 199 | (when (eq (car-safe transient-mark-mode) 'only) | 199 | (frame (when (window-live-p window) |
| 200 | (point)))) | 200 | (frame-parameter |
| 201 | (window-frame window) 'mouse-wheel-frame)))) | ||
| 202 | (when (frame-live-p frame) | ||
| 203 | (let* ((pos (mouse-absolute-pixel-position)) | ||
| 204 | (pos-x (car pos)) | ||
| 205 | (pos-y (cdr pos))) | ||
| 206 | (walk-window-tree | ||
| 207 | (lambda (window-1) | ||
| 208 | (let ((edges (window-edges window-1 nil t t))) | ||
| 209 | (when (and (<= (nth 0 edges) pos-x) | ||
| 210 | (<= pos-x (nth 2 edges)) | ||
| 211 | (<= (nth 1 edges) pos-y) | ||
| 212 | (<= pos-y (nth 3 edges))) | ||
| 213 | (throw 'found window-1)))) | ||
| 214 | frame nil t))))) | ||
| 215 | (mwheel-event-window event))) | ||
| 216 | (old-point | ||
| 217 | (and (eq scroll-window selected-window) | ||
| 218 | (eq (car-safe transient-mark-mode) 'only) | ||
| 219 | (window-point))) | ||
| 201 | (mods | 220 | (mods |
| 202 | (delq 'click (delq 'double (delq 'triple (event-modifiers event))))) | 221 | (delq 'click (delq 'double (delq 'triple (event-modifiers event))))) |
| 203 | (amt (assoc mods mouse-wheel-scroll-amount))) | 222 | (amt (assoc mods mouse-wheel-scroll-amount))) |
| @@ -232,18 +251,18 @@ systems." | |||
| 232 | ;; Make sure we do indeed scroll to the end of the buffer. | 251 | ;; Make sure we do indeed scroll to the end of the buffer. |
| 233 | (end-of-buffer (while t (funcall mwheel-scroll-up-function))))) | 252 | (end-of-buffer (while t (funcall mwheel-scroll-up-function))))) |
| 234 | (t (error "Bad binding in mwheel-scroll")))) | 253 | (t (error "Bad binding in mwheel-scroll")))) |
| 235 | (if curwin (select-window curwin))) | 254 | (if (eq scroll-window selected-window) |
| 236 | ;; If there is a temporarily active region, deactivate it if | 255 | ;; If there is a temporarily active region, deactivate it if |
| 237 | ;; scrolling moves point. | 256 | ;; scrolling moved point. |
| 238 | (when opoint | 257 | (when (and old-point (/= old-point (window-point))) |
| 239 | (with-current-buffer buffer | 258 | ;; Call `deactivate-mark' at the original position, so that |
| 240 | (when (/= opoint (point)) | 259 | ;; the original region is saved to the X selection. |
| 241 | ;; Call `deactivate-mark' at the original position, so that | 260 | (let ((new-point (window-point))) |
| 242 | ;; the original region is saved to the X selection. | 261 | (goto-char old-point) |
| 243 | (let ((newpoint (point))) | 262 | (deactivate-mark) |
| 244 | (goto-char opoint) | 263 | (goto-char new-point))) |
| 245 | (deactivate-mark) | 264 | (select-window selected-window t)))) |
| 246 | (goto-char newpoint)))))) | 265 | |
| 247 | (when (and mouse-wheel-click-event mouse-wheel-inhibit-click-time) | 266 | (when (and mouse-wheel-click-event mouse-wheel-inhibit-click-time) |
| 248 | (if mwheel-inhibit-click-event-timer | 267 | (if mwheel-inhibit-click-event-timer |
| 249 | (cancel-timer mwheel-inhibit-click-event-timer) | 268 | (cancel-timer mwheel-inhibit-click-event-timer) |
diff --git a/lisp/window.el b/lisp/window.el index 505024342ed..bea8383fcde 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -1533,7 +1533,7 @@ return the minimum pixel-size of WINDOW." | |||
| 1533 | (window-normalize-window window) horizontal ignore pixelwise)) | 1533 | (window-normalize-window window) horizontal ignore pixelwise)) |
| 1534 | 1534 | ||
| 1535 | (defun window--min-size-ignore-p (window ignore) | 1535 | (defun window--min-size-ignore-p (window ignore) |
| 1536 | "Return non-nil if IGNORE says to ignore height restrictions for WINDOW." | 1536 | "Return non-nil if IGNORE says to ignore size restrictions for WINDOW." |
| 1537 | (if (window-valid-p ignore) | 1537 | (if (window-valid-p ignore) |
| 1538 | (eq window ignore) | 1538 | (eq window ignore) |
| 1539 | (not (memq ignore '(nil preserved))))) | 1539 | (not (memq ignore '(nil preserved))))) |
| @@ -8735,13 +8735,14 @@ means suspend autoselection." | |||
| 8735 | If the mouse position has stabilized in a non-selected window, select | 8735 | If the mouse position has stabilized in a non-selected window, select |
| 8736 | that window. The minibuffer window is selected only if the minibuffer | 8736 | that window. The minibuffer window is selected only if the minibuffer |
| 8737 | is active. This function is run by `mouse-autoselect-window-timer'." | 8737 | is active. This function is run by `mouse-autoselect-window-timer'." |
| 8738 | (ignore-errors | 8738 | (let* ((mouse-position (mouse-position)) |
| 8739 | (let* ((mouse-position (mouse-position)) | 8739 | (mouse-x (and (numberp (cadr mouse-position)) |
| 8740 | (window | 8740 | (cadr mouse-position))) |
| 8741 | (ignore-errors | 8741 | (mouse-y (and (numberp (cddr mouse-position)) |
| 8742 | (window-at (cadr mouse-position) (cddr mouse-position) | 8742 | (cddr mouse-position))) |
| 8743 | (car mouse-position))))) | 8743 | (frame (and mouse-x mouse-y (car mouse-position))) |
| 8744 | (cond | 8744 | (window (and frame (window-at mouse-x mouse-y frame)))) |
| 8745 | (cond | ||
| 8745 | ((or (and (fboundp 'menu-or-popup-active-p) (menu-or-popup-active-p)) | 8746 | ((or (and (fboundp 'menu-or-popup-active-p) (menu-or-popup-active-p)) |
| 8746 | (and window | 8747 | (and window |
| 8747 | (let ((coords (coordinates-in-window-p | 8748 | (let ((coords (coordinates-in-window-p |
| @@ -8752,72 +8753,63 @@ is active. This function is run by `mouse-autoselect-window-timer'." | |||
| 8752 | ;; text region of WINDOW: Suspend autoselection temporarily. | 8753 | ;; text region of WINDOW: Suspend autoselection temporarily. |
| 8753 | (mouse-autoselect-window-start mouse-position nil t)) | 8754 | (mouse-autoselect-window-start mouse-position nil t)) |
| 8754 | ((or (eq mouse-autoselect-window-state 'suspend) | 8755 | ((or (eq mouse-autoselect-window-state 'suspend) |
| 8755 | ;; When the mouse is at its first recorded position, restart | 8756 | ;; When the mouse is at its first recorded position, restart |
| 8756 | ;; delayed autoselection. This works around a scenario with | 8757 | ;; delayed autoselection. This works around a scenario with |
| 8757 | ;; two two-window frames with identical dimensions: select the | 8758 | ;; two two-window frames with identical dimensions: select the |
| 8758 | ;; first window of the first frame, switch to the second | 8759 | ;; first window of the first frame, switch to the second |
| 8759 | ;; frame, move the mouse to its second window, minimize the | 8760 | ;; frame, move the mouse to its second window, minimize the |
| 8760 | ;; second frame. Now the second window of the first frame | 8761 | ;; second frame. Now the second window of the first frame |
| 8761 | ;; gets selected although the mouse never really "moved" into | 8762 | ;; gets selected although the mouse never really "moved" into |
| 8762 | ;; that window. | 8763 | ;; that window. |
| 8763 | (and (numberp mouse-autoselect-window) | 8764 | (and (numberp mouse-autoselect-window) |
| 8764 | (equal (mouse-position) mouse-autoselect-window-position-1))) | 8765 | (equal (mouse-position) mouse-autoselect-window-position-1))) |
| 8765 | ;; Delayed autoselection was temporarily suspended, reenable it. | 8766 | ;; Delayed autoselection was temporarily suspended, reenable it. |
| 8766 | (mouse-autoselect-window-start mouse-position)) | 8767 | (mouse-autoselect-window-start mouse-position)) |
| 8767 | ((and window (not (eq window (selected-window))) | 8768 | ((and window |
| 8768 | (or (not (numberp mouse-autoselect-window)) | 8769 | (or (not (numberp mouse-autoselect-window)) |
| 8769 | (and (>= mouse-autoselect-window 0) | 8770 | (and (>= mouse-autoselect-window 0) |
| 8770 | ;; If `mouse-autoselect-window' is non-negative, | 8771 | ;; If `mouse-autoselect-window' is non-negative, |
| 8771 | ;; select window if it's the same as before. | 8772 | ;; select window if it's the same as before. |
| 8772 | (eq window mouse-autoselect-window-window)) | 8773 | (eq window mouse-autoselect-window-window)) |
| 8773 | ;; Otherwise select window iff the mouse is at the same | 8774 | ;; Otherwise select window iff the mouse is at the same |
| 8774 | ;; position as before. Observe that the first test | 8775 | ;; position as before. Observe that the first test |
| 8775 | ;; after starting autoselection usually fails since the | 8776 | ;; after starting autoselection usually fails since the |
| 8776 | ;; value of `mouse-autoselect-window-position' recorded | 8777 | ;; value of `mouse-autoselect-window-position' recorded |
| 8777 | ;; there is the position where the mouse has entered the | 8778 | ;; there is the position where the mouse has entered the |
| 8778 | ;; new window and not necessarily where the mouse has | 8779 | ;; new window and not necessarily where the mouse has |
| 8779 | ;; stopped moving. | 8780 | ;; stopped moving. |
| 8780 | (equal mouse-position mouse-autoselect-window-position)) | 8781 | (equal mouse-position mouse-autoselect-window-position)) |
| 8781 | ;; The minibuffer is a candidate window if it's active. | 8782 | ;; The minibuffer is a candidate window if it's active. |
| 8782 | (or (not (window-minibuffer-p window)) | 8783 | (or (not (window-minibuffer-p window)) |
| 8783 | (eq window (active-minibuffer-window)))) | 8784 | (eq window (active-minibuffer-window)))) |
| 8784 | ;; Mouse position has stabilized in non-selected window: Cancel | 8785 | ;; Mouse position has stabilized in non-selected window: Cancel |
| 8785 | ;; delayed autoselection and try to select that window. | 8786 | ;; delayed autoselection and try to select that window. |
| 8786 | (mouse-autoselect-window-cancel t) | 8787 | (mouse-autoselect-window-cancel t) |
| 8787 | ;; Select window where mouse appears unless the selected window is the | 8788 | ;; Use `unread-command-events' in order to execute pre- and |
| 8788 | ;; minibuffer. Use `unread-command-events' in order to execute pre- | 8789 | ;; post-command hooks and trigger idle timers. To avoid delaying |
| 8789 | ;; and post-command hooks and trigger idle timers. To avoid delaying | 8790 | ;; autoselection again, set `mouse-autoselect-window-state'." |
| 8790 | ;; autoselection again, set `mouse-autoselect-window-state'." | 8791 | (setq mouse-autoselect-window-state 'select) |
| 8791 | (unless (window-minibuffer-p) | 8792 | (setq unread-command-events |
| 8792 | (setq mouse-autoselect-window-state 'select) | 8793 | (cons (list 'select-window (list window)) |
| 8793 | (setq unread-command-events | 8794 | unread-command-events))) |
| 8794 | (cons (list 'select-window (list window)) | 8795 | ((or (not (numberp mouse-autoselect-window)) |
| 8795 | unread-command-events)))) | 8796 | (equal mouse-position mouse-autoselect-window-position)) |
| 8796 | ((or (and window (eq window (selected-window))) | 8797 | ;; Mouse position has stabilized at |
| 8797 | (not (numberp mouse-autoselect-window)) | 8798 | ;; `mouse-autoselect-window-position': Cancel delayed |
| 8798 | (equal mouse-position mouse-autoselect-window-position)) | 8799 | ;; autoselection. |
| 8799 | ;; Mouse position has either stabilized in the selected window or at | 8800 | (mouse-autoselect-window-cancel t)) |
| 8800 | ;; `mouse-autoselect-window-position': Cancel delayed autoselection. | 8801 | (window |
| 8801 | (mouse-autoselect-window-cancel t)) | 8802 | ;; Mouse position has not stabilized yet, resume delayed |
| 8802 | (t | 8803 | ;; autoselection. |
| 8803 | ;; Mouse position has not stabilized yet, resume delayed | 8804 | (mouse-autoselect-window-start mouse-position window))))) |
| 8804 | ;; autoselection. | ||
| 8805 | (mouse-autoselect-window-start mouse-position window)))))) | ||
| 8806 | 8805 | ||
| 8807 | (defun handle-select-window (event) | 8806 | (defun handle-select-window (event) |
| 8808 | "Handle select-window events." | 8807 | "Handle select-window events." |
| 8809 | (interactive "^e") | 8808 | (interactive "^e") |
| 8810 | (let ((window (posn-window (event-start event)))) | 8809 | (let* ((window (posn-window (event-start event))) |
| 8810 | (frame (and (window-live-p window) (window-frame window))) | ||
| 8811 | (old-frame (selected-frame))) | ||
| 8811 | (unless (or (not (window-live-p window)) | 8812 | (unless (or (not (window-live-p window)) |
| 8812 | ;; Don't switch if we're currently in the minibuffer. | ||
| 8813 | ;; This tries to work around problems where the | ||
| 8814 | ;; minibuffer gets unselected unexpectedly, and where | ||
| 8815 | ;; you then have to move your mouse all the way down to | ||
| 8816 | ;; the minibuffer to select it. | ||
| 8817 | (window-minibuffer-p) | ||
| 8818 | ;; Don't switch to minibuffer window unless it's active. | ||
| 8819 | (and (window-minibuffer-p window) | ||
| 8820 | (not (minibuffer-window-active-p window))) | ||
| 8821 | ;; Don't switch when autoselection shall be delayed. | 8813 | ;; Don't switch when autoselection shall be delayed. |
| 8822 | (and (numberp mouse-autoselect-window) | 8814 | (and (numberp mouse-autoselect-window) |
| 8823 | (not (eq mouse-autoselect-window-state 'select)) | 8815 | (not (eq mouse-autoselect-window-state 'select)) |
| @@ -8830,15 +8822,40 @@ is active. This function is run by `mouse-autoselect-window-timer'." | |||
| 8830 | (mouse-autoselect-window-start position window) | 8822 | (mouse-autoselect-window-start position window) |
| 8831 | ;; Executing a command cancels delayed autoselection. | 8823 | ;; Executing a command cancels delayed autoselection. |
| 8832 | (add-hook | 8824 | (add-hook |
| 8833 | 'pre-command-hook 'mouse-autoselect-window-cancel)))) | 8825 | 'pre-command-hook 'mouse-autoselect-window-cancel))) |
| 8834 | (when mouse-autoselect-window | 8826 | ;; Don't switch to a `no-accept-focus' frame unless it's |
| 8835 | ;; Reset state of delayed autoselection. | 8827 | ;; already selected. |
| 8836 | (setq mouse-autoselect-window-state nil) | 8828 | (and (not (eq frame (selected-frame))) |
| 8837 | ;; Run `mouse-leave-buffer-hook' when autoselecting window. | 8829 | (frame-parameter frame 'no-accept-focus)) |
| 8838 | (run-hooks 'mouse-leave-buffer-hook)) | 8830 | ;; Don't switch to minibuffer window unless it's active. |
| 8831 | (and (window-minibuffer-p window) | ||
| 8832 | (not (minibuffer-window-active-p window)))) | ||
| 8833 | ;; Reset state of delayed autoselection. | ||
| 8834 | (setq mouse-autoselect-window-state nil) | ||
| 8835 | ;; Run `mouse-leave-buffer-hook' when autoselecting window. | ||
| 8836 | (run-hooks 'mouse-leave-buffer-hook) | ||
| 8839 | ;; Clear echo area. | 8837 | ;; Clear echo area. |
| 8840 | (message nil) | 8838 | (message nil) |
| 8841 | (select-window window)))) | 8839 | ;; Select the window before giving the frame focus since otherwise |
| 8840 | ;; we might get two windows with an active cursor. | ||
| 8841 | (select-window window) | ||
| 8842 | (cond | ||
| 8843 | ((or (not (memq (window-system frame) '(x w32 ns))) | ||
| 8844 | (not focus-follows-mouse) | ||
| 8845 | ;; Focus FRAME if it's either a child frame or an ancestor | ||
| 8846 | ;; of the frame switched from. | ||
| 8847 | (and (not (frame-parameter frame 'parent-frame)) | ||
| 8848 | (not (frame-ancestor-p frame old-frame))))) | ||
| 8849 | ((eq focus-follows-mouse 'auto-raise) | ||
| 8850 | ;; Focus and auto-raise frame. | ||
| 8851 | (x-focus-frame frame) | ||
| 8852 | ;; This doesn't seem to work when we move from a normal frame | ||
| 8853 | ;; right into the child frame of another frame - we should raise | ||
| 8854 | ;; that child frame's ancestor frame first ... | ||
| 8855 | (raise-frame frame)) | ||
| 8856 | (t | ||
| 8857 | ;; Just focus frame. | ||
| 8858 | (x-focus-frame frame)))))) | ||
| 8842 | 8859 | ||
| 8843 | (defun truncated-partial-width-window-p (&optional window) | 8860 | (defun truncated-partial-width-window-p (&optional window) |
| 8844 | "Return non-nil if lines in WINDOW are specifically truncated due to its width. | 8861 | "Return non-nil if lines in WINDOW are specifically truncated due to its width. |