Skip to content

Commit

Permalink
#3592 move towards generic feature requests
Browse files Browse the repository at this point in the history
  • Loading branch information
totaam committed Sep 8, 2022
1 parent 70e1624 commit ff0a3d0
Show file tree
Hide file tree
Showing 17 changed files with 64 additions and 57 deletions.
14 changes: 9 additions & 5 deletions xpra/client/gobject_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,13 @@ def __init__(self, opts):
self.printing = False
self.command_timeout = None
#don't bother with many of these things for one-off commands:
for x in ("ui_client", "wants_aliases", "wants_encodings",
"wants_versions", "wants_features", "wants_sound", "windows",
"webcam", "keyboard", "mouse", "network-state",
for x in ("ui_client",
"wants_aliases", "wants_encodings", "wants_versions", "wants_features", "wants_sound",
"windows", "webcam", "keyboard", "mouse", "network-state",
):
self.hello_extra[x] = False
#for newer versions, it is easier:
self.hello_extra["wants"] = []

def setup_connection(self, conn):
protocol = super().setup_connection(conn)
Expand Down Expand Up @@ -391,8 +393,9 @@ class MonitorXpraClient(SendCommandConnectClient):

def __init__(self, opts):
super().__init__(opts)
for x in ("wants_features", "wants_events", "event_request"):
self.hello_extra[x] = True
for x in ("features", "events", "request"):
self.hello_extra[f"wants_{x}"] = True
self.hello_extra.setdefault("wants", []).append(x)
self.hello_extra["request"] = "event"
self.hello_extra["info-namespace"] = True

Expand Down Expand Up @@ -709,6 +712,7 @@ def do_command(self, caps : typedict):

def make_hello(self):
capabilities = super().make_hello()
capabilities.setdefault("wants", []).append("features")
capabilities["wants_features"] = True #so we know if printing is supported or not
capabilities["print_request"] = True #marker to skip full setup
capabilities["request"] = "print"
Expand Down
1 change: 1 addition & 0 deletions xpra/client/ui_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ def make_hello(self):
"xdg-menu-update", "mouse",
):
caps[x] = True
caps.setdefault("wants", []).append("events")
caps.update({
#generic server flags:
"share" : self.client_supports_sharing,
Expand Down
4 changes: 2 additions & 2 deletions xpra/server/gtk_server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,15 @@ def do_run(self):

def make_hello(self, source):
capabilities = super().make_hello(source)
if source.wants_display:
if "display" in source.wants:
display = Gdk.Display.get_default()
max_size = tuple(display.get_maximal_cursor_size())
capabilities.update({
"display" : display.get_name(),
"cursor.default_size" : display.get_default_cursor_size(),
"cursor.max_size" : max_size,
})
if source.wants_versions and FULL_INFO>2:
if "versions" in source.wants and FULL_INFO>2:
capabilities.update(flatten_dict(get_gtk_version_info()))
return capabilities

Expand Down
3 changes: 2 additions & 1 deletion xpra/server/mixins/child_command_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ def get_caps(self, source) -> dict:
if not source:
return caps
#don't assume we have a real ClientConnection object:
if getattr(source, "wants_features", False) and getattr(source, "ui_client", False):
wants = getattr(source, "wants", [])
if "feature" in wants and getattr(source, "ui_client", False):
caps["xdg-menu"] = {}
if not source.xdg_menu_update:
log.warn("Warning: outdated client does not support xdg-menu update")
Expand Down
10 changes: 5 additions & 5 deletions xpra/server/server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,12 +510,12 @@ def make_hello(self, source):
if c!=ServerCore:
merge_dicts(capabilities, c.get_caps(self, source))
capabilities["server_type"] = "base"
if source.wants_display:
if "display" in source.wants:
capabilities.update({
"max_desktop_size" : self.get_max_screen_size(),
"display" : os.environ.get("DISPLAY", "Main"),
})
if source.wants_features:
if "features" in source.wants:
capabilities.update({
"client-shutdown" : self.client_shutdown,
"sharing" : self.sharing is not False,
Expand All @@ -535,7 +535,7 @@ def make_hello(self, source):

def send_hello(self, server_source, root_w, root_h, server_cipher):
capabilities = self.make_hello(server_source)
if server_source.wants_encodings and server_features.windows:
if "encodings" in server_source.wants and server_features.windows:
try:
from xpra.codecs.loader import codec_versions
except ImportError:
Expand Down Expand Up @@ -564,12 +564,12 @@ def send_encoding_caps():
#check for mmap:
if getattr(self, "mmap_size", 0)==0:
self.after_threaded_init(server_source.print_encoding_info)
if server_source.wants_display:
if "display" in server_source.wants:
capabilities.update({
"actual_desktop_size" : (root_w, root_h),
"root_window_size" : (root_w, root_h),
})
if self._aliases and server_source.wants_aliases:
if "aliases" in self._aliases and server_source.wants:
reverse_aliases = {}
for i, packet_type in self._aliases.items():
reverse_aliases[packet_type] = i
Expand Down
6 changes: 3 additions & 3 deletions xpra/server/server_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2160,7 +2160,7 @@ def server_idle_timedout(self):
def make_hello(self, source=None):
now = time()
capabilities = flatten_dict(get_network_caps(FULL_INFO))
if source is None or source.wants_versions:
if source is None or "versions" in source.wants:
capabilities.update(flatten_dict(self.get_minimal_server_info()))
capabilities.update({
"version" : vparts(XPRA_VERSION, FULL_INFO+1),
Expand All @@ -2171,13 +2171,13 @@ def make_hello(self, source=None):
"server.mode" : self.get_server_mode(),
"hostname" : socket.gethostname(),
})
if source is None or source.wants_features:
if source is None or "features" in source.wants:
capabilities.update({
"readonly-server" : True,
"readonly" : self.readonly,
"server-log" : os.environ.get("XPRA_SERVER_LOG", ""),
})
if source is None or source.wants_versions:
if source is None or "versions" in source.wants:
capabilities["uuid"] = get_user_uuid()
mid = get_machine_id()
if mid:
Expand Down
2 changes: 1 addition & 1 deletion xpra/server/shadow/gtk_shadow_server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def last_client_exited(self):
def make_hello(self, source):
caps = ShadowServerBase.make_hello(self, source)
caps.update(GTKServerBase.make_hello(self, source))
if source.wants_features:
if "features" in source.wants:
caps["screen_sizes"] = get_screen_sizes()
return caps

Expand Down
2 changes: 1 addition & 1 deletion xpra/server/source/audio_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def stop_new_stream_notification(self, proc):


def parse_client_caps(self, c):
self.wants_sound = c.boolget("wants_sound", True)
self.wants_sound = c.boolget("wants_sound", True) or "sound" in c.strtupleget("wants")
audio = c.dictget("audio")
if audio:
audio = typedict(audio)
Expand Down
11 changes: 3 additions & 8 deletions xpra/server/source/client_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,8 @@ def init_state(self):
self.ssh_auth_sock = ""
#what we send back in hello packet:
self.ui_client = True
self.wants_aliases = True
self.wants_encodings = False
self.wants_versions = True
self.wants_features = True
self.wants_display = True
self.wants_events = False
self.wants_default_cursor = False
#default 'wants' is not including "events" or "default_cursor":
self.wants = ["aliases", "encodings", "versions", "features", "display"]
#these statistics are shared by all WindowSource instances:
self.statistics = GlobalPerformanceStatistics()

Expand Down Expand Up @@ -395,7 +390,7 @@ def send_setting_change(self, setting, value):


def send_server_event(self, *args):
if self.wants_events:
if "events" in self.wants:
self.send_more("server-event", *args)


Expand Down
20 changes: 13 additions & 7 deletions xpra/server/source/client_connection_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@


def get_client_connection_class(caps):
# pylint: disable=import-outside-toplevel
from xpra.server.source.clientinfo_mixin import ClientInfoMixin
CC = [ClientInfoMixin]
if server_features.notifications:
Expand Down Expand Up @@ -133,13 +134,18 @@ def module_name(m):

def parse_hello(self, c : typedict):
self.ui_client = c.boolget("ui_client", True)
self.wants_encodings = c.boolget("wants_encodings", self.ui_client)
self.wants_display = c.boolget("wants_display", self.ui_client)
self.wants_events = c.boolget("wants_events", False)
self.wants_aliases = c.boolget("wants_aliases", True)
self.wants_versions = c.boolget("wants_versions", True)
self.wants_features = c.boolget("wants_features", True)
self.wants_default_cursor = c.boolget("wants_default_cursor", False)
self.wants = list(c.strtupleget("wants"), self.wants)
for x, default_value in {
"encodings" : self.ui_client,
"display" : self.ui_client,
"events" : False,
"aliases" : True,
"versions" : True,
"features" : True,
"default_cursor" : False,
}.items():
if c.boolget(f"wants_{x}", default_value):
self.wants.append(x)
for bc in CC_BASES:
log("%s.parse_client_caps(..)", bc)
bc.parse_client_caps(self, c)
Expand Down
7 changes: 2 additions & 5 deletions xpra/server/source/encodings_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ def is_needed(cls, caps : typedict) -> bool:
return bool(caps.strtupleget("encodings"))

def init_state(self):
self.wants_encodings = False
self.wants_features = False

#contains default values, some of which may be supplied by the client:
self.default_batch_config = batch_config.DamageBatchConfig()
self.global_batch_config = self.default_batch_config.clone() #global batch config
Expand Down Expand Up @@ -113,9 +110,9 @@ def all_window_sources(self):

def get_caps(self) -> dict:
caps = {}
if self.wants_encodings and self.encoding:
if "encodings" in self.wants and self.encoding:
caps["encoding"] = self.encoding
if self.wants_features:
if "features" in self.wants:
caps.update({
"auto_refresh_delay" : self.auto_refresh_delay,
})
Expand Down
20 changes: 11 additions & 9 deletions xpra/server/source/windows_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,22 +248,24 @@ def send_cursor(self):
gbc = self.global_batch_config
if not self.cursor_timer and gbc:
delay = max(10, int(gbc.delay/4))
self.cursor_timer = self.timeout_add(delay, self.do_send_cursor, delay)
def do_send_cursor():
self.cursor_timer = None
cd = self.get_cursor_data_cb()
if not cd or not cd[0]:
self.send_empty_cursor()
return
cursor_data = list(cd[0])
cursor_sizes = cd[1]
self.do_send_cursor(delay, cursor_data, cursor_sizes)
self.cursor_timer = self.timeout_add(delay, do_send_cursor)

def cancel_cursor_timer(self):
ct = self.cursor_timer
if ct:
self.cursor_timer = None
self.source_remove(ct)

def do_send_cursor(self, delay):
self.cursor_timer = None
cd = self.get_cursor_data_cb()
if not cd or not cd[0]:
self.send_empty_cursor()
return
cursor_data = list(cd[0])
cursor_sizes = cd[1]
def do_send_cursor(self, delay, cursor_data, cursor_sizes):
#skip first two fields (if present) as those are coordinates:
if self.last_cursor_sent and self.last_cursor_sent[2:9]==cursor_data[2:9]:
cursorlog("do_send_cursor(..) cursor identical to the last one we sent, nothing to do")
Expand Down
2 changes: 1 addition & 1 deletion xpra/x11/desktop/desktop_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def get_server_mode(self):

def make_hello(self, source):
capabilities = super().make_hello(source)
if source.wants_features:
if "features" in source.wants:
capabilities.update({
"desktop" : True,
})
Expand Down
2 changes: 1 addition & 1 deletion xpra/x11/desktop/desktop_server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def get_server_mode(self):

def make_hello(self, source):
capabilities = super().make_hello(source)
if source.wants_features:
if "features" in source.wants:
capabilities.update({
"pointer.grabs" : True,
"desktop" : True,
Expand Down
2 changes: 1 addition & 1 deletion xpra/x11/desktop/monitor_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def get_server_mode(self):

def make_hello(self, source):
capabilities = super().make_hello(source)
if source.wants_features:
if "features" in source.wants:
capabilities.update({
"monitor" : True,
"multi-monitors" : True,
Expand Down
4 changes: 2 additions & 2 deletions xpra/x11/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def __init__(self, clobber):

def init(self, opts):
self.wm_name = opts.wm_name
self.sync_xvfb = int(opts.sync_xvfb)
self.sync_xvfb = int(opts.sync_xvfb or 0)
self.system_tray = opts.system_tray
self._exit_with_windows = opts.exit_with_windows
super().init(opts)
Expand Down Expand Up @@ -249,7 +249,7 @@ def server_event(self, *args):

def make_hello(self, source):
capabilities = super().make_hello(source)
if source.wants_features:
if "features" in source.wants:
capabilities["pointer.grabs"] = True
updict(capabilities, "window", {
"decorations" : True, #v4 clients assume this is enabled
Expand Down
11 changes: 6 additions & 5 deletions xpra/x11/x11_server_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ def set_keyboard_repeat(self, key_repeat):
def make_hello(self, source):
capabilities = super().make_hello(source)
capabilities["server_type"] = "Python/gtk/x11"
if source.wants_features:
if "features" in source.wants:
capabilities.update({
"resize_screen" : self.randr,
"resize_exact" : self.randr_exact_size,
Expand All @@ -349,7 +349,7 @@ def make_hello(self, source):
sizes = self.get_all_screen_sizes()
if len(sizes)>1:
capabilities["screen-sizes"] = sizes
if self.default_cursor_image and source.wants_default_cursor:
if self.default_cursor_image and "default_cursor" in source.wants:
capabilities["cursor.default"] = self.default_cursor_image
return capabilities

Expand Down Expand Up @@ -502,16 +502,17 @@ def get_cursor_image(self):
with xlog:
return X11Keyboard.get_cursor_image()

def get_cursor_data(self):
def get_cursor_data(self, skip_default=True):
#must be called from the UI thread!
cursor_image = self.get_cursor_image()
if cursor_image is None:
cursorlog("get_cursor_data() failed to get cursor image")
return None, []
self.last_cursor_image = cursor_image
self.last_cursor_image = list(cursor_image)
pixels = self.last_cursor_image[7]
cursorlog("get_cursor_image() cursor=%s", cursor_image[:7]+["%s bytes" % len(pixels)]+cursor_image[8:])
if self.default_cursor_image is not None and str(pixels)==str(self.default_cursor_image[7]):
is_default = self.default_cursor_image is not None and str(pixels)==str(self.default_cursor_image[7])
if skip_default and is_default:
cursorlog("get_cursor_data(): default cursor - clearing it")
cursor_image = None
cursor_sizes = self.get_cursor_sizes()
Expand Down

0 comments on commit ff0a3d0

Please sign in to comment.