From 719fd9334634dfc91e145d0a7320387a8bb4b75f Mon Sep 17 00:00:00 2001 From: Jan D Date: Wed, 25 Feb 2015 20:16:44 +0100 Subject: [PATCH] Redo the whole window offsets and coordinate translation for X. * frame.h (struct frame): Remove x_pixels_diff, y_pixels_diff. * w32fns.c (x_real_positions): Remove setting of x_pixels_diff, y_pixels_diff. * xfns.c (x_real_pos_and_offsets): New function, basically the code from x_real_positions. (x_real_positions): Call x_real_pos_and_offsets. (x_relative_mouse_position): Use XTranslateCoordinates instead of OUTER_TO_INNER_DIFF macros. (Fx_frame_geometry): Get offsets with x_real_pos_and_offsets, border from window attributes. Adjust tool bar and menu widths. * xmenu.c (create_and_show_popup_menu): Use XTranslateCoordinates instead of OUTER_TO_INNER_DIFF macros. * xterm.h (struct x_output): Remove x_pixels_outer_diff, y_pixels_outer_diff, FRAME_OUTER_TO_INNER_DIFF_X, FRAME_OUTER_TO_INNER_DIFF_Y. Declare x_real_pos_and_offsets. --- src/ChangeLog | 22 +++++++++++ src/frame.h | 4 -- src/w32fns.c | 4 -- src/xfns.c | 106 ++++++++++++++++++++++++++++++++++++-------------- src/xmenu.c | 16 +++++++- src/xterm.h | 28 +++++-------- 6 files changed, 121 insertions(+), 59 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 1f0781fef10..e4506968baa 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,25 @@ +2015-02-25 Jan Djärv + + * xterm.h (struct x_output): Remove x_pixels_outer_diff, + y_pixels_outer_diff, FRAME_OUTER_TO_INNER_DIFF_X, + FRAME_OUTER_TO_INNER_DIFF_Y. Declare x_real_pos_and_offsets. + + * xmenu.c (create_and_show_popup_menu): Use XTranslateCoordinates + instead of OUTER_TO_INNER_DIFF macros. + + * xfns.c (x_real_pos_and_offsets): New function, basically the code + from x_real_positions. + (x_real_positions): Call x_real_pos_and_offsets. + (x_relative_mouse_position): Use XTranslateCoordinates instead of + OUTER_TO_INNER_DIFF macros. + (Fx_frame_geometry): Get offsets with x_real_pos_and_offsets, + border from window attributes. Adjust tool bar and menu widths. + + * w32fns.c (x_real_positions): Remove setting of x_pixels_diff, + y_pixels_diff. + + * frame.h (struct frame): Remove x_pixels_diff, y_pixels_diff. + 2015-02-25 Paul Eggert Backtrace after malloc arena is corrupted diff --git a/src/frame.h b/src/frame.h index 6f5de3f5689..ddbf93e98f5 100644 --- a/src/frame.h +++ b/src/frame.h @@ -396,10 +396,6 @@ struct frame widths) in pixels. */ int pixel_width, pixel_height; - /* These many pixels are the difference between the outer window (i.e. the - left and top of the window manager decoration) and FRAME_X_WINDOW. */ - int x_pixels_diff, y_pixels_diff; - /* This is the gravity value for the specified window position. */ int win_gravity; diff --git a/src/w32fns.c b/src/w32fns.c index 1e685ad6d98..6f404e98a62 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -346,10 +346,6 @@ x_real_positions (struct frame *f, int *xptr, int *yptr) /* Convert (0, 0) in the client area to screen co-ordinates. */ ClientToScreen (FRAME_W32_WINDOW (f), &pt); - /* Remember x_pixels_diff and y_pixels_diff. */ - f->x_pixels_diff = pt.x - rect.left; - f->y_pixels_diff = pt.y - rect.top; - *xptr = rect.left; *yptr = rect.top; } diff --git a/src/xfns.c b/src/xfns.c index 80be6ac257c..afbd460b7c8 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -168,12 +168,25 @@ check_x_display_info (Lisp_Object object) return dpyinfo; } -/* Store the screen positions of frame F into XPTR and YPTR. +/* Return the screen positions and offsets of frame F. + Store the offsets between FRAME_OUTER_WINDOW and the containing + window manager window into LEFT_OFFSET_X, RIGHT_OFFSET_X, + TOP_OFFSET_Y and BOTTOM_OFFSET_Y. + Store the offsets between FRAME_X_WINDOW and the containing + window manager window into X_PIXELS_DIFF and Y_PIXELS_DIFF. + Store the screen positions of frame F into XPTR and YPTR. These are the positions of the containing window manager window, not Emacs's own window. */ - void -x_real_positions (struct frame *f, int *xptr, int *yptr) +x_real_pos_and_offsets (struct frame *f, + int *left_offset_x, + int *right_offset_x, + int *top_offset_y, + int *bottom_offset_y, + int *x_pixels_diff, + int *y_pixels_diff, + int *xptr, + int *yptr) { int win_x, win_y, outer_x IF_LINT (= 0), outer_y IF_LINT (= 0); int real_x = 0, real_y = 0; @@ -187,6 +200,7 @@ x_real_positions (struct frame *f, int *xptr, int *yptr) Display *dpy = FRAME_X_DISPLAY (f); unsigned char *tmp_data = NULL; Atom target_type = XA_CARDINAL; + unsigned int ow IF_LINT (= 0), oh IF_LINT (= 0); block_input (); @@ -230,7 +244,7 @@ x_real_positions (struct frame *f, int *xptr, int *yptr) /* Get the real coordinates for the WM window upper left corner */ XGetGeometry (FRAME_X_DISPLAY (f), win, - &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign); + &rootw, &real_x, &real_y, &ow, &oh, &ign, &ign); /* Translate real coordinates to coordinates relative to our window. For our window, the upper left corner is 0, 0. @@ -310,16 +324,38 @@ x_real_positions (struct frame *f, int *xptr, int *yptr) if (had_errors) return; - f->x_pixels_diff = -win_x; - f->y_pixels_diff = -win_y; + if (x_pixels_diff) *x_pixels_diff = -win_x; + if (y_pixels_diff) *y_pixels_diff = -win_y; + + if (left_offset_x) *left_offset_x = -outer_x; + if (top_offset_y) *top_offset_y = -outer_x; - FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x; - FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y; + if (xptr) *xptr = real_x; + if (yptr) *yptr = real_y; - *xptr = real_x; - *yptr = real_y; + if (right_offset_x || bottom_offset_y) + { + unsigned int ign, fw, fh; + Window rootw; + + XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), + &rootw, &ign, &ign, &fw, &fh, &ign, &ign); + if (right_offset_x) *right_offset_x = ow - fw + outer_x; + if (bottom_offset_y) *bottom_offset_y = oh - fh + outer_y; + } } +/* Store the screen positions of frame F into XPTR and YPTR. + These are the positions of the containing window manager window, + not Emacs's own window. */ + +void +x_real_positions (struct frame *f, int *xptr, int *yptr) +{ + x_real_pos_and_offsets (f, NULL, NULL, NULL, NULL, NULL, NULL, xptr, yptr); +} + + /* Get the mouse position in frame relative coordinates. */ void @@ -351,11 +387,19 @@ x_relative_mouse_position (struct frame *f, int *x, int *y) we don't care. */ (unsigned int *) &dummy); - unblock_input (); + XTranslateCoordinates (FRAME_X_DISPLAY (f), + + /* From-window, to-window. */ + FRAME_DISPLAY_INFO (f)->root_window, + FRAME_X_WINDOW (f), - /* Translate root window coordinates to window coordinates. */ - *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f); - *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f); + /* From-position, to-position. */ + *x, *y, x, y, + + /* Child of win. */ + &dummy_window); + + unblock_input (); } /* Gamma-correct COLOR on frame F. */ @@ -4279,13 +4323,23 @@ elements (all size values are in pixels). Lisp_Object fullscreen = Fframe_parameter (frame, Qfullscreen); int menu_bar_height, menu_bar_width, tool_bar_height, tool_bar_width; - border = FRAME_OUTER_TO_INNER_DIFF_X (f); - title = FRAME_X_OUTPUT (f)->y_pixels_outer_diff - border; + int left_off, right_off, top_off, bottom_off; + XWindowAttributes atts; + + block_input (); + + XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &atts); + + x_real_pos_and_offsets (f, &left_off, &right_off, &top_off, &bottom_off, + NULL, NULL, NULL, NULL); + + unblock_input (); + + border = atts.border_width; + title = top_off; - outer_width = FRAME_PIXEL_WIDTH (f) + 2 * border; - outer_height = (FRAME_PIXEL_HEIGHT (f) - + FRAME_OUTER_TO_INNER_DIFF_Y (f) - + FRAME_OUTER_TO_INNER_DIFF_X (f)); + outer_width = FRAME_PIXEL_WIDTH (f) + 2 * border + right_off + left_off; + outer_height = FRAME_PIXEL_HEIGHT (f) + 2 * border + top_off + bottom_off; #if defined (USE_GTK) { @@ -4298,16 +4352,10 @@ elements (all size values are in pixels). tool_bar_height = (tool_bar_left_right ? FRAME_PIXEL_HEIGHT (f) : FRAME_TOOLBAR_HEIGHT (f)); - if (tool_bar_left_right) - /* For some reason FRAME_OUTER_TO_INNER_DIFF_X does not count the - width of a tool bar. */ - outer_width += FRAME_TOOLBAR_WIDTH (f); } #else tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f); - tool_bar_width = ((tool_bar_height > 0) - ? outer_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f) - : 0); + tool_bar_width = tool_bar_height > 0 ? FRAME_PIXEL_WIDTH (f) : 0; #endif #if defined (USE_X_TOOLKIT) || defined (USE_GTK) @@ -4316,9 +4364,7 @@ elements (all size values are in pixels). menu_bar_height = FRAME_MENU_BAR_HEIGHT (f); #endif - menu_bar_width = ((menu_bar_height > 0) - ? outer_width - 2 * border - : 0); + menu_bar_width = menu_bar_height > 0 ? FRAME_PIXEL_WIDTH (f) : 0; if (!FRAME_EXTERNAL_MENU_BAR (f)) inner_height -= menu_bar_height; diff --git a/src/xmenu.c b/src/xmenu.c index fdf1f6f4d84..c9f150f67f3 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1211,13 +1211,25 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, if (use_pos_func) { + Window dummy_window; + /* Not invoked by a click. pop up at x/y. */ pos_func = menu_position_func; /* Adjust coordinates to be root-window-relative. */ - x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f); - y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f); + block_input (); + XTranslateCoordinates (FRAME_X_DISPLAY (f), + + /* From-window, to-window. */ + FRAME_X_WINDOW (f), + FRAME_DISPLAY_INFO (f)->root_window, + /* From-position, to-position. */ + x, y, &x, &y, + + /* Child of win. */ + &dummy_window); + unblock_input (); popup_x_y.x = x; popup_x_y.y = y; popup_x_y.f = f; diff --git a/src/xterm.h b/src/xterm.h index e597227c81c..16868f114e8 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -628,15 +628,6 @@ struct x_output They are changed only when a different background is involved. */ unsigned long relief_background; - /* As x_pixels_diff, but to FRAME_OUTER_WINDOW. For some reason the - two might differ by a pixel, depending on WM */ - int x_pixels_outer_diff; - - /* As y_pixels_diff, but to FRAME_OUTER_WINDOW. In the toolkit version, - these may differ because this does not take into account possible - menubar. y_pixels_diff is with menubar height included */ - int y_pixels_outer_diff; - /* Keep track of focus. May be EXPLICIT if we received a FocusIn for this frame, or IMPLICIT if we received an EnterNotify. FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */ @@ -759,16 +750,6 @@ enum /* This is the Colormap which frame F uses. */ #define FRAME_X_COLORMAP(f) FRAME_DISPLAY_INFO (f)->cmap -/* The difference in pixels between the top left corner of the - Emacs window (including possible window manager decorations) - and FRAME_X_WINDOW (f). */ -#define FRAME_OUTER_TO_INNER_DIFF_X(f) \ - ((f)->output_data.x->x_pixels_outer_diff) -#define FRAME_OUTER_TO_INNER_DIFF_Y(f) \ - ((f)->output_data.x->y_pixels_outer_diff \ - + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) - - #define FRAME_XIC(f) ((f)->output_data.x->xic) #define FRAME_X_XIM(f) (FRAME_DISPLAY_INFO (f)->xim) #define FRAME_X_XIM_STYLES(f) (FRAME_DISPLAY_INFO (f)->xim_styles) @@ -971,6 +952,15 @@ SELECTION_EVENT_DISPLAY (struct input_event *ev) extern void x_free_gcs (struct frame *); extern void x_relative_mouse_position (struct frame *, int *, int *); +extern void x_real_pos_and_offsets (struct frame *f, + int *left_offset_x, + int *right_offset_x, + int *top_offset_y, + int *bottom_offset_y, + int *x_pixels_diff, + int *y_pixels_diff, + int *xptr, + int *yptr); /* From xrdb.c. */ -- 2.39.2