mirror of
https://github.com/labwc/labwc.git
synced 2025-11-04 13:30:07 -05:00
edges: simplify output edge validation
This commit is contained in:
parent
01af000cd1
commit
b82d4783ea
1 changed files with 57 additions and 57 deletions
114
src/edges.c
114
src/edges.c
|
|
@ -39,17 +39,20 @@ validate_edges(struct border *valid_edges,
|
||||||
struct border view, struct border target,
|
struct border view, struct border target,
|
||||||
struct border region, edge_validator_t validator)
|
struct border region, edge_validator_t validator)
|
||||||
{
|
{
|
||||||
/* When a view snaps to a region while moving to its target, it can do
|
/*
|
||||||
|
* When a view snaps to another while moving to its target, it can do
|
||||||
* so in two ways: a view edge can snap to an "opposing" edge of the
|
* so in two ways: a view edge can snap to an "opposing" edge of the
|
||||||
* region (left <-> right, top <-> bottom) or to an "aligned" edge
|
* region (left <-> right, top <-> bottom) or to an "aligned" edge
|
||||||
* (left <-> left, right <-> right, top <-> top, bottom <-> bottom).
|
* (left <-> left, right <-> right, top <-> top, bottom <-> bottom).
|
||||||
*
|
*
|
||||||
* When a view hits the opposing edge of a region, it should be
|
* When a view hits the opposing edge of a region, it should be
|
||||||
* separated by a gap; when a view hits the aligned edge, it should not
|
* separated by any configured gap and will resist *entry* into the
|
||||||
* be separated. The view and its target already include necessary
|
* region; when a view hits the aligned edge, it should not be
|
||||||
* padding to reflect the gap. The region does not. To make sure the
|
* separated by a gap and will resist *departure* from the region. The
|
||||||
* "aligned" edges are properly aligned, add padding to the region
|
* view and its target already include necessary padding to reflect the
|
||||||
* borders for aligned edges only.
|
* gap. The region does not. To make sure the "aligned" edges are
|
||||||
|
* properly aligned with respect to the configured gap, add padding to
|
||||||
|
* the region borders for aligned edges only.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct border region_pad = {
|
struct border region_pad = {
|
||||||
|
|
@ -76,6 +79,52 @@ validate_edges(struct border *valid_edges,
|
||||||
region.top, region_pad.bottom, /* lesser */ false);
|
region.top, region_pad.bottom, /* lesser */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
validate_output_edges(struct border *valid_edges,
|
||||||
|
struct border view, struct border target,
|
||||||
|
struct wlr_box usable, edge_validator_t validator)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* When a view snaps to an output that contains it, it can be
|
||||||
|
* transformed into either of two equivalent problems:
|
||||||
|
*
|
||||||
|
* 1. The output region can be treated as if it were bounded by four
|
||||||
|
* half-planes, one sharing each edge of the view and extending
|
||||||
|
* infinitely *away* from the output. The moving view should then be
|
||||||
|
* tested as it encounters the "opposing" edge of each external region.
|
||||||
|
*
|
||||||
|
* 2. The output region can be treated as if it were composed of four
|
||||||
|
* half-planes, one sharing each edge of the view and extending
|
||||||
|
* infinitely to *overlap* the output. The moving view should then be
|
||||||
|
* tested as it encounters the "aligned" edge of each overlapping
|
||||||
|
* region.
|
||||||
|
*
|
||||||
|
* Either one of these problems can be realized by four calls to
|
||||||
|
* validate_edges with suitably defined half-plane regions, but most of
|
||||||
|
* the work in those validations will just be comparing invalid
|
||||||
|
* infinite edges.
|
||||||
|
*
|
||||||
|
* To save a bit of effort, just choose Problem 1 and directly validate
|
||||||
|
* only the non-infinite edges.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Left edge encounters a half-infinite region to the left of the output */
|
||||||
|
validator(&valid_edges->left, view.left, target.left,
|
||||||
|
usable.x, INT_MIN, /* lesser */ true);
|
||||||
|
|
||||||
|
/* Right edge encounters a half-infinite region to the right of the output */
|
||||||
|
validator(&valid_edges->right, view.right, target.right,
|
||||||
|
usable.x + usable.width, INT_MAX, /* lesser */ false);
|
||||||
|
|
||||||
|
/* Top edge encounters a half-infinite region above the output */
|
||||||
|
validator(&valid_edges->top, view.top, target.top,
|
||||||
|
usable.y, INT_MIN, /* lesser */ true);
|
||||||
|
|
||||||
|
/* Bottom edge encounters a half-infinite region below the output */
|
||||||
|
validator(&valid_edges->bottom, view.bottom, target.bottom,
|
||||||
|
usable.y + usable.height, INT_MAX, /* lesser */ false);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
edges_find_neighbors(struct border *nearest_edges, struct view *view,
|
edges_find_neighbors(struct border *nearest_edges, struct view *view,
|
||||||
struct wlr_box target, struct output *output,
|
struct wlr_box target, struct output *output,
|
||||||
|
|
@ -154,57 +203,8 @@ edges_find_outputs(struct border *nearest_edges, struct view *view,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
validate_output_edges(nearest_edges,
|
||||||
* Split a single "leaving output" problem into four "entering
|
view_edges, target_edges, usable, validator);
|
||||||
* complementary region" problems, treating the view, its
|
|
||||||
* target and the screen boundaries as half planes. This
|
|
||||||
* prevents unexpected snapping behavior like the bottom of a
|
|
||||||
* window snapping above the top of an output, where it would
|
|
||||||
* become invisible.
|
|
||||||
*/
|
|
||||||
struct border screen;
|
|
||||||
struct border view_eff;
|
|
||||||
struct border target_eff;
|
|
||||||
|
|
||||||
/* First problem: view toward upper half-plane */
|
|
||||||
edges_initialize(&screen);
|
|
||||||
edges_initialize(&view_eff);
|
|
||||||
edges_initialize(&target_eff);
|
|
||||||
|
|
||||||
screen.bottom = usable.y;
|
|
||||||
view_eff.top = view_edges.top;
|
|
||||||
target_eff.top = target_edges.top;
|
|
||||||
validate_edges(nearest_edges, view_eff, target_eff, screen, validator);
|
|
||||||
|
|
||||||
/* Second problem: view toward lower half-plane */
|
|
||||||
edges_initialize(&screen);
|
|
||||||
edges_initialize(&view_eff);
|
|
||||||
edges_initialize(&target_eff);
|
|
||||||
|
|
||||||
screen.top = usable.y + usable.height;
|
|
||||||
view_eff.bottom = view_edges.bottom;
|
|
||||||
target_eff.bottom = target_edges.bottom;
|
|
||||||
validate_edges(nearest_edges, view_eff, target_eff, screen, validator);
|
|
||||||
|
|
||||||
/* Third problem: view toward left half-plane */
|
|
||||||
edges_initialize(&screen);
|
|
||||||
edges_initialize(&view_eff);
|
|
||||||
edges_initialize(&target_eff);
|
|
||||||
|
|
||||||
screen.right = usable.x;
|
|
||||||
view_eff.left = view_edges.left;
|
|
||||||
target_eff.left = target_edges.left;
|
|
||||||
validate_edges(nearest_edges, view_eff, target_eff, screen, validator);
|
|
||||||
|
|
||||||
/* Fourth problem: view toward right half-plane */
|
|
||||||
edges_initialize(&screen);
|
|
||||||
edges_initialize(&view_eff);
|
|
||||||
edges_initialize(&target_eff);
|
|
||||||
|
|
||||||
screen.left = usable.x + usable.width;
|
|
||||||
view_eff.right = view_edges.right;
|
|
||||||
target_eff.right = target_edges.right;
|
|
||||||
validate_edges(nearest_edges, view_eff, target_eff, screen, validator);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue