emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: suggested feature -- console-mode frame title sets Xterm title


From: Martin Pool
Subject: Re: suggested feature -- console-mode frame title sets Xterm title
Date: Fri, 26 Sep 2003 15:04:23 +1000
User-agent: Pan/0.14.2 (This is not a psychotic episode. It's a cleansing moment of clarity. (Debian GNU/Linux))

On Sat, 15 Jun 2002 15:47:30 -0600, Richard Stallman wrote:

>     the user so requests) send those sorts of characters, thus updating
>     Putty, or the xterm it's running under, or whatever, in the same
>     situations in which it would modify its frame title if it were running
>     under X.
> 
> It seems worth a try.  I suggest doing it when the mode line is updated.

I thought I would try this.

Updating the title can be done pretty easily from lisp by sending the
right characters directly to the terminal.  Noah S. Friedman has an
example of how to do it here:

  http://www.splode.com/~friedman/software/emacs-lisp/src/xterm-frobs.el

Noah's code, like most of the xterm-handling code in emacs, uses
hardcoded escape sequences.  I think they ought to be taken from the
fs/ds/es fields in the termcap database, but for some reason the
normal 'xterm' terminal definition doesn't seem to have them.  If we
relied on using termcap to get the right control codes then users
would have to patch their termcap to get it to work.

It looks like the title update is done purely in C and not visible to
Lisp; there doesn't seem to be a hook that's run at any relevant time.
Also it looks like the code that expands the format string is not
accessible to Lisp.  I suppose this makes sense since the
window-system title must be set by C code.

I can see where the title is built up into a buffer in
x_consider_frame_title.  At the moment that code is only compiled when
we're built for a window system.  That assumption needs to come out.

In addition, the function only acts on frames that have
windowing-system windows.  This too needs to change so we consider
frames which either have windows or which are FRAME_TERMCAP_P().  

I'm not sure how this will interact with creation of multiple frames
on a terminal, if anyone uses that.

Anyhow, here is a patch against 21.3.  It seems to work for me in
quick tests in three domains:

 - in a terminal, built --without-x

 - in a terminal, built --with-x

 - on x

Comments would be very welcome.  I would like it if something like
this could eventually be merged.

Regards,
-- 
Martin



--- /home/mbp/work/emacs/emacs-21.3/src/xdisp.c.~1~     2003-01-18 
00:45:13.000000000 +1100
+++ /home/mbp/work/emacs/emacs-21.3/src/xdisp.c 2003-09-26 15:02:16.000000000 
+1000
@@ -7142,7 +7142,6 @@ echo_area_display (update_frame_p)
  ***********************************************************************/
 
 
-#ifdef HAVE_WINDOW_SYSTEM
 
 /* A buffer for constructing frame titles in it; allocated from the
    heap in init_xdisp and resized as needed in store_frame_title_char.  */
@@ -7211,6 +7210,8 @@ store_frame_title (str, field_width, pre
 }
 
 
+const char *xterm_title_start = "\033]2;", *xterm_title_end = "\007";
+
 /* Set the title of FRAME, if it has changed.  The title format is
    Vicon_title_format if FRAME is iconified, otherwise it is
    frame_title_format.  */
@@ -7222,6 +7223,7 @@ x_consider_frame_title (frame)
   struct frame *f = XFRAME (frame);
 
   if (FRAME_WINDOW_P (f)
+      || FRAME_TERMCAP_P (f)
       || FRAME_MINIBUF_ONLY_P (f)
       || f->explicit_name)
     {
@@ -7260,24 +7262,32 @@ x_consider_frame_title (frame)
       frame_title_ptr = NULL;
       set_buffer_internal (obuf);
 
+#ifdef HAVE_WINDOW_SYSTEM
       /* Set the title only if it's changed.  This avoids consing in
         the common case where it hasn't.  (If it turns out that we've
         already wasted too much time by walking through the list with
         display_mode_element, then we might need to optimize at a
         higher level than this.)  */
-      if (! STRINGP (f->name) 
-         || STRING_BYTES (XSTRING (f->name)) != len
-         || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
-       x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
+
+      /* Even if we're compiled with a window system, we might not be
+         using it for this frame... */
+      if (FRAME_WINDOW_P (f)) 
+        if (! STRINGP (f->name) 
+            || STRING_BYTES (XSTRING (f->name)) != len
+            || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
+          x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
+#endif
+      
+      if (FRAME_TERMCAP_P (f))
+        {
+          fwrite (xterm_title_start, 1, strlen (xterm_title_start), stdout);
+          fwrite (frame_title_buf, 1, len, stdout);
+          fwrite (xterm_title_end, 1, strlen (xterm_title_end), stdout);
+          fflush (stdout);
+        }
     }
 }
 
-#else /* not HAVE_WINDOW_SYSTEM */
-
-#define frame_title_ptr ((char *)0)
-#define store_frame_title(str, mincol, maxcol) 0
-
-#endif /* not HAVE_WINDOW_SYSTEM */
 
 
 
@@ -7307,7 +7317,6 @@ prepare_menu_bars ()
   /* Update all frame titles based on their buffer names, etc.  We do
      this before the menu bars so that the buffer-menu will show the
      up-to-date frame titles.  */
-#ifdef HAVE_WINDOW_SYSTEM
   if (windows_or_buffers_changed || update_mode_lines)
     {
       Lisp_Object tail, frame;
@@ -7320,7 +7329,6 @@ prepare_menu_bars ()
            x_consider_frame_title (frame);
        }
     }
-#endif /* HAVE_WINDOW_SYSTEM */
 
   /* Update the menu bar item lists, if appropriate.  This has to be
      done before any actual redisplay or generation of display lines.  */
@@ -15120,7 +15128,6 @@ init_xdisp ()
        default_invis_vector[i] = make_number ('.');
     }
 
-#ifdef HAVE_WINDOW_SYSTEM
   {
     /* Allocate the buffer for frame titles.  */
     int size = 100;
@@ -15128,7 +15135,6 @@ init_xdisp ()
     frame_title_buf_end = frame_title_buf + size;
     frame_title_ptr = NULL;
   }
-#endif /* HAVE_WINDOW_SYSTEM */
   
   help_echo_showing_p = 0;
 }






reply via email to

[Prev in Thread] Current Thread [Next in Thread]