Skip to content

Commit

Permalink
#3519 use 'scroll' encoding more judiciously
Browse files Browse the repository at this point in the history
  • Loading branch information
totaam committed Apr 13, 2022
1 parent d41e280 commit f67fbd8
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 9 deletions.
4 changes: 2 additions & 2 deletions xpra/platform/darwin/shadow_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,9 @@ def do_process_button_action(self, proto, wid, button, pressed, pointer, modifie
self._update_modifiers(proto, wid, modifiers)
pointer = self._process_mouse_common(proto, wid, pointer)
if pointer:
self.button_action(pointer, button, pressed, -1, *args)
self.button_action(wid, pointer, button, pressed, -1, *args)

def button_action(self, pointer, button, pressed, _deviceid=-1, *_args):
def button_action(self, wid, pointer, button, pressed, _deviceid=-1, *_args):
if button<=3:
#we should be using CGEventCreateMouseEvent
#instead we clear previous clicks when a "higher" button is pressed... oh well
Expand Down
4 changes: 2 additions & 2 deletions xpra/platform/win32/shadow_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,9 +590,9 @@ def do_process_button_action(self, proto, wid, button, pressed, pointer, modifie
pointer = self._process_mouse_common(proto, wid, pointer)
if pointer:
self.get_server_source(proto).user_event()
self.button_action(pointer, button, pressed, -1, *args)
self.button_action(wid, pointer, button, pressed, -1, *args)

def button_action(self, pointer, button, pressed, deviceid=-1, *args):
def button_action(self, wid, pointer, button, pressed, deviceid=-1, *args):
event = BUTTON_EVENTS.get((button, pressed))
if event is None:
log.warn("no matching event found for button=%s, pressed=%s", button, pressed)
Expand Down
2 changes: 1 addition & 1 deletion xpra/server/dbus/dbus_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def MouseClick(self, button, pressed):
button, pressed = ni(button), nb(pressed)
self.log(".MouseClick%s", (button, pressed))
device_id = -1
self.server.button_action(None, button, pressed, device_id)
self.server.button_action(0, None, button, pressed, device_id)


@dbus.service.method(INTERFACE, in_signature='iiii')
Expand Down
2 changes: 1 addition & 1 deletion xpra/server/rfb/rfb_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def process_pointer_event():
if buttons & mask != self.rfb_buttons & mask:
pressed = bool(buttons & mask)
mouselog(" %spressing button %i", ["un",""][pressed], 1+button)
self.button_action((x, y), 1+button, pressed, -1)
self.button_action(0, (x, y), 1+button, pressed, -1)
self.rfb_buttons = buttons
self.idle_add(process_pointer_event)

Expand Down
6 changes: 6 additions & 0 deletions xpra/server/source/windows_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,12 @@ def cancel_damage(self, wid):
ws.cancel_damage()


def record_scroll_event(self, wid):
ws = self.window_sources.get(wid)
if ws:
ws.record_scroll_event()


def reinit_encoders(self):
for ws in tuple(self.window_sources.values()):
ws.init_encoders()
Expand Down
3 changes: 3 additions & 0 deletions xpra/server/window/window_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ def __init__(self,
self.av_sync_timer = None
self.encode_queue = []
self.encode_queue_max_size = 10
self.last_scroll_event = 0

self.server_core_encodings = server_core_encodings
self.server_encodings = server_encodings
Expand Down Expand Up @@ -649,6 +650,8 @@ def unlock_batch_delay(self):
self.batch_config.locked = False
self.batch_config.delay = self.batch_config.saved

def record_scroll_event(self):
self.last_scroll_event = monotonic()

def suspend(self):
self.cancel_damage()
Expand Down
17 changes: 17 additions & 0 deletions xpra/server/window/window_video_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def __init__(self, *args):
#for older clients, we check an encoding option:
"scroll" in self.server_core_encodings and self.encoding_options.boolget("scrolling") and not STRICT_MODE)
self.scroll_min_percent = self.encoding_options.intget("scrolling.min-percent", SCROLL_MIN_PERCENT)
self.scroll_preference = self.encoding_options.intget("scrolling.preference", 100)
self.supports_video_b_frames = self.encoding_options.strtupleget("video_b_frames", ())
self.video_max_size = self.encoding_options.inttupleget("video_max_size", (8192, 8192), 2, 2)
self.video_subregion = VideoSubregion(self.timeout_add, self.source_remove, self.refresh_subregion, self.auto_refresh_delay, VIDEO_SUBREGION)
Expand Down Expand Up @@ -256,6 +257,9 @@ def addcinfo(prefix, x):
"scrolling" : {
"enabled" : self.supports_scrolling,
"min-percent" : self.scroll_min_percent,
"preference" : self.scroll_preference,
"event" : self.last_scroll_event,
"time" : self.last_scroll_time,
}
}
if self._last_pipeline_check>0:
Expand Down Expand Up @@ -413,6 +417,7 @@ def do_set_client_properties(self, properties):
#for older clients, we check an encoding option:
"scroll" in self.server_core_encodings and properties.boolget("scrolling", self.supports_scrolling) and not STRICT_MODE)
self.scroll_min_percent = properties.intget("scrolling.min-percent", self.scroll_min_percent)
self.scroll_preference = properties.intget("scrolling.preference", self.scroll_preference)
self.video_subregion.supported = properties.boolget("encoding.video_subregion", VIDEO_SUBREGION) and VIDEO_SUBREGION
if properties.get("scaling.control") is not None:
self.scaling_control = max(0, min(100, properties.intget("scaling.control", 0)))
Expand Down Expand Up @@ -1864,6 +1869,18 @@ def may_use_scrolling(self, image, options):
scrolllog("no scrolling: b_frame_flush_timer=%s", self.b_frame_flush_timer)
self.do_free_scroll_data()
return False
speed = options.get("speed", self._current_speed)
if speed>=50 or self.scroll_preference<100:
now = monotonic()
scroll_event_elapsed = now-self.last_scroll_event
scroll_encode_elapsed = now-self.last_scroll_time
#how long since we last successfully used scroll encoding,
#or seen a scroll mouse wheel event:
scroll_elapsed = min(scroll_event_elapsed, scroll_encode_elapsed)
max_time = 1+min((100-speed)/10, self.scroll_preference/20)
if scroll_elapsed>=max_time:
scrolllog("no scrolling: elapsed=%.1f, max time=%.1f", scroll_elapsed, max_time)
return False
return self.do_scroll_encode(image, options, self.scroll_min_percent)

def scroll_encode(self, coding, image, options):
Expand Down
14 changes: 11 additions & 3 deletions xpra/x11/x11_server_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,7 @@ def _process_wheel_motion(self, proto, packet):
if not ss:
return
wid, button, distance, pointer, modifiers, _buttons = packet[1:7]
self.record_wheel_event(wid, button)
with xsync:
if self.do_process_mouse_common(proto, wid, pointer):
self.last_mouse_user = ss.uuid
Expand Down Expand Up @@ -998,19 +999,26 @@ def do_process_button_action(self, proto, wid, button, pressed, pointer,
self._update_modifiers(proto, wid, modifiers)
#TODO: pass extra args
if self._process_mouse_common(proto, wid, pointer, deviceid):
self.button_action(pointer, button, pressed, deviceid)
self.button_action(wid, pointer, button, pressed, deviceid)

def button_action(self, pointer, button, pressed, deviceid=-1, *args):
def button_action(self, wid, pointer, button, pressed, deviceid=-1, *args):
device = self.get_pointer_device(deviceid)
assert device, "pointer device %s not found" % deviceid
if button in (4, 5) and wid:
self.record_wheel_event(wid, button)
try:
mouselog("%s%s", device.click, (button, pressed, args))
with xsync:
device.click(button, pressed, *args)
except XError:
mouselog("button_action(%s, %s, %s, %s, %s)", pointer, button, pressed, deviceid, args, exc_info=True)
mouselog("button_action(%s, %s, %s, %s, %s, %s)",
wid, pointer, button, pressed, deviceid, args, exc_info=True)
mouselog.error("Error: failed (un)press mouse button %s", button)

def record_wheel_event(self, wid, button):
mouselog("recording scroll event for button %i", button)
for ss in self.window_sources():
ss.record_scroll_event(wid)

def make_screenshot_packet_from_regions(self, regions):
#regions = array of (wid, x, y, PIL.Image)
Expand Down

0 comments on commit f67fbd8

Please sign in to comment.