class ClientExtras(object): def __init__(self, client): self.client = client self.setup_xprops() def setup_xprops(self): self.ROOT_PROPS = {"RESOURCE_MANAGER": "resource-manager"} def setup_xprop_xsettings(client): log.debug("setup_xprop_xsettings(%s)", client) try: from xpra.x11.xsettings import XSettingsWatcher from xpra.x11.xroot_props import XRootPropWatcher self._xsettings_watcher = XSettingsWatcher() self._xsettings_watcher.connect("xsettings-changed", self._handle_xsettings_changed) self._handle_xsettings_changed() self._root_props_watcher = XRootPropWatcher( self.ROOT_PROPS.keys()) self._root_props_watcher.connect( "root-prop-changed", self._handle_root_prop_changed) self._root_props_watcher.notify_all() except ImportError, e: log.error( "failed to load X11 properties/settings bindings: %s - root window properties will not be propagated", e) self.client.connect("handshake-complete", setup_xprop_xsettings)
class ClientExtras(object): def __init__(self, client): self.client = client self._xsettings_watcher = None self._root_props_watcher = None if client.xsettings_enabled: self.setup_xprops() def cleanup(self): log("cleanup() xsettings_watcher=%s, root_props_watcher=%s", self._xsettings_watcher, self._root_props_watcher) if self._xsettings_watcher: self._xsettings_watcher.cleanup() self._xsettings_watcher = None if self._root_props_watcher: self._root_props_watcher.cleanup() self._root_props_watcher = None def setup_xprops(self): #wait for handshake to complete: self.client.connect("handshake-complete", self.do_setup_xprops) def do_setup_xprops(self, *args): log.debug("do_setup_xprops(%s)", args) ROOT_PROPS = ["RESOURCE_MANAGER", "_NET_WORKAREA"] try: from xpra.x11.xsettings import XSettingsWatcher from xpra.x11.xroot_props import XRootPropWatcher self._xsettings_watcher = XSettingsWatcher() self._xsettings_watcher.connect("xsettings-changed", self._handle_xsettings_changed) self._handle_xsettings_changed() self._root_props_watcher = XRootPropWatcher(ROOT_PROPS) self._root_props_watcher.connect("root-prop-changed", self._handle_root_prop_changed) #ensure we get the initial value: self._root_props_watcher.do_notify("RESOURCE_MANAGER") except ImportError, e: log.error( "failed to load X11 properties/settings bindings: %s - root window properties will not be propagated", e)
class ClientExtras(object): def __init__(self, client): self.client = client self.setup_xprops() def setup_xprops(self): self.ROOT_PROPS = { "RESOURCE_MANAGER": "resource-manager" } def setup_xprop_xsettings(client): log.debug("setup_xprop_xsettings(%s)", client) try: from xpra.x11.xsettings import XSettingsWatcher from xpra.x11.xroot_props import XRootPropWatcher self._xsettings_watcher = XSettingsWatcher() self._xsettings_watcher.connect("xsettings-changed", self._handle_xsettings_changed) self._handle_xsettings_changed() self._root_props_watcher = XRootPropWatcher(self.ROOT_PROPS.keys()) self._root_props_watcher.connect("root-prop-changed", self._handle_root_prop_changed) self._root_props_watcher.notify_all() except ImportError, e: log.error("failed to load X11 properties/settings bindings: %s - root window properties will not be propagated", e) self.client.connect("handshake-complete", setup_xprop_xsettings)
class ClientExtras(object): def __init__(self, client): self.client = client self._xsettings_watcher = None self._root_props_watcher = None if client.xsettings_enabled: self.setup_xprops() def cleanup(self): log("cleanup() xsettings_watcher=%s, root_props_watcher=%s", self._xsettings_watcher, self._root_props_watcher) if self._xsettings_watcher: self._xsettings_watcher.cleanup() self._xsettings_watcher = None if self._root_props_watcher: self._root_props_watcher.cleanup() self._root_props_watcher = None def setup_xprops(self): #wait for handshake to complete: self.client.connect("handshake-complete", self.do_setup_xprops) def do_setup_xprops(self, *args): log.debug("do_setup_xprops(%s)", args) ROOT_PROPS = ["RESOURCE_MANAGER", "_NET_WORKAREA"] try: from xpra.x11.xsettings import XSettingsWatcher from xpra.x11.xroot_props import XRootPropWatcher self._xsettings_watcher = XSettingsWatcher() self._xsettings_watcher.connect("xsettings-changed", self._handle_xsettings_changed) self._handle_xsettings_changed() self._root_props_watcher = XRootPropWatcher(ROOT_PROPS) self._root_props_watcher.connect("root-prop-changed", self._handle_root_prop_changed) #ensure we get the initial value: self._root_props_watcher.do_notify("RESOURCE_MANAGER") except ImportError, e: log.error("failed to load X11 properties/settings bindings: %s - root window properties will not be propagated", e)
class ClientExtras: def __init__(self, client, _opts): self.client = client self._xsettings_watcher = None self._root_props_watcher = None self.system_bus = None self.session_bus = None self.upower_resuming_match = None self.upower_sleeping_match = None self.login1_match = None self.screensaver_match = None self.x11_filter = None if client.xsettings_enabled: self.setup_xprops() self.xi_setup_failures = 0 input_devices = getattr(client, "input_devices", None) if input_devices in ("xi", "auto"): #this would trigger warnings with our temporary opengl windows: #only enable it after we have connected: self.client.after_handshake(self.setup_xi) self.setup_dbus_signals() def ready(self): """ unused on xposix """ def init_x11_filter(self): if self.x11_filter: return try: from xpra.x11.gtk_x11.gdk_bindings import init_x11_filter #@UnresolvedImport, @UnusedImport self.x11_filter = init_x11_filter() log("x11_filter=%s", self.x11_filter) except Exception as e: log("init_x11_filter()", exc_info=True) log.error("Error: failed to initialize X11 GDK filter:") log.error(" %s", e) self.x11_filter = None def cleanup(self): log("cleanup() xsettings_watcher=%s, root_props_watcher=%s", self._xsettings_watcher, self._root_props_watcher) if self.x11_filter: self.x11_filter = None from xpra.x11.gtk_x11.gdk_bindings import cleanup_x11_filter #@UnresolvedImport, @UnusedImport cleanup_x11_filter() if self._xsettings_watcher: self._xsettings_watcher.cleanup() self._xsettings_watcher = None if self._root_props_watcher: self._root_props_watcher.cleanup() self._root_props_watcher = None if self.system_bus: bus = self.system_bus log("cleanup() system bus=%s, matches: %s", bus, (self.upower_resuming_match, self.upower_sleeping_match, self.login1_match)) self.system_bus = None if self.upower_resuming_match: bus._clean_up_signal_match(self.upower_resuming_match) self.upower_resuming_match = None if self.upower_sleeping_match: bus._clean_up_signal_match(self.upower_sleeping_match) self.upower_sleeping_match = None if self.login1_match: bus._clean_up_signal_match(self.login1_match) self.login1_match = None if self.session_bus: if self.screensaver_match: self.session_bus._clean_up_signal_match(self.screensaver_match) self.screensaver_match = None global WINDOW_METHOD_OVERRIDES WINDOW_METHOD_OVERRIDES = {} def resuming_callback(self, *args): eventlog("resuming_callback%s", args) self.client.resume() def sleeping_callback(self, *args): eventlog("sleeping_callback%s", args) self.client.suspend() def setup_dbus_signals(self): try: import xpra.dbus assert xpra.dbus except ImportError as e: dbuslog("setup_dbus_signals()", exc_info=True) dbuslog.info("dbus support is not installed") dbuslog.info(" no support for power events") return try: from xpra.dbus.common import init_system_bus, init_session_bus except ImportError as e: dbuslog("setup_dbus_signals()", exc_info=True) dbuslog.error("Error: dbus bindings are missing,") dbuslog.error(" cannot setup event listeners:") dbuslog.error(" %s", e) return try: bus = init_system_bus() self.system_bus = bus dbuslog("setup_dbus_signals() system bus=%s", bus) except Exception as e: dbuslog("setup_dbus_signals()", exc_info=True) dbuslog.error("Error setting up dbus signals:") dbuslog.error(" %s", e) else: #the UPower signals: try: bus_name = 'org.freedesktop.UPower' dbuslog("bus has owner(%s)=%s", bus_name, bus.name_has_owner(bus_name)) iface_name = 'org.freedesktop.UPower' self.upower_resuming_match = bus.add_signal_receiver( self.resuming_callback, 'Resuming', iface_name, bus_name) self.upower_sleeping_match = bus.add_signal_receiver( self.sleeping_callback, 'Sleeping', iface_name, bus_name) dbuslog( "listening for 'Resuming' and 'Sleeping' signals on %s", iface_name) except Exception as e: dbuslog("failed to setup UPower event listener: %s", e) #the "logind" signals: try: bus_name = 'org.freedesktop.login1' dbuslog("bus has owner(%s)=%s", bus_name, bus.name_has_owner(bus_name)) def sleep_event_handler(suspend): if suspend: self.sleeping_callback() else: self.resuming_callback() iface_name = 'org.freedesktop.login1.Manager' self.login1_match = bus.add_signal_receiver( sleep_event_handler, 'PrepareForSleep', iface_name, bus_name) dbuslog("listening for 'PrepareForSleep' signal on %s", iface_name) except Exception as e: dbuslog("failed to setup login1 event listener: %s", e) if DBUS_SCREENSAVER: try: session_bus = init_session_bus() self.session_bus = session_bus dbuslog("setup_dbus_signals() session bus=%s", session_bus) except Exception as e: dbuslog("setup_dbus_signals()", exc_info=True) dbuslog.error("Error setting up dbus signals:") dbuslog.error(" %s", e) else: #screensaver signals: try: bus_name = "org.gnome.ScreenSaver" iface_name = bus_name self.screensaver_match = bus.add_signal_receiver( self.ActiveChanged, "ActiveChanged", iface_name, bus_name) dbuslog("listening for 'ActiveChanged' signal on %s", iface_name) except Exception as e: dbuslog.warn( "Warning: failed to setup screensaver event listener: %s", e) def ActiveChanged(self, active): log("ActiveChanged(%s)", active) if active: self.client.suspend() else: self.client.resume() def setup_xprops(self): #wait for handshake to complete: if not is_Wayland(): self.client.after_handshake(self.do_setup_xprops) def do_setup_xprops(self, *args): log("do_setup_xprops(%s)", args) ROOT_PROPS = [ "RESOURCE_MANAGER", "_NET_WORKAREA", "_NET_CURRENT_DESKTOP" ] try: self.init_x11_filter() from xpra.gtk_common.gtk_util import get_default_root_window from xpra.x11.xsettings import XSettingsWatcher from xpra.x11.xroot_props import XRootPropWatcher root = get_default_root_window() if self._xsettings_watcher is None: self._xsettings_watcher = XSettingsWatcher() self._xsettings_watcher.connect("xsettings-changed", self._handle_xsettings_changed) self._handle_xsettings_changed() if self._root_props_watcher is None: self._root_props_watcher = XRootPropWatcher(ROOT_PROPS, root) self._root_props_watcher.connect( "root-prop-changed", self._handle_root_prop_changed) #ensure we get the initial value: self._root_props_watcher.do_notify("RESOURCE_MANAGER") except ImportError as e: log("do_setup_xprops%s", args, exc_info=True) log.error( "Error: failed to load X11 properties/settings bindings:") log.error(" %s", e) log.error(" root window properties will not be propagated") def do_xi_devices_changed(self, event): log("do_xi_devices_changed(%s)", event) XI2 = X11XI2Bindings() devices = XI2.get_devices() if devices: self.client.send_input_devices("xi", devices) def setup_xi(self): self.client.timeout_add(100, self.do_setup_xi) def do_setup_xi(self): if self.client.server_input_devices not in ("xi", "uinput"): xinputlog("server does not support xi input devices") if self.client.server_input_devices: log(" server uses: %s", self.client.server_input_devices) return False try: from xpra.gtk_common.error import xsync, XError assert X11WindowBindings, "no X11 window bindings" assert X11XI2Bindings, "no XI2 window bindings" XI2 = X11XI2Bindings() #this may fail when windows are being destroyed, #ie: when another client disconnects because we are stealing the session try: with xsync: XI2.select_xi2_events() except XError: self.xi_setup_failures += 1 xinputlog("select_xi2_events() failed, attempt %i", self.xi_setup_failures, exc_info=True) return self.xi_setup_failures < 10 #try again with xsync: XI2.gdk_inject() self.init_x11_filter() if self.client.server_input_devices: XI2.connect(0, "XI_HierarchyChanged", self.do_xi_devices_changed) devices = XI2.get_devices() if devices: self.client.send_input_devices("xi", devices) except Exception as e: xinputlog("enable_xi2()", exc_info=True) xinputlog.error("Error: cannot enable XI2 events") xinputlog.error(" %s", e) else: #register our enhanced event handlers: self.add_xi2_method_overrides() return False def add_xi2_method_overrides(self): global WINDOW_ADD_HOOKS WINDOW_ADD_HOOKS = [XI2_Window] def _get_xsettings(self): try: return self._xsettings_watcher.get_settings() except Exception: log.error("failed to get XSETTINGS", exc_info=True) return None def _handle_xsettings_changed(self, *_args): settings = self._get_xsettings() log("xsettings_changed new value=%s", settings) if settings is not None: self.client.send("server-settings", {"xsettings-blob": settings}) def get_resource_manager(self): try: from xpra.gtk_common.gtk_util import get_default_root_window from xpra.x11.gtk_x11.prop import prop_get root = get_default_root_window() value = prop_get(root, "RESOURCE_MANAGER", "latin1", ignore_errors=True) if value is not None: return value.encode("utf-8") except (ImportError, UnicodeEncodeError): log.error("failed to get RESOURCE_MANAGER", exc_info=True) return None def _handle_root_prop_changed(self, obj, prop): log("root_prop_changed(%s, %s)", obj, prop) if prop == "RESOURCE_MANAGER": rm = self.get_resource_manager() if rm is not None: self.client.send("server-settings", {"resource-manager": rm}) elif prop == "_NET_WORKAREA": self.client.screen_size_changed("from %s event" % self._root_props_watcher) elif prop == "_NET_CURRENT_DESKTOP": self.client.workspace_changed("from %s event" % self._root_props_watcher) elif prop in ("_NET_DESKTOP_NAMES", "_NET_NUMBER_OF_DESKTOPS"): self.client.desktops_changed("from %s event" % self._root_props_watcher) else: log.error("unknown property %s", prop)
class ClientExtras(object): def __init__(self, client, opts): self.client = client self._xsettings_watcher = None self._root_props_watcher = None self.system_bus = None self.upower_resuming_match = None self.upower_sleeping_match = None self.login1_match = None if client.xsettings_enabled: self.setup_xprops() self.setup_dbus_signals() def ready(self): pass def cleanup(self): log("cleanup() xsettings_watcher=%s, root_props_watcher=%s", self._xsettings_watcher, self._root_props_watcher) if self._xsettings_watcher: self._xsettings_watcher.cleanup() self._xsettings_watcher = None if self._root_props_watcher: self._root_props_watcher.cleanup() self._root_props_watcher = None if self.system_bus: bus = self.system_bus log("cleanup() system bus=%s, matches: %s", bus, (self.upower_resuming_match, self.upower_sleeping_match, self.login1_match)) self.system_bus = None if self.upower_resuming_match: bus._clean_up_signal_match(self.upower_resuming_match) if self.upower_sleeping_match: bus._clean_up_signal_match(self.upower_sleeping_match) if self.login1_match: bus._clean_up_signal_match(self.login1_match) def resuming_callback(self, *args): eventlog("resuming_callback%s", args) self.client.resume() def sleeping_callback(self, *args): eventlog("sleeping_callback%s", args) self.client.suspend() def setup_dbus_signals(self): try: import xpra.dbus assert xpra.dbus except ImportError as e: dbuslog("setup_dbus_signals()", exc_info=True) dbuslog.info("dbus support is not installed") dbuslog.info(" no support for power events") return try: from xpra.dbus.common import init_system_bus bus = init_system_bus() self.system_bus = bus dbuslog("setup_dbus_signals() system bus=%s", bus) except Exception as e: dbuslog("setup_dbus_signals()", exc_info=True) dbuslog.error("Error setting up dbus signals:") dbuslog.error(" %s", e) return #the UPower signals: try: bus_name = 'org.freedesktop.UPower' dbuslog("bus has owner(%s)=%s", bus_name, bus.name_has_owner(bus_name)) iface_name = 'org.freedesktop.UPower' self.upower_resuming_match = bus.add_signal_receiver(self.resuming_callback, 'Resuming', iface_name, bus_name) self.upower_sleeping_match = bus.add_signal_receiver(self.sleeping_callback, 'Sleeping', iface_name, bus_name) dbuslog("listening for 'Resuming' and 'Sleeping' signals on %s", iface_name) except Exception as e: dbuslog("failed to setup UPower event listener: %s", e) #the "logind" signals: try: bus_name = 'org.freedesktop.login1' dbuslog("bus has owner(%s)=%s", bus_name, bus.name_has_owner(bus_name)) def sleep_event_handler(suspend): if suspend: self.sleeping_callback() else: self.resuming_callback() iface_name = 'org.freedesktop.login1.Manager' self.login1_match = bus.add_signal_receiver(sleep_event_handler, 'PrepareForSleep', iface_name, bus_name) dbuslog("listening for 'PrepareForSleep' signal on %s", iface_name) except Exception as e: dbuslog("failed to setup login1 event listener: %s", e) def setup_xprops(self): #wait for handshake to complete: self.client.after_handshake(self.do_setup_xprops) def do_setup_xprops(self, *args): log("do_setup_xprops(%s)", args) if is_gtk3(): log("x11 root properties and XSETTINGS are not supported yet with GTK3") return ROOT_PROPS = ["RESOURCE_MANAGER", "_NET_WORKAREA", "_NET_CURRENT_DESKTOP"] try: from xpra.x11.xsettings import XSettingsWatcher from xpra.x11.xroot_props import XRootPropWatcher if self._xsettings_watcher is None: self._xsettings_watcher = XSettingsWatcher() self._xsettings_watcher.connect("xsettings-changed", self._handle_xsettings_changed) self._handle_xsettings_changed() if self._root_props_watcher is None: self._root_props_watcher = XRootPropWatcher(ROOT_PROPS) self._root_props_watcher.connect("root-prop-changed", self._handle_root_prop_changed) #ensure we get the initial value: self._root_props_watcher.do_notify("RESOURCE_MANAGER") except ImportError as e: log.error("failed to load X11 properties/settings bindings: %s - root window properties will not be propagated", e) def _get_xsettings(self): try: return self._xsettings_watcher.get_settings() except: log.error("failed to get XSETTINGS", exc_info=True) return None def _handle_xsettings_changed(self, *args): settings = self._get_xsettings() log("xsettings_changed new value=%s", settings) if settings is not None: self.client.send("server-settings", {"xsettings-blob": settings}) def get_resource_manager(self): try: import gtk.gdk root = gtk.gdk.get_default_root_window() from xpra.x11.gtk_x11.prop import prop_get value = prop_get(root, "RESOURCE_MANAGER", "latin1", ignore_errors=True) if value is not None: return value.encode("utf-8") except: log.error("failed to get RESOURCE_MANAGER", exc_info=True) return None def _handle_root_prop_changed(self, obj, prop): log("root_prop_changed(%s, %s)", obj, prop) if prop=="RESOURCE_MANAGER": rm = self.get_resource_manager() if rm is not None: self.client.send("server-settings", {"resource-manager" : rm}) elif prop=="_NET_WORKAREA": self.client.screen_size_changed("from %s event" % self._root_props_watcher) elif prop=="_NET_CURRENT_DESKTOP": self.client.workspace_changed("from %s event" % self._root_props_watcher) elif prop in ("_NET_DESKTOP_NAMES", "_NET_NUMBER_OF_DESKTOPS"): self.client.desktops_changed("from %s event" % self._root_props_watcher) else: log.error("unknown property %s", prop)
class DesktopModel(WindowModelStub, WindowDamageHandler): __gsignals__ = {} __gsignals__.update(WindowDamageHandler.__common_gsignals__) __gsignals__.update({ "resized" : no_arg_signal, "client-contents-changed" : one_arg_signal, }) __gproperties__ = { "iconic": (GObject.TYPE_BOOLEAN, "ICCCM 'iconic' state -- any sort of 'not on desktop'.", "", False, GObject.ParamFlags.READWRITE), "focused": (GObject.TYPE_BOOLEAN, "Is the window focused", "", False, GObject.ParamFlags.READWRITE), "size-hints": (GObject.TYPE_PYOBJECT, "Client hints on constraining its size", "", GObject.ParamFlags.READABLE), "wm-name": (GObject.TYPE_PYOBJECT, "The name of the window manager or session manager", "", GObject.ParamFlags.READABLE), "icons": (GObject.TYPE_PYOBJECT, "The icon of the window manager or session manager", "", GObject.ParamFlags.READABLE), } _property_names = [ "xid", "client-machine", "window-type", "shadow", "size-hints", "class-instance", "focused", "title", "depth", "icons", "content-type", ] _dynamic_property_names = ["size-hints", "title", "icons"] def __init__(self, root, resize_exact=False): WindowDamageHandler.__init__(self, root) WindowModelStub.__init__(self) self.root_prop_watcher = XRootPropWatcher(["WINDOW_MANAGER", "_NET_SUPPORTING_WM_CHECK"], root) self.root_prop_watcher.connect("root-prop-changed", self.root_prop_changed) self.update_icon() self.resize_exact = resize_exact def __repr__(self): return "DesktopModel(%#x)" % self.client_window.get_xid() def setup(self): WindowDamageHandler.setup(self) screen = self.client_window.get_screen() screen.connect("size-changed", self._screen_size_changed) self.update_size_hints(screen) self._depth = X11Window.get_depth(self.client_window.get_xid()) self._managed = True self._setup_done = True def unmanage(self, exiting=False): WindowDamageHandler.destroy(self) WindowModelStub.unmanage(self, exiting) self._managed = False rpw = self.root_prop_watcher if rpw: self.root_prop_watcher = None rpw.cleanup() def root_prop_changed(self, watcher, prop): iconlog("root_prop_changed(%s, %s)", watcher, prop) if self.update_wm_name(): self.update_icon() def update_wm_name(self): try: wm_name = get_wm_name() #pylint: disable=assignment-from-none except Exception: wm_name = "" iconlog("update_wm_name() wm-name=%s", wm_name) return self._updateprop("wm-name", wm_name) def update_icon(self): icons = None try: wm_name = get_wm_name() #pylint: disable=assignment-from-none if not wm_name: return icon_name = get_icon_filename(wm_name.lower()+".png") from PIL import Image img = Image.open(icon_name) iconlog("Image(%s)=%s", icon_name, img) if img: icon_data = load_binary_file(icon_name) assert icon_data w, h = img.size icon = (w, h, "png", icon_data) icons = (icon,) except Exception: iconlog("failed to return window icon", exc_info=True) return self._updateprop("icons", icons) def get_geometry(self): return self.client_window.get_geometry()[:4] def get_dimensions(self): return self.client_window.get_geometry()[2:4] def uses_XShm(self): return bool(self._xshm_handle) def get_default_window_icon(self, _size): icon_name = get_generic_os_name()+".png" icon = get_icon(icon_name) if not icon: return None return icon.get_width(), icon.get_height(), "RGBA", icon.get_pixels() def get_property(self, prop): if prop=="xid": return int(self.client_window.get_xid()) if prop=="depth": return self._depth if prop=="title": return get_wm_name() or "xpra desktop" if prop=="client-machine": return socket.gethostname() if prop=="window-type": return ["NORMAL"] if prop=="shadow": return True if prop=="class-instance": return ("xpra-desktop", "Xpra-Desktop") if prop=="content-type": return "desktop" return GObject.GObject.get_property(self, prop) def _screen_size_changed(self, screen): w, h = screen.get_width(), screen.get_height() screenlog("screen size changed: new size %ix%i", w, h) screenlog("root window geometry=%s", self.client_window.get_geometry()) self.invalidate_pixmap() self.update_size_hints(screen) self.emit("resized") def update_size_hints(self, screen): w, h = screen.get_width(), screen.get_height() screenlog("screen dimensions: %ix%i", w, h) size_hints = {} def use_fixed_size(): size = w, h size_hints.update({ "maximum-size" : size, "minimum-size" : size, "base-size" : size, }) if RandR.has_randr(): if self.resize_exact: #assume resize_exact is enabled #no size restrictions size_hints = {} else: try: with xsync: screen_sizes = RandR.get_xrr_screen_sizes() except XError: screenlog("failed to query screen sizes", exc_info=True) else: if not screen_sizes: use_fixed_size() else: #find the maximum size supported: max_size = {} for tw, th in screen_sizes: max_size[tw*th] = (tw, th) max_pixels = sorted(max_size.keys())[-1] size_hints["maximum-size"] = max_size[max_pixels] #find the best increment we can use: inc_hits = {} #we should also figure out what the potential increments are, #rather than hardcoding them here: INC_VALUES = (16, 32, 64, 128, 256) for inc in INC_VALUES: hits = 0 for tsize in screen_sizes: tw, th = tsize if (tw+inc, th+inc) in screen_sizes: hits += 1 inc_hits[inc] = hits screenlog("size increment hits: %s", inc_hits) max_hits = max(inc_hits.values()) if max_hits>16: #find the first increment value matching the max hits for inc in INC_VALUES: if inc_hits[inc]==max_hits: break #TODO: also get these values from the screen sizes: size_hints.update({ "base-size" : (640, 640), "minimum-size" : (640, 640), "increment" : (128, 128), "minimum-aspect-ratio" : (1, 3), "maximum-aspect-ratio" : (3, 1), }) else: use_fixed_size() screenlog("size-hints=%s", size_hints) self._updateprop("size-hints", size_hints) def do_xpra_damage_event(self, event): self.emit("client-contents-changed", event)
class ClientExtras(object): def __init__(self, client, opts): self.client = client self._xsettings_watcher = None self._root_props_watcher = None self.system_bus = None self.upower_resuming_match = None self.upower_sleeping_match = None self.login1_match = None if client.xsettings_enabled: self.setup_xprops() self.setup_dbus_signals() def cleanup(self): log("cleanup() xsettings_watcher=%s, root_props_watcher=%s", self._xsettings_watcher, self._root_props_watcher) if self._xsettings_watcher: self._xsettings_watcher.cleanup() self._xsettings_watcher = None if self._root_props_watcher: self._root_props_watcher.cleanup() self._root_props_watcher = None if self.system_bus: bus = self.system_bus log("cleanup() system bus=%s, matches: %s", bus, (self.upower_resuming_match, self.upower_sleeping_match, self.login1_match)) self.system_bus = None if self.upower_resuming_match: bus._clean_up_signal_match(self.upower_resuming_match) if self.upower_sleeping_match: bus._clean_up_signal_match(self.upower_sleeping_match) if self.login1_match: bus._clean_up_signal_match(self.login1_match) def resuming_callback(self, *args): eventlog("resuming_callback%s", args) self.client.resume() def sleeping_callback(self, *args): eventlog("sleeping_callback%s", args) self.client.suspend() def setup_dbus_signals(self): try: from xpra.dbus.common import init_system_bus bus = init_system_bus() self.system_bus = bus dbuslog("setup_dbus_signals() system bus=%s", bus) except Exception as e: dbuslog.error("Error setting up dbus signals:") dbuslog.error(" %s", e) return #the UPower signals: try: bus_name = 'org.freedesktop.UPower' dbuslog("bus has owner(%s)=%s", bus_name, bus.name_has_owner(bus_name)) iface_name = 'org.freedesktop.UPower' self.upower_resuming_match = bus.add_signal_receiver(self.resuming_callback, 'Resuming', iface_name, bus_name) self.upower_sleeping_match = bus.add_signal_receiver(self.sleeping_callback, 'Sleeping', iface_name, bus_name) dbuslog("listening for 'Resuming' and 'Sleeping' signals on %s", iface_name) except Exception as e: dbuslog("failed to setup UPower event listener: %s", e) #the "logind" signals: try: bus_name = 'org.freedesktop.login1' dbuslog("bus has owner(%s)=%s", bus_name, bus.name_has_owner(bus_name)) def sleep_event_handler(suspend): if suspend: self.sleeping_callback() else: self.resuming_callback() iface_name = 'org.freedesktop.login1.Manager' self.login1_match = bus.add_signal_receiver(sleep_event_handler, 'PrepareForSleep', iface_name, bus_name) dbuslog("listening for 'PrepareForSleep' signal on %s", iface_name) except Exception as e: dbuslog("failed to setup login1 event listener: %s", e) def setup_xprops(self): #wait for handshake to complete: self.client.after_handshake(self.do_setup_xprops) def do_setup_xprops(self, *args): log("do_setup_xprops(%s)", args) if is_gtk3(): log("x11 root properties and XSETTINGS are not supported yet with GTK3") return ROOT_PROPS = ["RESOURCE_MANAGER", "_NET_WORKAREA", "_NET_CURRENT_DESKTOP"] try: from xpra.x11.xsettings import XSettingsWatcher from xpra.x11.xroot_props import XRootPropWatcher if self._xsettings_watcher is None: self._xsettings_watcher = XSettingsWatcher() self._xsettings_watcher.connect("xsettings-changed", self._handle_xsettings_changed) self._handle_xsettings_changed() if self._root_props_watcher is None: self._root_props_watcher = XRootPropWatcher(ROOT_PROPS) self._root_props_watcher.connect("root-prop-changed", self._handle_root_prop_changed) #ensure we get the initial value: self._root_props_watcher.do_notify("RESOURCE_MANAGER") except ImportError as e: log.error("failed to load X11 properties/settings bindings: %s - root window properties will not be propagated", e) def _get_xsettings(self): try: return self._xsettings_watcher.get_settings() except: log.error("failed to get XSETTINGS", exc_info=True) return None def _handle_xsettings_changed(self, *args): settings = self._get_xsettings() log("xsettings_changed new value=%s", settings) if settings is not None: self.client.send("server-settings", {"xsettings-blob": settings}) def get_resource_manager(self): try: import gtk.gdk root = gtk.gdk.get_default_root_window() from xpra.x11.gtk_x11.prop import prop_get value = prop_get(root, "RESOURCE_MANAGER", "latin1", ignore_errors=True) if value is not None: return value.encode("utf-8") except: log.error("failed to get RESOURCE_MANAGER", exc_info=True) return None def _handle_root_prop_changed(self, obj, prop): log("root_prop_changed(%s, %s)", obj, prop) if prop=="RESOURCE_MANAGER": rm = self.get_resource_manager() if rm is not None: self.client.send("server-settings", {"resource-manager" : rm}) elif prop=="_NET_WORKAREA": self.client.screen_size_changed("from %s event" % self._root_props_watcher) elif prop=="_NET_CURRENT_DESKTOP": self.client.workspace_changed("from %s event" % self._root_props_watcher) elif prop in ("_NET_DESKTOP_NAMES", "_NET_NUMBER_OF_DESKTOPS"): self.client.desktops_changed("from %s event" % self._root_props_watcher) else: log.error("unknown property %s", prop)
class ClientExtras(object): def __init__(self, client, opts): self.client = client self._xsettings_watcher = None self._root_props_watcher = None self.system_bus = None self.upower_resuming_match = None self.upower_sleeping_match = None self.login1_match = None self.x11_filter = None if client.xsettings_enabled: self.setup_xprops() if client.input_devices == "xi": #this would trigger warnings with our temporary opengl windows: #only enable it after we have connected: self.client.after_handshake(self.setup_xi) self.setup_dbus_signals() def ready(self): pass def init_x11_filter(self): if self.x11_filter: return try: from xpra.x11.gtk2.gdk_bindings import init_x11_filter #@UnresolvedImport self.x11_filter = init_x11_filter() log("x11_filter=%s", self.x11_filter) except: self.x11_filter = None def cleanup(self): log("cleanup() xsettings_watcher=%s, root_props_watcher=%s", self._xsettings_watcher, self._root_props_watcher) if self.x11_filter: from xpra.x11.gtk2.gdk_bindings import cleanup_x11_filter #@UnresolvedImport self.x11_filter = None cleanup_x11_filter() if self._xsettings_watcher: self._xsettings_watcher.cleanup() self._xsettings_watcher = None if self._root_props_watcher: self._root_props_watcher.cleanup() self._root_props_watcher = None if self.system_bus: bus = self.system_bus log("cleanup() system bus=%s, matches: %s", bus, (self.upower_resuming_match, self.upower_sleeping_match, self.login1_match)) self.system_bus = None if self.upower_resuming_match: bus._clean_up_signal_match(self.upower_resuming_match) if self.upower_sleeping_match: bus._clean_up_signal_match(self.upower_sleeping_match) if self.login1_match: bus._clean_up_signal_match(self.login1_match) global WINDOW_METHOD_OVERRIDES WINDOW_METHOD_OVERRIDES = {} def resuming_callback(self, *args): eventlog("resuming_callback%s", args) self.client.resume() def sleeping_callback(self, *args): eventlog("sleeping_callback%s", args) self.client.suspend() def setup_dbus_signals(self): try: import xpra.dbus assert xpra.dbus except ImportError as e: dbuslog("setup_dbus_signals()", exc_info=True) dbuslog.info("dbus support is not installed") dbuslog.info(" no support for power events") return try: from xpra.dbus.common import init_system_bus bus = init_system_bus() self.system_bus = bus dbuslog("setup_dbus_signals() system bus=%s", bus) except Exception as e: dbuslog("setup_dbus_signals()", exc_info=True) dbuslog.error("Error setting up dbus signals:") dbuslog.error(" %s", e) return #the UPower signals: try: bus_name = 'org.freedesktop.UPower' dbuslog("bus has owner(%s)=%s", bus_name, bus.name_has_owner(bus_name)) iface_name = 'org.freedesktop.UPower' self.upower_resuming_match = bus.add_signal_receiver( self.resuming_callback, 'Resuming', iface_name, bus_name) self.upower_sleeping_match = bus.add_signal_receiver( self.sleeping_callback, 'Sleeping', iface_name, bus_name) dbuslog("listening for 'Resuming' and 'Sleeping' signals on %s", iface_name) except Exception as e: dbuslog("failed to setup UPower event listener: %s", e) #the "logind" signals: try: bus_name = 'org.freedesktop.login1' dbuslog("bus has owner(%s)=%s", bus_name, bus.name_has_owner(bus_name)) def sleep_event_handler(suspend): if suspend: self.sleeping_callback() else: self.resuming_callback() iface_name = 'org.freedesktop.login1.Manager' self.login1_match = bus.add_signal_receiver( sleep_event_handler, 'PrepareForSleep', iface_name, bus_name) dbuslog("listening for 'PrepareForSleep' signal on %s", iface_name) except Exception as e: dbuslog("failed to setup login1 event listener: %s", e) def setup_xprops(self): #wait for handshake to complete: self.client.after_handshake(self.do_setup_xprops) def do_setup_xprops(self, *args): log("do_setup_xprops(%s)", args) if is_gtk3(): log("x11 root properties and XSETTINGS are not supported yet with GTK3" ) return ROOT_PROPS = [ "RESOURCE_MANAGER", "_NET_WORKAREA", "_NET_CURRENT_DESKTOP" ] try: self.init_x11_filter() from xpra.x11.xsettings import XSettingsWatcher from xpra.x11.xroot_props import XRootPropWatcher if self._xsettings_watcher is None: self._xsettings_watcher = XSettingsWatcher() self._xsettings_watcher.connect("xsettings-changed", self._handle_xsettings_changed) self._handle_xsettings_changed() if self._root_props_watcher is None: self._root_props_watcher = XRootPropWatcher(ROOT_PROPS) self._root_props_watcher.connect( "root-prop-changed", self._handle_root_prop_changed) #ensure we get the initial value: self._root_props_watcher.do_notify("RESOURCE_MANAGER") except ImportError as e: log.error( "failed to load X11 properties/settings bindings: %s - root window properties will not be propagated", e) def do_xi_devices_changed(self, event): log("do_xi_devices_changed(%s)", event) XI2 = X11XI2Bindings() devices = XI2.get_devices() if devices: self.client.send_input_devices("xi", devices) def setup_xi(self): if self.client.server_input_devices != "xi": log.info("server does not support xi input devices") try: from xpra.gtk_common.error import xsync with xsync: assert X11WindowBindings, "no X11 window bindings" assert X11XI2Bindings, "no XI2 window bindings" X11XI2Bindings().gdk_inject() self.init_x11_filter() XI2 = X11XI2Bindings() XI2.select_xi2_events() if self.client.server_input_devices: XI2.connect(0, "XI_HierarchyChanged", self.do_xi_devices_changed) devices = XI2.get_devices() if devices: self.client.send_input_devices("xi", devices) except Exception as e: log("enable_xi2()", exc_info=True) log.error("Error: cannot enable XI2 events") log.error(" %s", e) else: #register our enhanced event handlers: self.add_xi2_method_overrides() def add_xi2_method_overrides(self): global WINDOW_ADD_HOOKS WINDOW_ADD_HOOKS = [XI2_Window] def _get_xsettings(self): try: return self._xsettings_watcher.get_settings() except: log.error("failed to get XSETTINGS", exc_info=True) return None def _handle_xsettings_changed(self, *args): settings = self._get_xsettings() log("xsettings_changed new value=%s", settings) if settings is not None: self.client.send("server-settings", {"xsettings-blob": settings}) def get_resource_manager(self): try: import gtk.gdk root = gtk.gdk.get_default_root_window() from xpra.x11.gtk_x11.prop import prop_get value = prop_get(root, "RESOURCE_MANAGER", "latin1", ignore_errors=True) if value is not None: return value.encode("utf-8") except: log.error("failed to get RESOURCE_MANAGER", exc_info=True) return None def _handle_root_prop_changed(self, obj, prop): log("root_prop_changed(%s, %s)", obj, prop) if prop == "RESOURCE_MANAGER": rm = self.get_resource_manager() if rm is not None: self.client.send("server-settings", {"resource-manager": rm}) elif prop == "_NET_WORKAREA": self.client.screen_size_changed("from %s event" % self._root_props_watcher) elif prop == "_NET_CURRENT_DESKTOP": self.client.workspace_changed("from %s event" % self._root_props_watcher) elif prop in ("_NET_DESKTOP_NAMES", "_NET_NUMBER_OF_DESKTOPS"): self.client.desktops_changed("from %s event" % self._root_props_watcher) else: log.error("unknown property %s", prop)