jcs
/wallops
/amendments
/120
chatter: Use Cmd+Number for switching tabs, not windows
Also add Cmd+, and Cmd+. for previous and next, but keep them in the
menu bar for discoverability and to let people change them through
ResEdit.
jcs made amendment 120 2 months ago
--- chatter.c Tue Sep 17 22:10:43 2024
+++ chatter.c Wed Sep 18 09:54:36 2024
@@ -139,8 +139,6 @@ chatter_init(const char *server, const unsigned short
snprintf(title, sizeof(title), "Disconnected");
CtoPstr(title);
InsMenuItem(window_menu, title, WINDOW_MENU_N_ID + focusable->id);
- SetItemCmd(window_menu, WINDOW_MENU_N_ID + focusable->id,
- '1' + focusable->id);
chatter_printf(chatter, NULL, NULL,
"$B***$0 Welcome to %s %s",
@@ -249,7 +247,7 @@ chatter_add_tab(struct chatter *chatter, Rect *win_bou
tab = xmalloczero(sizeof(struct chatter_tab));
if (tab == NULL)
- panic("xmalloc failed: out of memory");
+ panic("Out of memory allocating for new tab");
SLIST_APPEND(&chatter->tabs_list, tab, chatter_tab, list);
chatter->ntabs++;
tab->conn = conn;
@@ -937,7 +935,7 @@ bool
chatter_menu(struct focusable *focusable, short menu, short item)
{
struct chatter *chatter = (struct chatter *)(focusable->cookie);
- struct chatter_tab *tab = chatter->current_tab;
+ struct chatter_tab *tab = chatter->current_tab, *ttab;
switch (menu) {
case EDIT_MENU_ID:
@@ -964,6 +962,31 @@ chatter_menu(struct focusable *focusable, short menu,
break;
case VIEW_MENU_ID:
switch (item) {
+ case VIEW_MENU_PREV_TAB_ID: {
+ struct chatter_tab *last_tab = NULL;
+
+ SLIST_FOREACH(ttab, &chatter->tabs_list, list) {
+ if (ttab == tab) {
+ if (last_tab != NULL) {
+ chatter_use_shadow(chatter);
+ chatter_focus_tab(chatter, last_tab);
+ chatter_reveal_shadow(chatter);
+ }
+ /* TODO: otherwise wrap around to last tab? */
+ break;
+ }
+ last_tab = ttab;
+ }
+ return true;
+ }
+ case VIEW_MENU_NEXT_TAB_ID:
+ if ((ttab = SLIST_NEXT(tab, list))) {
+ chatter_use_shadow(chatter);
+ chatter_focus_tab(chatter, ttab);
+ chatter_reveal_shadow(chatter);
+ }
+ /* TODO: otherwise wrap around to first tab? */
+ return true;
case VIEW_MENU_CLOSE_ID:
if (chatter->current_tab->query_nick[0] ||
chatter->current_tab->channel)
@@ -987,6 +1010,16 @@ chatter_update_menu(struct focusable *focusable)
HLock(chatter->input_te);
HLock(tab->messages_te);
+ if (chatter->current_tab == SLIST_FIRST(&chatter->tabs_list))
+ DisableItem(view_menu, VIEW_MENU_PREV_TAB_ID);
+ else
+ EnableItem(view_menu, VIEW_MENU_PREV_TAB_ID);
+
+ if (SLIST_NEXT(chatter->current_tab, list))
+ EnableItem(view_menu, VIEW_MENU_NEXT_TAB_ID);
+ else
+ DisableItem(view_menu, VIEW_MENU_NEXT_TAB_ID);
+
if (chatter->current_tab->query_nick[0] ||
chatter->current_tab->channel)
EnableItem(view_menu, VIEW_MENU_CLOSE_ID);
@@ -1021,12 +1054,30 @@ void
chatter_key_down(struct focusable *focusable, EventRecord *event)
{
struct chatter *chatter = (struct chatter *)(focusable->cookie);
- struct chatter_tab *tab = chatter->current_tab;
+ struct chatter_tab *tab = chatter->current_tab, *ttab;
TERec *te;
+ short n;
char k;
k = (event->message & charCodeMask);
+ if ((event->modifiers & cmdKey) != 0) {
+ /* cmd+number focuses that tab */
+ if (k >= '1' && k <= '9') {
+ n = 0;
+ SLIST_FOREACH(ttab, &chatter->tabs_list, list) {
+ if (n == (k - '1')) {
+ chatter_use_shadow(chatter);
+ chatter_focus_tab(chatter, ttab);
+ chatter_reveal_shadow(chatter);
+ break;
+ }
+ n++;
+ }
+ }
+ return;
+ }
+
if (k == '\t') {
chatter_tab_complete(chatter);
return;
@@ -1357,13 +1408,13 @@ chatter_close_tab(struct chatter *chatter, struct chat
if (channel)
irc_part_channel(conn, channel);
- if (next_tab == NULL)
+ if (next_tab == NULL) {
chatter_draw_tab_bar(chatter);
- else
+ chatter_update_menu(chatter->focusable);
+ } else
chatter_focus_tab(chatter, next_tab);
chatter_reveal_shadow(chatter);
- chatter_update_menu(chatter->focusable);
}
void
--- chatter.h Tue Sep 17 16:06:44 2024
+++ chatter.h Wed Sep 18 09:46:30 2024
@@ -48,8 +48,10 @@
#define EDIT_MENU_PASTE_ID 3
#define VIEW_MENU_ID 131
-#define VIEW_MENU_CLOSE_ID 1
-#define VIEW_MENU_IGNORE_ID 2
+#define VIEW_MENU_PREV_TAB_ID 1
+#define VIEW_MENU_NEXT_TAB_ID 2
+#define VIEW_MENU_CLOSE_ID 3
+#define VIEW_MENU_IGNORE_ID 4
#define IGNORE_MENU_ID 132
#define IGNORE_MENU_JOINS_ID 1
--- README Tue Sep 17 16:03:49 2024
+++ README Wed Sep 18 09:44:12 2024
@@ -18,6 +18,9 @@ See http://jcs.org/wallops for more information and ve
- Supports selective ignoring of certain channel events such as joins,
parts/quits, and nick changes.
- Supports tab completion of nicks at the beginning of messages to a channel
+- Command+Number switches to that number tab in the current window, and
+ Command+, and Command+. switch to the previous and next tabs,
+ respectively.
- Implements the following commands, though any unsupported commands
can be sent to the server with "/quote <raw command>":
--- wallops.π.r Thu Sep 12 21:48:58 2024
+++ wallops.π.r Wed Sep 18 10:00:04 2024
@@ -19,8 +19,10 @@ data 'MENU' (130) {
data 'MENU' (131) {
$"0083 0000 0000 0000 0000 FFFF FFFF 0456" /* .É.............V */
- $"6965 7709 436C 6F73 6520 5461 6200 5700" /* iew∆Close Tab.W. */
- $"0006 4967 6E6F 7265 001B 8400 00" /* ..Ignore..Ñ.. */
+ $"6965 770C 5072 6576 696F 7573 2054 6162" /* iew.Previous Tab */
+ $"002C 0000 084E 6578 7420 5461 6200 2E00" /* .,...Next Tab... */
+ $"0009 436C 6F73 6520 5461 6200 5700 0006" /* .∆Close Tab.W... */
+ $"4967 6E6F 7265 001B 8400 00" /* Ignore..Ñ.. */
};
data 'MENU' (132) {
@@ -94,10 +96,10 @@ data 'DLOG' (130, "ABOUT") {
};
data 'vers' (1) {
- $"0200 8000 0000 0332 2E30 2B32 2E30 20A9" /* ..Ä....2.0+2.0 © */
- $"2032 3032 322D 3230 3234 2C20 6A6F 7368" /* 2022-2024, josh */
- $"7561 2073 7465 696E 203C 6A63 7340 6A63" /* ua stein <jcs@jc */
- $"732E 6F72 673E" /* s.org> */
+ $"0210 6000 0000 0432 2E31 622C 322E 3162" /* ..`....2.1b,2.1b */
+ $"20A9 2032 3032 322D 3230 3234 2C20 6A6F" /* © 2022-2024, jo */
+ $"7368 7561 2073 7465 696E 203C 6A63 7340" /* shua stein <jcs@ */
+ $"6A63 732E 6F72 673E" /* jcs.org> */
};
data 'ICN#' (128) {