aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
authorMartin Rudalics2017-04-12 10:38:25 +0200
committerMartin Rudalics2017-04-12 10:38:25 +0200
commit3fdd3bb56c006a2a24761b8fcea0cbd9b0cba422 (patch)
treea0b8f5e431ba812b4fe69261a8515e973a3e7ed3 /src/xterm.c
parent449bc49c768a4733411c7e05186be7efc163cd7c (diff)
downloademacs-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.c389
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
10007x_calc_absolute_position (struct frame *f) 10117x_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 */
10420void
10421x_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 */
10451void
10452x_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,
11047void 11286void
11048x_make_frame_visible (struct frame *f) 11287x_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;