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
|
||||
{
|
||||
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
||||
META_DO_GRAVITY_ADJUST = 1 << 1,
|
||||
META_IS_USER_ACTION = 1 << 2,
|
||||
META_IS_MOVE_ACTION = 1 << 3,
|
||||
META_IS_RESIZE_ACTION = 1 << 4,
|
||||
META_IS_WAYLAND_RESIZE = 1 << 5
|
||||
META_IS_USER_ACTION = 1 << 1,
|
||||
META_IS_MOVE_ACTION = 1 << 2,
|
||||
META_IS_RESIZE_ACTION = 1 << 3,
|
||||
META_IS_WAYLAND_RESIZE = 1 << 4,
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
typedef enum
|
||||
|
@ -3625,121 +3625,6 @@ meta_window_activate_with_workspace (MetaWindow *window,
|
||||
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:
|
||||
* @window: a #MetaWindow
|
||||
@ -3889,46 +3774,14 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
/* meta_window_move_resize_internal gets called with very different
|
||||
* meanings for root_x_nw and root_y_nw. w & h are always the area
|
||||
* of the inner or client window (i.e. excluding the frame) and
|
||||
* gravity is the relevant gravity associated with the request (note
|
||||
* 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:
|
||||
/* The rectangle here that's passed in is always the root position
|
||||
* of the client window. For undecorated or client-decorated windows,
|
||||
* this is the root position of the X11 window. For server-decorated
|
||||
* windows, this is the root position of the client area of the window.
|
||||
*
|
||||
* Case | Called from (flags; gravity)
|
||||
* -----+-----------------------------------------------
|
||||
* 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.
|
||||
* Similarly, the width and height passed in are in client window
|
||||
* coordinates as well.
|
||||
*/
|
||||
gboolean is_configure_request;
|
||||
gboolean do_gravity_adjust;
|
||||
gboolean is_user_action;
|
||||
gboolean did_placement;
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
|
||||
/* 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_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,
|
||||
is_configure_request ? " (configure request)" : "",
|
||||
is_user_action ? " (user move/resize)" : "",
|
||||
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",
|
||||
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;
|
||||
|
||||
|
@ -250,6 +250,116 @@ send_configure_notify (MetaWindow *window)
|
||||
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
|
||||
meta_window_apply_session_info (MetaWindow *window,
|
||||
const MetaWindowSessionInfo *info)
|
||||
@ -359,31 +469,31 @@ meta_window_apply_session_info (MetaWindow *window,
|
||||
|
||||
if (info->geometry_set)
|
||||
{
|
||||
int x, y, w, h;
|
||||
MetaRectangle rect;
|
||||
MetaMoveResizeFlags flags;
|
||||
|
||||
window->placed = TRUE; /* don't do placement algorithms later */
|
||||
|
||||
x = info->rect.x;
|
||||
y = info->rect.y;
|
||||
rect.x = info->rect.x;
|
||||
rect.y = info->rect.y;
|
||||
|
||||
w = window->size_hints.base_width +
|
||||
info->rect.width * window->size_hints.width_inc;
|
||||
h = window->size_hints.base_height +
|
||||
info->rect.height * window->size_hints.height_inc;
|
||||
rect.width = window->size_hints.base_width + info->rect.width * window->size_hints.width_inc;
|
||||
rect.height = window->size_hints.base_height + info->rect.height * window->size_hints.height_inc;
|
||||
|
||||
/* Force old gravity, ignoring anything now set */
|
||||
window->size_hints.win_gravity = info->gravity;
|
||||
|
||||
meta_topic (META_DEBUG_SM,
|
||||
"Restoring pos %d,%d size %d x %d for %s\n",
|
||||
x, y, w, h, window->desc);
|
||||
flags = META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
|
||||
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,
|
||||
flags,
|
||||
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;
|
||||
if (!window->override_redirect)
|
||||
{
|
||||
MetaRectangle rect;
|
||||
|
||||
rect.x = window->size_hints.x;
|
||||
rect.y = window->size_hints.y;
|
||||
rect.width = window->size_hints.width;
|
||||
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,
|
||||
window->size_hints.x,
|
||||
window->size_hints.y,
|
||||
window->size_hints.width,
|
||||
window->size_hints.height);
|
||||
rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1958,13 +2079,24 @@ meta_window_move_resize_request (MetaWindow *window,
|
||||
flags |= META_IS_RESIZE_ACTION;
|
||||
|
||||
if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
|
||||
{
|
||||
MetaRectangle rect;
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
adjust_for_gravity (window,
|
||||
TRUE,
|
||||
window->size_hints.win_gravity,
|
||||
&rect);
|
||||
|
||||
meta_window_move_resize_internal (window,
|
||||
flags,
|
||||
gravity,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height);
|
||||
rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
Loading…
Reference in New Issue
Block a user