Ticket #1934: window-filters.patch
File window-filters.patch, 10.2 KB (added by , 2 years ago) |
---|
-
xpra/server/mixins/server_base_controlcommands.py
98 98 ArgsControlCommand("reset-video-region", "reset video region heuristics", min_args=1, max_args=1, validation=[int]), 99 99 ArgsControlCommand("lock-batch-delay", "set a specific batch delay for a window", min_args=2, max_args=2, validation=[int, int]), 100 100 ArgsControlCommand("unlock-batch-delay", "let the heuristics calculate the batch delay again for a window (following a 'lock-batch-delay')", min_args=1, max_args=1, validation=[int]), 101 ArgsControlCommand("remove-window-filters", "remove all window filters", min_args=0, max_args=1), 102 ArgsControlCommand("add-window-filter", "add a window filter", min_args=4, max_args=5), 101 103 ): 102 104 cmd.do_run = getattr(self, "control_command_%s" % cmd.name.replace("-", "_")) 103 105 self.control_commands[cmd.name] = cmd … … 281 283 return "%s of '%s' to %s initiated" % (command_type, filename, client_uuids) 282 284 283 285 286 def control_command_remove_window_filters(self, client_uuids=""): 287 #modify the existing list object, 288 #which is referenced by all the sources 289 l = len(self.window_filters) 290 self.window_filters[:] = [] 291 return "removed %i window-filters" % l 292 293 def control_command_add_window_filter(self, object_name, property_name, operator, value, client_uuids=""): 294 from xpra.server.window import filters 295 window_filter = filters.get_window_filter(object_name, property_name, operator, value) 296 #log("%s%s=%s", filters.get_window_filter, (object_name, property_name, operator, value), window_filter) 297 if client_uuids=="*": 298 #applies to all sources: 299 self.window_filters.append(("*", window_filter)) 300 else: 301 sources = tuple(self._control_get_sources(client_uuids)) 302 for ss in sources: 303 ss.do_add_window_filter(window_filter) 304 return "added window-filter: %s" % window_filter 305 306 284 307 def control_command_compression(self, compression): 285 308 c = compression.lower() 286 309 from xpra.net import compression -
xpra/server/server_base.py
314 314 315 315 def drop_client(reason="unknown", *args): 316 316 self.disconnect_client(proto, reason, *args) 317 ClientConnectionClass = self.get_server_source_class()318 ss = ClientConnection Class(proto, drop_client,317 from xpra.server.source.client_connection import ClientConnection 318 ss = ClientConnection(proto, drop_client, 319 319 self.session_name, self, 320 320 self.idle_add, self.timeout_add, self.source_remove, 321 321 self.setting_changed, … … 335 335 self.idle_add(self.parse_hello_ui, ss, c, auth_caps, send_ui, share_count) 336 336 337 337 338 def get_server_source_class(self):339 from xpra.server.source.client_connection import ClientConnection340 return ClientConnection341 342 338 def reset_window_filters(self): 343 339 self.window_filters = [] 344 340 -
xpra/server/source/windows_mixin.py
303 303 def get_all_window_filters(self): 304 304 return [f for uuid, f in self.window_filters if uuid==self.uuid] 305 305 306 def get_window_filter(self, object_name, property_name, operator, value):307 if object_name!="window":308 raise ValueError("invalid object name")309 from xpra.server.window.filters import WindowPropertyIn, WindowPropertyNotIn310 if operator=="=":311 return WindowPropertyIn(property_name, [value])312 elif operator=="!=":313 return WindowPropertyNotIn(property_name, [value])314 raise ValueError("unknown filter operator: %s" % operator)315 316 306 def add_window_filter(self, object_name, property_name, operator, value): 317 window_filter = self.get_window_filter(object_name, property_name, operator, value) 307 from xpra.server.window.filters import get_window_filter 308 window_filter = get_window_filter(object_name, property_name, operator, value) 318 309 assert window_filter 319 self. window_filters.append((self.uuid, window_filter.show))310 self.do_add_window_filter(window_filter) 320 311 312 def do_add_window_filter(self, window_filter): 313 #(reminder: filters are shared between all sources) 314 self.window_filters.append((self.uuid, window_filter)) 315 321 316 def can_send_window(self, window): 322 317 if not self.hello_sent: 323 318 return False 324 for uuid,x in self.window_filters: 325 v = x(window) 319 for uuid, window_filter in self.window_filters: 320 v = window_filter.can_show(window) 321 isuuidmatch = uuid==self.uuid or uuid=="*" 326 322 if v is True: 327 return uuid==self.uuid 323 return isuuidmatch 324 elif v is False: 325 return not(isuuidmatch) 328 326 if self.send_windows and self.system_tray: 329 327 #common case shortcut 330 328 return True -
xpra/server/window/filters.py
6 6 7 7 from xpra.log import Logger 8 8 log = Logger("window") 9 log.enable_debug() 9 10 10 11 11 12 class WindowPropertyFilter(object): 12 def __init__(self, property_name, value ):13 def __init__(self, property_name, value, recurse=False): 13 14 self.property_name = property_name 14 15 self.value = value 16 self.recurse = recurse 15 17 18 def get_window(self, window): 19 return window.get_property("client-window") 20 16 21 def get_window_value(self, window): 22 assert window 17 23 return window.get_property(self.property_name) 18 24 19 def show(self, window):25 def can_show(self, window): 20 26 try: 21 v = self.get_window_value(window) 22 log("%s.show(%s) %s(..)=%s", type(self).__name__, window, self.get_window_value, v) 27 w = self.get_window(window) 28 log("get_window(%s)=%s", window, w) 29 v = self.get_window_value(w) 30 log("%s.can_show(%s) %s(..)=%s", self, w, self.get_window_value, v) 23 31 except Exception: 24 log("%s. show(%s) %s(..) error:", type(self).__name__, window, self.get_window_value, exc_info=True)32 log("%s.can_show(%s) %s(..) error:", self, w, self.get_window_value, exc_info=True) 25 33 v = None 26 34 e = self.evaluate(v) 35 log("%s.evaluate(%s)=%s", self, v, e) 27 36 return e 28 37 29 38 def evaluate(self, window_value): … … 35 44 def evaluate(self, window_value): 36 45 return window_value in self.value 37 46 47 def __repr__(self): 48 return "WindowPropertyIn(%s=%s, recurse=%s)" % (self.property_name, self.value, self.recurse) 38 49 50 39 51 class WindowPropertyNotIn(WindowPropertyIn): 40 52 41 53 def evaluate(self, window_value): 42 return not(WindowPropertyIn.evaluate(window_value)) 54 return not(WindowPropertyIn.evaluate(self, window_value)) 55 56 def __repr__(self): 57 return "WindowPropertyNotIn(%s=%s, recurse=%s)" % (self.property_name, self.value, self.recurse) 58 59 60 def get_window_filter(object_name, property_name, operator, value): 61 oname = object_name.lower() 62 if oname not in ("window", "window-parent"): 63 raise ValueError("invalid object name '%s'" % object_name) 64 recurse = oname=="window-parent" 65 if operator=="=": 66 window_filter = WindowPropertyIn(property_name, [value], recurse) 67 elif operator=="!=": 68 window_filter = WindowPropertyNotIn(property_name, [value], recurse) 69 else: 70 raise ValueError("invalid window filter operator: %s" % operator) 71 log("get_window_filter%s=%s", (object_name, property_name, operator, value), window_filter) 72 return window_filter -
xpra/x11/bindings/window_bindings.pyx
984 984 xreq_type, &xactual_type, 985 985 &actual_format, &nitems, &bytes_after, &prop) 986 986 if status != Success: 987 raise None987 raise XError("XGetWindowProperty status: %s" % status) 988 988 if xactual_type == XNone: 989 raise None989 raise BadPropertyType("None type") 990 990 # This should only occur for bad property types: 991 991 assert not (bytes_after and not nitems) 992 992 if bytes_after: 993 raise None993 raise BadPropertyType("incomplete data: %i bytes after" % bytes_after) 994 994 assert actual_format in (8, 16, 32) 995 995 XFree(prop) 996 996 return self.XGetAtomName(xactual_type) -
xpra/x11/x11_server_core.py
103 103 self.current_keyboard_group = None 104 104 with xsync: 105 105 self.x11_init() 106 from xpra.server import server_features 107 if server_features.windows: 108 from xpra.x11.x11_window_filters import init_x11_window_filters 109 init_x11_window_filters() 106 110 111 107 112 def x11_init(self): 108 113 clean_keyboard_state() 109 114 if self.fake_xinerama: … … 275 280 self.input_devices = "xtest" 276 281 277 282 278 def get_server_source_class(self):279 from xpra.x11.x11_source import X11ServerSource280 return X11ServerSource281 282 283 283 def get_child_env(self): 284 284 #adds fakeXinerama: 285 285 env = super(X11ServerCore, self).get_child_env()