From 634731748a90d8392f42115c354780413199652b Mon Sep 17 00:00:00 2001 From: Dmitry Maksyoma Date: Wed, 14 May 2025 20:21:10 +1200 Subject: [PATCH 1/5] VNC-155 Refactor --- unix/vncserver | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/unix/vncserver b/unix/vncserver index 1ac99c8..32b32ba 100755 --- a/unix/vncserver +++ b/unix/vncserver @@ -1246,6 +1246,10 @@ sub DefineConfigToCLIConversion { pattern => qr/^(never|\d+)$/, errorMessage => "must be a number or 'never'" }); + my $percentValidator = KasmVNC::PatternValidator->new({ + pattern => qr/^(\d+%)$/, + errorMessage => "must be a number, followed by %" + }); my $allConfigKeysValidatorSub = sub { my @allConfigKeys = map { $_->configKeyNames() } @xvncOptions; @@ -1999,10 +2003,7 @@ sub DefineConfigToCLIConversion { configKeys => [ KasmVNC::ConfigKey->new({ name => "encoding.video_encoding_mode.enter_video_encoding_mode.area_threshold", - validator => KasmVNC::PatternValidator->new({ - pattern => qr/^(\d+%)$/, - errorMessage => "must be a number, followed by %" - }), + validator => $percentValidator }) ], deriveValueSub => sub { From f12264c5ad4574cf925e7cb342fe89db17bfd5a5 Mon Sep 17 00:00:00 2001 From: Dmitry Maksyoma Date: Wed, 14 May 2025 21:10:45 +1200 Subject: [PATCH 2/5] VNC-155 Refactor --- unix/vncserver | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/unix/vncserver b/unix/vncserver index 32b32ba..ee2fb33 100755 --- a/unix/vncserver +++ b/unix/vncserver @@ -1257,6 +1257,14 @@ sub DefineConfigToCLIConversion { allowedValues => [flatten(@allConfigKeys)] }) }; + my $deriveValueStripPercentSub = sub { + $self = shift; + + my $value = $self->configValue(); + $value =~ s/%$//; + + $value; + }; KasmVNC::CliOption::beforeIsActive(\&limitVncModeOptions); my $ipv4_regexp = '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}'; my $ipv6_regexp = '(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))'; @@ -2006,14 +2014,7 @@ sub DefineConfigToCLIConversion { validator => $percentValidator }) ], - deriveValueSub => sub { - $self = shift; - - my $value = $self->configValue(); - $value =~ s/%$//; - - $value; - } + deriveValueSub => $deriveValueStripPercentSub }), KasmVNC::CliOption->new({ name => 'VideoOutTime', From 0924817a7694544b1bfae3cd682703bc021bb9fb Mon Sep 17 00:00:00 2001 From: Dmitry Maksyoma Date: Wed, 14 May 2025 21:30:58 +1200 Subject: [PATCH 3/5] VNC-155 ConfigKey can have both type and validator Type can check whether value is boolean or int, and validator can check whether another configuration key is defined, for example. --- unix/KasmVNC/ConfigKey.pm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/unix/KasmVNC/ConfigKey.pm b/unix/KasmVNC/ConfigKey.pm index f60fd63..b8ff425 100644 --- a/unix/KasmVNC/ConfigKey.pm +++ b/unix/KasmVNC/ConfigKey.pm @@ -32,13 +32,6 @@ sub validate { return if $self->isValueBlank(); - if ($self->{validator}) { - $self->resolveValidatorFromFunction() if (ref $self->{validator} eq "CODE"); - - $self->{validator}->validate($self); - return; - } - switch($self->{type}) { case INT { $self->validateInt(); @@ -47,6 +40,13 @@ sub validate { $self->validateBoolean(); } } + + if ($self->{validator}) { + $self->resolveValidatorFromFunction() if (ref $self->{validator} eq "CODE"); + + $self->{validator}->validate($self); + return; + } } sub resolveValidatorFromFunction { From 14ef7178b22984633226670216d562e5d99b624e Mon Sep 17 00:00:00 2001 From: Dmitry Maksyoma Date: Wed, 14 May 2025 21:44:08 +1200 Subject: [PATCH 4/5] VNC-155 Add scrolling configuration keys encoding.scrolling.detect_vertical_scrolling encoding.scrolling.detect_horizontal_scrolling encoding.scrolling.scroll_detect_threshold --- unix/kasmvnc_defaults.yaml | 4 +++ unix/vncserver | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/unix/kasmvnc_defaults.yaml b/unix/kasmvnc_defaults.yaml index afad666..0ed63ce 100644 --- a/unix/kasmvnc_defaults.yaml +++ b/unix/kasmvnc_defaults.yaml @@ -134,6 +134,10 @@ encoding: compare_framebuffer: auto zrle_zlib_level: auto hextile_improved_compression: true + scrolling: + detect_vertical_scrolling: false + detect_horizontal_scrolling: false + scroll_detect_threshold: 25% server: http: diff --git a/unix/vncserver b/unix/vncserver index ee2fb33..7a9588f 100755 --- a/unix/vncserver +++ b/unix/vncserver @@ -2464,6 +2464,56 @@ sub DefineConfigToCLIConversion { }) ] }), + KasmVNC::CliOption->new({ + name => 'DetectScrolling', + configKeys => [ + KasmVNC::ConfigKey->new({ + name => "encoding.scrolling.detect_vertical_scrolling", + type => KasmVNC::ConfigKey::BOOLEAN + }) + ], + isActiveSub => sub { + $self = shift; + + my $value = $self->configValue(); + isPresent($value) && $value eq 'true'; + } + }), + KasmVNC::CliOption->new({ + name => 'DetectHorizontal', + configKeys => [ + KasmVNC::ConfigKey->new({ + name => "encoding.scrolling.detect_horizontal_scrolling", + type => KasmVNC::ConfigKey::BOOLEAN, + validator => KasmVNC::CallbackValidator->new({ + isValidCallback => sub { + my $value = shift; + + return 1 if $value eq "false"; + + ConfigValue("encoding.scrolling.detect_vertical_scrolling") eq "true"; + }, + errorMessage => "Detection of horizontal scrolling requires detection of vertical scrolling enabled" + }), + }) + ], + isActiveSub => sub { + $self = shift; + + my $value = $self->configValue(); + isPresent($value) && $value eq 'true'; + } + }), + KasmVNC::CliOption->new({ + name => 'ScrollDetectLimit', + configKeys => [ + KasmVNC::ConfigKey->new({ + name => "encoding.scrolling.scroll_detect_threshold", + validator => $percentValidator + }) + ], + deriveValueSub => $deriveValueStripPercentSub + }), ); %cliArgMap = map { ("-" . $_->{name}) => $_ } @xvncOptions; From e1a4f9db65624a9dccb905cc9927e960164ce42e Mon Sep 17 00:00:00 2001 From: Dmitry Maksyoma Date: Wed, 14 May 2025 23:25:26 +1200 Subject: [PATCH 5/5] VNC-155 Add scrolling CLI options to Xvnc man page --- unix/xserver/hw/vnc/Xvnc.man | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man index 206784c..2afd1fa 100644 --- a/unix/xserver/hw/vnc/Xvnc.man +++ b/unix/xserver/hw/vnc/Xvnc.man @@ -584,6 +584,23 @@ When this option is used, benchmarking results can be saved to a file specified .B -BenchmarkResults Save the benchmarking results to the specified file. Use this option together with \fB-Benchmark\fP to output the report to a custom file. +. +.TP +.B \-DetectScrolling +Try to detect scrolled sections in a changed area. + +Detect vertical scrolling on the screen and then use copyRects instead of +sending jpeg. A copy rect tells the client to copy a section of the screen and +paste it somewhere else. This significantly reduces bandwidth usage when someone +is scrolling down a page. +. +.TP +.B \-DetectHorizontal +With \fB-DetectScrolling\fP enabled, try to detect horizontal scrolls too, not just vertical. +. +.TP +.B \-ScrollDetectLimit +At least this % of the screen must change for scroll detection to happen, default 25. .SH USAGE WITH INETD By configuring the \fBinetd\fP(1) service appropriately, Xvnc can be launched