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/frameset.el | |
| 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/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.") | |||
| 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) |