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()
atoms = conn.core.ListProperties(win_id).reply().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
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()}
type_atom_cache = {}
def get_property_value(property_reply):
if property_reply.format == 8:
if 0 in property_reply.value[:-1]:
ret = []
s = []
for o in property_reply.value:
if o == 0:
ret.append(''.join(s))
s = []
else:
s.append(chr(o))
else:
ret = str(property_reply.value.buf())
if len(property_reply.value) > 0 and 0 == property_reply.value[-1]:
ret = ret[:-1]
return ret
is_list_of_strings = 0 in property_reply.value[:-1]
ans = bytes(property_reply.value.buf())
if property_reply.type not in type_atom_cache:
type_atom_cache[property_reply.type] = bytes(conn.core.GetAtomNameUnchecked(property_reply.type).reply().name.buf())
if type_atom_cache[property_reply.type] == b'UTF8_STRING':
ans = ans.decode('utf-8')
if is_list_of_strings:
ans = ans.split('\0')
return ans
elif property_reply.format in (16, 32):
return list(struct.unpack(b'I' * property_reply.value_len,
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
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
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():
atom = conn.core.InternAtom(False, len(name), name).reply().atom
conn.core.ChangePropertyChecked(xcb.xproto.PropMode.Replace, win_id, atom, xcb.xproto.Atom.STRING, 8, len(val), val)
atom = atoms[name].reply().atom
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.disconnect()