aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremmett1 <me@emmett1.my>2026-03-30 23:16:04 +0800
committeremmett1 <me@emmett1.my>2026-03-30 23:16:04 +0800
commit5af6eb7deb0b44c4326d0d9ef9f1b644a4a6c959 (patch)
tree4f137c32e4eb9b73e4524245dc320d43e43c0497
parentf62c73d5a605f871ebd39a5442dee976f67c9acd (diff)
fix channel switching order
-rw-r--r--sirc.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/sirc.c b/sirc.c
index 6f67bed..37aa12c 100644
--- a/sirc.c
+++ b/sirc.c
@@ -425,9 +425,38 @@ static void chan_sort_users(Channel *ch) {
/* next/prev channel index that is NOT a *status* channel (unless it's the
only kind), skipping nothing — just a linear wrap */
+/* Build the visual order of channels (same traversal as draw_channels).
+ Returns the count; fills idx[] with g_chans indices in display order. */
+static int visual_order(int *idx, int max) {
+ int n = 0;
+ for (int si = 0; si < g_srv_count && n < max; si++) {
+ /* *status* first */
+ for (int ci = 0; ci < g_chan_count && n < max; ci++) {
+ if (g_chans[ci].srv != si) continue;
+ if (strcmp(g_chans[ci].name, "*status*") == 0)
+ idx[n++] = ci;
+ }
+ /* then regular channels */
+ for (int ci = 0; ci < g_chan_count && n < max; ci++) {
+ if (g_chans[ci].srv != si) continue;
+ if (strcmp(g_chans[ci].name, "*status*") != 0)
+ idx[n++] = ci;
+ }
+ }
+ return n;
+}
+
static int chan_next(int cur, int dir) {
if (g_chan_count <= 1) return cur;
- return (cur + dir + g_chan_count) % g_chan_count;
+ int idx[MAX_CHANS_TOTAL];
+ int n = visual_order(idx, MAX_CHANS_TOTAL);
+ if (n == 0) return cur;
+ /* find cur in visual order */
+ int pos = 0;
+ for (int i = 0; i < n; i++)
+ if (idx[i] == cur) { pos = i; break; }
+ pos = (pos + dir + n) % n;
+ return idx[pos];
}
/* ── ignore list ───────────────────────────────────────────────────────────── */