diff options
author | Martin Rudalics <rudalics@gmx.at> | 2017-04-12 10:38:25 +0200 |
---|---|---|
committer | Martin Rudalics <rudalics@gmx.at> | 2017-04-12 10:38:25 +0200 |
commit | 3fdd3bb56c006a2a24761b8fcea0cbd9b0cba422 (patch) | |
tree | a0b8f5e431ba812b4fe69261a8515e973a3e7ed3 /lisp/frameset.el | |
parent | 449bc49c768a4733411c7e05186be7efc163cd7c (diff) | |
download | emacs-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.el | 100 |
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) |