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