Commit 719fd933 authored by Jan D's avatar Jan D

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.
parent 0731a2e8
2015-02-25 Jan Djärv <jan.h.d@swipnet.se>
* 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 <eggert@cs.ucla.edu>
Backtrace after malloc arena is corrupted
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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. */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment