changeset 112237:ca0df3b7fb20

Backport bug 7517 fixes from trunk. * coding.h (ENCODE_UTF_8): Remove "Used by ..." comment. * nsfns.m (ns_set_name_iconic): Remove. (ns_get_screen): Don't assign integer to f. (ns_set_name_internal): New function. (Vicon_title_format): Extern declare. (ns_set_name): Call ns_set_name_internal. (x_explicitly_set_name): Remove call to ns_set_name_iconic. (x_implicitly_set_name): Ditto. (x_set_title): Remove commet about EXPLICIT. Call ns_set_name_internal. (ns_set_name_as_filename): Encode name with ENCODE_UTF_8. Always use buffer name for title and buffer filename only for RepresentedFilename. Handle bad UTF-8 in buffer name (Bug#7517).
author Jan D. <jan.h.d@swipnet.se>
date Mon, 03 Jan 2011 22:26:22 +0100
parents 3fd4ea7be3a2
children 4f72b1e43644 fd7837a29da3 98276eb8b0ed
files src/ChangeLog src/coding.h src/nsfns.m
diffstat 3 files changed, 107 insertions(+), 100 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Jan 03 21:32:41 2011 +0200
+++ b/src/ChangeLog	Mon Jan 03 22:26:22 2011 +0100
@@ -1,3 +1,19 @@
+2011-01-03  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* coding.h (ENCODE_UTF_8): Remove "Used by ..." comment.
+
+	* nsfns.m (ns_set_name_iconic): Remove.
+	(ns_get_screen): Don't assign integer to f.
+	(ns_set_name_internal): New function (Bug#7517).
+	(Vicon_title_format): Extern declare.
+	(ns_set_name): Call ns_set_name_internal.
+	(x_explicitly_set_name): Remove call to ns_set_name_iconic.
+	(x_implicitly_set_name): Ditto.
+	(x_set_title): Remove commet about EXPLICIT.  Call ns_set_name_internal.
+	(ns_set_name_as_filename): Encode name with ENCODE_UTF_8.
+	Always use buffer name for title and buffer filename only for
+	RepresentedFilename. Handle bad UTF-8 in buffer name (Bug#7517).
+
 2011-01-03  Eli Zaretskii  <eliz@gnu.org>
 
 	* image.c (png_jmpbuf): Remove definition.
--- a/src/coding.h	Mon Jan 03 21:32:41 2011 +0200
+++ b/src/coding.h	Mon Jan 03 22:26:22 2011 +0100
@@ -686,8 +686,7 @@
    ? code_convert_string_norecord (str, Vlocale_coding_system, 0)	   \
    : str)
 
-/* Used by the gtk menu code.  Note that this encodes utf-8, not
-   utf-8-emacs, so it's not a no-op.  */
+/* Note that this encodes utf-8, not utf-8-emacs, so it's not a no-op.  */
 #define ENCODE_UTF_8(str) code_convert_string_norecord (str, Qutf_8, 1)
 
 /* Extern declarations.  */
--- a/src/nsfns.m	Mon Jan 03 21:32:41 2011 +0200
+++ b/src/nsfns.m	Mon Jan 03 22:26:22 2011 +0100
@@ -81,7 +81,7 @@
 extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
 extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle;
 extern Lisp_Object Qnone;
-extern Lisp_Object Vframe_title_format;
+extern Lisp_Object Vframe_title_format, Vicon_title_format;
 
 Lisp_Object Qbuffered;
 Lisp_Object Qfontsize;
@@ -224,7 +224,8 @@
   else
     {
       struct ns_display_info *dpyinfo = terminal->display_info.ns;
-      f = (dpyinfo->x_focus_frame || dpyinfo->x_highlight_frame);
+      f = dpyinfo->x_focus_frame 
+        ? dpyinfo->x_focus_frame : dpyinfo->x_highlight_frame;
     }
 
   return ((f && FRAME_NS_P (f)) ? [[FRAME_NS_VIEW (f) window] screen]
@@ -468,55 +469,37 @@
         [NSString stringWithUTF8String: SDATA (arg)]];
 }
 
-
 static void
-ns_set_name_iconic (struct frame *f, Lisp_Object name, int explicit)
+ns_set_name_internal (FRAME_PTR f, Lisp_Object name)
 {
+  struct gcpro gcpro1;
+  Lisp_Object encoded_name, encoded_icon_name;
+  NSString *str;
   NSView *view = FRAME_NS_VIEW (f);
-  NSTRACE (ns_set_name_iconic);
-
-  if (ns_in_resize)
-    return;
-
-  /* Make sure that requests from lisp code override requests from
-     Emacs redisplay code.  */
-  if (explicit)
-    {
-      /* If we're switching from explicit to implicit, we had better
-         update the mode lines and thereby update the title.  */
-      if (f->explicit_name && NILP (name))
-        update_mode_lines = 1;
-
-      f->explicit_name = ! NILP (name);
-    }
-  else if (f->explicit_name)
-    name = f->name;
-
-  /* title overrides explicit name */
-  if (! NILP (f->title))
-    name = f->title;
-
-  /* icon_name overrides title and explicit name */
-  if (! NILP (f->icon_name))
-    name = f->icon_name;
-
-  if (NILP (name))
-    name = build_string([ns_app_name UTF8String]);
-  else
-    CHECK_STRING (name);
+
+  GCPRO1 (name);
+  encoded_name = ENCODE_UTF_8 (name);
+  UNGCPRO;
+
+  str = [NSString stringWithUTF8String: SDATA (encoded_name)];
 
   /* Don't change the name if it's already NAME.  */
+  if (! [[[view window] title] isEqualToString: str])
+    [[view window] setTitle: str];
+
+  if (!STRINGP (f->icon_name))
+    encoded_icon_name = encoded_name;
+  else
+    encoded_icon_name = ENCODE_UTF_8 (f->icon_name);    
+
+  str = [NSString stringWithUTF8String: SDATA (encoded_icon_name)];
+
   if ([[view window] miniwindowTitle] &&
-      ([[[view window] miniwindowTitle]
-             isEqualToString: [NSString stringWithUTF8String:
-                                           SDATA (name)]]))
-    return;
-
-  [[view window] setMiniwindowTitle:
-        [NSString stringWithUTF8String: SDATA (name)]];
+      ! [[[view window] miniwindowTitle] isEqualToString: str])
+    [[view window] setMiniwindowTitle: str];
+
 }
 
-
 static void
 ns_set_name (struct frame *f, Lisp_Object name, int explicit)
 {
@@ -542,6 +525,12 @@
 
   if (NILP (name))
     name = build_string([ns_app_name UTF8String]);
+  else
+    CHECK_STRING (name);
+
+  /* Don't change the name if it's already NAME.  */
+  if (! NILP (Fstring_equal (name, f->name)))
+    return;
 
   f->name = name;
 
@@ -549,17 +538,7 @@
   if (! NILP (f->title))
     name = f->title;
 
-  CHECK_STRING (name);
-
-  view = FRAME_NS_VIEW (f);
-
-  /* Don't change the name if it's already NAME.  */
-  if ([[[view window] title]
-            isEqualToString: [NSString stringWithUTF8String:
-                                          SDATA (name)]])
-    return;
-  [[view window] setTitle: [NSString stringWithUTF8String:
-                                        SDATA (name)]];
+  ns_set_name_internal (f, name);
 }
 
 
@@ -570,7 +549,6 @@
 x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
 {
   NSTRACE (x_explicitly_set_name);
-  ns_set_name_iconic (f, arg, 1);
   ns_set_name (f, arg, 1);
 }
 
@@ -582,9 +560,10 @@
 x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
 {
   NSTRACE (x_implicitly_set_name);
-  if (FRAME_ICONIFIED_P (f))
-    ns_set_name_iconic (f, arg, 0);
-  else if (FRAME_NS_P (f) && EQ (Vframe_title_format, Qt))
+
+  /* Deal with NS specific format t.  */
+  if (FRAME_NS_P (f) && ((FRAME_ICONIFIED_P (f) && EQ (Vicon_title_format, Qt))
+                         || EQ (Vframe_title_format, Qt)))
     ns_set_name_as_filename (f);
   else
     ns_set_name (f, arg, 0);
@@ -592,15 +571,8 @@
 
 
 /* Change the title of frame F to NAME.
-   If NAME is nil, use the frame name as the title.
-
-   If EXPLICIT is non-zero, that indicates that lisp code is setting the
-   name; if NAME is a string, set F's name to NAME and set
-   F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
-
-   If EXPLICIT is zero, that indicates that Emacs redisplay code is
-   suggesting a new name, which lisp code should override; if
-   F->explicit_name is set, ignore the new name; otherwise, set it.  */
+   If NAME is nil, use the frame name as the title.  */
+
 static void
 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
 {
@@ -612,6 +584,13 @@
   update_mode_lines = 1;
 
   f->title = name;
+
+  if (NILP (name))
+    name = f->name;
+  else
+    CHECK_STRING (name);
+
+  ns_set_name_internal (f, name);
 }
 
 
@@ -619,10 +598,13 @@
 ns_set_name_as_filename (struct frame *f)
 {
   NSView *view;
-  Lisp_Object name;
+  Lisp_Object name, filename;
   Lisp_Object buf = XWINDOW (f->selected_window)->buffer;
   const char *title;
   NSAutoreleasePool *pool;
+  struct gcpro gcpro1;
+  Lisp_Object encoded_name, encoded_filename;
+  NSString *str;
   NSTRACE (ns_set_name_as_filename);
 
   if (f->explicit_name || ! NILP (f->title) || ns_in_resize)
@@ -630,56 +612,66 @@
 
   BLOCK_INPUT;
   pool = [[NSAutoreleasePool alloc] init];
-  name = XBUFFER (buf)->filename;
-  if (NILP (name) || FRAME_ICONIFIED_P (f)) name =XBUFFER (buf)->name;
-
-  if (FRAME_ICONIFIED_P (f) && !NILP (f->icon_name))
-    name = f->icon_name;
+  filename = XBUFFER (buf)->filename;
+  name = XBUFFER (buf)->name;
 
   if (NILP (name))
-    name = build_string ([ns_app_name UTF8String]);
-  else
-    CHECK_STRING (name);
+    {
+      if (! NILP (filename))
+        name = Ffile_name_nondirectory (filename);
+      else
+        name = build_string ([ns_app_name UTF8String]);
+    }
+
+  GCPRO1 (name);
+  encoded_name = ENCODE_UTF_8 (name);
+  UNGCPRO;
 
   view = FRAME_NS_VIEW (f);
 
   title = FRAME_ICONIFIED_P (f) ? [[[view window] miniwindowTitle] UTF8String]
                                 : [[[view window] title] UTF8String];
 
-  if (title && (! strcmp (title, SDATA (name))))
+  if (title && (! strcmp (title, SDATA (encoded_name))))
     {
       [pool release];
       UNBLOCK_INPUT;
       return;
     }
 
-  if (! FRAME_ICONIFIED_P (f))
+  str = [NSString stringWithUTF8String: SDATA (encoded_name)];
+  if (str == nil) str = @"Bad coding";
+
+  if (FRAME_ICONIFIED_P (f))
+    [[view window] setMiniwindowTitle: str];
+  else 
     {
+      NSString *fstr;
+
+      if (! NILP (filename))
+        {
+          GCPRO1 (filename);
+          encoded_filename = ENCODE_UTF_8 (filename);
+          UNGCPRO;
+
+          fstr = [NSString stringWithUTF8String: SDATA (encoded_filename)];
+          if (fstr == nil) fstr = @"";
 #ifdef NS_IMPL_COCOA
-      /* work around a bug observed on 10.3 where
-         setTitleWithRepresentedFilename does not clear out previous state
-         if given filename does not exist */
-      NSString *str = [NSString stringWithUTF8String: SDATA (name)];
-      if (![[NSFileManager defaultManager] fileExistsAtPath: str])
-        {
-          [[view window] setTitleWithRepresentedFilename: @""];
-          [[view window] setTitle: str];
+          /* work around a bug observed on 10.3 and later where
+             setTitleWithRepresentedFilename does not clear out previous state
+             if given filename does not exist */
+          if (! [[NSFileManager defaultManager] fileExistsAtPath: fstr])
+            [[view window] setRepresentedFilename: @""];
+#endif
         }
       else
-        {
-          [[view window] setTitleWithRepresentedFilename: str];
-        }
-#else
-      [[view window] setTitleWithRepresentedFilename:
-                         [NSString stringWithUTF8String: SDATA (name)]];
-#endif
+        fstr = @"";
+
+      [[view window] setRepresentedFilename: fstr];
+      [[view window] setTitle: str];
       f->name = name;
     }
-  else
-    {
-      [[view window] setMiniwindowTitle:
-            [NSString stringWithUTF8String: SDATA (name)]];
-    }
+
   [pool release];
   UNBLOCK_INPUT;
 }