From: VMware, Inc <> Date: Tue, 29 Mar 2011 18:51:10 +0000 (-0700) Subject: Unity/X11: Handle window titles encoded with COMPOUND_TEXT encoding. X-Git-Tag: 2011.03.28-387002~83 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a336498ba3b384979bcbe548e2731ecf8442165d;p=thirdparty%2Fopen-vm-tools.git Unity/X11: Handle window titles encoded with COMPOUND_TEXT encoding. 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 --- diff --git a/open-vm-tools/services/plugins/unity/unitylib/unityPlatformX11.cc b/open-vm-tools/services/plugins/unity/unitylib/unityPlatformX11.cc index 62d29482f..e62cdf872 100644 --- a/open-vm-tools/services/plugins/unity/unitylib/unityPlatformX11.cc +++ b/open-vm-tools/services/plugins/unity/unitylib/unityPlatformX11.cc @@ -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 diff --git a/open-vm-tools/services/plugins/unity/unitylib/unityPlatformX11Window.cc b/open-vm-tools/services/plugins/unity/unitylib/unityPlatformX11Window.cc index bcde1abde..1d02e3b2e 100644 --- a/open-vm-tools/services/plugins/unity/unitylib/unityPlatformX11Window.cc +++ b/open-vm-tools/services/plugins/unity/unitylib/unityPlatformX11Window.cc @@ -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, diff --git a/open-vm-tools/services/plugins/unity/unitylib/unityX11.h b/open-vm-tools/services/plugins/unity/unitylib/unityX11.h index 510b39eac..fb5c76ed4 100644 --- a/open-vm-tools/services/plugins/unity/unitylib/unityX11.h +++ b/open-vm-tools/services/plugins/unity/unitylib/unityX11.h @@ -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;