Compare commits

...

53 Commits
3.4 ... master

Author SHA1 Message Date
Thomas Adam 4c2eedca5a Merge branch 'obsd-master' 2024-05-19 06:01:09 +01:00
jsg ac6c1e9589 remove prototype with no matching function 2024-05-19 03:27:58 +00:00
Thomas Adam 0903790b00 Merge branch 'obsd-master' 2024-05-18 12:01:09 +01:00
jsg 03de52653e remove prototypes with no matching function; ok nicm@ 2024-05-18 08:51:26 +00:00
jsg da06719309 remove externs with no matching var; ok nicm@ 2024-05-18 08:50:11 +00:00
Thomas Adam fc84097379 Merge branch 'obsd-master' 2024-05-15 14:01:09 +01:00
Thomas Adam 4fd725c6e1 Merge branch 'obsd-master' 2024-05-15 12:01:10 +01:00
nicm d39dcea30a Use default-shell for command prompt #() and popups as well 2024-05-15 09:59:12 +00:00
nicm bfd65398a9 Fix memory leaks reported by Lu Ming Yin. 2024-05-15 08:39:30 +00:00
Thomas Adam 452d987e0e Merge branch 'obsd-master' 2024-05-14 14:01:10 +01:00
Thomas Adam 8ef899f315 Merge branch 'obsd-master' 2024-05-14 12:01:09 +01:00
nicm a18d1146aa Add missing time.h to tty.c (from Ismail Donmez), also remove some stray
spaces.
2024-05-14 10:11:09 +00:00
nicm 5b5004e5ac Revert part of the change for GitHub issue 3675 because it does not work
correctly, it was intended to skip lines that are already being searched
as part of a previous wrapped line but in fact is skipping all lines
except the last in wrapped lines.

Also revert the search-wrapped-lines option (I didn't realize it was
intended to work around this).
2024-05-14 09:32:37 +00:00
Thomas Adam 6ff8f8fbf9 Merge branch 'obsd-master' 2024-05-14 10:01:10 +01:00
nicm c9616700ca Add a command-error hook when a command fails, from Hugh Davenport in
GitHub issue 3973.
2024-05-14 07:52:19 +00:00
nicm 4c928dce74 Add an option to disable unwrapping lines for searching, from
meanderingprogrammer at gmail dot com, GitHub issue 3975.
2024-05-14 07:40:39 +00:00
nicm fb37d52dde Restore previous behaviour or writing to stdout if available. 2024-05-14 07:33:01 +00:00
Thomas Adam 363d9c401e Merge branch 'obsd-master' 2024-05-13 14:01:10 +01:00
nicm 8643ece345 Fix memory leak, from Fadi Afani. 2024-05-13 11:45:05 +00:00
Nicholas Marriott 9ba433e521 Use printf not echo -e, from Joyce Lin. 2024-05-13 12:42:14 +01:00
Nicholas Marriott 3823fa2c57 Send SIGHUP since some programs ignore SIGTERM, from Eduardo Grajeda in GitHub
issue 3958.
2024-04-30 12:38:58 +01:00
Thomas Adam 0a8571b6fe Merge branch 'obsd-master' 2024-04-23 16:09:50 +01:00
jsg ea9f416c99 correct indentation; no functional change
ok tb@
2024-04-23 13:34:51 +00:00
Thomas Adam 036d8993e6 Merge branch 'obsd-master' 2024-04-15 12:01:11 +01:00
nicm e8530c9fee Fixes for memory leaks reported by Lu Ming Yin, fixes from Howard Chu. 2024-04-15 08:19:55 +00:00
Nicholas Marriott dd4c0109a9 Missing headers for Android, from Biswapriyo Nath. 2024-04-15 09:07:41 +01:00
Thomas Adam 43530d4397 Merge branch 'obsd-master' 2024-04-10 10:01:13 +01:00
nicm 553d4cba79 Add an option allow-set-title to forbid applications from changing the
pane title, from someone in GitHub issue 3930.
2024-04-10 07:36:25 +00:00
nicm c62a9ca16b Correct handling of mouse up events (don't ignore all but the last
released button), and always process down event for double click. From
Rudy Dellomas III in GitHub issue 3919.
2024-04-10 07:29:15 +00:00
nicm 424f13fe13 Do not get muddled and crash if focusing a pane that is exiting,
reported by Saul Nogueras in GitHub issue 3776.
2024-04-10 07:15:21 +00:00
Thomas Adam 4bb6da75ba Merge branch 'obsd-master' 2024-04-05 02:01:09 +01:00
nicm a28175dbfd Pick newest session as documented, not oldest, from Magnus Gross. 2024-04-04 22:44:40 +00:00
Thomas Adam fc204bb5e5 Merge branch 'obsd-master' 2024-03-26 12:01:11 +00:00
nicm 6207a45139 Fix selection present check, reported by M Kelly. 2024-03-26 10:20:20 +00:00
Thomas Adam 3c3643f580 Merge branch 'obsd-master' 2024-03-21 14:01:10 +00:00
nicm 89c1c43ef9 Write padding character into the right position. 2024-03-21 12:10:57 +00:00
nicm 2e9d7ebf15 Reduce escape-time default to 10 milliseconds, 500 is far too long for
modern terminals and networks. Case made by Kurtis Rader in GitHub issue
3844.
2024-03-21 11:53:11 +00:00
nicm d8ddeec7db Add -M to always turn mouse on in a menu, GitHub issue 3779. 2024-03-21 11:51:32 +00:00
nicm 6f0254e6a8 Look for feature code 21 for DECSLRM and 28 for DECFRA in the device
attributes and also accept level 1 (there is no hardware with this but
some emulators may use it). Pointed out by James Holderness.
2024-03-21 11:47:55 +00:00
Nicholas Marriott aa17f0e0c1 Fix crash if SIXEL colour register is invalid and remove SIXEL images before
reflow to avoid a different crash, from Anindya Mukherjee.
2024-03-21 11:37:09 +00:00
nicm 0ae8b681b2 Use -p for default paste-buffer command in buffer mode, it will only do
anything if the application asked for it. From Gregory Anders.
2024-03-21 11:32:49 +00:00
nicm 6c0067c103 Do not notify window-layout-changed if the window is about to be
destroyed (since it may have been freed by the time the notify happens),
from Romain Francoise in GitHub issue 3860.
2024-03-21 11:30:42 +00:00
nicm 5458cb2850 Revert detach-client part of last, did not intend this to go in. 2024-03-21 11:27:18 +00:00
nicm 0c374868ca Do not consider a selection present if it is empty, from Michael Grant
(GitHub issue 3869). Also a typo fix from GitHub issue 3877.
2024-03-21 11:26:28 +00:00
Nicholas Marriott bf5d3f2e26 Typo, GitHub issue 3877. 2024-03-21 11:19:59 +00:00
Nicholas Marriott d5ef837f63 Remove duplicate .tmux.conf mention, from Valentin Rylenko. 2024-03-21 11:18:49 +00:00
Thomas Adam b79e28b2c3 Merge branch 'obsd-master' 2024-03-13 14:01:09 +00:00
nicm 8ffd5458ff Make the attach-session description clearer - do not mention creating a
client which is not important, explicitly say the session must exist,
and mention new-session and new-session -A. Prompted by Theo.
2024-03-13 11:25:50 +00:00
Thomas Adam b54e1fc4f7 Merge branch 'obsd-master' 2024-03-07 00:01:10 +00:00
Nicholas Marriott bdb6321229 Update lock.yml. 2024-03-06 21:45:26 +00:00
nicm bd29a48b56 Check for the right flag to fix split-window -p, from Bryan Childs. 2024-03-06 21:32:39 +00:00
Nicholas Marriott f3f1c3db58 Add missing headers, from Marvin Schmidt. 2024-03-06 21:29:28 +00:00
Nicholas Marriott 608d113486 next-3.5 2024-02-13 10:20:18 +00:00
42 changed files with 273 additions and 165 deletions

View File

@ -3,27 +3,32 @@ name: 'Lock Threads'
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
permissions:
contents: read
issues: write
pull-requests: write
discussions: write
concurrency:
group: lock-threads
jobs:
lock:
permissions:
issues: write # for dessant/lock-threads to lock issues
pull-requests: write # for dessant/lock-threads to lock PRs
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2
- uses: dessant/lock-threads@v5
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: '30'
pr-lock-inactive-days: '60'
issue-lock-comment: >
issue-inactive-days: '30'
issue-comment: >
This issue has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new issue for related bugs.
pr-lock-comment: >
pr-inactive-days: '60'
pr-comment: >
This pull request has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new issue for related bugs.
discussion-inactive-days: '60'
discussion-comment: >
This discussion has been automatically locked since there
has not been any recent activity after it was closed.

View File

@ -84,7 +84,7 @@ CHANGES FROM 3.3a to 3.4
* Add message-line option to control where message and prompt go.
* Notification when a when a paste buffer is deleted.
* Notification when a paste buffer is deleted.
* Add a Nobr terminfo(5) capability to tell tmux the terminal does not use bright
colours for bold.

View File

@ -164,10 +164,14 @@ args_parse_flag_argument(struct args_value *values, u_int count, char **cause,
argument = &values[*i];
if (argument->type != ARGS_STRING) {
xasprintf(cause, "-%c argument must be a string", flag);
args_free_value(new);
free(new);
return (-1);
}
}
if (argument == NULL) {
args_free_value(new);
free(new);
if (optional_argument) {
log_debug("%s: -%c (optional)", __func__, flag);
args_set(args, flag, NULL, ARGS_ENTRY_OPTIONAL_VALUE);
@ -662,6 +666,8 @@ args_set(struct args *args, u_char flag, struct args_value *value, int flags)
entry->count++;
if (value != NULL && value->type != ARGS_NONE)
TAILQ_INSERT_TAIL(&entry->values, value, entry);
else
free(value);
}
/* Get argument value. Will be NULL if it isn't present. */

View File

@ -497,20 +497,10 @@ client_send_identify(const char *ttynam, const char *termname, char **caps,
static __dead void
client_exec(const char *shell, const char *shellcmd)
{
const char *name, *ptr;
char *argv0;
char *argv0;
log_debug("shell %s, command %s", shell, shellcmd);
ptr = strrchr(shell, '/');
if (ptr != NULL && *(ptr + 1) != '\0')
name = ptr + 1;
else
name = shell;
if (client_flags & CLIENT_LOGIN)
xasprintf(&argv0, "-%s", name);
else
xasprintf(&argv0, "%s", name);
argv0 = shell_argv0(shell, !!(client_flags & CLIENT_LOGIN));
setenv("SHELL", shell, 1);
proc_clear_signals(client_proc, 1);

View File

@ -143,6 +143,7 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
cdata->prompt_type = status_prompt_type(type);
if (cdata->prompt_type == PROMPT_TYPE_INVALID) {
cmdq_error(item, "unknown type: %s", type);
cmd_command_prompt_free(cdata);
return (CMD_RETURN_ERROR);
}
} else

View File

@ -76,8 +76,10 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
cdata = xcalloc(1, sizeof *cdata);
cdata->cmdlist = args_make_commands_now(self, item, 0, 1);
if (cdata->cmdlist == NULL)
if (cdata->cmdlist == NULL) {
free(cdata);
return (CMD_RETURN_ERROR);
}
if (wait)
cdata->item = item;
@ -90,6 +92,7 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
cdata->confirm_key = confirm_key[0];
else {
cmdq_error(item, "invalid confirm key");
free(cdata);
return (CMD_RETURN_ERROR);
}
}
@ -100,8 +103,8 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
xasprintf(&new_prompt, "%s ", prompt);
else {
cmd = cmd_get_entry(cmd_list_first(cdata->cmdlist))->name;
xasprintf(&new_prompt, "Confirm '%s'? (%c/n) ",
cmd, cdata->confirm_key);
xasprintf(&new_prompt, "Confirm '%s'? (%c/n) ", cmd,
cdata->confirm_key);
}
status_prompt_set(tc, target, new_prompt, NULL,

View File

@ -38,8 +38,8 @@ const struct cmd_entry cmd_display_menu_entry = {
.name = "display-menu",
.alias = "menu",
.args = { "b:c:C:H:s:S:Ot:T:x:y:", 1, -1, cmd_display_menu_args_parse },
.usage = "[-O] [-b border-lines] [-c target-client] "
.args = { "b:c:C:H:s:S:MOt:T:x:y:", 1, -1, cmd_display_menu_args_parse },
.usage = "[-MO] [-b border-lines] [-c target-client] "
"[-C starting-choice] [-H selected-style] [-s style] "
"[-S border-style] " CMD_TARGET_PANE_USAGE "[-T title] "
"[-x position] [-y position] name key command ...",
@ -373,7 +373,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'O'))
flags |= MENU_STAYOPEN;
if (!event->m.valid)
if (!event->m.valid && !args_has(args, 'M'))
flags |= MENU_NOMOUSE;
if (menu_display(menu, flags, starting_choice, item, px, py, tc, lines,
style, selected_style, border_style, target, NULL, NULL) != 0)

View File

@ -246,7 +246,7 @@ cmd_display_panes_key(struct client *c, void *data, struct key_event *event)
wp = window_pane_at_index(w, index);
if (wp == NULL)
return (1);
window_unzoom(w);
window_unzoom(w, 1);
xasprintf(&expanded, "%%%u", wp->id);

View File

@ -664,9 +664,18 @@ cmdq_fire_command(struct cmdq_item *item)
out:
item->client = saved;
if (retval == CMD_RETURN_ERROR)
if (retval == CMD_RETURN_ERROR) {
fsp = NULL;
if (cmd_find_valid_state(&item->target))
fsp = &item->target;
else if (cmd_find_valid_state(&item->state->current))
fsp = &item->state->current;
else if (cmd_find_from_client(&fs, item->client, 0) == 0)
fsp = &fs;
cmdq_insert_hook(fsp != NULL ? fsp->s : NULL, item, fsp,
"command-error");
cmdq_guard(item, "error", flags);
else
} else
cmdq_guard(item, "end", flags);
return (retval);
}
@ -805,10 +814,10 @@ cmdq_running(struct client *c)
struct cmdq_list *queue = cmdq_get(c);
if (queue->item == NULL)
return (NULL);
if (queue->item->flags & CMDQ_WAITING)
return (NULL);
return (queue->item);
return (NULL);
if (queue->item->flags & CMDQ_WAITING)
return (NULL);
return (queue->item);
}
/* Print a guard line. */

View File

@ -87,7 +87,7 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'Z')) {
if (w->flags & WINDOW_ZOOMED)
window_unzoom(w);
window_unzoom(w, 1);
else
window_zoom(wp);
server_redraw_window(w);

View File

@ -85,12 +85,18 @@ cmd_run_shell_print(struct job *job, const char *msg)
if (cdata->wp_id != -1)
wp = window_pane_find_by_id(cdata->wp_id);
if (wp == NULL && cdata->item != NULL && cdata->client != NULL)
wp = server_client_get_pane(cdata->client);
if (wp == NULL && cmd_find_from_nothing(&fs, 0) == 0)
wp = fs.wp;
if (wp == NULL)
return;
if (wp == NULL) {
if (cdata->item != NULL) {
cmdq_print(cdata->item, "%s", msg);
return;
}
if (cdata->item != NULL && cdata->client != NULL)
wp = server_client_get_pane(cdata->client);
if (wp == NULL && cmd_find_from_nothing(&fs, 0) == 0)
wp = fs.wp;
if (wp == NULL)
return;
}
wme = TAILQ_FIRST(&wp->modes);
if (wme == NULL || wme->mode != &window_view_mode)

View File

@ -93,10 +93,10 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
size = -1;
if (args_has(args, 'l')) {
size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
item, &cause);
item, &cause);
} else if (args_has(args, 'p')) {
size = args_strtonum_and_expand(args, 'l', 0, 100, item,
&cause);
size = args_strtonum_and_expand(args, 'p', 0, 100, item,
&cause);
if (cause == NULL)
size = curval * size / 100;
}

2
cmd.c
View File

@ -47,7 +47,6 @@ extern const struct cmd_entry cmd_display_menu_entry;
extern const struct cmd_entry cmd_display_message_entry;
extern const struct cmd_entry cmd_display_popup_entry;
extern const struct cmd_entry cmd_display_panes_entry;
extern const struct cmd_entry cmd_down_pane_entry;
extern const struct cmd_entry cmd_find_window_entry;
extern const struct cmd_entry cmd_has_session_entry;
extern const struct cmd_entry cmd_if_shell_entry;
@ -117,7 +116,6 @@ extern const struct cmd_entry cmd_swap_window_entry;
extern const struct cmd_entry cmd_switch_client_entry;
extern const struct cmd_entry cmd_unbind_key_entry;
extern const struct cmd_entry cmd_unlink_window_entry;
extern const struct cmd_entry cmd_up_pane_entry;
extern const struct cmd_entry cmd_wait_for_entry;
const struct cmd_entry *cmd_table[] = {

View File

@ -289,6 +289,11 @@ void explicit_bzero(void *, size_t);
int getdtablecount(void);
#endif
#ifndef HAVE_GETDTABLESIZE
/* getdtablesize.c */
int getdtablesize(void);
#endif
#ifndef HAVE_CLOSEFROM
/* closefrom.c */
void closefrom(int);

View File

@ -14,6 +14,7 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <arpa/inet.h>
#include <sys/types.h>
#include "compat.h"

View File

@ -14,6 +14,7 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <arpa/inet.h>
#include <sys/types.h>
#include "compat.h"

View File

@ -17,6 +17,7 @@
#include <sys/types.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "compat.h"

View File

@ -24,7 +24,9 @@
#include <systemd/sd-login.h>
#include <systemd/sd-id128.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
@ -142,6 +144,17 @@ systemd_move_pid_to_new_cgroup(pid_t pid, char **cause)
goto finish;
}
/*
* Make sure that the session shells are terminated with SIGHUP since
* bash and friends tend to ignore SIGTERM.
*/
r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", 1);
if (r < 0) {
xasprintf(cause, "failed to append to properties: %s",
strerror(-r));
goto finish;
}
/*
* Inherit the slice from the parent process, or default to
* "app-tmux.slice" if that fails.

View File

@ -1,6 +1,6 @@
# configure.ac
AC_INIT([tmux], 3.4)
AC_INIT([tmux], next-3.5)
AC_PREREQ([2.60])
AC_CONFIG_AUX_DIR(etc)

View File

@ -489,6 +489,9 @@ sixel_print(struct sixel_image *si, struct sixel_image *map, size_t *size)
colours = si->colours;
ncolours = si->ncolours;
}
if (ncolours == 0)
return (NULL);
contains = xcalloc(1, ncolours);
len = 8192;

View File

@ -1839,7 +1839,7 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
/* Handle CSI graphics SM. */
static void
input_csi_dispatch_sm_graphics(struct input_ctx *ictx)
input_csi_dispatch_sm_graphics(__unused struct input_ctx *ictx)
{
#ifdef ENABLE_SIXEL
int n, m, o;
@ -2372,7 +2372,9 @@ input_exit_osc(struct input_ctx *ictx)
switch (option) {
case 0:
case 2:
if (screen_set_title(sctx->s, p) && wp != NULL) {
if (wp != NULL &&
options_get_number(wp->options, "allow-set-title") &&
screen_set_title(sctx->s, p)) {
notify_pane("pane-title-changed", wp);
server_redraw_window_borders(wp->window);
server_status_window(wp->window);

31
job.c
View File

@ -77,19 +77,28 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
struct environ *env;
pid_t pid;
int nullfd, out[2], master;
const char *home;
const char *home, *shell;
sigset_t set, oldset;
struct winsize ws;
char **argvp, tty[TTY_NAME_MAX];
char **argvp, tty[TTY_NAME_MAX], *argv0;
/*
* Do not set TERM during .tmux.conf, it is nice to be able to use
* if-shell to decide on default-terminal based on outside TERM.
* Do not set TERM during .tmux.conf (second argument here), it is nice
* to be able to use if-shell to decide on default-terminal based on
* outside TERM.
*/
env = environ_for_session(s, !cfg_finished);
if (e != NULL)
environ_copy(e, env);
if (s != NULL)
shell = options_get_string(s->options, "default-shell");
else
shell = options_get_string(global_s_options, "default-shell");
if (!checkshell(shell))
shell = _PATH_BSHELL;
argv0 = shell_argv0(shell, 0);
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, &oldset);
@ -105,10 +114,11 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
}
if (cmd == NULL) {
cmd_log_argv(argc, argv, "%s:", __func__);
log_debug("%s: cwd=%s", __func__, cwd == NULL ? "" : cwd);
log_debug("%s: cwd=%s, shell=%s", __func__,
cwd == NULL ? "" : cwd, shell);
} else {
log_debug("%s: cmd=%s, cwd=%s", __func__, cmd,
cwd == NULL ? "" : cwd);
log_debug("%s: cmd=%s, cwd=%s, shell=%s", __func__, cmd,
cwd == NULL ? "" : cwd, shell);
}
switch (pid) {
@ -150,7 +160,8 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
closefrom(STDERR_FILENO + 1);
if (cmd != NULL) {
execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
setenv("SHELL", shell, 1);
execl(shell, argv0, "-c", cmd, (char *)NULL);
fatal("execl failed");
} else {
argvp = cmd_copy_argv(argc, argv);
@ -161,6 +172,7 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
sigprocmask(SIG_SETMASK, &oldset, NULL);
environ_free(env);
free(argv0);
job = xmalloc(sizeof *job);
job->state = JOB_RUNNING;
@ -194,12 +206,13 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
fatalx("out of memory");
bufferevent_enable(job->event, EV_READ|EV_WRITE);
log_debug("run job %p: %s, pid %ld", job, job->cmd, (long) job->pid);
log_debug("run job %p: %s, pid %ld", job, job->cmd, (long)job->pid);
return (job);
fail:
sigprocmask(SIG_SETMASK, &oldset, NULL);
environ_free(env);
free(argv0);
return (NULL);
}

View File

@ -230,7 +230,7 @@ layout_parse(struct window *w, const char *layout, char **cause)
/* Check the new layout. */
if (!layout_check(lc)) {
*cause = xstrdup("size mismatch after applying layout");
return (-1);
goto fail;
}
/* Resize to the layout size. */

View File

@ -285,7 +285,7 @@ const struct options_table_entry options_table[] = {
.scope = OPTIONS_TABLE_SERVER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 500,
.default_num = 10,
.unit = "milliseconds",
.text = "Time to wait before assuming a key is Escape."
},
@ -875,6 +875,14 @@ const struct options_table_entry options_table[] = {
"to rename windows."
},
{ .name = "allow-set-title",
.type = OPTIONS_TABLE_FLAG,
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_num = 1,
.text = "Whether applications are allowed to use the escape sequence "
"to set the pane title."
},
{ .name = "alternate-screen",
.type = OPTIONS_TABLE_FLAG,
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
@ -1317,6 +1325,7 @@ const struct options_table_entry options_table[] = {
OPTIONS_TABLE_HOOK("client-focus-out", ""),
OPTIONS_TABLE_HOOK("client-resized", ""),
OPTIONS_TABLE_HOOK("client-session-changed", ""),
OPTIONS_TABLE_HOOK("command-error", ""),
OPTIONS_TABLE_PANE_HOOK("pane-died", ""),
OPTIONS_TABLE_PANE_HOOK("pane-exited", ""),
OPTIONS_TABLE_PANE_HOOK("pane-focus-in", ""),

View File

@ -345,7 +345,7 @@ popup_make_pane(struct popup_data *pd, enum layout_type type)
u_int hlimit;
const char *shell;
window_unzoom(w);
window_unzoom(w, 1);
lc = layout_split_pane(wp, type, -1, 0);
hlimit = options_get_number(s->options, "history-limit");

View File

@ -42,14 +42,14 @@ $TMUX send-keys -X begin-selection
$TMUX send-keys -X next-word-end
$TMUX send-keys -X next-word-end
$TMUX send-keys -X copy-selection
[ "$($TMUX show-buffer)" = "$(echo -e "words\n Indented")" ] || exit 1
[ "$($TMUX show-buffer)" = "$(printf "words\n Indented")" ] || exit 1
# Test that `next-word` wraps around un-indented line breaks.
$TMUX send-keys -X next-word
$TMUX send-keys -X begin-selection
$TMUX send-keys -X next-word
$TMUX send-keys -X copy-selection
[ "$($TMUX show-buffer)" = "$(echo -e "line\n")" ] || exit 1
[ "$($TMUX show-buffer)" = "$(printf "line\n")" ] || exit 1
# Test that `next-word-end` treats periods as letters.
$TMUX send-keys -X next-word
@ -63,14 +63,14 @@ $TMUX send-keys -X previous-word
$TMUX send-keys -X begin-selection
$TMUX send-keys -X next-word
$TMUX send-keys -X copy-selection
[ "$($TMUX show-buffer)" = "$(echo -e "line...\n")" ] || exit 1
[ "$($TMUX show-buffer)" = "$(printf "line...\n")" ] || exit 1
# Test that `previous-space` and `next-space` treat periods as letters.
$TMUX send-keys -X previous-space
$TMUX send-keys -X begin-selection
$TMUX send-keys -X next-space
$TMUX send-keys -X copy-selection
[ "$($TMUX show-buffer)" = "$(echo -e "line...\n")" ] || exit 1
[ "$($TMUX show-buffer)" = "$(printf "line...\n")" ] || exit 1
# Test that `next-word` and `next-word-end` treat other symbols as letters.
$TMUX send-keys -X begin-selection
@ -87,7 +87,7 @@ $TMUX send-keys -X previous-word
$TMUX send-keys -X begin-selection
$TMUX send-keys -X next-word
$TMUX send-keys -X copy-selection
[ "$($TMUX show-buffer)" = "$(echo -e "\$ym_bols[]{}\n ")" ] || exit 1
[ "$($TMUX show-buffer)" = "$(printf "\$ym_bols[]{}\n ")" ] || exit 1
# Test that `next-word-end` treats digits as letters
$TMUX send-keys -X next-word-end

View File

@ -41,14 +41,14 @@ $TMUX send-keys -X begin-selection
$TMUX send-keys -X next-word-end
$TMUX send-keys -X next-word-end
$TMUX send-keys -X copy-selection
[ "$($TMUX show-buffer)" = "$(echo -e "words\n Indented")" ] || exit 1
[ "$($TMUX show-buffer)" = "$(printf "words\n Indented")" ] || exit 1
# Test that `next-word` wraps around un-indented line breaks.
$TMUX send-keys -X next-word
$TMUX send-keys -X begin-selection
$TMUX send-keys -X next-word
$TMUX send-keys -X copy-selection
[ "$($TMUX show-buffer)" = "$(echo -e "line\nA")" ] || exit 1
[ "$($TMUX show-buffer)" = "$(printf "line\nA")" ] || exit 1
# Test that `next-word-end` does not treat periods as letters.
$TMUX send-keys -X next-word
@ -69,7 +69,7 @@ $TMUX send-keys -X previous-space
$TMUX send-keys -X begin-selection
$TMUX send-keys -X next-space
$TMUX send-keys -X copy-selection
[ "$($TMUX show-buffer)" = "$(echo -e "line...\n.")" ] || exit 1
[ "$($TMUX show-buffer)" = "$(printf "line...\n.")" ] || exit 1
# Test that `next-word` and `next-word-end` do not treat other symbols as letters.
$TMUX send-keys -X begin-selection
@ -85,7 +85,7 @@ $TMUX send-keys -X next-space
$TMUX send-keys -X begin-selection
$TMUX send-keys -X next-space
$TMUX send-keys -X copy-selection
[ "$($TMUX show-buffer)" = "$(echo -e "\$ym_bols[]{}\n ?")" ] || exit 1
[ "$($TMUX show-buffer)" = "$(printf "\$ym_bols[]{}\n ?")" ] || exit 1
# Test that `next-word-end` treats digits as letters
$TMUX send-keys -X next-word-end

View File

@ -40,7 +40,7 @@ resize_window(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
/* If the window is zoomed, unzoom. */
zoomed = w->flags & WINDOW_ZOOMED;
if (zoomed)
window_unzoom(w);
window_unzoom(w, 1);
/* Resize the layout first. */
layout_resize(w, sx, sy);

View File

@ -2148,7 +2148,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
/* Set the new cell. */
grid_view_set_cell(gd, cx - n, cy, &last);
if (force_wide)
grid_view_set_padding(gd, cx, cy);
grid_view_set_padding(gd, cx - 1, cy);
/*
* Redraw the combined cell. If forcing the cell to width 2, reset the
@ -2283,6 +2283,10 @@ screen_write_sixelimage(struct screen_write_ctx *ctx, struct sixel_image *si,
new = sixel_scale(si, 0, 0, 0, y - sy, sx, sy, 1);
sixel_free(si);
si = new;
/* Bail out if the image cannot be scaled. */
if (si == NULL)
return;
sixel_size_in_cells(si, &x, &y);
}

View File

@ -308,12 +308,12 @@ screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
if (sy != screen_size_y(s))
screen_resize_y(s, sy, eat_empty, &cy);
if (reflow) {
#ifdef ENABLE_SIXEL
image_free_all(s);
image_free_all(s);
#endif
if (reflow)
screen_reflow(s, sx, &cx, &cy, cursor);
}
if (cy >= s->grid->hsize) {
s->cx = cx;
@ -400,7 +400,7 @@ screen_resize_y(struct screen *s, u_int sy, int eat_empty, u_int *cy)
/*
* Try to pull as much as possible out of scrolled history, if
* is is enabled.
* it is enabled.
*/
available = gd->hscrolled;
if (gd->flags & GRID_HISTORY && available > 0) {

View File

@ -622,6 +622,8 @@ server_client_check_mouse(struct client *c, struct key_event *event)
} else if (MOUSE_RELEASE(m->b)) {
type = UP;
x = m->x, y = m->y, b = m->lb;
if (m->sgr_type == 'm')
b = m->sgr_b;
log_debug("up at %u,%u", x, y);
} else {
if (c->flags & CLIENT_DOUBLECLICK) {
@ -642,7 +644,10 @@ server_client_check_mouse(struct client *c, struct key_event *event)
log_debug("triple-click at %u,%u", x, y);
goto have_event;
}
} else {
}
/* DOWN is the only remaining event type. */
if (type == NOTYPE) {
type = DOWN;
x = m->x, y = m->y, b = m->b;
log_debug("down at %u,%u", x, y);

View File

@ -411,7 +411,7 @@ server_find_session(struct session *s,
static int
server_newer_session(struct session *s_loop, struct session *s_out)
{
return (timercmp(&s_loop->activity_time, &s_out->activity_time, <));
return (timercmp(&s_loop->activity_time, &s_out->activity_time, >));
}
static int
@ -488,6 +488,6 @@ server_check_unattached(void)
void
server_unzoom_window(struct window *w)
{
if (window_unzoom(w) == 0)
if (window_unzoom(w, 1) == 0)
server_redraw_window(w);
}

View File

@ -264,7 +264,7 @@ server_loop(void)
struct client *c;
u_int items;
current_time = time (NULL);
current_time = time(NULL);
do {
items = cmdq_next(NULL);

View File

@ -994,8 +994,7 @@ status_prompt_paste(struct client *c)
if ((pb = paste_get_top(NULL)) == NULL)
return (0);
bufdata = paste_buffer_data(pb, &bufsize);
ud = xreallocarray(NULL, bufsize + 1, sizeof *ud);
udp = ud;
ud = udp = xreallocarray(NULL, bufsize + 1, sizeof *ud);
for (i = 0; i != bufsize; /* nothing */) {
more = utf8_open(udp, bufdata[i]);
if (more == UTF8_MORE) {
@ -1016,25 +1015,24 @@ status_prompt_paste(struct client *c)
udp->size = 0;
n = udp - ud;
}
if (n == 0)
return (0);
c->prompt_buffer = xreallocarray(c->prompt_buffer, size + n + 1,
sizeof *c->prompt_buffer);
if (c->prompt_index == size) {
memcpy(c->prompt_buffer + c->prompt_index, ud,
n * sizeof *c->prompt_buffer);
c->prompt_index += n;
c->prompt_buffer[c->prompt_index].size = 0;
} else {
memmove(c->prompt_buffer + c->prompt_index + n,
c->prompt_buffer + c->prompt_index,
(size + 1 - c->prompt_index) * sizeof *c->prompt_buffer);
memcpy(c->prompt_buffer + c->prompt_index, ud,
n * sizeof *c->prompt_buffer);
c->prompt_index += n;
if (n != 0) {
c->prompt_buffer = xreallocarray(c->prompt_buffer, size + n + 1,
sizeof *c->prompt_buffer);
if (c->prompt_index == size) {
memcpy(c->prompt_buffer + c->prompt_index, ud,
n * sizeof *c->prompt_buffer);
c->prompt_index += n;
c->prompt_buffer[c->prompt_index].size = 0;
} else {
memmove(c->prompt_buffer + c->prompt_index + n,
c->prompt_buffer + c->prompt_index,
(size + 1 - c->prompt_index) *
sizeof *c->prompt_buffer);
memcpy(c->prompt_buffer + c->prompt_index, ud,
n * sizeof *c->prompt_buffer);
c->prompt_index += n;
}
}
if (ud != c->prompt_saved)
free(ud);
return (1);
@ -1839,6 +1837,7 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
}
if (size == 0) {
menu_free(menu);
free(spm);
return (NULL);
}
if (size == 1) {
@ -1849,6 +1848,7 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
} else
tmp = list[0];
free(list);
free(spm);
return (tmp);
}
if (height > size)

46
tmux.1
View File

@ -140,10 +140,9 @@ By default,
loads the system configuration file from
.Pa @SYSCONFDIR@/tmux.conf ,
if present, then looks for a user configuration file at
.Pa \[ti]/.tmux.conf,
.Pa $XDG_CONFIG_HOME/tmux/tmux.conf
.Pa \[ti]/.tmux.conf
or
.Pa \[ti]/.tmux.conf .
.Pa $XDG_CONFIG_HOME/tmux/tmux.conf .
.Pp
The configuration file is a set of
.Nm
@ -1039,9 +1038,17 @@ The following commands are available to manage clients and sessions:
.D1 Pq alias: Ic attach
If run from outside
.Nm ,
create a new client in the current terminal and attach it to
attach to
.Ar target-session
in the current terminal.
.Ar target-session
must already exist - to create a new session, see the
.Ic new-session
command (with
.Fl A
to create or attach).
If used from inside, switch the currently attached session to
.Ar target-session .
If used from inside, switch the current client.
If
.Fl d
is specified, any other clients attached to the session are detached.
@ -3740,7 +3747,6 @@ Set the time in milliseconds for which
.Nm
waits after an escape is input to determine if it is part of a function or meta
key sequences.
The default is 500 milliseconds.
.It Ic editor Ar shell-command
Set the command used when
.Nm
@ -4746,6 +4752,12 @@ they will be allowed even if the pane is invisible.
Allow programs in the pane to change the window name using a terminal escape
sequence (\eek...\ee\e\e).
.Pp
.It Xo Ic allow-set-title
.Op Ic on | off
.Xc
Allow programs in the pane to change the title using the terminal escape
sequences (\ee]2;...\ee\e\e or \ee]0;...\ee\e\e).
.Pp
.It Xo Ic alternate-screen
.Op Ic on | off
.Xc
@ -4871,6 +4883,14 @@ layout after every
set-hook -g after-split-window "selectl even-vertical"
.Ed
.Pp
If a command fails, the
.Ql command-error
hook will be fired.
For example, this could be used to write to a log file:
.Bd -literal -offset indent
set-hook -g command-error "run-shell \\"echo 'a tmux command failed' >>/tmp/log\\""
.Ed
.Pp
All the notifications listed in the
.Sx CONTROL MODE
section are hooks (without any arguments), except
@ -4903,6 +4923,8 @@ Run when focus exits a client
Run when a client is resized.
.It client-session-changed
Run when a client's attached session is changed.
.It command-error
Run when a command fails.
.It pane-died
Run when the program running in a pane exits, but
.Ic remain-on-exit
@ -6111,7 +6133,7 @@ the default is
.Ql y .
.Tg menu
.It Xo Ic display-menu
.Op Fl O
.Op Fl OM
.Op Fl b Ar border-lines
.Op Fl c Ar target-client
.Op Fl C Ar starting-choice
@ -6218,7 +6240,13 @@ changes this behaviour so that the menu does not close when the mouse button is
released without an item selected the menu is not closed and a mouse button
must be clicked to choose an item.
.Pp
The following keys are also available:
.Fl M
tells
.Nm
the menu should handle mouse events; by default only menus opened from mouse
key bindings do so.
.Pp
The following keys are available in menus:
.Bl -column "Key" "Function" -offset indent
.It Sy "Key" Ta Sy "Function"
.It Li "Enter" Ta "Choose selected item"
@ -6464,7 +6492,7 @@ is replaced by the buffer name in
and the result executed as a command.
If
.Ar template
is not given, "paste-buffer -b \[aq]%%\[aq]" is used.
is not given, "paste-buffer -p -b \[aq]%%\[aq]" is used.
.Pp
.Fl O
specifies the initial sort field: one of

18
tmux.c
View File

@ -235,6 +235,24 @@ fail:
return (NULL);
}
char *
shell_argv0(const char *shell, int is_login)
{
const char *slash, *name;
char *argv0;
slash = strrchr(shell, '/');
if (slash != NULL && slash[1] != '\0')
name = slash + 1;
else
name = shell;
if (is_login)
xasprintf(&argv0, "-%s", name);
else
xasprintf(&argv0, "%s", name);
return (argv0);
}
void
setblocking(int fd, int state)
{

13
tmux.h
View File

@ -877,7 +877,7 @@ struct screen_sel;
struct screen_titles;
struct screen {
char *title;
char *path;
char *path;
struct screen_titles *titles;
struct grid *grid; /* grid data */
@ -2096,6 +2096,7 @@ extern int ptm_fd;
extern const char *shell_command;
int checkshell(const char *);
void setblocking(int, int);
char *shell_argv0(const char *, int);
uint64_t get_timer(void);
const char *sig2name(int);
const char *find_cwd(void);
@ -2390,7 +2391,6 @@ void tty_cmd_clearstartofscreen(struct tty *, const struct tty_ctx *);
void tty_cmd_deletecharacter(struct tty *, const struct tty_ctx *);
void tty_cmd_clearcharacter(struct tty *, const struct tty_ctx *);
void tty_cmd_deleteline(struct tty *, const struct tty_ctx *);
void tty_cmd_erasecharacter(struct tty *, const struct tty_ctx *);
void tty_cmd_insertcharacter(struct tty *, const struct tty_ctx *);
void tty_cmd_insertline(struct tty *, const struct tty_ctx *);
void tty_cmd_linefeed(struct tty *, const struct tty_ctx *);
@ -2567,7 +2567,6 @@ enum cmd_retval cmd_attach_session(struct cmdq_item *, const char *, int, int,
int, const char *, int, const char *);
/* cmd-parse.c */
void cmd_parse_empty(struct cmd_parse_input *);
struct cmd_parse_result *cmd_parse_from_file(FILE *, struct cmd_parse_input *);
struct cmd_parse_result *cmd_parse_from_string(const char *,
struct cmd_parse_input *);
@ -2728,8 +2727,6 @@ void server_client_suspend(struct client *);
void server_client_detach(struct client *, enum msgtype);
void server_client_exec(struct client *, const char *);
void server_client_loop(void);
void server_client_push_stdout(struct client *);
void server_client_push_stderr(struct client *);
const char *server_client_get_cwd(struct client *, struct session *);
void server_client_set_flags(struct client *, const char *);
const char *server_client_get_flags(struct client *);
@ -3070,7 +3067,7 @@ struct window_pane *window_add_pane(struct window *, struct window_pane *,
void window_resize(struct window *, u_int, u_int, int, int);
void window_pane_send_resize(struct window_pane *, u_int, u_int);
int window_zoom(struct window_pane *);
int window_unzoom(struct window *);
int window_unzoom(struct window *, int);
int window_push_zoom(struct window *, int, int);
int window_pop_zoom(struct window *);
void window_lost_pane(struct window *, struct window_pane *);
@ -3259,8 +3256,6 @@ void control_add_sub(struct client *, const char *, enum control_sub_type,
void control_remove_sub(struct client *, const char *);
/* control-notify.c */
void control_notify_input(struct client *, struct window_pane *,
const u_char *, size_t);
void control_notify_pane_mode_changed(int);
void control_notify_window_layout_changed(struct window *);
void control_notify_window_pane_changed(struct window *);
@ -3294,8 +3289,6 @@ char *session_check_name(const char *);
void session_update_activity(struct session *, struct timeval *);
struct session *session_next_session(struct session *);
struct session *session_previous_session(struct session *);
struct winlink *session_new(struct session *, const char *, int, char **,
const char *, const char *, int, char **);
struct winlink *session_attach(struct session *, struct window *, int,
char **);
int session_detach(struct session *, struct winlink *);

View File

@ -1314,26 +1314,21 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
break;
}
/*
* Add terminal features. Hardware level 5 does not offer SIXEL but
* some terminal emulators report it anyway and it does not harm
* to check it here.
*
* DECSLRM and DECFRA should be supported by level 5 as well as level
* 4, but VTE has rather ruined it by advertising level 5 despite not
* supporting them.
*/
/* Add terminal features. */
switch (p[0]) {
case 64: /* level 4 */
tty_add_features(features, "margins,rectfill", ",");
/* FALLTHROUGH */
case 61: /* level 1 */
case 62: /* level 2 */
case 63: /* level 3 */
case 64: /* level 4 */
case 65: /* level 5 */
for (i = 1; i < n; i++) {
log_debug("%s: DA feature: %d", c->name, p[i]);
if (p[i] == 4)
tty_add_features(features, "sixel", ",");
if (p[i] == 21)
tty_add_features(features, "margins", ",");
if (p[i] == 28)
tty_add_features(features, "rectfill", ",");
}
break;
}
@ -1405,11 +1400,6 @@ tty_keys_device_attributes2(struct tty *tty, const char *buf, size_t len,
* we can't use level 5 from DA because of VTE.
*/
switch (p[0]) {
case 41: /* VT420 */
case 61: /* VT510 */
case 64: /* VT520 */
tty_add_features(features, "margins,rectfill", ",");
break;
case 'M': /* mintty */
tty_default_features(features, "mintty", 0);
break;

5
tty.c
View File

@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include "tmux.h"
@ -379,13 +380,13 @@ tty_send_requests(struct tty *tty)
tty_puts(tty, "\033]11;?\033\\");
} else
tty->flags |= TTY_ALL_REQUEST_FLAGS;
tty->last_requests = time (NULL);
tty->last_requests = time(NULL);
}
void
tty_repeat_requests(struct tty *tty)
{
time_t t = time (NULL);
time_t t = time(NULL);
if (~tty->flags & TTY_STARTED)
return;

View File

@ -36,7 +36,7 @@ static void window_buffer_key(struct window_mode_entry *,
struct client *, struct session *,
struct winlink *, key_code, struct mouse_event *);
#define WINDOW_BUFFER_DEFAULT_COMMAND "paste-buffer -b '%%'"
#define WINDOW_BUFFER_DEFAULT_COMMAND "paste-buffer -p -b '%%'"
#define WINDOW_BUFFER_DEFAULT_FORMAT \
"#{t/p:buffer_created}: #{buffer_sample}"

View File

@ -795,16 +795,24 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft)
format_add(ft, "copy_cursor_x", "%d", data->cx);
format_add(ft, "copy_cursor_y", "%d", data->cy);
format_add(ft, "selection_present", "%d", data->screen.sel != NULL);
if (data->screen.sel != NULL) {
format_add(ft, "selection_start_x", "%d", data->selx);
format_add(ft, "selection_start_y", "%d", data->sely);
format_add(ft, "selection_end_x", "%d", data->endselx);
format_add(ft, "selection_end_y", "%d", data->endsely);
format_add(ft, "selection_active", "%d",
data->cursordrag != CURSORDRAG_NONE);
} else
format_add(ft, "selection_active", "%d", 0);
if (data->cursordrag != CURSORDRAG_NONE)
format_add(ft, "selection_active", "1");
else
format_add(ft, "selection_active", "0");
if (data->endselx != data->selx || data->endsely != data->sely)
format_add(ft, "selection_present", "1");
else
format_add(ft, "selection_present", "0");
} else {
format_add(ft, "selection_active", "0");
format_add(ft, "selection_present", "0");
}
format_add(ft, "search_present", "%d", data->searchmark != NULL);
format_add_cb(ft, "search_match", window_copy_search_match_cb);
@ -3606,11 +3614,10 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap,
int direction, int regex)
{
u_int i, px, sx, ssize = 1;
int found = 0, cflags = REG_EXTENDED;
char *sbuf;
regex_t reg;
struct grid_line *gl;
u_int i, px, sx, ssize = 1;
int found = 0, cflags = REG_EXTENDED;
char *sbuf;
regex_t reg;
if (regex) {
sbuf = xmalloc(ssize);
@ -3627,9 +3634,6 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
if (direction) {
for (i = fy; i <= endline; i++) {
gl = grid_get_line(gd, i);
if (i != endline && gl->flags & GRID_LINE_WRAPPED)
continue;
if (regex) {
found = window_copy_search_lr_regex(gd,
&px, &sx, i, fx, gd->sx, &reg);
@ -3643,9 +3647,6 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
}
} else {
for (i = fy + 1; endline < i; i--) {
gl = grid_get_line(gd, i - 1);
if (i != endline && gl->flags & GRID_LINE_WRAPPED)
continue;
if (regex) {
found = window_copy_search_rl_regex(gd,
&px, &sx, i - 1, 0, fx + 1, &reg);
@ -4686,7 +4687,7 @@ window_copy_get_selection(struct window_mode_entry *wme, size_t *len)
if (keys == MODEKEY_EMACS || lastex <= ey_last) {
if (~grid_get_line(data->backing->grid, ey)->flags &
GRID_LINE_WRAPPED || lastex != ey_last)
off -= 1;
off -= 1;
}
*len = off;
return (buf);

View File

@ -338,7 +338,7 @@ window_destroy(struct window *w)
{
log_debug("window @%u destroyed (%d references)", w->id, w->references);
window_unzoom(w);
window_unzoom(w, 0);
RB_REMOVE(windows, &windows, w);
if (w->layout_root != NULL)
@ -481,7 +481,7 @@ window_pane_update_focus(struct window_pane *wp)
struct client *c;
int focused = 0;
if (wp != NULL) {
if (wp != NULL && (~wp->flags & PANE_EXITED)) {
if (wp != wp->window->active)
focused = 0;
else {
@ -673,7 +673,7 @@ window_zoom(struct window_pane *wp)
}
int
window_unzoom(struct window *w)
window_unzoom(struct window *w, int notify)
{
struct window_pane *wp;
@ -690,7 +690,9 @@ window_unzoom(struct window *w)
wp->saved_layout_cell = NULL;
}
layout_fix_panes(w, NULL);
notify_window("window-layout-changed", w);
if (notify)
notify_window("window-layout-changed", w);
return (0);
}
@ -704,7 +706,7 @@ window_push_zoom(struct window *w, int always, int flag)
w->flags |= WINDOW_WASZOOMED;
else
w->flags &= ~WINDOW_WASZOOMED;
return (window_unzoom(w) == 0);
return (window_unzoom(w, 1) == 0);
}
int