1# -*- coding: utf-8 -*- 2# This file is part of Xpra. 3# Copyright (C) 2015-2019 Antoine Martin <antoine@xpra.org> 4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any 5# later version. See the file COPYING for details. 6 7from xpra.log import Logger 8from xpra.os_util import strtobytes 9from xpra.gtk_common.error import xsync 10from xpra.x11.gtk_x11.prop import prop_get, get_python_type 11from xpra.x11.bindings.window_bindings import X11WindowBindings #@UnresolvedImport 12 13window_bindings = X11WindowBindings() 14log = Logger("x11", "filters") 15 16 17def get_x11_window_value(prop, window): 18 try: 19 with xsync: 20 xid = window.get_xid() 21 x11type = window_bindings.GetWindowPropertyType(xid, prop)[0] 22 except Exception: 23 log("get_x11_window_value(%s, %s)", prop, window, exc_info=True) 24 x11type = None 25 if x11type: 26 ptype = get_python_type(x11type) 27 #log("%s: %s (%s)", filter_object.property_name, x11type, ptype) 28 assert ptype, "type '%s' is not handled!" % x11type 29 v = prop_get(window, prop, ptype) 30 log("prop_get(%s, %s, %s)=%s", window, prop, ptype, v) 31 if v and isinstance(v, str): 32 v = strtobytes(v).replace("\0", "") 33 else: 34 v = None 35 log("%s=%s (type=%s)", prop, v, x11type) 36 return v 37 38def get_window_value(filter_object, gdkwin): 39 return get_x11_window_value(filter_object.property_name, gdkwin) 40 41def get_window(filter_object, window): 42 gdkwin = window.get_property("client-window") 43 p = gdkwin 44 log("get_window%s gdkwin=%s, recurse=%s", (filter_object, window), gdkwin, filter_object.recurse) 45 while filter_object.recurse and p: 46 gdkwin = p 47 p = None 48 try: 49 prop = "WM_TRANSIENT_FOR" 50 p = prop_get(gdkwin, prop, "window", ignore_errors=True) 51 log("prop_get(%s, %s)=%s", gdkwin, prop, p) 52 except Exception: 53 log("prop_get(%s, %s)", gdkwin, prop, exc_info=True) 54 break 55 return gdkwin 56 57def init_x11_window_filters(): 58 from xpra.server.window import filters 59 original_get_window_filter = filters.get_window_filter 60 61 def get_x11_window_filter(object_name, property_name, operator, value): 62 oname = object_name.lower() 63 wf = original_get_window_filter(oname.replace("x11:", ""), property_name, operator, value) 64 if oname.startswith("x11:"): 65 #same filter but use X11 properties: 66 import types 67 wf.get_window = types.MethodType(get_window, wf) 68 wf.get_window_value = types.MethodType(get_window_value, wf) 69 log("patched methods: %s, %s", wf.get_window, wf.get_window_value) 70 log("x11 get_window_filter%s=%s", (object_name, property_name, operator, value), wf) 71 return wf 72 73 filters.get_window_filter = get_x11_window_filter 74 log("init_x11_window_filters() filters.get_window_filter=%s", filters.get_window_filter) 75