diff --git a/cmd-attach-session.c b/cmd-attach-session.c index e55f7c46..0dea764f 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-attach-session.c,v 1.35 2009-12-04 22:14:47 tcunha Exp $ */ +/* $Id: cmd-attach-session.c,v 1.36 2010-02-08 18:27:34 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,8 +28,8 @@ int cmd_attach_session_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_attach_session_entry = { "attach-session", "attach", - "[-d] " CMD_TARGET_SESSION_USAGE, - CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, "d", + "[-dr] " CMD_TARGET_SESSION_USAGE, + CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, "dr", cmd_target_init, cmd_target_parse, cmd_attach_session_exec, @@ -89,6 +89,9 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx) return (-1); } + if (cmd_check_flag(data->chflags, 'r')) + ctx->cmdclient->flags |= CLIENT_READONLY; + if (cmd_check_flag(data->chflags, 'd')) server_write_session(s, MSG_DETACH, NULL, 0); diff --git a/cmd-detach-client.c b/cmd-detach-client.c index 13f00d67..774179b7 100644 --- a/cmd-detach-client.c +++ b/cmd-detach-client.c @@ -1,4 +1,4 @@ -/* $Id: cmd-detach-client.c,v 1.10 2009-11-14 17:56:39 tcunha Exp $ */ +/* $Id: cmd-detach-client.c,v 1.11 2010-02-08 18:27:34 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -29,7 +29,7 @@ int cmd_detach_client_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_detach_client_entry = { "detach-client", "detach", CMD_TARGET_CLIENT_USAGE, - 0, "", + CMD_READONLY, "", cmd_target_init, cmd_target_parse, cmd_detach_client_exec, diff --git a/key-bindings.c b/key-bindings.c index 3af974f8..1c6d9112 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,4 +1,4 @@ -/* $Id: key-bindings.c,v 1.87 2009-12-10 16:59:02 tcunha Exp $ */ +/* $Id: key-bindings.c,v 1.88 2010-02-08 18:27:34 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -239,7 +239,9 @@ key_bindings_info(struct cmd_ctx *ctx, const char *fmt, ...) void key_bindings_dispatch(struct key_binding *bd, struct client *c) { - struct cmd_ctx ctx; + struct cmd_ctx ctx; + struct cmd *cmd; + int readonly; ctx.msgdata = NULL; ctx.curclient = c; @@ -250,5 +252,15 @@ key_bindings_dispatch(struct key_binding *bd, struct client *c) ctx.cmdclient = NULL; + readonly = 1; + TAILQ_FOREACH(cmd, bd->cmdlist, qentry) { + if (!(cmd->entry->flags & CMD_READONLY)) + readonly = 0; + } + if (!readonly && c->flags & CLIENT_READONLY) { + key_bindings_info(&ctx, "Client is read-only"); + return; + } + cmd_list_exec(bd->cmdlist, &ctx); } diff --git a/server-client.c b/server-client.c index ff633d0b..9d49e0f6 100644 --- a/server-client.c +++ b/server-client.c @@ -1,4 +1,4 @@ -/* $Id: server-client.c,v 1.30 2010-02-08 18:25:04 tcunha Exp $ */ +/* $Id: server-client.c,v 1.31 2010-02-08 18:27:34 tcunha Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -270,6 +270,8 @@ server_client_handle_key(int key, struct mouse_event *mouse, void *data) /* Special case: number keys jump to pane in identify mode. */ if (c->flags & CLIENT_IDENTIFY && key >= '0' && key <= '9') { + if (c->flags & CLIENT_READONLY) + return; wp = window_pane_at_index(w, key - '0'); if (wp != NULL && window_pane_visible(wp)) window_set_active_pane(w, wp); @@ -278,15 +280,20 @@ server_client_handle_key(int key, struct mouse_event *mouse, void *data) } /* Handle status line. */ - status_message_clear(c); - server_clear_identify(c); + if (!(c->flags & CLIENT_READONLY)) { + status_message_clear(c); + server_clear_identify(c); + } if (c->prompt_string != NULL) { - status_prompt_key(c, key); + if (!(c->flags & CLIENT_READONLY)) + status_prompt_key(c, key); return; } /* Check for mouse keys. */ if (key == KEYC_MOUSE) { + if (c->flags & CLIENT_READONLY) + return; if (options_get_number(oo, "mouse-select-pane")) { window_set_active_at(w, mouse->x, mouse->y); server_redraw_window_borders(w); @@ -312,9 +319,10 @@ server_client_handle_key(int key, struct mouse_event *mouse, void *data) c->flags |= CLIENT_PREFIX; else { /* Try as a non-prefix key binding. */ - if ((bd = key_bindings_lookup(key)) == NULL) - window_pane_key(wp, c, key); - else + if ((bd = key_bindings_lookup(key)) == NULL) { + if (!(c->flags & CLIENT_READONLY)) + window_pane_key(wp, c, key); + } else key_bindings_dispatch(bd, c); } return; @@ -328,7 +336,7 @@ server_client_handle_key(int key, struct mouse_event *mouse, void *data) c->flags &= ~CLIENT_REPEAT; if (isprefix) c->flags |= CLIENT_PREFIX; - else + else if (!(c->flags & CLIENT_READONLY)) window_pane_key(wp, c, key); } return; @@ -339,7 +347,7 @@ server_client_handle_key(int key, struct mouse_event *mouse, void *data) c->flags &= ~CLIENT_REPEAT; if (isprefix) c->flags |= CLIENT_PREFIX; - else + else if (!(c->flags & CLIENT_READONLY)) window_pane_key(wp, c, key); return; } @@ -659,7 +667,6 @@ server_client_msg_command(struct client *c, struct msg_command_data *data) { struct cmd_ctx ctx; struct cmd_list *cmdlist = NULL; - struct cmd *cmd; int argc; char **argv, *cause; diff --git a/tmux.1 b/tmux.1 index 02f89b5e..7e5270e7 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $Id: tmux.1,v 1.229 2010-02-08 18:13:17 tcunha Exp $ +.\" $Id: tmux.1,v 1.230 2010-02-08 18:27:34 tcunha Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -364,7 +364,7 @@ new-window ; split-window -d The following commands are available: .Bl -tag -width Ds .It Xo Ic attach-session -.Op Fl d +.Op Fl dr .Op Fl t Ar target-session .Xc .D1 (alias: Ic attach ) @@ -376,6 +376,10 @@ If used from inside, switch the current client. If .Fl d is specified, any other clients attached to the session are detached. +.Fl r +signifies the client is read-only (only keys bound to the +.Ic detach-client +command have any effect) .Pp If no server is started, .Ic attach-session diff --git a/tmux.h b/tmux.h index c1eaa0d7..4681e076 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.542 2010-02-08 18:13:17 tcunha Exp $ */ +/* $Id: tmux.h,v 1.543 2010-02-08 18:27:34 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1093,6 +1093,7 @@ struct client { #define CLIENT_IDENTIFY 0x100 #define CLIENT_DEAD 0x200 #define CLIENT_BORDERS 0x400 +#define CLIENT_READONLY 0x800 int flags; struct event identify_timer; @@ -1171,6 +1172,7 @@ struct cmd_entry { #define CMD_ARG01 0x10 #define CMD_ARG2 0x20 #define CMD_ARG12 0x40 +#define CMD_READONLY 0x80 int flags; const char *chflags;