xpra icon
Bug tracker and wiki

Ticket #826: debug-window-title-v3.patch

File debug-window-title-v3.patch, 5.9 KB (added by Antoine Martin, 5 years ago)

allows us to try many different ways of setting the title

  • xpra/client/client_window_base.py

     
    1818workspacelog = Logger("workspace")
    1919metalog = Logger("metadata")
    2020
     21#ugly workaround for buggy gtk set_title:
     22try:
     23    import ctypes
     24    from ctypes.wintypes import BOOL, HANDLE, LPCSTR, LPWSTR, LPCWSTR, UINT, DWORD
     25    kernel32 = ctypes.windll.kernel32
     26    user32 = ctypes.windll.user32
     27    IsWindowUnicode = user32.IsWindowUnicode
     28    IsWindowUnicode.restype = BOOL
     29    IsWindowUnicode.argtypes = [HANDLE]
     30    SetWindowTextW = user32.SetWindowTextW
     31    SetWindowTextW.restype = BOOL
     32    SetWindowTextW.argtypes = [HANDLE, LPCWSTR]
     33    MultiByteToWideChar = kernel32.MultiByteToWideChar
     34    MultiByteToWideChar.argtypes = [UINT, DWORD,
     35                                    LPCSTR, ctypes.c_int,
     36                                    LPWSTR, ctypes.c_int]
     37    MultiByteToWideChar.restype = ctypes.c_int
     38except:
     39    SetWindowTextW, IsWindowUnicode = None, None
    2140
     41
    2242class ClientWindowBase(ClientWidgetBase):
    2343
    2444    def __init__(self, client, group_leader, wid, x, y, w, h, metadata, override_redirect, client_properties, border, max_window_size):
     
    146166        metalog("set_metadata(%s)", metadata)
    147167        if b"title" in metadata:
    148168            try:
     169                metalog("title update, title string=%s", self._client.title)
    149170                title = bytestostr(self._client.title).replace("\0", "")
     171                metalog("cleaned up title string=%s", title)
    150172                if title.find("@")>=0:
    151173                    #perform metadata variable substitutions:
    152174                    #full of py3k unicode headaches that don't need to be
    153175                    default_values = {"title"           : "<untitled window>",
    154176                                      "client-machine"  : "<unknown machine>"}
     177                    import binascii
    155178                    def metadata_replace(match):
    156179                        atvar = match.group(0)          #ie: '@title@'
     180                        metalog("metadata_replace atvar=%s", atvar)
    157181                        var = atvar[1:len(atvar)-1]     #ie: 'title'
     182                        metalog("metadata_replace var=%s", var)
    158183                        default_value = default_values.get(var, "<unknown %s>" % var)
     184                        metalog("metadata_replace default_value=%s", default_value)
    159185                        value = self._metadata.strget(var, default_value)
     186                        metalog("metadata_replace str value=%s", value)
     187                        value = self._metadata.get(var, default_value)
     188                        metalog("metadata_replace type(%s)=%s", value, type(value))
     189                        metalog("metadata_replace value=%s", binascii.hexlify(value))
     190                        metalog("metadata_replace value=%s", value)
    160191                        if sys.version<'3':
    161192                            value = value.decode("utf-8")
     193                        metalog("metadata_replace=%s", value)
    162194                        return value
    163195                    title = re.sub("@[\w\-]*@", metadata_replace, title)
     196                    metalog("title after substitution=%s", title)
    164197                    if sys.version<'3':
    165198                        utf8_title = title.encode("utf-8")
    166199                    else:
    167200                        utf8_title = title
     201                    metalog("utf8_title=%s", utf8_title)
     202                    metalog("title after substitution=%s", type(utf8_title))
     203                    metalog("title after substitution=%s", binascii.hexlify(utf8_title))
    168204            except Exception as e:
    169205                log.error("error parsing window title: %s", e)
    170206                utf8_title = b""
    171             self.set_title(utf8_title)
     207            try:
     208                import win32gui, win32con, os
     209                handle = self.get_window().handle
     210                WM_TEXT_ENCODING = os.environ.get("WM_TEXT_ENCODING", "utf-16")
     211                #title = u"â ậ ấ ầ ẩ"
     212                v = title.encode(WM_TEXT_ENCODING)
     213                metalog("setting title=%s on %#x with encoding=%s : %s", title, handle, WM_TEXT_ENCODING, binascii.hexlify(v))
     214                method = int(os.environ.get("SET_TITLE_METHOD", "0"))
     215                if method==0:
     216                    metalog("using %s", win32gui.SendMessage)
     217                    win32gui.SendMessage(handle, win32con.WM_SETTEXT, None, v)
     218                elif method==1:
     219                    metalog("using %s", win32gui.SetWindowText)
     220                    win32gui.SetWindowText(handle, v)
     221                elif method==2:
     222                    from ctypes import windll, c_wchar_p
     223                    wt = c_wchar_p(v)
     224                    metalog("using %s(%s)", windll.user32.SetWindowTextW, wt)
     225                    windll.user32.SetWindowTextW(handle, wt)
     226                elif method==3:
     227                    metalog("user32.IsWindowUnicode=%s", IsWindowUnicode(handle))
     228                    metalog("user32.SetWindowTextW=%s, hwnd=%s", SetWindowTextW, handle)
     229                    CP_UTF8 = 65001
     230                    utf8_title = title.encode("utf-8")
     231                    self.title_wide = ctypes.create_unicode_buffer(len(title)*4)
     232                    ret = MultiByteToWideChar(CP_UTF8, 0, utf8_title, len(utf8_title), self.title_wide, len(self.title_wide))
     233                    metalog("ret=%s, title_wide=%s", ret, self.title_wide)
     234                    metalog("using %s(%s)", SetWindowTextW, self.title_wide)
     235                    SetWindowTextW(handle, self.title_wide)
     236                else:
     237                    assert False, "invalid method: %s" % method
     238            except Exception as e:
     239                metalog("failed using native code", exc_info=True)
     240                metalog("using %s", self.set_title)
     241                self.set_title(utf8_title)
    172242
    173243        if b"icon-title" in metadata:
    174244            icon_title = metadata.strget("icon-title")