[fix] follow the selected device cursor in DeskHub

This commit is contained in:
dijunkun
2026-10-14 10:20:31 +08:00
parent 5721222724
commit 3043b5f110
6 changed files with 62 additions and 31 deletions
@@ -4395,6 +4395,8 @@ void GuiApplication::ReleaseControl() {
ReleasePressedInput();
gallery_group_control_id_.clear();
ui_->wall->set_gallery_group_controlling(false);
ui_->wall->set_gallery_remote_cursor_shape(
static_cast<int>(RemoteCursorShape::default_cursor));
if (!ui_->gallery_control_id.empty()) {
ui_->gallery_control_id.clear();
ui_->wall->set_gallery_controlling(false);
@@ -5148,12 +5150,27 @@ void GuiApplication::SyncGallery() {
ReleaseControl();
ui_->wall->set_gallery_fullscreen(fullscreen);
}
auto cursor_shape = RemoteCursorShape::default_cursor;
if (!ui_->gallery_control_id.empty()) {
// Only the selected control source owns the wall cursor, including group
// control. Followers can report different shapes without replacing it.
auto controlled = FindRemoteSession(ui_->gallery_control_id);
if (!visible || !controlled || controlled->closing_ ||
controlled->connection_status_ != ConnectionStatus::Connected)
controlled->connection_status_ != ConnectionStatus::Connected) {
ReleaseControl();
} else {
HostPlatform platform;
{
std::lock_guard lock(controlled->remote_version_mutex_);
platform = controlled->remote_platform_;
}
std::lock_guard lock(controlled->remote_cursor_state_mutex_);
if (controlled->remote_cursor_state_received_)
cursor_shape = controlled->cursor_presentation_.Resolve(
SDL_GetTicks(), platform);
}
}
ui_->wall->set_gallery_remote_cursor_shape(static_cast<int>(cursor_shape));
const auto now = std::chrono::steady_clock::now();
const auto action = transition.Advance(now, current_size.width, current_size.height,
window.scale_factor(), fullscreen, placement.Restoring());
@@ -1,4 +1,5 @@
import { GalleryStrings } from "device_strings.slint";
import { RemoteCursor } from "remote_cursor.slint";
import { DeviceCardActions, DeviceCardStyle } from "device_card_actions.slint";
import { GalleryMenuButton } from "gallery_menu_button.slint";
import { GroupFilter } from "group_filter.slint";
@@ -44,6 +45,7 @@ export struct GalleryActionDevice {
export component GalleryView inherits Rectangle {
in property <bool> controlling: false;
in property <int> remote-cursor-shape: 0;
in property <bool> group-controlling: false;
in property <bool> input-suspended: false;
in property <bool> simplified: false;
@@ -620,6 +622,8 @@ export component GalleryView inherits Rectangle {
accept
}
TouchArea {
mouse-cursor: root.controlling && !root.input-suspended
? RemoteCursor.shape(root.remote-cursor-shape) : MouseCursor.default;
pointer-event(event) => {
if !root.input-suspended {
if event.kind == PointerEventKind.down { video-focus.focus(); }
@@ -309,6 +309,7 @@ export component MainWindow inherits Window {
}
in-out property <string> connection-input-error;
in property <bool> gallery-controlling: false;
in property <int> gallery-remote-cursor-shape: 0;
in property <bool> gallery-group-controlling: false;
out property <float> gallery-video-width: gallery.video-width;
out property <float> gallery-video-height: gallery.video-height;
@@ -1323,6 +1324,7 @@ export component MainWindow inherits Window {
focus-rail-height <=> root.gallery-focus-rail-height;
network-open => { root.gallery-network-open = true; }
controlling: root.gallery-controlling;
remote-cursor-shape: root.gallery-remote-cursor-shape;
group-controlling: root.gallery-group-controlling;
input-suspended: root.gallery-transitioning;
pointer-input(button, kind, x, y) => { root.gallery-pointer(button, kind, x, y); }
@@ -0,0 +1,34 @@
export global RemoteCursor {
// Numeric values mirror crossdesk::RemoteCursorShape on the wire.
public pure function shape(value: int) -> MouseCursor {
return value == 1 ? MouseCursor.none
: value == 2 ? MouseCursor.help
: value == 3 ? MouseCursor.pointer
: value == 4 ? MouseCursor.progress
: value == 5 ? MouseCursor.wait
: value == 6 ? MouseCursor.crosshair
: value == 7 ? MouseCursor.text
: value == 8 ? MouseCursor.alias
: value == 9 ? MouseCursor.copy
: value == 10 ? MouseCursor.move
: value == 11 ? MouseCursor.no-drop
: value == 12 ? MouseCursor.not-allowed
: value == 13 ? MouseCursor.grab
: value == 14 ? MouseCursor.grabbing
: value == 15 ? MouseCursor.col-resize
: value == 16 ? MouseCursor.row-resize
: value == 17 ? MouseCursor.n-resize
: value == 18 ? MouseCursor.e-resize
: value == 19 ? MouseCursor.s-resize
: value == 20 ? MouseCursor.w-resize
: value == 21 ? MouseCursor.ne-resize
: value == 22 ? MouseCursor.nw-resize
: value == 23 ? MouseCursor.se-resize
: value == 24 ? MouseCursor.sw-resize
: value == 25 ? MouseCursor.ew-resize
: value == 26 ? MouseCursor.ns-resize
: value == 27 ? MouseCursor.nesw-resize
: value == 28 ? MouseCursor.nwse-resize
: MouseCursor.default;
}
}
+3 -30
View File
@@ -1,4 +1,5 @@
import { ComboBox, ScrollView } from "std-widgets.slint";
import { RemoteCursor } from "remote_cursor.slint";
import { FontAwesomeIcons, IconButton, PrimaryButton, DialogSurface, ImGuiLineStyle, ImGuiFontStyle, FloatingBarStyle } from "common.slint";
export struct StreamTab {
@@ -714,36 +715,8 @@ export component StreamWindow inherits Window {
accept
}
pointer := TouchArea {
mouse-cursor: !root.remote-cursor-active ? MouseCursor.default
: root.remote-cursor-shape == 1 ? MouseCursor.none
: root.remote-cursor-shape == 2 ? MouseCursor.help
: root.remote-cursor-shape == 3 ? MouseCursor.pointer
: root.remote-cursor-shape == 4 ? MouseCursor.progress
: root.remote-cursor-shape == 5 ? MouseCursor.wait
: root.remote-cursor-shape == 6 ? MouseCursor.crosshair
: root.remote-cursor-shape == 7 ? MouseCursor.text
: root.remote-cursor-shape == 8 ? MouseCursor.alias
: root.remote-cursor-shape == 9 ? MouseCursor.copy
: root.remote-cursor-shape == 10 ? MouseCursor.move
: root.remote-cursor-shape == 11 ? MouseCursor.no-drop
: root.remote-cursor-shape == 12 ? MouseCursor.not-allowed
: root.remote-cursor-shape == 13 ? MouseCursor.grab
: root.remote-cursor-shape == 14 ? MouseCursor.grabbing
: root.remote-cursor-shape == 15 ? MouseCursor.col-resize
: root.remote-cursor-shape == 16 ? MouseCursor.row-resize
: root.remote-cursor-shape == 17 ? MouseCursor.n-resize
: root.remote-cursor-shape == 18 ? MouseCursor.e-resize
: root.remote-cursor-shape == 19 ? MouseCursor.s-resize
: root.remote-cursor-shape == 20 ? MouseCursor.w-resize
: root.remote-cursor-shape == 21 ? MouseCursor.ne-resize
: root.remote-cursor-shape == 22 ? MouseCursor.nw-resize
: root.remote-cursor-shape == 23 ? MouseCursor.se-resize
: root.remote-cursor-shape == 24 ? MouseCursor.sw-resize
: root.remote-cursor-shape == 25 ? MouseCursor.ew-resize
: root.remote-cursor-shape == 26 ? MouseCursor.ns-resize
: root.remote-cursor-shape == 27 ? MouseCursor.nesw-resize
: root.remote-cursor-shape == 28 ? MouseCursor.nwse-resize
: MouseCursor.default;
mouse-cursor: root.remote-cursor-active
? RemoteCursor.shape(root.remote-cursor-shape) : MouseCursor.default;
pointer-event(event) => {
let over-control = self.mouse-x >= control.x
&& self.mouse-x <= control.x + control.width