Add simple menus to tree, client, buffer modes.

This commit is contained in:
nicm 2019-05-12 08:58:09 +00:00
parent c91323e4d6
commit a131655235
8 changed files with 209 additions and 24 deletions

View File

@ -67,7 +67,7 @@ cmd_send_keys_inject(struct client *c, struct cmd_find_state *fs,
if (wme == NULL || wme->mode->key_table == NULL) { if (wme == NULL || wme->mode->key_table == NULL) {
if (options_get_number(fs->wp->window->options, "xterm-keys")) if (options_get_number(fs->wp->window->options, "xterm-keys"))
key |= KEYC_XTERM; key |= KEYC_XTERM;
window_pane_key(fs->wp, NULL, fs->s, fs->wl, key, NULL); window_pane_key(fs->wp, item->client, fs->s, fs->wl, key, NULL);
return (item); return (item);
} }
table = key_bindings_get_table(wme->mode->key_table(wme), 1); table = key_bindings_get_table(wme->mode->key_table(wme), 1);
@ -132,7 +132,7 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
cmdq_error(item, "no mouse target"); cmdq_error(item, "no mouse target");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
window_pane_key(wp, NULL, s, wl, m->key, m); window_pane_key(wp, item->client, s, wl, m->key, m);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@ -278,8 +278,8 @@ key_bindings_init(void)
"bind -n WheelDownStatus next-window", "bind -n WheelDownStatus next-window",
"bind -n WheelUpStatus previous-window", "bind -n WheelUpStatus previous-window",
"bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'", "bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'",
"bind -n MouseDown3Pane if-shell -Ft= '#{mouse_any_flag}' 'select-pane -t=; send-keys -M' 'select-pane -mt='", "bind -n MouseDown3Pane if -Ft= '#{||:mouse_any_flag,pane_in_mode}' 'select-pane -t=; send-keys -M' 'select-pane -mt='",
"bind -n WheelUpPane if-shell -Ft= '#{mouse_any_flag}' 'send-keys -M' 'if -Ft= \"#{pane_in_mode}\" \"send-keys -M\" \"copy-mode -et=\"'", "bind -n WheelUpPane if -Ft= '#{mouse_any_flag}' 'send-keys -M' 'if -Ft= \"#{pane_in_mode}\" \"send-keys -M\" \"copy-mode -et=\"'",
"bind -n MouseDown3StatusRight display-menu -t= -xM -yS -F -M \"#{client_menu}\" -T \"#[align=centre]#{client_name}\"", "bind -n MouseDown3StatusRight display-menu -t= -xM -yS -F -M \"#{client_menu}\" -T \"#[align=centre]#{client_name}\"",
"bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -F -M \"#{session_menu}\" -T \"#[align=centre]#{session_name}\"", "bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -F -M \"#{session_menu}\" -T \"#[align=centre]#{session_name}\"",
"bind -n MouseDown3Status display-menu -t= -xW -yS -F -M \"#{window_menu}\" -T \"#[align=centre]#{window_index}:#{window_name}\"", "bind -n MouseDown3Status display-menu -t= -xW -yS -F -M \"#{window_menu}\" -T \"#[align=centre]#{window_index}:#{window_name}\"",

14
menu.c
View File

@ -56,7 +56,11 @@ menu_add_item(struct menu *menu, struct menu_item *item, struct client *c,
if (item == NULL || *item->name == '\0') /* horizontal line */ if (item == NULL || *item->name == '\0') /* horizontal line */
return; return;
name = format_single(NULL, item->name, c, fs->s, fs->wl, fs->wp); if (fs != NULL) {
name = format_single(NULL, item->name, c, fs->s, fs->wl,
fs->wp);
} else
name = xstrdup(item->name);
if (*name == '\0') { /* no item if empty after format expanded */ if (*name == '\0') { /* no item if empty after format expanded */
menu->count--; menu->count--;
return; return;
@ -118,7 +122,6 @@ menu_create(const char *s, struct client *c, struct cmd_find_state *fs,
copy = string = xstrdup(s); copy = string = xstrdup(s);
do { do {
next = (char *)format_skip(string, "|"); next = (char *)format_skip(string, "|");
log_debug("XXX %s -- %s", next, string);
if (next != NULL) if (next != NULL)
*next++ = '\0'; *next++ = '\0';
if (*string == '\0') if (*string == '\0')
@ -180,6 +183,9 @@ menu_free_cb(struct client *c)
if (md->item != NULL) if (md->item != NULL)
md->item->flags &= ~CMDQ_WAITING; md->item->flags &= ~CMDQ_WAITING;
if (md->cb != NULL)
md->cb(md->menu, UINT_MAX, KEYC_NONE, md->data);
screen_free(&md->s); screen_free(&md->s);
menu_free(md->menu); menu_free(md->menu);
free(md); free(md);
@ -274,6 +280,7 @@ chosen:
return (1); return (1);
if (md->cb != NULL) { if (md->cb != NULL) {
md->cb(md->menu, md->choice, item->key, md->data); md->cb(md->menu, md->choice, item->key, md->data);
md->cb = NULL;
return (1); return (1);
} }
cmdlist = cmd_string_parse(item->command, NULL, 0, &cause); cmdlist = cmd_string_parse(item->command, NULL, 0, &cause);
@ -308,7 +315,8 @@ menu_display(struct menu *menu, int flags, struct cmdq_item *item, u_int px,
md->item = item; md->item = item;
md->flags = flags; md->flags = flags;
cmd_find_copy_state(&md->fs, fs); if (fs != NULL)
cmd_find_copy_state(&md->fs, fs);
screen_init(&md->s, menu->width + 4, menu->count + 2, 0); screen_init(&md->s, menu->width + 4, menu->count + 2, 0);
md->px = px; md->px = px;

View File

@ -35,6 +35,7 @@ struct mode_tree_data {
struct window_pane *wp; struct window_pane *wp;
void *modedata; void *modedata;
const char *menu;
const char **sort_list; const char **sort_list;
u_int sort_size; u_int sort_size;
@ -43,6 +44,7 @@ struct mode_tree_data {
mode_tree_build_cb buildcb; mode_tree_build_cb buildcb;
mode_tree_draw_cb drawcb; mode_tree_draw_cb drawcb;
mode_tree_search_cb searchcb; mode_tree_search_cb searchcb;
mode_tree_menu_cb menucb;
struct mode_tree_list children; struct mode_tree_list children;
struct mode_tree_list saved; struct mode_tree_list saved;
@ -89,8 +91,21 @@ struct mode_tree_line {
int flat; int flat;
}; };
struct mode_tree_menu {
struct mode_tree_data *data;
struct client *c;
u_int line;
void *itemdata;
};
static void mode_tree_free_items(struct mode_tree_list *); static void mode_tree_free_items(struct mode_tree_list *);
#define MODE_TREE_MENU \
"Scroll Left,<,|" \
"Scroll Right,>,|" \
"|" \
"Cancel,q,"
static struct mode_tree_item * static struct mode_tree_item *
mode_tree_find_item(struct mode_tree_list *mtl, uint64_t tag) mode_tree_find_item(struct mode_tree_list *mtl, uint64_t tag)
{ {
@ -299,8 +314,9 @@ mode_tree_each_tagged(struct mode_tree_data *mtd, mode_tree_each_cb cb,
struct mode_tree_data * struct mode_tree_data *
mode_tree_start(struct window_pane *wp, struct args *args, mode_tree_start(struct window_pane *wp, struct args *args,
mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb, mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb,
mode_tree_search_cb searchcb, void *modedata, const char **sort_list, mode_tree_search_cb searchcb, mode_tree_menu_cb menucb, void *modedata,
u_int sort_size, struct screen **s) const char *menu, const char **sort_list, u_int sort_size,
struct screen **s)
{ {
struct mode_tree_data *mtd; struct mode_tree_data *mtd;
const char *sort; const char *sort;
@ -311,6 +327,7 @@ mode_tree_start(struct window_pane *wp, struct args *args,
mtd->wp = wp; mtd->wp = wp;
mtd->modedata = modedata; mtd->modedata = modedata;
mtd->menu = menu;
mtd->sort_list = sort_list; mtd->sort_list = sort_list;
mtd->sort_size = sort_size; mtd->sort_size = sort_size;
@ -334,6 +351,7 @@ mode_tree_start(struct window_pane *wp, struct args *args,
mtd->buildcb = buildcb; mtd->buildcb = buildcb;
mtd->drawcb = drawcb; mtd->drawcb = drawcb;
mtd->searchcb = searchcb; mtd->searchcb = searchcb;
mtd->menucb = menucb;
TAILQ_INIT(&mtd->children); TAILQ_INIT(&mtd->children);
@ -762,6 +780,71 @@ mode_tree_filter_free(void *data)
mode_tree_remove_ref(data); mode_tree_remove_ref(data);
} }
static void
mode_tree_menu_callback(__unused struct menu *menu, __unused u_int idx,
key_code key, void *data)
{
struct mode_tree_menu *mtm = data;
struct mode_tree_data *mtd = mtm->data;
struct mode_tree_item *mti;
if (mtd->dead || key == KEYC_NONE)
goto out;
if (mtm->line >= mtd->line_size)
goto out;
mti = mtd->line_list[mtm->line].item;
if (mti->itemdata != mtm->itemdata)
goto out;
mtd->current = mtm->line;
mtd->menucb (mtd->modedata, mtm->c, key);
out:
mode_tree_remove_ref(mtd);
free(mtm);
}
static void
mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x,
u_int y, int outside)
{
struct mode_tree_item *mti;
struct menu *menu;
struct mode_tree_menu *mtm;
const char *s;
char *title;
u_int line;
if (mtd->offset + y > mtd->line_size - 1)
line = mtd->current;
else
line = mtd->offset + y;
mti = mtd->line_list[line].item;
if (!outside) {
s = mtd->menu;
xasprintf(&title, "#[align=centre]%s", mti->name);
} else {
s = MODE_TREE_MENU;
title = xstrdup("");
}
menu = menu_create(s, c, NULL, title);
free(title);
if (menu == NULL)
return;
mtm = xmalloc(sizeof *mtm);
mtm->data = mtd;
mtm->c = c;
mtm->line = line;
mtm->itemdata = mti->itemdata;
mtd->references++;
if (menu_display(menu, 0, NULL, x, y, c, NULL, mode_tree_menu_callback,
mtm) != 0)
menu_free(menu);
}
int int
mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
struct mouse_event *m, u_int *xp, u_int *yp) struct mouse_event *m, u_int *xp, u_int *yp)
@ -772,7 +855,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
int choice; int choice;
key_code tmp; key_code tmp;
if (KEYC_IS_MOUSE(*key)) { if (KEYC_IS_MOUSE(*key) && m != NULL) {
if (cmd_mouse_at(mtd->wp, m, &x, &y, 0) != 0) { if (cmd_mouse_at(mtd->wp, m, &x, &y, 0) != 0) {
*key = KEYC_NONE; *key = KEYC_NONE;
return (0); return (0);
@ -782,20 +865,29 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
if (yp != NULL) if (yp != NULL)
*yp = y; *yp = y;
if (x > mtd->width || y > mtd->height) { if (x > mtd->width || y > mtd->height) {
if (*key == KEYC_MOUSEDOWN3_PANE)
mode_tree_display_menu(mtd, c, x, y, 1);
if (!mtd->preview) if (!mtd->preview)
*key = KEYC_NONE; *key = KEYC_NONE;
return (0); return (0);
} }
if (mtd->offset + y < mtd->line_size) { if (mtd->offset + y < mtd->line_size) {
if (*key == KEYC_MOUSEDOWN1_PANE || if (*key == KEYC_MOUSEDOWN1_PANE ||
*key == KEYC_MOUSEDOWN3_PANE ||
*key == KEYC_DOUBLECLICK1_PANE) *key == KEYC_DOUBLECLICK1_PANE)
mtd->current = mtd->offset + y; mtd->current = mtd->offset + y;
if (*key == KEYC_DOUBLECLICK1_PANE) if (*key == KEYC_DOUBLECLICK1_PANE)
*key = '\r'; *key = '\r';
else else {
if (*key == KEYC_MOUSEDOWN3_PANE)
mode_tree_display_menu(mtd, c, x, y, 0);
*key = KEYC_NONE; *key = KEYC_NONE;
} else }
} else {
if (*key == KEYC_MOUSEDOWN3_PANE)
mode_tree_display_menu(mtd, c, x, y, 0);
*key = KEYC_NONE; *key = KEYC_NONE;
}
return (0); return (0);
} }
@ -879,7 +971,8 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
current->tagged = 1; current->tagged = 1;
} else } else
current->tagged = 0; current->tagged = 0;
mode_tree_down(mtd, 0); if (m != NULL)
mode_tree_down(mtd, 0);
break; break;
case 'T': case 'T':
for (i = 0; i < mtd->line_size; i++) for (i = 0; i < mtd->line_size; i++)

6
tmux.h
View File

@ -2408,8 +2408,9 @@ u_int layout_set_previous(struct window *);
/* mode-tree.c */ /* mode-tree.c */
typedef void (*mode_tree_build_cb)(void *, u_int, uint64_t *, const char *); typedef void (*mode_tree_build_cb)(void *, u_int, uint64_t *, const char *);
typedef void (*mode_tree_draw_cb)(void *, void *, struct screen_write_ctx *, typedef void (*mode_tree_draw_cb)(void *, void *, struct screen_write_ctx *,
u_int, u_int); u_int, u_int);
typedef int (*mode_tree_search_cb)(void *, void *, const char *); typedef int (*mode_tree_search_cb)(void *, void *, const char *);
typedef void (*mode_tree_menu_cb)(void *, struct client *, key_code);
typedef void (*mode_tree_each_cb)(void *, void *, struct client *, key_code); typedef void (*mode_tree_each_cb)(void *, void *, struct client *, key_code);
u_int mode_tree_count_tagged(struct mode_tree_data *); u_int mode_tree_count_tagged(struct mode_tree_data *);
void *mode_tree_get_current(struct mode_tree_data *); void *mode_tree_get_current(struct mode_tree_data *);
@ -2420,7 +2421,8 @@ void mode_tree_each_tagged(struct mode_tree_data *, mode_tree_each_cb,
void mode_tree_down(struct mode_tree_data *, int); void mode_tree_down(struct mode_tree_data *, int);
struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *, struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *,
mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb, mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb,
void *, const char **, u_int, struct screen **); mode_tree_menu_cb, void *, const char *, const char **, u_int,
struct screen **);
void mode_tree_zoom(struct mode_tree_data *, struct args *); void mode_tree_zoom(struct mode_tree_data *, struct args *);
void mode_tree_build(struct mode_tree_data *); void mode_tree_build(struct mode_tree_data *);
void mode_tree_free(struct mode_tree_data *); void mode_tree_free(struct mode_tree_data *);

View File

@ -39,6 +39,19 @@ static void window_buffer_key(struct window_mode_entry *,
#define WINDOW_BUFFER_DEFAULT_FORMAT \ #define WINDOW_BUFFER_DEFAULT_FORMAT \
"#{buffer_size} bytes (#{t:buffer_created})" "#{buffer_size} bytes (#{t:buffer_created})"
#define WINDOW_BUFFER_MENU \
"Paste,p,|" \
"Paste Tagged,P,|" \
"|" \
"Tag,t,|" \
"Tag All,C-t,|" \
"Tag None,T,|" \
"|" \
"Delete,d,|" \
"Delete Tagged,D,|" \
"|" \
"Cancel,q,"
const struct window_mode window_buffer_mode = { const struct window_mode window_buffer_mode = {
.name = "buffer-mode", .name = "buffer-mode",
.default_format = WINDOW_BUFFER_DEFAULT_FORMAT, .default_format = WINDOW_BUFFER_DEFAULT_FORMAT,
@ -67,7 +80,9 @@ struct window_buffer_itemdata {
}; };
struct window_buffer_modedata { struct window_buffer_modedata {
struct window_pane *wp;
struct cmd_find_state fs; struct cmd_find_state fs;
struct mode_tree_data *data; struct mode_tree_data *data;
char *command; char *command;
char *format; char *format;
@ -264,6 +279,19 @@ window_buffer_search(__unused void *modedata, void *itemdata, const char *ss)
return (memmem(bufdata, bufsize, ss, strlen(ss)) != NULL); return (memmem(bufdata, bufsize, ss, strlen(ss)) != NULL);
} }
static void
window_buffer_menu(void *modedata, struct client *c, key_code key)
{
struct window_buffer_modedata *data = modedata;
struct window_pane *wp = data->wp;
struct window_mode_entry *wme;
wme = TAILQ_FIRST(&wp->modes);
if (wme == NULL || wme->data != modedata)
return;
window_buffer_key(wme, c, NULL, NULL, key, NULL);
}
static struct screen * static struct screen *
window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs, window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
struct args *args) struct args *args)
@ -273,6 +301,7 @@ window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
struct screen *s; struct screen *s;
wme->data = data = xcalloc(1, sizeof *data); wme->data = data = xcalloc(1, sizeof *data);
data->wp = wp;
cmd_find_copy_state(&data->fs, fs); cmd_find_copy_state(&data->fs, fs);
if (args == NULL || !args_has(args, 'F')) if (args == NULL || !args_has(args, 'F'))
@ -285,8 +314,9 @@ window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
data->command = xstrdup(args->argv[0]); data->command = xstrdup(args->argv[0]);
data->data = mode_tree_start(wp, args, window_buffer_build, data->data = mode_tree_start(wp, args, window_buffer_build,
window_buffer_draw, window_buffer_search, data, window_buffer_draw, window_buffer_search, window_buffer_menu, data,
window_buffer_sort_list, nitems(window_buffer_sort_list), &s); WINDOW_BUFFER_MENU, window_buffer_sort_list,
nitems(window_buffer_sort_list), &s);
mode_tree_zoom(data->data, args); mode_tree_zoom(data->data, args);
mode_tree_build(data->data); mode_tree_build(data->data);

View File

@ -40,6 +40,16 @@ static void window_client_key(struct window_mode_entry *,
"session #{session_name} " \ "session #{session_name} " \
"(#{client_width}x#{client_height}, #{t:client_activity})" "(#{client_width}x#{client_height}, #{t:client_activity})"
#define WINDOW_CLIENT_MENU \
"Detach,d,|" \
"Detach Tagged,D,|" \
"|" \
"Tag,t,|" \
"Tag All,C-t,|" \
"Tag None,T,|" \
"|" \
"Cancel,q,"
const struct window_mode window_client_mode = { const struct window_mode window_client_mode = {
.name = "client-mode", .name = "client-mode",
.default_format = WINDOW_CLIENT_DEFAULT_FORMAT, .default_format = WINDOW_CLIENT_DEFAULT_FORMAT,
@ -68,6 +78,8 @@ struct window_client_itemdata {
}; };
struct window_client_modedata { struct window_client_modedata {
struct window_pane *wp;
struct mode_tree_data *data; struct mode_tree_data *data;
char *format; char *format;
char *command; char *command;
@ -249,6 +261,19 @@ window_client_draw(__unused void *modedata, void *itemdata,
screen_write_fast_copy(ctx, &c->status.screen, 0, 0, sx, lines); screen_write_fast_copy(ctx, &c->status.screen, 0, 0, sx, lines);
} }
static void
window_client_menu(void *modedata, struct client *c, key_code key)
{
struct window_client_modedata *data = modedata;
struct window_pane *wp = data->wp;
struct window_mode_entry *wme;
wme = TAILQ_FIRST(&wp->modes);
if (wme == NULL || wme->data != modedata)
return;
window_client_key(wme, c, NULL, NULL, key, NULL);
}
static struct screen * static struct screen *
window_client_init(struct window_mode_entry *wme, window_client_init(struct window_mode_entry *wme,
__unused struct cmd_find_state *fs, struct args *args) __unused struct cmd_find_state *fs, struct args *args)
@ -258,6 +283,7 @@ window_client_init(struct window_mode_entry *wme,
struct screen *s; struct screen *s;
wme->data = data = xcalloc(1, sizeof *data); wme->data = data = xcalloc(1, sizeof *data);
data->wp = wp;
if (args == NULL || !args_has(args, 'F')) if (args == NULL || !args_has(args, 'F'))
data->format = xstrdup(WINDOW_CLIENT_DEFAULT_FORMAT); data->format = xstrdup(WINDOW_CLIENT_DEFAULT_FORMAT);
@ -269,7 +295,8 @@ window_client_init(struct window_mode_entry *wme,
data->command = xstrdup(args->argv[0]); data->command = xstrdup(args->argv[0]);
data->data = mode_tree_start(wp, args, window_client_build, data->data = mode_tree_start(wp, args, window_client_build,
window_client_draw, NULL, data, window_client_sort_list, window_client_draw, NULL, window_client_menu, data,
WINDOW_CLIENT_MENU, window_client_sort_list,
nitems(window_client_sort_list), &s); nitems(window_client_sort_list), &s);
mode_tree_zoom(data->data, args); mode_tree_zoom(data->data, args);

View File

@ -53,6 +53,19 @@ static void window_tree_key(struct window_mode_entry *,
"}" \ "}" \
"}" "}"
#define WINDOW_TREE_MENU \
"Select,Enter,|" \
"Expand,Right,|" \
"|" \
"Tag,t,|" \
"Tag All,C-t,|" \
"Tag None,T,|" \
"|" \
"Kill,x,|" \
"Kill Tagged,X,|" \
"|" \
"Cancel,q,"
const struct window_mode window_tree_mode = { const struct window_mode window_tree_mode = {
.name = "tree-mode", .name = "tree-mode",
.default_format = WINDOW_TREE_DEFAULT_FORMAT, .default_format = WINDOW_TREE_DEFAULT_FORMAT,
@ -814,6 +827,19 @@ window_tree_search(__unused void *modedata, void *itemdata, const char *ss)
return (0); return (0);
} }
static void
window_tree_menu(void *modedata, struct client *c, key_code key)
{
struct window_tree_modedata *data = modedata;
struct window_pane *wp = data->wp;
struct window_mode_entry *wme;
wme = TAILQ_FIRST(&wp->modes);
if (wme == NULL || wme->data != modedata)
return;
window_tree_key(wme, c, NULL, NULL, key, NULL);
}
static struct screen * static struct screen *
window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs, window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
struct args *args) struct args *args)
@ -823,6 +849,8 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
struct screen *s; struct screen *s;
wme->data = data = xcalloc(1, sizeof *data); wme->data = data = xcalloc(1, sizeof *data);
data->wp = wp;
data->references = 1;
if (args_has(args, 's')) if (args_has(args, 's'))
data->type = WINDOW_TREE_SESSION; data->type = WINDOW_TREE_SESSION;
@ -832,9 +860,6 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
data->type = WINDOW_TREE_PANE; data->type = WINDOW_TREE_PANE;
memcpy(&data->fs, fs, sizeof data->fs); memcpy(&data->fs, fs, sizeof data->fs);
data->wp = wp;
data->references = 1;
if (args == NULL || !args_has(args, 'F')) if (args == NULL || !args_has(args, 'F'))
data->format = xstrdup(WINDOW_TREE_DEFAULT_FORMAT); data->format = xstrdup(WINDOW_TREE_DEFAULT_FORMAT);
else else
@ -846,7 +871,8 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
data->squash_groups = !args_has(args, 'G'); data->squash_groups = !args_has(args, 'G');
data->data = mode_tree_start(wp, args, window_tree_build, data->data = mode_tree_start(wp, args, window_tree_build,
window_tree_draw, window_tree_search, data, window_tree_sort_list, window_tree_draw, window_tree_search, window_tree_menu, data,
WINDOW_TREE_MENU, window_tree_sort_list,
nitems(window_tree_sort_list), &s); nitems(window_tree_sort_list), &s);
mode_tree_zoom(data->data, args); mode_tree_zoom(data->data, args);
@ -1146,7 +1172,7 @@ window_tree_key(struct window_mode_entry *wme, struct client *c,
item = new_item; item = new_item;
data->offset = 0; data->offset = 0;
} }
if (KEYC_IS_MOUSE(key)) if (KEYC_IS_MOUSE(key) && m != NULL)
key = window_tree_mouse(data, key, x, item); key = window_tree_mouse(data, key, x, item);
switch (key) { switch (key) {
case '<': case '<':
@ -1207,7 +1233,6 @@ window_tree_key(struct window_mode_entry *wme, struct client *c,
free(prompt); free(prompt);
break; break;
case '\r': case '\r':
item = mode_tree_get_current(data->data);
name = window_tree_get_target(item, &fs); name = window_tree_get_target(item, &fs);
if (name != NULL) if (name != NULL)
mode_tree_run_command(c, NULL, data->command, name); mode_tree_run_command(c, NULL, data->command, name);