Properly support UTF8_STRING atoms

This commit is contained in:
Kovid Goyal 2014-10-31 16:27:15 +05:30
parent 8dab918f98
commit bf6165ebd2
2 changed files with 23 additions and 18 deletions

View File

@ -208,28 +208,24 @@ class MyApplication(Gtk.Application):
conn = xcb.Connection() conn = xcb.Connection()
atoms = conn.core.ListProperties(win_id).reply().atoms atoms = conn.core.ListProperties(win_id).reply().atoms
atom_names = {atom:conn.core.GetAtomNameUnchecked(atom) for atom in atoms} atom_names = {atom:conn.core.GetAtomNameUnchecked(atom) for atom in atoms}
atom_names = {k:str(a.reply().name.buf()) for k, a in atom_names.iteritems()} atom_names = {k:bytes(a.reply().name.buf()) for k, a in atom_names.iteritems()}
property_names = {name:atom for atom, name in atom_names.iteritems() if property_names = {name:atom for atom, name in atom_names.iteritems() if
name.startswith('_GTK') or name.startswith('_UNITY') or name.startswith('_GNOME')} name.startswith('_GTK') or name.startswith('_UNITY') or name.startswith('_GNOME')}
replies = {name:conn.core.GetProperty(False, win_id, atom, xcb.xproto.GetPropertyType.Any, 0, 2 ** 32 - 1) for name, atom in property_names.iteritems()} replies = {name:conn.core.GetProperty(False, win_id, atom, xcb.xproto.GetPropertyType.Any, 0, 2 ** 32 - 1) for name, atom in property_names.iteritems()}
type_atom_cache = {}
def get_property_value(property_reply): def get_property_value(property_reply):
if property_reply.format == 8: if property_reply.format == 8:
if 0 in property_reply.value[:-1]: is_list_of_strings = 0 in property_reply.value[:-1]
ret = [] ans = bytes(property_reply.value.buf())
s = [] if property_reply.type not in type_atom_cache:
for o in property_reply.value: type_atom_cache[property_reply.type] = bytes(conn.core.GetAtomNameUnchecked(property_reply.type).reply().name.buf())
if o == 0: if type_atom_cache[property_reply.type] == b'UTF8_STRING':
ret.append(''.join(s)) ans = ans.decode('utf-8')
s = [] if is_list_of_strings:
else: ans = ans.split('\0')
s.append(chr(o)) return ans
else:
ret = str(property_reply.value.buf())
if len(property_reply.value) > 0 and 0 == property_reply.value[-1]:
ret = ret[:-1]
return ret
elif property_reply.format in (16, 32): elif property_reply.format in (16, 32):
return list(struct.unpack(b'I' * property_reply.value_len, return list(struct.unpack(b'I' * property_reply.value_len,
property_reply.value.buf())) property_reply.value.buf()))

View File

@ -129,10 +129,19 @@ def setup_for_cli_run():
signal.signal(signal.SIGINT, signal.SIG_DFL) # quit on Ctrl-C signal.signal(signal.SIGINT, signal.SIG_DFL) # quit on Ctrl-C
def set_X_window_properties(win_id, **properties): def set_X_window_properties(win_id, **properties):
' Set X Window properties on the window with the specified id. Only string values are supported. '
import xcb, xcb.xproto import xcb, xcb.xproto
conn = xcb.connect() conn = xcb.connect()
atoms = {name:conn.core.InternAtom(False, len(name), name) for name in properties}
utf8_string_atom = None
for name, val in properties.iteritems(): for name, val in properties.iteritems():
atom = conn.core.InternAtom(False, len(name), name).reply().atom atom = atoms[name].reply().atom
conn.core.ChangePropertyChecked(xcb.xproto.PropMode.Replace, win_id, atom, xcb.xproto.Atom.STRING, 8, len(val), val) type_atom = xcb.xproto.Atom.STRING
if isinstance(val, unicode):
if utf8_string_atom is None:
utf8_string_atom = conn.core.InternAtom(True, len(b'UTF8_STRING'), b'UTF8_STRING').reply().atom
type_atom = utf8_string_atom
val = val.encode('utf-8')
conn.core.ChangePropertyChecked(xcb.xproto.PropMode.Replace, win_id, atom, type_atom, 8, len(val), val)
conn.flush() conn.flush()
conn.disconnect() conn.disconnect()