mirror of
https://github.com/tmux/tmux.git
synced 2026-01-09 22:30:19 +00:00
Add support to minimise panes, both tiled and floating. New PREFIX _ key binding to minimise a pane. New functions minimise-pane and unminimise-pane. Add double-click on pane in status to minimise pane. Single click on pane in status unminimises pane.
This commit is contained in:
@@ -106,6 +106,7 @@ dist_tmux_SOURCES = \
|
||||
cmd-list-windows.c \
|
||||
cmd-load-buffer.c \
|
||||
cmd-lock-server.c \
|
||||
cmd-minimise-pane.c \
|
||||
cmd-move-window.c \
|
||||
cmd-new-pane.c \
|
||||
cmd-new-session.c \
|
||||
|
||||
@@ -977,15 +977,20 @@ cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item,
|
||||
} else if (cmd_find_from_client(¤t, cmdq_get_client(item),
|
||||
flags) == 0) {
|
||||
fs->current = ¤t;
|
||||
/* No active pane, window empty, return the window instead. */
|
||||
if (current.wp == NULL) {
|
||||
type = CMD_FIND_WINDOW;
|
||||
}
|
||||
log_debug("%s: current is from client", __func__);
|
||||
} else {
|
||||
if (~flags & CMD_FIND_QUIET)
|
||||
cmdq_error(item, "no current target");
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
if (!cmd_find_valid_state(fs->current))
|
||||
fatalx("invalid current find state");
|
||||
|
||||
*/
|
||||
/* An empty or NULL target is the current. */
|
||||
if (target == NULL || *target == '\0')
|
||||
goto current;
|
||||
@@ -1010,7 +1015,7 @@ cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item,
|
||||
fs->w = fs->wl->window;
|
||||
fs->wp = fs->w->active;
|
||||
}
|
||||
break;
|
||||
goto found;
|
||||
}
|
||||
if (fs->wp == NULL) {
|
||||
if (~flags & CMD_FIND_QUIET)
|
||||
|
||||
@@ -62,6 +62,11 @@ cmd_kill_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if (wp == NULL) {
|
||||
/* No active window pane. */
|
||||
cmdq_error(item, "No active pane to kill.");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
server_kill_pane(wp);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
8
cmd.c
8
cmd.c
@@ -69,8 +69,10 @@ extern const struct cmd_entry cmd_load_buffer_entry;
|
||||
extern const struct cmd_entry cmd_lock_client_entry;
|
||||
extern const struct cmd_entry cmd_lock_server_entry;
|
||||
extern const struct cmd_entry cmd_lock_session_entry;
|
||||
extern const struct cmd_entry cmd_minimise_pane_entry;
|
||||
extern const struct cmd_entry cmd_move_pane_entry;
|
||||
extern const struct cmd_entry cmd_move_window_entry;
|
||||
extern const struct cmd_entry cmd_new_pane_entry;
|
||||
extern const struct cmd_entry cmd_new_session_entry;
|
||||
extern const struct cmd_entry cmd_new_window_entry;
|
||||
extern const struct cmd_entry cmd_next_layout_entry;
|
||||
@@ -109,7 +111,6 @@ extern const struct cmd_entry cmd_show_prompt_history_entry;
|
||||
extern const struct cmd_entry cmd_show_window_options_entry;
|
||||
extern const struct cmd_entry cmd_source_file_entry;
|
||||
extern const struct cmd_entry cmd_split_window_entry;
|
||||
extern const struct cmd_entry cmd_new_pane_entry;
|
||||
extern const struct cmd_entry cmd_start_server_entry;
|
||||
extern const struct cmd_entry cmd_suspend_client_entry;
|
||||
extern const struct cmd_entry cmd_swap_pane_entry;
|
||||
@@ -117,6 +118,7 @@ extern const struct cmd_entry cmd_swap_window_entry;
|
||||
extern const struct cmd_entry cmd_switch_client_entry;
|
||||
extern const struct cmd_entry cmd_unbind_key_entry;
|
||||
extern const struct cmd_entry cmd_unlink_window_entry;
|
||||
extern const struct cmd_entry cmd_unminimise_pane_entry;
|
||||
extern const struct cmd_entry cmd_wait_for_entry;
|
||||
|
||||
const struct cmd_entry *cmd_table[] = {
|
||||
@@ -162,8 +164,10 @@ const struct cmd_entry *cmd_table[] = {
|
||||
&cmd_lock_client_entry,
|
||||
&cmd_lock_server_entry,
|
||||
&cmd_lock_session_entry,
|
||||
&cmd_minimise_pane_entry,
|
||||
&cmd_move_pane_entry,
|
||||
&cmd_move_window_entry,
|
||||
&cmd_new_pane_entry,
|
||||
&cmd_new_session_entry,
|
||||
&cmd_new_window_entry,
|
||||
&cmd_next_layout_entry,
|
||||
@@ -202,7 +206,6 @@ const struct cmd_entry *cmd_table[] = {
|
||||
&cmd_show_window_options_entry,
|
||||
&cmd_source_file_entry,
|
||||
&cmd_split_window_entry,
|
||||
&cmd_new_pane_entry,
|
||||
&cmd_start_server_entry,
|
||||
&cmd_suspend_client_entry,
|
||||
&cmd_swap_pane_entry,
|
||||
@@ -210,6 +213,7 @@ const struct cmd_entry *cmd_table[] = {
|
||||
&cmd_switch_client_entry,
|
||||
&cmd_unbind_key_entry,
|
||||
&cmd_unlink_window_entry,
|
||||
&cmd_unminimise_pane_entry,
|
||||
&cmd_wait_for_entry,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -347,6 +347,10 @@ key_bindings_init(void)
|
||||
{
|
||||
static const char *const defaults[] = {
|
||||
/* Prefix keys. */
|
||||
"bind -N 'Minimise pane' _ { minimise-pane }",
|
||||
/* Mouse button 1 double click on status line. */
|
||||
"bind -n DoubleClick1Status { minimise-pane -t= }",
|
||||
|
||||
"bind -N 'Send the prefix key' C-b { send-prefix }",
|
||||
"bind -N 'Rotate through the panes' C-o { rotate-window }",
|
||||
"bind -N 'Suspend the current client' C-z { suspend-client }",
|
||||
|
||||
72
layout.c
72
layout.c
@@ -254,6 +254,9 @@ layout_fix_offsets1(struct layout_cell *lc)
|
||||
if (lc->type == LAYOUT_LEFTRIGHT) {
|
||||
xoff = lc->xoff;
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||
if (lcchild->type == LAYOUT_WINDOWPANE &&
|
||||
lcchild->wp->flags & PANE_MINIMISED)
|
||||
continue;
|
||||
lcchild->xoff = xoff;
|
||||
lcchild->yoff = lc->yoff;
|
||||
if (lcchild->type != LAYOUT_WINDOWPANE)
|
||||
@@ -263,6 +266,8 @@ layout_fix_offsets1(struct layout_cell *lc)
|
||||
} else {
|
||||
yoff = lc->yoff;
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||
if (lcchild->wp->flags & PANE_MINIMISED)
|
||||
continue;
|
||||
lcchild->xoff = lc->xoff;
|
||||
lcchild->yoff = yoff;
|
||||
if (lcchild->type != LAYOUT_WINDOWPANE)
|
||||
@@ -526,8 +531,7 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
||||
if (lcparent == NULL) {
|
||||
if (lc->wp != NULL && ~lc->wp->flags & PANE_FLOATING)
|
||||
*lcroot = NULL;
|
||||
/* xxx if (lc->type == LAYOUT_WINDOWPANE) */
|
||||
layout_free_cell(lc);
|
||||
layout_free_cell(lc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -569,6 +573,70 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
||||
}
|
||||
}
|
||||
|
||||
/* Minimise a cell and redistribute the space in tiled cells. */
|
||||
void
|
||||
layout_minimise_cell(struct window *w, struct layout_cell *lc)
|
||||
{
|
||||
struct layout_cell *lcother, *lcparent, *lcchild;
|
||||
u_int space = 0;
|
||||
|
||||
lcparent = lc->parent;
|
||||
if (lcparent == NULL ||
|
||||
lcparent->type == LAYOUT_FLOATING) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Merge the space into the previous or next cell. */
|
||||
if (lc == TAILQ_FIRST(&lcparent->cells))
|
||||
lcother = TAILQ_NEXT(lc, entry);
|
||||
else
|
||||
lcother = TAILQ_PREV(lc, layout_cells, entry);
|
||||
if (lcother != NULL && lcparent->type == LAYOUT_LEFTRIGHT)
|
||||
layout_resize_adjust(w, lcother, lcparent->type, lc->sx + 1);
|
||||
else if (lcother != NULL)
|
||||
layout_resize_adjust(w, lcother, lcparent->type, lc->sy + 1);
|
||||
|
||||
/* If the parent cells are all minimised, minimise it too. */
|
||||
if (lcparent != NULL) {
|
||||
TAILQ_FOREACH(lcchild, &lcparent->cells, entry) {
|
||||
if (lcchild->wp == NULL ||
|
||||
lcchild->wp->flags & PANE_MINIMISED)
|
||||
continue;
|
||||
if (lcparent->type == LAYOUT_LEFTRIGHT) {
|
||||
space += lcchild->sx;
|
||||
} else if (lcparent->type == LAYOUT_TOPBOTTOM) {
|
||||
space += lcchild->sy;
|
||||
}
|
||||
}
|
||||
if (space == 0)
|
||||
layout_minimise_cell(w, lcparent);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unminimise a cell and redistribute the space in tiled cells. */
|
||||
void
|
||||
layout_unminimise_cell(struct window *w, struct layout_cell *lc)
|
||||
{
|
||||
struct layout_cell *lcother, *lcparent;
|
||||
|
||||
lcparent = lc->parent;
|
||||
if (lcparent == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* In tiled layouts, merge the space into the previous or next cell. */
|
||||
if (lcparent->type != LAYOUT_FLOATING) {
|
||||
if (lc == TAILQ_FIRST(&lcparent->cells))
|
||||
lcother = TAILQ_NEXT(lc, entry);
|
||||
else
|
||||
lcother = TAILQ_PREV(lc, layout_cells, entry);
|
||||
if (lcother != NULL && lcparent->type == LAYOUT_LEFTRIGHT)
|
||||
layout_resize_adjust(w, lcother, lcparent->type, -(lc->sx + 1));
|
||||
else if (lcother != NULL)
|
||||
layout_resize_adjust(w, lcother, lcparent->type, -(lc->sy + 1));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
layout_init(struct window *w, struct window_pane *wp)
|
||||
{
|
||||
|
||||
@@ -439,10 +439,13 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
|
||||
(int)py <= wp->yoff + (int)wp->sy))
|
||||
break;
|
||||
}
|
||||
if (wp == NULL)
|
||||
if (wp == NULL) {
|
||||
start = wp = server_client_get_pane(c);
|
||||
else
|
||||
if (wp == NULL)
|
||||
return (CELL_OUTSIDE);
|
||||
} else {
|
||||
start = wp;
|
||||
}
|
||||
|
||||
if (px == sx || py == sy) /* window border */
|
||||
return (screen_redraw_type_of_cell(ctx, wp, px, py));
|
||||
@@ -538,6 +541,8 @@ screen_redraw_check_is(struct screen_redraw_ctx *ctx, u_int px, u_int py,
|
||||
{
|
||||
enum screen_redraw_border_type border;
|
||||
|
||||
if (wp == NULL)
|
||||
return (0); /* No active pane. */
|
||||
border = screen_redraw_pane_border(ctx, wp, px, py);
|
||||
if (border != SCREEN_REDRAW_INSIDE && border != SCREEN_REDRAW_OUTSIDE)
|
||||
return (1);
|
||||
|
||||
@@ -2957,7 +2957,7 @@ server_client_reset_state(struct client *c)
|
||||
if (c->overlay_draw != NULL) {
|
||||
if (c->overlay_mode != NULL)
|
||||
s = c->overlay_mode(c, c->overlay_data, &cx, &cy);
|
||||
} else if (c->prompt_string == NULL)
|
||||
} else if (wp != NULL && c->prompt_string == NULL)
|
||||
s = wp->screen;
|
||||
else
|
||||
s = c->status.active;
|
||||
@@ -2985,7 +2985,7 @@ server_client_reset_state(struct client *c)
|
||||
cy = tty->sy - 1;
|
||||
}
|
||||
cx = c->prompt_cursor;
|
||||
} else if (c->overlay_draw == NULL) {
|
||||
} else if (wp != NULL && c->overlay_draw == NULL) {
|
||||
cursor = 0;
|
||||
tty_window_offset(tty, &ox, &oy, &sx, &sy);
|
||||
if (wp->xoff + s->cx >= ox && wp->xoff + s->cx <= ox + sx &&
|
||||
@@ -3004,7 +3004,9 @@ server_client_reset_state(struct client *c)
|
||||
|
||||
if (!cursor)
|
||||
mode &= ~MODE_CURSOR;
|
||||
}
|
||||
} else
|
||||
mode &= ~MODE_CURSOR;
|
||||
|
||||
log_debug("%s: cursor to %u,%u", __func__, cx, cy);
|
||||
tty_cursor(tty, cx, cy);
|
||||
|
||||
|
||||
4
tmux.h
4
tmux.h
@@ -3270,6 +3270,8 @@ struct window_pane *window_find_string(struct window *, const char *);
|
||||
int window_has_pane(struct window *, struct window_pane *);
|
||||
int window_set_active_pane(struct window *, struct window_pane *,
|
||||
int);
|
||||
int window_deactivate_pane(struct window *, struct window_pane *,
|
||||
int);
|
||||
void window_update_focus(struct window *);
|
||||
void window_pane_update_focus(struct window_pane *);
|
||||
void window_redraw_active_switch(struct window *,
|
||||
@@ -3350,6 +3352,8 @@ void layout_free_cell(struct layout_cell *);
|
||||
void layout_print_cell(struct layout_cell *, const char *, u_int);
|
||||
void layout_destroy_cell(struct window *, struct layout_cell *,
|
||||
struct layout_cell **);
|
||||
void layout_minimise_cell(struct window *, struct layout_cell *);
|
||||
void layout_unminimise_cell(struct window *, struct layout_cell *);
|
||||
void layout_resize_layout(struct window *, struct layout_cell *,
|
||||
enum layout_type, int, int);
|
||||
struct layout_cell *layout_search_by_border(struct layout_cell *, u_int, u_int);
|
||||
|
||||
43
window.c
43
window.c
@@ -536,6 +536,20 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
|
||||
w->active->active_point = next_active_point++;
|
||||
w->active->flags |= PANE_CHANGED;
|
||||
|
||||
if (wp->flags & PANE_MINIMISED) {
|
||||
wp->flags &= ~PANE_MINIMISED;
|
||||
if (w->layout_root != NULL) {
|
||||
wp->layout_cell = wp->saved_layout_cell;
|
||||
wp->saved_layout_cell = NULL;
|
||||
layout_unminimise_cell(w, wp->layout_cell);
|
||||
layout_fix_offsets(w);
|
||||
layout_fix_panes(w, NULL);
|
||||
}
|
||||
}
|
||||
notify_window("window-layout-changed", w);
|
||||
server_redraw_window(w);
|
||||
|
||||
|
||||
if (options_get_number(global_options, "focus-events")) {
|
||||
window_pane_update_focus(lastwp);
|
||||
window_pane_update_focus(w->active);
|
||||
@@ -548,6 +562,33 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
window_deactivate_pane(struct window *w, struct window_pane *wp, int notify)
|
||||
{
|
||||
struct window_pane *lastwp;
|
||||
|
||||
log_debug("%s: pane %%%u", __func__, wp->id);
|
||||
|
||||
if (w->flags & WINDOW_ZOOMED)
|
||||
window_unzoom(w, 1);
|
||||
lastwp = w->active;
|
||||
|
||||
window_pane_stack_remove(&w->last_panes, wp);
|
||||
window_pane_stack_push(&w->last_panes, lastwp);
|
||||
|
||||
w->active = NULL;
|
||||
|
||||
if (options_get_number(global_options, "focus-events")) {
|
||||
window_pane_update_focus(lastwp);
|
||||
}
|
||||
|
||||
tty_update_window_offset(w);
|
||||
|
||||
if (notify)
|
||||
notify_window("window-pane-changed", w);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
window_pane_get_palette(struct window_pane *wp, int c)
|
||||
{
|
||||
@@ -600,6 +641,8 @@ window_redraw_active_switch(struct window *w, struct window_pane *wp)
|
||||
}
|
||||
|
||||
wp = w->active;
|
||||
if (wp == NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user