mirror of
https://github.com/tmux/tmux.git
synced 2026-08-23 23:21:36 +00:00
Add a way for floating panes to stay above zoom (-A) flag. Use by
default for modal panes to match popups.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cmd-select-pane.c,v 1.77 2026/07/17 12:42:51 nicm Exp $ */
|
||||
/* $OpenBSD: cmd-select-pane.c,v 1.78 2026/08/20 09:19:24 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -160,6 +160,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
char *title;
|
||||
const char *style;
|
||||
struct options_entry *o;
|
||||
int visible, Zflag = args_has(args, 'Z');
|
||||
|
||||
if (entry == &cmd_last_pane_entry || args_has(args, 'l')) {
|
||||
/*
|
||||
@@ -185,14 +186,18 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
server_redraw_window_borders(lastwp->window);
|
||||
server_status_window(lastwp->window);
|
||||
} else {
|
||||
if (window_push_zoom(w, 0, args_has(args, 'Z')))
|
||||
if (w->modal != NULL && lastwp != w->modal)
|
||||
visible = 1;
|
||||
else
|
||||
visible = window_pane_is_visible(lastwp);
|
||||
if (!visible && window_push_zoom(w, 0, Zflag))
|
||||
server_redraw_window(w);
|
||||
window_redraw_active_switch(w, lastwp);
|
||||
if (window_set_active_pane(w, lastwp, 1)) {
|
||||
cmd_find_from_winlink(current, wl, 0);
|
||||
cmd_select_pane_redraw(w);
|
||||
}
|
||||
if (window_pop_zoom(w))
|
||||
if (!visible && window_pop_zoom(w))
|
||||
server_redraw_window(w);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
@@ -268,14 +273,18 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
|
||||
if (wp == w->active)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
if (window_push_zoom(w, 0, args_has(args, 'Z')))
|
||||
if (w->modal != NULL && wp != w->modal)
|
||||
visible = 1;
|
||||
else
|
||||
visible = window_pane_is_visible(wp);
|
||||
if (!visible && window_push_zoom(w, 0, Zflag))
|
||||
server_redraw_window(w);
|
||||
window_redraw_active_switch(w, wp);
|
||||
if (window_set_active_pane(w, wp, 1))
|
||||
cmd_find_from_winlink_pane(current, wl, wp, 0);
|
||||
cmdq_insert_hook(s, item, current, "after-select-pane");
|
||||
cmd_select_pane_redraw(w);
|
||||
if (window_pop_zoom(w))
|
||||
if (!visible && window_pop_zoom(w))
|
||||
server_redraw_window(w);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cmd-split-window.c,v 1.149 2026/08/19 10:56:10 nicm Exp $ */
|
||||
/* $OpenBSD: cmd-split-window.c,v 1.150 2026/08/20 09:19:24 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -41,8 +41,8 @@ const struct cmd_entry cmd_new_pane_entry = {
|
||||
.name = "new-pane",
|
||||
.alias = "newp",
|
||||
|
||||
.args = { "bB:Cc:de:EfF:hIkl:KLMm:Op:PR:s:S:t:T:vWx:X:y:Y:Z", 0, -1, NULL },
|
||||
.usage = "[-bCdefhIkKLMOPvWZ] [-B border-lines] "
|
||||
.args = { "AbB:Cc:de:EfF:hIkl:KLMm:Op:PR:s:S:t:T:vWx:X:y:Y:Z", 0, -1, NULL },
|
||||
.usage = "[-AbCdefhIkKLMOPvWZ] [-B border-lines] "
|
||||
"[-c start-directory] [-e environment] "
|
||||
"[-F format] [-l size] [-m message] [-p percentage] "
|
||||
"[-s style] [-S active-border-style] "
|
||||
@@ -90,6 +90,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
struct cmd_find_state fs;
|
||||
struct key_event *event = cmdq_get_event(item);
|
||||
int input, empty, is_floating, flags = 0;
|
||||
int restore_zoom = 0;
|
||||
const char *template, *style, *value;
|
||||
char *cause = NULL, *cp, *title;
|
||||
const struct options_table_entry *oe;
|
||||
@@ -97,10 +98,16 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
enum pane_lines lines;
|
||||
u_int count = args_count(args);
|
||||
|
||||
if (window_active_pane_is_over_zoom(w))
|
||||
restore_zoom = 1;
|
||||
|
||||
if (cmd_get_entry(self) == &cmd_new_pane_entry)
|
||||
is_floating = !args_has(args, 'L');
|
||||
else {
|
||||
window_unzoom(w, 1);
|
||||
if (!window_pane_is_visible(wp))
|
||||
restore_zoom = 0;
|
||||
if (!restore_zoom)
|
||||
window_unzoom(w, 1);
|
||||
is_floating = window_pane_is_floating(wp);
|
||||
flags |= SPAWN_SPLIT;
|
||||
}
|
||||
@@ -134,7 +141,11 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (args_has(args, 'Z'))
|
||||
flags |= SPAWN_ZOOM;
|
||||
if (args_has(args, 'O'))
|
||||
flags |= SPAWN_MODAL;
|
||||
flags |= SPAWN_MODAL|SPAWN_FLOATOVERZOOM;
|
||||
if (is_floating && args_has(args, 'A'))
|
||||
flags |= SPAWN_FLOATOVERZOOM;
|
||||
if ((w->flags & WINDOW_ZOOMED) && (flags & SPAWN_FLOATOVERZOOM))
|
||||
restore_zoom = 1;
|
||||
|
||||
input = args_has(args, 'I');
|
||||
if (input || (count == 1 && *args_string(args, 0) == '\0'))
|
||||
@@ -170,6 +181,8 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (cause != NULL) {
|
||||
cmdq_error(item, "%s", cause);
|
||||
free(cause);
|
||||
if (restore_zoom)
|
||||
window_pop_zoom(w);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
@@ -274,7 +287,10 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (~flags & SPAWN_DETACHED)
|
||||
cmd_find_from_winlink_pane(current, wl, new_wp, 0);
|
||||
|
||||
if ((~flags & SPAWN_FLOATING) && !args_has(args, 'O')) {
|
||||
if (restore_zoom) {
|
||||
window_pop_zoom(wp->window);
|
||||
server_redraw_window(wp->window);
|
||||
} else if ((~flags & SPAWN_FLOATING) && !args_has(args, 'O')) {
|
||||
window_pop_zoom(wp->window);
|
||||
server_redraw_window(wp->window);
|
||||
}
|
||||
@@ -325,8 +341,9 @@ fail:
|
||||
if (!is_floating)
|
||||
layout_close_pane(new_wp);
|
||||
window_remove_pane(wp->window, new_wp);
|
||||
} else if (args_has(args, 'O'))
|
||||
window_pop_modal_zoom(wp->window);
|
||||
}
|
||||
if (restore_zoom || (~flags & SPAWN_FLOATING))
|
||||
window_pop_zoom(wp->window);
|
||||
if (sc.argv != NULL)
|
||||
cmd_free_argv(sc.argc, sc.argv);
|
||||
environ_free(sc.environ);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cmd-switch-client.c,v 1.74 2026/05/22 15:22:43 nicm Exp $ */
|
||||
/* $OpenBSD: cmd-switch-client.c,v 1.75 2026/08/20 09:19:24 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -53,7 +53,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
|
||||
struct cmd_find_state target;
|
||||
const char *tflag = args_get(args, 't');
|
||||
enum cmd_find_type type;
|
||||
int flags;
|
||||
int flags, visible, Zflag = args_has(args, 'Z');
|
||||
struct client *c = cmdq_get_client(item);
|
||||
struct client *tc = cmdq_get_target_client(item);
|
||||
struct session *s;
|
||||
@@ -139,11 +139,15 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
if (wl != NULL && wp != NULL && wp != wl->window->active) {
|
||||
w = wl->window;
|
||||
if (window_push_zoom(w, 0, args_has(args, 'Z')))
|
||||
if (w->modal != NULL && wp != w->modal)
|
||||
visible = 1;
|
||||
else
|
||||
visible = window_pane_is_visible(wp);
|
||||
if (!visible && window_push_zoom(w, 0, Zflag))
|
||||
server_redraw_window(w);
|
||||
window_redraw_active_switch(w, wp);
|
||||
window_set_active_pane(w, wp, 1);
|
||||
if (window_pop_zoom(w))
|
||||
if (!visible && window_pop_zoom(w))
|
||||
server_redraw_window(w);
|
||||
}
|
||||
if (wl != NULL) {
|
||||
|
||||
13
layout.c
13
layout.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: layout.c,v 1.96 2026/07/15 13:02:33 nicm Exp $ */
|
||||
/* $OpenBSD: layout.c,v 1.97 2026/08/20 09:19:24 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -1650,7 +1650,10 @@ layout_get_tiled_cell(struct cmdq_item *item, struct args *args,
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
window_push_zoom(wp->window, 1, (flags & SPAWN_ZOOM));
|
||||
if (window_active_pane_is_over_zoom(w))
|
||||
window_push_zoom(w, 0, 1);
|
||||
else
|
||||
window_push_zoom(w, 1, (flags & SPAWN_ZOOM));
|
||||
lc = layout_split_pane(wp, type, size, flags);
|
||||
if (lc == NULL)
|
||||
*cause = xstrdup("no space for a new pane");
|
||||
@@ -1677,8 +1680,10 @@ layout_get_floating_cell(struct cmdq_item *item, struct args *args,
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (flags & SPAWN_MODAL)
|
||||
window_push_modal_zoom(w);
|
||||
if (flags & SPAWN_FLOATOVERZOOM)
|
||||
window_push_zoom(wp->window, 0, 1);
|
||||
else if (window_active_pane_is_over_zoom(w))
|
||||
window_push_zoom(wp->window, 0, 1);
|
||||
else
|
||||
window_push_zoom(wp->window, 1, (flags & SPAWN_ZOOM));
|
||||
lcnew = layout_floating_pane(w, wp, &fg);
|
||||
|
||||
14
resize.c
14
resize.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: resize.c,v 1.58 2026/07/17 08:37:29 nicm Exp $ */
|
||||
/* $OpenBSD: resize.c,v 1.59 2026/08/20 09:19:24 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -42,8 +42,8 @@ resize_fire_window_resized(struct window *w, u_int old_sx, u_int old_sy)
|
||||
void
|
||||
resize_window(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
|
||||
{
|
||||
u_int old_sx = w->sx, old_sy = w->sy;
|
||||
int zoomed;
|
||||
struct window_pane *zwp;
|
||||
u_int old_sx = w->sx, old_sy = w->sy;
|
||||
|
||||
/* Check size limits. */
|
||||
if (sx < WINDOW_MINIMUM)
|
||||
@@ -56,8 +56,8 @@ resize_window(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
|
||||
sy = WINDOW_MAXIMUM;
|
||||
|
||||
/* If the window is zoomed, unzoom. */
|
||||
zoomed = w->flags & WINDOW_ZOOMED;
|
||||
if (zoomed)
|
||||
zwp = window_zoomed_pane(w);
|
||||
if (zwp != NULL)
|
||||
window_unzoom(w, 1);
|
||||
|
||||
/* Resize the layout first. */
|
||||
@@ -73,8 +73,8 @@ resize_window(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
|
||||
sx, sy, w->layout_root->g.sx, w->layout_root->g.sy);
|
||||
|
||||
/* Restore the window zoom state. */
|
||||
if (zoomed)
|
||||
window_zoom(w->active);
|
||||
if (zwp != NULL && window_has_pane(w, zwp))
|
||||
window_zoom(zwp);
|
||||
|
||||
tty_update_window_offset(w);
|
||||
server_redraw_window(w);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: server-client.c,v 1.504 2026/08/19 10:56:10 nicm Exp $ */
|
||||
/* $OpenBSD: server-client.c,v 1.505 2026/08/20 09:19:24 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -806,8 +806,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
|
||||
} else {
|
||||
/* Try the pane borders. */
|
||||
TAILQ_FOREACH(fwp, &w->panes, entry) {
|
||||
if ((w->flags & WINDOW_ZOOMED) &&
|
||||
(~fwp->flags & PANE_ZOOMED))
|
||||
if (!window_pane_is_visible(fwp))
|
||||
continue;
|
||||
if (window_pane_is_floating(fwp) &&
|
||||
window_pane_get_pane_lines(fwp) == PANE_LINES_NONE)
|
||||
|
||||
11
server-fn.c
11
server-fn.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: server-fn.c,v 1.150 2026/08/18 07:32:09 nicm Exp $ */
|
||||
/* $OpenBSD: server-fn.c,v 1.151 2026/08/20 09:19:24 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -227,10 +227,11 @@ server_kill_pane(struct window_pane *wp)
|
||||
server_kill_window(w, 1);
|
||||
recalculate_sizes();
|
||||
} else {
|
||||
server_unzoom_window(w);
|
||||
window_push_zoom(w, 0, wp->flags & PANE_FLOATOVERZOOM);
|
||||
server_client_remove_pane(wp);
|
||||
layout_close_pane(wp);
|
||||
window_remove_pane(w, wp);
|
||||
window_pop_zoom(w);
|
||||
server_redraw_window(w);
|
||||
}
|
||||
}
|
||||
@@ -418,15 +419,17 @@ server_destroy_pane(struct window_pane *wp, int notify)
|
||||
if (notify)
|
||||
server_fire_pane_exit("pane-exited", wp);
|
||||
|
||||
server_unzoom_window(w);
|
||||
window_push_zoom(w, 0, wp->flags & PANE_FLOATOVERZOOM);
|
||||
server_client_remove_pane(wp);
|
||||
layout_close_pane(wp);
|
||||
window_remove_pane(w, wp);
|
||||
|
||||
if (TAILQ_EMPTY(&w->panes))
|
||||
server_kill_window(w, 1);
|
||||
else
|
||||
else {
|
||||
window_pop_zoom(w);
|
||||
server_redraw_window(w);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
13
spawn.c
13
spawn.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: spawn.c,v 1.51 2026/08/18 07:43:44 nicm Exp $ */
|
||||
/* $OpenBSD: spawn.c,v 1.52 2026/08/20 09:19:24 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -362,6 +362,8 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
}
|
||||
if (sc->flags & SPAWN_FLOATING)
|
||||
new_wp->layout_cell->flags |= LAYOUT_CELL_FLOATING;
|
||||
if (sc->flags & SPAWN_FLOATOVERZOOM)
|
||||
new_wp->flags |= PANE_FLOATOVERZOOM;
|
||||
|
||||
/*
|
||||
* If window currently zoomed, window_set_active_pane calls
|
||||
@@ -725,10 +727,10 @@ spawn_editor(struct client *c, const char *buf, size_t len,
|
||||
lg.sy = w->sy * 9 / 10;
|
||||
lg.xoff = w->sx / 2 - lg.sx / 2;
|
||||
lg.yoff = w->sy / 2 - lg.sy / 2;
|
||||
window_push_modal_zoom(w);
|
||||
window_push_zoom(w, 0, 1);
|
||||
lc = layout_floating_pane(w, NULL, &lg);
|
||||
if (lc == NULL) {
|
||||
window_pop_modal_zoom(w);
|
||||
window_pop_zoom(w);
|
||||
spawn_editor_free(es);
|
||||
return (NULL);
|
||||
}
|
||||
@@ -745,17 +747,18 @@ spawn_editor(struct client *c, const char *buf, size_t len,
|
||||
sc.environ = env;
|
||||
sc.idx = -1;
|
||||
sc.cwd = _PATH_TMP;
|
||||
sc.flags = SPAWN_FLOATING|SPAWN_MODAL;
|
||||
sc.flags = SPAWN_FLOATING|SPAWN_MODAL|SPAWN_FLOATOVERZOOM;
|
||||
|
||||
wp = spawn_pane(&sc, &cause);
|
||||
free(cmd);
|
||||
environ_free(env);
|
||||
if (wp == NULL) {
|
||||
free(cause);
|
||||
window_pop_modal_zoom(w);
|
||||
window_pop_zoom(w);
|
||||
spawn_editor_free(es);
|
||||
return (NULL);
|
||||
}
|
||||
window_pop_zoom(w);
|
||||
options_set_number(wp->options, "remain-on-exit", 0);
|
||||
es->pid = wp->pid;
|
||||
wp->editor = es;
|
||||
|
||||
10
tmux.1
10
tmux.1
@@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: tmux.1,v 1.1157 2026/08/19 10:56:10 nicm Exp $
|
||||
.\" $OpenBSD: tmux.1,v 1.1158 2026/08/20 09:19:24 nicm Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
.\"
|
||||
@@ -14,7 +14,7 @@
|
||||
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: August 19 2026 $
|
||||
.Dd $Mdocdate: August 20 2026 $
|
||||
.Dt TMUX 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -3642,7 +3642,7 @@ but a different format may be specified with
|
||||
.Fl F .
|
||||
.Tg newp
|
||||
.It Xo Ic new\-pane
|
||||
.Op Fl bCdefhIkKLMOPvWZ
|
||||
.Op Fl AbCdefhIkKLMOPvWZ
|
||||
.Op Fl B Ar border\-lines
|
||||
.Op Fl c Ar start\-directory
|
||||
.Op Fl e Ar environment
|
||||
@@ -3691,8 +3691,8 @@ sets the pane border lines for floating panes; see
|
||||
.Fl M
|
||||
may be used when bound to a mouse drag key; the new floating pane is resized to
|
||||
follow the mouse drag.
|
||||
It has no effect with
|
||||
.Fl L .
|
||||
.Fl A
|
||||
creates a floating pane which remains visible above a zoomed pane.
|
||||
.Fl O
|
||||
creates a modal pane.
|
||||
A modal pane is always the active pane and prevents interaction with any other
|
||||
|
||||
10
tmux.h
10
tmux.h
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tmux.h,v 1.1428 2026/08/19 10:56:10 nicm Exp $ */
|
||||
/* $OpenBSD: tmux.h,v 1.1429 2026/08/20 09:19:24 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -1302,6 +1302,7 @@ struct window_pane {
|
||||
#define PANE_ACTIVITY 0x40000
|
||||
#define PANE_CLOSEONCLICK 0x80000
|
||||
#define PANE_CAPTUREALLKEYS 0x100000
|
||||
#define PANE_FLOATOVERZOOM 0x200000
|
||||
|
||||
bitstr_t *sync_dirty;
|
||||
u_int sync_dirty_size;
|
||||
@@ -1408,6 +1409,7 @@ struct window {
|
||||
struct window_pane *active;
|
||||
struct window_pane *modal;
|
||||
struct window_pane *modal_last;
|
||||
struct window_pane *was_zoomed;
|
||||
struct window_panes last_panes;
|
||||
struct window_panes z_index;
|
||||
struct window_panes panes;
|
||||
@@ -1450,7 +1452,6 @@ struct window {
|
||||
#define WINDOW_ZOOMED 0x8
|
||||
#define WINDOW_WASZOOMED 0x10
|
||||
#define WINDOW_RESIZE 0x20
|
||||
#define WINDOW_WASMODALZOOMED 0x40
|
||||
#define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE)
|
||||
|
||||
int alerts_queued;
|
||||
@@ -2494,6 +2495,7 @@ struct spawn_context {
|
||||
#define SPAWN_HORIZONTAL 0x200
|
||||
#define SPAWN_SPLIT 0x400
|
||||
#define SPAWN_MODAL 0x800
|
||||
#define SPAWN_FLOATOVERZOOM 0x1000
|
||||
};
|
||||
|
||||
/* Paste buffer. */
|
||||
@@ -3682,8 +3684,8 @@ void window_resize(struct window *, u_int, u_int, int, int);
|
||||
void window_pane_send_resize(struct window_pane *, u_int, u_int);
|
||||
int window_zoom(struct window_pane *);
|
||||
int window_unzoom(struct window *, int);
|
||||
void window_push_modal_zoom(struct window *);
|
||||
int window_pop_modal_zoom(struct window *);
|
||||
int window_active_pane_is_over_zoom(struct window *);
|
||||
struct window_pane *window_zoomed_pane(struct window *);
|
||||
int window_push_zoom(struct window *, int, int);
|
||||
int window_pop_zoom(struct window *);
|
||||
void window_lost_pane(struct window *, struct window_pane *);
|
||||
|
||||
130
window.c
130
window.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: window.c,v 1.369 2026/07/29 14:06:32 nicm Exp $ */
|
||||
/* $OpenBSD: window.c,v 1.370 2026/08/20 09:19:24 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -711,7 +711,7 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
|
||||
return (0);
|
||||
if (w->modal != NULL && wp != w->modal)
|
||||
return (0);
|
||||
if (w->flags & WINDOW_ZOOMED)
|
||||
if ((w->flags & WINDOW_ZOOMED) && !window_pane_is_visible(wp))
|
||||
window_unzoom(w, 1);
|
||||
lastwp = w->active;
|
||||
|
||||
@@ -911,13 +911,18 @@ window_zoom(struct window_pane *wp)
|
||||
{
|
||||
struct window *w = wp->window;
|
||||
struct window_pane *wp1;
|
||||
struct layout_cell *lc;
|
||||
struct layout_geometry lg;
|
||||
|
||||
if (w->flags & WINDOW_ZOOMED)
|
||||
return (-1);
|
||||
if (window_count_panes(w, 1) == 1)
|
||||
return (-1);
|
||||
|
||||
if (w->active != wp)
|
||||
if (w->active != wp &&
|
||||
(w->active == NULL ||
|
||||
(~w->active->flags & PANE_FLOATOVERZOOM) ||
|
||||
!window_pane_is_floating(w->active)))
|
||||
window_set_active_pane(w, wp, 1);
|
||||
wp->flags |= PANE_ZOOMED;
|
||||
|
||||
@@ -928,6 +933,22 @@ window_zoom(struct window_pane *wp)
|
||||
|
||||
w->saved_layout_root = w->layout_root;
|
||||
layout_init(w, wp);
|
||||
TAILQ_FOREACH(wp1, &w->panes, entry) {
|
||||
lc = wp1->saved_layout_cell;
|
||||
if (wp1 == wp ||
|
||||
(~wp1->flags & PANE_FLOATOVERZOOM) ||
|
||||
lc == NULL ||
|
||||
(~lc->flags & LAYOUT_CELL_FLOATING))
|
||||
continue;
|
||||
memcpy(&lg, &lc->g, sizeof lg);
|
||||
lc = layout_floating_pane(w, wp, &lg);
|
||||
layout_assign_pane(lc, wp1, 0);
|
||||
}
|
||||
/* A floating zoom target is now tiled, so put it behind the floats. */
|
||||
if (wp->saved_layout_cell->flags & LAYOUT_CELL_FLOATING) {
|
||||
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||
TAILQ_INSERT_TAIL(&w->z_index, wp, zentry);
|
||||
}
|
||||
w->flags |= WINDOW_ZOOMED;
|
||||
events_fire_window("window-zoomed", w);
|
||||
events_fire_window("window-layout-changed", w);
|
||||
@@ -939,11 +960,26 @@ window_zoom(struct window_pane *wp)
|
||||
int
|
||||
window_unzoom(struct window *w, int notify)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
struct window_pane *wp, *zoomed = NULL;
|
||||
struct layout_cell *slc;
|
||||
|
||||
if (!(w->flags & WINDOW_ZOOMED))
|
||||
if (~w->flags & WINDOW_ZOOMED)
|
||||
return (-1);
|
||||
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp->flags & PANE_ZOOMED)
|
||||
zoomed = wp;
|
||||
if (~wp->flags & PANE_FLOATOVERZOOM)
|
||||
continue;
|
||||
if (wp->flags & PANE_ZOOMED)
|
||||
continue;
|
||||
slc = wp->saved_layout_cell;
|
||||
if (slc == NULL || wp->layout_cell == NULL)
|
||||
continue;
|
||||
memcpy(&slc->g, &wp->layout_cell->g, sizeof slc->g);
|
||||
memcpy(&slc->fg, &wp->layout_cell->fg, sizeof slc->fg);
|
||||
}
|
||||
|
||||
w->flags &= ~WINDOW_ZOOMED;
|
||||
layout_free(w, 0);
|
||||
w->layout_root = w->saved_layout_root;
|
||||
@@ -954,6 +990,22 @@ window_unzoom(struct window *w, int notify)
|
||||
wp->saved_layout_cell = NULL;
|
||||
wp->flags &= ~PANE_ZOOMED;
|
||||
}
|
||||
/* Put a floating zoom target back into the floating part of the list. */
|
||||
if (zoomed != NULL && window_pane_is_floating(zoomed)) {
|
||||
TAILQ_REMOVE(&w->z_index, zoomed, zentry);
|
||||
if (zoomed == w->active)
|
||||
TAILQ_INSERT_HEAD(&w->z_index, zoomed, zentry);
|
||||
else {
|
||||
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
||||
if (!window_pane_is_floating(wp))
|
||||
break;
|
||||
}
|
||||
if (wp == NULL)
|
||||
TAILQ_INSERT_TAIL(&w->z_index, zoomed, zentry);
|
||||
else
|
||||
TAILQ_INSERT_BEFORE(wp, zoomed, zentry);
|
||||
}
|
||||
}
|
||||
layout_fix_panes(w, NULL);
|
||||
|
||||
if (notify) {
|
||||
@@ -965,48 +1017,69 @@ window_unzoom(struct window *w, int notify)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
window_push_modal_zoom(struct window *w)
|
||||
struct window_pane *
|
||||
window_zoomed_pane(struct window *w)
|
||||
{
|
||||
if (w->flags & WINDOW_ZOOMED)
|
||||
w->flags |= WINDOW_WASMODALZOOMED;
|
||||
else
|
||||
w->flags &= ~WINDOW_WASMODALZOOMED;
|
||||
window_unzoom(w, 1);
|
||||
struct window_pane *wp;
|
||||
|
||||
if (~w->flags & WINDOW_ZOOMED)
|
||||
return (NULL);
|
||||
TAILQ_FOREACH_REVERSE(wp, &w->z_index, window_panes_zindex, zentry) {
|
||||
if (wp->layout_cell != NULL && !window_pane_is_floating(wp))
|
||||
return (wp);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
window_pop_modal_zoom(struct window *w)
|
||||
window_active_pane_is_over_zoom(struct window *w)
|
||||
{
|
||||
struct window_pane *wp = w->active;
|
||||
|
||||
if (~w->flags & WINDOW_WASMODALZOOMED)
|
||||
if (~w->flags & WINDOW_ZOOMED)
|
||||
return (0);
|
||||
w->flags &= ~WINDOW_WASMODALZOOMED;
|
||||
if (wp != NULL && window_has_pane(w, wp))
|
||||
return (window_zoom(wp) == 0);
|
||||
return (0);
|
||||
if (w->active == NULL)
|
||||
return (0);
|
||||
if (~w->active->flags & PANE_FLOATOVERZOOM)
|
||||
return (0);
|
||||
return (window_pane_is_floating(w->active));
|
||||
}
|
||||
|
||||
int
|
||||
window_push_zoom(struct window *w, int always, int flag)
|
||||
{
|
||||
struct window_pane *wp = window_zoomed_pane(w);
|
||||
|
||||
log_debug("%s: @%u %d", __func__, w->id,
|
||||
flag && (w->flags & WINDOW_ZOOMED));
|
||||
if (flag && (always || (w->flags & WINDOW_ZOOMED)))
|
||||
w->flags |= WINDOW_WASZOOMED;
|
||||
else
|
||||
w->flags &= ~WINDOW_WASZOOMED;
|
||||
if (w->flags & WINDOW_WASZOOMED)
|
||||
w->was_zoomed = wp;
|
||||
else
|
||||
w->was_zoomed = NULL;
|
||||
return (window_unzoom(w, 1) == 0);
|
||||
}
|
||||
|
||||
int
|
||||
window_pop_zoom(struct window *w)
|
||||
{
|
||||
struct window_pane *wp = w->was_zoomed;
|
||||
|
||||
log_debug("%s: @%u %d", __func__, w->id,
|
||||
!!(w->flags & WINDOW_WASZOOMED));
|
||||
if (w->flags & WINDOW_WASZOOMED)
|
||||
return (window_zoom(w->active) == 0);
|
||||
if (w->flags & WINDOW_WASZOOMED) {
|
||||
w->flags &= ~WINDOW_WASZOOMED;
|
||||
w->was_zoomed = NULL;
|
||||
if (w->active != NULL &&
|
||||
((~w->active->flags & PANE_FLOATOVERZOOM) ||
|
||||
!window_pane_is_floating(w->active)))
|
||||
wp = w->active;
|
||||
if (wp == NULL || !window_has_pane(w, wp))
|
||||
wp = w->active;
|
||||
if (wp != NULL)
|
||||
return (window_zoom(wp) == 0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -1058,8 +1131,8 @@ window_lost_pane(struct window *w, struct window_pane *wp)
|
||||
server_clear_marked();
|
||||
if (wp == w->modal_last)
|
||||
w->modal_last = NULL;
|
||||
if (w->modal_last == NULL)
|
||||
w->flags &= ~WINDOW_WASMODALZOOMED;
|
||||
if (wp == w->was_zoomed)
|
||||
w->was_zoomed = NULL;
|
||||
|
||||
window_pane_stack_remove(&w->last_panes, wp);
|
||||
if (wp == w->active) {
|
||||
@@ -1086,7 +1159,6 @@ window_lost_pane(struct window *w, struct window_pane *wp)
|
||||
}
|
||||
} else if (wp == w->modal) {
|
||||
w->modal = w->modal_last = NULL;
|
||||
w->flags &= ~WINDOW_WASMODALZOOMED;
|
||||
}
|
||||
redraw_invalidate_scene(w);
|
||||
}
|
||||
@@ -1094,13 +1166,9 @@ window_lost_pane(struct window *w, struct window_pane *wp)
|
||||
void
|
||||
window_remove_pane(struct window *w, struct window_pane *wp)
|
||||
{
|
||||
int pop = (wp == w->modal);
|
||||
|
||||
window_lost_pane(w, wp);
|
||||
TAILQ_REMOVE(&w->panes, wp, entry);
|
||||
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||
if (pop && window_pop_modal_zoom(w))
|
||||
server_redraw_window(w);
|
||||
redraw_invalidate_scene(w);
|
||||
window_pane_destroy(wp);
|
||||
}
|
||||
@@ -1256,6 +1324,8 @@ window_pane_printable_flags(struct window_pane *wp)
|
||||
flags[pos++] = 'Z';
|
||||
if (window_pane_is_floating(wp))
|
||||
flags[pos++] = 'F';
|
||||
if (wp->flags & PANE_FLOATOVERZOOM)
|
||||
flags[pos++] = 'A';
|
||||
if (wp == w->modal)
|
||||
flags[pos++] = 'O';
|
||||
flags[pos] = '\0';
|
||||
@@ -1958,7 +2028,7 @@ window_pane_is_visible(struct window_pane *wp)
|
||||
{
|
||||
if (~wp->window->flags & WINDOW_ZOOMED)
|
||||
return (1);
|
||||
return (wp == wp->window->active);
|
||||
return (wp->layout_cell != NULL);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user