def get_menu_data(self, force_reload=False, remove_icons=False, wait=True): log("get_menu_data%s", (force_reload, remove_icons, wait)) if not EXPORT_XDG_MENU_DATA: return None if OSX: return None menu_data = self.menu_data if self.load_lock.acquire(wait): try: if not self.menu_data or force_reload: if POSIX: from xpra.platform.xposix.xdg_helper import load_xdg_menu_data menu_data = load_xdg_menu_data() elif WIN32: from xpra.platform.win32.menu_helper import load_menu menu_data = load_menu() else: log.error("Error: unsupported platform!") return None self.menu_data = menu_data add_work_item(self.got_menu_data) finally: self.load_lock.release() if remove_icons and self.menu_data: menu_data = noicondata(self.menu_data) return menu_data
def cleanup_protocol(self, protocol): netlog("cleanup_protocol(%s)", protocol) #this ensures that from now on we ignore any incoming packets coming #from this connection as these could potentially set some keys pressed, etc try: self._potential_protocols.remove(protocol) except ValueError: pass source = self._server_sources.pop(protocol, None) if source: self.cleanup_source(source) add_work_item(self.mdns_update) for c in SERVER_BASES: c.cleanup_protocol(self, protocol) return source
def may_recalculate(self, wid, pixel_count): if wid in self.calculate_window_ids: return #already scheduled v = self.calculate_window_pixels.get(wid, 0)+pixel_count self.calculate_window_pixels[wid] = v if v<MIN_PIXEL_RECALCULATE: return #not enough pixel updates statslog("may_recalculate(%i, %i) total %i pixels, scheduling recalculate work item", wid, pixel_count, v) self.calculate_window_ids.add(wid) if self.calculate_timer: #already due return delta = monotonic_time() - self.calculate_last_time RECALCULATE_DELAY = 1.0 #1s if delta>RECALCULATE_DELAY: add_work_item(self.recalculate_delays) else: self.calculate_timer = self.timeout_add(int(1000*(RECALCULATE_DELAY-delta)), add_work_item, self.recalculate_delays)
def get_menu_data(self, force_reload=False, remove_icons=False, wait=True): log("get_menu_data%s", (force_reload, remove_icons, wait)) if not EXPORT_XDG_MENU_DATA: return None if OSX: return None menu_data = self.menu_data if self.load_lock.acquire(wait): menu_data = self.menu_data try: if not self.menu_data or force_reload: from xpra.platform.menu_helper import load_menu #pylint: disable=import-outside-toplevel self.menu_data = load_menu() add_work_item(self.got_menu_data) finally: self.load_lock.release() if remove_icons and self.menu_data: menu_data = noicondata(self.menu_data) return menu_data
def test_run(self): assert get_worker(False) is None w = get_worker() assert repr(w) def error_item(): raise Exception("work item test error") add_work_item(error_item) def slow_item(): time.sleep(1) #trigger the warning with more than 10 items: for _ in range(11): w.add(slow_item) stop_worker() stop_worker(True) #no-op: stop_worker(True) #let the worker print its messages: time.sleep(1)
def test_run(self): assert get_worker(False) is None w = get_worker() assert repr(w) def error_item(): raise Exception("work item test error") with silence_error(background_worker): add_work_item(error_item) time.sleep(0.1) #add the same item twice, with "no-duplicates" #(should only get added once) ndc = [] def nodupe(): ndc.append(True) w.add(nodupe, False) w.add(nodupe, False) time.sleep(1) with LoggerSilencer(background_worker, ("warn", "info")): #trigger the warning with more than 10 items: def slow_item(): time.sleep(1) for _ in range(12): w.add(slow_item) stop_worker() stop_worker(True) #no-op: stop_worker(True) #let the worker print its messages: time.sleep(1) assert len( ndc) == 1, "nodupe item should have been run once only, got %i" % ( len(ndc), )
def hello_oked(self, proto, packet, c, auth_caps): if self._server_sources.get(proto): log.warn("Warning: received another 'hello' packet") log.warn(" from an existing connection: %s", proto) return if ServerCore.hello_oked(self, proto, packet, c, auth_caps): #has been handled return if not self.sanity_checks(proto, c): return if not c.boolget("steal", True) and self._server_sources: self.disconnect_client(proto, SESSION_BUSY, "this session is already active") return if c.boolget("screenshot_request"): self.send_screenshot(proto) return #added in 2.2: request = c.strget("request") def is_req(mode): return request == mode or c.boolget("%s_request" % mode, False) if not request: #"normal" connection, so log welcome message: log.info("Handshake complete; enabling connection") else: log("handling request %s", request) self.server_event("handshake-complete") # Things are okay, we accept this connection, and may disconnect previous one(s) # (but only if this is going to be a UI session - control sessions can co-exist) ui_client = c.boolget("ui_client", True) share = c.boolget("share") uuid = c.strget("uuid") detach_request = is_req("detach") accepted, share_count, disconnected = self.handle_sharing( proto, ui_client, detach_request, share, uuid) if not accepted: return if is_req("detach"): self.disconnect_client( proto, DONE, "%i other clients have been disconnected" % disconnected) return if not request and ui_client: #a bit of explanation: #normally these things are synchronized using xsettings, which we handle already #but non-posix clients have no such thing, #and we don't want to expose that as an interface #(it's not very nice and it is very X11 specific) #also, clients may want to override what is in their xsettings.. #so if the client specifies what it wants to use, we patch the xsettings with it #(the actual xsettings part is done in update_all_server_settings in the X11 specific subclasses) if share_count > 0: log.info("sharing with %s other client(s)", share_count) self.dpi = 0 self.xdpi = 0 self.ydpi = 0 self.double_click_time = -1 self.double_click_distance = -1, -1 self.antialias = {} self.cursor_size = 24 else: self.dpi = c.intget("dpi", 0) self.xdpi = c.intget("dpi.x", 0) self.ydpi = c.intget("dpi.y", 0) self.double_click_time = c.intget("double_click.time", -1) self.double_click_distance = c.intpair("double_click.distance", (-1, -1)) self.antialias = c.dictget("antialias", {}) self.cursor_size = c.intget("cursor.size", 0) #FIXME: this belongs in DisplayManager! screenlog( "dpi=%s, dpi.x=%s, dpi.y=%s, antialias=%s, cursor_size=%s", self.dpi, self.xdpi, self.ydpi, self.antialias, self.cursor_size) log("double-click time=%s, distance=%s", self.double_click_time, self.double_click_distance) #if we're not sharing, reset all the settings: reset = share_count == 0 self.update_all_server_settings(reset) self.accept_client(proto, c) #use blocking sockets from now on: if not WIN32: set_socket_timeout(proto._conn, None) def drop_client(reason="unknown", *args): self.disconnect_client(proto, reason, *args) cc_class = self.get_client_connection_class(c) ss = cc_class( proto, drop_client, self.session_name, self, self.idle_add, self.timeout_add, self.source_remove, self.setting_changed, self._socket_dir, self.unix_socket_paths, not request, self.bandwidth_limit, self.bandwidth_detection, ) log("process_hello clientconnection=%s", ss) try: ss.parse_hello(c) except: #close it already ss.close() raise self._server_sources[proto] = ss add_work_item(self.mdns_update) #process ui half in ui thread: send_ui = ui_client and not request self.idle_add(self._process_hello_ui, ss, c, auth_caps, send_ui, share_count)
def do_video_encoder_cleanup(self): #MUST be called with video lock held! if self._video_encoder is None: return add_work_item(self._video_encoder.clean) self._video_encoder = None
def do_video_encoder_cleanup(self): #MUST be called with video lock held! if self._video_encoder is None: return add_work_item(self._video_encoder.clean) self._video_encoder = None