From 77f724e547129b38100cfbe5fad4620407b76ed1 Mon Sep 17 00:00:00 2001 From: rickpeters Date: Sun, 27 Sep 2026 17:56:57 +0200 Subject: [PATCH] fix(ui): B never quits (Steam sends Esc for it), Ctrl+Q does; started from Steam, the hints show the Steam Controller's buttons --- ui/qml/AppState.qml | 7 +++++-- ui/qml/Glyph.qml | 2 +- ui/qml/Input.qml | 11 ++++++++--- ui/qml/Main.qml | 2 ++ ui/qml/MenuScreen.qml | 3 +++ ui/qml/PasswordScreen.qml | 2 +- ui/steamify-ui | 3 +++ 7 files changed, 23 insertions(+), 7 deletions(-) diff --git a/ui/qml/AppState.qml b/ui/qml/AppState.qml index 7e9aab9..ba4ebe3 100644 --- a/ui/qml/AppState.qml +++ b/ui/qml/AppState.qml @@ -215,7 +215,9 @@ Item { boot = a === "left" ? "gamescope" : "desktop"; else if (a === "apply") goReview(false); else if (a === "reapply") goReview(true); - else if (a === "back") Qt.quit(); + // B/Esc/Back don't quit: Steam's desktop layout sends Esc for a + // Steam Controller's B, which should only ever go back. + else if (a === "quit") Qt.quit(); } else if (screen === "review") { if (a === "accept" || a === "apply") onApplyPressed(); else if (a === "back") { reapply = false; screen = "menu"; } @@ -254,7 +256,7 @@ Item { if (screen === "bios2" && Input.type !== "keyboard" && (e.key === Qt.Key_Return || e.key === Qt.Key_Enter)) { if (!e.isAutoRepeat) act("hold"); e.accepted = true; return; } - if (!fromRemote) Input.type = "keyboard"; + if (!fromRemote) Input.type = Input.fromSteam ? "steam" : "keyboard"; var k = e.key; if (k === Qt.Key_Up) act("up"); else if (k === Qt.Key_Down) act("down"); @@ -268,6 +270,7 @@ Item { else if (k === Qt.Key_Return || k === Qt.Key_Enter) act("accept"); else if (k === Qt.Key_Escape || k === Qt.Key_Back || k === Qt.Key_Backspace) { if (!e.isAutoRepeat) act("back"); } else if (k === Qt.Key_R) act("reapply"); + else if (k === Qt.Key_Q && (e.modifiers & Qt.ControlModifier)) act("quit"); else return; e.accepted = true; } diff --git a/ui/qml/Glyph.qml b/ui/qml/Glyph.qml index 9f0befb..3bf60aa 100644 --- a/ui/qml/Glyph.qml +++ b/ui/qml/Glyph.qml @@ -6,7 +6,7 @@ Rectangle { property string k property bool dark: false height: 26; width: Math.max(26, gt.implicitWidth + 14) - radius: Input.type === "controller" && k.length === 1 ? 13 : 7 + radius: (Input.type === "controller" || Input.type === "steam") && k.length === 1 ? 13 : 7 color: dark ? Theme.ink : Theme.key Text { id: gt; anchors.centerIn: parent; text: glyph.k; color: glyph.dark ? Theme.accent : Theme.textHi font.family: Theme.body; font.pixelSize: 12; font.weight: Font.DemiBold } diff --git a/ui/qml/Input.qml b/ui/qml/Input.qml index e45b641..8844060 100644 --- a/ui/qml/Input.qml +++ b/ui/qml/Input.qml @@ -5,10 +5,15 @@ import QtQuick QtObject { property string type: "keyboard" + // Started from Steam: keys come from a Steam Controller through Steam's + // desktop layout (A = Enter, B = Esc, Y = Space, X = Steam's keyboard), + // shown as "steam" with the controller's buttons. + property bool fromSteam: false readonly property var glyphs: ({ - controller: { toggle: "A", choose: "◀ ▶", reapply: "Y", quit: "B", apply: "X", ok: "A", back: "B" }, - keyboard: { toggle: "Enter", choose: "← →", reapply: "R", quit: "Esc", apply: "Ctrl+Enter", ok: "Enter", back: "Esc" }, - remote: { toggle: "OK", choose: "◀ ▶", reapply: "Red", quit: "Back", apply: "↓ Apply", ok: "OK", back: "Back" } + controller: { toggle: "A", choose: "◀ ▶", reapply: "Y", quit: "", apply: "X", ok: "A", back: "B" }, + keyboard: { toggle: "Enter", choose: "← →", reapply: "R", quit: "Ctrl+Q", apply: "Ctrl+Enter", ok: "Enter", back: "Esc" }, + steam: { toggle: "A", choose: "◀ ▶", reapply: "", quit: "", apply: "↓ A", ok: "A", back: "B" }, + remote: { toggle: "OK", choose: "◀ ▶", reapply: "Red", quit: "", apply: "↓ Apply", ok: "OK", back: "Back" } }) readonly property var g: glyphs[type] } diff --git a/ui/qml/Main.qml b/ui/qml/Main.qml index f60ef7b..41ced9b 100644 --- a/ui/qml/Main.qml +++ b/ui/qml/Main.qml @@ -12,6 +12,8 @@ ApplicationWindow { required property var gamepad required property bool fullscreen required property string iconUrl + required property bool fromSteam + Component.onCompleted: Input.fromSteam = fromSteam width: 1280; height: 720 minimumWidth: 960; minimumHeight: 540 diff --git a/ui/qml/MenuScreen.qml b/ui/qml/MenuScreen.qml index e0f397e..b368a82 100644 --- a/ui/qml/MenuScreen.qml +++ b/ui/qml/MenuScreen.qml @@ -59,7 +59,10 @@ Item { Row { anchors.left: parent.left; anchors.leftMargin: 40; anchors.verticalCenter: parent.verticalCenter; spacing: 28 Repeater { + // Quit only has a key on a keyboard (Ctrl+Q), and re-apply has + // none through Steam's layout; a controller quits through Steam. model: [[screen.g.toggle, "Toggle"], [screen.g.choose, "Choose"], [screen.g.reapply, "Re-apply what's on"], [screen.g.quit, "Quit"]] + .filter(function (h) { return h[0] !== ""; }) Row { required property var modelData; spacing: 8 Glyph { k: parent.modelData[0]; anchors.verticalCenter: parent.verticalCenter } Text { text: parent.modelData[1]; color: Theme.label; font.family: Theme.body; font.pixelSize: 14; anchors.verticalCenter: parent.verticalCenter } } diff --git a/ui/qml/PasswordScreen.qml b/ui/qml/PasswordScreen.qml index 922b198..48e94e3 100644 --- a/ui/qml/PasswordScreen.qml +++ b/ui/qml/PasswordScreen.qml @@ -47,7 +47,7 @@ Rectangle { Text { visible: app.wrongPassword; text: "That password didn't work. Try again."; color: Theme.bad; font.family: Theme.body; font.pixelSize: 14 } Rectangle { width: parent.width; height: 46; radius: 12; color: Theme.note Text { anchors.verticalCenter: parent.verticalCenter; x: 14; color: Theme.soft; font.family: Theme.body; font.pixelSize: 14 - text: ({ controller: "Press Steam + X for the on-screen keyboard.", keyboard: "Type your password and press Enter.", remote: "Select the field for the on-screen keyboard." })[Input.type] } } + text: ({ controller: "Press Steam + X for the on-screen keyboard.", keyboard: "Type your password and press Enter.", steam: "Press X for Steam's on-screen keyboard, type your password and press A.", remote: "Select the field for the on-screen keyboard." })[Input.type] } } Item { width: parent.width; height: 48 Btn { k: Input.g.back; text: "Back"; onClicked: app.act("back") } Btn { anchors.right: parent.right; k: Input.g.ok; text: "Apply"; primary: true; onClicked: screen.submit() } } diff --git a/ui/steamify-ui b/ui/steamify-ui index 8da4519..2fefa95 100755 --- a/ui/steamify-ui +++ b/ui/steamify-ui @@ -373,6 +373,9 @@ def main(): engine = QQmlApplicationEngine() engine.setInitialProperties({"backend": backend, "gamepad": pad, "fullscreen": fullscreen, + # Started from Steam: its keys are a Steam + # Controller's buttons (desktop layout). + "fromSteam": bool(os.environ.get("SteamGameId")), "iconUrl": QUrl.fromLocalFile(os.path.realpath(icon)).toString()}) engine.load(os.path.join(HERE, "qml", "Main.qml")) if not engine.rootObjects():