mirror of
https://github.com/brl/mutter.git
synced 2025-08-03 15:14:46 +00:00
Use utility functions to convert between frame and client rectangles
There are extensive places in the code where we convert between the client rectangle and the frame rectangle. Instead of manually doing it use new helper functions on MetaWindow and the existing meta_window_get_outer_rect(). This fixes a number of bugs where the computation was being done incorrectly, most of these bugs are with the recently added custom frame extents, but some relate to invisible borders or even simply to confusion between the window and frame rectangle. Switch the placement code to place the frame rectangle rather than the client window - this simplifies things considerably. https://bugzilla.gnome.org/show_bug.cgi?id=707194
This commit is contained in:
@@ -3959,7 +3959,7 @@ meta_window_can_tile_side_by_side (MetaWindow *window)
|
||||
{
|
||||
int monitor;
|
||||
MetaRectangle tile_area;
|
||||
MetaFrameBorders borders;
|
||||
MetaRectangle client_rect;
|
||||
|
||||
if (!meta_window_can_tile_maximized (window))
|
||||
return FALSE;
|
||||
@@ -3973,13 +3973,10 @@ meta_window_can_tile_side_by_side (MetaWindow *window)
|
||||
|
||||
tile_area.width /= 2;
|
||||
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
meta_window_frame_rect_to_client_rect (window, &tile_area, &client_rect);
|
||||
|
||||
tile_area.width -= (borders.visible.left + borders.visible.right);
|
||||
tile_area.height -= (borders.visible.top + borders.visible.bottom);
|
||||
|
||||
return tile_area.width >= window->size_hints.min_width &&
|
||||
tile_area.height >= window->size_hints.min_height;
|
||||
return client_rect.width >= window->size_hints.min_width &&
|
||||
client_rect.height >= window->size_hints.min_height;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -5670,23 +5667,10 @@ meta_window_move_frame (MetaWindow *window,
|
||||
int root_x_nw,
|
||||
int root_y_nw)
|
||||
{
|
||||
int x = root_x_nw;
|
||||
int y = root_y_nw;
|
||||
MetaRectangle rect = { root_x_nw, root_y_nw, 0, 0 };
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
MetaFrameBorders borders;
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
/* root_x_nw and root_y_nw correspond to where the top of
|
||||
* the visible frame should be. Offset by the distance between
|
||||
* the origin of the window and the origin of the enclosing
|
||||
* window decorations.
|
||||
*/
|
||||
x += window->frame->child_x - borders.invisible.left;
|
||||
y += window->frame->child_y - borders.invisible.top;
|
||||
}
|
||||
meta_window_move (window, user_op, x, y);
|
||||
meta_window_frame_rect_to_client_rect (window, &rect, &rect);
|
||||
meta_window_move (window, user_op, rect.x, rect.y);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -5734,18 +5718,10 @@ meta_window_move_resize_frame (MetaWindow *window,
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
MetaFrameBorders borders;
|
||||
MetaRectangle rect = { root_x_nw, root_y_nw, w, h };
|
||||
meta_window_frame_rect_to_client_rect (window, &rect, &rect);
|
||||
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
/* offset by the distance between the origin of the window
|
||||
* and the origin of the enclosing window decorations ( + border)
|
||||
*/
|
||||
root_x_nw += borders.visible.left;
|
||||
root_y_nw += borders.visible.top;
|
||||
w -= borders.visible.left + borders.visible.right;
|
||||
h -= borders.visible.top + borders.visible.bottom;
|
||||
|
||||
meta_window_move_resize (window, user_op, root_x_nw, root_y_nw, w, h);
|
||||
meta_window_move_resize (window, user_op, rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6057,6 +6033,91 @@ meta_window_get_input_rect (const MetaWindow *window,
|
||||
*rect = window->rect;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_client_rect_to_frame_rect:
|
||||
* @window: a #MetaWindow
|
||||
* @frame_rect: client rectangle in root coordinates
|
||||
* @client_rect: (out): location to store the computed corresponding frame bounds.
|
||||
*
|
||||
* Converts a desired bounds of the client window - what is passed to meta_window_move_resize() -
|
||||
* into the corresponding bounds of the window frame (excluding invisible borders
|
||||
* and client side shadows.)
|
||||
*/
|
||||
void
|
||||
meta_window_client_rect_to_frame_rect (MetaWindow *window,
|
||||
MetaRectangle *frame_rect,
|
||||
MetaRectangle *client_rect)
|
||||
{
|
||||
if (!client_rect)
|
||||
return;
|
||||
|
||||
*client_rect = *frame_rect;
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
MetaFrameBorders borders;
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
client_rect->x -= borders.visible.left;
|
||||
client_rect->y -= borders.visible.top;
|
||||
client_rect->width += borders.visible.left + borders.visible.right;
|
||||
client_rect->height += borders.visible.top + borders.visible.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window->has_custom_frame_extents)
|
||||
{
|
||||
const GtkBorder *extents = &window->custom_frame_extents;
|
||||
client_rect->x += extents->left;
|
||||
client_rect->y += extents->top;
|
||||
client_rect->width -= extents->left + extents->right;
|
||||
client_rect->height -= extents->top + extents->bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_frame_rect_to_client_rect:
|
||||
* @window: a #MetaWindow
|
||||
* @frame_rect: desired frame bounds for the window
|
||||
* @client_rect: (out): location to store the computed corresponding client rectangle.
|
||||
*
|
||||
* Converts a desired frame bounds for a window into the bounds of the client
|
||||
* window - what is passed to meta_window_move_resize().
|
||||
*/
|
||||
void
|
||||
meta_window_frame_rect_to_client_rect (MetaWindow *window,
|
||||
MetaRectangle *frame_rect,
|
||||
MetaRectangle *client_rect)
|
||||
{
|
||||
if (!client_rect)
|
||||
return;
|
||||
|
||||
*client_rect = *frame_rect;
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
MetaFrameBorders borders;
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
client_rect->x += borders.visible.left;
|
||||
client_rect->y += borders.visible.top;
|
||||
client_rect->width -= borders.visible.left + borders.visible.right;
|
||||
client_rect->height -= borders.visible.top + borders.visible.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window->has_custom_frame_extents)
|
||||
{
|
||||
const GtkBorder *extents = &window->custom_frame_extents;
|
||||
client_rect->x -= extents->left;
|
||||
client_rect->y -= extents->top;
|
||||
client_rect->width += extents->left + extents->right;
|
||||
client_rect->height += extents->top + extents->bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_outer_rect:
|
||||
* @window: a #MetaWindow
|
||||
@@ -8784,18 +8845,13 @@ recalc_window_features (MetaWindow *window)
|
||||
|
||||
if (window->has_maximize_func)
|
||||
{
|
||||
MetaRectangle work_area;
|
||||
MetaFrameBorders borders;
|
||||
int min_frame_width, min_frame_height;
|
||||
MetaRectangle work_area, client_rect;
|
||||
|
||||
meta_window_get_work_area_current_monitor (window, &work_area);
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
meta_window_frame_rect_to_client_rect (window, &work_area, &client_rect);
|
||||
|
||||
min_frame_width = window->size_hints.min_width + borders.visible.left + borders.visible.right;
|
||||
min_frame_height = window->size_hints.min_height + borders.visible.top + borders.visible.bottom;
|
||||
|
||||
if (min_frame_width >= work_area.width ||
|
||||
min_frame_height >= work_area.height)
|
||||
if (window->size_hints.min_width >= client_rect.width ||
|
||||
window->size_hints.min_height >= client_rect.height)
|
||||
window->has_maximize_func = FALSE;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user