window: Move adjust_for_gravity to window-x11
This removes the weirdness about which edge cases are where in the move_resize_internal API, and we now always pass in client top-left coordinates.
This commit is contained in:
parent
4c21a46452
commit
acb3dc6754
@ -74,11 +74,10 @@ typedef enum {
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
||||||
META_DO_GRAVITY_ADJUST = 1 << 1,
|
META_IS_USER_ACTION = 1 << 1,
|
||||||
META_IS_USER_ACTION = 1 << 2,
|
META_IS_MOVE_ACTION = 1 << 2,
|
||||||
META_IS_MOVE_ACTION = 1 << 3,
|
META_IS_RESIZE_ACTION = 1 << 3,
|
||||||
META_IS_RESIZE_ACTION = 1 << 4,
|
META_IS_WAYLAND_RESIZE = 1 << 4,
|
||||||
META_IS_WAYLAND_RESIZE = 1 << 5
|
|
||||||
} MetaMoveResizeFlags;
|
} MetaMoveResizeFlags;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -3625,121 +3625,6 @@ meta_window_activate_with_workspace (MetaWindow *window,
|
|||||||
meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace);
|
meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Manually fix all the weirdness explained in the big comment at the
|
|
||||||
* beginning of meta_window_move_resize_internal() giving positions
|
|
||||||
* expected by meta_window_constrain (i.e. positions & sizes of the
|
|
||||||
* internal or client window).
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
adjust_for_gravity (MetaWindow *window,
|
|
||||||
gboolean coords_assume_border,
|
|
||||||
int gravity,
|
|
||||||
MetaRectangle *rect)
|
|
||||||
{
|
|
||||||
int ref_x, ref_y;
|
|
||||||
int bw;
|
|
||||||
int child_x, child_y;
|
|
||||||
int frame_width, frame_height;
|
|
||||||
MetaFrameBorders borders;
|
|
||||||
|
|
||||||
if (coords_assume_border)
|
|
||||||
bw = window->border_width;
|
|
||||||
else
|
|
||||||
bw = 0;
|
|
||||||
|
|
||||||
meta_frame_calc_borders (window->frame, &borders);
|
|
||||||
|
|
||||||
child_x = borders.visible.left;
|
|
||||||
child_y = borders.visible.top;
|
|
||||||
frame_width = child_x + rect->width + borders.visible.right;
|
|
||||||
frame_height = child_y + rect->height + borders.visible.bottom;
|
|
||||||
|
|
||||||
/* We're computing position to pass to window_move, which is
|
|
||||||
* the position of the client window (StaticGravity basically)
|
|
||||||
*
|
|
||||||
* (see WM spec description of gravity computation, but note that
|
|
||||||
* their formulas assume we're honoring the border width, rather
|
|
||||||
* than compensating for having turned it off)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Calculate the the reference point, which is the corner of the
|
|
||||||
* outer window specified by the gravity. So, NorthEastGravity
|
|
||||||
* would have the reference point as the top-right corner of the
|
|
||||||
* outer window. */
|
|
||||||
ref_x = rect->x;
|
|
||||||
ref_y = rect->y;
|
|
||||||
|
|
||||||
switch (gravity)
|
|
||||||
{
|
|
||||||
case NorthGravity:
|
|
||||||
case CenterGravity:
|
|
||||||
case SouthGravity:
|
|
||||||
ref_x += rect->width / 2 + bw;
|
|
||||||
break;
|
|
||||||
case NorthEastGravity:
|
|
||||||
case EastGravity:
|
|
||||||
case SouthEastGravity:
|
|
||||||
ref_x += rect->width + bw * 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (gravity)
|
|
||||||
{
|
|
||||||
case WestGravity:
|
|
||||||
case CenterGravity:
|
|
||||||
case EastGravity:
|
|
||||||
ref_y += rect->height / 2 + bw;
|
|
||||||
break;
|
|
||||||
case SouthWestGravity:
|
|
||||||
case SouthGravity:
|
|
||||||
case SouthEastGravity:
|
|
||||||
ref_y += rect->height + bw * 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the top-left corner of the outer window from
|
|
||||||
* the reference point. */
|
|
||||||
|
|
||||||
rect->x = ref_x;
|
|
||||||
rect->y = ref_y;
|
|
||||||
|
|
||||||
switch (gravity)
|
|
||||||
{
|
|
||||||
case NorthGravity:
|
|
||||||
case CenterGravity:
|
|
||||||
case SouthGravity:
|
|
||||||
rect->x -= frame_width / 2;
|
|
||||||
break;
|
|
||||||
case NorthEastGravity:
|
|
||||||
case EastGravity:
|
|
||||||
case SouthEastGravity:
|
|
||||||
rect->x -= frame_width;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (gravity)
|
|
||||||
{
|
|
||||||
case WestGravity:
|
|
||||||
case CenterGravity:
|
|
||||||
case EastGravity:
|
|
||||||
rect->y -= frame_height / 2;
|
|
||||||
break;
|
|
||||||
case SouthWestGravity:
|
|
||||||
case SouthGravity:
|
|
||||||
case SouthEastGravity:
|
|
||||||
rect->y -= frame_height;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjust to get the top-left corner of the inner window. */
|
|
||||||
rect->x += child_x;
|
|
||||||
rect->y += child_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_window_updates_are_frozen:
|
* meta_window_updates_are_frozen:
|
||||||
* @window: a #MetaWindow
|
* @window: a #MetaWindow
|
||||||
@ -3889,46 +3774,14 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
int w,
|
int w,
|
||||||
int h)
|
int h)
|
||||||
{
|
{
|
||||||
/* meta_window_move_resize_internal gets called with very different
|
/* The rectangle here that's passed in is always the root position
|
||||||
* meanings for root_x_nw and root_y_nw. w & h are always the area
|
* of the client window. For undecorated or client-decorated windows,
|
||||||
* of the inner or client window (i.e. excluding the frame) and
|
* this is the root position of the X11 window. For server-decorated
|
||||||
* gravity is the relevant gravity associated with the request (note
|
* windows, this is the root position of the client area of the window.
|
||||||
* that gravity is ignored for move-only operations unless its
|
|
||||||
* e.g. a configure request). The location is different for
|
|
||||||
* different cases because of how this function gets called; note
|
|
||||||
* that in all cases what we want to find out is the upper left
|
|
||||||
* corner of the position of the inner window:
|
|
||||||
*
|
*
|
||||||
* Case | Called from (flags; gravity)
|
* Similarly, the width and height passed in are in client window
|
||||||
* -----+-----------------------------------------------
|
* coordinates as well.
|
||||||
* 1 | A resize only ConfigureRequest
|
|
||||||
* 1 | meta_window_resize
|
|
||||||
* 1 | meta_window_resize_with_gravity
|
|
||||||
* 2 | New window
|
|
||||||
* 2 | Session restore
|
|
||||||
* 2 | A not-resize-only ConfigureRequest/net_moveresize_window request
|
|
||||||
* 3 | meta_window_move
|
|
||||||
* 3 | meta_window_move_resize
|
|
||||||
* 4 | meta_window_move_resize_wayland
|
|
||||||
*
|
|
||||||
* For each of the cases, root_x_nw and root_y_nw must be treated as follows:
|
|
||||||
*
|
|
||||||
* (1) They should be entirely ignored; instead the previous position
|
|
||||||
* and size of the window should be resized according to the given
|
|
||||||
* gravity in order to determine the new position of the window.
|
|
||||||
* (2) Needs to be fixed up by adjust_for_gravity() as these
|
|
||||||
* coordinates are relative to some corner or side of the outer
|
|
||||||
* window (except for the case of StaticGravity) and we want to
|
|
||||||
* know the location of the upper left corner of the inner window.
|
|
||||||
* (3) These values are already the desired position of the NW corner
|
|
||||||
* of the inner window
|
|
||||||
* (4) These values are already the desired position of the NW corner
|
|
||||||
* of the inner window (which is also the outer window, because
|
|
||||||
* we don't decorate wayland clients), and the client has acknowledged
|
|
||||||
* the window size change.
|
|
||||||
*/
|
*/
|
||||||
gboolean is_configure_request;
|
|
||||||
gboolean do_gravity_adjust;
|
|
||||||
gboolean is_user_action;
|
gboolean is_user_action;
|
||||||
gboolean did_placement;
|
gboolean did_placement;
|
||||||
/* used for the configure request, but may not be final
|
/* used for the configure request, but may not be final
|
||||||
@ -3941,8 +3794,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
|
|
||||||
g_return_if_fail (!window->override_redirect);
|
g_return_if_fail (!window->override_redirect);
|
||||||
|
|
||||||
is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0;
|
|
||||||
do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0;
|
|
||||||
is_user_action = (flags & META_IS_USER_ACTION) != 0;
|
is_user_action = (flags & META_IS_USER_ACTION) != 0;
|
||||||
|
|
||||||
/* The action has to be a move, a resize or the wayland client
|
/* The action has to be a move, a resize or the wayland client
|
||||||
@ -3956,9 +3807,8 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
meta_window_get_client_root_coords (window, &old_rect);
|
meta_window_get_client_root_coords (window, &old_rect);
|
||||||
|
|
||||||
meta_topic (META_DEBUG_GEOMETRY,
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
"Move/resize %s to %d,%d %dx%d%s%s from %d,%d %dx%d\n",
|
"Move/resize %s to %d,%d %dx%d%s from %d,%d %dx%d\n",
|
||||||
window->desc, root_x_nw, root_y_nw, w, h,
|
window->desc, root_x_nw, root_y_nw, w, h,
|
||||||
is_configure_request ? " (configure request)" : "",
|
|
||||||
is_user_action ? " (user move/resize)" : "",
|
is_user_action ? " (user move/resize)" : "",
|
||||||
old_rect.x, old_rect.y, old_rect.width, old_rect.height);
|
old_rect.x, old_rect.y, old_rect.width, old_rect.height);
|
||||||
|
|
||||||
@ -3986,21 +3836,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
"Compensated for gravity in resize action; new pos %d,%d\n",
|
"Compensated for gravity in resize action; new pos %d,%d\n",
|
||||||
new_rect.x, new_rect.y);
|
new_rect.x, new_rect.y);
|
||||||
}
|
}
|
||||||
else if (is_configure_request || do_gravity_adjust)
|
|
||||||
{
|
|
||||||
adjust_for_gravity (window,
|
|
||||||
/* configure request coords assume
|
|
||||||
* the border width existed
|
|
||||||
*/
|
|
||||||
is_configure_request,
|
|
||||||
gravity,
|
|
||||||
&new_rect);
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_GEOMETRY,
|
|
||||||
"Compensated for configure_request/do_gravity_adjust needing "
|
|
||||||
"weird positioning; new pos %d,%d\n",
|
|
||||||
new_rect.x, new_rect.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
did_placement = !window->placed && window->calc_placement;
|
did_placement = !window->placed && window->calc_placement;
|
||||||
|
|
||||||
|
@ -250,6 +250,116 @@ send_configure_notify (MetaWindow *window)
|
|||||||
meta_error_trap_pop (window->display);
|
meta_error_trap_pop (window->display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
adjust_for_gravity (MetaWindow *window,
|
||||||
|
gboolean coords_assume_border,
|
||||||
|
int gravity,
|
||||||
|
MetaRectangle *rect)
|
||||||
|
{
|
||||||
|
int ref_x, ref_y;
|
||||||
|
int bw;
|
||||||
|
int child_x, child_y;
|
||||||
|
int frame_width, frame_height;
|
||||||
|
MetaFrameBorders borders;
|
||||||
|
|
||||||
|
if (coords_assume_border)
|
||||||
|
bw = window->border_width;
|
||||||
|
else
|
||||||
|
bw = 0;
|
||||||
|
|
||||||
|
meta_frame_calc_borders (window->frame, &borders);
|
||||||
|
|
||||||
|
child_x = borders.visible.left;
|
||||||
|
child_y = borders.visible.top;
|
||||||
|
frame_width = child_x + rect->width + borders.visible.right;
|
||||||
|
frame_height = child_y + rect->height + borders.visible.bottom;
|
||||||
|
|
||||||
|
/* We're computing position to pass to window_move, which is
|
||||||
|
* the position of the client window (StaticGravity basically)
|
||||||
|
*
|
||||||
|
* (see WM spec description of gravity computation, but note that
|
||||||
|
* their formulas assume we're honoring the border width, rather
|
||||||
|
* than compensating for having turned it off)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Calculate the the reference point, which is the corner of the
|
||||||
|
* outer window specified by the gravity. So, NorthEastGravity
|
||||||
|
* would have the reference point as the top-right corner of the
|
||||||
|
* outer window. */
|
||||||
|
ref_x = rect->x;
|
||||||
|
ref_y = rect->y;
|
||||||
|
|
||||||
|
switch (gravity)
|
||||||
|
{
|
||||||
|
case NorthGravity:
|
||||||
|
case CenterGravity:
|
||||||
|
case SouthGravity:
|
||||||
|
ref_x += rect->width / 2 + bw;
|
||||||
|
break;
|
||||||
|
case NorthEastGravity:
|
||||||
|
case EastGravity:
|
||||||
|
case SouthEastGravity:
|
||||||
|
ref_x += rect->width + bw * 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gravity)
|
||||||
|
{
|
||||||
|
case WestGravity:
|
||||||
|
case CenterGravity:
|
||||||
|
case EastGravity:
|
||||||
|
ref_y += rect->height / 2 + bw;
|
||||||
|
break;
|
||||||
|
case SouthWestGravity:
|
||||||
|
case SouthGravity:
|
||||||
|
case SouthEastGravity:
|
||||||
|
ref_y += rect->height + bw * 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the top-left corner of the outer window from
|
||||||
|
* the reference point. */
|
||||||
|
|
||||||
|
rect->x = ref_x;
|
||||||
|
rect->y = ref_y;
|
||||||
|
|
||||||
|
switch (gravity)
|
||||||
|
{
|
||||||
|
case NorthGravity:
|
||||||
|
case CenterGravity:
|
||||||
|
case SouthGravity:
|
||||||
|
rect->x -= frame_width / 2;
|
||||||
|
break;
|
||||||
|
case NorthEastGravity:
|
||||||
|
case EastGravity:
|
||||||
|
case SouthEastGravity:
|
||||||
|
rect->x -= frame_width;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gravity)
|
||||||
|
{
|
||||||
|
case WestGravity:
|
||||||
|
case CenterGravity:
|
||||||
|
case EastGravity:
|
||||||
|
rect->y -= frame_height / 2;
|
||||||
|
break;
|
||||||
|
case SouthWestGravity:
|
||||||
|
case SouthGravity:
|
||||||
|
case SouthEastGravity:
|
||||||
|
rect->y -= frame_height;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust to get the top-left corner of the inner window. */
|
||||||
|
rect->x += child_x;
|
||||||
|
rect->y += child_y;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_apply_session_info (MetaWindow *window,
|
meta_window_apply_session_info (MetaWindow *window,
|
||||||
const MetaWindowSessionInfo *info)
|
const MetaWindowSessionInfo *info)
|
||||||
@ -359,31 +469,31 @@ meta_window_apply_session_info (MetaWindow *window,
|
|||||||
|
|
||||||
if (info->geometry_set)
|
if (info->geometry_set)
|
||||||
{
|
{
|
||||||
int x, y, w, h;
|
MetaRectangle rect;
|
||||||
MetaMoveResizeFlags flags;
|
MetaMoveResizeFlags flags;
|
||||||
|
|
||||||
window->placed = TRUE; /* don't do placement algorithms later */
|
window->placed = TRUE; /* don't do placement algorithms later */
|
||||||
|
|
||||||
x = info->rect.x;
|
rect.x = info->rect.x;
|
||||||
y = info->rect.y;
|
rect.y = info->rect.y;
|
||||||
|
|
||||||
w = window->size_hints.base_width +
|
rect.width = window->size_hints.base_width + info->rect.width * window->size_hints.width_inc;
|
||||||
info->rect.width * window->size_hints.width_inc;
|
rect.height = window->size_hints.base_height + info->rect.height * window->size_hints.height_inc;
|
||||||
h = window->size_hints.base_height +
|
|
||||||
info->rect.height * window->size_hints.height_inc;
|
|
||||||
|
|
||||||
/* Force old gravity, ignoring anything now set */
|
/* Force old gravity, ignoring anything now set */
|
||||||
window->size_hints.win_gravity = info->gravity;
|
window->size_hints.win_gravity = info->gravity;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_SM,
|
flags = META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||||
"Restoring pos %d,%d size %d x %d for %s\n",
|
|
||||||
x, y, w, h, window->desc);
|
adjust_for_gravity (window,
|
||||||
|
FALSE,
|
||||||
|
window->size_hints.win_gravity,
|
||||||
|
&rect);
|
||||||
|
|
||||||
flags = META_DO_GRAVITY_ADJUST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
|
||||||
meta_window_move_resize_internal (window,
|
meta_window_move_resize_internal (window,
|
||||||
flags,
|
flags,
|
||||||
window->size_hints.win_gravity,
|
window->size_hints.win_gravity,
|
||||||
x, y, w, h);
|
rect.x, rect.y, rect.width, rect.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,13 +538,24 @@ meta_window_x11_manage (MetaWindow *window)
|
|||||||
*/
|
*/
|
||||||
flags = META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
flags = META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||||
if (!window->override_redirect)
|
if (!window->override_redirect)
|
||||||
meta_window_move_resize_internal (window,
|
{
|
||||||
flags,
|
MetaRectangle rect;
|
||||||
window->size_hints.win_gravity,
|
|
||||||
window->size_hints.x,
|
rect.x = window->size_hints.x;
|
||||||
window->size_hints.y,
|
rect.y = window->size_hints.y;
|
||||||
window->size_hints.width,
|
rect.width = window->size_hints.width;
|
||||||
window->size_hints.height);
|
rect.height = window->size_hints.height;
|
||||||
|
|
||||||
|
adjust_for_gravity (window,
|
||||||
|
TRUE,
|
||||||
|
window->size_hints.win_gravity,
|
||||||
|
&rect);
|
||||||
|
|
||||||
|
meta_window_move_resize_internal (window,
|
||||||
|
flags,
|
||||||
|
window->size_hints.win_gravity,
|
||||||
|
rect.x, rect.y, rect.width, rect.height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1958,13 +2079,24 @@ meta_window_move_resize_request (MetaWindow *window,
|
|||||||
flags |= META_IS_RESIZE_ACTION;
|
flags |= META_IS_RESIZE_ACTION;
|
||||||
|
|
||||||
if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
|
if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
|
||||||
meta_window_move_resize_internal (window,
|
{
|
||||||
flags,
|
MetaRectangle rect;
|
||||||
gravity,
|
|
||||||
x,
|
rect.x = x;
|
||||||
y,
|
rect.y = y;
|
||||||
width,
|
rect.width = width;
|
||||||
height);
|
rect.height = height;
|
||||||
|
|
||||||
|
adjust_for_gravity (window,
|
||||||
|
TRUE,
|
||||||
|
window->size_hints.win_gravity,
|
||||||
|
&rect);
|
||||||
|
|
||||||
|
meta_window_move_resize_internal (window,
|
||||||
|
flags,
|
||||||
|
gravity,
|
||||||
|
rect.x, rect.y, rect.width, rect.height);
|
||||||
|
}
|
||||||
|
|
||||||
/* window->user_rect exists to allow "snapping-back" the window if a
|
/* window->user_rect exists to allow "snapping-back" the window if a
|
||||||
* new strut is set (causing the window to move) and then the strut
|
* new strut is set (causing the window to move) and then the strut
|
||||||
|
Loading…
Reference in New Issue
Block a user