Compare commits

...

17 Commits

Author SHA1 Message Date
Nicholas Marriott
e9634d4074 Set used for popup ranges. 2026-08-31 11:25:09 +01:00
nicm
181e818b93 Do no free input context if it is NULL when popup create fails. 2026-08-28 11:46:41 +01:00
nicm
1c98c3a2a3 Do not walk off end of grid lines if last line is wrapped, reported by
Moe Khalilov.
2026-08-28 11:46:20 +01:00
Nicholas Marriott
d28c9f613d Do not loop forever if a pane ends up with borders the wrong way round. 2026-08-28 10:25:42 +01:00
Nicholas Marriott
0d7b9e87f4 Update CHANGES. 2026-08-24 16:01:11 +01:00
nicm
4ec08da492 Do not use stale pointers in modes. 2026-08-24 15:57:56 +01:00
Nicholas Marriott
22cdf6acac 3.7d bits. 2026-08-24 08:18:18 +01:00
nicm
83b9aff1ae Make list-keys only use a message if -1 is given, otherwise behave like
other commands (stdout or mode).
2026-08-24 08:17:56 +01:00
Nicholas Marriott
e476c1230b Build with jemalloc on macOS for 3.7c also. 2026-07-23 12:16:26 +01:00
Nicholas Marriott
746f275d41 Update CHANGES. 2026-07-13 11:34:52 +01:00
nicm
e2d26c20d2 Check time periodically in loops rather than every one. 2026-07-13 11:33:01 +01:00
nicm
81e12f5397 Allow empty name with new-window again, from Jacob Koziej. 2026-07-09 08:51:07 +01:00
nicm
8f3963635b Set initial scrollbar state, from Michael Grant. 2026-07-08 12:15:47 +01:00
Nicholas Marriott
18d5232804 Fix empty argument to splitw. 2026-07-08 09:57:49 +01:00
nicm
c515d8cae0 Do not crash looking for next or previous session. GitHub issue 5344. 2026-07-08 09:56:40 +01:00
Nicholas Marriott
8237d72900 Unzoom before creating floating pane. 2026-07-06 09:05:05 +01:00
nicm
173cc3dfc5 Use message-style as default for message-format again. GitHub issue 5315. 2026-07-06 09:00:10 +01:00
16 changed files with 207 additions and 29 deletions

19
CHANGES
View File

@@ -1,3 +1,22 @@
CHANGES FROM 3.7c TO 3.7d
* Do not use stale pointers to windows when panes in modes are joined.
* Fix problem where list-keys output can go to view mode instead of stdout.
CHANGES FROM 3.7b TO 3.7c
* Build with jemalloc on macOS to avoid what appears to be a bug in calloc
(issue 5385).
* Fix scrollbar initial state so they appear on new windows (issue 5339).
* Check time periodically in loops rather than every one (issue 5367).
* Use message-style again as default for message-format.
* Unzoom before creating floating panes to avoid a crash.
CHANGES FROM 3.7a TO 3.7b CHANGES FROM 3.7a TO 3.7b
* Fix so that the end of a synchronized update again triggers a redraw. * Fix so that the end of a synchronized update again triggers a redraw.

View File

@@ -237,7 +237,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
cmd_list_keys_format_add_key_binding(ft, l[i], prefix); cmd_list_keys_format_add_key_binding(ft, l[i], prefix);
line = format_expand(ft, template); line = format_expand(ft, template);
if ((single && tc != NULL) || n == 1) if (single && tc != NULL && (~tc->flags & CLIENT_CONTROL))
status_message_set(tc, -1, 1, 0, 0, "%s", line); status_message_set(tc, -1, 1, 0, 0, "%s", line);
else if (*line != '\0') else if (*line != '\0')
cmdq_print(item, "%s", line); cmdq_print(item, "%s", line);

View File

@@ -101,7 +101,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
flags |= SPAWN_FULLSIZE; flags |= SPAWN_FULLSIZE;
input = args_has(args, 'I'); input = args_has(args, 'I');
if (input) if (input || (count == 1 && *args_string(args, 0) == '\0'))
empty = 1; empty = 1;
else else
empty = args_has(args, 'E'); empty = args_has(args, 'E');

View File

@@ -1,6 +1,6 @@
# configure.ac # configure.ac
AC_INIT([tmux], 3.7b) AC_INIT([tmux], 3.7d)
AC_PREREQ([2.60]) AC_PREREQ([2.60])
AC_CONFIG_AUX_DIR(etc) AC_CONFIG_AUX_DIR(etc)
@@ -76,9 +76,7 @@ AM_CONDITIONAL(IS_OPTIMIZED, test "x$enable_optimizations" = xyes)
# Is this --enable-asan? # Is this --enable-asan?
AC_ARG_ENABLE( AC_ARG_ENABLE(
asan, asan,
AS_HELP_STRING(--enable-asan, enable ASAN build flags), AS_HELP_STRING(--enable-asan, enable ASAN build flags)
,
enable_asan=no
) )
AM_CONDITIONAL(IS_ASAN, test "x$enable_asan" = xyes) AM_CONDITIONAL(IS_ASAN, test "x$enable_asan" = xyes)
@@ -241,6 +239,7 @@ AC_LIBOBJ(getopt_long)
# Look for libevent. Try libevent_core or libevent with pkg-config first then # Look for libevent. Try libevent_core or libevent with pkg-config first then
# look for the library. # look for the library.
libevent_version=off
PKG_CHECK_MODULES( PKG_CHECK_MODULES(
LIBEVENT_CORE, LIBEVENT_CORE,
[libevent_core >= 2], [libevent_core >= 2],
@@ -249,6 +248,8 @@ PKG_CHECK_MODULES(
CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS" CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS"
LIBS="$LIBEVENT_CORE_LIBS $LIBS" LIBS="$LIBEVENT_CORE_LIBS $LIBS"
found_libevent=yes found_libevent=yes
libevent_version=`$PKG_CONFIG --modversion libevent_core 2>/dev/null`
test "x$libevent_version" = x && libevent_version=on
], ],
found_libevent=no found_libevent=no
) )
@@ -261,6 +262,8 @@ if test x$found_libevent = xno; then
CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS" CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS"
LIBS="$LIBEVENT_LIBS $LIBS" LIBS="$LIBEVENT_LIBS $LIBS"
found_libevent=yes found_libevent=yes
libevent_version=`$PKG_CONFIG --modversion libevent 2>/dev/null`
test "x$libevent_version" = x && libevent_version=on
], ],
found_libevent=no found_libevent=no
) )
@@ -269,7 +272,8 @@ if test x$found_libevent = xno; then
AC_SEARCH_LIBS( AC_SEARCH_LIBS(
event_init, event_init,
[event_core event event-1.4], [event_core event event-1.4],
found_libevent=yes, [found_libevent=yes
libevent_version=on],
found_libevent=no found_libevent=no
) )
fi fi
@@ -296,6 +300,7 @@ fi
# Look for ncurses or curses. Try pkg-config first then directly for the # Look for ncurses or curses. Try pkg-config first then directly for the
# library. # library.
ncurses_version=off
PKG_CHECK_MODULES( PKG_CHECK_MODULES(
LIBTINFOW, LIBTINFOW,
tinfow, tinfow,
@@ -304,6 +309,8 @@ PKG_CHECK_MODULES(
CPPFLAGS="$LIBTINFOW_CFLAGS $SAVED_CPPFLAGS" CPPFLAGS="$LIBTINFOW_CFLAGS $SAVED_CPPFLAGS"
LIBS="$LIBTINFOW_LIBS $LIBS" LIBS="$LIBTINFOW_LIBS $LIBS"
found_ncurses=yes found_ncurses=yes
ncurses_version=`$PKG_CONFIG --modversion tinfow 2>/dev/null`
test "x$ncurses_version" = x && ncurses_version=on
], ],
found_ncurses=no found_ncurses=no
) )
@@ -316,6 +323,8 @@ if test "x$found_ncurses" = xno; then
CPPFLAGS="$LIBTINFO_CFLAGS $SAVED_CPPFLAGS" CPPFLAGS="$LIBTINFO_CFLAGS $SAVED_CPPFLAGS"
LIBS="$LIBTINFO_LIBS $LIBS" LIBS="$LIBTINFO_LIBS $LIBS"
found_ncurses=yes found_ncurses=yes
ncurses_version=`$PKG_CONFIG --modversion tinfo 2>/dev/null`
test "x$ncurses_version" = x && ncurses_version=on
], ],
found_ncurses=no found_ncurses=no
) )
@@ -329,6 +338,8 @@ if test "x$found_ncurses" = xno; then
CPPFLAGS="$LIBNCURSESW_CFLAGS $SAVED_CPPFLAGS" CPPFLAGS="$LIBNCURSESW_CFLAGS $SAVED_CPPFLAGS"
LIBS="$LIBNCURSESW_LIBS $LIBS" LIBS="$LIBNCURSESW_LIBS $LIBS"
found_ncurses=yes found_ncurses=yes
ncurses_version=`$PKG_CONFIG --modversion ncursesw 2>/dev/null`
test "x$ncurses_version" = x && ncurses_version=on
], ],
found_ncurses=no found_ncurses=no
) )
@@ -342,6 +353,8 @@ if test "x$found_ncurses" = xno; then
CPPFLAGS="$LIBNCURSES_CFLAGS $SAVED_CPPFLAGS" CPPFLAGS="$LIBNCURSES_CFLAGS $SAVED_CPPFLAGS"
LIBS="$LIBNCURSES_LIBS $LIBS" LIBS="$LIBNCURSES_LIBS $LIBS"
found_ncurses=yes found_ncurses=yes
ncurses_version=`$PKG_CONFIG --modversion ncurses 2>/dev/null`
test "x$ncurses_version" = x && ncurses_version=on
], ],
found_ncurses=no found_ncurses=no
) )
@@ -350,7 +363,8 @@ if test "x$found_ncurses" = xno; then
AC_SEARCH_LIBS( AC_SEARCH_LIBS(
setupterm, setupterm,
[tinfow tinfo terminfo ncursesw ncurses], [tinfow tinfo terminfo ncursesw ncurses],
found_ncurses=yes, [found_ncurses=yes
ncurses_version=on],
found_ncurses=no found_ncurses=no
) )
if test "x$found_ncurses" = xyes; then if test "x$found_ncurses" = xyes; then
@@ -380,6 +394,7 @@ else
LIBS="$LIBS -lcurses" LIBS="$LIBS -lcurses"
CPPFLAGS="$CPPFLAGS -DHAVE_CURSES_H" CPPFLAGS="$CPPFLAGS -DHAVE_CURSES_H"
AC_DEFINE(HAVE_CURSES_H) AC_DEFINE(HAVE_CURSES_H)
ncurses_version=on
else else
AC_MSG_ERROR("curses not found") AC_MSG_ERROR("curses not found")
fi fi
@@ -390,6 +405,7 @@ AC_CHECK_FUNCS([ \
]) ])
# Look for utempter. # Look for utempter.
utempter_version=off
AC_ARG_ENABLE( AC_ARG_ENABLE(
utempter, utempter,
AS_HELP_STRING(--enable-utempter, use utempter if it is installed) AS_HELP_STRING(--enable-utempter, use utempter if it is installed)
@@ -406,17 +422,34 @@ if test "x$enable_utempter" = xyes; then
fi fi
if test "x$enable_utempter" = xyes; then if test "x$enable_utempter" = xyes; then
AC_DEFINE(HAVE_UTEMPTER) AC_DEFINE(HAVE_UTEMPTER)
utempter_version=on
else else
AC_MSG_ERROR("utempter not found") AC_MSG_ERROR("utempter not found")
fi fi
fi fi
# Look for utf8proc. # Look for utf8proc.
utf8proc_version=off
AC_ARG_ENABLE( AC_ARG_ENABLE(
utf8proc, utf8proc,
AS_HELP_STRING(--enable-utf8proc, use utf8proc if it is installed) AS_HELP_STRING(--enable-utf8proc, use utf8proc if it is installed)
) )
try_utf8proc=no
require_utf8proc=no
if test "x$enable_utf8proc" = xyes; then if test "x$enable_utf8proc" = xyes; then
try_utf8proc=yes
elif test "x$enable_utf8proc" = x; then
case "$host_os" in
*darwin*)
try_utf8proc=yes
require_utf8proc=yes
;;
esac
fi
if test "x$try_utf8proc" = xyes; then
SAVED_AM_CPPFLAGS="$AM_CPPFLAGS"
SAVED_OLD_CPPFLAGS="$CPPFLAGS"
SAVED_LIBS="$LIBS"
PKG_CHECK_MODULES( PKG_CHECK_MODULES(
LIBUTF8PROC, LIBUTF8PROC,
libutf8proc, libutf8proc,
@@ -424,7 +457,10 @@ if test "x$enable_utf8proc" = xyes; then
AM_CPPFLAGS="$LIBUTF8PROC_CFLAGS $AM_CPPFLAGS" AM_CPPFLAGS="$LIBUTF8PROC_CFLAGS $AM_CPPFLAGS"
CPPFLAGS="$LIBUTF8PROC_CFLAGS $SAVED_CPPFLAGS" CPPFLAGS="$LIBUTF8PROC_CFLAGS $SAVED_CPPFLAGS"
LIBS="$LIBUTF8PROC_LIBS $LIBS" LIBS="$LIBUTF8PROC_LIBS $LIBS"
] utf8proc_version=`$PKG_CONFIG --modversion libutf8proc 2>/dev/null`
test "x$utf8proc_version" = x && utf8proc_version=on
],
[:]
) )
AC_CHECK_HEADER(utf8proc.h, enable_utf8proc=yes, enable_utf8proc=no) AC_CHECK_HEADER(utf8proc.h, enable_utf8proc=yes, enable_utf8proc=no)
if test "x$enable_utf8proc" = xyes; then if test "x$enable_utf8proc" = xyes; then
@@ -437,13 +473,23 @@ if test "x$enable_utf8proc" = xyes; then
fi fi
if test "x$enable_utf8proc" = xyes; then if test "x$enable_utf8proc" = xyes; then
AC_DEFINE(HAVE_UTF8PROC) AC_DEFINE(HAVE_UTF8PROC)
test "x$utf8proc_version" = xoff && utf8proc_version=on
else else
AC_MSG_ERROR("utf8proc not found") AM_CPPFLAGS="$SAVED_AM_CPPFLAGS"
CPPFLAGS="$SAVED_OLD_CPPFLAGS"
LIBS="$SAVED_LIBS"
utf8proc_version=off
if test "x$require_utf8proc" = xyes; then
enable_utf8proc=
else
AC_MSG_ERROR("utf8proc not found")
fi
fi fi
fi fi
AM_CONDITIONAL(HAVE_UTF8PROC, [test "x$enable_utf8proc" = xyes]) AM_CONDITIONAL(HAVE_UTF8PROC, [test "x$enable_utf8proc" = xyes])
# Check for systemd support. # Check for systemd support.
systemd_version=off
AC_ARG_ENABLE( AC_ARG_ENABLE(
systemd, systemd,
AS_HELP_STRING(--enable-systemd, enable systemd integration) AS_HELP_STRING(--enable-systemd, enable systemd integration)
@@ -457,6 +503,8 @@ if test x"$enable_systemd" = xyes; then
CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS" CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS"
LIBS="$SYSTEMD_LIBS $LIBS" LIBS="$SYSTEMD_LIBS $LIBS"
found_systemd=yes found_systemd=yes
systemd_version=`$PKG_CONFIG --modversion libsystemd 2>/dev/null`
test "x$systemd_version" = x && systemd_version=on
], ],
found_systemd=no found_systemd=no
) )
@@ -581,11 +629,27 @@ if test "x$found_malloc_trim" = xyes; then
fi fi
# Build against jemalloc if requested. # Build against jemalloc if requested.
jemalloc_version=off
AC_ARG_ENABLE( AC_ARG_ENABLE(
jemalloc, jemalloc,
AS_HELP_STRING(--enable-jemalloc, use jemalloc if it is installed) AS_HELP_STRING(--enable-jemalloc, use jemalloc if it is installed)
) )
try_jemalloc=no
require_jemalloc=no
if test "x$enable_jemalloc" = xyes; then if test "x$enable_jemalloc" = xyes; then
try_jemalloc=yes
elif test "x$enable_jemalloc" = x; then
case "$host_os" in
*darwin*)
try_jemalloc=yes
require_jemalloc=yes
;;
esac
fi
if test "x$try_jemalloc" = xyes; then
SAVED_AM_CPPFLAGS="$AM_CPPFLAGS"
SAVED_OLD_CPPFLAGS="$CPPFLAGS"
SAVED_LIBS="$LIBS"
PKG_CHECK_MODULES( PKG_CHECK_MODULES(
JEMALLOC, JEMALLOC,
jemalloc, jemalloc,
@@ -593,9 +657,26 @@ if test "x$enable_jemalloc" = xyes; then
AM_CPPFLAGS="$JEMALLOC_CFLAGS $AM_CPPFLAGS" AM_CPPFLAGS="$JEMALLOC_CFLAGS $AM_CPPFLAGS"
CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS" CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS"
LIBS="$LIBS $JEMALLOC_LIBS" LIBS="$LIBS $JEMALLOC_LIBS"
jemalloc_version=`$PKG_CONFIG --modversion jemalloc 2>/dev/null`
test "x$jemalloc_version" = x && jemalloc_version=on
], ],
AC_MSG_ERROR("jemalloc not found") enable_jemalloc=no
) )
if test "x$enable_jemalloc" = xno; then
AM_CPPFLAGS="$SAVED_AM_CPPFLAGS"
CPPFLAGS="$SAVED_OLD_CPPFLAGS"
LIBS="$SAVED_LIBS"
jemalloc_version=off
if test "x$require_jemalloc" = xyes; then
enable_jemalloc=
else
AC_MSG_ERROR("jemalloc not found")
fi
else
enable_jemalloc=yes
AC_DEFINE(HAVE_JEMALLOC)
test "x$jemalloc_version" = xoff && jemalloc_version=on
fi
fi fi
# Check for CMSG_DATA. On some platforms like HP-UX this requires UNIX 95 # Check for CMSG_DATA. On some platforms like HP-UX this requires UNIX 95
@@ -942,6 +1023,20 @@ case "$host_os" in
AC_MSG_NOTICE([]) AC_MSG_NOTICE([])
AC_MSG_ERROR([must give --enable-utf8proc or --disable-utf8proc]) AC_MSG_ERROR([must give --enable-utf8proc or --disable-utf8proc])
fi fi
#
# macOS calloc(3) does not appear to always zero memory correctly,
# so complain and suggest using jemalloc instead.
#
if test "x$enable_jemalloc" = x; then
AC_MSG_NOTICE([])
AC_MSG_NOTICE([ macOS calloc(3) appears not to correctly])
AC_MSG_NOTICE([ zero allocations in some circumstances;])
AC_MSG_NOTICE([ to avoid this, configuring with])
AC_MSG_NOTICE([ --enable-jemalloc is recommended. To build])
AC_MSG_NOTICE([ without anyway, use --disable-jemalloc])
AC_MSG_NOTICE([])
AC_MSG_ERROR([must give --enable-jemalloc or --disable-jemalloc])
fi
;; ;;
*dragonfly*) *dragonfly*)
AC_MSG_RESULT(dragonfly) AC_MSG_RESULT(dragonfly)
@@ -1029,6 +1124,26 @@ AC_MSG_CHECKING(lock-command)
AC_MSG_RESULT($DEFAULT_LOCK_CMD) AC_MSG_RESULT($DEFAULT_LOCK_CMD)
AC_SUBST(DEFAULT_LOCK_CMD) AC_SUBST(DEFAULT_LOCK_CMD)
# Print a summary.
AC_MSG_NOTICE([])
if test "x$enable_asan" = xyes; then
AC_MSG_NOTICE([ASAN: on])
else
AC_MSG_NOTICE([ASAN: off])
fi
if test "x$enable_debug" = xyes; then
AC_MSG_NOTICE([debug: on])
else
AC_MSG_NOTICE([debug: off])
fi
AC_MSG_NOTICE([jemalloc: $jemalloc_version])
AC_MSG_NOTICE([libevent: $libevent_version])
AC_MSG_NOTICE([ncurses: $ncurses_version])
AC_MSG_NOTICE([systemd: $systemd_version])
AC_MSG_NOTICE([utempter: $utempter_version])
AC_MSG_NOTICE([utf8proc: $utf8proc_version])
AC_MSG_NOTICE([])
# Save our CFLAGS/CPPFLAGS/LDFLAGS for the Makefile and restore the old user # Save our CFLAGS/CPPFLAGS/LDFLAGS for the Makefile and restore the old user
# variables. # variables.
AC_SUBST(AM_CPPFLAGS) AC_SUBST(AM_CPPFLAGS)

View File

@@ -124,6 +124,9 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
/* Limit on time taken (milliseconds). */ /* Limit on time taken (milliseconds). */
#define FORMAT_TIME_LIMIT 100 #define FORMAT_TIME_LIMIT 100
/* How often to check the time in long loops. */
#define FORMAT_TIME_LOOP_CHECK 10000
/* Format expand flags. */ /* Format expand flags. */
#define FORMAT_EXPAND_TIME 0x1 #define FORMAT_EXPAND_TIME 0x1
#define FORMAT_EXPAND_NOJOBS 0x2 #define FORMAT_EXPAND_NOJOBS 0x2
@@ -4193,10 +4196,14 @@ found:
/* Check if format has not taken too long. */ /* Check if format has not taken too long. */
static int static int
format_check_time(struct format_expand_state *es) format_check_time(struct format_expand_state *es, u_int *check)
{ {
uint64_t t = get_timer(); uint64_t t;
if (check != NULL && ++*check % FORMAT_TIME_LOOP_CHECK != 0)
return (1);
t = get_timer();
if (t - es->start_time < FORMAT_TIME_LIMIT) if (t - es->start_time < FORMAT_TIME_LIMIT)
return (1); return (1);
t -= es->start_time; t -= es->start_time;
@@ -4211,10 +4218,11 @@ format_unescape(struct format_expand_state *es, const char *s)
{ {
char *out, *cp; char *out, *cp;
int brackets = 0; int brackets = 0;
u_int check = 0;
cp = out = xmalloc(strlen(s) + 1); cp = out = xmalloc(strlen(s) + 1);
for (; *s != '\0'; s++) { for (; *s != '\0'; s++) {
if (!format_check_time(es)){ if (!format_check_time(es, &check)) {
free(out); free(out);
return (xstrdup("")); return (xstrdup(""));
} }
@@ -4240,10 +4248,11 @@ format_strip(struct format_expand_state *es, const char *s)
{ {
char *out, *cp; char *out, *cp;
int brackets = 0; int brackets = 0;
u_int check = 0;
cp = out = xmalloc(strlen(s) + 1); cp = out = xmalloc(strlen(s) + 1);
for (; *s != '\0'; s++) { for (; *s != '\0'; s++) {
if (!format_check_time(es)){ if (!format_check_time(es, &check)) {
free(out); free(out);
return (xstrdup("")); return (xstrdup(""));
} }
@@ -4267,9 +4276,10 @@ static const char *
format_skip1(struct format_expand_state *es, const char *s, const char *end) format_skip1(struct format_expand_state *es, const char *s, const char *end)
{ {
int brackets = 0; int brackets = 0;
u_int check = 0;
for (; *s != '\0'; s++) { for (; *s != '\0'; s++) {
if (es != NULL && !format_check_time(es)) if (es != NULL && !format_check_time(es, &check))
return (NULL); return (NULL);
if (*s == '#' && s[1] == '{') if (*s == '#' && s[1] == '{')
brackets++; brackets++;
@@ -5059,7 +5069,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
struct format_modifier *list, *cmp = NULL, *search = NULL; struct format_modifier *list, *cmp = NULL, *search = NULL;
struct format_modifier **sub = NULL, *mexp = NULL, *fm; struct format_modifier **sub = NULL, *mexp = NULL, *fm;
struct format_modifier *bool_op_n = NULL; struct format_modifier *bool_op_n = NULL;
u_int i, count, nsub = 0, nrep; u_int i, count, nsub = 0, nrep, check = 0;
struct format_expand_state next; struct format_expand_state next;
/* Set sorting defaults. */ /* Set sorting defaults. */
@@ -5346,7 +5356,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
else { else {
value = xstrdup(""); value = xstrdup("");
for (i = 0; i < nrep; i++) { for (i = 0; i < nrep; i++) {
if (!format_check_time(es)) { if (!format_check_time(es, &check)) {
free(right); free(right);
free(left); free(left);
free(value); free(value);
@@ -5626,7 +5636,7 @@ format_expand1(struct format_expand_state *es, const char *fmt)
int ch, brackets; int ch, brackets;
char expanded[8192]; char expanded[8192];
if (fmt == NULL || *fmt == '\0' || !format_check_time(es)) if (fmt == NULL || *fmt == '\0' || !format_check_time(es, NULL))
return (xstrdup("")); return (xstrdup(""));
if (es->loop == FORMAT_LOOP_LIMIT) { if (es->loop == FORMAT_LOOP_LIMIT) {

4
grid.c
View File

@@ -1538,7 +1538,7 @@ grid_wrap_position(struct grid *gd, u_int px, u_int py, u_int *wx, u_int *wy)
void void
grid_unwrap_position(struct grid *gd, u_int *px, u_int *py, u_int wx, u_int wy) grid_unwrap_position(struct grid *gd, u_int *px, u_int *py, u_int wx, u_int wy)
{ {
u_int yy, ay = 0; u_int yy, ay = 0, ey = gd->hsize + gd->sy - 1;
for (yy = 0; yy < gd->hsize + gd->sy - 1; yy++) { for (yy = 0; yy < gd->hsize + gd->sy - 1; yy++) {
if (ay == wy) if (ay == wy)
@@ -1552,7 +1552,7 @@ grid_unwrap_position(struct grid *gd, u_int *px, u_int *py, u_int wx, u_int wy)
* until we find the end or the line now containing wx. * until we find the end or the line now containing wx.
*/ */
if (wx == UINT_MAX) { if (wx == UINT_MAX) {
while (gd->linedata[yy].flags & GRID_LINE_WRAPPED) while (yy < ey && gd->linedata[yy].flags & GRID_LINE_WRAPPED)
yy++; yy++;
wx = gd->linedata[yy].cellused; wx = gd->linedata[yy].cellused;
} else { } else {

View File

@@ -1417,6 +1417,7 @@ layout_get_floating_cell(struct cmdq_item *item, struct args *args,
w->last_new_pane_y = oy; w->last_new_pane_y = oy;
} }
window_push_zoom(wp->window, 1, args_has(args, 'Z'));
lcnew = layout_floating_pane(w, sx, sy, ox, oy); lcnew = layout_floating_pane(w, sx, sy, ox, oy);
return (lcnew); return (lcnew);
} }

View File

@@ -110,7 +110,8 @@ popup_free(struct popup_data *pd)
if (pd->job != NULL) if (pd->job != NULL)
job_free(pd->job); job_free(pd->job);
input_free(pd->ictx); if (pd->ictx != NULL)
input_free(pd->ictx);
free(pd->or[0].ranges); free(pd->or[0].ranges);
free(pd->or[1].ranges); free(pd->or[1].ranges);
@@ -278,6 +279,7 @@ popup_check_cb(struct client* c, void *data, u_int px, u_int py, u_int nx)
k++; k++;
} }
} }
r->used = k;
return (r); return (r);
} }

13
proc.c
View File

@@ -31,6 +31,10 @@
#include <ncurses.h> #include <ncurses.h>
#endif #endif
#ifdef HAVE_JEMALLOC
#include <jemalloc/jemalloc.h>
#endif
#include "tmux.h" #include "tmux.h"
struct tmuxproc { struct tmuxproc {
@@ -180,6 +184,10 @@ proc_start(const char *name)
{ {
struct tmuxproc *tp; struct tmuxproc *tp;
struct utsname u; struct utsname u;
#ifdef HAVE_JEMALLOC
const char *version;
size_t size = sizeof version;
#endif
log_open(name); log_open(name);
setproctitle("%s (%s)", name, socket_path); setproctitle("%s (%s)", name, socket_path);
@@ -194,6 +202,11 @@ proc_start(const char *name)
#ifdef HAVE_UTF8PROC #ifdef HAVE_UTF8PROC
log_debug("using utf8proc %s", utf8proc_version()); log_debug("using utf8proc %s", utf8proc_version());
#endif #endif
#ifdef HAVE_JEMALLOC
if (mallctl("version", &version, &size, NULL, 0) != 0)
version = "(unknown version)";
log_debug("using jemalloc %s", version);
#endif
#ifdef NCURSES_VERSION #ifdef NCURSES_VERSION
log_debug("using ncurses %s %06u", NCURSES_VERSION, NCURSES_VERSION_PATCH); log_debug("using ncurses %s %06u", NCURSES_VERSION, NCURSES_VERSION_PATCH);
#endif #endif

View File

@@ -1201,6 +1201,8 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, int px,
for (i = 0; i < r->used; i++) { for (i = 0; i < r->used; i++) {
ri = &r->ranges[i]; ri = &r->ranges[i];
if (ri->nx == 0)
continue;
if (w->sb_pos == PANE_SCROLLBARS_LEFT) { if (w->sb_pos == PANE_SCROLLBARS_LEFT) {
if (wp->xoff > sb_w) if (wp->xoff > sb_w)
lb = wp->xoff - 1 - sb_w; lb = wp->xoff - 1 - sb_w;
@@ -1218,6 +1220,8 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, int px,
rb = wp->xoff + wp->sx + sb_w; rb = wp->xoff + wp->sx + sb_w;
if (rb > (int)w->sx) if (rb > (int)w->sx)
rb = w->sx - 1; rb = w->sx - 1;
if (lb > rb)
continue;
sx = ri->px; sx = ri->px;
ex = sx + ri->nx - 1; ex = sx + ri->nx - 1;

View File

@@ -438,6 +438,7 @@ server_destroy_session(struct session *s)
{ {
struct client *c; struct client *c;
struct session *s_new = NULL, *cs_new = NULL, *use_s; struct session *s_new = NULL, *cs_new = NULL, *use_s;
struct sort_criteria sort_crit = { .order = SORT_NAME };
int detach_on_destroy; int detach_on_destroy;
detach_on_destroy = options_get_number(s->options, "detach-on-destroy"); detach_on_destroy = options_get_number(s->options, "detach-on-destroy");
@@ -446,9 +447,11 @@ server_destroy_session(struct session *s)
else if (detach_on_destroy == 2) else if (detach_on_destroy == 2)
s_new = server_find_session(s, server_newer_detached_session); s_new = server_find_session(s, server_newer_detached_session);
else if (detach_on_destroy == 3) else if (detach_on_destroy == 3)
s_new = session_previous_session(s, NULL); s_new = session_previous_session(s, &sort_crit);
else if (detach_on_destroy == 4) else if (detach_on_destroy == 4)
s_new = session_next_session(s, NULL); s_new = session_next_session(s, &sort_crit);
if (s_new == s)
s_new = NULL;
/* /*
* If no suitable new session was found above, then look for any * If no suitable new session was found above, then look for any

View File

@@ -177,7 +177,7 @@ spawn_window(struct spawn_context *sc, char **cause)
/* Set the name of the new window. */ /* Set the name of the new window. */
if (~sc->flags & SPAWN_RESPAWN) { if (~sc->flags & SPAWN_RESPAWN) {
free(w->name); free(w->name);
if (sc->name == NULL || *sc->name == '\0') if (sc->name == NULL)
w->name = default_window_name(w); w->name = default_window_name(w);
else { else {
w->name = xstrdup(sc->name); w->name = xstrdup(sc->name);

View File

@@ -630,7 +630,7 @@ status_message_redraw(struct client *c)
status_prompt_area(c, &ax, &aw); status_prompt_area(c, &ax, &aw);
ft = format_create_defaults(NULL, c, NULL, NULL, NULL); ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
memcpy(&gc, &grid_default_cell, sizeof gc); style_apply(&gc, s->options, "message-style", ft);
/* /*
* Set #{message} in the format tree. If styles should be ignored in * Set #{message} in the format tree. If styles should be ignored in

View File

@@ -73,6 +73,7 @@ const struct window_mode window_client_mode = {
struct window_client_itemdata { struct window_client_itemdata {
struct client *c; struct client *c;
char *ttyname;
}; };
struct window_client_modedata { struct window_client_modedata {
@@ -110,6 +111,7 @@ static void
window_client_free_item(struct window_client_itemdata *item) window_client_free_item(struct window_client_itemdata *item)
{ {
server_client_unref(item->c); server_client_unref(item->c);
free(item->ttyname);
free(item); free(item);
} }
@@ -137,6 +139,7 @@ window_client_build(void *modedata, struct sort_criteria *sort_crit,
item = window_client_add_item(data); item = window_client_add_item(data);
item->c = l[i]; item->c = l[i];
item->ttyname = xstrdup(l[i]->ttyname);
l[i]->references++; l[i]->references++;
} }
@@ -381,7 +384,7 @@ window_client_key(struct window_mode_entry *wme, struct client *c,
break; break;
case '\r': case '\r':
item = mode_tree_get_current(mtd); item = mode_tree_get_current(mtd);
mode_tree_run_command(c, NULL, data->command, item->c->ttyname); mode_tree_run_command(c, NULL, data->command, item->ttyname);
finished = 1; finished = 1;
break; break;
} }

View File

@@ -254,6 +254,7 @@ window_tree_build_window(struct session *s, struct winlink *wl,
u_int n, i; u_int n, i;
int expanded; int expanded;
struct format_tree *ft; struct format_tree *ft;
uint64_t tag = FORMAT_NONE;
item = window_tree_add_item(data); item = window_tree_add_item(data);
item->type = WINDOW_TREE_WINDOW; item->type = WINDOW_TREE_WINDOW;
@@ -261,7 +262,9 @@ window_tree_build_window(struct session *s, struct winlink *wl,
item->winlink = wl->idx; item->winlink = wl->idx;
item->pane = -1; item->pane = -1;
ft = format_create(NULL, NULL, FORMAT_PANE|wl->window->active->id, 0); if (wl->window != NULL && wl->window->active != NULL)
tag = FORMAT_PANE|wl->window->active->id;
ft = format_create(NULL, NULL, tag, 0);
format_defaults(ft, NULL, s, wl, NULL); format_defaults(ft, NULL, s, wl, NULL);
text = format_expand(ft, data->format); text = format_expand(ft, data->format);
xasprintf(&name, "%u", wl->idx); xasprintf(&name, "%u", wl->idx);
@@ -313,6 +316,7 @@ window_tree_build_session(struct session *s, void *modedata,
u_int n, i, empty; u_int n, i, empty;
int expanded; int expanded;
struct format_tree *ft; struct format_tree *ft;
uint64_t tag = FORMAT_NONE;
item = window_tree_add_item(data); item = window_tree_add_item(data);
item->type = WINDOW_TREE_SESSION; item->type = WINDOW_TREE_SESSION;
@@ -320,7 +324,9 @@ window_tree_build_session(struct session *s, void *modedata,
item->winlink = -1; item->winlink = -1;
item->pane = -1; item->pane = -1;
ft = format_create(NULL, NULL, FORMAT_PANE|wl->window->active->id, 0); if (wl != NULL && wl->window != NULL && wl->window->active != NULL)
tag = FORMAT_PANE|wl->window->active->id;
ft = format_create(NULL, NULL, tag, 0);
format_defaults(ft, NULL, s, NULL, NULL); format_defaults(ft, NULL, s, NULL, NULL);
text = format_expand(ft, data->format); text = format_expand(ft, data->format);
format_free(ft); format_free(ft);

View File

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