-/* $OpenBSD: options-table.c,v 1.177 2024/08/21 04:37:42 nicm Exp $ */
+/* $OpenBSD: options-table.c,v 1.178 2024/09/16 20:28:22 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
.text = "Maximum number of server messages to keep."
},
+ { .name = "prefix-timeout",
+ .type = OPTIONS_TABLE_NUMBER,
+ .scope = OPTIONS_TABLE_SERVER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 0,
+ .unit = "milliseconds",
+ .text = "The timeout for the prefix key if no subsequent key is "
+ "pressed. Zero means disabled."
+ },
+
{ .name = "prompt-history-limit",
.type = OPTIONS_TABLE_NUMBER,
.scope = OPTIONS_TABLE_SERVER,
-/* $OpenBSD: server-client.c,v 1.408 2024/09/11 19:12:33 nicm Exp $ */
+/* $OpenBSD: server-client.c,v 1.409 2024/09/16 20:28:22 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
key_bindings_unref_table(c->keytable);
c->keytable = key_bindings_get_table(name, 1);
c->keytable->references++;
+ if (gettimeofday(&c->keytable->activity_time, NULL) != 0)
+ fatal("gettimeofday failed");
+}
+
+static uint64_t
+server_client_key_table_activity_diff(struct client *c)
+{
+ struct timeval diff;
+
+ timersub(&c->activity_time, &c->keytable->activity_time, &diff);
+ return ((diff.tv_sec * 1000ULL) + (diff.tv_usec / 1000ULL));
}
/* Get default key table. */
struct key_table *table, *first;
struct key_binding *bd;
int xtimeout;
- uint64_t flags;
+ uint64_t flags, prefix_delay;
struct cmd_find_state fs;
key_code key0, prefix, prefix2;
if (c->flags & CLIENT_REPEAT)
log_debug("currently repeating");
- /* Try to see if there is a key binding in the current table. */
bd = key_bindings_get(table, key0);
+
+ /*
+ * If prefix-timeout is enabled and we're in the prefix table, see if
+ * the timeout has been exceeded. Revert to the root table if so.
+ */
+ prefix_delay = options_get_number(global_options, "prefix-timeout");
+ if (prefix_delay > 0 &&
+ strcmp(table->name, "prefix") == 0 &&
+ server_client_key_table_activity_diff(c) > prefix_delay) {
+ /*
+ * If repeating is active and this is a repeating binding,
+ * ignore the timeout.
+ */
+ if (bd != NULL &&
+ (c->flags & CLIENT_REPEAT) &&
+ (bd->flags & KEY_BINDING_REPEAT)) {
+ log_debug("prefix timeout ignored, repeat is active");
+ } else {
+ log_debug("prefix timeout exceeded");
+ server_client_set_key_table(c, NULL);
+ first = table = c->keytable;
+ server_status_client(c);
+ goto table_changed;
+ }
+ }
+
+ /* Try to see if there is a key binding in the current table. */
if (bd != NULL) {
/*
* Key was matched in this table. If currently repeating but a
-.\" $OpenBSD: tmux.1,v 1.954 2024/08/27 07:49:07 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.955 2024/09/16 20:28:22 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 27 2024 $
+.Dd $Mdocdate: September 16 2024 $
.Dt TMUX 1
.Os
.Sh NAME
.Ic prefix2
can be set to
.Ql None .
+.It Ic prefix-timeout Ar time
+Set the time in milliseconds for which
+.Nm
+waits after
+.Ic prefix
+is input before dismissing it.
+Can be set to zero to disable any timeout.
.It Xo Ic renumber-windows
.Op Ic on | off
.Xc