[feat] add Wayland session notice with X11 guidance

This commit is contained in:
kunkundi
2026-09-29 00:46:08 +08:00
parent a83b6badd0
commit 597c1dd2c9
5 changed files with 173 additions and 1 deletions
@@ -1123,6 +1123,9 @@ void GuiApplication::InitializeUi() {
}
#endif
#if defined(__linux__) && !defined(__APPLE__)
// Detect the desktop session before temporarily hiding Wayland variables
// for the XWayland GUI backend below.
const bool is_wayland_session = IsWaylandSession();
// Winit prefers Wayland whenever WAYLAND_DISPLAY/WAYLAND_SOCKET is present.
// Hide them only while Slint selects its process-wide window backend, then
// restore the environment before the rest of the application starts.
@@ -1144,6 +1147,8 @@ void GuiApplication::InitializeUi() {
#elif defined(__linux__)
ui_->main->set_custom_titlebar(use_x11_custom_titlebar_);
ui_->main->set_wayland_titlebar(use_xwayland_gui_);
// Set this only at startup so dismissing the notice lasts until exit.
ui_->main->set_wayland_notice_open(is_wayland_session);
#endif
ui_->main->set_release_note_blocks(ui_->release_note_blocks_model);
RegisterFontAwesome(ui_->main->window());
@@ -330,6 +330,34 @@ struct TranslationRow {
X(permission_required_message, u8"该应用需要授权以下权限:", \
"The application requires the following permissions:", \
u8"Для работы приложения требуются следующие разрешения:") \
X(wayland_notice_title, u8"Wayland 会话提示", "Wayland Session Notice", \
u8"Уведомление о сеансе Wayland") \
X(wayland_notice_subtitle, u8"检测到当前桌面会话使用 Wayland。", \
"The current desktop session uses Wayland.", \
u8"Текущий сеанс рабочего стола использует Wayland.") \
X(wayland_permission_title, u8"每次共享均需本机授权", \
"Local approval required each time", \
u8"Разрешение требуется каждый раз") \
X(wayland_notice_message, \
u8"受 Wayland 安全机制限制,每次启动远程桌面共享时," \
u8"均需在本机手动授权屏幕共享与远程控制,授权后方可正常使用。", \
"Wayland security restrictions require you to authorize screen sharing " \
"and remote control locally each time you start sharing this desktop. " \
"Remote access is available only after authorization.", \
u8"Из-за ограничений безопасности Wayland при каждом запуске общего " \
u8"доступа к рабочему столу необходимо вручную разрешать на этом " \
u8"компьютере показ экрана и удалённое управление. Удалённый доступ " \
u8"возможен только после разрешения.") \
X(wayland_recommendation_title, u8"建议使用 X11(Xorg)", \
"X11 (Xorg) is recommended", u8"Рекомендуем X11 (Xorg)") \
X(wayland_recommendation_message, \
u8"为便于持续使用远程桌面,建议注销当前桌面会话," \
u8"在登录界面选择 X11(Xorg)会话后重新登录。", \
"For ongoing remote desktop access, we recommend logging out, selecting " \
"an X11 (Xorg) session on the login screen, and logging in again.", \
u8"Для постоянного удалённого доступа рекомендуем завершить сеанс, " \
u8"выбрать X11 (Xorg) на экране входа и войти снова.") \
X(wayland_notice_acknowledge, u8"我知道了", "Got it", u8"Понятно") \
X(show_main_window, u8"显示主界面", "Show Main Window", \
u8"Показать главное окно") \
X(privacy_screen_unlock_hint, u8"按下快捷键,解除隐私屏", \
+123 -1
View File
@@ -80,6 +80,13 @@ export global UiStrings {
in-out property <string> permission-required: "The application requires the following permissions:";
in-out property <string> screen-recording-permission: "Screen recording permission";
in-out property <string> accessibility-permission: "Accessibility permission";
in-out property <string> wayland-notice-title: "Wayland Session Notice";
in-out property <string> wayland-notice-subtitle;
in-out property <string> wayland-permission-title;
in-out property <string> wayland-notice-message;
in-out property <string> wayland-recommendation-title;
in-out property <string> wayland-recommendation-message;
in-out property <string> wayland-notice-acknowledge: "Got it";
in-out property <string> service-setup-title: "Install CrossDesk Service";
in-out property <string> service-setup-message: "Administrator permission is required to control this device while it is locked.";
in-out property <string> service-settings-label: "Lock Screen Service:";
@@ -288,6 +295,7 @@ export component MainWindow inherits Window {
in property <bool> permission-dialog-open: false;
in property <bool> screen-recording-granted: true;
in property <bool> accessibility-granted: true;
in-out property <bool> wayland-notice-open: false;
in property <bool> portable-service-settings-visible: false;
in property <bool> portable-service-dialog-open: false;
in property <bool> portable-service-suppressed-notice-open: false;
@@ -398,6 +406,10 @@ export component MainWindow inherits Window {
}
}
changed wayland-notice-open => {
if root.wayland-notice-open { focus-sink.focus(); }
}
reset-remote-id => {
root.remote-id-input = "";
remote-id-editor.focus();
@@ -602,7 +614,18 @@ export component MainWindow inherits Window {
border-width: 0px;
border-radius: 0px;
focus-sink := FocusScope { x: 0px; y: 0px; width: 0px; height: 0px; }
focus-sink := FocusScope {
x: 0px; y: 0px; width: 0px; height: 0px;
key-pressed(event) => {
if root.wayland-notice-open {
if event.text == Key.Return || event.text == Key.Escape {
root.wayland-notice-open = false;
}
return accept;
}
return reject;
}
}
TouchArea { clicked => { focus-sink.focus(); } }
// Slint owns the client area below the native macOS title bar. Draw
@@ -1810,6 +1833,105 @@ export component MainWindow inherits Window {
}
}
// Linux Wayland sessions show this advisory once per application launch.
if root.wayland-notice-open: Rectangle {
background: #14233b66;
z: 50;
TouchArea { clicked => { focus-sink.focus(); } }
DialogSurface {
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
width: 512px;
height: wayland-notice-content.preferred-height;
border-radius: 14px;
border-color: #dce3ee;
drop-shadow-color: #07142b30;
drop-shadow-blur: 28px;
drop-shadow-offset-y: 10px;
wayland-notice-content := VerticalLayout {
padding: 24px; spacing: 18px;
VerticalLayout {
spacing: 7px;
Text {
text: UiStrings.wayland-notice-title;
color: #1c2b43;
font-size: 20px;
font-weight: 700;
wrap: word-wrap;
}
Text {
text: UiStrings.wayland-notice-subtitle;
color: #68758a;
font-size: ImGuiFontStyle.base;
wrap: word-wrap;
}
}
Rectangle {
background: #fff8eb;
border-color: #f0dfba;
border-width: 1px;
border-radius: 9px;
VerticalLayout {
padding: 14px; spacing: 8px;
Text {
text: UiStrings.wayland-permission-title;
color: #805719;
font-size: 13px;
font-weight: 600;
wrap: word-wrap;
}
Text {
text: UiStrings.wayland-notice-message;
color: #6c5a3d;
font-size: ImGuiFontStyle.base;
wrap: word-wrap;
}
}
}
Rectangle {
background: #f3f7fd;
border-color: #dfe8f5;
border-width: 1px;
border-radius: 9px;
VerticalLayout {
padding: 14px; spacing: 8px;
Text {
text: UiStrings.wayland-recommendation-title;
color: #244c87;
font-size: 13px;
font-weight: 600;
wrap: word-wrap;
}
Text {
text: UiStrings.wayland-recommendation-message;
color: #59677c;
font-size: ImGuiFontStyle.base;
wrap: word-wrap;
}
}
}
Rectangle { height: 1px; background: #e9edf3; }
HorizontalLayout {
height: 34px; alignment: end;
PrimaryButton {
width: 104px; height: 34px;
border-radius: 7px;
text-size: ImGuiFontStyle.base;
text: UiStrings.wayland-notice-acknowledge;
accessible-role: button;
accessible-label: UiStrings.wayland-notice-acknowledge;
accessible-action-default => { root.wayland-notice-open = false; }
clicked => { root.wayland-notice-open = false; }
}
}
}
}
}
// Portable Windows builds prompt for the optional lock-screen service.
if root.portable-service-dialog-open: Rectangle {
background: #00000052;
+14
View File
@@ -104,6 +104,20 @@ inline int ApplyMainWindowStrings(
Text(localization::screen_recording_permission[language]));
strings.set_accessibility_permission(
Text(localization::accessibility_permission[language]));
strings.set_wayland_notice_title(
Text(localization::wayland_notice_title[language]));
strings.set_wayland_notice_subtitle(
Text(localization::wayland_notice_subtitle[language]));
strings.set_wayland_permission_title(
Text(localization::wayland_permission_title[language]));
strings.set_wayland_notice_message(
Text(localization::wayland_notice_message[language]));
strings.set_wayland_recommendation_title(
Text(localization::wayland_recommendation_title[language]));
strings.set_wayland_recommendation_message(
Text(localization::wayland_recommendation_message[language]));
strings.set_wayland_notice_acknowledge(
Text(localization::wayland_notice_acknowledge[language]));
strings.set_service_setup_title(
Text(localization::windows_service_setup_title[language]));
strings.set_service_setup_message(
@@ -186,6 +186,7 @@ void ResetMainCaptureState(
window->set_permission_dialog_open(false);
window->set_screen_recording_granted(true);
window->set_accessibility_granted(true);
window->set_wayland_notice_open(false);
window->set_settings_session_active(false);
window->set_portable_service_settings_visible(false);
window->set_portable_service_dialog_open(false);
@@ -277,6 +278,8 @@ void ConfigureMainCapturePage(
window->set_permission_dialog_open(true);
window->set_screen_recording_granted(false);
window->set_accessibility_granted(false);
} else if (options.page == "wayland-notice") {
window->set_wayland_notice_open(true);
}
}