diff --git a/TODO b/TODO index 60121c3c..b290aefa 100644 --- a/TODO +++ b/TODO @@ -99,4 +99,8 @@ - option to show bells visually - window-status command to show current window info in status line - H/M/L commands in copy mode with vi-keys, for jumping to the top/middle/last line on the screen +- if the server is started with IDENTIFY_UTF8 then set the global utf8 option? +- I think there are potential leaks in the prompt code if a new prompt is created without the + callback for the old being cleared; this might be quite hard to hit, lock-server seems the only + candidate - tidy up and prioritise todo list ;-) diff --git a/cmd-down-pane.c b/cmd-down-pane.c index 8a48c38a..71b19bbe 100644 --- a/cmd-down-pane.c +++ b/cmd-down-pane.c @@ -1,4 +1,4 @@ -/* $Id: cmd-down-pane.c,v 1.8 2009-07-14 06:43:32 nicm Exp $ */ +/* $Id: cmd-down-pane.c,v 1.9 2009-07-15 17:42:43 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -55,7 +55,7 @@ cmd_down_pane_exec(struct cmd *self, struct cmd_ctx *ctx) if (w->active == NULL) w->active = TAILQ_FIRST(&w->panes); layout_refresh(w, 1); - } while (w->active->flags & PANE_HIDDEN); + } while (!window_pane_visible(w->active)); return (0); } diff --git a/cmd-rotate-window.c b/cmd-rotate-window.c index 6718db93..008fcc73 100644 --- a/cmd-rotate-window.c +++ b/cmd-rotate-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-rotate-window.c,v 1.5 2009-07-14 06:43:32 nicm Exp $ */ +/* $Id: cmd-rotate-window.c,v 1.6 2009-07-15 17:42:43 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -60,7 +60,6 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx) struct window *w; struct window_pane *wp, *wp2; u_int sx, sy, xoff, yoff; - int flags; if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return (-1); @@ -73,18 +72,13 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx) xoff = wp->xoff; yoff = wp->yoff; sx = wp->sx; sy = wp->sy; - flags = wp->flags; TAILQ_FOREACH(wp, &w->panes, entry) { if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL) break; wp->xoff = wp2->xoff; wp->yoff = wp2->yoff; - wp->flags &= ~PANE_HIDDEN; - wp->flags |= wp2->flags & PANE_HIDDEN; window_pane_resize(wp, wp2->sx, wp2->sy); } wp->xoff = xoff; wp->yoff = yoff; - wp->flags &= ~PANE_HIDDEN; - wp->flags |= flags & PANE_HIDDEN; window_pane_resize(wp, sx, sy); if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL) @@ -97,18 +91,13 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx) xoff = wp->xoff; yoff = wp->yoff; sx = wp->sx; sy = wp->sy; - flags = wp->flags; TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) { if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL) break; wp->xoff = wp2->xoff; wp->yoff = wp2->yoff; - wp->flags &= ~PANE_HIDDEN; - wp->flags |= wp2->flags & PANE_HIDDEN; window_pane_resize(wp, wp2->sx, wp2->sy); } wp->xoff = xoff; wp->yoff = yoff; - wp->flags &= ~PANE_HIDDEN; - wp->flags |= flags & PANE_HIDDEN; window_pane_resize(wp, sx, sy); if ((wp = TAILQ_NEXT(w->active, entry)) == NULL) diff --git a/cmd-select-pane.c b/cmd-select-pane.c index d77bac32..b185a5d5 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -1,4 +1,4 @@ -/* $Id: cmd-select-pane.c,v 1.5 2009-07-14 06:43:32 nicm Exp $ */ +/* $Id: cmd-select-pane.c,v 1.6 2009-07-15 17:42:43 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -58,8 +58,8 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx) } } - if (wp->flags & PANE_HIDDEN) { - ctx->error(ctx, "pane %d is hidden", data->pane); + if (!window_pane_visible(wp)) { + ctx->error(ctx, "pane %d is not visible", data->pane); return (-1); } window_set_active_pane(wl->window, wp); diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c index 05ab0a99..e3066ce7 100644 --- a/cmd-swap-pane.c +++ b/cmd-swap-pane.c @@ -1,4 +1,4 @@ -/* $Id: cmd-swap-pane.c,v 1.7 2009-07-14 06:43:33 nicm Exp $ */ +/* $Id: cmd-swap-pane.c,v 1.8 2009-07-15 17:42:43 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -158,7 +158,6 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx) struct window *w; struct window_pane *tmp_wp, *src_wp, *dst_wp; u_int xx, yy; - int flags; if (data == NULL) return (0); @@ -210,15 +209,10 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx) xx = src_wp->xoff; yy = src_wp->yoff; - flags = src_wp->flags; src_wp->xoff = dst_wp->xoff; src_wp->yoff = dst_wp->yoff; - src_wp->flags &= ~PANE_HIDDEN; - src_wp->flags |= dst_wp->flags & PANE_HIDDEN; dst_wp->xoff = xx; dst_wp->yoff = yy; - dst_wp->flags &= ~PANE_HIDDEN; - dst_wp->flags |= flags & PANE_HIDDEN; xx = src_wp->sx; yy = src_wp->sy; @@ -227,7 +221,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx) if (!data->flag_detached) { tmp_wp = dst_wp; - if (tmp_wp->flags & PANE_HIDDEN) + if (!window_pane_visible(tmp_wp)) tmp_wp = src_wp; window_set_active_pane(w, tmp_wp); layout_refresh(w, 0); diff --git a/cmd-up-pane.c b/cmd-up-pane.c index 5273f8ed..fb5828b6 100644 --- a/cmd-up-pane.c +++ b/cmd-up-pane.c @@ -1,4 +1,4 @@ -/* $Id: cmd-up-pane.c,v 1.8 2009-07-14 06:43:33 nicm Exp $ */ +/* $Id: cmd-up-pane.c,v 1.9 2009-07-15 17:42:43 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -55,7 +55,7 @@ cmd_up_pane_exec(struct cmd *self, struct cmd_ctx *ctx) if (w->active == NULL) w->active = TAILQ_LAST(&w->panes, window_panes); layout_refresh(w, 1); - } while (w->active->flags & PANE_HIDDEN); + } while (!window_pane_visible(w->active)); return (0); } diff --git a/layout-manual.c b/layout-manual.c index f08fd731..9798b8ca 100644 --- a/layout-manual.c +++ b/layout-manual.c @@ -1,4 +1,4 @@ -/* $Id: layout-manual.c,v 1.3 2009-05-18 21:29:11 nicm Exp $ */ +/* $Id: layout-manual.c,v 1.4 2009-07-15 17:42:44 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -26,7 +26,7 @@ void layout_manual_v_refresh(struct window *w, unused int active_only) { struct window_pane *wp; - u_int npanes, canfit, total; + u_int npanes, total, height; int left; if (active_only) @@ -35,34 +35,25 @@ layout_manual_v_refresh(struct window *w, unused int active_only) if (TAILQ_EMPTY(&w->panes)) return; - /* Clear hidden flags. */ - TAILQ_FOREACH(wp, &w->panes, entry) - wp->flags &= ~PANE_HIDDEN; - /* Check the new size. */ npanes = window_count_panes(w); if (w->sy <= PANE_MINIMUM * npanes) { - /* How many can we fit? */ - canfit = w->sy / PANE_MINIMUM; - if (canfit == 0) { - /* None. Just use this size for the first. */ - TAILQ_FOREACH(wp, &w->panes, entry) { - if (wp == TAILQ_FIRST(&w->panes)) - wp->sy = w->sy; - else - wp->flags |= PANE_HIDDEN; - } - } else { - /* >=1, set minimum for them all. */ - TAILQ_FOREACH(wp, &w->panes, entry) { - if (canfit-- > 0) - wp->sy = PANE_MINIMUM - 1; - else - wp->flags |= PANE_HIDDEN; - } - /* And increase the first by the rest. */ - TAILQ_FIRST(&w->panes)->sy += 1 + w->sy % PANE_MINIMUM; + /* + * Make the first pane the smaller of the minimum and total (it + * must fit to be visible) and the rest the minimum size. + */ + height = PANE_MINIMUM; + if (height > w->sy) + height = w->sy + 1; + TAILQ_FOREACH(wp, &w->panes, entry) { + if (wp == TAILQ_FIRST(&w->panes)) + wp->sy = height - 1; + else + wp->sy = PANE_MINIMUM - 1; } + /* And increase the first by the rest if possible. */ + if (w->sy >= PANE_MINIMUM) + TAILQ_FIRST(&w->panes)->sy += 1 + w->sy % PANE_MINIMUM; } else { /* In theory they will all fit. Find the current total. */ total = 0; @@ -174,8 +165,6 @@ layout_manual_v_update_offsets(struct window *w) yoff = 0; TAILQ_FOREACH(wp, &w->panes, entry) { - if (wp->flags & PANE_HIDDEN) - continue; wp->xoff = 0; wp->yoff = yoff; yoff += wp->sy + 1; diff --git a/layout.c b/layout.c index 7d6e3994..7cc588d7 100644 --- a/layout.c +++ b/layout.c @@ -1,4 +1,4 @@ -/* $Id: layout.c,v 1.14 2009-05-18 22:17:24 nicm Exp $ */ +/* $Id: layout.c,v 1.15 2009-07-15 17:42:44 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -125,14 +125,19 @@ void layout_active_only_refresh(struct window *w, unused int active_only) { struct window_pane *wp; + u_int xoff; + xoff = w->sx; TAILQ_FOREACH(wp, &w->panes, entry) { - if (wp == w->active) { - wp->flags &= ~PANE_HIDDEN; - wp->xoff = wp->yoff = 0; - window_pane_resize(wp, w->sx, w->sy); - } else - wp->flags |= PANE_HIDDEN; + /* Put the active pane on screen and the rest to the right. */ + if (wp == w->active) + wp->xoff = 0; + else { + wp->xoff = xoff; + xoff += w->sx; + } + wp->yoff = 0; + window_pane_resize(wp, w->sx, w->sy); } } @@ -145,6 +150,12 @@ layout_even_h_refresh(struct window *w, int active_only) if (active_only) return; + /* If the screen is too small, show active only. */ + if (w->sx < PANE_MINIMUM || w->sy < PANE_MINIMUM) { + layout_active_only_refresh(w, active_only); + return; + } + /* Get number of panes. */ n = window_count_panes(w); if (n == 0) @@ -153,19 +164,13 @@ layout_even_h_refresh(struct window *w, int active_only) /* How many can we fit? */ if (w->sx / n < PANE_MINIMUM) { width = PANE_MINIMUM; - n = w->sx / PANE_MINIMUM; + n = UINT_MAX; } else width = w->sx / n; /* Fit the panes. */ i = xoff = 0; TAILQ_FOREACH(wp, &w->panes, entry) { - if (i > n) { - wp->flags |= PANE_HIDDEN; - continue; - } - wp->flags &= ~PANE_HIDDEN; - wp->xoff = xoff; wp->yoff = 0; if (i != n - 1) @@ -193,6 +198,12 @@ layout_even_v_refresh(struct window *w, int active_only) if (active_only) return; + /* If the screen is too small, show active only. */ + if (w->sx < PANE_MINIMUM || w->sy < PANE_MINIMUM) { + layout_active_only_refresh(w, active_only); + return; + } + /* Get number of panes. */ n = window_count_panes(w); if (n == 0) @@ -201,19 +212,13 @@ layout_even_v_refresh(struct window *w, int active_only) /* How many can we fit? */ if (w->sy / n < PANE_MINIMUM) { height = PANE_MINIMUM; - n = w->sy / PANE_MINIMUM; + n = UINT_MAX; } else height = w->sy / n; /* Fit the panes. */ i = yoff = 0; TAILQ_FOREACH(wp, &w->panes, entry) { - if (i > n) { - wp->flags |= PANE_HIDDEN; - continue; - } - wp->flags &= ~PANE_HIDDEN; - wp->xoff = 0; wp->yoff = yoff; if (i != n - 1) @@ -250,7 +255,8 @@ layout_main_v_refresh(struct window *w, int active_only) mainwidth = options_get_number(&w->options, "main-pane-width") + 1; /* Need >1 pane and minimum columns; if fewer, display active only. */ - if (n == 1 || w->sx < mainwidth + PANE_MINIMUM) { + if (n == 1 || + w->sx < mainwidth + PANE_MINIMUM || w->sy < PANE_MINIMUM) { layout_active_only_refresh(w, active_only); return; } @@ -270,16 +276,9 @@ layout_main_v_refresh(struct window *w, int active_only) wp->xoff = 0; wp->yoff = 0; window_pane_resize(wp, mainwidth - 1, w->sy); - wp->flags &= ~PANE_HIDDEN; continue; } - if (i > n) { - wp->flags |= PANE_HIDDEN; - continue; - } - wp->flags &= ~PANE_HIDDEN; - wp->xoff = mainwidth; wp->yoff = yoff; if (i != n - 1) @@ -320,7 +319,8 @@ layout_main_h_refresh(struct window *w, int active_only) mainheight = options_get_number(&w->options, "main-pane-height") + 1; /* Need >1 pane and minimum rows; if fewer, display active only. */ - if (n == 1 || w->sy < mainheight + PANE_MINIMUM) { + if (n == 1 || + w->sy < mainheight + PANE_MINIMUM || w->sx < PANE_MINIMUM) { layout_active_only_refresh(w, active_only); return; } @@ -340,16 +340,9 @@ layout_main_h_refresh(struct window *w, int active_only) wp->xoff = 0; wp->yoff = 0; window_pane_resize(wp, w->sx, mainheight - 1); - wp->flags &= ~PANE_HIDDEN; continue; } - if (i > n) { - wp->flags |= PANE_HIDDEN; - continue; - } - wp->flags &= ~PANE_HIDDEN; - wp->xoff = xoff; wp->yoff = mainheight; if (i != n - 1) diff --git a/resize.c b/resize.c index e6c73222..b8f7b0d3 100644 --- a/resize.c +++ b/resize.c @@ -1,4 +1,4 @@ -/* $Id: resize.c,v 1.21 2009-04-01 21:10:08 nicm Exp $ */ +/* $Id: resize.c,v 1.22 2009-07-15 17:42:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -48,6 +48,7 @@ recalculate_sizes(void) struct session *s; struct client *c; struct window *w; + struct window_pane *wp; u_int i, j, ssx, ssy, has, limit; int flag; @@ -132,6 +133,20 @@ recalculate_sizes(void) "window size %u,%u (was %u,%u)", ssx, ssy, w->sx, w->sy); window_resize(w, ssx, ssy); + + /* + * If the current pane is now not visible, move to the next + * that is. + */ + wp = w->active; + while (!window_pane_visible(w->active)) { + w->active = TAILQ_PREV(w->active, window_panes, entry); + if (w->active == NULL) + w->active = TAILQ_LAST(&w->panes, window_panes); + if (w->active == wp) + break; + } + server_redraw_window(w); layout_refresh(w, 0); } diff --git a/screen-redraw.c b/screen-redraw.c index a2ca1dcd..79f3e9c4 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -1,4 +1,4 @@ -/* $Id: screen-redraw.c,v 1.38 2009-06-25 16:21:32 nicm Exp $ */ +/* $Id: screen-redraw.c,v 1.39 2009-07-15 17:42:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -35,6 +35,9 @@ screen_redraw_check_cell(struct client *c, u_int px, u_int py) return (0); TAILQ_FOREACH(wp, &w->panes, entry) { + if (!window_pane_visible(wp)) + continue; + /* Inside pane. */ if (px >= wp->xoff && px < wp->xoff + wp->sx && py >= wp->yoff && py < wp->yoff + wp->sy) @@ -104,7 +107,7 @@ screen_redraw_screen(struct client *c) /* Draw the panes. */ TAILQ_FOREACH(wp, &w->panes, entry) { - if (wp->flags & PANE_HIDDEN) + if (!window_pane_visible(wp)) continue; tty_reset(tty); diff --git a/tmux.h b/tmux.h index 70791a42..94a41614 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.361 2009-07-14 06:43:33 nicm Exp $ */ +/* $Id: tmux.h,v 1.362 2009-07-15 17:42:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -47,7 +47,7 @@ extern const char *__progname; #define PROMPT_HISTORY 100 /* Minimum pane size. */ -#define PANE_MINIMUM 4 /* includes separator line */ +#define PANE_MINIMUM 5 /* includes separator line */ /* Automatic name refresh interval, in milliseconds. */ #define NAME_INTERVAL 500 @@ -599,8 +599,7 @@ struct window_pane { u_int yoff; int flags; -#define PANE_HIDDEN 0x1 -#define PANE_REDRAW 0x2 +#define PANE_REDRAW 0x1 char *cmd; char *cwd; @@ -1453,6 +1452,7 @@ void window_pane_parse(struct window_pane *); void window_pane_key(struct window_pane *, struct client *, int); void window_pane_mouse(struct window_pane *, struct client *, u_char, u_char, u_char); +int window_pane_visible(struct window_pane *); char *window_pane_search( struct window_pane *, const char *, u_int *); diff --git a/tty-write.c b/tty-write.c index 14c0ec3d..5f13bbda 100644 --- a/tty-write.c +++ b/tty-write.c @@ -1,4 +1,4 @@ -/* $Id: tty-write.c,v 1.18 2009-06-25 16:47:00 nicm Exp $ */ +/* $Id: tty-write.c,v 1.19 2009-07-15 17:42:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -44,7 +44,7 @@ tty_vwrite_cmd(struct window_pane *wp, enum tty_cmd cmd, va_list ap) if (wp->window->flags & WINDOW_REDRAW || wp->flags & PANE_REDRAW) return; - if (wp->window->flags & WINDOW_HIDDEN || wp->flags & PANE_HIDDEN) + if (wp->window->flags & WINDOW_HIDDEN || !window_pane_visible(wp)) return; for (i = 0; i < ARRAY_LENGTH(&clients); i++) { diff --git a/window.c b/window.c index 6473120d..4e3eccbf 100644 --- a/window.c +++ b/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.90 2009-07-14 06:40:33 nicm Exp $ */ +/* $Id: window.c,v 1.91 2009-07-15 17:42:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -289,8 +289,14 @@ void window_set_active_pane(struct window *w, struct window_pane *wp) { w->active = wp; - while (w->active->flags & PANE_HIDDEN) + + while (!window_pane_visible(w->active)) { w->active = TAILQ_PREV(w->active, window_panes, entry); + if (w->active == NULL) + w->active = TAILQ_LAST(&w->panes, window_panes); + if (w->active == wp) + return; + } } struct window_pane * @@ -605,6 +611,18 @@ window_pane_mouse( input_mouse(wp, b, x, y); } +int +window_pane_visible(struct window_pane *wp) +{ + struct window *w = wp->window; + + if (wp->xoff >= w->sx || wp->yoff >= w->sy) + return (0); + if (wp->xoff + wp->sx > w->sx || wp->yoff + wp->sy > w->sy) + return (0); + return (1); +} + char * window_pane_search(struct window_pane *wp, const char *searchstr, u_int *lineno) {