diff options
| author | emmett1 <me@emmett1.my> | 2026-03-30 23:16:04 +0800 |
|---|---|---|
| committer | emmett1 <me@emmett1.my> | 2026-03-30 23:16:04 +0800 |
| commit | 5af6eb7deb0b44c4326d0d9ef9f1b644a4a6c959 (patch) | |
| tree | 4f137c32e4eb9b73e4524245dc320d43e43c0497 | |
| parent | f62c73d5a605f871ebd39a5442dee976f67c9acd (diff) | |
fix channel switching order
| -rw-r--r-- | sirc.c | 31 |
1 files changed, 30 insertions, 1 deletions
@@ -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 ───────────────────────────────────────────────────────────── */ |
