summaryrefslogtreecommitdiff
path: root/lisp/frameset.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/frameset.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/frameset.el')
-rw-r--r--lisp/frameset.el100
1 files changed, 81 insertions, 19 deletions
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.")
(buffer-list . :never)
(buffer-predicate . :never)
(buried-buffer-list . :never)
+ (delete-before . :never)
(font . frameset-filter-shelve-param)
(foreground-color . frameset-filter-sanitize-color)
(fullscreen . frameset-filter-shelve-param)
@@ -455,7 +456,9 @@ DO NOT MODIFY. See `frameset-filter-alist' for a full description.")
(GUI:width . frameset-filter-unshelve-param)
(height . frameset-filter-shelve-param)
(outer-window-id . :never)
+ (parent-frame . :never)
(parent-id . :never)
+ (mouse-wheel-frame . :never)
(tty . frameset-filter-tty-to-GUI)
(tty-type . frameset-filter-tty-to-GUI)
(width . frameset-filter-shelve-param)
@@ -717,9 +720,18 @@ If nil, check all live frames."
;; Saving framesets
-(defun frameset--record-minibuffer-relationships (frame-list)
- "Process FRAME-LIST and record minibuffer relationships.
-FRAME-LIST is a list of frames. Internal use only."
+(defun frameset--record-relationships (frame-list)
+ "Process FRAME-LIST and record relationships.
+FRAME-LIST is a list of frames.
+
+The relationships recorded for each frame are
+
+- `minibuffer' via `frameset--mini'
+- `delete-before' via `frameset--delete-before'
+- `parent-frame' via `frameset--parent-frame'
+- `mouse-wheel-frame' via `frameset--mouse-wheel-frame'
+
+Internal use only."
;; Record frames with their own minibuffer
(dolist (frame (minibuffer-frame-list))
(when (memq frame frame-list)
@@ -730,22 +742,41 @@ FRAME-LIST is a list of frames. Internal use only."
(set-frame-parameter frame
'frameset--mini
(cons t (eq frame default-minibuffer-frame)))))
- ;; Now link minibufferless frames with their minibuffer frames
+ ;; Now link minibufferless frames with their minibuffer frames and
+ ;; store `parent-frame', `delete-before' and `mouse-wheel-frame'
+ ;; relationships in a similar way.
(dolist (frame frame-list)
- (unless (frame-parameter frame 'frameset--mini)
- (frameset--set-id frame)
- (let ((mb-frame (window-frame (minibuffer-window frame))))
- ;; For minibufferless frames, frameset--mini is a cons
- ;; (nil . FRAME-ID), where FRAME-ID is the frameset--id of
- ;; the frame containing its minibuffer window.
- ;; FRAME-ID can be set to nil, if FRAME-LIST doesn't contain
- ;; the minibuffer frame of a minibufferless frame; we allow
- ;; it without trying to second-guess the user.
- (set-frame-parameter frame
- 'frameset--mini
- (cons nil
- (and mb-frame
- (frameset-frame-id mb-frame))))))))
+ (let ((parent-frame (frame-parent frame))
+ (delete-before (frame-parameter frame 'delete-before))
+ (mouse-wheel-frame (frame-parameter frame 'mouse-wheel-frame))
+ (nomini (not (frame-parameter frame 'frameset--mini))))
+ (when (or nomini parent-frame delete-before mouse-wheel-frame)
+ (when nomini
+ (frameset--set-id frame))
+ (when parent-frame
+ (set-frame-parameter
+ frame 'frameset--parent-frame (frameset-frame-id parent-frame)))
+ (when delete-before
+ (set-frame-parameter
+ frame 'frameset--delete-before (frameset-frame-id delete-before)))
+ (when mouse-wheel-frame
+ (set-frame-parameter
+ frame 'frameset--mouse-wheel-frame
+ (frameset-frame-id mouse-wheel-frame)))
+ (when nomini
+ (let ((mb-frame (window-frame (minibuffer-window frame))))
+ ;; For minibufferless frames, frameset--mini is a cons
+ ;; (nil . FRAME-ID), where FRAME-ID is the frameset--id of
+ ;; the frame containing its minibuffer window.
+ ;; FRAME-ID can be set to nil, if FRAME-LIST doesn't contain
+ ;; the minibuffer frame of a minibufferless frame; we allow
+ ;; it without trying to second-guess the user.
+ (set-frame-parameter
+ frame
+ 'frameset--mini
+ (cons nil
+ (and mb-frame
+ (frameset-frame-id mb-frame))))))))))
;;;###autoload
(cl-defun frameset-save (frame-list
@@ -768,7 +799,7 @@ PROPERTIES is a user-defined property list to add to the frameset."
(cl-delete-if-not predicate list)
list)))
fs)
- (frameset--record-minibuffer-relationships frames)
+ (frameset--record-relationships frames)
(setq fs (frameset--make
:app app
:name name
@@ -993,6 +1024,14 @@ Internal use only."
(frameset--initial-params filtered-cfg))))
(puthash frame :created frameset--action-map))
+ ;; Try to assign parent-frame right here - it will improve things
+ ;; for minibuffer-less child frames.
+ (let* ((frame-id (frame-parameter frame 'frameset--parent-frame))
+ (parent-frame
+ (and frame-id (frameset-frame-with-id frame-id))))
+ (when (frame-live-p parent-frame)
+ (set-frame-parameter frame 'parent-frame parent-frame)))
+
(modify-frame-parameters frame
(if (eq (frame-parameter frame 'fullscreen) fullscreen)
;; Workaround for bug#14949
@@ -1205,6 +1244,29 @@ All keyword parameters default to nil."
(error
(delay-warning 'frameset (error-message-string err) :error))))))
+ ;; Setting the parent frame after the frame has been created is a
+ ;; pain because one can see the frame move on the screen. Ideally,
+ ;; we would restore minibuffer equipped child frames after their
+ ;; respective parents have been made but this might interfere with
+ ;; the reordering of minibuffer frames. Left to the experts ...
+ (dolist (frame (frame-list))
+ (let* ((frame-id (frame-parameter frame 'frameset--parent-frame))
+ (parent-frame
+ (and frame-id (frameset-frame-with-id frame-id))))
+ (when (and (not (eq (frame-parameter frame 'parent-frame) parent-frame))
+ (frame-live-p parent-frame))
+ (set-frame-parameter frame 'parent-frame parent-frame)))
+ (let* ((frame-id (frame-parameter frame 'frameset--delete-before))
+ (delete-before
+ (and frame-id (frameset-frame-with-id frame-id))))
+ (when (frame-live-p delete-before)
+ (set-frame-parameter frame 'delete-before delete-before)))
+ (let* ((frame-id (frame-parameter frame 'frameset--mouse-wheel-frame))
+ (mouse-wheel-frame
+ (and frame-id (frameset-frame-with-id frame-id))))
+ (when (frame-live-p mouse-wheel-frame)
+ (set-frame-parameter frame 'mouse-wheel-frame mouse-wheel-frame))))
+
;; In case we try to delete the initial frame, we want to make sure that
;; other frames are already visible (discussed in thread for bug#14841).
(sit-for 0 t)