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 /src/xterm.c | |
| 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 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 389 |
1 files changed, 325 insertions, 64 deletions
diff --git a/src/xterm.c b/src/xterm.c index 1d14407aa43..4444a5c187a 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -945,11 +945,14 @@ x_set_frame_alpha (struct frame *f) | |||
| 945 | Do this unconditionally as this function is called on reparent when | 945 | Do this unconditionally as this function is called on reparent when |
| 946 | alpha has not changed on the frame. */ | 946 | alpha has not changed on the frame. */ |
| 947 | 947 | ||
| 948 | parent = x_find_topmost_parent (f); | 948 | if (!FRAME_PARENT_FRAME (f)) |
| 949 | if (parent != None) | 949 | { |
| 950 | XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity, | 950 | parent = x_find_topmost_parent (f); |
| 951 | XA_CARDINAL, 32, PropModeReplace, | 951 | if (parent != None) |
| 952 | (unsigned char *) &opac, 1); | 952 | XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity, |
| 953 | XA_CARDINAL, 32, PropModeReplace, | ||
| 954 | (unsigned char *) &opac, 1); | ||
| 955 | } | ||
| 953 | 956 | ||
| 954 | /* return unless necessary */ | 957 | /* return unless necessary */ |
| 955 | { | 958 | { |
| @@ -4964,6 +4967,9 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, | |||
| 4964 | containing the pointer. */ | 4967 | containing the pointer. */ |
| 4965 | { | 4968 | { |
| 4966 | Window win, child; | 4969 | Window win, child; |
| 4970 | #ifdef USE_GTK | ||
| 4971 | Window first_win = 0; | ||
| 4972 | #endif | ||
| 4967 | int win_x, win_y; | 4973 | int win_x, win_y; |
| 4968 | int parent_x = 0, parent_y = 0; | 4974 | int parent_x = 0, parent_y = 0; |
| 4969 | 4975 | ||
| @@ -5010,20 +5016,37 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, | |||
| 5010 | &child); | 5016 | &child); |
| 5011 | 5017 | ||
| 5012 | if (child == None || child == win) | 5018 | if (child == None || child == win) |
| 5013 | break; | 5019 | { |
| 5020 | #ifdef USE_GTK | ||
| 5021 | /* On GTK we have not inspected WIN yet. If it has | ||
| 5022 | a frame and that frame has a parent, use it. */ | ||
| 5023 | struct frame *f = x_window_to_frame (dpyinfo, win); | ||
| 5024 | |||
| 5025 | if (f && FRAME_PARENT_FRAME (f)) | ||
| 5026 | first_win = win; | ||
| 5027 | #endif | ||
| 5028 | break; | ||
| 5029 | } | ||
| 5014 | #ifdef USE_GTK | 5030 | #ifdef USE_GTK |
| 5015 | /* We don't wan't to know the innermost window. We | 5031 | /* We don't wan't to know the innermost window. We |
| 5016 | want the edit window. For non-Gtk+ the innermost | 5032 | want the edit window. For non-Gtk+ the innermost |
| 5017 | window is the edit window. For Gtk+ it might not | 5033 | window is the edit window. For Gtk+ it might not |
| 5018 | be. It might be the tool bar for example. */ | 5034 | be. It might be the tool bar for example. */ |
| 5019 | if (x_window_to_frame (dpyinfo, win)) | 5035 | if (x_window_to_frame (dpyinfo, win)) |
| 5020 | break; | 5036 | /* But don't hurry. We might find a child frame |
| 5037 | beneath. */ | ||
| 5038 | first_win = win; | ||
| 5021 | #endif | 5039 | #endif |
| 5022 | win = child; | 5040 | win = child; |
| 5023 | parent_x = win_x; | 5041 | parent_x = win_x; |
| 5024 | parent_y = win_y; | 5042 | parent_y = win_y; |
| 5025 | } | 5043 | } |
| 5026 | 5044 | ||
| 5045 | #ifdef USE_GTK | ||
| 5046 | if (first_win) | ||
| 5047 | win = first_win; | ||
| 5048 | #endif | ||
| 5049 | |||
| 5027 | /* Now we know that: | 5050 | /* Now we know that: |
| 5028 | win is the innermost window containing the pointer | 5051 | win is the innermost window containing the pointer |
| 5029 | (XTC says it has no child containing the pointer), | 5052 | (XTC says it has no child containing the pointer), |
| @@ -6496,10 +6519,14 @@ x_scroll_bar_create (struct window *w, int top, int left, | |||
| 6496 | Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); | 6519 | Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); |
| 6497 | XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0); | 6520 | XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0); |
| 6498 | XtMapWidget (scroll_bar); | 6521 | XtMapWidget (scroll_bar); |
| 6522 | /* Don't obscure any child frames. */ | ||
| 6523 | XLowerWindow (FRAME_X_DISPLAY (f), bar->x_window); | ||
| 6499 | #endif /* not USE_GTK */ | 6524 | #endif /* not USE_GTK */ |
| 6500 | } | 6525 | } |
| 6501 | #else /* not USE_TOOLKIT_SCROLL_BARS */ | 6526 | #else /* not USE_TOOLKIT_SCROLL_BARS */ |
| 6502 | XMapRaised (FRAME_X_DISPLAY (f), bar->x_window); | 6527 | XMapWindow (FRAME_X_DISPLAY (f), bar->x_window); |
| 6528 | /* Don't obscure any child frames. */ | ||
| 6529 | XLowerWindow (FRAME_X_DISPLAY (f), bar->x_window); | ||
| 6503 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | 6530 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ |
| 6504 | 6531 | ||
| 6505 | unblock_input (); | 6532 | unblock_input (); |
| @@ -7067,10 +7094,10 @@ x_scroll_bar_expose (struct scroll_bar *bar, const XEvent *event) | |||
| 7067 | /* x, y, width, height */ | 7094 | /* x, y, width, height */ |
| 7068 | 0, 0, bar->width - 1, bar->height - 1); | 7095 | 0, 0, bar->width - 1, bar->height - 1); |
| 7069 | 7096 | ||
| 7070 | /* Restore the foreground color of the GC if we changed it above. */ | 7097 | /* Restore the foreground color of the GC if we changed it above. */ |
| 7071 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) | 7098 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) |
| 7072 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 7099 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 7073 | FRAME_FOREGROUND_PIXEL (f)); | 7100 | FRAME_FOREGROUND_PIXEL (f)); |
| 7074 | 7101 | ||
| 7075 | unblock_input (); | 7102 | unblock_input (); |
| 7076 | 7103 | ||
| @@ -7839,8 +7866,21 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 7839 | f = x_top_window_to_frame (dpyinfo, event->xreparent.window); | 7866 | f = x_top_window_to_frame (dpyinfo, event->xreparent.window); |
| 7840 | if (f) | 7867 | if (f) |
| 7841 | { | 7868 | { |
| 7842 | f->output_data.x->parent_desc = event->xreparent.parent; | 7869 | /* Maybe we shouldn't set this for child frames ?? */ |
| 7843 | x_real_positions (f, &f->left_pos, &f->top_pos); | 7870 | f->output_data.x->parent_desc = event->xreparent.parent; |
| 7871 | if (!FRAME_PARENT_FRAME (f)) | ||
| 7872 | x_real_positions (f, &f->left_pos, &f->top_pos); | ||
| 7873 | else | ||
| 7874 | { | ||
| 7875 | Window root; | ||
| 7876 | unsigned int dummy_uint; | ||
| 7877 | |||
| 7878 | block_input (); | ||
| 7879 | XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 7880 | &root, &f->left_pos, &f->top_pos, | ||
| 7881 | &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint); | ||
| 7882 | unblock_input (); | ||
| 7883 | } | ||
| 7844 | 7884 | ||
| 7845 | /* Perhaps reparented due to a WM restart. Reset this. */ | 7885 | /* Perhaps reparented due to a WM restart. Reset this. */ |
| 7846 | FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; | 7886 | FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; |
| @@ -8000,7 +8040,26 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8000 | /* Check if fullscreen was specified before we where mapped the | 8040 | /* Check if fullscreen was specified before we where mapped the |
| 8001 | first time, i.e. from the command line. */ | 8041 | first time, i.e. from the command line. */ |
| 8002 | if (!f->output_data.x->has_been_visible) | 8042 | if (!f->output_data.x->has_been_visible) |
| 8003 | x_check_fullscreen (f); | 8043 | { |
| 8044 | |||
| 8045 | x_check_fullscreen (f); | ||
| 8046 | #ifndef USE_GTK | ||
| 8047 | /* For systems that cannot synthesize `skip_taskbar' for | ||
| 8048 | unmapped windows do the following. */ | ||
| 8049 | if (FRAME_SKIP_TASKBAR (f)) | ||
| 8050 | x_set_skip_taskbar (f, Qt, Qnil); | ||
| 8051 | #endif /* Not USE_GTK */ | ||
| 8052 | } | ||
| 8053 | |||
| 8054 | if (!iconified) | ||
| 8055 | { | ||
| 8056 | /* The `z-group' is reset every time a frame becomes | ||
| 8057 | invisible. Handle this here. */ | ||
| 8058 | if (FRAME_Z_GROUP (f) == z_group_above) | ||
| 8059 | x_set_z_group (f, Qabove, Qnil); | ||
| 8060 | else if (FRAME_Z_GROUP (f) == z_group_below) | ||
| 8061 | x_set_z_group (f, Qbelow, Qnil); | ||
| 8062 | } | ||
| 8004 | 8063 | ||
| 8005 | SET_FRAME_VISIBLE (f, 1); | 8064 | SET_FRAME_VISIBLE (f, 1); |
| 8006 | SET_FRAME_ICONIFIED (f, false); | 8065 | SET_FRAME_ICONIFIED (f, false); |
| @@ -8444,34 +8503,46 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8444 | #endif | 8503 | #endif |
| 8445 | if (f) | 8504 | if (f) |
| 8446 | { | 8505 | { |
| 8447 | 8506 | /* Maybe generate a SELECT_WINDOW_EVENT for | |
| 8448 | /* Generate SELECT_WINDOW_EVENTs when needed. | 8507 | `mouse-autoselect-window' but don't let popup menus |
| 8449 | Don't let popup menus influence things (bug#1261). */ | 8508 | interfere with this (Bug#1261). */ |
| 8450 | if (!NILP (Vmouse_autoselect_window) && !popup_activated ()) | 8509 | if (!NILP (Vmouse_autoselect_window) |
| 8510 | && !popup_activated () | ||
| 8511 | /* Don't switch if we're currently in the minibuffer. | ||
| 8512 | This tries to work around problems where the | ||
| 8513 | minibuffer gets unselected unexpectedly, and where | ||
| 8514 | you then have to move your mouse all the way down to | ||
| 8515 | the minibuffer to select it. */ | ||
| 8516 | && !MINI_WINDOW_P (XWINDOW (selected_window)) | ||
| 8517 | /* With `focus-follows-mouse' non-nil create an event | ||
| 8518 | also when the target window is on another frame. */ | ||
| 8519 | && (f == XFRAME (selected_frame) | ||
| 8520 | || !NILP (focus_follows_mouse))) | ||
| 8451 | { | 8521 | { |
| 8452 | static Lisp_Object last_mouse_window; | 8522 | static Lisp_Object last_mouse_window; |
| 8453 | Lisp_Object window = window_from_coordinates | 8523 | Lisp_Object window = window_from_coordinates |
| 8454 | (f, event->xmotion.x, event->xmotion.y, 0, false); | 8524 | (f, event->xmotion.x, event->xmotion.y, 0, false); |
| 8455 | 8525 | ||
| 8456 | /* Window will be selected only when it is not selected now and | 8526 | /* A window will be autoselected only when it is not |
| 8457 | last mouse movement event was not in it. Minibuffer window | 8527 | selected now and the last mouse movement event was |
| 8458 | will be selected only when it is active. */ | 8528 | not in it. The remainder of the code is a bit vague |
| 8529 | wrt what a "window" is. For immediate autoselection, | ||
| 8530 | the window is usually the entire window but for GTK | ||
| 8531 | where the scroll bars don't count. For delayed | ||
| 8532 | autoselection the window is usually the window's text | ||
| 8533 | area including the margins. */ | ||
| 8459 | if (WINDOWP (window) | 8534 | if (WINDOWP (window) |
| 8460 | && !EQ (window, last_mouse_window) | 8535 | && !EQ (window, last_mouse_window) |
| 8461 | && !EQ (window, selected_window) | 8536 | && !EQ (window, selected_window)) |
| 8462 | /* For click-to-focus window managers | ||
| 8463 | create event iff we don't leave the | ||
| 8464 | selected frame. */ | ||
| 8465 | && (focus_follows_mouse | ||
| 8466 | || (EQ (XWINDOW (window)->frame, | ||
| 8467 | XWINDOW (selected_window)->frame)))) | ||
| 8468 | { | 8537 | { |
| 8469 | inev.ie.kind = SELECT_WINDOW_EVENT; | 8538 | inev.ie.kind = SELECT_WINDOW_EVENT; |
| 8470 | inev.ie.frame_or_window = window; | 8539 | inev.ie.frame_or_window = window; |
| 8471 | } | 8540 | } |
| 8541 | |||
| 8472 | /* Remember the last window where we saw the mouse. */ | 8542 | /* Remember the last window where we saw the mouse. */ |
| 8473 | last_mouse_window = window; | 8543 | last_mouse_window = window; |
| 8474 | } | 8544 | } |
| 8545 | |||
| 8475 | if (!note_mouse_movement (f, &event->xmotion)) | 8546 | if (!note_mouse_movement (f, &event->xmotion)) |
| 8476 | help_echo_string = previous_help_echo_string; | 8547 | help_echo_string = previous_help_echo_string; |
| 8477 | } | 8548 | } |
| @@ -8621,7 +8692,19 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8621 | 8692 | ||
| 8622 | XSETFRAME (frame, f); | 8693 | XSETFRAME (frame, f); |
| 8623 | 8694 | ||
| 8624 | x_real_positions (f, &f->left_pos, &f->top_pos); | 8695 | if (!FRAME_PARENT_FRAME (f)) |
| 8696 | x_real_positions (f, &f->left_pos, &f->top_pos); | ||
| 8697 | else | ||
| 8698 | { | ||
| 8699 | Window root; | ||
| 8700 | unsigned int dummy_uint; | ||
| 8701 | |||
| 8702 | block_input (); | ||
| 8703 | XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 8704 | &root, &f->left_pos, &f->top_pos, | ||
| 8705 | &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint); | ||
| 8706 | unblock_input (); | ||
| 8707 | } | ||
| 8625 | 8708 | ||
| 8626 | if (old_left != f->left_pos || old_top != f->top_pos) | 8709 | if (old_left != f->left_pos || old_top != f->top_pos) |
| 8627 | { | 8710 | { |
| @@ -8650,8 +8733,35 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8650 | dpyinfo->last_mouse_glyph_frame = NULL; | 8733 | dpyinfo->last_mouse_glyph_frame = NULL; |
| 8651 | x_display_set_last_user_time (dpyinfo, event->xbutton.time); | 8734 | x_display_set_last_user_time (dpyinfo, event->xbutton.time); |
| 8652 | 8735 | ||
| 8653 | f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame | 8736 | if (x_mouse_grabbed (dpyinfo)) |
| 8654 | : x_window_to_frame (dpyinfo, event->xbutton.window)); | 8737 | f = dpyinfo->last_mouse_frame; |
| 8738 | else | ||
| 8739 | { | ||
| 8740 | f = x_window_to_frame (dpyinfo, event->xbutton.window); | ||
| 8741 | |||
| 8742 | if (f && event->xbutton.type == ButtonPress | ||
| 8743 | && !popup_activated () | ||
| 8744 | && !x_window_to_scroll_bar (event->xbutton.display, | ||
| 8745 | event->xbutton.window, 2) | ||
| 8746 | && !FRAME_NO_ACCEPT_FOCUS (f)) | ||
| 8747 | { | ||
| 8748 | /* When clicking into a child frame or when clicking | ||
| 8749 | into a parent frame with the child frame selected and | ||
| 8750 | `no-accept-focus' is not set, select the clicked | ||
| 8751 | frame. */ | ||
| 8752 | struct frame *hf = dpyinfo->x_highlight_frame; | ||
| 8753 | |||
| 8754 | if (FRAME_PARENT_FRAME (f) || frame_ancestor_p (f, hf)) | ||
| 8755 | { | ||
| 8756 | block_input (); | ||
| 8757 | XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 8758 | RevertToParent, CurrentTime); | ||
| 8759 | if (FRAME_PARENT_FRAME (f)) | ||
| 8760 | XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); | ||
| 8761 | unblock_input (); | ||
| 8762 | } | ||
| 8763 | } | ||
| 8764 | } | ||
| 8655 | 8765 | ||
| 8656 | #ifdef USE_GTK | 8766 | #ifdef USE_GTK |
| 8657 | if (f && xg_event_is_for_scrollbar (f, event)) | 8767 | if (f && xg_event_is_for_scrollbar (f, event)) |
| @@ -10007,6 +10117,7 @@ static void | |||
| 10007 | x_calc_absolute_position (struct frame *f) | 10117 | x_calc_absolute_position (struct frame *f) |
| 10008 | { | 10118 | { |
| 10009 | int flags = f->size_hint_flags; | 10119 | int flags = f->size_hint_flags; |
| 10120 | struct frame *p = FRAME_PARENT_FRAME (f); | ||
| 10010 | 10121 | ||
| 10011 | /* We have nothing to do if the current position | 10122 | /* We have nothing to do if the current position |
| 10012 | is already for the top-left corner. */ | 10123 | is already for the top-left corner. */ |
| @@ -10015,32 +10126,72 @@ x_calc_absolute_position (struct frame *f) | |||
| 10015 | 10126 | ||
| 10016 | /* Treat negative positions as relative to the leftmost bottommost | 10127 | /* Treat negative positions as relative to the leftmost bottommost |
| 10017 | position that fits on the screen. */ | 10128 | position that fits on the screen. */ |
| 10018 | if (flags & XNegative) | 10129 | if ((flags & XNegative) && (f->left_pos <= 0)) |
| 10019 | f->left_pos = x_display_pixel_width (FRAME_DISPLAY_INFO (f)) | 10130 | { |
| 10020 | - FRAME_PIXEL_WIDTH (f) + f->left_pos; | 10131 | int width = FRAME_PIXEL_WIDTH (f); |
| 10021 | 10132 | ||
| 10022 | { | 10133 | /* A frame that has been visible at least once should have outer |
| 10023 | int height = FRAME_PIXEL_HEIGHT (f); | 10134 | edges. */ |
| 10135 | if (f->output_data.x->has_been_visible && !p) | ||
| 10136 | { | ||
| 10137 | Lisp_Object frame; | ||
| 10138 | Lisp_Object edges = Qnil; | ||
| 10139 | |||
| 10140 | XSETFRAME (frame, f); | ||
| 10141 | edges = Fx_frame_edges (frame, Qouter_edges); | ||
| 10142 | if (!NILP (edges)) | ||
| 10143 | width = (XINT (Fnth (make_number (2), edges)) | ||
| 10144 | - XINT (Fnth (make_number (0), edges))); | ||
| 10145 | } | ||
| 10146 | |||
| 10147 | if (p) | ||
| 10148 | f->left_pos = (FRAME_PIXEL_WIDTH (p) - width - 2 * f->border_width | ||
| 10149 | + f->left_pos); | ||
| 10150 | else | ||
| 10151 | f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f)) | ||
| 10152 | - width + f->left_pos); | ||
| 10153 | |||
| 10154 | } | ||
| 10155 | |||
| 10156 | if ((flags & YNegative) && (f->top_pos <= 0)) | ||
| 10157 | { | ||
| 10158 | int height = FRAME_PIXEL_HEIGHT (f); | ||
| 10024 | 10159 | ||
| 10025 | #if defined USE_X_TOOLKIT && defined USE_MOTIF | 10160 | #if defined USE_X_TOOLKIT && defined USE_MOTIF |
| 10026 | /* Something is fishy here. When using Motif, starting Emacs with | 10161 | /* Something is fishy here. When using Motif, starting Emacs with |
| 10027 | `-g -0-0', the frame appears too low by a few pixels. | 10162 | `-g -0-0', the frame appears too low by a few pixels. |
| 10028 | 10163 | ||
| 10029 | This seems to be so because initially, while Emacs is starting, | 10164 | This seems to be so because initially, while Emacs is starting, |
| 10030 | the column widget's height and the frame's pixel height are | 10165 | the column widget's height and the frame's pixel height are |
| 10031 | different. The column widget's height is the right one. In | 10166 | different. The column widget's height is the right one. In |
| 10032 | later invocations, when Emacs is up, the frame's pixel height | 10167 | later invocations, when Emacs is up, the frame's pixel height |
| 10033 | is right, though. | 10168 | is right, though. |
| 10034 | 10169 | ||
| 10035 | It's not obvious where the initial small difference comes from. | 10170 | It's not obvious where the initial small difference comes from. |
| 10036 | 2000-12-01, gerd. */ | 10171 | 2000-12-01, gerd. */ |
| 10037 | 10172 | ||
| 10038 | XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL); | 10173 | XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL); |
| 10039 | #endif | 10174 | #endif |
| 10040 | 10175 | ||
| 10041 | if (flags & YNegative) | 10176 | if (f->output_data.x->has_been_visible && !p) |
| 10042 | f->top_pos = x_display_pixel_height (FRAME_DISPLAY_INFO (f)) | 10177 | { |
| 10043 | - height + f->top_pos; | 10178 | Lisp_Object frame; |
| 10179 | Lisp_Object edges = Qnil; | ||
| 10180 | |||
| 10181 | XSETFRAME (frame, f); | ||
| 10182 | if (NILP (edges)) | ||
| 10183 | edges = Fx_frame_edges (frame, Qouter_edges); | ||
| 10184 | if (!NILP (edges)) | ||
| 10185 | height = (XINT (Fnth (make_number (3), edges)) | ||
| 10186 | - XINT (Fnth (make_number (1), edges))); | ||
| 10187 | } | ||
| 10188 | |||
| 10189 | if (p) | ||
| 10190 | f->top_pos = (FRAME_PIXEL_HEIGHT (p) - height - 2 * f->border_width | ||
| 10191 | + f->top_pos); | ||
| 10192 | else | ||
| 10193 | f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f)) | ||
| 10194 | - height + f->top_pos); | ||
| 10044 | } | 10195 | } |
| 10045 | 10196 | ||
| 10046 | /* The left_pos and top_pos | 10197 | /* The left_pos and top_pos |
| @@ -10125,6 +10276,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_ | |||
| 10125 | need to compute the top/left offset adjustment for this frame. */ | 10276 | need to compute the top/left offset adjustment for this frame. */ |
| 10126 | 10277 | ||
| 10127 | if (change_gravity != 0 | 10278 | if (change_gravity != 0 |
| 10279 | && !FRAME_PARENT_FRAME (f) | ||
| 10128 | && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN | 10280 | && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN |
| 10129 | || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A | 10281 | || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A |
| 10130 | && (FRAME_X_OUTPUT (f)->move_offset_left == 0 | 10282 | && (FRAME_X_OUTPUT (f)->move_offset_left == 0 |
| @@ -10255,6 +10407,92 @@ x_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | |||
| 10255 | dpyinfo->Xatom_net_wm_state_sticky, None); | 10407 | dpyinfo->Xatom_net_wm_state_sticky, None); |
| 10256 | } | 10408 | } |
| 10257 | 10409 | ||
| 10410 | /** | ||
| 10411 | * x_set_skip_taskbar: | ||
| 10412 | * | ||
| 10413 | * Set frame F's `skip-taskbar' parameter. If non-nil, this should | ||
| 10414 | * remove F's icon from the taskbar associated with the display of F's | ||
| 10415 | * window-system window and inhibit switching to F's window via | ||
| 10416 | * <Alt>-<TAB>. If nil, lift these restrictions. | ||
| 10417 | * | ||
| 10418 | * Some window managers may not honor this parameter. | ||
| 10419 | */ | ||
| 10420 | void | ||
| 10421 | x_set_skip_taskbar (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 10422 | { | ||
| 10423 | if (!EQ (new_value, old_value)) | ||
| 10424 | { | ||
| 10425 | #ifdef USE_GTK | ||
| 10426 | xg_set_skip_taskbar (f, new_value); | ||
| 10427 | #else | ||
| 10428 | Lisp_Object frame; | ||
| 10429 | struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 10430 | |||
| 10431 | XSETFRAME (frame, f); | ||
| 10432 | set_wm_state (frame, !NILP (new_value), | ||
| 10433 | dpyinfo->Xatom_net_wm_state_skip_taskbar, None); | ||
| 10434 | #endif /* USE_GTK */ | ||
| 10435 | FRAME_SKIP_TASKBAR (f) = !NILP (new_value); | ||
| 10436 | } | ||
| 10437 | } | ||
| 10438 | |||
| 10439 | /** | ||
| 10440 | * x_set_z_group: | ||
| 10441 | * | ||
| 10442 | * Set frame F's `z-group' parameter. If `above', F's window-system | ||
| 10443 | * window is displayed above all windows that do not have the `above' | ||
| 10444 | * property set. If nil, F's window is shown below all windows that | ||
| 10445 | * have the `above' property set and above all windows that have the | ||
| 10446 | * `below' property set. If `below', F's window is displayed below all | ||
| 10447 | * windows that do not have the `below' property set. | ||
| 10448 | * | ||
| 10449 | * Some window managers may not honor this parameter. | ||
| 10450 | */ | ||
| 10451 | void | ||
| 10452 | x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 10453 | { | ||
| 10454 | /* We don't care about old_value. The window manager might have | ||
| 10455 | reset the value without telling us. */ | ||
| 10456 | Lisp_Object frame; | ||
| 10457 | struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 10458 | |||
| 10459 | XSETFRAME (frame, f); | ||
| 10460 | |||
| 10461 | if (NILP (new_value)) | ||
| 10462 | { | ||
| 10463 | set_wm_state (frame, false, | ||
| 10464 | dpyinfo->Xatom_net_wm_state_above, None); | ||
| 10465 | set_wm_state (frame, false, | ||
| 10466 | dpyinfo->Xatom_net_wm_state_below, None); | ||
| 10467 | FRAME_Z_GROUP (f) = z_group_none; | ||
| 10468 | } | ||
| 10469 | else if (EQ (new_value, Qabove)) | ||
| 10470 | { | ||
| 10471 | set_wm_state (frame, true, | ||
| 10472 | dpyinfo->Xatom_net_wm_state_above, None); | ||
| 10473 | set_wm_state (frame, false, | ||
| 10474 | dpyinfo->Xatom_net_wm_state_below, None); | ||
| 10475 | FRAME_Z_GROUP (f) = z_group_above; | ||
| 10476 | } | ||
| 10477 | else if (EQ (new_value, Qbelow)) | ||
| 10478 | { | ||
| 10479 | set_wm_state (frame, false, | ||
| 10480 | dpyinfo->Xatom_net_wm_state_above, None); | ||
| 10481 | set_wm_state (frame, true, | ||
| 10482 | dpyinfo->Xatom_net_wm_state_below, None); | ||
| 10483 | FRAME_Z_GROUP (f) = z_group_below; | ||
| 10484 | } | ||
| 10485 | else if (EQ (new_value, Qabove_suspended)) | ||
| 10486 | { | ||
| 10487 | set_wm_state (frame, false, | ||
| 10488 | dpyinfo->Xatom_net_wm_state_above, None); | ||
| 10489 | FRAME_Z_GROUP (f) = z_group_above_suspended; | ||
| 10490 | } | ||
| 10491 | else | ||
| 10492 | error ("Invalid z-group specification"); | ||
| 10493 | } | ||
| 10494 | |||
| 10495 | |||
| 10258 | /* Return the current _NET_WM_STATE. | 10496 | /* Return the current _NET_WM_STATE. |
| 10259 | SIZE_STATE is set to one of the FULLSCREEN_* values. | 10497 | SIZE_STATE is set to one of the FULLSCREEN_* values. |
| 10260 | Set *STICKY to the sticky state. | 10498 | Set *STICKY to the sticky state. |
| @@ -10758,7 +10996,8 @@ x_set_window_size_1 (struct frame *f, bool change_gravity, | |||
| 10758 | int old_height = FRAME_PIXEL_HEIGHT (f); | 10996 | int old_height = FRAME_PIXEL_HEIGHT (f); |
| 10759 | Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); | 10997 | Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); |
| 10760 | 10998 | ||
| 10761 | if (change_gravity) f->win_gravity = NorthWestGravity; | 10999 | if (change_gravity) |
| 11000 | f->win_gravity = NorthWestGravity; | ||
| 10762 | x_wm_set_size_hint (f, 0, false); | 11001 | x_wm_set_size_hint (f, 0, false); |
| 10763 | 11002 | ||
| 10764 | /* When the frame is fullheight and we only want to change the width | 11003 | /* When the frame is fullheight and we only want to change the width |
| @@ -11047,6 +11286,26 @@ xembed_send_message (struct frame *f, Time t, enum xembed_message msg, | |||
| 11047 | void | 11286 | void |
| 11048 | x_make_frame_visible (struct frame *f) | 11287 | x_make_frame_visible (struct frame *f) |
| 11049 | { | 11288 | { |
| 11289 | if (FRAME_PARENT_FRAME (f)) | ||
| 11290 | { | ||
| 11291 | if (!FRAME_VISIBLE_P (f)) | ||
| 11292 | { | ||
| 11293 | block_input (); | ||
| 11294 | #ifdef USE_GTK | ||
| 11295 | gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 11296 | XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 11297 | f->left_pos, f->top_pos); | ||
| 11298 | #else | ||
| 11299 | XMapRaised (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); | ||
| 11300 | #endif | ||
| 11301 | unblock_input (); | ||
| 11302 | |||
| 11303 | SET_FRAME_VISIBLE (f, true); | ||
| 11304 | SET_FRAME_ICONIFIED (f, false); | ||
| 11305 | } | ||
| 11306 | return; | ||
| 11307 | } | ||
| 11308 | |||
| 11050 | block_input (); | 11309 | block_input (); |
| 11051 | 11310 | ||
| 11052 | x_set_bitmap_icon (f); | 11311 | x_set_bitmap_icon (f); |
| @@ -11115,9 +11374,10 @@ x_make_frame_visible (struct frame *f) | |||
| 11115 | because the window manager may choose the position | 11374 | because the window manager may choose the position |
| 11116 | and we don't want to override it. */ | 11375 | and we don't want to override it. */ |
| 11117 | 11376 | ||
| 11118 | if (! FRAME_VISIBLE_P (f) | 11377 | if (!FRAME_VISIBLE_P (f) |
| 11119 | && ! FRAME_ICONIFIED_P (f) | 11378 | && !FRAME_ICONIFIED_P (f) |
| 11120 | && ! FRAME_X_EMBEDDED_P (f) | 11379 | && !FRAME_X_EMBEDDED_P (f) |
| 11380 | && !FRAME_PARENT_FRAME (f) | ||
| 11121 | && f->win_gravity == NorthWestGravity | 11381 | && f->win_gravity == NorthWestGravity |
| 11122 | && previously_visible) | 11382 | && previously_visible) |
| 11123 | { | 11383 | { |
| @@ -11180,15 +11440,15 @@ x_make_frame_invisible (struct frame *f) | |||
| 11180 | xembed_set_info (f, 0); | 11440 | xembed_set_info (f, 0); |
| 11181 | else | 11441 | else |
| 11182 | #endif | 11442 | #endif |
| 11183 | { | ||
| 11184 | 11443 | ||
| 11185 | if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window, | 11444 | if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window, |
| 11186 | DefaultScreen (FRAME_X_DISPLAY (f)))) | 11445 | DefaultScreen (FRAME_X_DISPLAY (f)))) |
| 11187 | { | 11446 | { |
| 11188 | unblock_input (); | 11447 | unblock_input (); |
| 11189 | error ("Can't notify window manager of window withdrawal"); | 11448 | error ("Can't notify window manager of window withdrawal"); |
| 11190 | } | 11449 | } |
| 11191 | } | 11450 | |
| 11451 | x_sync (f); | ||
| 11192 | 11452 | ||
| 11193 | /* We can't distinguish this from iconification | 11453 | /* We can't distinguish this from iconification |
| 11194 | just by the event that we get from the server. | 11454 | just by the event that we get from the server. |
| @@ -11198,8 +11458,6 @@ x_make_frame_invisible (struct frame *f) | |||
| 11198 | SET_FRAME_VISIBLE (f, 0); | 11458 | SET_FRAME_VISIBLE (f, 0); |
| 11199 | SET_FRAME_ICONIFIED (f, false); | 11459 | SET_FRAME_ICONIFIED (f, false); |
| 11200 | 11460 | ||
| 11201 | x_sync (f); | ||
| 11202 | |||
| 11203 | unblock_input (); | 11461 | unblock_input (); |
| 11204 | } | 11462 | } |
| 11205 | 11463 | ||
| @@ -12355,6 +12613,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 12355 | ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID) | 12613 | ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID) |
| 12356 | ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop) | 12614 | ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop) |
| 12357 | ATOM_REFS_INIT ("MANAGER", Xatom_xsettings_mgr) | 12615 | ATOM_REFS_INIT ("MANAGER", Xatom_xsettings_mgr) |
| 12616 | ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", Xatom_net_wm_state_skip_taskbar) | ||
| 12617 | ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above) | ||
| 12618 | ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below) | ||
| 12358 | }; | 12619 | }; |
| 12359 | 12620 | ||
| 12360 | int i; | 12621 | int i; |