From ddf929390e2780f8e53536a7c0b2f974a3ce2721 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 19 Aug 2013 22:31:38 +0100 Subject: [PATCH 1/5] Accept multiple parameters to SM/RM/DECSET/DECRST, based on a diff from Hayaki Saito. --- input.c | 151 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 99 insertions(+), 52 deletions(-) diff --git a/input.c b/input.c index 30d3bb98..259fad16 100644 --- a/input.c +++ b/input.c @@ -70,6 +70,10 @@ int input_input(struct input_ctx *); int input_c0_dispatch(struct input_ctx *); int input_esc_dispatch(struct input_ctx *); int input_csi_dispatch(struct input_ctx *); +void input_csi_dispatch_rm(struct input_ctx *); +void input_csi_dispatch_rm_private(struct input_ctx *); +void input_csi_dispatch_sm(struct input_ctx *); +void input_csi_dispatch_sm_private(struct input_ctx *); void input_csi_dispatch_sgr(struct input_ctx *); int input_dcs_dispatch(struct input_ctx *); int input_utf8_open(struct input_ctx *); @@ -1071,7 +1075,6 @@ int input_csi_dispatch(struct input_ctx *ictx) { struct screen_write_ctx *sctx = &ictx->ctx; - struct window_pane *wp = ictx->wp; struct screen *s = sctx->s; struct input_table_entry *entry; int n, m; @@ -1230,7 +1233,60 @@ input_csi_dispatch(struct input_ctx *ictx) screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy); break; case INPUT_CSI_RM: - switch (input_get(ictx, 0, 0, -1)) { + input_csi_dispatch_rm(ictx); + break; + case INPUT_CSI_RM_PRIVATE: + input_csi_dispatch_rm_private(ictx); + break; + case INPUT_CSI_SCP: + memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); + ictx->old_cx = s->cx; + ictx->old_cy = s->cy; + break; + case INPUT_CSI_SGR: + input_csi_dispatch_sgr(ictx); + break; + case INPUT_CSI_SM: + input_csi_dispatch_sm(ictx); + break; + case INPUT_CSI_SM_PRIVATE: + input_csi_dispatch_sm_private(ictx); + break; + case INPUT_CSI_TBC: + switch (input_get(ictx, 0, 0, 0)) { + case 0: + if (s->cx < screen_size_x(s)) + bit_clear(s->tabs, s->cx); + break; + case 3: + bit_nclear(s->tabs, 0, screen_size_x(s) - 1); + break; + default: + log_debug("%s: unknown '%c'", __func__, ictx->ch); + break; + } + break; + case INPUT_CSI_VPA: + n = input_get(ictx, 0, 1, 1); + screen_write_cursormove(sctx, s->cx, n - 1); + break; + case INPUT_CSI_DECSCUSR: + n = input_get(ictx, 0, 0, 0); + screen_set_cursor_style(s, n); + break; + } + + return (0); +} + +/* Handle CSI RM. */ +void +input_csi_dispatch_rm(struct input_ctx *ictx) +{ + u_int i; + + for (i = 0; i < ictx->param_list_len; i++) { + switch (input_get(ictx, i, 0, -1)) { case 4: /* IRM */ screen_write_mode_clear(&ictx->ctx, MODE_INSERT); break; @@ -1238,10 +1294,18 @@ input_csi_dispatch(struct input_ctx *ictx) log_debug("%s: unknown '%c'", __func__, ictx->ch); break; } - break; - case INPUT_CSI_RM_PRIVATE: - switch (input_get(ictx, 0, 0, -1)) { - case 1: /* GATM */ + } +} + +/* Handle CSI private RM. */ +void +input_csi_dispatch_rm_private(struct input_ctx *ictx) +{ + u_int i; + + for (i = 0; i < ictx->param_list_len; i++) { + switch (input_get(ictx, i, 0, -1)) { + case 1: /* DECCKM */ screen_write_mode_clear(&ictx->ctx, MODE_KCURSOR); break; case 3: /* DECCOLM */ @@ -1271,10 +1335,10 @@ input_csi_dispatch(struct input_ctx *ictx) break; case 47: case 1047: - window_pane_alternate_off(wp, &ictx->cell, 0); + window_pane_alternate_off(ictx->wp, &ictx->cell, 0); break; case 1049: - window_pane_alternate_off(wp, &ictx->cell, 1); + window_pane_alternate_off(ictx->wp, &ictx->cell, 1); break; case 2004: screen_write_mode_clear(&ictx->ctx, MODE_BRACKETPASTE); @@ -1283,17 +1347,17 @@ input_csi_dispatch(struct input_ctx *ictx) log_debug("%s: unknown '%c'", __func__, ictx->ch); break; } - break; - case INPUT_CSI_SCP: - memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); - ictx->old_cx = s->cx; - ictx->old_cy = s->cy; - break; - case INPUT_CSI_SGR: - input_csi_dispatch_sgr(ictx); - break; - case INPUT_CSI_SM: - switch (input_get(ictx, 0, 0, -1)) { + } +} + +/* Handle CSI SM. */ +void +input_csi_dispatch_sm(struct input_ctx *ictx) +{ + u_int i; + + for (i = 0; i < ictx->param_list_len; i++) { + switch (input_get(ictx, i, 0, -1)) { case 4: /* IRM */ screen_write_mode_set(&ictx->ctx, MODE_INSERT); break; @@ -1301,10 +1365,18 @@ input_csi_dispatch(struct input_ctx *ictx) log_debug("%s: unknown '%c'", __func__, ictx->ch); break; } - break; - case INPUT_CSI_SM_PRIVATE: - switch (input_get(ictx, 0, 0, -1)) { - case 1: /* GATM */ + } +} + +/* Handle CSI private SM. */ +void +input_csi_dispatch_sm_private(struct input_ctx *ictx) +{ + u_int i; + + for (i = 0; i < ictx->param_list_len; i++) { + switch (input_get(ictx, i, 0, -1)) { + case 1: /* DECCKM */ screen_write_mode_set(&ictx->ctx, MODE_KCURSOR); break; case 3: /* DECCOLM */ @@ -1330,10 +1402,10 @@ input_csi_dispatch(struct input_ctx *ictx) screen_write_mode_set(&ictx->ctx, MODE_MOUSE_ANY); break; case 1004: - if (s->mode & MODE_FOCUSON) + if (ictx->ctx.s->mode & MODE_FOCUSON) break; screen_write_mode_set(&ictx->ctx, MODE_FOCUSON); - wp->flags |= PANE_FOCUSPUSH; /* force update */ + ictx->wp->flags |= PANE_FOCUSPUSH; /* force update */ break; case 1005: screen_write_mode_set(&ictx->ctx, MODE_MOUSE_UTF8); @@ -1343,10 +1415,10 @@ input_csi_dispatch(struct input_ctx *ictx) break; case 47: case 1047: - window_pane_alternate_on(wp, &ictx->cell, 0); + window_pane_alternate_on(ictx->wp, &ictx->cell, 0); break; case 1049: - window_pane_alternate_on(wp, &ictx->cell, 1); + window_pane_alternate_on(ictx->wp, &ictx->cell, 1); break; case 2004: screen_write_mode_set(&ictx->ctx, MODE_BRACKETPASTE); @@ -1355,32 +1427,7 @@ input_csi_dispatch(struct input_ctx *ictx) log_debug("%s: unknown '%c'", __func__, ictx->ch); break; } - break; - case INPUT_CSI_TBC: - switch (input_get(ictx, 0, 0, 0)) { - case 0: - if (s->cx < screen_size_x(s)) - bit_clear(s->tabs, s->cx); - break; - case 3: - bit_nclear(s->tabs, 0, screen_size_x(s) - 1); - break; - default: - log_debug("%s: unknown '%c'", __func__, ictx->ch); - break; - } - break; - case INPUT_CSI_VPA: - n = input_get(ictx, 0, 1, 1); - screen_write_cursormove(sctx, s->cx, n - 1); - break; - case INPUT_CSI_DECSCUSR: - n = input_get(ictx, 0, 0, 0); - screen_set_cursor_style(s, n); - break; } - - return (0); } /* Handle CSI SGR. */ From 5dbf3cb036d8093599494b8c02407e8d2d079f0d Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 16 Aug 2013 11:58:32 +0100 Subject: [PATCH 2/5] Assign mouse x/y coords before checking them When receiving mouse inputs, we should set the x/y coordinates earlier than we currently do, so that we aren't off-by-one in the case when the statusbar is at the top of the screen. --- tty-keys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tty-keys.c b/tty-keys.c index d1c9d875..595ad6e1 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -746,6 +746,8 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size) m->sgr = sgr; m->sgr_xb = sgr_b; m->sgr_rel = sgr_rel; + m->x = x; + m->y = y; if (b & 64) { /* wheel button */ b &= 3; if (b == 0) @@ -773,8 +775,6 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size) } m->button = (b & 3); } - m->x = x; - m->y = y; return (0); } From 5532766b1935a8888fb60fb9a238f0849b96050b Mon Sep 17 00:00:00 2001 From: Thomas Adam Date: Tue, 13 Aug 2013 21:56:41 +0100 Subject: [PATCH 3/5] Renumber windows: Lookup lastw via window not index When calling 'movew -r' on a session to reorder the winlinks, ensure when adding back in the information for the lastw stack that we look up the winlink based on the window and not its index. Using the index doesn't make sense here because when comparing it to the old set, it will never match since the winlink has been renumbered. Bug reported by Ben Boeckel. --- session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/session.c b/session.c index 24e2e5e7..bb742d8f 100644 --- a/session.c +++ b/session.c @@ -615,7 +615,7 @@ session_renumber_windows(struct session *s) memcpy(&old_lastw, &s->lastw, sizeof old_lastw); TAILQ_INIT(&s->lastw); TAILQ_FOREACH(wl, &old_lastw, sentry) { - wl_new = winlink_find_by_index(&s->windows, wl->idx); + wl_new = winlink_find_by_window(&s->windows, wl->window); if (wl_new != NULL) TAILQ_INSERT_TAIL(&s->lastw, wl_new, sentry); } From aa4920fea3dcdcaa0dbe4d373160195b1a3ca892 Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 9 Aug 2013 10:37:46 +0100 Subject: [PATCH 4/5] choose-tree: Reset top when toggling items When choose-tree is told to expand/collapse items (especially when first rendering collapsed to just show sessions), ensure that in addition to setting the selected item, that the item itself appears on the bottom of the screen, rather than off screen. This was causing rendering glitches when a very small tmux window tried to render a list of items in choose-tree much larger than itself, and the selected item appeared off screen, and didn't show the selection until the selection had wrapped around to the top of the screen. --- cmd-choose-tree.c | 1 - window-choose.c | 25 +++++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c index a9b6ffbc..2fe6e171 100644 --- a/cmd-choose-tree.c +++ b/cmd-choose-tree.c @@ -228,7 +228,6 @@ windows_only: free(final_win_template_last); window_choose_ready(wl->window->active, cur_win, NULL); - window_choose_collapse_all(wl->window->active); if (args_has(args, 'u')) { window_choose_expand_all(wl->window->active); diff --git a/window-choose.c b/window-choose.c index 5ed85f0e..572581a5 100644 --- a/window-choose.c +++ b/window-choose.c @@ -81,6 +81,7 @@ int window_choose_key_index(struct window_choose_mode_data *, u_int); int window_choose_index_key(struct window_choose_mode_data *, int); void window_choose_prompt_input(enum window_choose_input_type, const char *, struct window_pane *, int); +void window_choose_reset_top(struct window_pane *, u_int); void window_choose_add(struct window_pane *wp, struct window_choose_data *wcd) @@ -107,8 +108,17 @@ window_choose_set_current(struct window_pane *wp, u_int cur) struct screen *s = &data->screen; data->selected = cur; - if (data->selected > screen_size_y(s) - 1) - data->top = ARRAY_LENGTH(&data->list) - screen_size_y(s); + window_choose_reset_top(wp, screen_size_y(s)); +} + +void +window_choose_reset_top(struct window_pane *wp, u_int sy) +{ + struct window_choose_mode_data *data = wp->modedata; + + data->top = 0; + if (data->selected > sy - 1) + data->top = data->selected - (sy - 1); window_choose_redraw_screen(wp); } @@ -277,10 +287,7 @@ window_choose_resize(struct window_pane *wp, u_int sx, u_int sy) struct window_choose_mode_data *data = wp->modedata; struct screen *s = &data->screen; - data->top = 0; - if (data->selected > sy - 1) - data->top = data->selected - (sy - 1); - + window_choose_reset_top(wp, sy); screen_resize(s, sx, sy, 0); window_choose_redraw_screen(wp); } @@ -373,6 +380,7 @@ window_choose_collapse_all(struct window_pane *wp) { struct window_choose_mode_data *data = wp->modedata; struct window_choose_mode_item *item; + struct screen *scr = &data->screen; struct session *s, *chosen; u_int i; @@ -391,7 +399,7 @@ window_choose_collapse_all(struct window_pane *wp) if (item->wcd->type & TREE_SESSION) data->selected = i; } - window_choose_redraw_screen(wp); + window_choose_reset_top(wp, screen_size_y(scr)); } void @@ -399,6 +407,7 @@ window_choose_expand_all(struct window_pane *wp) { struct window_choose_mode_data *data = wp->modedata; struct window_choose_mode_item *item; + struct screen *scr = &data->screen; struct session *s; u_int i; @@ -414,7 +423,7 @@ window_choose_expand_all(struct window_pane *wp) } } - window_choose_redraw_screen(wp); + window_choose_reset_top(wp, screen_size_y(scr)); } void From c103f2fbcbeb82019b694bed6869942bc1cbe966 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 20 Aug 2013 10:37:55 +0100 Subject: [PATCH 5/5] Clear window->flags when clearing winlinks When clearing WINLINK_ALERTFLAGS for all sessions, we must also, for that window, clear the window->flags as well, otherwise sessions may well still see flags for winlinks long since cleared. This therfore introduces WINDOW_ALERTFLAGS to help with this. --- tmux.h | 1 + window.c | 1 + 2 files changed, 2 insertions(+) diff --git a/tmux.h b/tmux.h index 6ab9861b..0a17f72b 100644 --- a/tmux.h +++ b/tmux.h @@ -1005,6 +1005,7 @@ struct window { #define WINDOW_REDRAW 0x4 #define WINDOW_SILENCE 0x8 #define WINDOW_ZOOMED 0x10 +#define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE) struct options options; diff --git a/window.c b/window.c index 7678adc6..7912bd37 100644 --- a/window.c +++ b/window.c @@ -1243,6 +1243,7 @@ winlink_clear_flags(struct winlink *wl) continue; wm->flags &= ~WINLINK_ALERTFLAGS; + wm->window->flags &= ~WINDOW_ALERTFLAGS; server_status_session(s); } }