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();
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 {

View File

@ -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:

View File

@ -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;
@ -1253,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]))';
@ -1999,20 +2011,10 @@ 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 {
$self = shift;
my $value = $self->configValue();
$value =~ s/%$//;
$value;
}
deriveValueSub => $deriveValueStripPercentSub
}),
KasmVNC::CliOption->new({
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;

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>
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