]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Unity/X11: Handle window titles encoded with COMPOUND_TEXT encoding.
authorVMware, Inc <>
Tue, 29 Mar 2011 18:51:10 +0000 (11:51 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Tue, 29 Mar 2011 18:51:10 +0000 (11:51 -0700)
COMPOUND_TEXT is a string type used to encode characters outside the
ASCII range, and it may be used to encode window titles.  Unity/X11
ignored all such titles, so the host UI assumed there was no title.
Whoops.

This change employs GDK to do the heavy lifting for us.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/services/plugins/unity/unitylib/unityPlatformX11.cc
open-vm-tools/services/plugins/unity/unitylib/unityPlatformX11Window.cc
open-vm-tools/services/plugins/unity/unitylib/unityX11.h

index 62d29482f23b8da4ac8dcfd2011ce3b6d6e9d60b..e62cdf8720e62cf6c0e1925b409dd94834215cdd 100644 (file)
@@ -288,6 +288,8 @@ UnityPlatformInit(UnityWindowTracker *tracker,                            // IN
    INIT_ATOM(WM_STATE);
    INIT_ATOM(WM_TRANSIENT_FOR);
    INIT_ATOM(WM_WINDOW_ROLE);
+   INIT_ATOM(COMPOUND_TEXT);
+   INIT_ATOM(UTF8_STRING);
 
 #  undef INIT_ATOM
 
index bcde1abdeaae7cbc156486957b465250287e6889..1d02e3b2e03e289d5fb8b6e6dcfd9ba664b69189 100644 (file)
@@ -2608,16 +2608,48 @@ UPWindowUpdateTitle(UnityPlatform *up,        // IN
       return;
    }
 
-   if (propertyType != XA_STRING || propertyFormat != 8) {
+   if (bytesRemaining != 0) {
+      Log("Skipping title update for window %#lx.  Title too long.\n",
+          upw->clientWindow);
       return;
    }
 
-   DynBuf_Init(&titleBuf);
-   DynBuf_Append(&titleBuf, valueReturned, itemsReturned);
-   if (!itemsReturned || valueReturned[itemsReturned-1] != '\0') {
-      DynBuf_AppendString(&titleBuf, "");
+   /*
+    * propertyFormat tells us (in bits) the size of each item returned.  Let's
+    * convert that to bytes.  See XGetWindowProperty(3) for details.
+    */
+   size_t bytesRead = itemsReturned * propertyFormat / 8;
+   Glib::ustring newTitle;
+
+   if (bytesRead) {                 // i.e. valueReturned isn't empty
+      if (   propertyType == XA_STRING
+          || propertyType == up->atoms.UTF8_STRING) {
+         /*
+          * Insert() used because NUL termination isn't guaranteed.  (Is that
+          * really the case?  TODO: Look this up.)
+          */
+         newTitle.insert(0, (const char *)valueReturned, bytesRead);
+      } else if (propertyType == up->atoms.COMPOUND_TEXT) {
+         /*
+          * COMPOUND_TEXT strings may contain characters outside the ASCII set.
+          * We'll convert these to something usable (*cough*UTF-8*cough*) via
+          * our trusty good pal, Gdk.
+          */
+         gchar **utf8List = NULL;
+         gint nconverted;
+         nconverted = gdk_text_property_to_utf8_list(
+            gdk_x11_xatom_to_atom(up->atoms.COMPOUND_TEXT), propertyFormat,
+            valueReturned, bytesRead, &utf8List);
+         if (nconverted) {
+            newTitle.assign(utf8List[0]);
+         }
+         g_strfreev(utf8List);
+      }
    }
    XFree(valueReturned);
+
+   DynBuf_Init(&titleBuf);
+   DynBuf_Append(&titleBuf, newTitle.c_str(), newTitle.bytes() + 1);
    Debug("Set title of window %#lx to %s\n",
          upw->clientWindow, (char *)DynBuf_Get(&titleBuf));
    UnityWindowTracker_SetWindowTitle(up->tracker, (UnityWindowId) upw->toplevelWindow,
index 510b39eac3fc6b2dc9e395c42570347e606db063..fb5c76ed4b3d9f05c0ac76c550ccae3b1859e346 100644 (file)
@@ -252,7 +252,9 @@ struct _UnityPlatform {
       WM_PROTOCOLS,
       WM_STATE,
       WM_TRANSIENT_FOR,
-      WM_WINDOW_ROLE;
+      WM_WINDOW_ROLE,
+      COMPOUND_TEXT,
+      UTF8_STRING;
    } atoms;
 
    UnityWindowTracker *tracker;