mirror of
https://github.com/tmux/tmux.git
synced 2026-10-13 14:24:28 +00:00
Add support for local windows for a client.
This commit is contained in:
@@ -85,6 +85,7 @@ endif
|
|||||||
|
|
||||||
# List of sources.
|
# List of sources.
|
||||||
dist_tmux_SOURCES = \
|
dist_tmux_SOURCES = \
|
||||||
|
active.c \
|
||||||
alerts.c \
|
alerts.c \
|
||||||
arguments.c \
|
arguments.c \
|
||||||
attributes.c \
|
attributes.c \
|
||||||
|
|||||||
449
active.c
Normal file
449
active.c
Normal file
@@ -0,0 +1,449 @@
|
|||||||
|
/* $OpenBSD$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "tmux.h"
|
||||||
|
|
||||||
|
/* Local last-window stack entry. */
|
||||||
|
struct active_window_entry {
|
||||||
|
u_int window;
|
||||||
|
TAILQ_ENTRY(active_window_entry) entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Local last-window stack. */
|
||||||
|
TAILQ_HEAD(active_window_stack, active_window_entry);
|
||||||
|
|
||||||
|
/* Per-client and per-session local active window state. */
|
||||||
|
struct active_window {
|
||||||
|
struct client *client;
|
||||||
|
struct session *session;
|
||||||
|
|
||||||
|
u_int window;
|
||||||
|
struct active_window_stack lastw;
|
||||||
|
|
||||||
|
RB_ENTRY(active_window) entry;
|
||||||
|
};
|
||||||
|
RB_HEAD(active_windows, active_window);
|
||||||
|
|
||||||
|
static int
|
||||||
|
active_window_cmp(struct active_window *aw1, struct active_window *aw2)
|
||||||
|
{
|
||||||
|
uintptr_t c1 = (uintptr_t)aw1->client;
|
||||||
|
uintptr_t c2 = (uintptr_t)aw2->client;
|
||||||
|
uintptr_t s1 = (uintptr_t)aw1->session;
|
||||||
|
uintptr_t s2 = (uintptr_t)aw2->session;
|
||||||
|
|
||||||
|
if (c1 < c2)
|
||||||
|
return (-1);
|
||||||
|
if (c1 > c2)
|
||||||
|
return (1);
|
||||||
|
if (s1 < s2)
|
||||||
|
return (-1);
|
||||||
|
if (s1 > s2)
|
||||||
|
return (1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
RB_GENERATE_STATIC(active_windows, active_window, entry, active_window_cmp);
|
||||||
|
|
||||||
|
static struct active_window *active_get(struct client *, struct session *);
|
||||||
|
static struct active_window *active_add(struct client *, struct session *,
|
||||||
|
struct winlink *);
|
||||||
|
static void active_free(struct active_window *);
|
||||||
|
static struct winlink *active_resolve(struct active_window *);
|
||||||
|
static void active_stack_remove(struct active_window_stack *, u_int);
|
||||||
|
static void active_stack_push(struct active_window_stack *, u_int);
|
||||||
|
static void active_changed(struct client *, struct session *,
|
||||||
|
struct winlink *, struct winlink *);
|
||||||
|
|
||||||
|
/* All local active window states. */
|
||||||
|
static struct active_windows active_windows = RB_INITIALIZER(&active_windows);
|
||||||
|
|
||||||
|
/* Find local active window state for a client and session. */
|
||||||
|
static struct active_window *
|
||||||
|
active_get(struct client *c, struct session *s)
|
||||||
|
{
|
||||||
|
struct active_window aw;
|
||||||
|
|
||||||
|
if (c == NULL || s == NULL)
|
||||||
|
return (NULL);
|
||||||
|
aw.client = c;
|
||||||
|
aw.session = s;
|
||||||
|
return (RB_FIND(active_windows, &active_windows, &aw));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add local active window state for a client and session. */
|
||||||
|
static struct active_window *
|
||||||
|
active_add(struct client *c, struct session *s, struct winlink *wl)
|
||||||
|
{
|
||||||
|
struct active_window *aw;
|
||||||
|
|
||||||
|
aw = active_get(c, s);
|
||||||
|
if (aw == NULL) {
|
||||||
|
aw = xcalloc(1, sizeof *aw);
|
||||||
|
aw->client = c;
|
||||||
|
aw->session = s;
|
||||||
|
TAILQ_INIT(&aw->lastw);
|
||||||
|
RB_INSERT(active_windows, &active_windows, aw);
|
||||||
|
}
|
||||||
|
if (wl != NULL)
|
||||||
|
aw->window = wl->window->id;
|
||||||
|
return (aw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free local active window state. */
|
||||||
|
static void
|
||||||
|
active_free(struct active_window *aw)
|
||||||
|
{
|
||||||
|
struct active_window_entry *awe;
|
||||||
|
|
||||||
|
while (!TAILQ_EMPTY(&aw->lastw)) {
|
||||||
|
awe = TAILQ_FIRST(&aw->lastw);
|
||||||
|
TAILQ_REMOVE(&aw->lastw, awe, entry);
|
||||||
|
free(awe);
|
||||||
|
}
|
||||||
|
RB_REMOVE(active_windows, &active_windows, aw);
|
||||||
|
free(aw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resolve local active window state to a valid winlink. */
|
||||||
|
static struct winlink *
|
||||||
|
active_resolve(struct active_window *aw)
|
||||||
|
{
|
||||||
|
struct winlink *wl, *next;
|
||||||
|
u_int window;
|
||||||
|
|
||||||
|
if (aw == NULL || aw->session->curw == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
wl = winlink_find_by_window_id(&aw->session->windows, aw->window);
|
||||||
|
if (wl != NULL)
|
||||||
|
return (wl);
|
||||||
|
|
||||||
|
while (!TAILQ_EMPTY(&aw->lastw)) {
|
||||||
|
window = TAILQ_FIRST(&aw->lastw)->window;
|
||||||
|
|
||||||
|
next = winlink_find_by_window_id(&aw->session->windows, window);
|
||||||
|
active_stack_remove(&aw->lastw, window);
|
||||||
|
if (next != NULL) {
|
||||||
|
aw->window = next->window->id;
|
||||||
|
return (next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aw->window = aw->session->curw->window->id;
|
||||||
|
return (aw->session->curw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove a window from a local last-window stack. */
|
||||||
|
static void
|
||||||
|
active_stack_remove(struct active_window_stack *stack, u_int window)
|
||||||
|
{
|
||||||
|
struct active_window_entry *awe, *awe1;
|
||||||
|
|
||||||
|
TAILQ_FOREACH_SAFE(awe, stack, entry, awe1) {
|
||||||
|
if (awe->window == window) {
|
||||||
|
TAILQ_REMOVE(stack, awe, entry);
|
||||||
|
free(awe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Push a window onto a local last-window stack. */
|
||||||
|
static void
|
||||||
|
active_stack_push(struct active_window_stack *stack, u_int window)
|
||||||
|
{
|
||||||
|
struct active_window_entry *awe;
|
||||||
|
|
||||||
|
active_stack_remove(stack, window);
|
||||||
|
awe = xcalloc(1, sizeof *awe);
|
||||||
|
awe->window = window;
|
||||||
|
TAILQ_INSERT_HEAD(stack, awe, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notify the server that a client's effective window changed. */
|
||||||
|
static void
|
||||||
|
active_changed(struct client *c, struct session *s, struct winlink *wl,
|
||||||
|
struct winlink *old)
|
||||||
|
{
|
||||||
|
struct event_payload *ep;
|
||||||
|
struct cmd_find_state fs;
|
||||||
|
|
||||||
|
if (wl == NULL || wl == old)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (options_get_number(global_options, "focus-events")) {
|
||||||
|
if (old != NULL)
|
||||||
|
window_update_focus(old->window);
|
||||||
|
window_update_focus(wl->window);
|
||||||
|
}
|
||||||
|
winlink_clear_flags(wl);
|
||||||
|
window_update_activity(wl->window);
|
||||||
|
tty_update_window_offset(wl->window);
|
||||||
|
|
||||||
|
if (c != NULL && c->session == s)
|
||||||
|
wl->window->latest = c;
|
||||||
|
|
||||||
|
ep = event_payload_create();
|
||||||
|
cmd_find_from_winlink(&fs, wl, 0);
|
||||||
|
event_payload_set_target(ep, &fs);
|
||||||
|
event_payload_set_client(ep, "client", c);
|
||||||
|
event_payload_set_session(ep, "session", s);
|
||||||
|
event_payload_set_window(ep, "window", wl->window);
|
||||||
|
event_payload_set_window(ep, "new_window", wl->window);
|
||||||
|
event_payload_set_int(ep, "window_index", wl->idx);
|
||||||
|
event_payload_set_int(ep, "new_window_index", wl->idx);
|
||||||
|
if (old != NULL) {
|
||||||
|
event_payload_set_window(ep, "old_window", old->window);
|
||||||
|
event_payload_set_int(ep, "old_window_index", old->idx);
|
||||||
|
}
|
||||||
|
events_fire("client-window-changed", ep);
|
||||||
|
|
||||||
|
if (c != NULL) {
|
||||||
|
c->flags |= CLIENT_REDRAWWINDOW|CLIENT_REDRAWSTATUS|
|
||||||
|
CLIENT_REDRAWBORDERS;
|
||||||
|
tty_update_client_offset(c);
|
||||||
|
status_update_cache(s);
|
||||||
|
}
|
||||||
|
recalculate_sizes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return if a client has local window selection for a session. */
|
||||||
|
int
|
||||||
|
active_is_local_window(struct client *c, struct session *s)
|
||||||
|
{
|
||||||
|
return (active_get(c, s) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make a client use local or shared window selection for a session. */
|
||||||
|
void
|
||||||
|
active_set_local_window(struct client *c, struct session *s,
|
||||||
|
enum active_window_mode mode)
|
||||||
|
{
|
||||||
|
struct active_window *aw;
|
||||||
|
struct winlink *wl, *old;
|
||||||
|
|
||||||
|
if (c == NULL || s == NULL || s->curw == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
old = active_get_effective_winlink(c, s);
|
||||||
|
if (mode == ACTIVE_LOCAL) {
|
||||||
|
active_add(c, s, old);
|
||||||
|
if (c != NULL && c->session == s)
|
||||||
|
c->flags |= CLIENT_REDRAWSTATUS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aw = active_get(c, s);
|
||||||
|
if (aw != NULL) {
|
||||||
|
active_free(aw);
|
||||||
|
wl = active_get_effective_winlink(c, s);
|
||||||
|
active_changed(c, s, wl, old);
|
||||||
|
if (c != NULL && c->session == s)
|
||||||
|
c->flags |= CLIENT_REDRAWSTATUS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the effective winlink for a client and session. */
|
||||||
|
struct winlink *
|
||||||
|
active_get_effective_winlink(struct client *c, struct session *s)
|
||||||
|
{
|
||||||
|
struct active_window *aw;
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
return (NULL);
|
||||||
|
aw = active_get(c, s);
|
||||||
|
if (aw != NULL)
|
||||||
|
return (active_resolve(aw));
|
||||||
|
return (s->curw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the effective window for a client and session. */
|
||||||
|
struct window *
|
||||||
|
active_get_effective_window(struct client *c, struct session *s)
|
||||||
|
{
|
||||||
|
struct winlink *wl;
|
||||||
|
|
||||||
|
wl = active_get_effective_winlink(c, s);
|
||||||
|
if (wl == NULL)
|
||||||
|
return (NULL);
|
||||||
|
return (wl->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select a winlink for a client and session. */
|
||||||
|
int
|
||||||
|
active_select_window(struct client *c, struct session *s, struct winlink *wl)
|
||||||
|
{
|
||||||
|
struct active_window *aw;
|
||||||
|
struct winlink *old;
|
||||||
|
int changed;
|
||||||
|
|
||||||
|
if (wl == NULL)
|
||||||
|
return (-1);
|
||||||
|
aw = active_get(c, s);
|
||||||
|
if (aw == NULL)
|
||||||
|
return (session_set_current(s, wl));
|
||||||
|
|
||||||
|
old = active_resolve(aw);
|
||||||
|
if (old == wl)
|
||||||
|
return (1);
|
||||||
|
if (old != NULL)
|
||||||
|
active_stack_push(&aw->lastw, old->window->id);
|
||||||
|
active_stack_remove(&aw->lastw, wl->window->id);
|
||||||
|
aw->window = wl->window->id;
|
||||||
|
changed = (old != wl);
|
||||||
|
active_changed(c, s, wl, old);
|
||||||
|
return (changed ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select a window by index. */
|
||||||
|
int
|
||||||
|
active_select_window_index(struct client *c, struct session *s, int idx)
|
||||||
|
{
|
||||||
|
struct winlink *wl;
|
||||||
|
|
||||||
|
wl = winlink_find_by_index(&s->windows, idx);
|
||||||
|
return (active_select_window(c, s, wl));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select the next window. */
|
||||||
|
int
|
||||||
|
active_next_window(struct client *c, struct session *s, int alert)
|
||||||
|
{
|
||||||
|
struct winlink *wl;
|
||||||
|
|
||||||
|
wl = active_get_effective_winlink(c, s);
|
||||||
|
if (wl == NULL)
|
||||||
|
return (-1);
|
||||||
|
do {
|
||||||
|
wl = winlink_next(wl);
|
||||||
|
if (wl == NULL)
|
||||||
|
wl = RB_MIN(winlinks, &s->windows);
|
||||||
|
if (!alert || (wl->flags & WINLINK_ALERTFLAGS))
|
||||||
|
return (active_select_window(c, s, wl));
|
||||||
|
} while (wl != active_get_effective_winlink(c, s));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select the previous window. */
|
||||||
|
int
|
||||||
|
active_previous_window(struct client *c, struct session *s, int alert)
|
||||||
|
{
|
||||||
|
struct winlink *wl;
|
||||||
|
|
||||||
|
wl = active_get_effective_winlink(c, s);
|
||||||
|
if (wl == NULL)
|
||||||
|
return (-1);
|
||||||
|
do {
|
||||||
|
wl = winlink_previous(wl);
|
||||||
|
if (wl == NULL)
|
||||||
|
wl = RB_MAX(winlinks, &s->windows);
|
||||||
|
if (!alert || (wl->flags & WINLINK_ALERTFLAGS))
|
||||||
|
return (active_select_window(c, s, wl));
|
||||||
|
} while (wl != active_get_effective_winlink(c, s));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select the last window. */
|
||||||
|
int
|
||||||
|
active_last_window(struct client *c, struct session *s)
|
||||||
|
{
|
||||||
|
struct active_window *aw;
|
||||||
|
struct winlink *wl;
|
||||||
|
u_int window;
|
||||||
|
|
||||||
|
aw = active_get(c, s);
|
||||||
|
if (aw == NULL)
|
||||||
|
return (session_last(s));
|
||||||
|
while (!TAILQ_EMPTY(&aw->lastw)) {
|
||||||
|
window = TAILQ_FIRST(&aw->lastw)->window;
|
||||||
|
|
||||||
|
wl = winlink_find_by_window_id(&s->windows, window);
|
||||||
|
if (wl != NULL)
|
||||||
|
return (active_select_window(c, s, wl));
|
||||||
|
active_stack_remove(&aw->lastw, window);
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove all state for a client. */
|
||||||
|
void
|
||||||
|
active_remove_client(struct client *c)
|
||||||
|
{
|
||||||
|
struct active_window *aw, *aw1;
|
||||||
|
|
||||||
|
RB_FOREACH_SAFE(aw, active_windows, &active_windows, aw1) {
|
||||||
|
if (aw->client == c)
|
||||||
|
active_free(aw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove all state for a session. */
|
||||||
|
void
|
||||||
|
active_remove_session(struct session *s)
|
||||||
|
{
|
||||||
|
struct active_window *aw, *aw1;
|
||||||
|
|
||||||
|
RB_FOREACH_SAFE(aw, active_windows, &active_windows, aw1) {
|
||||||
|
if (aw->session == s)
|
||||||
|
active_free(aw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove a window from all local state. */
|
||||||
|
void
|
||||||
|
active_remove_window(struct window *w)
|
||||||
|
{
|
||||||
|
struct active_window *aw;
|
||||||
|
|
||||||
|
RB_FOREACH(aw, active_windows, &active_windows) {
|
||||||
|
active_stack_remove(&aw->lastw, w->id);
|
||||||
|
if (aw->window == w->id && aw->session->curw != NULL)
|
||||||
|
aw->window = aw->session->curw->window->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return if this winlink is the effective winlink. */
|
||||||
|
int
|
||||||
|
active_is_effective_window(struct client *c, struct session *s,
|
||||||
|
struct winlink *wl)
|
||||||
|
{
|
||||||
|
return (wl != NULL && wl == active_get_effective_winlink(c, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return if this winlink is the last effective winlink. */
|
||||||
|
int
|
||||||
|
active_is_last_window(struct client *c, struct session *s, struct winlink *wl)
|
||||||
|
{
|
||||||
|
struct active_window *aw;
|
||||||
|
struct active_window_entry *awe;
|
||||||
|
|
||||||
|
if (wl == NULL)
|
||||||
|
return (0);
|
||||||
|
aw = active_get(c, s);
|
||||||
|
if (aw == NULL)
|
||||||
|
return (wl == TAILQ_FIRST(&s->lastw));
|
||||||
|
TAILQ_FOREACH(awe, &aw->lastw, entry) {
|
||||||
|
if (winlink_find_by_window_id(&s->windows, awe->window) == NULL)
|
||||||
|
continue;
|
||||||
|
return (wl->window->id == awe->window);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
2
alerts.c
2
alerts.c
@@ -314,7 +314,7 @@ alerts_set_message(struct winlink *wl, const char *type, const char *option)
|
|||||||
tty_putcode(&c->tty, TTYC_BEL);
|
tty_putcode(&c->tty, TTYC_BEL);
|
||||||
if (visual == VISUAL_OFF)
|
if (visual == VISUAL_OFF)
|
||||||
continue;
|
continue;
|
||||||
if (c->session->curw == wl) {
|
if (active_get_effective_winlink(c, c->session) == wl) {
|
||||||
status_message_set(c, -1, 1, 0, 0,
|
status_message_set(c, -1, 1, 0, 0,
|
||||||
"%s in current window", type);
|
"%s in current window", type);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
|
|||||||
if (wl != NULL) {
|
if (wl != NULL) {
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
window_set_active_pane(wp->window, wp, 1);
|
window_set_active_pane(wp->window, wp, 1);
|
||||||
session_set_current(s, wl);
|
active_select_window(c, s, wl);
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
cmd_find_from_winlink_pane(current, wl, wp, 0);
|
cmd_find_from_winlink_pane(current, wl, wp, 0);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -93,14 +93,18 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct cmd_find_state *current = cmdq_get_current(item);
|
struct cmd_find_state *current = cmdq_get_current(item);
|
||||||
struct cmd_find_state *target = cmdq_get_target(item);
|
struct cmd_find_state *target = cmdq_get_target(item);
|
||||||
struct cmd_find_state *source = cmdq_get_source(item);
|
struct cmd_find_state *source = cmdq_get_source(item);
|
||||||
|
struct client *c = cmdq_get_client(item);
|
||||||
struct client *tc = cmdq_get_target_client(item);
|
struct client *tc = cmdq_get_target_client(item);
|
||||||
|
struct client *ac;
|
||||||
struct winlink *wl = source->wl;
|
struct winlink *wl = source->wl;
|
||||||
|
struct winlink *current_wl;
|
||||||
struct session *src_s = source->s;
|
struct session *src_s = source->s;
|
||||||
struct session *dst_s = target->s;
|
struct session *dst_s = target->s;
|
||||||
struct window_pane *wp = source->wp;
|
struct window_pane *wp = source->wp;
|
||||||
struct window *w = wl->window, *old_w = w;
|
struct window *w = wl->window, *old_w = w;
|
||||||
char *cause, *cp;
|
char *cause, *cp;
|
||||||
int idx = target->idx, before, old_idx = wl->idx;
|
int idx = target->idx, before, old_idx = wl->idx;
|
||||||
|
int detached, local;
|
||||||
const char *template, *name = args_get(args, 'n');
|
const char *template, *name = args_get(args, 'n');
|
||||||
|
|
||||||
if (wp == w->modal) {
|
if (wp == w->modal) {
|
||||||
@@ -117,11 +121,18 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
before = args_has(args, 'b');
|
before = args_has(args, 'b');
|
||||||
|
ac = tc;
|
||||||
|
if (ac == NULL || ac->session != dst_s)
|
||||||
|
ac = c;
|
||||||
|
detached = args_has(args, 'd');
|
||||||
|
local = (!detached && active_is_local_window(ac, dst_s));
|
||||||
if (args_has(args, 'a') || before) {
|
if (args_has(args, 'a') || before) {
|
||||||
if (target->wl != NULL)
|
if (target->wl != NULL)
|
||||||
idx = winlink_shuffle_up(dst_s, target->wl, before);
|
idx = winlink_shuffle_up(dst_s, target->wl, before);
|
||||||
else
|
else {
|
||||||
idx = winlink_shuffle_up(dst_s, dst_s->curw, before);
|
current_wl = active_get_effective_winlink(ac, dst_s);
|
||||||
|
idx = winlink_shuffle_up(dst_s, current_wl, before);
|
||||||
|
}
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
@@ -129,7 +140,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
if (window_count_panes(w, 1) == 1) {
|
if (window_count_panes(w, 1) == 1) {
|
||||||
if (server_link_window(src_s, wl, dst_s, idx, 0,
|
if (server_link_window(src_s, wl, dst_s, idx, 0,
|
||||||
!args_has(args, 'd'), &cause) != 0) {
|
!detached && !local, &cause) != 0) {
|
||||||
cmdq_error(item, "%s", cause);
|
cmdq_error(item, "%s", cause);
|
||||||
free(cause);
|
free(cause);
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
@@ -142,6 +153,13 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
wl = winlink_find_by_window(&dst_s->windows, w);
|
wl = winlink_find_by_window(&dst_s->windows, w);
|
||||||
if (wl == NULL)
|
if (wl == NULL)
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
|
if (local) {
|
||||||
|
active_select_window(ac, dst_s, wl);
|
||||||
|
if (ac != NULL && ac->session == dst_s)
|
||||||
|
cmd_find_from_client(current, ac, 0);
|
||||||
|
if (ac != NULL && ac->session == dst_s)
|
||||||
|
server_redraw_client(ac);
|
||||||
|
}
|
||||||
window_fire_pane_moved(wp, old_w, old_idx, w, wl->idx);
|
window_fire_pane_moved(wp, old_w, old_idx, w, wl->idx);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -183,9 +201,17 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
window_remove_ref(w, __func__);
|
window_remove_ref(w, __func__);
|
||||||
events_fire_window("window-created", w);
|
events_fire_window("window-created", w);
|
||||||
window_fire_pane_moved(wp, old_w, old_idx, w, wl->idx);
|
window_fire_pane_moved(wp, old_w, old_idx, w, wl->idx);
|
||||||
if (!args_has(args, 'd')) {
|
if (!detached) {
|
||||||
session_select(dst_s, wl->idx);
|
if (local)
|
||||||
cmd_find_from_session(current, dst_s, 0);
|
active_select_window(ac, dst_s, wl);
|
||||||
|
else
|
||||||
|
session_select(dst_s, wl->idx);
|
||||||
|
if (local && ac != NULL && ac->session == dst_s)
|
||||||
|
cmd_find_from_client(current, ac, 0);
|
||||||
|
else
|
||||||
|
cmd_find_from_session(current, dst_s, 0);
|
||||||
|
if (local && ac != NULL && ac->session == dst_s)
|
||||||
|
server_redraw_client(ac);
|
||||||
}
|
}
|
||||||
|
|
||||||
server_redraw_session(src_s);
|
server_redraw_session(src_s);
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
char *title, *cause = NULL;
|
char *title, *cause = NULL;
|
||||||
int flags = 0, starting_choice = 0;
|
int flags = 0, starting_choice = 0;
|
||||||
u_int px, py, i, count = args_count(args);
|
u_int px, py, i, count = args_count(args);
|
||||||
struct options *o = target->s->curw->window->options;
|
struct options *o = target->w->options;
|
||||||
struct options_entry *oe;
|
struct options_entry *oe;
|
||||||
|
|
||||||
if (args_has(args, 'C')) {
|
if (args_has(args, 'C')) {
|
||||||
@@ -584,7 +584,7 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
u_int px, py, w, h, count = args_count(args);
|
u_int px, py, w, h, count = args_count(args);
|
||||||
struct args_value *av;
|
struct args_value *av;
|
||||||
struct environ *env = NULL;
|
struct environ *env = NULL;
|
||||||
struct options *o = s->curw->window->options;
|
struct options *o = target->w->options;
|
||||||
struct options_entry *oe;
|
struct options_entry *oe;
|
||||||
|
|
||||||
if (args_has(args, 'C')) {
|
if (args_has(args, 'C')) {
|
||||||
|
|||||||
84
cmd-find.c
84
cmd-find.c
@@ -884,13 +884,13 @@ cmd_find_from_client(struct cmd_find_state *fs, struct client *c, int flags)
|
|||||||
if (c->session != NULL) {
|
if (c->session != NULL) {
|
||||||
cmd_find_clear_state(fs, flags);
|
cmd_find_clear_state(fs, flags);
|
||||||
|
|
||||||
fs->wp = c->session->curw->window->active;
|
fs->wl = active_get_effective_winlink(c, c->session);
|
||||||
|
fs->wp = fs->wl->window->active;
|
||||||
if (fs->wp == NULL) {
|
if (fs->wp == NULL) {
|
||||||
cmd_find_from_session(fs, c->session, flags);
|
cmd_find_from_session(fs, c->session, flags);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
fs->s = c->session;
|
fs->s = c->session;
|
||||||
fs->wl = fs->s->curw;
|
|
||||||
fs->w = fs->wl->window;
|
fs->w = fs->wl->window;
|
||||||
|
|
||||||
cmd_find_log_state(__func__, fs);
|
cmd_find_log_state(__func__, fs);
|
||||||
@@ -931,6 +931,57 @@ unknown_pane:
|
|||||||
return (cmd_find_from_nothing(fs, flags));
|
return (cmd_find_from_nothing(fs, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find state from mouse target. */
|
||||||
|
static int
|
||||||
|
cmd_find_target_from_mouse(struct cmd_find_state *fs, struct cmdq_item *item,
|
||||||
|
enum cmd_find_type type)
|
||||||
|
{
|
||||||
|
struct mouse_event *m = &cmdq_get_event(item)->m;
|
||||||
|
struct client *c = cmdq_get_client(item);
|
||||||
|
struct client *tc = cmdq_get_target_client(item);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case CMD_FIND_PANE:
|
||||||
|
if (m->s != -1 && m->w == -1 && m->wp == -1 &&
|
||||||
|
(fs->s = session_find_by_id(m->s)) != NULL) {
|
||||||
|
if (tc != NULL && tc->session == fs->s)
|
||||||
|
fs->wl = active_get_effective_winlink(tc, fs->s);
|
||||||
|
else if (c != NULL && c->session == fs->s)
|
||||||
|
fs->wl = active_get_effective_winlink(c, fs->s);
|
||||||
|
else
|
||||||
|
fs->wl = fs->s->curw;
|
||||||
|
if (fs->wl != NULL) {
|
||||||
|
fs->w = fs->wl->window;
|
||||||
|
fs->wp = fs->w->active;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fs->wp = cmd_mouse_pane(m, &fs->s, &fs->wl);
|
||||||
|
if (fs->wp != NULL) {
|
||||||
|
fs->w = fs->wl->window;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case CMD_FIND_WINDOW:
|
||||||
|
case CMD_FIND_SESSION:
|
||||||
|
fs->wl = cmd_mouse_window(m, &fs->s);
|
||||||
|
if (fs->s != NULL && m->w == -1 &&
|
||||||
|
tc != NULL && tc->session == fs->s)
|
||||||
|
fs->wl = active_get_effective_winlink(tc, fs->s);
|
||||||
|
else if (fs->s != NULL && m->w == -1 &&
|
||||||
|
c != NULL && c->session == fs->s)
|
||||||
|
fs->wl = active_get_effective_winlink(c, fs->s);
|
||||||
|
if (fs->wl == NULL && fs->s != NULL)
|
||||||
|
fs->wl = fs->s->curw;
|
||||||
|
if (fs->wl != NULL) {
|
||||||
|
fs->w = fs->wl->window;
|
||||||
|
fs->wp = fs->w->active;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (fs->wp == NULL ? -1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Split target into pieces and resolve for the given type. Fills in the given
|
* Split target into pieces and resolve for the given type. Fills in the given
|
||||||
* state. Returns 0 on success or -1 on error.
|
* state. Returns 0 on success or -1 on error.
|
||||||
@@ -939,7 +990,6 @@ int
|
|||||||
cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item,
|
cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item,
|
||||||
const char *target, enum cmd_find_type type, int flags)
|
const char *target, enum cmd_find_type type, int flags)
|
||||||
{
|
{
|
||||||
struct mouse_event *m;
|
|
||||||
struct client *c;
|
struct client *c;
|
||||||
struct cmd_find_state current;
|
struct cmd_find_state current;
|
||||||
char *colon, *period, *copy = NULL, tmp[256];
|
char *colon, *period, *copy = NULL, tmp[256];
|
||||||
@@ -1015,35 +1065,15 @@ cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item,
|
|||||||
cmdq_error(item, "no current client");
|
cmdq_error(item, "no current client");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
fs->wl = c->session->curw;
|
fs->wl = active_get_effective_winlink(c, c->session);
|
||||||
fs->wp = c->session->curw->window->active;
|
fs->wp = fs->wl->window->active;
|
||||||
fs->w = c->session->curw->window;
|
fs->w = fs->wl->window;
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mouse target is a plain = or {mouse}. */
|
/* Mouse target is a plain = or {mouse}. */
|
||||||
if (strcmp(target, "=") == 0 || strcmp(target, "{mouse}") == 0) {
|
if (strcmp(target, "=") == 0 || strcmp(target, "{mouse}") == 0) {
|
||||||
m = &cmdq_get_event(item)->m;
|
if (cmd_find_target_from_mouse(fs, item, type) != 0) {
|
||||||
switch (type) {
|
|
||||||
case CMD_FIND_PANE:
|
|
||||||
fs->wp = cmd_mouse_pane(m, &fs->s, &fs->wl);
|
|
||||||
if (fs->wp != NULL) {
|
|
||||||
fs->w = fs->wl->window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case CMD_FIND_WINDOW:
|
|
||||||
case CMD_FIND_SESSION:
|
|
||||||
fs->wl = cmd_mouse_window(m, &fs->s);
|
|
||||||
if (fs->wl == NULL && fs->s != NULL)
|
|
||||||
fs->wl = fs->s->curw;
|
|
||||||
if (fs->wl != NULL) {
|
|
||||||
fs->w = fs->wl->window;
|
|
||||||
fs->wp = fs->w->active;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (fs->wp == NULL) {
|
|
||||||
if (~flags & CMD_FIND_QUIET)
|
if (~flags & CMD_FIND_QUIET)
|
||||||
cmdq_error(item, "no mouse target");
|
cmdq_error(item, "no mouse target");
|
||||||
goto error;
|
goto error;
|
||||||
|
|||||||
@@ -410,13 +410,16 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct cmd_find_state *current = cmdq_get_current(item);
|
struct cmd_find_state *current = cmdq_get_current(item);
|
||||||
struct cmd_find_state *target = cmdq_get_target(item);
|
struct cmd_find_state *target = cmdq_get_target(item);
|
||||||
struct cmd_find_state *source = cmdq_get_source(item);
|
struct cmd_find_state *source = cmdq_get_source(item);
|
||||||
|
struct client *c = cmdq_get_client(item);
|
||||||
|
struct client *tc = cmdq_get_target_client(item);
|
||||||
|
struct client *ac;
|
||||||
struct session *dst_s;
|
struct session *dst_s;
|
||||||
struct winlink *src_wl, *dst_wl;
|
struct winlink *src_wl, *dst_wl;
|
||||||
struct window *src_w, *dst_w;
|
struct window *src_w, *dst_w;
|
||||||
struct window_pane *src_wp, *dst_wp;
|
struct window_pane *src_wp, *dst_wp;
|
||||||
const char *s;
|
const char *s;
|
||||||
char *cause = NULL;
|
char *cause = NULL;
|
||||||
int flags = 0, dst_idx;
|
int flags = 0, dst_idx, local;
|
||||||
struct layout_cell *lc;
|
struct layout_cell *lc;
|
||||||
|
|
||||||
dst_s = target->s;
|
dst_s = target->s;
|
||||||
@@ -424,6 +427,10 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
dst_wp = target->wp;
|
dst_wp = target->wp;
|
||||||
dst_w = dst_wl->window;
|
dst_w = dst_wl->window;
|
||||||
dst_idx = dst_wl->idx;
|
dst_idx = dst_wl->idx;
|
||||||
|
ac = tc;
|
||||||
|
if (ac == NULL || ac->session != dst_s)
|
||||||
|
ac = c;
|
||||||
|
local = active_is_local_window(ac, dst_s);
|
||||||
|
|
||||||
if (cmd_get_entry(self) == &cmd_move_pane_entry) {
|
if (cmd_get_entry(self) == &cmd_move_pane_entry) {
|
||||||
if (args_has(args, 'M'))
|
if (args_has(args, 'M'))
|
||||||
@@ -511,9 +518,18 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
if (!args_has(args, 'd')) {
|
if (!args_has(args, 'd')) {
|
||||||
window_set_active_pane(dst_w, src_wp, 1);
|
window_set_active_pane(dst_w, src_wp, 1);
|
||||||
session_select(dst_s, dst_idx);
|
if (local)
|
||||||
cmd_find_from_session(current, dst_s, 0);
|
active_select_window(ac, dst_s, dst_wl);
|
||||||
server_redraw_session(dst_s);
|
else
|
||||||
|
session_select(dst_s, dst_idx);
|
||||||
|
if (local && ac != NULL && ac->session == dst_s)
|
||||||
|
cmd_find_from_client(current, ac, 0);
|
||||||
|
else
|
||||||
|
cmd_find_from_session(current, dst_s, 0);
|
||||||
|
if (local && ac != NULL && ac->session == dst_s)
|
||||||
|
server_redraw_client(ac);
|
||||||
|
else
|
||||||
|
server_redraw_session(dst_s);
|
||||||
} else
|
} else
|
||||||
server_status_session(dst_s);
|
server_status_session(dst_s);
|
||||||
|
|
||||||
|
|||||||
@@ -62,12 +62,15 @@ cmd_move_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct args *args = cmd_get_args(self);
|
struct args *args = cmd_get_args(self);
|
||||||
struct cmd_find_state *source = cmdq_get_source(item);
|
struct cmd_find_state *source = cmdq_get_source(item);
|
||||||
struct cmd_find_state target;
|
struct cmd_find_state target;
|
||||||
|
struct client *c = cmdq_get_client(item);
|
||||||
|
struct client *tc = cmdq_get_target_client(item);
|
||||||
|
struct client *ac;
|
||||||
const char *tflag = args_get(args, 't');
|
const char *tflag = args_get(args, 't');
|
||||||
struct session *src = source->s;
|
struct session *src = source->s;
|
||||||
struct session *dst;
|
struct session *dst;
|
||||||
struct winlink *wl = source->wl;
|
struct winlink *wl = source->wl, *dstwl, *current_wl;
|
||||||
char *cause;
|
char *cause;
|
||||||
int idx, kflag, dflag, sflag, before;
|
int idx, kflag, dflag, sflag, before, local;
|
||||||
|
|
||||||
if (args_has(args, 'r')) {
|
if (args_has(args, 'r')) {
|
||||||
if (cmd_find_target(&target, item, tflag, CMD_FIND_SESSION,
|
if (cmd_find_target(&target, item, tflag, CMD_FIND_SESSION,
|
||||||
@@ -90,23 +93,37 @@ cmd_move_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
dflag = args_has(args, 'd');
|
dflag = args_has(args, 'd');
|
||||||
sflag = args_has(args, 's');
|
sflag = args_has(args, 's');
|
||||||
|
|
||||||
|
ac = tc;
|
||||||
|
if (ac == NULL || ac->session != dst)
|
||||||
|
ac = c;
|
||||||
|
local = (!dflag && active_is_local_window(ac, dst));
|
||||||
|
|
||||||
before = args_has(args, 'b');
|
before = args_has(args, 'b');
|
||||||
if (args_has(args, 'a') || before) {
|
if (args_has(args, 'a') || before) {
|
||||||
if (target.wl != NULL)
|
if (target.wl != NULL)
|
||||||
idx = winlink_shuffle_up(dst, target.wl, before);
|
idx = winlink_shuffle_up(dst, target.wl, before);
|
||||||
else
|
else {
|
||||||
idx = winlink_shuffle_up(dst, dst->curw, before);
|
current_wl = active_get_effective_winlink(ac, dst);
|
||||||
|
idx = winlink_shuffle_up(dst, current_wl, before);
|
||||||
|
}
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
|
if (server_link_window(src, wl, dst, idx, kflag, !dflag && !local,
|
||||||
|
&cause) != 0) {
|
||||||
cmdq_error(item, "%s", cause);
|
cmdq_error(item, "%s", cause);
|
||||||
free(cause);
|
free(cause);
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
dstwl = winlink_find_by_window(&dst->windows, wl->window);
|
||||||
if (cmd_get_entry(self) == &cmd_move_window_entry)
|
if (cmd_get_entry(self) == &cmd_move_window_entry)
|
||||||
server_unlink_window(src, wl);
|
server_unlink_window(src, wl);
|
||||||
|
if (local && dstwl != NULL) {
|
||||||
|
active_select_window(ac, dst, dstwl);
|
||||||
|
if (ac != NULL && ac->session == dst)
|
||||||
|
server_redraw_client(ac);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Renumber the winlinks in the src session only, the destination
|
* Renumber the winlinks in the src session only, the destination
|
||||||
|
|||||||
@@ -58,9 +58,11 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct cmd_find_state *target = cmdq_get_target(item);
|
struct cmd_find_state *target = cmdq_get_target(item);
|
||||||
struct spawn_context sc = { 0 };
|
struct spawn_context sc = { 0 };
|
||||||
struct client *tc = cmdq_get_target_client(item);
|
struct client *tc = cmdq_get_target_client(item);
|
||||||
|
struct client *ac;
|
||||||
struct session *s = target->s;
|
struct session *s = target->s;
|
||||||
struct winlink *wl = target->wl, *new_wl = NULL;
|
struct winlink *wl = target->wl, *new_wl = NULL;
|
||||||
int idx = target->idx, before, count = args_count(args);
|
int idx = target->idx, before, count = args_count(args);
|
||||||
|
int detached, local;
|
||||||
char *cause = NULL, *cp, *expanded, *wname = NULL;
|
char *cause = NULL, *cp, *expanded, *wname = NULL;
|
||||||
const char *template, *name;
|
const char *template, *name;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
@@ -107,10 +109,15 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
free(wname);
|
free(wname);
|
||||||
if (args_has(args, 'd'))
|
if (args_has(args, 'd'))
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
if (session_set_current(s, new_wl) == 0)
|
if (active_select_window(c, s, new_wl) == 0) {
|
||||||
server_redraw_session(s);
|
if (active_is_local_window(c, s) && c != NULL &&
|
||||||
|
c->session == s)
|
||||||
|
server_redraw_client(c);
|
||||||
|
else
|
||||||
|
server_redraw_session(s);
|
||||||
|
}
|
||||||
if (c != NULL && c->session != NULL)
|
if (c != NULL && c->session != NULL)
|
||||||
s->curw->window->latest = c;
|
active_get_effective_window(c, s)->latest = c;
|
||||||
recalculate_sizes();
|
recalculate_sizes();
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
@@ -140,10 +147,16 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
sc.idx = idx;
|
sc.idx = idx;
|
||||||
sc.cwd = args_get(args, 'c');
|
sc.cwd = args_get(args, 'c');
|
||||||
|
|
||||||
|
ac = tc;
|
||||||
|
if (ac == NULL || ac->session != s)
|
||||||
|
ac = c;
|
||||||
|
detached = args_has(args, 'd');
|
||||||
|
local = (!detached && active_is_local_window(ac, s));
|
||||||
|
|
||||||
sc.flags = 0;
|
sc.flags = 0;
|
||||||
if (args_has(args, 'E') || (count == 1 && *args_string(args, 0) == '\0'))
|
if (args_has(args, 'E') || (count == 1 && *args_string(args, 0) == '\0'))
|
||||||
sc.flags |= SPAWN_EMPTY;
|
sc.flags |= SPAWN_EMPTY;
|
||||||
if (args_has(args, 'd'))
|
if (detached || local)
|
||||||
sc.flags |= SPAWN_DETACHED;
|
sc.flags |= SPAWN_DETACHED;
|
||||||
if (args_has(args, 'k'))
|
if (args_has(args, 'k'))
|
||||||
sc.flags |= SPAWN_KILL;
|
sc.flags |= SPAWN_KILL;
|
||||||
@@ -153,7 +166,13 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
free(cause);
|
free(cause);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!args_has(args, 'd') || new_wl == s->curw) {
|
if (local) {
|
||||||
|
if (active_select_window(ac, s, new_wl) == 0)
|
||||||
|
cmd_find_from_winlink(current, new_wl, 0);
|
||||||
|
if (ac != NULL && ac->session == s)
|
||||||
|
server_redraw_client(ac);
|
||||||
|
server_status_session_group(s);
|
||||||
|
} else if (!detached || new_wl == s->curw) {
|
||||||
cmd_find_from_winlink(current, new_wl, 0);
|
cmd_find_from_winlink(current, new_wl, 0);
|
||||||
server_redraw_session_group(s);
|
server_redraw_session_group(s);
|
||||||
} else
|
} else
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
if (args_has(args, 'c'))
|
if (args_has(args, 'c'))
|
||||||
tc->pan_window = NULL;
|
tc->pan_window = NULL;
|
||||||
else {
|
else {
|
||||||
w = tc->session->curw->window;
|
w = active_get_effective_window(tc, tc->session);
|
||||||
if (tc->pan_window != w) {
|
if (tc->pan_window != w) {
|
||||||
tc->pan_window = w;
|
tc->pan_window = w;
|
||||||
tc->pan_ox = tty->oox;
|
tc->pan_ox = tty->oox;
|
||||||
|
|||||||
@@ -79,7 +79,10 @@ static void
|
|||||||
cmd_run_shell_print(struct job *job, const char *msg)
|
cmd_run_shell_print(struct job *job, const char *msg)
|
||||||
{
|
{
|
||||||
struct cmd_run_shell_data *cdata = job_get_data(job);
|
struct cmd_run_shell_data *cdata = job_get_data(job);
|
||||||
|
struct client *c;
|
||||||
|
struct session *s;
|
||||||
struct window_pane *wp = NULL;
|
struct window_pane *wp = NULL;
|
||||||
|
struct window *w;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
struct window_mode_entry *wme;
|
struct window_mode_entry *wme;
|
||||||
|
|
||||||
@@ -90,8 +93,12 @@ cmd_run_shell_print(struct job *job, const char *msg)
|
|||||||
cmdq_print(cdata->item, "%s", msg);
|
cmdq_print(cdata->item, "%s", msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cdata->client != NULL && cdata->client->session != NULL)
|
c = cdata->client;
|
||||||
wp = cdata->client->session->curw->window->active;
|
if (c != NULL && c->session != NULL) {
|
||||||
|
s = c->session;
|
||||||
|
w = active_get_effective_window(c, s);
|
||||||
|
wp = w->active;
|
||||||
|
}
|
||||||
if (wp == NULL && cmd_find_from_nothing(&fs, 0) == 0)
|
if (wp == NULL && cmd_find_from_nothing(&fs, 0) == 0)
|
||||||
wp = fs.wp;
|
wp = fs.wp;
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
|
|||||||
@@ -68,10 +68,11 @@ cmd_select_pane_redraw(struct window *w)
|
|||||||
TAILQ_FOREACH(c, &clients, entry) {
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
if (c->session == NULL || (c->flags & CLIENT_CONTROL))
|
if (c->session == NULL || (c->flags & CLIENT_CONTROL))
|
||||||
continue;
|
continue;
|
||||||
if (c->session->curw->window == w && tty_window_bigger(&c->tty))
|
if (active_get_effective_window(c, c->session) == w &&
|
||||||
|
tty_window_bigger(&c->tty))
|
||||||
server_redraw_client(c);
|
server_redraw_client(c);
|
||||||
else {
|
else {
|
||||||
if (c->session->curw->window == w)
|
if (active_get_effective_window(c, c->session) == w)
|
||||||
c->flags |= CLIENT_REDRAWBORDERS;
|
c->flags |= CLIENT_REDRAWBORDERS;
|
||||||
if (session_has(c->session, w))
|
if (session_has(c->session, w))
|
||||||
c->flags |= CLIENT_REDRAWSTATUS;
|
c->flags |= CLIENT_REDRAWSTATUS;
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ const struct cmd_entry cmd_select_window_entry = {
|
|||||||
.name = "select-window",
|
.name = "select-window",
|
||||||
.alias = "selectw",
|
.alias = "selectw",
|
||||||
|
|
||||||
.args = { "lnpTt:", 0, 0, NULL },
|
.args = { "LlSnpTt:", 0, 0, NULL },
|
||||||
.usage = "[-lnpT] " CMD_TARGET_WINDOW_USAGE,
|
.usage = "[-LlnpST] " CMD_TARGET_WINDOW_USAGE,
|
||||||
|
|
||||||
.target = { 't', CMD_FIND_WINDOW, 0 },
|
.target = { 't', CMD_FIND_WINDOW, 0 },
|
||||||
|
|
||||||
@@ -88,8 +88,9 @@ cmd_select_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct client *c = cmdq_get_client(item);
|
struct client *c = cmdq_get_client(item);
|
||||||
struct cmd_find_state *current = cmdq_get_current(item);
|
struct cmd_find_state *current = cmdq_get_current(item);
|
||||||
struct cmd_find_state *target = cmdq_get_target(item);
|
struct cmd_find_state *target = cmdq_get_target(item);
|
||||||
struct winlink *wl = target->wl;
|
struct winlink *wl = target->wl, *current_wl;
|
||||||
struct session *s = target->s;
|
struct session *s = target->s;
|
||||||
|
enum active_window_mode mode;
|
||||||
int next, previous, last, activity;
|
int next, previous, last, activity;
|
||||||
|
|
||||||
next = (cmd_get_entry(self) == &cmd_next_window_entry);
|
next = (cmd_get_entry(self) == &cmd_next_window_entry);
|
||||||
@@ -102,48 +103,104 @@ cmd_select_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
if (args_has(args, 'l'))
|
if (args_has(args, 'l'))
|
||||||
last = 1;
|
last = 1;
|
||||||
|
|
||||||
|
if (args_has(args, 'L') || args_has(args, 'S')) {
|
||||||
|
if (c == NULL || c->session == NULL) {
|
||||||
|
cmdq_error(item, "no current client");
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
if (args_has(args, 'S'))
|
||||||
|
mode = ACTIVE_SHARED;
|
||||||
|
else
|
||||||
|
mode = ACTIVE_LOCAL;
|
||||||
|
active_set_local_window(c, s, mode);
|
||||||
|
if (!next &&
|
||||||
|
!previous &&
|
||||||
|
!last &&
|
||||||
|
!args_has(args, 't') &&
|
||||||
|
!args_has(args, 'T')) {
|
||||||
|
if (current->s == s) {
|
||||||
|
if (c->session == s)
|
||||||
|
cmd_find_from_client(current, c, 0);
|
||||||
|
else
|
||||||
|
cmd_find_from_session(current, s, 0);
|
||||||
|
}
|
||||||
|
if (c->session == s)
|
||||||
|
server_redraw_client(c);
|
||||||
|
else
|
||||||
|
server_redraw_session(s);
|
||||||
|
cmdq_insert_hook(s, item, current, "after-select-window");
|
||||||
|
recalculate_sizes();
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active_is_local_window(c, s))
|
||||||
|
mode = ACTIVE_LOCAL;
|
||||||
|
else
|
||||||
|
mode = ACTIVE_SHARED;
|
||||||
if (next || previous || last) {
|
if (next || previous || last) {
|
||||||
activity = args_has(args, 'a');
|
activity = args_has(args, 'a');
|
||||||
if (next) {
|
if (next) {
|
||||||
if (session_next(s, activity) != 0) {
|
if (active_next_window(c, s, activity) != 0) {
|
||||||
cmdq_error(item, "no next window");
|
cmdq_error(item, "no next window");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
} else if (previous) {
|
} else if (previous) {
|
||||||
if (session_previous(s, activity) != 0) {
|
if (active_previous_window(c, s, activity) != 0) {
|
||||||
cmdq_error(item, "no previous window");
|
cmdq_error(item, "no previous window");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (session_last(s) != 0) {
|
if (active_last_window(c, s) != 0) {
|
||||||
cmdq_error(item, "no last window");
|
cmdq_error(item, "no last window");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd_find_from_session(current, s, 0);
|
if (mode == ACTIVE_LOCAL && c != NULL && c->session == s)
|
||||||
server_redraw_session(s);
|
cmd_find_from_client(current, c, 0);
|
||||||
|
else
|
||||||
|
cmd_find_from_session(current, s, 0);
|
||||||
|
if (mode == ACTIVE_LOCAL && c != NULL && c->session == s)
|
||||||
|
server_redraw_client(c);
|
||||||
|
else
|
||||||
|
server_redraw_session(s);
|
||||||
cmdq_insert_hook(s, item, current, "after-select-window");
|
cmdq_insert_hook(s, item, current, "after-select-window");
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* If -T and select-window is invoked on same window as
|
* If -T and select-window is invoked on same window as
|
||||||
* current, switch to previous window.
|
* current, switch to previous window.
|
||||||
*/
|
*/
|
||||||
if (args_has(args, 'T') && wl == s->curw) {
|
current_wl = active_get_effective_winlink(c, s);
|
||||||
if (session_last(s) != 0) {
|
if (args_has(args, 'T') && wl == current_wl) {
|
||||||
|
if (active_last_window(c, s) != 0) {
|
||||||
cmdq_error(item, "no last window");
|
cmdq_error(item, "no last window");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
if (current->s == s)
|
if (current->s == s) {
|
||||||
|
if (mode == ACTIVE_LOCAL && c != NULL &&
|
||||||
|
c->session == s)
|
||||||
|
cmd_find_from_client(current, c, 0);
|
||||||
|
else
|
||||||
|
cmd_find_from_session(current, s, 0);
|
||||||
|
}
|
||||||
|
if (mode == ACTIVE_LOCAL && c != NULL && c->session == s)
|
||||||
|
server_redraw_client(c);
|
||||||
|
else
|
||||||
|
server_redraw_session(s);
|
||||||
|
} else if (active_select_window(c, s, wl) == 0) {
|
||||||
|
if (mode == ACTIVE_LOCAL && c != NULL && c->session == s)
|
||||||
|
cmd_find_from_client(current, c, 0);
|
||||||
|
else
|
||||||
cmd_find_from_session(current, s, 0);
|
cmd_find_from_session(current, s, 0);
|
||||||
server_redraw_session(s);
|
if (mode == ACTIVE_LOCAL && c != NULL && c->session == s)
|
||||||
} else if (session_select(s, wl->idx) == 0) {
|
server_redraw_client(c);
|
||||||
cmd_find_from_session(current, s, 0);
|
else
|
||||||
server_redraw_session(s);
|
server_redraw_session(s);
|
||||||
}
|
}
|
||||||
cmdq_insert_hook(s, item, current, "after-select-window");
|
cmdq_insert_hook(s, item, current, "after-select-window");
|
||||||
}
|
}
|
||||||
if (c != NULL && c->session != NULL)
|
if (c != NULL && c->session != NULL)
|
||||||
s->curw->window->latest = c;
|
active_get_effective_window(c, s)->latest = c;
|
||||||
recalculate_sizes();
|
recalculate_sizes();
|
||||||
|
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
|
|||||||
@@ -48,10 +48,14 @@ cmd_swap_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct args *args = cmd_get_args(self);
|
struct args *args = cmd_get_args(self);
|
||||||
struct cmd_find_state *source = cmdq_get_source(item);
|
struct cmd_find_state *source = cmdq_get_source(item);
|
||||||
struct cmd_find_state *target = cmdq_get_target(item);
|
struct cmd_find_state *target = cmdq_get_target(item);
|
||||||
|
struct client *c = cmdq_get_client(item);
|
||||||
|
struct client *tc = cmdq_get_target_client(item);
|
||||||
|
struct client *ac;
|
||||||
struct session *src = source->s, *dst = target->s;
|
struct session *src = source->s, *dst = target->s;
|
||||||
struct session_group *sg_src, *sg_dst;
|
struct session_group *sg_src, *sg_dst;
|
||||||
struct winlink *wl_src = source->wl, *wl_dst = target->wl;
|
struct winlink *wl_src = source->wl, *wl_dst = target->wl;
|
||||||
struct window *w_src, *w_dst;
|
struct window *w_src, *w_dst;
|
||||||
|
int local_src, local_dst;
|
||||||
|
|
||||||
sg_src = session_group_contains(src);
|
sg_src = session_group_contains(src);
|
||||||
sg_dst = session_group_contains(dst);
|
sg_dst = session_group_contains(dst);
|
||||||
@@ -79,10 +83,22 @@ cmd_swap_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
if (marked_pane.wl == wl_src)
|
if (marked_pane.wl == wl_src)
|
||||||
marked_pane.wl = wl_dst;
|
marked_pane.wl = wl_dst;
|
||||||
|
ac = tc;
|
||||||
|
if (ac == NULL)
|
||||||
|
ac = c;
|
||||||
|
local_dst = active_is_local_window(ac, dst);
|
||||||
|
local_src = active_is_local_window(ac, src);
|
||||||
if (args_has(args, 'd')) {
|
if (args_has(args, 'd')) {
|
||||||
session_select(dst, wl_dst->idx);
|
if (local_dst)
|
||||||
if (src != dst)
|
active_select_window(ac, dst, wl_dst);
|
||||||
session_select(src, wl_src->idx);
|
else
|
||||||
|
session_select(dst, wl_dst->idx);
|
||||||
|
if (src != dst) {
|
||||||
|
if (local_src)
|
||||||
|
active_select_window(ac, src, wl_src);
|
||||||
|
else
|
||||||
|
session_select(src, wl_src->idx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
session_group_synchronize_from(src);
|
session_group_synchronize_from(src);
|
||||||
server_redraw_session_group(src);
|
server_redraw_session_group(src);
|
||||||
|
|||||||
@@ -53,11 +53,11 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct cmd_find_state target;
|
struct cmd_find_state target;
|
||||||
const char *tflag = args_get(args, 't');
|
const char *tflag = args_get(args, 't');
|
||||||
enum cmd_find_type type;
|
enum cmd_find_type type;
|
||||||
int flags;
|
int flags, window_target;
|
||||||
struct client *c = cmdq_get_client(item);
|
struct client *c = cmdq_get_client(item);
|
||||||
struct client *tc = cmdq_get_target_client(item);
|
struct client *tc = cmdq_get_target_client(item);
|
||||||
struct session *s;
|
struct session *s;
|
||||||
struct winlink *wl;
|
struct winlink *wl, *current_wl;
|
||||||
struct window *w;
|
struct window *w;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
const char *tablename;
|
const char *tablename;
|
||||||
@@ -65,8 +65,13 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct sort_criteria sort_crit;
|
struct sort_criteria sort_crit;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
|
|
||||||
if (tflag != NULL &&
|
window_target = 0;
|
||||||
(tflag[strcspn(tflag, ":.%")] != '\0' || strcmp(tflag, "=") == 0)) {
|
if (tflag != NULL) {
|
||||||
|
if (tflag[strcspn(tflag, ":.%")] != '\0' ||
|
||||||
|
strcmp(tflag, "=") == 0)
|
||||||
|
window_target = 1;
|
||||||
|
}
|
||||||
|
if (window_target) {
|
||||||
type = CMD_FIND_PANE;
|
type = CMD_FIND_PANE;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -137,7 +142,8 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
} else {
|
} else {
|
||||||
if (cmdq_get_client(item) == NULL)
|
if (cmdq_get_client(item) == NULL)
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
if (wl != NULL && wp != NULL && wp != wl->window->active) {
|
if (window_target && wl != NULL && wp != NULL &&
|
||||||
|
wp != wl->window->active) {
|
||||||
w = wl->window;
|
w = wl->window;
|
||||||
if (window_push_zoom(w, 0, args_has(args, 'Z')))
|
if (window_push_zoom(w, 0, args_has(args, 'Z')))
|
||||||
server_redraw_window(w);
|
server_redraw_window(w);
|
||||||
@@ -146,9 +152,13 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
if (window_pop_zoom(w))
|
if (window_pop_zoom(w))
|
||||||
server_redraw_window(w);
|
server_redraw_window(w);
|
||||||
}
|
}
|
||||||
if (wl != NULL) {
|
if (window_target && wl != NULL) {
|
||||||
session_set_current(s, wl);
|
active_select_window(tc, s, wl);
|
||||||
cmd_find_from_session(current, s, 0);
|
if (active_is_local_window(tc, s)) {
|
||||||
|
current_wl = active_get_effective_winlink(tc, s);
|
||||||
|
cmd_find_from_winlink(current, current_wl, 0);
|
||||||
|
} else
|
||||||
|
cmd_find_from_session(current, s, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -215,6 +215,28 @@ control_client_session_changed_cb(__unused const char *name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Notify control clients that a client changed its effective window. */
|
||||||
|
static void
|
||||||
|
control_client_window_changed_cb(__unused const char *name,
|
||||||
|
struct event_payload *ep, __unused void *sink_data)
|
||||||
|
{
|
||||||
|
struct client *cc = event_payload_get_client(ep, "client");
|
||||||
|
struct session *s = event_payload_get_session(ep, "session");
|
||||||
|
struct window *w = event_payload_get_window(ep, "window");
|
||||||
|
struct client *c;
|
||||||
|
|
||||||
|
if (cc == NULL || s == NULL || w == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
|
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
control_write(c, "%%client-window-changed %s $%u @%u",
|
||||||
|
cc->name, s->id, w->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Notify control clients that a client detached. */
|
/* Notify control clients that a client detached. */
|
||||||
static void
|
static void
|
||||||
control_client_detached_cb(__unused const char *name, struct event_payload *ep,
|
control_client_detached_cb(__unused const char *name, struct event_payload *ep,
|
||||||
@@ -356,6 +378,7 @@ control_build_events(void)
|
|||||||
{ "window-linked", control_window_linked_cb },
|
{ "window-linked", control_window_linked_cb },
|
||||||
{ "window-renamed", control_window_renamed_cb },
|
{ "window-renamed", control_window_renamed_cb },
|
||||||
{ "client-session-changed", control_client_session_changed_cb },
|
{ "client-session-changed", control_client_session_changed_cb },
|
||||||
|
{ "client-window-changed", control_client_window_changed_cb },
|
||||||
{ "client-detached", control_client_detached_cb },
|
{ "client-detached", control_client_detached_cb },
|
||||||
{ "session-renamed", control_session_renamed_cb },
|
{ "session-renamed", control_session_renamed_cb },
|
||||||
{ "session-created", control_session_created_cb },
|
{ "session-created", control_session_created_cb },
|
||||||
|
|||||||
89
format.c
89
format.c
@@ -800,7 +800,7 @@ format_cb_window_active_clients(struct format_tree *ft)
|
|||||||
if (client_session == NULL)
|
if (client_session == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (w == client_session->curw->window)
|
if (w == active_get_effective_window(loop, client_session))
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -832,7 +832,7 @@ format_cb_window_active_clients_list(struct format_tree *ft)
|
|||||||
if (client_session == NULL)
|
if (client_session == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (w == client_session->curw->window) {
|
if (w == active_get_effective_window(loop, client_session)) {
|
||||||
if (EVBUFFER_LENGTH(buffer) > 0)
|
if (EVBUFFER_LENGTH(buffer) > 0)
|
||||||
evbuffer_add(buffer, ",", 1);
|
evbuffer_add(buffer, ",", 1);
|
||||||
evbuffer_add_printf(buffer, "%s", loop->name);
|
evbuffer_add_printf(buffer, "%s", loop->name);
|
||||||
@@ -2886,11 +2886,48 @@ format_cb_sixel_support(__unused struct format_tree *ft)
|
|||||||
static void *
|
static void *
|
||||||
format_cb_active_window_index(struct format_tree *ft)
|
format_cb_active_window_index(struct format_tree *ft)
|
||||||
{
|
{
|
||||||
if (ft->s != NULL)
|
struct winlink *wl;
|
||||||
return (format_printf("%u", ft->s->curw->idx));
|
|
||||||
|
if (ft->s != NULL) {
|
||||||
|
wl = active_get_effective_winlink(ft->c, ft->s);
|
||||||
|
if (wl != NULL)
|
||||||
|
return (format_printf("%u", wl->idx));
|
||||||
|
}
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Callback for active_window_id. */
|
||||||
|
static void *
|
||||||
|
format_cb_active_window_id(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
struct winlink *wl;
|
||||||
|
|
||||||
|
if (ft->s != NULL) {
|
||||||
|
wl = active_get_effective_winlink(ft->c, ft->s);
|
||||||
|
if (wl != NULL)
|
||||||
|
return (format_printf("@%u", wl->window->id));
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for local_active_window. */
|
||||||
|
static void *
|
||||||
|
format_cb_local_active_window(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
if (ft->c != NULL && ft->s != NULL)
|
||||||
|
return (format_printf("%d", active_is_local_window(ft->c, ft->s)));
|
||||||
|
return (xstrdup("0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for active_window_mode. */
|
||||||
|
static void *
|
||||||
|
format_cb_active_window_mode(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
if (ft->c != NULL && ft->s != NULL && active_is_local_window(ft->c, ft->s))
|
||||||
|
return (xstrdup("local"));
|
||||||
|
return (xstrdup("shared"));
|
||||||
|
}
|
||||||
|
|
||||||
/* Callback for last_window_index. */
|
/* Callback for last_window_index. */
|
||||||
static void *
|
static void *
|
||||||
format_cb_last_window_index(struct format_tree *ft)
|
format_cb_last_window_index(struct format_tree *ft)
|
||||||
@@ -2908,8 +2945,11 @@ format_cb_last_window_index(struct format_tree *ft)
|
|||||||
static void *
|
static void *
|
||||||
format_cb_window_active(struct format_tree *ft)
|
format_cb_window_active(struct format_tree *ft)
|
||||||
{
|
{
|
||||||
|
struct winlink *wl;
|
||||||
|
|
||||||
if (ft->wl != NULL) {
|
if (ft->wl != NULL) {
|
||||||
if (ft->wl == ft->wl->session->curw)
|
wl = active_get_effective_winlink(ft->c, ft->wl->session);
|
||||||
|
if (ft->wl == wl)
|
||||||
return (xstrdup("1"));
|
return (xstrdup("1"));
|
||||||
return (xstrdup("0"));
|
return (xstrdup("0"));
|
||||||
}
|
}
|
||||||
@@ -2989,7 +3029,7 @@ static void *
|
|||||||
format_cb_window_flags(struct format_tree *ft)
|
format_cb_window_flags(struct format_tree *ft)
|
||||||
{
|
{
|
||||||
if (ft->wl != NULL)
|
if (ft->wl != NULL)
|
||||||
return (xstrdup(window_printable_flags(ft->wl, 1)));
|
return (xstrdup(window_printable_flags(ft->c, ft->wl, 1)));
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3176,7 +3216,7 @@ static void *
|
|||||||
format_cb_window_raw_flags(struct format_tree *ft)
|
format_cb_window_raw_flags(struct format_tree *ft)
|
||||||
{
|
{
|
||||||
if (ft->wl != NULL)
|
if (ft->wl != NULL)
|
||||||
return (xstrdup(window_printable_flags(ft->wl, 0)));
|
return (xstrdup(window_printable_flags(ft->c, ft->wl, 0)));
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3386,9 +3426,15 @@ struct format_table_entry {
|
|||||||
* Only variables which are added by the caller go into the tree.
|
* Only variables which are added by the caller go into the tree.
|
||||||
*/
|
*/
|
||||||
static const struct format_table_entry format_table[] = {
|
static const struct format_table_entry format_table[] = {
|
||||||
|
{ "active_window_id", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_active_window_id
|
||||||
|
},
|
||||||
{ "active_window_index", FORMAT_TABLE_STRING,
|
{ "active_window_index", FORMAT_TABLE_STRING,
|
||||||
format_cb_active_window_index
|
format_cb_active_window_index
|
||||||
},
|
},
|
||||||
|
{ "active_window_mode", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_active_window_mode
|
||||||
|
},
|
||||||
{ "alternate_on", FORMAT_TABLE_STRING,
|
{ "alternate_on", FORMAT_TABLE_STRING,
|
||||||
format_cb_alternate_on
|
format_cb_alternate_on
|
||||||
},
|
},
|
||||||
@@ -3557,6 +3603,9 @@ static const struct format_table_entry format_table[] = {
|
|||||||
{ "last_window_index", FORMAT_TABLE_STRING,
|
{ "last_window_index", FORMAT_TABLE_STRING,
|
||||||
format_cb_last_window_index
|
format_cb_last_window_index
|
||||||
},
|
},
|
||||||
|
{ "local_active_window", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_local_active_window
|
||||||
|
},
|
||||||
{ "mouse_all_flag", FORMAT_TABLE_STRING,
|
{ "mouse_all_flag", FORMAT_TABLE_STRING,
|
||||||
format_cb_mouse_all_flag
|
format_cb_mouse_all_flag
|
||||||
},
|
},
|
||||||
@@ -5092,15 +5141,18 @@ format_add_window_neighbour(struct format_tree *nft, struct winlink *wl,
|
|||||||
struct session *s, const char *prefix)
|
struct session *s, const char *prefix)
|
||||||
{
|
{
|
||||||
struct options_entry *o;
|
struct options_entry *o;
|
||||||
|
struct winlink *current;
|
||||||
const char *oname;
|
const char *oname;
|
||||||
char *key, *prefixed, *oval;
|
char *key, *prefixed, *oval;
|
||||||
|
|
||||||
|
current = active_get_effective_winlink(nft->c, s);
|
||||||
|
|
||||||
xasprintf(&key, "%s_window_index", prefix);
|
xasprintf(&key, "%s_window_index", prefix);
|
||||||
format_add(nft, key, "%u", wl->idx);
|
format_add(nft, key, "%u", wl->idx);
|
||||||
free(key);
|
free(key);
|
||||||
|
|
||||||
xasprintf(&key, "%s_window_active", prefix);
|
xasprintf(&key, "%s_window_active", prefix);
|
||||||
format_add(nft, key, "%d", wl == s->curw);
|
format_add(nft, key, "%d", wl == current);
|
||||||
free(key);
|
free(key);
|
||||||
|
|
||||||
o = options_first(wl->window->options);
|
o = options_first(wl->window->options);
|
||||||
@@ -5128,10 +5180,10 @@ format_loop_windows(struct format_expand_state *es, const char *fmt)
|
|||||||
struct cmdq_item *item = ft->item;
|
struct cmdq_item *item = ft->item;
|
||||||
struct format_tree *nft;
|
struct format_tree *nft;
|
||||||
struct format_expand_state next;
|
struct format_expand_state next;
|
||||||
char *all, *active, *use, *expanded, *value;
|
char *all, *active_fmt, *use, *expanded, *value;
|
||||||
struct evbuffer *buffer;
|
struct evbuffer *buffer;
|
||||||
size_t size;
|
size_t size;
|
||||||
struct winlink *wl, **l;
|
struct winlink *wl, **l, *active_wl;
|
||||||
struct window *w;
|
struct window *w;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
|
||||||
@@ -5140,9 +5192,9 @@ format_loop_windows(struct format_expand_state *es, const char *fmt)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format_choose(es, fmt, &all, &active, 0) != 0) {
|
if (format_choose(es, fmt, &all, &active_fmt, 0) != 0) {
|
||||||
all = xstrdup(fmt);
|
all = xstrdup(fmt);
|
||||||
active = NULL;
|
active_fmt = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = evbuffer_new();
|
buffer = evbuffer_new();
|
||||||
@@ -5150,12 +5202,13 @@ format_loop_windows(struct format_expand_state *es, const char *fmt)
|
|||||||
fatalx("out of memory");
|
fatalx("out of memory");
|
||||||
|
|
||||||
l = sort_get_winlinks_session(s, &n, sc);
|
l = sort_get_winlinks_session(s, &n, sc);
|
||||||
|
active_wl = active_get_effective_winlink(ft->c, s);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
wl = l[i];
|
wl = l[i];
|
||||||
w = wl->window;
|
w = wl->window;
|
||||||
format_log(es, "window loop: %u @%u", wl->idx, w->id);
|
format_log(es, "window loop: %u @%u", wl->idx, w->id);
|
||||||
if (active != NULL && wl == s->curw)
|
if (active_fmt != NULL && wl == active_wl)
|
||||||
use = active;
|
use = active_fmt;
|
||||||
else
|
else
|
||||||
use = all;
|
use = all;
|
||||||
nft = format_create(c, item, FORMAT_WINDOW|w->id, ft->flags);
|
nft = format_create(c, item, FORMAT_WINDOW|w->id, ft->flags);
|
||||||
@@ -5164,11 +5217,11 @@ format_loop_windows(struct format_expand_state *es, const char *fmt)
|
|||||||
format_add(nft, "loop_last_flag", "%d", i == n - 1);
|
format_add(nft, "loop_last_flag", "%d", i == n - 1);
|
||||||
|
|
||||||
/* Add neighbour window data to the format tree. */
|
/* Add neighbour window data to the format tree. */
|
||||||
if (i > 0 && l[i - 1] == s->curw)
|
if (i > 0 && l[i - 1] == active_wl)
|
||||||
format_add(nft, "window_after_active", "1");
|
format_add(nft, "window_after_active", "1");
|
||||||
else
|
else
|
||||||
format_add(nft, "window_after_active", "0");
|
format_add(nft, "window_after_active", "0");
|
||||||
if (i + 1 < n && l[i + 1] == s->curw)
|
if (i + 1 < n && l[i + 1] == active_wl)
|
||||||
format_add(nft, "window_before_active", "1");
|
format_add(nft, "window_before_active", "1");
|
||||||
else
|
else
|
||||||
format_add(nft, "window_before_active", "0");
|
format_add(nft, "window_before_active", "0");
|
||||||
@@ -5188,7 +5241,7 @@ format_loop_windows(struct format_expand_state *es, const char *fmt)
|
|||||||
free(expanded);
|
free(expanded);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(active);
|
free(active_fmt);
|
||||||
free(all);
|
free(all);
|
||||||
|
|
||||||
if ((size = EVBUFFER_LENGTH(buffer)) != 0)
|
if ((size = EVBUFFER_LENGTH(buffer)) != 0)
|
||||||
@@ -6691,7 +6744,7 @@ format_defaults(struct format_tree *ft, struct client *c, struct session *s,
|
|||||||
if (s == NULL && c != NULL)
|
if (s == NULL && c != NULL)
|
||||||
s = c->session;
|
s = c->session;
|
||||||
if (wl == NULL && s != NULL)
|
if (wl == NULL && s != NULL)
|
||||||
wl = s->curw;
|
wl = active_get_effective_winlink(c, s);
|
||||||
if (wp == NULL && wl != NULL)
|
if (wp == NULL && wl != NULL)
|
||||||
wp = wl->window->active;
|
wp = wl->window->active;
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
" 'Rename' 'r' {command-prompt -I '#S' {rename-session -- '%%'}}" \
|
" 'Rename' 'r' {command-prompt -I '#S' {rename-session -- '%%'}}" \
|
||||||
" 'Detach' 'd' {detach-client}" \
|
" 'Detach' 'd' {detach-client}" \
|
||||||
" ''" \
|
" ''" \
|
||||||
|
" '#{?local_active_window,Shared Window,Local Window}' 'L' {select-window #{?local_active_window,-S,-L}}" \
|
||||||
|
" ''" \
|
||||||
" 'New Session' 's' {new-session}" \
|
" 'New Session' 's' {new-session}" \
|
||||||
" 'New Window' 'w' {new-window}"
|
" 'New Window' 'w' {new-window}"
|
||||||
#define DEFAULT_WINDOW_MENU \
|
#define DEFAULT_WINDOW_MENU \
|
||||||
|
|||||||
2
menu.c
2
menu.c
@@ -584,7 +584,7 @@ menu_display(struct menu *menu, int flags, int starting_choice,
|
|||||||
struct options *o;
|
struct options *o;
|
||||||
|
|
||||||
if (fs == NULL)
|
if (fs == NULL)
|
||||||
w = c->session->curw->window;
|
w = active_get_effective_window(c, c->session);
|
||||||
else
|
else
|
||||||
w = fs->w;
|
w = fs->w;
|
||||||
o = w->options;
|
o = w->options;
|
||||||
|
|||||||
@@ -1115,7 +1115,8 @@ const struct options_table_entry options_table[] = {
|
|||||||
{ .name = "status-style",
|
{ .name = "status-style",
|
||||||
.type = OPTIONS_TABLE_STRING,
|
.type = OPTIONS_TABLE_STRING,
|
||||||
.scope = OPTIONS_TABLE_SESSION,
|
.scope = OPTIONS_TABLE_SESSION,
|
||||||
.default_str = "bg=themegreen,fg=themeblack",
|
.default_str = "bg=#{?local_active_window,themeblue,themegreen},"
|
||||||
|
"fg=themeblack",
|
||||||
.flags = OPTIONS_TABLE_IS_STYLE,
|
.flags = OPTIONS_TABLE_IS_STYLE,
|
||||||
.separator = ",",
|
.separator = ",",
|
||||||
.text = "Style of the status line."
|
.text = "Style of the status line."
|
||||||
@@ -1960,6 +1961,8 @@ const struct options_table_entry options_table[] = {
|
|||||||
"Run when a client is resized."),
|
"Run when a client is resized."),
|
||||||
OPTIONS_TABLE_HOOK("client-session-changed", "",
|
OPTIONS_TABLE_HOOK("client-session-changed", "",
|
||||||
"Run when a client's attached session is changed."),
|
"Run when a client's attached session is changed."),
|
||||||
|
OPTIONS_TABLE_HOOK("client-window-changed", "",
|
||||||
|
"Run when a client's effective window is changed."),
|
||||||
OPTIONS_TABLE_HOOK("client-light-theme", "",
|
OPTIONS_TABLE_HOOK("client-light-theme", "",
|
||||||
"Run when a client switches to a light theme."),
|
"Run when a client switches to a light theme."),
|
||||||
OPTIONS_TABLE_HOOK("client-dark-theme", "",
|
OPTIONS_TABLE_HOOK("client-dark-theme", "",
|
||||||
|
|||||||
8
popup.c
8
popup.c
@@ -102,9 +102,9 @@ popup_reapply_styles(struct popup_data *pd)
|
|||||||
|
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
return;
|
return;
|
||||||
o = s->curw->window->options;
|
o = active_get_effective_window(c, s)->options;
|
||||||
|
|
||||||
ft = format_create_defaults(NULL, c, s, s->curw, NULL);
|
ft = format_create_defaults(NULL, c, s, NULL, NULL);
|
||||||
|
|
||||||
/* Reapply popup style from options. */
|
/* Reapply popup style from options. */
|
||||||
memcpy(&pd->defaults, &grid_default_cell, sizeof pd->defaults);
|
memcpy(&pd->defaults, &grid_default_cell, sizeof pd->defaults);
|
||||||
@@ -569,9 +569,9 @@ popup_display(int flags, enum box_lines lines, struct cmdq_item *item, u_int px,
|
|||||||
struct style sytmp;
|
struct style sytmp;
|
||||||
|
|
||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
o = s->curw->window->options;
|
o = active_get_effective_window(c, s)->options;
|
||||||
else
|
else
|
||||||
o = c->session->curw->window->options;
|
o = active_get_effective_window(c, c->session)->options;
|
||||||
|
|
||||||
if (lines == BOX_LINES_DEFAULT)
|
if (lines == BOX_LINES_DEFAULT)
|
||||||
lines = options_get_number(o, "popup-border-lines");
|
lines = options_get_number(o, "popup-border-lines");
|
||||||
|
|||||||
151
regress/active-window.sh
Normal file
151
regress/active-window.sh
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
LC_ALL=C.UTF-8
|
||||||
|
LANG=C.UTF-8
|
||||||
|
export TERM LC_ALL LANG
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
TMUX="$TEST_TMUX -LtestA$$ -f/dev/null"
|
||||||
|
|
||||||
|
TMPDIR=$(mktemp -d)
|
||||||
|
IN1="$TMPDIR/in1"
|
||||||
|
IN2="$TMPDIR/in2"
|
||||||
|
OUT1="$TMPDIR/out1"
|
||||||
|
OUT2="$TMPDIR/out2"
|
||||||
|
PID1=
|
||||||
|
PID2=
|
||||||
|
|
||||||
|
cleanup()
|
||||||
|
{
|
||||||
|
[ -n "$PID1" ] && kill "$PID1" 2>/dev/null
|
||||||
|
[ -n "$PID2" ] && kill "$PID2" 2>/dev/null
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
rm -rf "$TMPDIR"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
fail()
|
||||||
|
{
|
||||||
|
echo "$1"
|
||||||
|
echo "client1:"
|
||||||
|
cat "$OUT1" 2>/dev/null
|
||||||
|
echo "client2:"
|
||||||
|
cat "$OUT2" 2>/dev/null
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for()
|
||||||
|
{
|
||||||
|
file=$1
|
||||||
|
pattern=$2
|
||||||
|
i=0
|
||||||
|
|
||||||
|
while [ "$i" -lt 60 ]; do
|
||||||
|
if grep -F -- "$pattern" "$file" >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
sleep 0.1
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
fail "missing '$pattern' in $file"
|
||||||
|
}
|
||||||
|
|
||||||
|
send1()
|
||||||
|
{
|
||||||
|
printf '%s\n' "$*" >&3
|
||||||
|
}
|
||||||
|
|
||||||
|
send2()
|
||||||
|
{
|
||||||
|
printf '%s\n' "$*" >&4
|
||||||
|
}
|
||||||
|
|
||||||
|
check_server()
|
||||||
|
{
|
||||||
|
out=$($TMUX display-message -p -t "$1" "$2")
|
||||||
|
[ "$out" = "$3" ] || fail "expected '$3' for $1 $2, got '$out'"
|
||||||
|
}
|
||||||
|
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
$TMUX new-session -d -s aw -x 80 -y 24 -n w0 || exit 1
|
||||||
|
$TMUX new-window -d -t aw: -n w1 || exit 1
|
||||||
|
$TMUX new-window -d -t aw: -n w2 || exit 1
|
||||||
|
$TMUX new-session -d -s aw2 -x 80 -y 24 -n x0 || exit 1
|
||||||
|
$TMUX new-window -d -t aw2: -n x1 || exit 1
|
||||||
|
|
||||||
|
mkfifo "$IN1" "$IN2" || exit 1
|
||||||
|
: >"$OUT1"
|
||||||
|
: >"$OUT2"
|
||||||
|
$TMUX -C attach-session -t aw <"$IN1" >"$OUT1" 2>&1 &
|
||||||
|
PID1=$!
|
||||||
|
$TMUX -C attach-session -t aw <"$IN2" >"$OUT2" 2>&1 &
|
||||||
|
PID2=$!
|
||||||
|
exec 3>"$IN1"
|
||||||
|
exec 4>"$IN2"
|
||||||
|
|
||||||
|
send1 'display-message -p C1READY'
|
||||||
|
send2 'display-message -p C2READY'
|
||||||
|
wait_for "$OUT1" C1READY
|
||||||
|
wait_for "$OUT2" C2READY
|
||||||
|
|
||||||
|
# Default shared selection: client 1 changes session current, client 2 follows.
|
||||||
|
send1 'display-message -p "C1A #{active_window_index} #{local_active_window} #{window_index}"'
|
||||||
|
wait_for "$OUT1" 'C1A 0 0 0'
|
||||||
|
send1 'select-window -t :1'
|
||||||
|
wait_for "$OUT2" '%session-window-changed $0 @1'
|
||||||
|
send2 'display-message -p "C2A #{active_window_index} #{local_active_window} #{window_index}"'
|
||||||
|
wait_for "$OUT2" 'C2A 1 0 1'
|
||||||
|
check_server 'aw:' '#{window_index}' '1'
|
||||||
|
|
||||||
|
# Local selection changes only client 1 and becomes the default command target.
|
||||||
|
send1 'select-window -L'
|
||||||
|
send1 'select-window -t :2'
|
||||||
|
send1 'display-message -p "C1B #{active_window_index} #{local_active_window} #{window_index}"'
|
||||||
|
wait_for "$OUT1" 'C1B 2 1 2'
|
||||||
|
send2 'display-message -p "C2B #{active_window_index} #{local_active_window} #{window_index}"'
|
||||||
|
wait_for "$OUT2" 'C2B 1 0 1'
|
||||||
|
check_server 'aw:' '#{window_index}' '1'
|
||||||
|
|
||||||
|
# Local last-window history is independent of the session shared stack.
|
||||||
|
send1 'last-window'
|
||||||
|
send1 'display-message -p "C1C #{active_window_index} #{window_index}"'
|
||||||
|
wait_for "$OUT1" 'C1C 1 1'
|
||||||
|
send1 'next-window'
|
||||||
|
send1 'display-message -p "C1D #{active_window_index} #{window_index}"'
|
||||||
|
wait_for "$OUT1" 'C1D 2 2'
|
||||||
|
check_server 'aw:' '#{window_index}' '1'
|
||||||
|
|
||||||
|
# Session switches preserve per-session local selections.
|
||||||
|
send1 'switch-client -t aw2'
|
||||||
|
send1 'select-window -L'
|
||||||
|
send1 'select-window -t :1'
|
||||||
|
send1 'display-message -p "C1E #{session_name} #{active_window_index} #{local_active_window}"'
|
||||||
|
wait_for "$OUT1" 'C1E aw2 1 1'
|
||||||
|
send1 'switch-client -t aw'
|
||||||
|
send1 'display-message -p "C1F #{session_name} #{active_window_index} #{local_active_window}"'
|
||||||
|
wait_for "$OUT1" 'C1F aw 2 1'
|
||||||
|
|
||||||
|
# Returning to shared mode immediately follows the session current window.
|
||||||
|
send1 'select-window -S'
|
||||||
|
send1 'display-message -p "C1G #{active_window_index} #{local_active_window} #{window_index}"'
|
||||||
|
wait_for "$OUT1" 'C1G 1 0 1'
|
||||||
|
|
||||||
|
# Invalid local windows recover to a valid session window without changing curw.
|
||||||
|
send1 'select-window -L'
|
||||||
|
send1 'select-window -t :2'
|
||||||
|
$TMUX kill-window -t aw:2 || fail 'kill-window failed'
|
||||||
|
send1 'display-message -p "C1H #{active_window_index} #{local_active_window} #{window_index}"'
|
||||||
|
wait_for "$OUT1" 'C1H 1 1 1'
|
||||||
|
check_server 'aw:' '#{window_index}' '1'
|
||||||
|
|
||||||
|
# Creating a window without -d in local mode selects it locally only.
|
||||||
|
send1 'new-window -n w3'
|
||||||
|
send1 'display-message -p "C1I #{local_active_window} #{window_name}"'
|
||||||
|
wait_for "$OUT1" 'C1I 1 w3'
|
||||||
|
send2 'display-message -p "C2C #{local_active_window} #{window_name}"'
|
||||||
|
wait_for "$OUT2" 'C2C 0 w1'
|
||||||
|
check_server 'aw:' '#{window_name}' 'w1'
|
||||||
|
|
||||||
|
exit 0
|
||||||
4
resize.c
4
resize.c
@@ -348,10 +348,10 @@ recalculate_size_skip_client(struct client *loop, __unused int type,
|
|||||||
* is not the current window - this is used for aggressive-resize.
|
* is not the current window - this is used for aggressive-resize.
|
||||||
* Otherwise skip any session that doesn't contain the window.
|
* Otherwise skip any session that doesn't contain the window.
|
||||||
*/
|
*/
|
||||||
if (loop->session->curw == NULL)
|
if (active_get_effective_window(loop, loop->session) == NULL)
|
||||||
return (1);
|
return (1);
|
||||||
if (current)
|
if (current)
|
||||||
return (loop->session->curw->window != w);
|
return (active_get_effective_window(loop, loop->session) != w);
|
||||||
return (session_has(loop->session, w) == 0);
|
return (session_has(loop->session, w) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ static void
|
|||||||
redraw_set_context(struct client *c, struct redraw_build_ctx *bctx)
|
redraw_set_context(struct client *c, struct redraw_build_ctx *bctx)
|
||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct window *w = s->curw->window;
|
struct window *w = active_get_effective_window(c, s);
|
||||||
|
|
||||||
memset(bctx, 0, sizeof *bctx);
|
memset(bctx, 0, sizeof *bctx);
|
||||||
bctx->c = c;
|
bctx->c = c;
|
||||||
@@ -966,7 +966,7 @@ static struct redraw_scene *
|
|||||||
redraw_make_scene(struct client *c)
|
redraw_make_scene(struct client *c)
|
||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct window *w = s->curw->window;
|
struct window *w = active_get_effective_window(c, s);
|
||||||
struct redraw_build_ctx bctx;
|
struct redraw_build_ctx bctx;
|
||||||
struct redraw_scene *scene;
|
struct redraw_scene *scene;
|
||||||
struct redraw_build_cell *bc, *last;
|
struct redraw_build_cell *bc, *last;
|
||||||
@@ -1076,7 +1076,7 @@ static struct redraw_scene *
|
|||||||
redraw_get_scene(struct client *c)
|
redraw_get_scene(struct client *c)
|
||||||
{
|
{
|
||||||
struct redraw_scene *scene = c->redraw_scene;
|
struct redraw_scene *scene = c->redraw_scene;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = active_get_effective_window(c, c->session);
|
||||||
const char *reason = NULL;
|
const char *reason = NULL;
|
||||||
u_int ox, oy, sx, sy;
|
u_int ox, oy, sx, sy;
|
||||||
|
|
||||||
@@ -1137,7 +1137,7 @@ redraw_get_default_border_style(struct redraw_draw_ctx *dctx,
|
|||||||
struct grid_cell *dgc = &dctx->default_gc;
|
struct grid_cell *dgc = &dctx->default_gc;
|
||||||
|
|
||||||
if (~dctx->flags & REDRAW_DEFAULT_SET) {
|
if (~dctx->flags & REDRAW_DEFAULT_SET) {
|
||||||
ft = format_create_defaults(NULL, c, s, s->curw, NULL);
|
ft = format_create_defaults(NULL, c, s, NULL, NULL);
|
||||||
memcpy(dgc, &grid_default_cell, sizeof *dgc);
|
memcpy(dgc, &grid_default_cell, sizeof *dgc);
|
||||||
style_add(dgc, oo, "pane-border-style", ft);
|
style_add(dgc, oo, "pane-border-style", ft);
|
||||||
format_free(ft);
|
format_free(ft);
|
||||||
@@ -1592,14 +1592,16 @@ redraw_set_draw_context(struct redraw_draw_ctx *dctx,
|
|||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct options *oo = s->options;
|
struct options *oo = s->options;
|
||||||
struct tty *tty = &c->tty;
|
struct tty *tty = &c->tty;
|
||||||
|
struct winlink *wl;
|
||||||
u_int lines;
|
u_int lines;
|
||||||
|
|
||||||
memset(dctx, 0, sizeof *dctx);
|
memset(dctx, 0, sizeof *dctx);
|
||||||
dctx->scene = scene;
|
dctx->scene = scene;
|
||||||
|
|
||||||
if (server_is_marked(s, s->curw, marked_pane.wp))
|
wl = active_get_effective_winlink(c, s);
|
||||||
|
if (server_is_marked(s, wl, marked_pane.wp))
|
||||||
dctx->marked = marked_pane.wp;
|
dctx->marked = marked_pane.wp;
|
||||||
dctx->active = s->curw->window->active;
|
dctx->active = active_get_effective_window(c, s)->active;
|
||||||
|
|
||||||
lines = status_line_size(c);
|
lines = status_line_size(c);
|
||||||
if (options_get_number(oo, "status-position") == 0)
|
if (options_get_number(oo, "status-position") == 0)
|
||||||
@@ -1672,7 +1674,7 @@ redraw_draw(struct client *c, struct window_pane *wp, int flags)
|
|||||||
{
|
{
|
||||||
struct redraw_draw_ctx dctx;
|
struct redraw_draw_ctx dctx;
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct window *w = s->curw->window;
|
struct window *w = active_get_effective_window(c, s);
|
||||||
struct tty *tty = &c->tty;
|
struct tty *tty = &c->tty;
|
||||||
struct screen *sl;
|
struct screen *sl;
|
||||||
struct redraw_scene *scene;
|
struct redraw_scene *scene;
|
||||||
@@ -1872,7 +1874,7 @@ redraw_screen(struct client *c)
|
|||||||
flags |= REDRAW_OVERLAY;
|
flags |= REDRAW_OVERLAY;
|
||||||
if (c->flags & CLIENT_REDRAWMENU)
|
if (c->flags & CLIENT_REDRAWMENU)
|
||||||
flags |= REDRAW_MENU;
|
flags |= REDRAW_MENU;
|
||||||
if (c->session->curw->window->menu != NULL)
|
if (active_get_effective_window(c, c->session)->menu != NULL)
|
||||||
flags |= REDRAW_MENU;
|
flags |= REDRAW_MENU;
|
||||||
if (flags != 0)
|
if (flags != 0)
|
||||||
redraw_draw(c, NULL, flags);
|
redraw_draw(c, NULL, flags);
|
||||||
@@ -1884,7 +1886,7 @@ void
|
|||||||
redraw_pane(struct client *c, struct window_pane *wp)
|
redraw_pane(struct client *c, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
redraw_draw(c, wp, REDRAW_PANE|REDRAW_PANE_SCROLLBAR);
|
redraw_draw(c, wp, REDRAW_PANE|REDRAW_PANE_SCROLLBAR);
|
||||||
if (c->session->curw->window->menu != NULL)
|
if (active_get_effective_window(c, c->session)->menu != NULL)
|
||||||
redraw_draw(c, NULL, REDRAW_MENU);
|
redraw_draw(c, NULL, REDRAW_MENU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->session->curw->window != wp->window)
|
if (active_get_effective_window(c, c->session) != wp->window)
|
||||||
return (0);
|
return (0);
|
||||||
if (wp->layout_cell == NULL)
|
if (wp->layout_cell == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ server_client_set_overlay(struct client *c, u_int delay,
|
|||||||
c->tty.flags |= TTY_FREEZE;
|
c->tty.flags |= TTY_FREEZE;
|
||||||
if (c->overlay_mode == NULL)
|
if (c->overlay_mode == NULL)
|
||||||
c->tty.flags |= TTY_NOCURSOR;
|
c->tty.flags |= TTY_NOCURSOR;
|
||||||
window_update_focus(c->session->curw->window);
|
window_update_focus(active_get_effective_window(c, c->session));
|
||||||
server_redraw_client(c);
|
server_redraw_client(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ server_client_clear_overlay(struct client *c)
|
|||||||
|
|
||||||
c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR);
|
c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR);
|
||||||
if (c->session != NULL)
|
if (c->session != NULL)
|
||||||
window_update_focus(c->session->curw->window);
|
window_update_focus(active_get_effective_window(c, c->session));
|
||||||
server_redraw_client(c);
|
server_redraw_client(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,7 +376,8 @@ server_client_attached_lost(struct client *c)
|
|||||||
found = NULL;
|
found = NULL;
|
||||||
TAILQ_FOREACH(loop, &clients, entry) {
|
TAILQ_FOREACH(loop, &clients, entry) {
|
||||||
s = loop->session;
|
s = loop->session;
|
||||||
if (loop == c || s == NULL || s->curw->window != w)
|
if (loop == c || s == NULL ||
|
||||||
|
active_get_effective_window(loop, s) != w)
|
||||||
continue;
|
continue;
|
||||||
if (found == NULL || timercmp(&loop->activity_time,
|
if (found == NULL || timercmp(&loop->activity_time,
|
||||||
&found->activity_time, >))
|
&found->activity_time, >))
|
||||||
@@ -457,15 +458,15 @@ server_client_set_session(struct client *c, struct session *s)
|
|||||||
c->flags |= CLIENT_FOCUSED;
|
c->flags |= CLIENT_FOCUSED;
|
||||||
|
|
||||||
if (old != NULL && old->curw != NULL)
|
if (old != NULL && old->curw != NULL)
|
||||||
window_update_focus(old->curw->window);
|
window_update_focus(active_get_effective_window(c, old));
|
||||||
if (s != NULL) {
|
if (s != NULL) {
|
||||||
s->curw->window->latest = c;
|
active_get_effective_window(c, s)->latest = c;
|
||||||
recalculate_sizes();
|
recalculate_sizes();
|
||||||
window_update_focus(s->curw->window);
|
window_update_focus(active_get_effective_window(c, s));
|
||||||
session_update_activity(s, NULL);
|
session_update_activity(s, NULL);
|
||||||
session_theme_changed(s);
|
session_theme_changed(s);
|
||||||
gettimeofday(&s->last_attached_time, NULL);
|
gettimeofday(&s->last_attached_time, NULL);
|
||||||
s->curw->flags &= ~WINLINK_ALERTFLAGS;
|
active_get_effective_winlink(c, s)->flags &= ~WINLINK_ALERTFLAGS;
|
||||||
alerts_check_session(s);
|
alerts_check_session(s);
|
||||||
tty_update_client_offset(c);
|
tty_update_client_offset(c);
|
||||||
status_timer_start(c);
|
status_timer_start(c);
|
||||||
@@ -490,6 +491,7 @@ server_client_lost(struct client *c)
|
|||||||
server_client_clear_overlay(c);
|
server_client_clear_overlay(c);
|
||||||
status_prompt_clear(c);
|
status_prompt_clear(c);
|
||||||
status_message_clear(c);
|
status_message_clear(c);
|
||||||
|
active_remove_client(c);
|
||||||
|
|
||||||
RB_FOREACH_SAFE(cf, client_files, &c->files, cf1) {
|
RB_FOREACH_SAFE(cf, client_files, &c->files, cf1) {
|
||||||
cf->error = EINTR;
|
cf->error = EINTR;
|
||||||
@@ -675,7 +677,7 @@ server_client_in_scrollbar_area(struct window_pane *wp, int px, int py)
|
|||||||
static void
|
static void
|
||||||
server_client_update_scrollbar_hover(struct client *c, int type, int px, int py)
|
server_client_update_scrollbar_hover(struct client *c, int type, int px, int py)
|
||||||
{
|
{
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = active_get_effective_window(c, c->session);
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
|
||||||
if (type != KEYC_TYPE_MOUSEMOVE)
|
if (type != KEYC_TYPE_MOUSEMOVE)
|
||||||
@@ -848,7 +850,7 @@ server_client_check_mouse(struct client *c, struct key_event *event)
|
|||||||
{
|
{
|
||||||
struct mouse_event *m = &event->m;
|
struct mouse_event *m = &event->m;
|
||||||
struct session *s = c->session, *fs;
|
struct session *s = c->session, *fs;
|
||||||
struct window *w = s->curw->window;
|
struct window *w = active_get_effective_window(c, s);
|
||||||
struct winlink *fwl;
|
struct winlink *fwl;
|
||||||
struct window_pane *wp, *fwp, *lwp = NULL;
|
struct window_pane *wp, *fwp, *lwp = NULL;
|
||||||
u_int x, y, sx, sy, px, py, n, sl_mpos = 0;
|
u_int x, y, sx, sy, px, py, n, sl_mpos = 0;
|
||||||
@@ -1346,7 +1348,7 @@ server_client_update_latest(struct client *c)
|
|||||||
|
|
||||||
if (c->session == NULL)
|
if (c->session == NULL)
|
||||||
return;
|
return;
|
||||||
w = c->session->curw->window;
|
w = active_get_effective_window(c, c->session);
|
||||||
|
|
||||||
if (w->latest == c)
|
if (w->latest == c)
|
||||||
return;
|
return;
|
||||||
@@ -1410,7 +1412,7 @@ server_client_key_callback(struct cmdq_item *item, void *data)
|
|||||||
/* Check the client is good to accept input. */
|
/* Check the client is good to accept input. */
|
||||||
if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
|
if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
|
||||||
goto out;
|
goto out;
|
||||||
wl = s->curw;
|
wl = active_get_effective_winlink(c, s);
|
||||||
|
|
||||||
/* Update the activity timer. */
|
/* Update the activity timer. */
|
||||||
memcpy(&c->last_activity_time, &c->activity_time,
|
memcpy(&c->last_activity_time, &c->activity_time,
|
||||||
@@ -1664,7 +1666,7 @@ out:
|
|||||||
static int
|
static int
|
||||||
server_client_handle_menu_key(struct client *c, struct key_event *event)
|
server_client_handle_menu_key(struct client *c, struct key_event *event)
|
||||||
{
|
{
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = active_get_effective_window(c, c->session);
|
||||||
struct key_event new_event;
|
struct key_event new_event;
|
||||||
struct mouse_event *m;
|
struct mouse_event *m;
|
||||||
u_int ox, oy, sx, sy;
|
u_int ox, oy, sx, sy;
|
||||||
@@ -1701,6 +1703,7 @@ server_client_handle_key0(struct client *c, struct key_event *event,
|
|||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct cmdq_item *item;
|
struct cmdq_item *item;
|
||||||
|
struct window *w;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
|
||||||
/* Check the client is good to accept input. */
|
/* Check the client is good to accept input. */
|
||||||
@@ -1756,9 +1759,10 @@ server_client_handle_key0(struct client *c, struct key_event *event,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wp = s->curw->window->active;
|
w = active_get_effective_window(c, s);
|
||||||
|
wp = w->active;
|
||||||
if (wp == NULL || !window_pane_has_prompt(wp)) {
|
if (wp == NULL || !window_pane_has_prompt(wp)) {
|
||||||
TAILQ_FOREACH(wp, &s->curw->window->panes, entry) {
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
if (window_pane_has_prompt(wp) &&
|
if (window_pane_has_prompt(wp) &&
|
||||||
window_pane_is_visible(wp))
|
window_pane_is_visible(wp))
|
||||||
break;
|
break;
|
||||||
@@ -2100,7 +2104,7 @@ static void
|
|||||||
server_client_reset_state(struct client *c)
|
server_client_reset_state(struct client *c)
|
||||||
{
|
{
|
||||||
struct tty *tty = &c->tty;
|
struct tty *tty = &c->tty;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = active_get_effective_window(c, c->session);
|
||||||
struct window_pane *wp = w->active, *loop;
|
struct window_pane *wp = w->active, *loop;
|
||||||
struct screen *s = NULL;
|
struct screen *s = NULL;
|
||||||
struct options *oo = c->session->options;
|
struct options *oo = c->session->options;
|
||||||
@@ -2341,7 +2345,7 @@ server_client_redraw_timer(__unused int fd, __unused short events,
|
|||||||
static void
|
static void
|
||||||
server_client_check_modes(struct client *c)
|
server_client_check_modes(struct client *c)
|
||||||
{
|
{
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
struct window_mode_entry *wme;
|
struct window_mode_entry *wme;
|
||||||
|
|
||||||
@@ -2349,6 +2353,7 @@ server_client_check_modes(struct client *c)
|
|||||||
return;
|
return;
|
||||||
if (~c->flags & CLIENT_REDRAWSTATUS)
|
if (~c->flags & CLIENT_REDRAWSTATUS)
|
||||||
return;
|
return;
|
||||||
|
w = active_get_effective_window(c, c->session);
|
||||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
wme = TAILQ_FIRST(&wp->modes);
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
if (wme != NULL && wme->mode->update != NULL)
|
if (wme != NULL && wme->mode->update != NULL)
|
||||||
@@ -2361,7 +2366,7 @@ static int
|
|||||||
server_client_any_pane_redraw(struct client *c)
|
server_client_any_pane_redraw(struct client *c)
|
||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct window *w = s->curw->window;
|
struct window *w = active_get_effective_window(c, s);
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
|
||||||
if (c->flags & CLIENT_REDRAWWINDOW)
|
if (c->flags & CLIENT_REDRAWWINDOW)
|
||||||
@@ -2379,7 +2384,7 @@ server_client_check_redraw(struct client *c)
|
|||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct tty *tty = &c->tty;
|
struct tty *tty = &c->tty;
|
||||||
struct window *w = s->curw->window;
|
struct window *w = active_get_effective_window(c, s);
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
int needed, tflags, mode = tty->mode;
|
int needed, tflags, mode = tty->mode;
|
||||||
struct timeval tv = { .tv_usec = 1000 };
|
struct timeval tv = { .tv_usec = 1000 };
|
||||||
@@ -2510,14 +2515,15 @@ static void
|
|||||||
server_client_set_path(struct client *c)
|
server_client_set_path(struct client *c)
|
||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
|
struct window *w = active_get_effective_window(c, s);
|
||||||
const char *path;
|
const char *path;
|
||||||
|
|
||||||
if (s->curw == NULL || s->curw->window->active == NULL)
|
if (w == NULL || w->active == NULL)
|
||||||
return;
|
return;
|
||||||
if (s->curw->window->active->base.path == NULL)
|
if (w->active->base.path == NULL)
|
||||||
path = "";
|
path = "";
|
||||||
else
|
else
|
||||||
path = s->curw->window->active->base.path;
|
path = w->active->base.path;
|
||||||
if (c->path == NULL || strcmp(path, c->path) != 0) {
|
if (c->path == NULL || strcmp(path, c->path) != 0) {
|
||||||
free(c->path);
|
free(c->path);
|
||||||
c->path = xstrdup(path);
|
c->path = xstrdup(path);
|
||||||
@@ -2530,11 +2536,12 @@ static void
|
|||||||
server_client_set_progress_bar(struct client *c)
|
server_client_set_progress_bar(struct client *c)
|
||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
|
struct window *w = active_get_effective_window(c, s);
|
||||||
struct progress_bar *pane_pb;
|
struct progress_bar *pane_pb;
|
||||||
|
|
||||||
if (s->curw == NULL || s->curw->window->active == NULL)
|
if (w == NULL || w->active == NULL)
|
||||||
return;
|
return;
|
||||||
pane_pb = &s->curw->window->active->base.progress_bar;
|
pane_pb = &w->active->base.progress_bar;
|
||||||
if (pane_pb->state == c->progress_bar.state &&
|
if (pane_pb->state == c->progress_bar.state &&
|
||||||
pane_pb->progress == c->progress_bar.progress)
|
pane_pb->progress == c->progress_bar.progress)
|
||||||
return;
|
return;
|
||||||
@@ -3120,7 +3127,7 @@ server_client_print(struct client *c, int parse, struct evbuffer *evb)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
wp = c->session->curw->window->active;
|
wp = active_get_effective_window(c, c->session)->active;
|
||||||
wme = TAILQ_FIRST(&wp->modes);
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
if (wme == NULL || wme->mode != &window_view_mode)
|
if (wme == NULL || wme->mode != &window_view_mode)
|
||||||
window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL,
|
window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL,
|
||||||
|
|||||||
@@ -122,8 +122,7 @@ server_redraw_window(struct window *w)
|
|||||||
|
|
||||||
TAILQ_FOREACH(c, &clients, entry) {
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
if (c->session != NULL &&
|
if (c->session != NULL &&
|
||||||
c->session->curw != NULL &&
|
active_get_effective_window(c, c->session) == w)
|
||||||
c->session->curw->window == w)
|
|
||||||
server_redraw_client(c);
|
server_redraw_client(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,8 +134,7 @@ server_redraw_window_menu(struct window *w)
|
|||||||
|
|
||||||
TAILQ_FOREACH(c, &clients, entry) {
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
if (c->session != NULL &&
|
if (c->session != NULL &&
|
||||||
c->session->curw != NULL &&
|
active_get_effective_window(c, c->session) == w)
|
||||||
c->session->curw->window == w)
|
|
||||||
c->flags |= CLIENT_REDRAWMENU;
|
c->flags |= CLIENT_REDRAWMENU;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,8 +146,7 @@ server_redraw_window_borders(struct window *w)
|
|||||||
|
|
||||||
TAILQ_FOREACH(c, &clients, entry) {
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
if (c->session != NULL &&
|
if (c->session != NULL &&
|
||||||
c->session->curw != NULL &&
|
active_get_effective_window(c, c->session) == w)
|
||||||
c->session->curw->window == w)
|
|
||||||
c->flags |= CLIENT_REDRAWBORDERS;
|
c->flags |= CLIENT_REDRAWBORDERS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ session_destroy(struct session *s, int notify, const char *from)
|
|||||||
if (s->curw == NULL)
|
if (s->curw == NULL)
|
||||||
return;
|
return;
|
||||||
s->curw = NULL;
|
s->curw = NULL;
|
||||||
|
active_remove_session(s);
|
||||||
|
|
||||||
RB_REMOVE(sessions, &sessions, s);
|
RB_REMOVE(sessions, &sessions, s);
|
||||||
if (notify)
|
if (notify)
|
||||||
|
|||||||
19
tmux.1
19
tmux.1
@@ -4026,12 +4026,22 @@ and
|
|||||||
.Ic swap\-window .
|
.Ic swap\-window .
|
||||||
.Tg selectw
|
.Tg selectw
|
||||||
.It Xo Ic select\-window
|
.It Xo Ic select\-window
|
||||||
.Op Fl lnpT
|
.Op Fl LlnpST
|
||||||
.Op Fl t Ar target\-window
|
.Op Fl t Ar target\-window
|
||||||
.Xc
|
.Xc
|
||||||
.D1 Pq alias: Ic selectw
|
.D1 Pq alias: Ic selectw
|
||||||
Select the window at
|
Select the window at
|
||||||
.Ar target\-window .
|
.Ar target\-window .
|
||||||
|
.Fl L
|
||||||
|
makes the attached client use a local current window for the target session.
|
||||||
|
Window navigation from that client then changes only that client's effective
|
||||||
|
window and leaves the session current window unchanged.
|
||||||
|
.Fl S
|
||||||
|
returns the client to the shared session current window.
|
||||||
|
Without
|
||||||
|
.Fl L ,
|
||||||
|
the current window is shared by the session and stored in the session.
|
||||||
|
.Pp
|
||||||
.Fl l ,
|
.Fl l ,
|
||||||
.Fl n
|
.Fl n
|
||||||
and
|
and
|
||||||
@@ -7177,7 +7187,10 @@ will be replaced by
|
|||||||
The following variables are available, where appropriate:
|
The following variables are available, where appropriate:
|
||||||
.Bl -column "XXXXXXXXXXXXXXXXXXX" "XXXXX"
|
.Bl -column "XXXXXXXXXXXXXXXXXXX" "XXXXX"
|
||||||
.It Sy "Variable name" Ta Sy "Alias" Ta Sy "Replaced with"
|
.It Sy "Variable name" Ta Sy "Alias" Ta Sy "Replaced with"
|
||||||
.It Li "active_window_index" Ta "" Ta "Index of active window in session"
|
.It Li "active_window_id" Ta "" Ta "ID of effective active window"
|
||||||
|
.It Li "active_window_index" Ta "" Ta "Index of effective active window"
|
||||||
|
.It Li "local_active_window" Ta "" Ta "1 if client has local window selection"
|
||||||
|
.It Li "active_window_mode" Ta "" Ta "Window selection mode, shared or local"
|
||||||
.It Li "alternate_on" Ta "" Ta "1 if pane is in alternate screen"
|
.It Li "alternate_on" Ta "" Ta "1 if pane is in alternate screen"
|
||||||
.It Li "alternate_saved_x" Ta "" Ta "Saved cursor X in alternate screen"
|
.It Li "alternate_saved_x" Ta "" Ta "Saved cursor X in alternate screen"
|
||||||
.It Li "alternate_saved_y" Ta "" Ta "Saved cursor Y in alternate screen"
|
.It Li "alternate_saved_y" Ta "" Ta "Saved cursor Y in alternate screen"
|
||||||
@@ -7392,7 +7405,7 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "uid" Ta "" Ta "Server UID"
|
.It Li "uid" Ta "" Ta "Server UID"
|
||||||
.It Li "user" Ta "" Ta "Server user"
|
.It Li "user" Ta "" Ta "Server user"
|
||||||
.It Li "version" Ta "" Ta "Server version"
|
.It Li "version" Ta "" Ta "Server version"
|
||||||
.It Li "window_active" Ta "" Ta "1 if window active"
|
.It Li "window_active" Ta "" Ta "1 if window is the effective active window"
|
||||||
.It Li "window_active_clients" Ta "" Ta "Number of clients viewing this window"
|
.It Li "window_active_clients" Ta "" Ta "Number of clients viewing this window"
|
||||||
.It Li "window_active_clients_list" Ta "" Ta "List of clients viewing this window"
|
.It Li "window_active_clients_list" Ta "" Ta "List of clients viewing this window"
|
||||||
.It Li "window_active_sessions" Ta "" Ta "Number of sessions on which this window is active"
|
.It Li "window_active_sessions" Ta "" Ta "Number of sessions on which this window is active"
|
||||||
|
|||||||
28
tmux.h
28
tmux.h
@@ -2741,6 +2741,32 @@ void events_fire_window(const char *, struct window *);
|
|||||||
void events_fire_pane(const char *, struct window_pane *);
|
void events_fire_pane(const char *, struct window_pane *);
|
||||||
void events_fire_winlink(const char *, struct winlink *);
|
void events_fire_winlink(const char *, struct winlink *);
|
||||||
|
|
||||||
|
/* active.c */
|
||||||
|
enum active_window_mode {
|
||||||
|
ACTIVE_SHARED,
|
||||||
|
ACTIVE_LOCAL
|
||||||
|
};
|
||||||
|
int active_is_local_window(struct client *, struct session *);
|
||||||
|
void active_set_local_window(struct client *, struct session *,
|
||||||
|
enum active_window_mode);
|
||||||
|
struct winlink *active_get_effective_winlink(struct client *,
|
||||||
|
struct session *);
|
||||||
|
struct window *active_get_effective_window(struct client *,
|
||||||
|
struct session *);
|
||||||
|
int active_select_window(struct client *, struct session *,
|
||||||
|
struct winlink *);
|
||||||
|
int active_select_window_index(struct client *, struct session *, int);
|
||||||
|
int active_next_window(struct client *, struct session *, int);
|
||||||
|
int active_previous_window(struct client *, struct session *, int);
|
||||||
|
int active_last_window(struct client *, struct session *);
|
||||||
|
void active_remove_client(struct client *);
|
||||||
|
void active_remove_session(struct session *);
|
||||||
|
void active_remove_window(struct window *);
|
||||||
|
int active_is_effective_window(struct client *, struct session *,
|
||||||
|
struct winlink *);
|
||||||
|
int active_is_last_window(struct client *, struct session *,
|
||||||
|
struct winlink *);
|
||||||
|
|
||||||
/* format-draw.c */
|
/* format-draw.c */
|
||||||
void format_draw(struct screen_write_ctx *, const struct grid_cell *,
|
void format_draw(struct screen_write_ctx *, const struct grid_cell *,
|
||||||
u_int, const char *, struct style_ranges *, int);
|
u_int, const char *, struct style_ranges *, int);
|
||||||
@@ -3733,7 +3759,7 @@ int window_pane_is_visible(struct window_pane *);
|
|||||||
int window_pane_exited(struct window_pane *);
|
int window_pane_exited(struct window_pane *);
|
||||||
u_int window_pane_search(struct window_pane *, const char *, int,
|
u_int window_pane_search(struct window_pane *, const char *, int,
|
||||||
int);
|
int);
|
||||||
const char *window_printable_flags(struct winlink *, int);
|
const char *window_printable_flags(struct client *, struct winlink *, int);
|
||||||
const char *window_pane_printable_flags(struct window_pane *);
|
const char *window_pane_printable_flags(struct window_pane *);
|
||||||
struct window_pane *window_pane_find_up(struct window_pane *);
|
struct window_pane *window_pane_find_up(struct window_pane *);
|
||||||
struct window_pane *window_pane_find_down(struct window_pane *);
|
struct window_pane *window_pane_find_down(struct window_pane *);
|
||||||
|
|||||||
@@ -1007,12 +1007,12 @@ complete_key:
|
|||||||
/* Check for focus events. */
|
/* Check for focus events. */
|
||||||
if (key == KEYC_FOCUS_OUT) {
|
if (key == KEYC_FOCUS_OUT) {
|
||||||
c->flags &= ~CLIENT_FOCUSED;
|
c->flags &= ~CLIENT_FOCUSED;
|
||||||
window_update_focus(c->session->curw->window);
|
window_update_focus(active_get_effective_window(c, c->session));
|
||||||
events_fire_client("client-focus-out", c);
|
events_fire_client("client-focus-out", c);
|
||||||
} else if (key == KEYC_FOCUS_IN) {
|
} else if (key == KEYC_FOCUS_IN) {
|
||||||
c->flags |= CLIENT_FOCUSED;
|
c->flags |= CLIENT_FOCUSED;
|
||||||
events_fire_client("client-focus-in", c);
|
events_fire_client("client-focus-in", c);
|
||||||
window_update_focus(c->session->curw->window);
|
window_update_focus(active_get_effective_window(c, c->session));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fire the key. */
|
/* Fire the key. */
|
||||||
|
|||||||
9
tty.c
9
tty.c
@@ -937,7 +937,7 @@ int
|
|||||||
tty_window_bigger(struct tty *tty)
|
tty_window_bigger(struct tty *tty)
|
||||||
{
|
{
|
||||||
struct client *c = tty->client;
|
struct client *c = tty->client;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = active_get_effective_window(c, c->session);
|
||||||
|
|
||||||
return (tty->sx < w->sx || tty->sy - status_line_size(c) < w->sy);
|
return (tty->sx < w->sx || tty->sy - status_line_size(c) < w->sy);
|
||||||
}
|
}
|
||||||
@@ -959,7 +959,7 @@ static int
|
|||||||
tty_window_offset1(struct tty *tty, u_int *ox, u_int *oy, u_int *sx, u_int *sy)
|
tty_window_offset1(struct tty *tty, u_int *ox, u_int *oy, u_int *sx, u_int *sy)
|
||||||
{
|
{
|
||||||
struct client *c = tty->client;
|
struct client *c = tty->client;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = active_get_effective_window(c, c->session);
|
||||||
struct window_pane *wp = w->active;
|
struct window_pane *wp = w->active;
|
||||||
u_int cx, cy, lines;
|
u_int cx, cy, lines;
|
||||||
|
|
||||||
@@ -1026,8 +1026,7 @@ tty_update_window_offset(struct window *w)
|
|||||||
|
|
||||||
TAILQ_FOREACH(c, &clients, entry) {
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
if (c->session != NULL &&
|
if (c->session != NULL &&
|
||||||
c->session->curw != NULL &&
|
active_get_effective_window(c, c->session) == w)
|
||||||
c->session->curw->window == w)
|
|
||||||
tty_update_client_offset(c);
|
tty_update_client_offset(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1529,7 +1528,7 @@ tty_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
|
|||||||
{
|
{
|
||||||
struct window_pane *wp = ttyctx->arg;
|
struct window_pane *wp = ttyctx->arg;
|
||||||
|
|
||||||
if (c->session->curw->window != wp->window)
|
if (active_get_effective_window(c, c->session) != wp->window)
|
||||||
return (0);
|
return (0);
|
||||||
if (wp->layout_cell == NULL)
|
if (wp->layout_cell == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ window_pane_get_border_style(struct window_pane *wp, struct client *c,
|
|||||||
struct grid_cell *saved;
|
struct grid_cell *saved;
|
||||||
int *flag;
|
int *flag;
|
||||||
|
|
||||||
if (wp == c->session->curw->window->active) {
|
if (wp == active_get_effective_window(c, c->session)->active) {
|
||||||
flag = &wp->active_border_gc_set;
|
flag = &wp->active_border_gc_set;
|
||||||
saved = &wp->active_border_gc;
|
saved = &wp->active_border_gc;
|
||||||
option = "pane-active-border-style";
|
option = "pane-active-border-style";
|
||||||
@@ -104,7 +104,7 @@ window_pane_get_border_style(struct window_pane *wp, struct client *c,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!*flag) {
|
if (!*flag) {
|
||||||
ft = format_create_defaults(NULL, c, s, s->curw, wp);
|
ft = format_create_defaults(NULL, c, s, NULL, wp);
|
||||||
style_apply(saved, wp->options, option, ft);
|
style_apply(saved, wp->options, option, ft);
|
||||||
format_free(ft);
|
format_free(ft);
|
||||||
*flag = 1;
|
*flag = 1;
|
||||||
@@ -133,7 +133,7 @@ window_make_pane_status(struct window_pane *wp, struct client *c, u_int width,
|
|||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
ft = format_create(c, NULL, FORMAT_PANE|wp->id, FORMAT_STATUS);
|
ft = format_create(c, NULL, FORMAT_PANE|wp->id, FORMAT_STATUS);
|
||||||
format_defaults(ft, c, c->session, c->session->curw, wp);
|
format_defaults(ft, c, c->session, NULL, wp);
|
||||||
|
|
||||||
fmt = options_get_string(wp->options, "pane-border-format");
|
fmt = options_get_string(wp->options, "pane-border-format");
|
||||||
expanded = format_expand_time(ft, fmt);
|
expanded = format_expand_time(ft, fmt);
|
||||||
|
|||||||
@@ -266,12 +266,13 @@ window_client_draw_info(__unused void *modedata, void *itemdata,
|
|||||||
struct window_client_itemdata *item = itemdata;
|
struct window_client_itemdata *item = itemdata;
|
||||||
struct client *c = item->c;
|
struct client *c = item->c;
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w;
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
u_int cx = s->cx, cy = s->cy, i;
|
u_int cx = s->cx, cy = s->cy, i;
|
||||||
struct format_tree *ft;
|
struct format_tree *ft;
|
||||||
char *expanded;
|
char *expanded;
|
||||||
|
|
||||||
|
w = active_get_effective_window(c, c->session);
|
||||||
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
||||||
|
|
||||||
screen_write_cursormove(ctx, cx, cy, 0);
|
screen_write_cursormove(ctx, cx, cy, 0);
|
||||||
|
|||||||
16
window.c
16
window.c
@@ -453,6 +453,7 @@ window_destroy(struct window *w)
|
|||||||
{
|
{
|
||||||
log_debug("window @%u destroyed (%d references)", w->id, w->references);
|
log_debug("window @%u destroyed (%d references)", w->id, w->references);
|
||||||
|
|
||||||
|
active_remove_window(w);
|
||||||
window_unzoom(w, 0);
|
window_unzoom(w, 0);
|
||||||
RB_REMOVE(windows, &windows, w);
|
RB_REMOVE(windows, &windows, w);
|
||||||
|
|
||||||
@@ -675,6 +676,7 @@ void
|
|||||||
window_pane_update_focus(struct window_pane *wp)
|
window_pane_update_focus(struct window_pane *wp)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct client *c;
|
||||||
|
struct window *w;
|
||||||
int focused = 0;
|
int focused = 0;
|
||||||
|
|
||||||
if (wp != NULL && (~wp->flags & PANE_EXITED)) {
|
if (wp != NULL && (~wp->flags & PANE_EXITED)) {
|
||||||
@@ -682,10 +684,12 @@ window_pane_update_focus(struct window_pane *wp)
|
|||||||
focused = 0;
|
focused = 0;
|
||||||
else {
|
else {
|
||||||
TAILQ_FOREACH(c, &clients, entry) {
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
if (c->session != NULL &&
|
if (c->session == NULL)
|
||||||
c->session->attached != 0 &&
|
continue;
|
||||||
|
w = active_get_effective_window(c, c->session);
|
||||||
|
if (c->session->attached != 0 &&
|
||||||
(c->flags & CLIENT_FOCUSED) &&
|
(c->flags & CLIENT_FOCUSED) &&
|
||||||
c->session->curw->window == wp->window &&
|
w == wp->window &&
|
||||||
c->overlay_draw == NULL &&
|
c->overlay_draw == NULL &&
|
||||||
wp->window->menu == NULL) {
|
wp->window->menu == NULL) {
|
||||||
focused = 1;
|
focused = 1;
|
||||||
@@ -1222,7 +1226,7 @@ window_destroy_panes(struct window *w)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
window_printable_flags(struct winlink *wl, int escape)
|
window_printable_flags(struct client *c, struct winlink *wl, int escape)
|
||||||
{
|
{
|
||||||
struct session *s = wl->session;
|
struct session *s = wl->session;
|
||||||
static char flags[32];
|
static char flags[32];
|
||||||
@@ -1237,9 +1241,9 @@ window_printable_flags(struct winlink *wl, int escape)
|
|||||||
flags[pos++] = '!';
|
flags[pos++] = '!';
|
||||||
if (wl->flags & WINLINK_SILENCE)
|
if (wl->flags & WINLINK_SILENCE)
|
||||||
flags[pos++] = '~';
|
flags[pos++] = '~';
|
||||||
if (wl == s->curw)
|
if (active_is_effective_window(c, s, wl))
|
||||||
flags[pos++] = '*';
|
flags[pos++] = '*';
|
||||||
if (wl == TAILQ_FIRST(&s->lastw))
|
if (active_is_last_window(c, s, wl))
|
||||||
flags[pos++] = '-';
|
flags[pos++] = '-';
|
||||||
if (server_check_marked() && wl == marked_pane.wl)
|
if (server_check_marked() && wl == marked_pane.wl)
|
||||||
flags[pos++] = 'M';
|
flags[pos++] = 'M';
|
||||||
|
|||||||
Reference in New Issue
Block a user