There is a small bug with screen's auto-aka feature. To reproduce: 0. use bash or another shell with prompt ending in '$ '. Ensure that the null title command, "k", is included in the shell prompt. Below, ^A means ctrl+a. Press the following key sequence: 1. ^A:shelltitle "$ |foo" 2. ^Ac 3. ^AA bar 4. sleep 2 Expected: 1. Sets the default title for new windows to 'foo' 2. Opens a new window with title 'foo' 3. Overrides the title of the new window to 'bar' 4. Invokes a sleep command in the new window We expect at this point the window's title to turn into 'sleep' for 2 seconds, then return back to 'bar' as requested interactively by the user. However, screen-4.0.3 erroneously resets the title to the session-wide default 'foo'. The attached patch is a proposal for a fix of this issue. Moreover, the special SEARCH|TITLE parsing of window names known from "shelltitle" command is now also applied to - the interactive "title" command, - the "-t" option, and - the "kWINDOWTITLE\" terminal sequence. (The latter can be used in applications like /bin/echo -ne \\033k`pwd|sed 's/.*\///'`\\033\\\\ to programmitically set the title of the current window.) Use the special title "|TITLE" to disable the auto-aka heuristic in a window. address@hidden ------------------------------------------------------------ --- screen-4.0.3.orig/ansi.c 2003-12-05 14:57:05.000000000 +0100 +++ screen-4.0.3/ansi.c 2009-07-23 16:28:38.000000000 +0200 @@ -1557,12 +1557,21 @@ LAY_DISPLAYS(&curr->w_layer, AddStr(curr->w_string)); break; case AKA: - if (curr->w_title == curr->w_akabuf && !*curr->w_string) - break; - ChangeAKA(curr, curr->w_string, strlen(curr->w_string)); - if (!*curr->w_string) - curr->w_autoaka = curr->w_y + 1; + if (*curr->w_string) + { + ChangeAKA(curr, NULL, 0); /* reset current command aka */ + ProcessDefaultAKA(curr, curr->w_string); + ChangeAKA(curr, NULL, 0); + } + else + { + if (curr->w_title == curr->w_akabuf) break; + + ChangeAKA(curr, NULL, 0); + curr->w_autoaka = curr->w_y + 1; + } break; + default: break; } @@ -2191,10 +2200,13 @@ p->w_akachange[i++] = c; } p->w_akachange[i] = 0; - p->w_title = p->w_akachange; - if (p->w_akachange != p->w_akabuf) - if (p->w_akachange[0] == 0 || p->w_akachange[-1] == ':') - p->w_title = p->w_akabuf + strlen(p->w_akabuf) + 1; + if (p->w_title != p->w_akabuf) + { + p->w_title = p->w_akachange; + if (p->w_akachange != p->w_akabuf) + if (p->w_akachange[0] == 0 || p->w_akachange[-1] == ':') + p->w_title = p->w_akabuf + strlen(p->w_akabuf) + 1; + } WindowChanged(p, 't'); WindowChanged((struct win *)0, 'w'); WindowChanged((struct win *)0, 'W'); @@ -2208,6 +2220,8 @@ register int len = strlen(wp->w_akabuf); int y; + if (!len || wp->w_title == wp->w_akabuf) return; + y = (wp->w_autoaka > 0 && wp->w_autoaka <= wp->w_height) ? wp->w_autoaka - 1 : wp->w_y; cols = wp->w_width; try_line: --- screen-4.0.3.orig/doc/screen.1 2003-12-05 14:51:57.000000000 +0100 +++ screen-4.0.3/doc/screen.1 2009-07-23 16:04:11.000000000 +0200 @@ -2885,6 +2885,15 @@ .I screen prompts for one. This command was known as `aka' in previous releases. +.PP +\fIwindowtitle\fP can be in the form \*Q\fIsearch|name\fP\*U +in which case the special heuristic for displaying the currently +running command is enabled. In a window under this heuristic, +subsequent \fIwindowtitle\fP changes only affect the \fIname\fP part +and thus leave the heuristic enabled. Use \fI|name\fP to disable the +heuristic again. +For further details about this heuristic, see the discussion +entitled \*QTITLES (naming windows)\*U. .sp .ne 3 .BI "unsetenv " var --- screen-4.0.3.orig/doc/screen.texinfo 2003-12-05 14:51:46.000000000 +0100 +++ screen-4.0.3/doc/screen.texinfo 2009-07-23 16:10:01.000000000 +0200 @@ -1943,6 +1943,14 @@ (@kbd{C-a A})@* Set the name of the current window to @var{windowtitle}. If no name is specified, screen prompts for one. + address@hidden can be in the form @var{search|name} in which case the +special heuristic for displaying the currently running command is +enabled (@pxref{Dynamic Titles}). In a window under this heuristic, +subsequent @var{windowtitle} changes only affect the @var{name} part and +thus leave the heuristic enabled. Use @var{|name} to disable the +heuristic again. + @end deffn @node Dynamic Titles, Title Prompts, Title Command, Naming Windows @@ -1955,7 +1963,9 @@ the @var{name} ends in a @samp{:} @code{screen} will add what it believes to be the current command running in the window to the end of the specified name (e.g. @var{name:cmd}). Otherwise the current -command name supersedes the shell name while it is running. +command name supersedes the shell name while it is running. In a window +under this heuristic the interactive title command (C-a A) changes only +the @var{name} portion. Here's how it works: you must modify your shell prompt to output a null title-escape-sequence (@key{ESC} k @key{ESC} \) as a part of your prompt. --- screen-4.0.3.orig/extern.h 2003-08-22 14:27:57.000000000 +0200 +++ screen-4.0.3/extern.h 2009-07-23 15:00:27.000000000 +0200 @@ -213,6 +213,8 @@ extern void ApplyAttrColor __P((int, struct mchar *)); extern void SwitchWindow __P((int)); extern int StuffKey __P((int)); +extern void ProcessDefaultAKA __P((struct win *, char *)); + /* termcap.c */ extern int InitTermcap __P((int, int)); --- screen-4.0.3.orig/process.c 2003-09-18 14:53:54.000000000 +0200 +++ screen-4.0.3/process.c 2009-07-29 13:20:48.000000000 +0200 @@ -33,7 +33,6 @@ #include #endif - #include "config.h" /* for solaris 2.1, Unixware (SVR4.2) and possibly others: */ @@ -124,7 +123,9 @@ static void Colonfin __P((char *, int, char *)); static void InputSelect __P((void)); static void InputSetenv __P((char *)); -static void InputAKA __P((void)); +static void SetDefaultAKA __P((char *)); +void ProcessDefaultAKA __P((struct win *, char *)); +static void InputDefaultAKA __P((void)); #ifdef MULTIUSER static int InputSu __P((struct win *, struct acluser **, char *)); static void su_fin __P((char *, int, char *)); @@ -1886,9 +1887,12 @@ break; case RC_TITLE: if (*args == 0) - InputAKA(); + InputDefaultAKA(); else - ChangeAKA(fore, *args, strlen(*args)); + { + SetDefaultAKA(*args); + ChangeAKA(fore, NULL, 0); + } break; case RC_COLON: Input(":", 100, INP_COOKED, Colonfin, NULL); @@ -5046,6 +5050,62 @@ Msg(0, "%s", buf); } +/* Here's briefly how I think the autoaka feature is implemented. + + w_akabuf is the buffer containing the raw title string. + w_title points to the current title. + w_akachange points to the null terminating w_title. + + user title string > |bash > |root: bash + + 1) at shell prompt (triggered in ansi.c by \033k\033\\ sequence) + + w_akabuf > \0bash\0 > \0root:\0 bash\0 + w_title bash\0 root:\0 bash\0 + w_akachange \0 \0 bash\0 + + 2) when executing command (triggered in ansi.c by \n sequence) + + w_akabuf > \0bashvi\0 > \0root:vi\0 bash\0 + w_title vi\0 root:vi\0 bash\0 + w_akachange vi\0 vi\0 bash\0 + +*/ + +static void +SetDefaultAKA(buf) + char *buf; +{ + ProcessDefaultAKA(fore, buf); +} + +void +ProcessDefaultAKA(f, buf) + struct win *f; + char *buf; +{ + char *p; + + if ((p = rindex(buf, '|')) != NULL) + { + if (p == buf) buf++; /* empty lookup, switch autoaka off again */ + strncpy(f->w_akabuf, buf, sizeof(f->w_akabuf)-1); + p = f->w_akabuf + (p - buf); + if (p >= f->w_akabuf) *p = '\0'; + p++; + f->w_title = p; + } + else + { + strncpy(f->w_title, buf, + sizeof(f->w_akabuf) - (f->w_title - f->w_akabuf)); + } + f->w_akabuf[sizeof(f->w_akabuf)-1] = '\0'; + f->w_akachange = f->w_title + strlen(f->w_title); + + f->w_autoaka = f->w_y + 1; +} + static void AKAfin(buf, len, data) char *buf; @@ -5053,12 +5113,14 @@ char *data; /* dummy */ { ASSERT(display); - if (len && fore) - ChangeAKA(fore, buf, strlen(buf)); + if (len && fore) { + SetDefaultAKA(buf); + ChangeAKA(fore, NULL, 0); + } } static void -InputAKA() +InputDefaultAKA() { char *s, *ss; int n;