]> git.mdlowis.com Git - proto/labwc.git/commitdiff
resistance: only resist "entry" into another window space
authorAndrew J. Hesford <ajh@sideband.org>
Tue, 6 Feb 2024 16:26:42 +0000 (11:26 -0500)
committerAndrew J. Hesford <ajh@sideband.org>
Tue, 6 Feb 2024 16:26:42 +0000 (11:26 -0500)
include/edges.h
src/edges.c
src/resistance.c
src/snap.c

index 974893bdbdc4a797c8c489f05ec209a32ca9ca66..4e7549eb28d7f834ef02d08af986841d7d92b6e8 100644 (file)
@@ -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);
 
index 6637f7b5bce7770b4b7aa179cf22d0f13ac6e1a8..86736a4d502baf27c0d295c0346f31e7e35d904d 100644 (file)
@@ -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
index 09cb4ce97b6eb524de852afa0a543fee9c19baea..e7869fc172fd17d30bdf9227a7420ef4e77ccb18 100644 (file)
 
 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
index af402ca16124b683c9bed5016998241231cd75c3..1215f0be0634cdc6d39dd0d3518b7197822f12a9 100644 (file)
@@ -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;