mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-28 00:33:06 +08:00
[ui] unify floating logo hand cursors with arrow fallback
This commit is contained in:
@@ -71,6 +71,7 @@
|
||||
#elif (defined(__linux__) && !defined(__OHOS__))
|
||||
#include <GL/gl.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -100,6 +101,41 @@ namespace {
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
bool SupportsControlHandCursor([[maybe_unused]] const slint::Window& window) {
|
||||
#if defined(_WIN32)
|
||||
return LoadCursorW(nullptr, IDC_HAND) != nullptr;
|
||||
#elif defined(__linux__) && !defined(__OHOS__)
|
||||
// Match winit's pointer aliases, without using any move/grab fallback.
|
||||
constexpr const char* names[] = {"pointer", "hand2", "hand1", "hand",
|
||||
"pointing_hand"};
|
||||
if (window.wayland_surface()) {
|
||||
const char* theme = std::getenv("XCURSOR_THEME");
|
||||
for (const char* name : names) {
|
||||
if (auto* images = XcursorLibraryLoadImages(name, theme, 24)) {
|
||||
const bool available = images->nimage > 0;
|
||||
XcursorImagesDestroy(images);
|
||||
if (available) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<Display, decltype(&XCloseDisplay)> display{
|
||||
XOpenDisplay(nullptr), XCloseDisplay};
|
||||
if (!display) return false;
|
||||
for (const char* name : names) {
|
||||
const Cursor cursor = XcursorLibraryLoadCursor(display.get(), name);
|
||||
if (cursor != None) {
|
||||
XFreeCursor(display.get(), cursor);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
// AppKit supplies pointingHandCursor; other adapters resolve pointer.
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::optional<std::string> GenerateRandomPassword(std::string_view current) {
|
||||
constexpr std::string_view alphabet =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
@@ -3640,6 +3676,8 @@ void GuiApplication::SyncStreamWindow() {
|
||||
if (!has_sessions) need_to_create_stream_window_ = false;
|
||||
if (need_to_create_stream_window_ && !ui_->stream) {
|
||||
ui_->stream.emplace(ui::StreamWindow::create());
|
||||
(*ui_->stream)->set_control_hand_cursor_supported(
|
||||
SupportsControlHandCursor(ui_->main->window()));
|
||||
#if (defined(__linux__) && !defined(__OHOS__))
|
||||
(*ui_->stream)->set_custom_titlebar(use_xwayland_gui_);
|
||||
#endif
|
||||
|
||||
@@ -102,6 +102,7 @@ component ControlBarButton inherits Rectangle {
|
||||
in property <bool> show-logo: false;
|
||||
in property <bool> logo-pressed: false;
|
||||
in property <bool> logo-dragging: false;
|
||||
in property <bool> hand-cursor-supported: true;
|
||||
in property <float> reveal-progress: 1;
|
||||
in property <string> badge: "";
|
||||
in property <string> tooltip: "";
|
||||
@@ -227,7 +228,7 @@ component ControlBarButton inherits Rectangle {
|
||||
}
|
||||
|
||||
touch := TouchArea {
|
||||
mouse-cursor: !root.action-enabled ? default : root.show-logo ? (root.logo-pressed ? grabbing : grab) : pointer;
|
||||
mouse-cursor: root.action-enabled && root.hand-cursor-supported ? pointer : default;
|
||||
scroll-event(event) => { accept }
|
||||
pointer-event(event) => {
|
||||
root.pointer-input(event.button, event.kind, self.mouse-x, self.mouse-y);
|
||||
@@ -285,6 +286,7 @@ export component StreamWindow inherits Window {
|
||||
default-font-size: ImGuiFontStyle.base;
|
||||
|
||||
in property <bool> custom-titlebar: false;
|
||||
in property <bool> control-hand-cursor-supported: true;
|
||||
in property <bool> native-video-enabled: false;
|
||||
// Export the actual input surface in logical pixels. Native rendering and
|
||||
// input mapping must follow the same layout, including title and tab bars.
|
||||
@@ -1073,7 +1075,8 @@ export component StreamWindow inherits Window {
|
||||
// The logo also retains a stable owner if another button is used.
|
||||
if root.remote-pointer-active || root.control-drag-pending: TouchArea {
|
||||
z: 15;
|
||||
mouse-cursor: root.control-drag-pending ? MouseCursor.grabbing
|
||||
mouse-cursor: root.control-drag-pending
|
||||
? (root.control-hand-cursor-supported ? MouseCursor.pointer : MouseCursor.default)
|
||||
: root.remote-cursor-active ? RemoteCursor.shape(root.remote-cursor-shape)
|
||||
: MouseCursor.default;
|
||||
pointer-event(event) => {
|
||||
@@ -1249,6 +1252,7 @@ export component StreamWindow inherits Window {
|
||||
width: root.control-toolbar-height;
|
||||
height: root.control-toolbar-height;
|
||||
show-logo: true;
|
||||
hand-cursor-supported: root.control-hand-cursor-supported;
|
||||
logo-pressed: root.control-drag-pending;
|
||||
logo-dragging: self.logo-pressed && root.control-dragging;
|
||||
tooltip: root.control-expanded ? StreamStrings.collapse-control : StreamStrings.expand-control;
|
||||
|
||||
Reference in New Issue
Block a user