Package: ratpoison
Version: 1.4.9-1
Severity: normal
Tags: patch
X-Debbugs-Cc: tsuyo...@yumegakanau.org

The focusup, focusdown, focusleft, and focusright commands, which move
to an adjacent frame, have some unintuitive behavior. For example,
suppose you have a grid of four equally-sized frames, arrayed in two
rows and two columns, like so:

        0       1

        2       3

And then suppose the original frame is 3, and you execute the focusup
command. Part of the algorithm is: if the left side of the original frame
is either aligned with or to the right of a frame, and if the left side of
the original frame is aligned with or to the left of the frame, move to
that frame. Because the left corner is numbered 0 and encountered first,
and it satisfies those conditions, it will move to frame 0, rather than 1,
which is what I would expect.

The included patch changes the algorithm of these commands to instead seek out
the frame which has the nearest left side (in the case of focusup and 
focusdown),
or the nearest top side (in the case of focusleft and focusright). So using the
above grid:

        focusright will move from 0 to 1 or 2 to 3
        focusleft will move from 1 to 0 or 3 to 2
        focusdown will move from 0 to 2 or 1 to 3
        focusup will move from 2 to 0 or 3 to 1

Which is exactly what I would expect.

diff -ur ratpoison-1.4.9/src/split.c new/ratpoison-1.4.9/src/split.c
--- ratpoison-1.4.9/src/split.c 2022-09-07 14:43:12.000000000 -0700
+++ new/ratpoison-1.4.9/src/split.c     2022-09-07 14:34:04.685739525 -0700
@@ -23,6 +23,8 @@
 
 #include <unistd.h>
 #include <string.h>
+#include <limits.h>
+#include <stdlib.h>
 
 #include "ratpoison.h"
 
@@ -1288,8 +1290,8 @@
   rp_screen *s;
   rp_frame *cur;
 
-  rp_frame *best_frame_yet = NULL;
-  int best_x_yet = frame_right_abs(frame) + 1;
+  rp_frame *nearest_frame_yet = NULL;
+  int smallest_distance_yet = INT_MAX;
 
   list_for_each_entry (s, &rp_screens, node)
     {
@@ -1297,18 +1299,18 @@
         {
           if (frame_top_abs (frame) == frame_bottom_abs (cur))
            {
-              if (frame_left_abs (frame) >= frame_left_abs(cur) && 
frame_left_abs(frame) <= frame_right_abs(cur))
-                return cur;
-              if (frame_left_abs(cur) >= frame_left_abs(frame) && 
frame_left_abs(cur) < best_x_yet )
-                {
-                  best_x_yet = frame_left_abs(cur);
-                  best_frame_yet = cur;
-                }
+             if (frame_left_abs (frame) == frame_left_abs (cur)) return cur;
+             int current_distance = abs(frame_left_abs (frame) - 
frame_left_abs (cur));
+             if (current_distance < smallest_distance_yet)
+               {
+                 nearest_frame_yet = cur;
+                 smallest_distance_yet = current_distance;
+               }
             }
         }
     }
 
-  return best_frame_yet;
+  return nearest_frame_yet;
 }
 
 rp_frame *
@@ -1317,8 +1319,8 @@
   rp_screen *s;
   rp_frame *cur;
 
-  rp_frame *best_frame_yet = NULL;
-  int best_x_yet = frame_right_abs(frame) + 1;
+  rp_frame *nearest_frame_yet = NULL;
+  int smallest_distance_yet = INT_MAX;
 
   list_for_each_entry (s, &rp_screens, node)
     {
@@ -1326,18 +1328,18 @@
         {
           if (frame_bottom_abs (frame) == frame_top_abs (cur))
             {
-              if (frame_left_abs(frame) >= frame_left_abs(cur) && 
frame_left_abs(frame) < frame_right_abs(cur))
-                return cur;
-              if (frame_left_abs(cur) >= frame_left_abs(frame) && 
frame_left_abs(cur) < best_x_yet)
-                {
-                  best_x_yet = frame_left_abs(cur);
-                  best_frame_yet = cur;
-                }
+             if (frame_left_abs (frame) == frame_left_abs (cur)) return cur;
+             int current_distance = abs(frame_left_abs (frame) - 
frame_left_abs (cur));
+             if (current_distance < smallest_distance_yet)
+               {
+                 nearest_frame_yet = cur;
+                 smallest_distance_yet = current_distance;
+               }
             }
         }
     }
 
-  return best_frame_yet;
+  return nearest_frame_yet;
 }
 
 rp_frame *
@@ -1346,8 +1348,8 @@
   rp_screen *s;
   rp_frame *cur;
 
-  rp_frame *best_frame_yet = NULL;
-  int best_y_yet = frame_bottom_abs(frame) + 1;
+  rp_frame *nearest_frame_yet = NULL;
+  int smallest_distance_yet = INT_MAX;
 
   list_for_each_entry (s, &rp_screens, node)
     {
@@ -1355,18 +1357,18 @@
         {
           if (frame_left_abs (frame) == frame_right_abs (cur))
             {
-              if (frame_top_abs (frame) >= frame_top_abs(cur) && 
frame_top_abs(frame) < frame_bottom_abs(cur))
-                return cur;
-              if (frame_top_abs(cur) >= frame_top_abs(frame) && 
frame_top_abs(cur) < best_y_yet)
-                {
-                  best_y_yet = frame_top_abs(cur);
-                  best_frame_yet = cur;
-                }
+             if (frame_top_abs (frame) == frame_top_abs (cur)) return cur;
+             int current_distance = abs(frame_top_abs (frame) - frame_top_abs 
(cur));
+             if (current_distance < smallest_distance_yet)
+               {
+                 nearest_frame_yet = cur;
+                 smallest_distance_yet = current_distance;
+               }
             }
         }
     }
 
-  return best_frame_yet;
+  return nearest_frame_yet;
 }
 
 rp_frame *
@@ -1375,8 +1377,8 @@
   rp_screen *s;
   rp_frame *cur;
 
-  rp_frame *best_frame_yet = NULL;
-  int best_y_yet = frame->y + frame->height + 1;
+  rp_frame *nearest_frame_yet = NULL;
+  int smallest_distance_yet = INT_MAX;
 
   list_for_each_entry (s, &rp_screens, node)
     {
@@ -1384,18 +1386,18 @@
         {
           if (frame_right_abs (frame) == frame_left_abs (cur))
             {
-          if (frame_top_abs(frame) >= frame_top_abs(cur) && 
frame_top_abs(frame) < frame_bottom_abs(cur))
-            return cur;
-          if (frame_top_abs(cur) >= frame_top_abs(frame) && frame_top_abs(cur) 
< best_y_yet )
-            {
-              best_y_yet = frame_top_abs(cur);
-              best_frame_yet = cur;
-            }
+             if (frame_top_abs (frame) == frame_top_abs (cur)) return cur;
+             int current_distance = abs(frame_top_abs (frame) - frame_top_abs 
(cur));
+             if (current_distance < smallest_distance_yet)
+               {
+                 nearest_frame_yet = cur;
+                 smallest_distance_yet = current_distance;
+               }
             }
         }
     }
 
-  return best_frame_yet;
+  return nearest_frame_yet;
 }
 
 rp_frame *

-- System Information:
Debian Release: bookworm/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.18.0-3-amd64 (SMP w/2 CPU threads; PREEMPT)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages ratpoison depends on:
ii  libc6       2.33-8
ii  libx11-6    2:1.7.5-1
ii  libxft2     2.3.4-1
ii  libxrandr2  2:1.5.2-2+b1
ii  libxtst6    2:1.2.3-1.1

Versions of packages ratpoison recommends:
ii  9menu                                 1.10-1
ii  gnome-terminal [x-terminal-emulator]  3.44.1-1
ii  menu                                  2.1.49
ii  rxvt-unicode [x-terminal-emulator]    9.30-2+b2
ii  xterm [x-terminal-emulator]           372-1

Versions of packages ratpoison suggests:
pn  xbindkeys  <none>
pn  xclip      <none>

-- no debconf information

Reply via email to