From 8a0f1f93552dda06c17e095db313963229253d02 Mon Sep 17 00:00:00 2001 From: "Andrew J. Hesford" Date: Tue, 6 Feb 2024 11:26:42 -0500 Subject: [PATCH] resistance: only resist "entry" into another window space --- include/edges.h | 3 ++- src/edges.c | 8 ++++++-- src/resistance.c | 46 ++++++++++++++++++++++++---------------------- src/snap.c | 2 +- 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/include/edges.h b/include/edges.h index 974893bd..4e7549eb 100644 --- a/include/edges.h +++ b/include/edges.h @@ -66,6 +66,7 @@ struct edge { * @target: position to which the moving edge will be moved * @oppose: opposing edge of encountered region * @align: aligned edge of encountered region + * @lesser: true if the moving edge is top or left, false otherwise * * This function will be used by edge_find_neighbors and edge_find_outputs to * validate and select the "best" output or neighbor edge against which a @@ -92,7 +93,7 @@ struct edge { * update the value of *best accordingly. */ typedef void (*edge_validator_t)(int *best, struct edge current, - struct edge target, struct edge oppose, struct edge align); + struct edge target, struct edge oppose, struct edge align, bool lesser); void edges_initialize(struct border *edges); diff --git a/src/edges.c b/src/edges.c index 6637f7b5..86736a4d 100644 --- a/src/edges.c +++ b/src/edges.c @@ -90,11 +90,13 @@ validate_single_region_edge(int *valid_edge, * the region borders for aligned edges only. */ + bool lesser = direction == VIEW_EDGE_LEFT || direction == VIEW_EDGE_UP; + validator(valid_edge, build_edge(view, direction, 0), build_edge(target, direction, 0), build_edge(region, view_edge_invert(direction), 0), - build_edge(region, direction, rc.gap)); + build_edge(region, direction, rc.gap), lesser); } static void @@ -132,11 +134,13 @@ validate_single_output_edge(int *valid_edge, .left = INT_MIN, }; + bool lesser = direction == VIEW_EDGE_LEFT || direction == VIEW_EDGE_UP; + validator(valid_edge, build_edge(view, direction, 0), build_edge(target, direction, 0), build_edge(region, direction, 0), - build_edge(unbounded, direction, 0)); + build_edge(unbounded, direction, 0), lesser); } static void diff --git a/src/resistance.c b/src/resistance.c index 09cb4ce9..e7869fc1 100644 --- a/src/resistance.c +++ b/src/resistance.c @@ -11,12 +11,11 @@ static void check_edge(int *next, struct edge current, struct edge target, - struct edge oppose, struct edge align, int tolerance) + struct edge oppose, struct edge align, int tolerance, bool lesser) { int cur = current.offset; int tgt = target.offset; int opp = oppose.offset; - int aln = align.offset; /* Ignore non-moving edges */ if (cur == tgt) { @@ -39,9 +38,28 @@ check_edge(int *next, struct edge current, struct edge target, /* Direction of motion for the edge */ const bool decreasing = tgt < cur; + /* + * Motion resists "entry" into the space of another window, but never + * resist leaving it. Without edge attraction, this only happens when + * the "leading" edge of a motion (top edge upward, bottom edge + * downward, left edge leftward, right edge rightward) encounters an + * opposing edge. If the motion is not of a leading edge, there is no + * need to check for any resistance. + * + * However, if there is attraction, a "trailing" edge of a motion (top + * edge downward, bottom edge upward, left edge rightward, right edge + * leftward) may be grabbed by the opposing edge of another window as + * it passes. Hence, trailing edges still need to be tested in + * attractive cases. + */ + if (tolerance >= 0 && lesser != decreasing) { + return; + } + /* Check the opposing edge */ bool valid = false; if (decreasing) { + /* Check for decreasing movement across opposing edge */ const int lo = clipped_sub(opp, abs(tolerance)); const int hi = clipped_sub(opp, MIN(tolerance, 0)); valid = tgt >= lo && tgt < hi && cur >= opp; @@ -55,38 +73,22 @@ check_edge(int *next, struct edge current, struct edge target, if (valid && edges_traverse_edge(current, target, oppose)) { *next = edge_get_best(*next, opp, decreasing); } - - /* Check the aligned edge */ - valid = false; - if (decreasing) { - const int lo = clipped_sub(aln, abs(tolerance)); - const int hi = clipped_sub(aln, MIN(tolerance, 0)); - valid = tgt >= lo && tgt < hi && cur >= aln; - } else { - const int lo = clipped_add(aln, MIN(tolerance, 0)); - const int hi = clipped_add(aln, abs(tolerance)); - valid = tgt > lo && tgt <= hi && cur <= aln; - } - - if (valid && edges_traverse_edge(current, target, align)) { - *next = edge_get_best(*next, aln, decreasing); - } } static void check_edge_output(int *next, struct edge current, struct edge target, - struct edge oppose, struct edge align) + struct edge oppose, struct edge align, bool lesser) { check_edge(next, current, target, - oppose, align, rc.screen_edge_strength); + oppose, align, rc.screen_edge_strength, lesser); } static void check_edge_window(int *next, struct edge current, struct edge target, - struct edge oppose, struct edge align) + struct edge oppose, struct edge align, bool lesser) { check_edge(next, current, target, - oppose, align, rc.window_edge_strength); + oppose, align, rc.window_edge_strength, lesser); } void diff --git a/src/snap.c b/src/snap.c index af402ca1..1215f0be 100644 --- a/src/snap.c +++ b/src/snap.c @@ -13,7 +13,7 @@ static void check_edge(int *next, struct edge current, struct edge target, - struct edge oppose, struct edge align) + struct edge oppose, struct edge align, bool lesser) { int cur = current.offset; int tgt = target.offset;