[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()
                     }
                 }
             }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.