[plasma/plasma-setup] src/qml: feat: improve focus handling and Enter key navigation
Kristen McWilliam <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 331a30e75e5a741ea1e46b3bdcb6cc0b9deaaa21 by Kristen McWilliam, on behalf of l10n daemon script. Committed on 31/07/2026 at 15:19. Pushed by merritt into branch 'master'. feat: improve focus handling and Enter key navigation The change aims to improve keyboard navigation and focus handling. It includes: - "Begin Setup" button receives immediate focus (both when starting the app and when returning from Language page) - "Finish" button in the last page receives immediate focus - Enter/Return key now works when the following buttons receive focus: "Begin Setup", "Back", "Next", "Finish" - When the user is in the Landing page, using Tab will NOT cycle through the elements of Language page anymore - In whatever page the user is, using Tab will NOT cycle through the "Begin Setup" button of the Landing page anymore - On Desktop, Shut Down / Restart buttons are always visible and reachable (also via Tab) The implementation reuses the existing navigation methods and landing page signal instead of duplicating navigation logic. M +18 -3 src/qml/LandingComponent.qml M +9 -0 src/qml/Main.qml M +26 -1 src/qml/Wizard.qml https://invent.kde.org/plasma/plasma-setup/-/commit/331a30e75e5a741ea1e46b3bdcb6cc0b9deaaa21 diff --git a/src/qml/LandingComponent.qml b/src/qml/LandingComponent.qml index fec30ab..24d8c89 100644 --- a/src/qml/LandingComponent.qml +++ b/src/qml/LandingComponent.qml @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: 2023 Devin Lin <[email protected]> +// SPDX-FileCopyrightText: 2026 Tiziano Gaia <[email protected]> +// // SPDX-License-Identifier: GPL-2.0-or-later + import QtCore import QtQuick import QtQuick.Controls @@ -17,12 +20,16 @@ Item { readonly property real scaleLanding: 1.2 readonly property real scaleSteps: 1 + property bool landingActive: true + signal requestNextPage() - function returnToLanding() { + function activateLanding(): void { backgroundImage.scale = scaleLanding; contentOpacityAnim.to = 1; contentOpacityAnim.restart(); + + button.forceActiveFocus(Qt.TabFocusReason); } property real contentOpacity: 0 @@ -104,8 +111,6 @@ Item { anchors.bottomMargin: Kirigami.Units.gridUnit * 2 spacing: Kirigami.Units.largeSpacing - opacity: root.contentOpacity - // spacers expand only on roomy screens to keep center content centered Item { Layout.fillWidth: true @@ -115,6 +120,11 @@ Item { ColumnLayout { id: centerBlock + + enabled: root.landingActive + + opacity: root.contentOpacity + Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter spacing: Kirigami.Units.largeSpacing @@ -146,6 +156,9 @@ Item { contentOpacityAnim.restart(); root.requestNextPage() } + + Keys.onEnterPressed: clicked() + Keys.onReturnPressed: clicked() } } @@ -165,6 +178,8 @@ Item { Kirigami.Heading { id: poweredBy + + opacity: root.contentOpacity width: parent.width y: root.isNarrow ? 0 : (parent.height - height) / 2 diff --git a/src/qml/Main.qml b/src/qml/Main.qml index ff0f6dd..0b18735 100644 --- a/src/qml/Main.qml +++ b/src/qml/Main.qml @@ -1,4 +1,6 @@ // SPDX-FileCopyrightText: 2025 Carl Schwan <[email protected]> +// SPDX-FileCopyrightText: 2026 Tiziano Gaia <[email protected]> +// // SPDX-License-Identifier: LGPL-2.1-or-later import QtQuick @@ -19,7 +21,14 @@ Kirigami.AbstractApplicationWindow { // applications. quitAction.enabled: false + onActiveChanged: { + if (active) { + wizard.activateLanding(); + } + } + Wizard { + id: wizard anchors.fill: parent } } diff --git a/src/qml/Wizard.qml b/src/qml/Wizard.qml index c1c7616..4afb723 100644 --- a/src/qml/Wizard.qml +++ b/src/qml/Wizard.qml @@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: 2023 Devin Lin <[email protected]> // SPDX-FileCopyrightText: 2025 Kristen McWilliam <[email protected]> +// SPDX-FileCopyrightText: 2026 Tiziano Gaia <[email protected]> // // SPDX-License-Identifier: GPL-2.0-or-later @@ -72,6 +73,10 @@ Kirigami.Page { requestPreviousPage(); } + function activateLanding(): void { + landingComponent.activateLanding(); + } + function finishFinalPage(): void { // Finalize the initial setup process and exit the wizard. InitialStartUtil.finish(); @@ -101,6 +106,11 @@ Kirigami.Page { } currentIndex++; + + if (root.onFinalPage) { + finishButton.forceActiveFocus(Qt.TabFocusReason); + } + stepHeading.changeText(currentStepItem.name); currentStepItemX = root.width; @@ -119,7 +129,7 @@ Kirigami.Page { if (currentIndex === 0) { root.showingLanding = true; - landingComponent.returnToLanding(); + landingComponent.activateLanding(); } else { nextStepItemX = 0; @@ -141,6 +151,8 @@ Kirigami.Page { LandingComponent { id: landingComponent anchors.fill: parent + + landingActive: root.showingLanding /* * On desktop, the landing page remains visible as a backdrop while the wizard steps float over it as a card. * On mobile, the steps take up the full screen so the landing is hidden once the user navigates into the wizard (showingLanding becomes false). @@ -181,6 +193,8 @@ Kirigami.Page { id: stepsComponent anchors.fill: parent + enabled: !root.showingLanding + // animation when we switch to step stage opacity: root.showingLanding ? 0 : 1 property real translateY: root.showingLanding ? overlaySteps.height : 0 @@ -303,6 +317,9 @@ Kirigami.Page { icon.name: "arrow-left-symbolic" onClicked: root.requestPreviousPage() + + Keys.onEnterPressed: clicked() + Keys.onReturnPressed: clicked() } Item { @@ -321,9 +338,14 @@ Kirigami.Page { enabled: root.currentModule.nextEnabled onClicked: root.requestNextPage() + + Keys.onEnterPressed: clicked() + Keys.onReturnPressed: clicked() } Button { + id: finishButton + Layout.alignment: Qt.AlignRight visible: root.onFinalPage @@ -338,6 +360,9 @@ Kirigami.Page { // Finalize and exit the wizard. root.finishFinalPage(); } + + Keys.onEnterPressed: clicked() + Keys.onReturnPressed: clicked() } } }