summaryrefslogtreecommitdiff
path: root/lisp/window.el
diff options
context:
space:
mode:
authorMartin Rudalics <rudalics@gmx.at>2017-04-12 10:38:25 +0200
committerMartin Rudalics <rudalics@gmx.at>2017-04-12 10:38:25 +0200
commit3fdd3bb56c006a2a24761b8fcea0cbd9b0cba422 (patch)
treea0b8f5e431ba812b4fe69261a8515e973a3e7ed3 /lisp/window.el
parent449bc49c768a4733411c7e05186be7efc163cd7c (diff)
downloademacs-3fdd3bb56c006a2a24761b8fcea0cbd9b0cba422.tar.gz
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/window.el')
-rw-r--r--lisp/window.el169
1 files changed, 93 insertions, 76 deletions
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."
(window-normalize-window window) horizontal ignore pixelwise))
(defun window--min-size-ignore-p (window ignore)
- "Return non-nil if IGNORE says to ignore height restrictions for WINDOW."
+ "Return non-nil if IGNORE says to ignore size restrictions for WINDOW."
(if (window-valid-p ignore)
(eq window ignore)
(not (memq ignore '(nil preserved)))))
@@ -8735,13 +8735,14 @@ means suspend autoselection."
If the mouse position has stabilized in a non-selected window, select
that window. The minibuffer window is selected only if the minibuffer
is active. This function is run by `mouse-autoselect-window-timer'."
- (ignore-errors
- (let* ((mouse-position (mouse-position))
- (window
- (ignore-errors
- (window-at (cadr mouse-position) (cddr mouse-position)
- (car mouse-position)))))
- (cond
+ (let* ((mouse-position (mouse-position))
+ (mouse-x (and (numberp (cadr mouse-position))
+ (cadr mouse-position)))
+ (mouse-y (and (numberp (cddr mouse-position))
+ (cddr mouse-position)))
+ (frame (and mouse-x mouse-y (car mouse-position)))
+ (window (and frame (window-at mouse-x mouse-y frame))))
+ (cond
((or (and (fboundp 'menu-or-popup-active-p) (menu-or-popup-active-p))
(and window
(let ((coords (coordinates-in-window-p
@@ -8752,72 +8753,63 @@ is active. This function is run by `mouse-autoselect-window-timer'."
;; text region of WINDOW: Suspend autoselection temporarily.
(mouse-autoselect-window-start mouse-position nil t))
((or (eq mouse-autoselect-window-state 'suspend)
- ;; When the mouse is at its first recorded position, restart
- ;; delayed autoselection. This works around a scenario with
- ;; two two-window frames with identical dimensions: select the
- ;; first window of the first frame, switch to the second
- ;; frame, move the mouse to its second window, minimize the
- ;; second frame. Now the second window of the first frame
- ;; gets selected although the mouse never really "moved" into
- ;; that window.
- (and (numberp mouse-autoselect-window)
- (equal (mouse-position) mouse-autoselect-window-position-1)))
- ;; Delayed autoselection was temporarily suspended, reenable it.
- (mouse-autoselect-window-start mouse-position))
- ((and window (not (eq window (selected-window)))
- (or (not (numberp mouse-autoselect-window))
- (and (>= mouse-autoselect-window 0)
- ;; If `mouse-autoselect-window' is non-negative,
- ;; select window if it's the same as before.
- (eq window mouse-autoselect-window-window))
- ;; Otherwise select window iff the mouse is at the same
- ;; position as before. Observe that the first test
- ;; after starting autoselection usually fails since the
- ;; value of `mouse-autoselect-window-position' recorded
- ;; there is the position where the mouse has entered the
- ;; new window and not necessarily where the mouse has
- ;; stopped moving.
- (equal mouse-position mouse-autoselect-window-position))
- ;; The minibuffer is a candidate window if it's active.
- (or (not (window-minibuffer-p window))
- (eq window (active-minibuffer-window))))
- ;; Mouse position has stabilized in non-selected window: Cancel
- ;; delayed autoselection and try to select that window.
- (mouse-autoselect-window-cancel t)
- ;; Select window where mouse appears unless the selected window is the
- ;; minibuffer. Use `unread-command-events' in order to execute pre-
- ;; and post-command hooks and trigger idle timers. To avoid delaying
- ;; autoselection again, set `mouse-autoselect-window-state'."
- (unless (window-minibuffer-p)
- (setq mouse-autoselect-window-state 'select)
- (setq unread-command-events
- (cons (list 'select-window (list window))
- unread-command-events))))
- ((or (and window (eq window (selected-window)))
- (not (numberp mouse-autoselect-window))
- (equal mouse-position mouse-autoselect-window-position))
- ;; Mouse position has either stabilized in the selected window or at
- ;; `mouse-autoselect-window-position': Cancel delayed autoselection.
- (mouse-autoselect-window-cancel t))
- (t
- ;; Mouse position has not stabilized yet, resume delayed
- ;; autoselection.
- (mouse-autoselect-window-start mouse-position window))))))
+ ;; When the mouse is at its first recorded position, restart
+ ;; delayed autoselection. This works around a scenario with
+ ;; two two-window frames with identical dimensions: select the
+ ;; first window of the first frame, switch to the second
+ ;; frame, move the mouse to its second window, minimize the
+ ;; second frame. Now the second window of the first frame
+ ;; gets selected although the mouse never really "moved" into
+ ;; that window.
+ (and (numberp mouse-autoselect-window)
+ (equal (mouse-position) mouse-autoselect-window-position-1)))
+ ;; Delayed autoselection was temporarily suspended, reenable it.
+ (mouse-autoselect-window-start mouse-position))
+ ((and window
+ (or (not (numberp mouse-autoselect-window))
+ (and (>= mouse-autoselect-window 0)
+ ;; If `mouse-autoselect-window' is non-negative,
+ ;; select window if it's the same as before.
+ (eq window mouse-autoselect-window-window))
+ ;; Otherwise select window iff the mouse is at the same
+ ;; position as before. Observe that the first test
+ ;; after starting autoselection usually fails since the
+ ;; value of `mouse-autoselect-window-position' recorded
+ ;; there is the position where the mouse has entered the
+ ;; new window and not necessarily where the mouse has
+ ;; stopped moving.
+ (equal mouse-position mouse-autoselect-window-position))
+ ;; The minibuffer is a candidate window if it's active.
+ (or (not (window-minibuffer-p window))
+ (eq window (active-minibuffer-window))))
+ ;; Mouse position has stabilized in non-selected window: Cancel
+ ;; delayed autoselection and try to select that window.
+ (mouse-autoselect-window-cancel t)
+ ;; Use `unread-command-events' in order to execute pre- and
+ ;; post-command hooks and trigger idle timers. To avoid delaying
+ ;; autoselection again, set `mouse-autoselect-window-state'."
+ (setq mouse-autoselect-window-state 'select)
+ (setq unread-command-events
+ (cons (list 'select-window (list window))
+ unread-command-events)))
+ ((or (not (numberp mouse-autoselect-window))
+ (equal mouse-position mouse-autoselect-window-position))
+ ;; Mouse position has stabilized at
+ ;; `mouse-autoselect-window-position': Cancel delayed
+ ;; autoselection.
+ (mouse-autoselect-window-cancel t))
+ (window
+ ;; Mouse position has not stabilized yet, resume delayed
+ ;; autoselection.
+ (mouse-autoselect-window-start mouse-position window)))))
(defun handle-select-window (event)
"Handle select-window events."
(interactive "^e")
- (let ((window (posn-window (event-start event))))
+ (let* ((window (posn-window (event-start event)))
+ (frame (and (window-live-p window) (window-frame window)))
+ (old-frame (selected-frame)))
(unless (or (not (window-live-p window))
- ;; Don't switch if we're currently in the minibuffer.
- ;; This tries to work around problems where the
- ;; minibuffer gets unselected unexpectedly, and where
- ;; you then have to move your mouse all the way down to
- ;; the minibuffer to select it.
- (window-minibuffer-p)
- ;; Don't switch to minibuffer window unless it's active.
- (and (window-minibuffer-p window)
- (not (minibuffer-window-active-p window)))
;; Don't switch when autoselection shall be delayed.
(and (numberp mouse-autoselect-window)
(not (eq mouse-autoselect-window-state 'select))
@@ -8830,15 +8822,40 @@ is active. This function is run by `mouse-autoselect-window-timer'."
(mouse-autoselect-window-start position window)
;; Executing a command cancels delayed autoselection.
(add-hook
- 'pre-command-hook 'mouse-autoselect-window-cancel))))
- (when mouse-autoselect-window
- ;; Reset state of delayed autoselection.
- (setq mouse-autoselect-window-state nil)
- ;; Run `mouse-leave-buffer-hook' when autoselecting window.
- (run-hooks 'mouse-leave-buffer-hook))
+ 'pre-command-hook 'mouse-autoselect-window-cancel)))
+ ;; Don't switch to a `no-accept-focus' frame unless it's
+ ;; already selected.
+ (and (not (eq frame (selected-frame)))
+ (frame-parameter frame 'no-accept-focus))
+ ;; Don't switch to minibuffer window unless it's active.
+ (and (window-minibuffer-p window)
+ (not (minibuffer-window-active-p window))))
+ ;; Reset state of delayed autoselection.
+ (setq mouse-autoselect-window-state nil)
+ ;; Run `mouse-leave-buffer-hook' when autoselecting window.
+ (run-hooks 'mouse-leave-buffer-hook)
;; Clear echo area.
(message nil)
- (select-window window))))
+ ;; Select the window before giving the frame focus since otherwise
+ ;; we might get two windows with an active cursor.
+ (select-window window)
+ (cond
+ ((or (not (memq (window-system frame) '(x w32 ns)))
+ (not focus-follows-mouse)
+ ;; Focus FRAME if it's either a child frame or an ancestor
+ ;; of the frame switched from.
+ (and (not (frame-parameter frame 'parent-frame))
+ (not (frame-ancestor-p frame old-frame)))))
+ ((eq focus-follows-mouse 'auto-raise)
+ ;; Focus and auto-raise frame.
+ (x-focus-frame frame)
+ ;; This doesn't seem to work when we move from a normal frame
+ ;; right into the child frame of another frame - we should raise
+ ;; that child frame's ancestor frame first ...
+ (raise-frame frame))
+ (t
+ ;; Just focus frame.
+ (x-focus-frame frame))))))
(defun truncated-partial-width-window-p (&optional window)
"Return non-nil if lines in WINDOW are specifically truncated due to its width.