Beispiel #1
0
 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
Beispiel #2
0
 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
Beispiel #3
0
 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)
Beispiel #4
0
 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
Beispiel #5
0
    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)
Beispiel #6
0
    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), )
Beispiel #7
0
    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)
Beispiel #8
0
 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
Beispiel #9
0
 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