From 2cd4defa9fdcae30188b03461770660812413591 Mon Sep 17 00:00:00 2001 From: lysec Date: Sun, 5 Oct 2025 23:21:08 +0200 Subject: [PATCH] LockScreen: more sizing tweaks --- Assets/Translations/de.json | 4 +- Assets/Translations/en.json | 4 +- Assets/Translations/es.json | 4 +- Assets/Translations/fr.json | 4 +- Assets/Translations/pt.json | 4 +- Assets/Translations/zh-CN.json | 4 +- Modules/Bar/Widgets/ScreenRecorder.qml | 11 +++- Modules/LockScreen/LockScreen.qml | 74 +++++++++++++------------- Services/ScreenRecorderService.qml | 10 +++- 9 files changed, 74 insertions(+), 45 deletions(-) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index f535ff73..c39eda4e 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -1415,7 +1415,9 @@ "failed-gpu": "gpu-screen-recorder unerwartet beendet.", "failed-general": "Der Rekorder wurde mit einem Fehler beendet.", "no-portals": "Desktop-Portale laufen nicht", - "no-portals-desc": "Starten Sie xdg-desktop-portal und ein Compositor-Portal (wlr/hyprland/gnome/kde)." + "no-portals-desc": "Starten Sie xdg-desktop-portal und ein Compositor-Portal (wlr/hyprland/gnome/kde).", + "not-installed": "gpu-screen-recorder nicht installiert", + "not-installed-desc": "Bitte installieren Sie gpu-screen-recorder, um Bildschirmaufnahme-Funktionen zu nutzen." }, "clipboard": { "unavailable": "Zwischenablage-Verlauf nicht verfügbar", diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 00658429..4749c20a 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -1386,7 +1386,9 @@ "failed-gpu": "gpu-screen-recorder exited unexpectedly.", "failed-general": "The recorder exited with an error.", "no-portals": "Desktop portals not running", - "no-portals-desc": "Start xdg-desktop-portal and a compositor portal (wlr/hyprland/gnome/kde)." + "no-portals-desc": "Start xdg-desktop-portal and a compositor portal (wlr/hyprland/gnome/kde).", + "not-installed": "gpu-screen-recorder not installed", + "not-installed-desc": "Please install gpu-screen-recorder to use screen recording features." }, "clipboard": { "unavailable": "Clipboard history unavailable", diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index e03f07c8..b2de0545 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -1383,7 +1383,9 @@ "failed-gpu": "gpu-screen-recorder se cerró inesperadamente.", "failed-general": "La grabadora se cerró con un error.", "no-portals": "Los portales de escritorio no están en ejecución", - "no-portals-desc": "Inicia xdg-desktop-portal y un portal de compositor (wlr/hyprland/gnome/kde)." + "no-portals-desc": "Inicia xdg-desktop-portal y un portal de compositor (wlr/hyprland/gnome/kde).", + "not-installed": "gpu-screen-recorder no instalado", + "not-installed-desc": "Por favor instala gpu-screen-recorder para usar las funciones de grabación de pantalla." }, "clipboard": { "unavailable": "Historial del portapapeles no disponible", diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index 31d6cf66..5a2070c8 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -1383,7 +1383,9 @@ "failed-gpu": "gpu-screen-recorder s'est arrêté de manière inattendue.", "failed-general": "L'enregistreur s'est arrêté avec une erreur.", "no-portals": "Les portails de bureau ne sont pas en cours d'exécution", - "no-portals-desc": "Démarrez xdg-desktop-portal et un portail de compositeur (wlr/hyprland/gnome/kde)." + "no-portals-desc": "Démarrez xdg-desktop-portal et un portail de compositeur (wlr/hyprland/gnome/kde).", + "not-installed": "gpu-screen-recorder non installé", + "not-installed-desc": "Veuillez installer gpu-screen-recorder pour utiliser les fonctionnalités d'enregistrement d'écran." }, "clipboard": { "unavailable": "Historique du presse-papiers indisponible", diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index ca05e085..7790f6aa 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -1383,7 +1383,9 @@ "failed-gpu": "gpu-screen-recorder encerrou inesperadamente.", "failed-general": "O gravador encerrou com um erro.", "no-portals": "Portais de desktop não estão em execução", - "no-portals-desc": "Inicie o xdg-desktop-portal e um portal de compositor (wlr/hyprland/gnome/kde)." + "no-portals-desc": "Inicie o xdg-desktop-portal e um portal de compositor (wlr/hyprland/gnome/kde).", + "not-installed": "gpu-screen-recorder não instalado", + "not-installed-desc": "Por favor instale o gpu-screen-recorder para usar as funcionalidades de gravação de tela." }, "clipboard": { "unavailable": "Histórico da área de transferência indisponível", diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 88db3c48..e36793be 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -1383,7 +1383,9 @@ "failed-gpu": "gpu-screen-recorder 意外退出。", "failed-general": "录制器因错误退出。", "no-portals": "桌面门户未运行", - "no-portals-desc": "请启动 xdg-desktop-portal 和一个合成器门户 (wlr/hyprland/gnome/kde)。" + "no-portals-desc": "请启动 xdg-desktop-portal 和一个合成器门户 (wlr/hyprland/gnome/kde)。", + "not-installed": "gpu-screen-recorder 未安装", + "not-installed-desc": "请安装 gpu-screen-recorder 以使用屏幕录制功能。" }, "clipboard": { "unavailable": "剪贴板历史记录不可用", diff --git a/Modules/Bar/Widgets/ScreenRecorder.qml b/Modules/Bar/Widgets/ScreenRecorder.qml index bb0a6d31..de14efdb 100644 --- a/Modules/Bar/Widgets/ScreenRecorder.qml +++ b/Modules/Bar/Widgets/ScreenRecorder.qml @@ -18,5 +18,14 @@ NIconButton { colorFg: ScreenRecorderService.isRecording ? Color.mOnPrimary : Color.mOnSurface colorBorder: Color.transparent colorBorderHover: Color.transparent - onClicked: ScreenRecorderService.toggleRecording() + + function handleClick() { + if (!ScreenRecorderService.isAvailable) { + ToastService.showError(I18n.tr("toast.recording.not-installed"), I18n.tr("toast.recording.not-installed-desc"), 7000) + return + } + ScreenRecorderService.toggleRecording() + } + + onClicked: handleClick() } diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index 379d2d00..5cffff21 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -119,7 +119,7 @@ Loader { id: timeText text: lockScreen.formatTime() Layout.alignment: Qt.AlignHCenter - pointSize: 80 * scaling + pointSize: 72 * scaling font.weight: Font.Medium color: Color.mOnSurface horizontalAlignment: Text.AlignHCenter @@ -159,8 +159,8 @@ Loader { Layout.alignment: Qt.AlignHCenter Rectangle { - Layout.preferredWidth: 160 * scaling - Layout.preferredHeight: 160 * scaling + Layout.preferredWidth: 140 * scaling + Layout.preferredHeight: 140 * scaling Layout.alignment: Qt.AlignHCenter radius: width * 0.5 color: Color.transparent @@ -189,8 +189,8 @@ Loader { NImageCircled { anchors.centerIn: parent - width: 150 * scaling - height: 150 * scaling + width: 130 * scaling + height: 130 * scaling imagePath: Settings.data.general.avatarImage fallbackIcon: "person" @@ -223,7 +223,7 @@ Loader { NText { text: Quickshell.env("USER") Layout.alignment: Qt.AlignHCenter - pointSize: Style.fontSizeXXXL * scaling * 1.2 + pointSize: Style.fontSizeXXXL * scaling font.weight: Font.Medium color: Color.mOnSurface horizontalAlignment: Text.AlignHCenter @@ -274,26 +274,26 @@ Loader { // Bottom container with weather, password input and controls Rectangle { - width: 800 * scaling - height: 240 * scaling + width: 750 * scaling + height: 220 * scaling anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom anchors.bottomMargin: 100 * scaling - radius: 35 * scaling + radius: 32 * scaling color: Qt.alpha(Color.mSurfaceContainerHighest, 0.9) border.color: Qt.alpha(Color.mOutline, 0.2) border.width: 1 ColumnLayout { anchors.fill: parent - anchors.margins: 16 * scaling - spacing: 16 * scaling + anchors.margins: 14 * scaling + spacing: 14 * scaling // Weather section RowLayout { Layout.fillWidth: true - Layout.preferredHeight: 70 * scaling - spacing: 20 * scaling + Layout.preferredHeight: 65 * scaling + spacing: 18 * scaling visible: LocationService.coordinatesReady && LocationService.data.weather !== null // Media widget with visualizer @@ -555,17 +555,17 @@ Loader { Rectangle { Layout.fillWidth: true - Layout.preferredHeight: 52 * scaling - radius: 26 * scaling + Layout.preferredHeight: 48 * scaling + radius: 24 * scaling color: Qt.alpha(Color.mSurfaceContainerHighest, 0.6) border.color: passwordInput.activeFocus ? Color.mPrimary : Qt.alpha(Color.mOutline, 0.3) border.width: passwordInput.activeFocus ? 2 : 1 Row { anchors.left: parent.left - anchors.leftMargin: 20 * scaling + anchors.leftMargin: 18 * scaling anchors.verticalCenter: parent.verticalCenter - spacing: 16 * scaling + spacing: 14 * scaling NIcon { icon: "lock" @@ -654,10 +654,10 @@ Loader { Rectangle { anchors.right: parent.right - anchors.rightMargin: 10 * scaling + anchors.rightMargin: 8 * scaling anchors.verticalCenter: parent.verticalCenter - width: 38 * scaling - height: 38 * scaling + width: 36 * scaling + height: 36 * scaling radius: width * 0.5 color: submitButtonArea.containsMouse ? Color.mPrimary : Qt.alpha(Color.mPrimary, 0.8) border.color: Color.mPrimary @@ -695,8 +695,8 @@ Loader { // System control buttons RowLayout { Layout.fillWidth: true - Layout.preferredHeight: 52 * scaling - spacing: 12 * scaling + Layout.preferredHeight: 48 * scaling + spacing: 10 * scaling Item { Layout.preferredWidth: Style.marginM * scaling @@ -704,24 +704,24 @@ Loader { Rectangle { Layout.fillWidth: true - Layout.preferredHeight: 52 * scaling - radius: 26 * scaling + Layout.preferredHeight: 48 * scaling + radius: 24 * scaling color: logoutButtonArea.containsMouse ? Color.mTertiary : "transparent" RowLayout { anchors.centerIn: parent - spacing: 8 * scaling + spacing: 6 * scaling NIcon { icon: "logout" - pointSize: Style.fontSizeXL * scaling + pointSize: Style.fontSizeL * scaling color: logoutButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant } NText { text: I18n.tr("session-menu.logout") color: logoutButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant - pointSize: Style.fontSizeL * scaling + pointSize: Style.fontSizeM * scaling font.weight: Font.Medium } } @@ -743,24 +743,24 @@ Loader { Rectangle { Layout.fillWidth: true - Layout.preferredHeight: 52 * scaling - radius: 26 * scaling + Layout.preferredHeight: 48 * scaling + radius: 24 * scaling color: rebootButtonArea.containsMouse ? Color.mTertiary : "transparent" RowLayout { anchors.centerIn: parent - spacing: 8 * scaling + spacing: 6 * scaling NIcon { icon: "reboot" - pointSize: Style.fontSizeXL * scaling + pointSize: Style.fontSizeL * scaling color: rebootButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant } NText { text: I18n.tr("session-menu.reboot") color: rebootButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant - pointSize: Style.fontSizeL * scaling + pointSize: Style.fontSizeM * scaling font.weight: Font.Medium } } @@ -782,26 +782,26 @@ Loader { Rectangle { Layout.fillWidth: true - Layout.preferredHeight: 52 * scaling - radius: 26 * scaling + Layout.preferredHeight: 48 * scaling + radius: 24 * scaling color: shutdownButtonArea.containsMouse ? Color.mError : "transparent" border.color: shutdownButtonArea.containsMouse ? Color.mError : Color.transparent border.width: 1 RowLayout { anchors.centerIn: parent - spacing: 8 * scaling + spacing: 6 * scaling NIcon { icon: "shutdown" - pointSize: Style.fontSizeXL * scaling + pointSize: Style.fontSizeL * scaling color: shutdownButtonArea.containsMouse ? Color.mOnError : Color.mOnSurfaceVariant } NText { text: I18n.tr("session-menu.shutdown") color: shutdownButtonArea.containsMouse ? Color.mOnError : Color.mOnSurfaceVariant - pointSize: Style.fontSizeL * scaling + pointSize: Style.fontSizeM * scaling font.weight: Font.Medium } } diff --git a/Services/ScreenRecorderService.qml b/Services/ScreenRecorderService.qml index f77f9f75..0493ee27 100644 --- a/Services/ScreenRecorderService.qml +++ b/Services/ScreenRecorderService.qml @@ -67,7 +67,7 @@ Singleton { elif command -v flatpak >/dev/null 2>&1 && _gpuscreenrecorder_flatpak_installed; then flatpak run --command=gpu-screen-recorder --file-forwarding com.dec05eba.gpu_screen_recorder ${flags} else - notify-send "gpu-screen-recorder not installed!" -u critical + echo "GPU_SCREEN_RECORDER_NOT_INSTALLED" fi` // Use Process instead of execDetached so we can monitor it and read stderr @@ -109,6 +109,14 @@ Singleton { // Process ended while we were pending - likely cancelled or error isPending = false pendingTimer.running = false + + // Check if gpu-screen-recorder is not installed + const stdout = String(stdout.text || "").trim() + if (stdout === "GPU_SCREEN_RECORDER_NOT_INSTALLED") { + ToastService.showError(I18n.tr("toast.recording.not-installed"), I18n.tr("toast.recording.not-installed-desc"), 7000) + return + } + // If it failed to start, show a clear error toast with stderr if (exitCode !== 0) { const err = String(stderr.text || "").trim()