window: Make edge constraint code more readable

It relied on indices in arrays determining tile direction and
non-obvious bitmask logic to translate to _GTK_EDGE_CONSTRAINTS. Change
this to explicitly named edge constraints, and clear translation methods
that converts between mutters and GTK+s edge constraint formats.
This commit is contained in:
Jonas Ådahl 2018-10-24 14:24:22 +02:00
parent 5fc07fcc23
commit 640a04d0e4
4 changed files with 107 additions and 49 deletions

View File

@ -222,11 +222,12 @@ struct _MetaWindow
guint saved_maximize : 1; guint saved_maximize : 1;
int tile_monitor_number; int tile_monitor_number;
/* 0 - top struct {
* 1 - right MetaEdgeConstraint top;
* 2 - bottom MetaEdgeConstraint right;
* 3 - left */ MetaEdgeConstraint bottom;
MetaEdgeConstraint edge_constraints[4]; MetaEdgeConstraint left;
} edge_constraints;
double tile_hfraction; double tile_hfraction;

View File

@ -3074,54 +3074,54 @@ update_edge_constraints (MetaWindow *window)
switch (window->tile_mode) switch (window->tile_mode)
{ {
case META_TILE_NONE: case META_TILE_NONE:
window->edge_constraints[0] = META_EDGE_CONSTRAINT_NONE; window->edge_constraints.top = META_EDGE_CONSTRAINT_NONE;
window->edge_constraints[1] = META_EDGE_CONSTRAINT_NONE; window->edge_constraints.right = META_EDGE_CONSTRAINT_NONE;
window->edge_constraints[2] = META_EDGE_CONSTRAINT_NONE; window->edge_constraints.bottom = META_EDGE_CONSTRAINT_NONE;
window->edge_constraints[3] = META_EDGE_CONSTRAINT_NONE; window->edge_constraints.left = META_EDGE_CONSTRAINT_NONE;
break; break;
case META_TILE_MAXIMIZED: case META_TILE_MAXIMIZED:
window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR;
window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR;
window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR;
window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR;
break; break;
case META_TILE_LEFT: case META_TILE_LEFT:
window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR;
if (window->tile_match) if (window->tile_match)
window->edge_constraints[1] = META_EDGE_CONSTRAINT_WINDOW; window->edge_constraints.right = META_EDGE_CONSTRAINT_WINDOW;
else else
window->edge_constraints[1] = META_EDGE_CONSTRAINT_NONE; window->edge_constraints.right = META_EDGE_CONSTRAINT_NONE;
window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR;
window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR;
break; break;
case META_TILE_RIGHT: case META_TILE_RIGHT:
window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR;
window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR;
window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR;
if (window->tile_match) if (window->tile_match)
window->edge_constraints[3] = META_EDGE_CONSTRAINT_WINDOW; window->edge_constraints.left = META_EDGE_CONSTRAINT_WINDOW;
else else
window->edge_constraints[3] = META_EDGE_CONSTRAINT_NONE; window->edge_constraints.left = META_EDGE_CONSTRAINT_NONE;
break; break;
} }
/* h/vmaximize also modify the edge constraints */ /* h/vmaximize also modify the edge constraints */
if (window->maximized_vertically) if (window->maximized_vertically)
{ {
window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR;
window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR;
} }
if (window->maximized_horizontally) if (window->maximized_horizontally)
{ {
window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR;
window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR;
} }
} }

View File

@ -162,29 +162,25 @@ fill_edge_states (struct wl_array *states,
{ {
uint32_t *s; uint32_t *s;
/* Top */ if (window->edge_constraints.top != META_EDGE_CONSTRAINT_MONITOR)
if (window->edge_constraints[0] != META_EDGE_CONSTRAINT_MONITOR)
{ {
s = wl_array_add (states, sizeof *s); s = wl_array_add (states, sizeof *s);
*s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_TOP; *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_TOP;
} }
/* Right */ if (window->edge_constraints.right != META_EDGE_CONSTRAINT_MONITOR)
if (window->edge_constraints[1] != META_EDGE_CONSTRAINT_MONITOR)
{ {
s = wl_array_add (states, sizeof *s); s = wl_array_add (states, sizeof *s);
*s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_RIGHT; *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_RIGHT;
} }
/* Bottom */ if (window->edge_constraints.bottom != META_EDGE_CONSTRAINT_MONITOR)
if (window->edge_constraints[2] != META_EDGE_CONSTRAINT_MONITOR)
{ {
s = wl_array_add (states, sizeof *s); s = wl_array_add (states, sizeof *s);
*s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_BOTTOM; *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_BOTTOM;
} }
/* Left */ if (window->edge_constraints.left != META_EDGE_CONSTRAINT_MONITOR)
if (window->edge_constraints[3] != META_EDGE_CONSTRAINT_MONITOR)
{ {
s = wl_array_add (states, sizeof *s); s = wl_array_add (states, sizeof *s);
*s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_LEFT; *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_LEFT;
@ -224,28 +220,28 @@ fill_states (struct wl_array *states,
} }
if (version >= GTK_SURFACE1_STATE_TILED_TOP_SINCE_VERSION && if (version >= GTK_SURFACE1_STATE_TILED_TOP_SINCE_VERSION &&
window->edge_constraints[0] != META_EDGE_CONSTRAINT_NONE) window->edge_constraints.top != META_EDGE_CONSTRAINT_NONE)
{ {
s = wl_array_add (states, sizeof *s); s = wl_array_add (states, sizeof *s);
*s = GTK_SURFACE1_STATE_TILED_TOP; *s = GTK_SURFACE1_STATE_TILED_TOP;
} }
if (version >= GTK_SURFACE1_STATE_TILED_RIGHT_SINCE_VERSION && if (version >= GTK_SURFACE1_STATE_TILED_RIGHT_SINCE_VERSION &&
window->edge_constraints[1] != META_EDGE_CONSTRAINT_NONE) window->edge_constraints.right != META_EDGE_CONSTRAINT_NONE)
{ {
s = wl_array_add (states, sizeof *s); s = wl_array_add (states, sizeof *s);
*s = GTK_SURFACE1_STATE_TILED_RIGHT; *s = GTK_SURFACE1_STATE_TILED_RIGHT;
} }
if (version >= GTK_SURFACE1_STATE_TILED_BOTTOM_SINCE_VERSION && if (version >= GTK_SURFACE1_STATE_TILED_BOTTOM_SINCE_VERSION &&
window->edge_constraints[2] != META_EDGE_CONSTRAINT_NONE) window->edge_constraints.bottom != META_EDGE_CONSTRAINT_NONE)
{ {
s = wl_array_add (states, sizeof *s); s = wl_array_add (states, sizeof *s);
*s = GTK_SURFACE1_STATE_TILED_BOTTOM; *s = GTK_SURFACE1_STATE_TILED_BOTTOM;
} }
if (version >= GTK_SURFACE1_STATE_TILED_LEFT_SINCE_VERSION && if (version >= GTK_SURFACE1_STATE_TILED_LEFT_SINCE_VERSION &&
window->edge_constraints[3] != META_EDGE_CONSTRAINT_NONE) window->edge_constraints.left != META_EDGE_CONSTRAINT_NONE)
{ {
s = wl_array_add (states, sizeof *s); s = wl_array_add (states, sizeof *s);
*s = GTK_SURFACE1_STATE_TILED_LEFT; *s = GTK_SURFACE1_STATE_TILED_LEFT;

View File

@ -50,6 +50,18 @@
#include "x11/window-props.h" #include "x11/window-props.h"
#include "x11/xprops.h" #include "x11/xprops.h"
enum _MetaGtkEdgeConstraints
{
META_GTK_EDGE_CONSTRAINT_TOP_TILED = 1 << 0,
META_GTK_EDGE_CONSTRAINT_TOP_RESIZABLE = 1 << 1,
META_GTK_EDGE_CONSTRAINT_RIGHT_TILED = 1 << 2,
META_GTK_EDGE_CONSTRAINT_RIGHT_RESIZABLE = 1 << 3,
META_GTK_EDGE_CONSTRAINT_BOTTOM_TILED = 1 << 4,
META_GTK_EDGE_CONSTRAINT_BOTTOM_RESIZABLE = 1 << 5,
META_GTK_EDGE_CONSTRAINT_LEFT_TILED = 1 << 6,
META_GTK_EDGE_CONSTRAINT_LEFT_RESIZABLE = 1 << 7
} MetaGtkEdgeConstraints;
G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW) G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW)
static void static void
@ -906,22 +918,71 @@ update_net_frame_extents (MetaWindow *window)
meta_x11_error_trap_pop (x11_display); meta_x11_error_trap_pop (x11_display);
} }
static gboolean
is_edge_constraint_resizable (MetaEdgeConstraint constraint)
{
switch (constraint)
{
case META_EDGE_CONSTRAINT_NONE:
case META_EDGE_CONSTRAINT_WINDOW:
return TRUE;
case META_EDGE_CONSTRAINT_MONITOR:
return FALSE;
}
g_assert_not_reached ();
}
static gboolean
is_edge_constraint_tiled (MetaEdgeConstraint constraint)
{
switch (constraint)
{
case META_EDGE_CONSTRAINT_NONE:
return FALSE;
case META_EDGE_CONSTRAINT_WINDOW:
case META_EDGE_CONSTRAINT_MONITOR:
return TRUE;
}
g_assert_not_reached ();
}
static unsigned long
edge_constraints_to_gtk_edge_constraints (MetaWindow *window)
{
unsigned long gtk_edge_constraints = 0;
if (is_edge_constraint_tiled (window->edge_constraints.top))
gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_TOP_TILED;
if (is_edge_constraint_resizable (window->edge_constraints.top))
gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_TOP_RESIZABLE;
if (is_edge_constraint_tiled (window->edge_constraints.right))
gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_RIGHT_TILED;
if (is_edge_constraint_resizable (window->edge_constraints.right))
gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_RIGHT_RESIZABLE;
if (is_edge_constraint_tiled (window->edge_constraints.bottom))
gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_BOTTOM_TILED;
if (is_edge_constraint_resizable (window->edge_constraints.bottom))
gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_BOTTOM_RESIZABLE;
if (is_edge_constraint_tiled (window->edge_constraints.left))
gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_LEFT_TILED;
if (is_edge_constraint_resizable (window->edge_constraints.left))
gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_LEFT_RESIZABLE;
return gtk_edge_constraints;
}
static void static void
update_gtk_edge_constraints (MetaWindow *window) update_gtk_edge_constraints (MetaWindow *window)
{ {
MetaX11Display *x11_display = window->display->x11_display; MetaX11Display *x11_display = window->display->x11_display;
MetaEdgeConstraint *constraints = window->edge_constraints;
unsigned long data[1]; unsigned long data[1];
/* Edge constraints */ data[0] = edge_constraints_to_gtk_edge_constraints (window);
data[0] = (constraints[0] != META_EDGE_CONSTRAINT_NONE ? 1 : 0) << 0 |
(constraints[0] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 1 |
(constraints[1] != META_EDGE_CONSTRAINT_NONE ? 1 : 0) << 2 |
(constraints[1] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 3 |
(constraints[2] != META_EDGE_CONSTRAINT_NONE ? 1 : 0) << 4 |
(constraints[2] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 5 |
(constraints[3] != META_EDGE_CONSTRAINT_NONE ? 1 : 0) << 6 |
(constraints[3] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 7;
meta_verbose ("Setting _GTK_EDGE_CONSTRAINTS to %lu\n", data[0]); meta_verbose ("Setting _GTK_EDGE_CONSTRAINTS to %lu\n", data[0]);