Merge branch 'feature/VNC-155-add-scroll-detection-config' into 'master'

VNC-155 ConfigKey can have both type and validator

Closes VNC-155

See merge request kasm-technologies/internal/KasmVNC!183
This commit is contained in:
Matthew McClaskey 2025-05-14 18:45:11 +00:00
commit 9184050dae
4 changed files with 92 additions and 19 deletions

View File

@ -32,13 +32,6 @@ sub validate {
return if $self->isValueBlank(); return if $self->isValueBlank();
if ($self->{validator}) {
$self->resolveValidatorFromFunction() if (ref $self->{validator} eq "CODE");
$self->{validator}->validate($self);
return;
}
switch($self->{type}) { switch($self->{type}) {
case INT { case INT {
$self->validateInt(); $self->validateInt();
@ -47,6 +40,13 @@ sub validate {
$self->validateBoolean(); $self->validateBoolean();
} }
} }
if ($self->{validator}) {
$self->resolveValidatorFromFunction() if (ref $self->{validator} eq "CODE");
$self->{validator}->validate($self);
return;
}
} }
sub resolveValidatorFromFunction { sub resolveValidatorFromFunction {

View File

@ -134,6 +134,10 @@ encoding:
compare_framebuffer: auto compare_framebuffer: auto
zrle_zlib_level: auto zrle_zlib_level: auto
hextile_improved_compression: true hextile_improved_compression: true
scrolling:
detect_vertical_scrolling: false
detect_horizontal_scrolling: false
scroll_detect_threshold: 25%
server: server:
http: http:

View File

@ -1246,6 +1246,10 @@ sub DefineConfigToCLIConversion {
pattern => qr/^(never|\d+)$/, pattern => qr/^(never|\d+)$/,
errorMessage => "must be a number or 'never'" 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 $allConfigKeysValidatorSub = sub {
my @allConfigKeys = map { $_->configKeyNames() } @xvncOptions; my @allConfigKeys = map { $_->configKeyNames() } @xvncOptions;
@ -1253,6 +1257,14 @@ sub DefineConfigToCLIConversion {
allowedValues => [flatten(@allConfigKeys)] allowedValues => [flatten(@allConfigKeys)]
}) })
}; };
my $deriveValueStripPercentSub = sub {
$self = shift;
my $value = $self->configValue();
$value =~ s/%$//;
$value;
};
KasmVNC::CliOption::beforeIsActive(\&limitVncModeOptions); KasmVNC::CliOption::beforeIsActive(\&limitVncModeOptions);
my $ipv4_regexp = '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}'; 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]))'; 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]))';
@ -1999,20 +2011,10 @@ sub DefineConfigToCLIConversion {
configKeys => [ configKeys => [
KasmVNC::ConfigKey->new({ KasmVNC::ConfigKey->new({
name => "encoding.video_encoding_mode.enter_video_encoding_mode.area_threshold", name => "encoding.video_encoding_mode.enter_video_encoding_mode.area_threshold",
validator => KasmVNC::PatternValidator->new({ validator => $percentValidator
pattern => qr/^(\d+%)$/,
errorMessage => "must be a number, followed by %"
}),
}) })
], ],
deriveValueSub => sub { deriveValueSub => $deriveValueStripPercentSub
$self = shift;
my $value = $self->configValue();
$value =~ s/%$//;
$value;
}
}), }),
KasmVNC::CliOption->new({ KasmVNC::CliOption->new({
name => 'VideoOutTime', name => 'VideoOutTime',
@ -2462,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; %cliArgMap = map { ("-" . $_->{name}) => $_ } @xvncOptions;

View File

@ -584,6 +584,23 @@ When this option is used, benchmarking results can be saved to a file specified
.B -BenchmarkResults <results_file.xml> .B -BenchmarkResults <results_file.xml>
Save the benchmarking results to the specified file. Save the benchmarking results to the specified file.
Use this option together with \fB-Benchmark\fP to output the report to a custom 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 .SH USAGE WITH INETD
By configuring the \fBinetd\fP(1) service appropriately, Xvnc can be launched By configuring the \fBinetd\fP(1) service appropriately, Xvnc can be launched