def __init__(self): gobject.GObject.__init__(self) RFBServer.__init__(self) X11ServerBase.__init__(self) self.session_type = "desktop" self.resize_timer = None self.resize_value = None
def server_init(self): X11ServerBase.server_init(self) screenlog("server_init() randr=%s", self.randr) if self.randr: from xpra.x11.vfb_util import set_initial_resolution, DEFAULT_DESKTOP_VFB_RESOLUTION with xlog: set_initial_resolution(self.initial_resolution or DEFAULT_DESKTOP_VFB_RESOLUTION)
def init(self, opts): X11ServerBase.init(self, opts) if not parse_bool("rfb-upgrade", opts.rfb_upgrade): self._rfb_upgrade = 0 else: self._rfb_upgrade = parse_number(int, "rfb-upgrade", opts.rfb_upgrade, 0)
def do_cleanup(self): self.cancel_resize_timer() X11ServerBase.do_cleanup(self) remove_catchall_receiver("xpra-motion-event", self) cleanup_x11_filter() with xswallow: cleanup_all_event_receivers()
def x11_init(self): X11ServerBase.x11_init(self) init_x11_filter() self._has_focus = 0 # Do this before creating the Wm object, to avoid clobbering its # selecting SubstructureRedirect. root = gtk.gdk.get_default_root_window() root.set_events(root.get_events() | gtk.gdk.SUBSTRUCTURE_MASK) root.property_change(gtk.gdk.atom_intern("XPRA_SERVER", False), gtk.gdk.atom_intern("STRING", False), 8, gtk.gdk.PROP_MODE_REPLACE, xpra.__version__) add_event_receiver(root, self) ### Create the WM object self._wm = Wm(self.clobber) self._wm.connect("new-window", self._new_window_signaled) self._wm.connect("bell", self._bell_signaled) self._wm.connect("quit", lambda _: self.quit(True)) self.default_cursor_data = None self.last_cursor_serial = None self.send_cursor_pending = False self.cursor_data = None self.cursor_sizes = None def get_default_cursor(): self.default_cursor_data = X11Keyboard.get_cursor_image() log("get_default_cursor=%s", self.default_cursor_data) trap.swallow_synced(get_default_cursor) self._wm.enableCursors(True)
def _process_mouse_common(self, proto, wid, pointer, modifiers): #adjust pointer position for offset in client: x, y = pointer wx, wy = self.mapped_at[:2] pointer = x - wx, y - wy X11ServerBase._process_mouse_common(self, proto, wid, pointer, modifiers)
def _move_pointer(self, wid, pos): window = self._id_to_window.get(wid) if not window: log("_process_mouse_common() invalid window id: %s", wid) else: window.raise_window() X11ServerBase._move_pointer(self, wid, pos)
def _move_pointer(self, wid, pos): window = self._id_to_window.get(wid) if not window: mouselog("_move_pointer(%s, %s) invalid window id", wid, pos) else: mouselog("raising %s", window) window.raise_window() X11ServerBase._move_pointer(self, wid, pos)
def _move_pointer(self, wid, pos): if wid>=0: window = self._id_to_window.get(wid) if not window: mouselog("_move_pointer(%s, %s) invalid window id", wid, pos) else: #TODO: just like shadow server, adjust for window position pass X11ServerBase._move_pointer(self, wid, pos)
def __init__(self, clobber=False): X11ServerBase.__init__(self, clobber) for c in DESKTOPSERVER_BASES: if c!=X11ServerBase: c.__init__(self) self.session_type = "desktop" self.resize_timer = None self.resize_value = None self.gsettings_modified = {}
def cleanup_source(self, protocol): had_client = len(self._server_sources)>0 X11ServerBase.cleanup_source(self, protocol) has_client = len(self._server_sources)>0 if had_client and not has_client: #last client is gone: self.reset_settings() if self._has_grab: self.X11_ungrab()
def cleanup_source(self, protocol): had_client = len(self._server_sources) > 0 X11ServerBase.cleanup_source(self, protocol) has_client = len(self._server_sources) > 0 if had_client and not has_client: #last client is gone: self.reset_settings() if self._has_grab: self.X11_ungrab()
def x11_init(self): X11ServerBase.x11_init(self) assert init_x11_filter() is True display = gtk.gdk.display_get_default() screens = display.get_n_screens() for n in range(screens): screen = display.get_screen(n) root = screen.get_root_window() add_event_receiver(root, self) add_catchall_receiver("xpra-motion-event", self) add_catchall_receiver("xpra-xkb-event", self) X11Keyboard.selectBellNotification(True)
def send_updated_screen_size(self): log("send_updated_screen_size") X11ServerBase.send_updated_screen_size(self) for wid, window in self._id_to_window.items(): w, h = window.get_dimensions() geomlog("%i new window dimensions: %s", wid, (w, h)) for ss in self._server_sources.values(): #first, make sure the size-hints are updated: ss.window_metadata(wid, window, "size-hints") #tell client to resize now: ss.resize_window(wid, window, w, h) #refresh to ensure the client gets the new window contents: ss.damage(wid, window, 0, 0, w, h)
def _set_client_properties(self, proto, wid, window, new_client_properties): """ Override so we can update the workspace on the window directly, instead of storing it as a client property """ workspace = new_client_properties.get("workspace") workspacelog("workspace from client properties %s: %s", new_client_properties, workspace) if workspace is not None: window.move_to_workspace(workspace) #we have handled it on the window directly, so remove it from client properties del new_client_properties["workspace"] #handle the rest as normal: X11ServerBase._set_client_properties(self, proto, wid, window, new_client_properties)
def load_existing_windows(self): #at present, just one window is forwarded: #the root window covering the whole display display = gtk.gdk.display_get_default() screens = display.get_n_screens() for n in range(screens): screen = display.get_screen(n) root = screen.get_root_window() model = DesktopModel(root) model.setup() windowlog("adding root window model %s", model) X11ServerBase._add_new_window_common(self, model) model.managed_connect("client-contents-changed", self._contents_changed) model.managed_connect("resized", self._window_resized_signaled)
def x11_init(self): X11ServerBase.x11_init(self) display = Gdk.Display.get_default() screens = display.get_n_screens() for n in range(screens): screen = display.get_screen(n) root = screen.get_root_window() add_event_receiver(root, self) add_catchall_receiver("xpra-motion-event", self) add_catchall_receiver("xpra-xkb-event", self) with xlog: X11Keyboard.selectBellNotification(True) if MODIFY_GSETTINGS: self.modify_gsettings()
def cleanup(self, *args): if self._tray: self._tray.cleanup() self._tray = None X11ServerBase.cleanup(self) cleanup_x11_filter() cleanup_all_event_receivers() if self._wm: self._wm.cleanup() self._wm = None if self._has_grab: #normally we set this value when we receive the NotifyUngrab #but at this point in the cleanup, we probably won't, so force set it: self._has_grab = 0 self.X11_ungrab()
def get_window_info(self, window): info = X11ServerBase.get_window_info(self, window) info["focused"] = self._has_focus and self._window_to_id.get( window, -1) == self._has_focus info["grabbed"] = self._has_grab and self._window_to_id.get( window, -1) == self._has_grab return info
def do_cleanup(self): self.cancel_resize_timer() X11ServerBase.do_cleanup(self) remove_catchall_receiver("xpra-motion-event", self) cleanup_x11_filter() #try a few times: #errors happen because windows are being destroyed #(even more so when we cleanup) #and we don't really care too much about this for l in (log, log, log, log, log.warn): try: with xsync: cleanup_all_event_receivers() #all went well, we're done return except Exception as e: l("failed to remove event receivers: %s", e)
def make_hello(self, source): capabilities = X11ServerBase.make_hello(self, source) if source.wants_features: capabilities["window.raise"] = True capabilities["window.resize-counter"] = True capabilities["window.configure.skip-geometry"] = True capabilities["pointer.grabs"] = True return capabilities
def _add_new_window_common(self, window): wid = X11ServerBase._add_new_window_common(self, window) window.managed_connect("client-contents-changed", self._contents_changed) window.managed_connect("unmanaged", self._lost_window) window.managed_connect("raised", self._raised_window) window.managed_connect("pointer-grab", self._pointer_grab) window.managed_connect("pointer-ungrab", self._pointer_ungrab) return wid
def x11_init(self): X11ServerBase.x11_init(self) assert init_x11_filter() is True self._has_grab = 0 self._has_focus = 0 # Do this before creating the Wm object, to avoid clobbering its # selecting SubstructureRedirect. root = gtk.gdk.get_default_root_window() root.set_events(root.get_events() | gtk.gdk.SUBSTRUCTURE_MASK) root.property_change(gtk.gdk.atom_intern("XPRA_SERVER", False), gtk.gdk.atom_intern("STRING", False), 8, gtk.gdk.PROP_MODE_REPLACE, xpra.__version__) add_event_receiver(root, self) ### Create the WM object self._wm = Wm(self.clobber, self.wm_name) self._wm.connect("new-window", self._new_window_signaled) self._wm.connect("bell", self._bell_signaled) self._wm.connect("quit", lambda _: self.clean_quit(True)) self._wm.connect("show-desktop", self._show_desktop) #save default xsettings: self.default_xsettings = XSettingsHelper().get_settings() settingslog("default_xsettings=%s", self.default_xsettings) self._settings = {} self._xsettings_manager = None #for handling resize synchronization between client and server (this is not xsync!): self.last_client_configure_event = 0 self.snc_timer = 0 #cursor: self.default_cursor_data = None self.last_cursor_serial = None self.last_cursor_data = None self.send_cursor_pending = False def get_default_cursor(): self.default_cursor_data = X11Keyboard.get_cursor_image() cursorlog("get_default_cursor=%s", self.default_cursor_data) trap.swallow_synced(get_default_cursor) self._wm.enableCursors(True)
def get_ui_info(self, proto, wids, *args): info = X11ServerBase.get_ui_info(self, proto, wids, *args) #now cursor size info: display = gtk.gdk.display_get_default() for prop, size in {"default" : display.get_default_cursor_size(), "max" : display.get_maximal_cursor_size()}.items(): if size is None: continue info["cursor.%s_size" % prop] = size return info
def _add_new_window_common(self, window): windowlog("adding window %s", window) for prop in window.get_dynamic_property_names(): window.connect("notify::%s" % prop, self._update_metadata) wid = X11ServerBase._add_new_window_common(self, window) window.managed_connect("client-contents-changed", self._contents_changed) window.managed_connect("unmanaged", self._lost_window) window.managed_connect("raised", self._raised_window) window.managed_connect("initiate-moveresize", self._initiate_moveresize) window.managed_connect("grab", self._window_grab) window.managed_connect("ungrab", self._window_ungrab) return wid
def poll_cursor(self): prev = self.last_cursor_data X11ServerBase.get_cursor_data(self) def cmpv(v): if v and len(v) > 2: return v[2:] return None if cmpv(prev) != cmpv(self.last_cursor_data): fields = ("x", "y", "width", "height", "xhot", "yhot", "serial", "pixels", "name") if len(prev or []) == len(self.last_cursor_data or []) and len( prev or []) == len(fields): diff = [] for i in range(len(prev)): if prev[i] != self.last_cursor_data[i]: diff.append(fields[i]) cursorlog("poll_cursor() attributes changed: %s", diff) for ss in self._server_sources.values(): ss.send_cursor() return True
def make_hello(self, source): capabilities = X11ServerBase.make_hello(self, source) if source.wants_features: capabilities.update({ "pointer.grabs" : True, "desktop" : True, }) updict(capabilities, "window", { "decorations" : True, "resize-counter" : True, "configure.skip-geometry": True, "configure.pointer" : True, }) return capabilities
def get_ui_info(self, proto, wids, *args): info = X11ServerBase.get_ui_info(self, proto, wids, *args) #_NET_WM_NAME: wm = self._wm if wm: info["window-manager-name"] = wm.get_net_wm_name() #now cursor size info: display = gtk.gdk.display_get_default() pos = display.get_default_screen().get_root_window().get_pointer()[:2] info["cursor.position"] = pos for prop, size in {"default" : display.get_default_cursor_size(), "max" : display.get_maximal_cursor_size()}.items(): if size is None: continue info["cursor.%s_size" % prop] = size return info
def make_hello(self, source): capabilities = X11ServerBase.make_hello(self, source) if source.wants_features: capabilities.update({ "pointer.grabs": True, "desktop": True, }) updict( capabilities, "window", { "decorations": True, "resize-counter": True, "configure.skip-geometry": True, "configure.pointer": True, "states": ["iconified", "focused"], }) capabilities["screen_sizes"] = get_screen_sizes() return capabilities
def do_get_info(self, proto, server_sources, window_ids): info = X11ServerBase.do_get_info(self, proto, server_sources, window_ids) log("do_get_info: adding cursor=%s", self.cursor_data) #copy to prevent race: cd = self.cursor_data if cd is None: info["cursor"] = "None" else: info["cursor.is_default"] = bool(self.default_cursor_data and len(self.default_cursor_data)>=8 and len(cd)>=8 and cd[7]==cd[7]) #all but pixels: i = 0 for x in ("x", "y", "width", "height", "xhot", "yhot", "serial", None, "name"): if x: v = cd[i] or "" info["cursor." + x] = v i += 1 return info
def do_get_info(self, proto, server_sources, window_ids): info = X11ServerBase.do_get_info(self, proto, server_sources, window_ids) info["focused"] = self._has_focus info["grabbed"] = self._has_grab log("do_get_info: adding cursor=%s", self.last_cursor_data) #copy to prevent race: cd = self.last_cursor_data if cd is None: info["cursor"] = "None" else: info["cursor.is_default"] = bool(self.default_cursor_data and len(self.default_cursor_data)>=8 and len(cd)>=8 and cd[7]==cd[7]) #all but pixels: for i, x in enumerate(("x", "y", "width", "height", "xhot", "yhot", "serial", None, "name")): if x: v = cd[i] or "" info["cursor." + x] = v return info
def get_ui_info(self, proto, wids, *args): info = X11ServerBase.get_ui_info(self, proto, wids, *args) #_NET_WM_NAME: wm = self._wm if wm: info["window-manager-name"] = wm.get_net_wm_name() #now cursor size info: display = gtk.gdk.display_get_default() pos = display.get_default_screen().get_root_window().get_pointer()[:2] info["cursor.position"] = pos for prop, size in { "default": display.get_default_cursor_size(), "max": display.get_maximal_cursor_size() }.items(): if size is None: continue info["cursor.%s_size" % prop] = size return info
def do_get_info(self, proto, server_sources, window_ids): info = X11ServerBase.do_get_info(self, proto, server_sources, window_ids) info["focused"] = self._has_focus info["grabbed"] = self._has_grab log("do_get_info: adding cursor=%s", self.last_cursor_data) #copy to prevent race: cd = self.last_cursor_data if cd is None: info["cursor"] = "None" else: info["cursor.is_default"] = bool( self.default_cursor_data and len(self.default_cursor_data) >= 8 and len(cd) >= 8 and cd[7] == cd[7]) #all but pixels: for i, x in enumerate(("x", "y", "width", "height", "xhot", "yhot", "serial", None, "name")): if x: v = cd[i] or "" info["cursor." + x] = v return info
def get_info(self, proto): info = X11ServerBase.get_info(self, proto) info.setdefault("features", {})["shadow"] = True info.setdefault("server", {})["type"] = "Python/gtk2/x11-shadow" return info
def make_hello(self): capabilities = X11ServerBase.make_hello(self) capabilities["window.raise"] = True capabilities["pointer.grabs"] = True return capabilities
def get_info(self, proto): info = X11ServerBase.get_info(self, proto) info["features.shadow"] = True info["server.type"] = "Python/gtk2/x11-shadow" return info
def get_window_info(self, window): info = X11ServerBase.get_window_info(self, window) info["focused"] = self._window_to_id.get(window, -1)==self._has_focus return info
def init(self, clobber, opts): X11ServerBase.init(self, clobber, opts)
def __init__(self): gobject.GObject.__init__(self) X11ServerBase.__init__(self)
def init(self, opts): GTKShadowServerBase.init(self, opts) X11ServerBase.init(self, opts)
def __init__(self): GTKShadowServerBase.__init__(self) X11ServerBase.__init__(self, False)
def cleanup(self, *args): if self._tray: self._tray.cleanup() self._tray = None X11ServerBase.cleanup(self)
def _process_mouse_common(self, proto, wid, pointer): pointer = self._adjust_pointer(pointer) X11ServerBase._process_mouse_common(self, proto, wid, pointer)
def last_client_exited(self): GTKShadowServerBase.last_client_exited(self) X11ServerBase.last_client_exited(self)
def make_hello(self, source): capabilities = X11ServerBase.make_hello(self, source) capabilities.update(GTKShadowServerBase.make_hello(self, source)) capabilities["server_type"] = "Python/gtk2/x11-shadow" return capabilities