Merge branch 'master' into events

This commit is contained in:
Nicholas Marriott
2026-07-07 13:15:12 +01:00
15 changed files with 323 additions and 253 deletions

View File

@@ -51,10 +51,9 @@ cmd_break_pane_float(struct cmdq_item *item, struct args *args,
struct window *w, struct window_pane *wp)
{
struct layout_cell *lc = wp->layout_cell;
u_int sx = lc->saved_sx, sy = lc->saved_sy;
int ox = lc->saved_xoff, oy = lc->saved_yoff;
char *cause = NULL;
enum pane_lines lines = window_get_pane_lines(w);
struct layout_geometry *fg = &lc->fg;
if (window_pane_is_floating(wp)) {
cmdq_error(item, "pane is already floating");
@@ -65,14 +64,13 @@ cmd_break_pane_float(struct cmdq_item *item, struct args *args,
return (CMD_RETURN_ERROR);
}
if (layout_floating_args_parse(item, args, lines, w, &sx, &sy, &ox, &oy,
&cause) != 0) {
if (layout_floating_args_parse(item, args, lines, w, fg, &cause) != 0) {
cmdq_error(item, "failed to float pane: %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
layout_remove_tile(w, lc);
layout_set_size(lc, sx, sy, ox, oy);
layout_set_size(lc, fg->sx, fg->sy, fg->xoff, fg->yoff);
lc->flags |= LAYOUT_CELL_FLOATING;
TAILQ_REMOVE(&w->z_index, wp, zentry);

View File

@@ -126,6 +126,10 @@ cmd_display_menu_get_pos(struct client *tc, struct cmdq_item *item,
format_add(ft, "popup_mouse_y", "%u", event->m.y);
}
/* Position of the previous menu, for -x/-y L. */
format_add(ft, "popup_last_x", "%u", tc->menu_last_px);
format_add(ft, "popup_last_y", "%u", tc->menu_last_py + h);
/*
* If there are any status lines, add this window position and the
* status line position.
@@ -238,6 +242,8 @@ cmd_display_menu_get_pos(struct client *tc, struct cmdq_item *item,
xp = "#{popup_pane_left}";
else if (strcmp(xp, "M") == 0)
xp = "#{popup_mouse_centre_x}";
else if (strcmp(xp, "L") == 0)
xp = "#{popup_last_x}";
else if (strcmp(xp, "W") == 0)
xp = "#{popup_window_status_line_x}";
p = format_expand(ft, xp);
@@ -258,6 +264,8 @@ cmd_display_menu_get_pos(struct client *tc, struct cmdq_item *item,
yp = "#{popup_pane_bottom}";
else if (strcmp(yp, "M") == 0)
yp = "#{popup_mouse_top}";
else if (strcmp(yp, "L") == 0)
yp = "#{popup_last_y}";
else if (strcmp(yp, "S") == 0)
yp = "#{popup_status_line_y}";
else if (strcmp(yp, "W") == 0)

View File

@@ -71,8 +71,9 @@ cmd_join_pane_place(struct cmdq_item *item, struct winlink *wl,
struct window *w = wl->window;
struct layout_cell *lc = wp->layout_cell;
struct window_pane *owp;
int wx = w->sx, wy = w->sy, px = lc->sx;
int py = lc->sy, xoff = lc->xoff, yoff = lc->yoff;
int wx = w->sx, wy = w->sy;
int px = lc->g.sx, py = lc->g.sy;
int xoff = lc->g.xoff, yoff = lc->g.yoff;
int border = 1;
if (window_pane_get_pane_lines(wp) == PANE_LINES_NONE)
@@ -180,9 +181,9 @@ cmd_join_pane_place(struct cmdq_item *item, struct winlink *wl,
return (CMD_RETURN_ERROR);
}
if (xoff != lc->xoff || yoff != lc->yoff) {
lc->xoff = xoff;
lc->yoff = yoff;
if (xoff != lc->g.xoff || yoff != lc->g.yoff) {
lc->g.xoff = xoff;
lc->g.yoff = yoff;
layout_fix_panes(w, NULL);
}
events_fire_window("window-layout-changed", w);
@@ -200,7 +201,7 @@ cmd_join_pane_move(struct cmdq_item *item, struct args *args,
const char *errstr, *argval;
const char flags[] = { 'U', 'D', 'L', 'R' };
char *cause = NULL, flag;
int xoff = lc->xoff, yoff = lc->yoff, adjust;
int xoff = lc->g.xoff, yoff = lc->g.yoff, adjust;
u_int i;
enum pane_lines lines = window_pane_get_pane_lines(wp);
@@ -251,9 +252,9 @@ cmd_join_pane_move(struct cmdq_item *item, struct args *args,
xoff += adjust;
}
if (xoff != lc->xoff || yoff != lc->yoff) {
lc->xoff = xoff;
lc->yoff = yoff;
if (xoff != lc->g.xoff || yoff != lc->g.yoff) {
lc->g.xoff = xoff;
lc->g.yoff = yoff;
layout_fix_panes(w, NULL);
events_fire_window("window-layout-changed", w);
server_redraw_window(w);
@@ -319,8 +320,8 @@ cmd_join_pane_mouse_move(struct client *c, struct mouse_event *m)
ly = m->statusat - 1;
if (x != lx || y != ly) {
lc->xoff += x - lx;
lc->yoff += y - ly;
lc->g.xoff += x - lx;
lc->g.yoff += y - ly;
layout_fix_panes(w, NULL);
server_redraw_window(w);
server_redraw_window_borders(w);
@@ -378,10 +379,11 @@ cmd_join_pane_tile(struct cmdq_item *item, struct args *args, struct window *w,
return (CMD_RETURN_ERROR);
}
lc->saved_sx = lc->sx;
lc->saved_sy = lc->sy;
lc->saved_xoff = lc->xoff;
lc->saved_yoff = lc->yoff;
lc->fg.sx = lc->g.sx;
lc->fg.sy = lc->g.sy;
lc->fg.xoff = lc->g.xoff;
lc->fg.yoff = lc->g.yoff;
if (layout_insert_tile(w, lc) != 0) {
cmdq_error(item, "no space for a new pane");
return (CMD_RETURN_ERROR);

View File

@@ -270,10 +270,10 @@ cmd_resize_pane_mouse_resize_move_floating(struct client *c,
if ((lx == left || lx == left + 1) && ly == wp->yoff - 1) {
/* Top left corner. */
new_sx = lc->sx + (lx - x);
new_sx = lc->g.sx + (lx - x);
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = lc->sy + (ly - y);
new_sy = lc->g.sy + (ly - y);
if (new_sy < PANE_MINIMUM)
new_sy = PANE_MINIMUM;
new_xoff = x + 1; /* because mouse is on border at xoff - 1 */
@@ -283,65 +283,65 @@ cmd_resize_pane_mouse_resize_move_floating(struct client *c,
} else if ((lx == right + 1 || lx == right) &&
ly == wp->yoff - 1) {
/* Top right corner. */
new_sx = x - lc->xoff;
new_sx = x - lc->g.xoff;
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = lc->sy + (ly - y);
new_sy = lc->g.sy + (ly - y);
if (new_sy < PANE_MINIMUM)
new_sy = PANE_MINIMUM;
new_yoff = y + 1;
layout_set_size(lc, new_sx, new_sy, lc->xoff, new_yoff);
layout_set_size(lc, new_sx, new_sy, lc->g.xoff, new_yoff);
resizes++;
} else if ((lx == left || lx == left + 1) &&
ly == wp->yoff + sy) {
/* Bottom left corner. */
new_sx = lc->sx + (lx - x);
new_sx = lc->g.sx + (lx - x);
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = y - lc->yoff;
new_sy = y - lc->g.yoff;
if (new_sy < PANE_MINIMUM)
return;
new_xoff = x + 1;
layout_set_size(lc, new_sx, new_sy, new_xoff, lc->yoff);
layout_set_size(lc, new_sx, new_sy, new_xoff, lc->g.yoff);
resizes++;
} else if ((lx == right + 1 || lx == right) &&
ly == wp->yoff + sy) {
/* Bottom right corner. */
new_sx = x - lc->xoff;
new_sx = x - lc->g.xoff;
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = y - lc->yoff;
new_sy = y - lc->g.yoff;
if (new_sy < PANE_MINIMUM)
new_sy = PANE_MINIMUM;
layout_set_size(lc, new_sx, new_sy, lc->xoff, lc->yoff);
layout_set_size(lc, new_sx, new_sy, lc->g.xoff, lc->g.yoff);
resizes++;
} else if (lx == right) {
/* Right border. */
new_sx = x - lc->xoff;
new_sx = x - lc->g.xoff;
if (new_sx < PANE_MINIMUM)
return;
layout_set_size(lc, new_sx, lc->sy, lc->xoff, lc->yoff);
layout_set_size(lc, new_sx, lc->g.sy, lc->g.xoff, lc->g.yoff);
resizes++;
} else if (lx == left) {
/* Left border. */
new_sx = lc->sx + (lx - x);
new_sx = lc->g.sx + (lx - x);
if (new_sx < PANE_MINIMUM)
return;
new_xoff = x + 1;
layout_set_size(lc, new_sx, lc->sy, new_xoff, lc->yoff);
layout_set_size(lc, new_sx, lc->g.sy, new_xoff, lc->g.yoff);
resizes++;
} else if (ly == wp->yoff + sy) {
/* Bottom border. */
new_sy = y - lc->yoff;
new_sy = y - lc->g.yoff;
if (new_sy < PANE_MINIMUM)
return;
layout_set_size(lc, lc->sx, new_sy, lc->xoff, lc->yoff);
layout_set_size(lc, lc->g.sx, new_sy, lc->g.xoff, lc->g.yoff);
resizes++;
} else if (ly == wp->yoff - 1) {
/* Top border (move instead of resize). */
new_xoff = lc->xoff + (x - lx);
new_xoff = lc->g.xoff + (x - lx);
new_yoff = y + 1;
layout_set_size(lc, lc->sx, lc->sy, new_xoff, new_yoff);
layout_set_size(lc, lc->g.sx, lc->g.sy, new_xoff, new_yoff);
resizes++;
}
if (resizes != 0) {

View File

@@ -59,6 +59,8 @@
" '#{?mouse_hyperlink,Type #[underscore]#{=/9/...:mouse_hyperlink},}' 'C-h' {copy-mode -q; send-keys -l -- \"#{q:mouse_hyperlink}\"}" \
" '#{?mouse_hyperlink,Copy #[underscore]#{=/9/...:mouse_hyperlink},}' 'h' {copy-mode -q; set-buffer -- \"#{q:mouse_hyperlink}\"}" \
" ''" \
" '#{?#{#{pane_floating_flag}},Move,}' '' {display-menu -xL -yL -T '#[align=centre]Move' " DEFAULT_MOVE_MENU " }" \
" '#{?#{#{pane_floating_flag}},Move & Resize,}' '' {display-menu -xL -yL -T '#[align=centre]Move & Resize' " DEFAULT_MOVE_RESIZE_MENU " }" \
" '#{?#{#{pane_floating_flag}},Tile,}' 't' { join-pane }" \
" '#{?#{!:#{pane_floating_flag}},Float,}' 'f' { break-pane -W }" \
" '#{?#{!:#{pane_floating_flag}},Horizontal Split,}' 'h' {split-window -h}" \
@@ -72,6 +74,30 @@
" 'Respawn' 'R' {respawn-pane -k}" \
" '#{?pane_marked,Unmark,Mark}' 'm' {select-pane -m}" \
" '#{?#{>:#{window_panes},1},,-}#{?window_zoomed_flag,Unzoom,Zoom}' 'z' {resize-pane -Z}"
#define DEFAULT_MOVE_MENU \
" 'Centre' 'c' {move-pane -P centre}" \
" ''" \
" 'Top Left' '1' {move-pane -P top-left}" \
" 'Top Right' '2' {move-pane -P top-right}" \
" 'Bottom Left' '3' {move-pane -P bottom-left}" \
" 'Bottom Right' '4' {move-pane -P bottom-right}" \
" ''" \
" 'Top' 't' {move-pane -P top-centre}" \
" 'Bottom' 'b' {move-pane -P bottom-centre}" \
" 'Left' 'l' {move-pane -P centre-left}" \
" 'Right' 'r' {move-pane -P centre-right}"
#define DEFAULT_MOVE_RESIZE_MENU \
" 'Fill' '0' {resize-pane -x100% -y100%; move-pane -P top-left}" \
" ''" \
" 'Top Left' '1' {resize-pane -x50% -y50%; move-pane -P top-left}" \
" 'Top Right' '2' {resize-pane -x50% -y50%; move-pane -P top-right}" \
" 'Bottom Left' '3' {resize-pane -x50% -y50%; move-pane -P bottom-left}" \
" 'Bottom Right' '4' {resize-pane -x50% -y50%; move-pane -P bottom-right}" \
" ''" \
" 'Top' 't' {resize-pane -x100% -y50%; move-pane -P top-centre}" \
" 'Bottom' 'b' {resize-pane -x100% -y50%; move-pane -P bottom-centre}" \
" 'Left' 'l' {resize-pane -x50% -y100%; move-pane -P centre-left}" \
" 'Right' 'r' {resize-pane -x50% -y100%; move-pane -P centre-right}"
static int key_bindings_cmp(struct key_binding *, struct key_binding *);
RB_GENERATE_STATIC(key_bindings, key_binding, entry, key_bindings_cmp);
@@ -410,10 +436,8 @@ key_bindings_init(void)
"bind -N 'Choose a window from a list' w { choose-tree -Zw }",
"bind -N 'Kill the active pane' x { confirm-before -p\"kill-pane #P? (y/n)\" kill-pane }",
"bind -N 'Zoom the active pane' z { resize-pane -Z }",
"bind -N 'Move pane to top-left corner' '{' { resize-pane -x50% -y50%; move-pane -P top-left }",
"bind -N 'Move pane to top-right corner' '}' { resize-pane -x50% -y50%; move-pane -P top-right }",
"bind -N 'Move pane to bottom-left corner' 'M-{' { resize-pane -x50% -y50%; move-pane -P bottom-left }",
"bind -N 'Move pane to bottom-right corner' 'M-}' { resize-pane -x50% -y50%; move-pane -P bottom-right }",
"bind -N 'Swap the active pane with the pane above' '{' { swap-pane -U }",
"bind -N 'Swap the active pane with the pane below' '}' { swap-pane -D }",
"bind -N 'Show messages' '~' { show-messages }",
"bind -N 'Enter copy mode and scroll up' PPage { copy-mode -u }",
"bind -N 'Select the pane above the active pane' -r Up { select-pane -U }",
@@ -444,6 +468,28 @@ key_bindings_init(void)
"bind -N 'Resize the pane left' -r C-Left if -F '#{?floating_pane_flag}' { resizep -R-1 } { resize-pane -L }",
"bind -N 'Resize the pane right' -r C-Right { resize-pane -R }",
/* Floating pane movement. */
"bind -N 'Move a floating pane' g { switch-client -Tmove }",
"bind -Tmove -N 'Move pane to top-left corner' 1 { move-pane -P top-left }",
"bind -Tmove -N 'Move pane to top-right corner' 2 { move-pane -P top-right }",
"bind -Tmove -N 'Move pane to bottom-left corner' 3 { move-pane -P bottom-left }",
"bind -Tmove -N 'Move pane to bottom-right corner' 4 { move-pane -P bottom-right }",
"bind -Tmove -N 'Move pane to top-left corner and resize' M-1 { resize-pane -x50% -y50%; move-pane -P top-left }",
"bind -Tmove -N 'Move pane to top-right corner and resize' M-2 { resize-pane -x50% -y50%; move-pane -P top-right }",
"bind -Tmove -N 'Move pane to bottom-left corner and resize' M-3 { resize-pane -x50% -y50%; move-pane -P bottom-left }",
"bind -Tmove -N 'Move pane to bottom-right corner and resize' M-4 { resize-pane -x50% -y50%; move-pane -P bottom-right }",
"bind -Tmove -N 'Move pane to top' 'Up' { move-pane -P top-centre }",
"bind -Tmove -N 'Move pane to bottom' 'Down' { move-pane -P bottom-centre }",
"bind -Tmove -N 'Move pane to left' 'Left' { move-pane -P centre-left }",
"bind -Tmove -N 'Move pane to right' 'Right' { move-pane -P centre-right }",
"bind -Tmove -N 'Move pane to top and resize' 'M-Up' { resizep -x100% -y50%; move-pane -P top-centre }",
"bind -Tmove -N 'Move pane to bottom and resize' 'M-Down' { resizep -x100% -y50%; move-pane -P bottom-centre }",
"bind -Tmove -N 'Move pane to left and resize' 'M-Left' { resizep -x50% -y100%; move-pane -P centre-left }",
"bind -Tmove -N 'Move pane to right and resize' 'M-Right' { resizep -x50% -y100%; move-pane -P centre-right }",
"bind -Tmove -N 'Move pane to fill the window' 0 { resize-pane -x100% -y100%; move-pane -P top-left }",
"bind -Tmove -N 'Display move menu' , { if -F '#{pane_floating_flag}' { display-menu -xP -yP -T '#[align=centre]Move' " DEFAULT_MOVE_MENU " } }",
"bind -Tmove -N 'Display move and resize menu' . { if -F '#{pane_floating_flag}' { display-menu -xP -yP -T '#[align=centre]Move & Resize' " DEFAULT_MOVE_RESIZE_MENU " } }",
/* Menu keys */
"bind -N 'Display window menu' < { display-menu -xW -yW -T '#[align=centre]#{window_index}:#{window_name}' " DEFAULT_WINDOW_MENU " }",
"bind -N 'Display pane menu' > { display-menu -xP -yP -T '#[align=centre]#{pane_index} (#{pane_id})' " DEFAULT_PANE_MENU " }",

View File

@@ -101,10 +101,10 @@ layout_append(struct layout_cell *lc, char *buf, size_t len)
return (0);
if (lc->wp != NULL) {
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%d,%d,%u",
lc->sx, lc->sy, lc->xoff, lc->yoff, lc->wp->id);
lc->g.sx, lc->g.sy, lc->g.xoff, lc->g.yoff, lc->wp->id);
} else {
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%d,%d",
lc->sx, lc->sy, lc->xoff, lc->yoff);
lc->g.sx, lc->g.sy, lc->g.xoff, lc->g.yoff);
}
if (tmplen > (sizeof tmp) - 1)
return (-1);
@@ -145,24 +145,24 @@ layout_check(struct layout_cell *lc)
break;
case LAYOUT_LEFTRIGHT:
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (lcchild->sy != lc->sy)
if (lcchild->g.sy != lc->g.sy)
return (0);
if (!layout_check(lcchild))
return (0);
n += lcchild->sx + 1;
n += lcchild->g.sx + 1;
}
if (n - 1 != lc->sx)
if (n - 1 != lc->g.sx)
return (0);
break;
case LAYOUT_TOPBOTTOM:
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (lcchild->sx != lc->sx)
if (lcchild->g.sx != lc->g.sx)
return (0);
if (!layout_check(lcchild))
return (0);
n += lcchild->sy + 1;
n += lcchild->g.sy + 1;
}
if (n - 1 != lc->sy)
if (n - 1 != lc->g.sy)
return (0);
break;
}
@@ -237,21 +237,21 @@ layout_parse(struct window *w, const char *layout, char **cause)
break;
case LAYOUT_LEFTRIGHT:
TAILQ_FOREACH(lcchild, &tiled_lc->cells, entry) {
sy = lcchild->sy + 1;
sx += lcchild->sx + 1;
sy = lcchild->g.sy + 1;
sx += lcchild->g.sx + 1;
}
break;
case LAYOUT_TOPBOTTOM:
TAILQ_FOREACH(lcchild, &tiled_lc->cells, entry) {
sx = lcchild->sx + 1;
sy += lcchild->sy + 1;
sx = lcchild->g.sx + 1;
sy += lcchild->g.sy + 1;
}
break;
}
if (tiled_lc->type != LAYOUT_WINDOWPANE &&
(tiled_lc->sx != sx || tiled_lc->sy != sy)) {
(tiled_lc->g.sx != sx || tiled_lc->g.sy != sy)) {
layout_print_cell(tiled_lc, __func__, 0);
tiled_lc->sx = sx - 1; tiled_lc->sy = sy - 1;
tiled_lc->g.sx = sx - 1; tiled_lc->g.sy = sy - 1;
}
/* Check the new layout. */
@@ -262,7 +262,7 @@ layout_parse(struct window *w, const char *layout, char **cause)
/* Resize window to the layout size. */
if (sx != 0 && sy != 0)
window_resize(w, tiled_lc->sx, tiled_lc->sy, -1, -1);
window_resize(w, tiled_lc->g.sx, tiled_lc->g.sy, -1, -1);
/* Destroy the old layout and swap to the new. */
layout_free_cell(w->layout_root, 0);
@@ -358,10 +358,10 @@ layout_construct_cell(struct layout_cell *lcparent, const char **layout)
}
lc = layout_create_cell(lcparent);
lc->sx = sx;
lc->sy = sy;
lc->xoff = xoff;
lc->yoff = yoff;
lc->g.sx = sx;
lc->g.sy = sy;
lc->g.xoff = xoff;
lc->g.yoff = yoff;
return (lc);
}

View File

@@ -170,8 +170,8 @@ layout_set_even(struct window *w, enum layout_type type)
TAILQ_INSERT_TAIL(&lcroot->cells, lcchild, entry);
lcchild->parent = lcroot;
if (layout_cell_is_tiled(lcchild)) {
lcchild->sx = w->sx;
lcchild->sy = w->sy;
lcchild->g.sx = w->sx;
lcchild->g.sy = w->sy;
}
}
@@ -182,7 +182,7 @@ layout_set_even(struct window *w, enum layout_type type)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
events_fire_window("window-layout-changed", w);
server_redraw_window(w);
}
@@ -291,7 +291,7 @@ layout_set_main_h(struct window *w)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
events_fire_window("window-layout-changed", w);
server_redraw_window(w);
}
@@ -388,7 +388,7 @@ layout_set_main_h_mirrored(struct window *w)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
events_fire_window("window-layout-changed", w);
server_redraw_window(w);
}
@@ -485,7 +485,7 @@ layout_set_main_v(struct window *w)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
events_fire_window("window-layout-changed", w);
server_redraw_window(w);
}
@@ -583,7 +583,7 @@ layout_set_main_v_mirrored(struct window *w)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
events_fire_window("window-layout-changed", w);
server_redraw_window(w);
}
@@ -705,7 +705,7 @@ layout_set_tiled(struct window *w)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
events_fire_window("window-layout-changed", w);
server_redraw_window(w);
}

280
layout.c
View File

@@ -56,32 +56,29 @@ static int layout_set_size_check(struct window *, struct layout_cell *,
static void layout_resize_child_cells(struct window *,
struct layout_cell *);
/* Initializes cell geometry to sentinel values. */
static void
layout_geometry_init(struct layout_geometry *lg)
{
lg->sx = UINT_MAX;
lg->sy = UINT_MAX;
lg->xoff = INT_MAX;
lg->yoff = INT_MAX;
}
/* Create a new layout cell. */
struct layout_cell *
layout_create_cell(struct layout_cell *lcparent)
{
struct layout_cell *lc;
lc = xmalloc(sizeof *lc);
lc = xcalloc(1, sizeof *lc);
lc->type = LAYOUT_WINDOWPANE;
lc->flags = 0;
lc->parent = lcparent;
TAILQ_INIT(&lc->cells);
lc->sx = UINT_MAX;
lc->sy = UINT_MAX;
lc->xoff = INT_MAX;
lc->yoff = INT_MAX;
lc->saved_sx = UINT_MAX;
lc->saved_sy = UINT_MAX;
lc->saved_xoff = INT_MAX;
lc->saved_yoff = INT_MAX;
lc->wp = NULL;
layout_geometry_init(&lc->g);
layout_geometry_init(&lc->fg);
return (lc);
}
@@ -144,8 +141,8 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
break;
}
log_debug("%s:%*s%p type %s [parent %p] wp=%p [%d,%d %ux%u]", hdr, n,
" ", lc, type, lc->parent, lc->wp, lc->xoff, lc->yoff, lc->sx,
lc->sy);
" ", lc, type, lc->parent, lc->wp, lc->g.xoff, lc->g.yoff, lc->g.sx,
lc->g.sy);
switch (lc->type) {
case LAYOUT_LEFTRIGHT:
case LAYOUT_TOPBOTTOM:
@@ -164,10 +161,10 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
struct layout_cell *lcchild, *last = NULL;
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if ((int)x >= lcchild->xoff &&
(int)x < lcchild->xoff + (int)lcchild->sx &&
(int)y >= lcchild->yoff &&
(int)y < lcchild->yoff + (int)lcchild->sy) {
if ((int)x >= lcchild->g.xoff &&
(int)x < lcchild->g.xoff + (int)lcchild->g.sx &&
(int)y >= lcchild->g.yoff &&
(int)y < lcchild->g.yoff + (int)lcchild->g.sy) {
/* Inside the cell - recurse. */
return (layout_search_by_border(lcchild, x, y));
}
@@ -179,13 +176,13 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
switch (lc->type) {
case LAYOUT_LEFTRIGHT:
if ((int)x < lcchild->xoff &&
(int)x >= last->xoff + (int)last->sx)
if ((int)x < lcchild->g.xoff &&
(int)x >= last->g.xoff + (int)last->g.sx)
return (last);
break;
case LAYOUT_TOPBOTTOM:
if ((int)y < lcchild->yoff &&
(int)y >= last->yoff + (int)last->sy)
if ((int)y < lcchild->g.yoff &&
(int)y >= last->g.yoff + (int)last->g.sy)
return (last);
break;
case LAYOUT_WINDOWPANE:
@@ -202,11 +199,11 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
void
layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, int xoff, int yoff)
{
lc->sx = sx;
lc->sy = sy;
lc->g.sx = sx;
lc->g.sy = sy;
lc->xoff = xoff;
lc->yoff = yoff;
lc->g.xoff = xoff;
lc->g.yoff = yoff;
}
/* Make a cell a leaf cell. */
@@ -331,28 +328,28 @@ layout_fix_offsets1(struct layout_cell *lc)
int xoff, yoff;
if (lc->type == LAYOUT_LEFTRIGHT) {
xoff = lc->xoff;
xoff = lc->g.xoff;
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (!layout_cell_is_tiled(lcchild) &&
!layout_cell_has_tiled_child(lcchild))
continue;
lcchild->xoff = xoff;
lcchild->yoff = lc->yoff;
lcchild->g.xoff = xoff;
lcchild->g.yoff = lc->g.yoff;
if (lcchild->type != LAYOUT_WINDOWPANE)
layout_fix_offsets1(lcchild);
xoff += lcchild->sx + 1;
xoff += lcchild->g.sx + 1;
}
} else {
yoff = lc->yoff;
yoff = lc->g.yoff;
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (!layout_cell_is_tiled(lcchild) &&
!layout_cell_has_tiled_child(lcchild))
continue;
lcchild->xoff = lc->xoff;
lcchild->yoff = yoff;
lcchild->g.xoff = lc->g.xoff;
lcchild->g.yoff = yoff;
if (lcchild->type != LAYOUT_WINDOWPANE)
layout_fix_offsets1(lcchild);
yoff += lcchild->sy + 1;
yoff += lcchild->g.sy + 1;
}
}
}
@@ -367,8 +364,8 @@ layout_fix_offsets(struct window *w)
if (lc->flags & LAYOUT_CELL_FLOATING)
return;
lc->xoff = 0;
lc->yoff = 0;
lc->g.xoff = 0;
lc->g.yoff = 0;
layout_fix_offsets1(lc);
}
@@ -452,10 +449,10 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
old_sx = wp->sx;
old_sy = wp->sy;
wp->xoff = lc->xoff;
wp->yoff = lc->yoff;
sx = lc->sx;
sy = lc->sy;
wp->xoff = lc->g.xoff;
wp->yoff = lc->g.yoff;
sx = lc->g.sx;
sy = lc->g.sy;
if (!window_pane_is_floating(wp) &&
layout_add_horizontal_border(w, lc, status)) {
@@ -536,14 +533,14 @@ layout_resize_check(struct window *w, struct layout_cell *lc,
if (lc->type == LAYOUT_WINDOWPANE) {
/* Space available in this cell only. */
if (type == LAYOUT_LEFTRIGHT) {
available = lc->sx;
available = lc->g.sx;
if (w->sb == PANE_SCROLLBARS_ALWAYS)
minimum = PANE_MINIMUM + sb_style->width +
sb_style->pad;
else
minimum = PANE_MINIMUM;
} else {
available = lc->sy;
available = lc->g.sy;
if (layout_add_horizontal_border(w, lc, status))
minimum = PANE_MINIMUM + 1;
else
@@ -585,9 +582,9 @@ layout_resize_adjust(struct window *w, struct layout_cell *lc,
/* Adjust the cell size. */
if (type == LAYOUT_LEFTRIGHT)
lc->sx += change;
lc->g.sx += change;
else
lc->sy += change;
lc->g.sy += change;
/* If this is a leaf cell, that is all that is necessary. */
if (type == LAYOUT_WINDOWPANE)
@@ -647,9 +644,9 @@ layout_resize_set_size(struct window *w, struct layout_cell *lc,
int change;
if (type == LAYOUT_LEFTRIGHT)
change = size - lc->sx;
change = size - lc->g.sx;
else
change = size - lc->sy;
change = size - lc->g.sy;
layout_resize_adjust(w, lc, type, change);
}
@@ -723,9 +720,9 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
lcother = layout_cell_get_neighbour(lc);
if (lcother != NULL) {
if (lcparent->type == LAYOUT_LEFTRIGHT)
change = lc->sx + 1;
change = lc->g.sx + 1;
else
change = lc->sy + 1;
change = lc->g.sy + 1;
layout_resize_adjust(w, lcother, lcparent->type, change);
} else
layout_remove_tile(w, lcparent);
@@ -746,8 +743,8 @@ out:
lc->parent = lcparent->parent;
if (lc->parent == NULL) {
if (layout_cell_is_tiled(lc)) {
lc->xoff = 0;
lc->yoff = 0;
lc->g.xoff = 0;
lc->g.yoff = 0;
}
*lcroot = lc;
} else
@@ -798,29 +795,29 @@ layout_resize(struct window *w, u_int sx, u_int sy)
*/
if (lc->type == LAYOUT_WINDOWPANE && (lc->flags & LAYOUT_CELL_FLOATING))
return;
xchange = sx - lc->sx;
xchange = sx - lc->g.sx;
xlimit = layout_resize_check(w, lc, LAYOUT_LEFTRIGHT);
if (xchange < 0 && xchange < -xlimit)
xchange = -xlimit;
if (xlimit == 0) {
if (sx <= lc->sx) /* lc->sx is minimum possible */
if (sx <= lc->g.sx) /* lc->g.sx is minimum possible */
xchange = 0;
else
xchange = sx - lc->sx;
xchange = sx - lc->g.sx;
}
if (xchange != 0)
layout_resize_adjust(w, lc, LAYOUT_LEFTRIGHT, xchange);
/* Adjust vertically in a similar fashion. */
ychange = sy - lc->sy;
ychange = sy - lc->g.sy;
ylimit = layout_resize_check(w, lc, LAYOUT_TOPBOTTOM);
if (ychange < 0 && ychange < -ylimit)
ychange = -ylimit;
if (ylimit == 0) {
if (sy <= lc->sy) /* lc->sy is minimum possible */
if (sy <= lc->g.sy) /* lc->g.sy is minimum possible */
ychange = 0;
else
ychange = sy - lc->sy;
ychange = sy - lc->g.sy;
}
if (ychange != 0)
layout_resize_adjust(w, lc, LAYOUT_TOPBOTTOM, ychange);
@@ -851,9 +848,9 @@ layout_resize_pane_to(struct window_pane *wp, enum layout_type type,
/* Work out the size adjustment. */
if (type == LAYOUT_LEFTRIGHT)
size = lc->sx;
size = lc->g.sx;
else
size = lc->sy;
size = lc->g.sy;
if (lc == TAILQ_LAST(&lcparent->cells, layout_cells))
change = size - new_size;
else
@@ -884,13 +881,13 @@ layout_resize_floating_pane_to(struct window_pane *wp, enum layout_type type,
}
if (type == LAYOUT_TOPBOTTOM) {
if (lc->sy == size)
if (lc->g.sy == size)
return (0);
lc->sy = size;
lc->g.sy = size;
} else {
if (lc->sx == size)
if (lc->g.sx == size)
return (0);
lc->sx = size;
lc->g.sx = size;
}
redraw_invalidate_scene(wp->window);
return (0);
@@ -912,23 +909,23 @@ layout_resize_floating_pane(struct window_pane *wp, enum layout_type type,
return (0);
if (type == LAYOUT_TOPBOTTOM) {
size = lc->sy + change;
size = lc->g.sy + change;
if (size < PANE_MINIMUM || size > PANE_MAXIMUM) {
*cause = xstrdup("change is too big or too small");
return (-1);
}
lc->sy = size;
lc->g.sy = size;
if (opposite)
lc->yoff -= change;
lc->g.yoff -= change;
} else {
size = lc->sx + change;
size = lc->g.sx + change;
if (size < PANE_MINIMUM || size > PANE_MAXIMUM) {
*cause = xstrdup("change is too big or too small");
return (-1);
}
lc->sx = size;
lc->g.sx = size;
if (opposite)
lc->xoff -= change;
lc->g.xoff -= change;
}
redraw_invalidate_scene(wp->window);
return (0);
@@ -1094,13 +1091,13 @@ layout_new_pane_size(struct window *w, u_int previous, struct layout_cell *lc,
*/
min = (PANE_MINIMUM + 1) * (count_left - 1);
if (type == LAYOUT_LEFTRIGHT) {
if (lc->sx - available > min)
min = lc->sx - available;
new_size = (lc->sx * size) / previous;
if (lc->g.sx - available > min)
min = lc->g.sx - available;
new_size = (lc->g.sx * size) / previous;
} else {
if (lc->sy - available > min)
min = lc->sy - available;
new_size = (lc->sy * size) / previous;
if (lc->g.sy - available > min)
min = lc->g.sy - available;
new_size = (lc->g.sy * size) / previous;
}
/* Check against the maximum and minimum size. */
@@ -1136,9 +1133,9 @@ layout_set_size_check(struct window *w, struct layout_cell *lc,
return (0);
if (type == LAYOUT_LEFTRIGHT)
previous = lc->sx;
previous = lc->g.sx;
else
previous = lc->sy;
previous = lc->g.sy;
idx = 0;
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
@@ -1174,32 +1171,32 @@ static void
layout_resize_child_cells(struct window *w, struct layout_cell *lc)
{
struct layout_cell *lcchild;
u_int previous, available, count, idx;
u_int prev, available, count, idx;
if (lc->type == LAYOUT_WINDOWPANE)
return;
/* What is the current size used? */
count = 0;
previous = 0;
prev = 0;
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (!layout_cell_is_tiled(lcchild) &&
!layout_cell_has_tiled_child(lcchild))
continue;
count++;
if (lc->type == LAYOUT_LEFTRIGHT)
previous += lcchild->sx;
prev += lcchild->g.sx;
else if (lc->type == LAYOUT_TOPBOTTOM)
previous += lcchild->sy;
prev += lcchild->g.sy;
}
previous += (count - 1);
prev += (count - 1);
/* And how much is available? */
available = 0;
if (lc->type == LAYOUT_LEFTRIGHT)
available = lc->sx;
available = lc->g.sx;
else if (lc->type == LAYOUT_TOPBOTTOM)
available = lc->sy;
available = lc->g.sy;
/* Resize children into the new size. */
idx = 0;
@@ -1208,20 +1205,20 @@ layout_resize_child_cells(struct window *w, struct layout_cell *lc)
!layout_cell_has_tiled_child(lcchild))
continue;
if (lc->type == LAYOUT_TOPBOTTOM) {
lcchild->sx = lc->sx;
lcchild->xoff = lc->xoff;
lcchild->g.sx = lc->g.sx;
lcchild->g.xoff = lc->g.xoff;
} else {
lcchild->sx = layout_new_pane_size(w, previous, lcchild,
lc->type, lc->sx, count - idx, available);
available -= (lcchild->sx + 1);
lcchild->g.sx = layout_new_pane_size(w, prev, lcchild,
lc->type, lc->g.sx, count - idx, available);
available -= (lcchild->g.sx + 1);
}
if (lc->type == LAYOUT_LEFTRIGHT) {
lcchild->sy = lc->sy;
lcchild->yoff = lc->yoff;
lcchild->g.sy = lc->g.sy;
lcchild->g.yoff = lc->g.yoff;
} else {
lcchild->sy = layout_new_pane_size(w, previous, lcchild,
lc->type, lc->sy, count - idx, available);
available -= (lcchild->sy + 1);
lcchild->g.sy = layout_new_pane_size(w, prev, lcchild,
lc->type, lc->g.sy, count - idx, available);
available -= (lcchild->g.sy + 1);
}
layout_resize_child_cells(w, lcchild);
idx++;
@@ -1241,7 +1238,7 @@ layout_replace_with_node(struct window *w, struct layout_cell *lc,
lcparent = layout_create_cell(lc->parent);
layout_make_node(lcparent, type);
layout_set_size(lcparent, lc->sx, lc->sy, lc->xoff, lc->yoff);
layout_set_size(lcparent, lc->g.sx, lc->g.sy, lc->g.xoff, lc->g.yoff);
if (lc->parent == NULL)
w->layout_root = lcparent;
else
@@ -1260,7 +1257,7 @@ layout_split_check_space(struct window_pane *wp, struct layout_cell *lc,
enum layout_type type)
{
struct style *sb_style = &wp->scrollbar_style;
u_int minimum, sx = lc->sx, sy = lc->sy;
u_int minimum, sx = lc->g.sx, sy = lc->g.sy;
int status;
if (lc->flags & LAYOUT_CELL_FLOATING)
@@ -1299,7 +1296,7 @@ layout_split_sizes(struct layout_cell *lc, int size, int before,
enum layout_type type, u_int *size1, u_int *size2, u_int *saved_size)
{
u_int s1, s2, ss;
u_int sx = lc->sx, sy = lc->sy;
u_int sx = lc->g.sx, sy = lc->g.sy;
if (type == LAYOUT_LEFTRIGHT)
ss = sx;
@@ -1346,10 +1343,10 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
lc = wp->layout_cell;
/* Copy the old cell size. */
sx = lc->sx;
sy = lc->sy;
xoff = lc->xoff;
yoff = lc->yoff;
sx = lc->g.sx;
sy = lc->g.sy;
xoff = lc->g.xoff;
yoff = lc->g.yoff;
/* Check there is enough space for the two new panes. */
if (!layout_split_check_space(wp, lc, type))
@@ -1390,13 +1387,13 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
* must be resized before inserting the new cell.
*/
if (lc->type == LAYOUT_LEFTRIGHT) {
lc->sx = new_size;
lc->g.sx = new_size;
layout_resize_child_cells(wp->window, lc);
lc->sx = saved_size;
lc->g.sx = saved_size;
} else if (lc->type == LAYOUT_TOPBOTTOM) {
lc->sy = new_size;
lc->g.sy = new_size;
layout_resize_child_cells(wp->window, lc);
lc->sy = saved_size;
lc->g.sy = saved_size;
}
resize_first = 1;
@@ -1440,10 +1437,10 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
*/
if (!resize_first && type == LAYOUT_LEFTRIGHT) {
layout_set_size(lc1, size1, sy, xoff, yoff);
layout_set_size(lc2, size2, sy, xoff + lc1->sx + 1, yoff);
layout_set_size(lc2, size2, sy, xoff + lc1->g.sx + 1, yoff);
} else if (!resize_first && type == LAYOUT_TOPBOTTOM) {
layout_set_size(lc1, sx, size1, xoff, yoff);
layout_set_size(lc2, sx, size2, xoff, yoff + lc1->sy + 1);
layout_set_size(lc2, sx, size2, xoff, yoff + lc1->g.sy + 1);
}
if (full_size) {
if (!resize_first)
@@ -1460,8 +1457,8 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
* layout_assign_pane before much else happens!
*/
struct layout_cell *
layout_floating_pane(struct window *w, struct window_pane *wp, u_int sx,
u_int sy, int ox, int oy)
layout_floating_pane(struct window *w, struct window_pane *wp,
struct layout_geometry *lg)
{
struct layout_cell *lc, *lcnew, *lcparent;
@@ -1473,16 +1470,16 @@ layout_floating_pane(struct window *w, struct window_pane *wp, u_int sx,
if (lcparent == NULL) {
/*
* Adding a pane to a root that isn't node. Must create and
* insert a new root.
*/
* Adding a pane to a root that isn't a node. Must create and
* insert a new root.
*/
lcparent = layout_replace_with_node(w, lc, LAYOUT_TOPBOTTOM);
}
lcnew = layout_create_cell(lcparent);
TAILQ_INSERT_AFTER(&lcparent->cells, lc, lcnew, entry);
lcnew->flags |= LAYOUT_CELL_FLOATING;
layout_set_size(lcnew, sx, sy, ox, oy);
layout_set_size(lcnew, lg->sx, lg->sy, lg->xoff, lg->yoff);
return (lcnew);
}
@@ -1525,12 +1522,12 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
status = window_get_pane_status(w);
if (parent->type == LAYOUT_LEFTRIGHT)
size = parent->sx;
size = parent->g.sx;
else if (parent->type == LAYOUT_TOPBOTTOM) {
if (layout_add_horizontal_border(w, parent, status))
size = parent->sy - 1;
size = parent->g.sy - 1;
else
size = parent->sy;
size = parent->g.sy;
} else
return (0);
if (size < number - 1)
@@ -1551,7 +1548,7 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
continue;
change = 0;
if (parent->type == LAYOUT_LEFTRIGHT) {
change = each - (int)lc->sx;
change = each - (int)lc->g.sx;
if (remainder > 0) {
change++;
remainder--;
@@ -1566,7 +1563,7 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
this++;
remainder--;
}
change = this - (int)lc->sy;
change = this - (int)lc->g.sy;
layout_resize_adjust(w, lc, LAYOUT_TOPBOTTOM, change);
}
if (change != 0)
@@ -1663,30 +1660,29 @@ layout_get_floating_cell(struct cmdq_item *item, struct args *args,
char **cause)
{
struct layout_cell *lcnew;
u_int sx = UINT_MAX, sy = UINT_MAX;
int ox = INT_MAX, oy = INT_MAX;
struct layout_geometry fg;
if (layout_floating_args_parse(item, args, lines, w, &sx, &sy, &ox, &oy,
cause) != 0)
layout_geometry_init(&fg);
if (layout_floating_args_parse(item, args, lines, w, &fg, cause) != 0)
return (NULL);
window_push_zoom(wp->window, 1, args_has(args, 'Z'));
lcnew = layout_floating_pane(w, wp, sx, sy, ox, oy);
lcnew = layout_floating_pane(w, wp, &fg);
return (lcnew);
}
int
layout_floating_args_parse(struct cmdq_item *item, struct args *args,
enum pane_lines lines, struct window *w, u_int *sxp, u_int *syp, int *oxp,
int *oyp, char **cause)
enum pane_lines lines, struct window *w, struct layout_geometry *lg,
char **cause)
{
int sx, sy, ox, oy;
char *error = NULL;
sx = *sxp == UINT_MAX ? w->sx / 2 : *sxp;
sy = *syp == UINT_MAX ? w->sy / 4 : *syp;
ox = *oxp == INT_MAX ? INT_MAX : *oxp;
oy = *oyp == INT_MAX ? INT_MAX : *oyp;
sx = lg->sx == UINT_MAX ? w->sx / 2 : lg->sx;
sy = lg->sy == UINT_MAX ? w->sy / 4 : lg->sy;
ox = lg->xoff;
oy = lg->yoff;
if (args_has(args, 'x')) {
sx = args_percentage_and_expand(args, 'x', 0, PANE_MAXIMUM,
@@ -1763,10 +1759,10 @@ layout_floating_args_parse(struct cmdq_item *item, struct args *args,
return (-1);
}
*sxp = sx;
*syp = sy;
*oxp = ox;
*oyp = oy;
lg->sx = sx;
lg->sy = sy;
lg->xoff = ox;
lg->yoff = oy;
return (0);
}
@@ -1795,9 +1791,9 @@ layout_remove_tile(struct window *w, struct layout_cell *lc)
* neighbour.
*/
if (type == LAYOUT_TOPBOTTOM)
change = lc->sy + 1;
change = lc->g.sy + 1;
else
change = lc->sx + 1;
change = lc->g.sx + 1;
layout_resize_adjust(w, lcneighbour, type, change);
}
@@ -1843,9 +1839,9 @@ layout_insert_tile(struct window *w, struct layout_cell *lc)
*/
layout_insert_tile(w, lcparent);
if (type == LAYOUT_LEFTRIGHT)
size1 = lcparent->sx;
size1 = lcparent->g.sx;
else
size1 = lcparent->sy;
size1 = lcparent->g.sy;
layout_resize_set_size(w, lc, type, size1);
} else {
/*
@@ -1863,10 +1859,10 @@ layout_insert_tile(struct window *w, struct layout_cell *lc)
/* Setting opposite of the 'split' size to that of the parent. */
if (lcparent->type == LAYOUT_LEFTRIGHT) {
size1 = lcparent->sy;
size1 = lcparent->g.sy;
type = LAYOUT_TOPBOTTOM;
} else {
size1 = lcparent->sx;
size1 = lcparent->g.sx;
type = LAYOUT_LEFTRIGHT;
}
layout_resize_set_size(w, lc, type, size1);

17
menu.c
View File

@@ -313,6 +313,7 @@ menu_key_cb(struct client *c, void *data, struct key_event *event)
struct mouse_event *m = &event->m;
u_int i;
int count = menu->count, old = md->choice;
int move;
const char *name = NULL;
const struct menu_item *item;
struct cmdq_state *state;
@@ -320,6 +321,14 @@ menu_key_cb(struct client *c, void *data, struct key_event *event)
char *error;
if (KEYC_IS_MOUSE(event->key)) {
/*
* A mouse move with no button held reports as a release, so
* treat it as highlight-only: it must never select or close the
* menu, otherwise a menu opened without a button already down
* (such as a submenu opened from another menu) would vanish as
* soon as the mouse moved over it.
*/
move = MOUSE_DRAG(m->b) && MOUSE_RELEASE(m->b);
if (md->flags & MENU_NOMOUSE) {
if (MOUSE_BUTTONS(m->b) != MOUSE_BUTTON_1)
return (1);
@@ -330,7 +339,7 @@ menu_key_cb(struct client *c, void *data, struct key_event *event)
m->y < md->py + 1 ||
m->y > md->py + 1 + count - 1) {
if (~md->flags & MENU_STAYOPEN) {
if (MOUSE_RELEASE(m->b))
if (!move && MOUSE_RELEASE(m->b))
return (1);
} else {
if (!MOUSE_RELEASE(m->b) &&
@@ -345,7 +354,7 @@ menu_key_cb(struct client *c, void *data, struct key_event *event)
return (0);
}
if (~md->flags & MENU_STAYOPEN) {
if (MOUSE_RELEASE(m->b))
if (!move && MOUSE_RELEASE(m->b))
goto chosen;
} else {
if (!MOUSE_WHEEL(m->b) && !MOUSE_DRAG(m->b))
@@ -558,6 +567,10 @@ menu_prepare(struct menu *menu, int flags, int starting_choice,
if (py + menu->count + 2 > c->tty.sy)
py = c->tty.sy - menu->count - 2;
/* Remember where this menu is so -x/-y L can reuse the position. */
c->menu_last_px = px;
c->menu_last_py = py;
if (lines == BOX_LINES_DEFAULT)
lines = options_get_number(o, "menu-border-lines");

View File

@@ -667,7 +667,7 @@ options_array_first(struct options_entry *o)
struct options_array_item *
options_array_next(struct options_array_item *a)
{
return (RB_NEXT(options_array, &o->value.array, a));
return (RB_NEXT(options_array, , a));
}
const char *

View File

@@ -46,13 +46,13 @@ resize_window(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
layout_resize(w, sx, sy);
/* Resize the window, it can be no smaller than the layout. */
if (sx < w->layout_root->sx)
sx = w->layout_root->sx;
if (sy < w->layout_root->sy)
sy = w->layout_root->sy;
if (sx < w->layout_root->g.sx)
sx = w->layout_root->g.sx;
if (sy < w->layout_root->g.sy)
sy = w->layout_root->g.sy;
window_resize(w, sx, sy, xpixel, ypixel);
log_debug("%s: @%u resized to %ux%u; layout %ux%u", __func__, w->id,
sx, sy, w->layout_root->sx, w->layout_root->sy);
sx, sy, w->layout_root->g.sx, w->layout_root->g.sy);
/* Restore the window zoom state. */
if (zoomed)

12
spawn.c
View File

@@ -632,13 +632,13 @@ spawn_editor(struct client *c, const char *buf, size_t len,
struct window *w = wl->window;
struct window_pane *wp;
struct layout_cell *lc;
struct layout_geometry lg;
struct environ *env;
FILE *f;
char *cmd, *cause = NULL;
char path[] = _PATH_TMP "tmux.XXXXXXXX";
const char *editor;
int fd;
u_int px, py, sx, sy;
editor = options_get_string(global_options, "editor");
fd = mkstemp(path);
@@ -662,12 +662,12 @@ spawn_editor(struct client *c, const char *buf, size_t len,
es->cb = cb;
es->arg = arg;
sx = w->sx * 9 / 10;
sy = w->sy * 9 / 10;
px = w->sx / 2 - sx / 2;
py = w->sy / 2 - sy / 2;
lg.sx = w->sx * 9 / 10;
lg.sy = w->sy * 9 / 10;
lg.xoff = w->sx / 2 - lg.sx / 2;
lg.yoff = w->sy / 2 - lg.sy / 2;
window_push_zoom(w, 1, 0);
lc = layout_floating_pane(w, NULL, sx, sy, px, py);
lc = layout_floating_pane(w, NULL, &lg);
if (lc == NULL) {
spawn_editor_free(es);
return (NULL);

15
tmux.1
View File

@@ -365,13 +365,13 @@ Toggle zoom state of the current pane.
.It Tab
Choose a new window and session by fuzzy matching.
.It {
Move floating pane to top-left corner.
Swap the current pane with the previous pane.
.It }
Move floating pane to top-right corner.
.It M-{
Move floating pane to bottom-left corner.
.It M-}
Move floating pane to bottom-right corner.
Swap the current pane with the next pane.
.It g 1, 2, 3, 4
.It g Up, Down, Left, Right
Move floating pane to corners or edges.
Meta resizes the pane as well.
.It \[ti]
Show previous messages from
.Nm ,
@@ -7959,6 +7959,7 @@ Both may be a row or column number, or one of the following special values:
.It Li "R" Ta Fl x Ta "The right side of the terminal"
.It Li "P" Ta "Both" Ta "The bottom left of the pane"
.It Li "M" Ta "Both" Ta "The mouse position"
.It Li "L" Ta "Both" Ta "The position of the last menu"
.It Li "W" Ta "Both" Ta "The window position on the status line"
.It Li "S" Ta Fl y Ta "The line above or below the status line"
.El
@@ -7969,6 +7970,8 @@ Or a format, which is expanded including the following additional variables:
.It Li "popup_centre_x" Ta "Centered in the client"
.It Li "popup_centre_y" Ta "Centered in the client"
.It Li "popup_height" Ta "Height of menu or popup"
.It Li "popup_last_x" Ta "Left of the last menu"
.It Li "popup_last_y" Ta "Bottom of the last menu"
.It Li "popup_mouse_bottom" Ta "Bottom of at the mouse"
.It Li "popup_mouse_centre_x" Ta "Horizontal centre at the mouse"
.It Li "popup_mouse_centre_y" Ta "Vertical centre at the mouse"

44
tmux.h
View File

@@ -1508,32 +1508,31 @@ enum layout_type {
LAYOUT_WINDOWPANE
};
/* Layout cell sizes and position. */
struct layout_geometry {
u_int sx;
u_int sy;
int xoff;
int yoff;
};
/* Layout cells queue. */
TAILQ_HEAD(layout_cells, layout_cell);
/* Layout cell. */
struct layout_cell {
enum layout_type type;
enum layout_type type;
int flags;
#define LAYOUT_CELL_FLOATING 0x1
int flags;
struct layout_cell *parent;
struct layout_cell *parent;
u_int sx;
u_int sy;
struct layout_geometry g;
struct layout_geometry fg; /* saved floating pane */
int xoff;
int yoff;
u_int saved_sx;
u_int saved_sy;
int saved_xoff;
int saved_yoff;
struct window_pane *wp;
struct layout_cells cells;
struct window_pane *wp;
struct layout_cells cells;
TAILQ_ENTRY(layout_cell) entry;
};
@@ -2313,6 +2312,9 @@ struct client {
void *overlay_data;
struct event overlay_timer;
u_int menu_last_px;
u_int menu_last_py;
struct client_files files;
u_int source_file_depth;
@@ -3786,7 +3788,7 @@ void layout_destroy_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);
void layout_set_size(struct layout_cell *, u_int, u_int, int, int);
void layout_set_size(struct layout_cell *, u_int, u_int, int, int);
void layout_make_leaf(struct layout_cell *, struct window_pane *);
void layout_make_node(struct layout_cell *, enum layout_type);
void layout_fix_zindexes(struct window *, struct layout_cell *);
@@ -3820,7 +3822,7 @@ struct layout_cell *layout_replace_with_node(struct window *,
struct layout_cell *layout_split_pane(struct window_pane *, enum layout_type,
int, int);
struct layout_cell *layout_floating_pane(struct window *, struct window_pane *,
u_int, u_int, int, int);
struct layout_geometry *);
void layout_close_pane(struct window_pane *);
int layout_spread_cell(struct window *, struct layout_cell *);
void layout_spread_out(struct window_pane *);
@@ -3828,10 +3830,10 @@ struct layout_cell *layout_get_tiled_cell(struct cmdq_item *, struct args *,
struct window *, struct window_pane *, int, char **);
struct layout_cell *layout_get_floating_cell(struct cmdq_item *, struct args *,
enum pane_lines, struct window *, struct window_pane *,
char **cause);
char **);
int layout_floating_args_parse(struct cmdq_item *, struct args *,
enum pane_lines, struct window *, u_int *, u_int *, int *,
int *, char **);
enum pane_lines, struct window *, struct layout_geometry *,
char **);
int layout_remove_tile(struct window *, struct layout_cell *);
int layout_insert_tile(struct window *, struct layout_cell *);

View File

@@ -368,6 +368,8 @@ window_create(u_int sx, u_int sy, u_int xpixel, u_int ypixel)
w->ypixel = ypixel;
w->options = options_create(global_w_options);
w->sb = options_get_number(w->options, "pane-scrollbars");
w->sb_pos = options_get_number(w->options, "pane-scrollbars-position");
w->references = 0;
TAILQ_INIT(&w->winlinks);