Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
 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")
Ejemplo n.º 5
0
def main():
    ROOT_PROPS = ["RESOURCE_MANAGER", "_NET_WORKAREA"]
    xrpw = XRootPropWatcher(ROOT_PROPS)
    gobject.timeout_add(1000, xrpw.notify_all)
    try:
        gtk.main()
    finally:
        xrpw.cleanup()
Ejemplo n.º 6
0
def main():
    ROOT_PROPS = ["RESOURCE_MANAGER", "_NET_WORKAREA"]
    root = gtk.gdk.get_default_root_window()
    xrpw = XRootPropWatcher(ROOT_PROPS, root)
    gobject.timeout_add(1000, xrpw.notify_all)
    try:
        gtk.main()
    finally:
        xrpw.cleanup()
Ejemplo n.º 7
0
def main():
    logging.basicConfig(format="%(asctime)s %(message)s")
    logging.root.setLevel(logging.INFO)

    ROOT_PROPS = ["RESOURCE_MANAGER", "_NET_WORKAREA"]
    xrpw = XRootPropWatcher(ROOT_PROPS)
    gobject.timeout_add(1000, xrpw.notify_all)
    try:
        gtk.main()
    finally:
        xrpw.cleanup()
Ejemplo n.º 8
0
 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)
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
 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)
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
 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)
Ejemplo n.º 14
0
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)
Ejemplo n.º 15
0
 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)
Ejemplo n.º 16
0
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)
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
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)
Ejemplo n.º 19
0
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)
Ejemplo n.º 20
0
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)