[plasma/plasma-mobile] containments/homescreens/folio: folio/appdrawer: App Gird Adjustments and Separate the Base Grid Logic to a New File for Reusability

Devin Lin <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 8cbbe5338a2c4b3bac5e8b0d892201e24c87aea0 by Devin Lin, on behalf of Micah Stanley.
Committed on 23/07/2026 at 00:43.
Pushed by devinlin into branch 'master'.

folio/appdrawer: App Gird Adjustments and Separate the Base Grid Logic to a New File for Reusability

- App drawer gird adjustments.
- Separate the base app drawer grid logic to a new file for reusability.

M  +2    -1    containments/homescreens/folio/CMakeLists.txt
M  +10   -3    containments/homescreens/folio/qml/AppDrawer.qml
A  +62   -0    containments/homescreens/folio/qml/AppDrawerAppGrid.qml     [License: GPL(v2.0+)]
M  +1    -1    containments/homescreens/folio/qml/FolioHomeScreen.qml
R  +26   -67   containments/homescreens/folio/qml/private/AppDrawerGrid.qml [from: containments/homescreens/folio/qml/AppDrawerGrid.qml - 055% similarity]

https://invent.kde.org/plasma/plasma-mobile/-/commit/8cbbe5338a2c4b3bac5e8b0d892201e24c87aea0

diff --git a/containments/homescreens/folio/CMakeLists.txt b/containments/homescreens/folio/CMakeLists.txt
index 960203dee..c3c76d778 100644
--- a/containments/homescreens/folio/CMakeLists.txt
+++ b/containments/homescreens/folio/CMakeLists.txt
@@ -6,7 +6,7 @@ add_definitions(-DTRANSLATION_DOMAIN=\"plasma_applet_org.kde.plasma.mobile.homes
 plasma_add_applet(org.kde.plasma.mobile.homescreen.folio
     QML_SOURCES
         qml/AppDrawer.qml
-        qml/AppDrawerGrid.qml
+        qml/AppDrawerAppGrid.qml
         qml/AppDrawerHeader.qml
         qml/DelegateDragItem.qml
         qml/DelegateDropArea.qml
@@ -62,6 +62,7 @@ ecm_target_qml_sources(org.kde.plasma.mobile.homescreen.folio SOURCES
     qml/private/WidgetHandlePosition.qml
     qml/private/WidgetResizeHandle.qml
     qml/private/WidgetResizeHandleFrame.qml
+    qml/private/AppDrawerGrid.qml
     PATH private
 )
 
diff --git a/containments/homescreens/folio/qml/AppDrawer.qml b/containments/homescreens/folio/qml/AppDrawer.qml
index a389b2054..d0d1d5264 100644
--- a/containments/homescreens/folio/qml/AppDrawer.qml
+++ b/containments/homescreens/folio/qml/AppDrawer.qml
@@ -42,6 +42,11 @@ Item {
         }
     }
 
+    function reset() {
+        root.flickable.contentY = 0 - root.flickable.topMargin;
+        root.flickable.returnToBounds();
+    }
+
     // App drawer container
     Item {
         anchors.fill: parent
@@ -79,16 +84,18 @@ Item {
         }
 
         // App list
-        AppDrawerGrid {
+        AppDrawerAppGrid {
             id: appDrawerGrid
             folio: root.folio
             homeScreen: root.homeScreen
             height: parent.height - drawerHeader.height
+            anchors.top: parent.top
+            anchors.topMargin: root.headerHeight
             anchors.left: parent.left
             anchors.right: parent.right
-            anchors.bottom: parent.bottom
             opacity: 0 // we display with the opacity gradient below
-            headerHeight: root.headerHeight
+
+            model: folio.ApplicationListSearchModel
 
             // Keyboard navigation
             topEdgeCallback: () => {
diff --git a/containments/homescreens/folio/qml/AppDrawerAppGrid.qml b/containments/homescreens/folio/qml/AppDrawerAppGrid.qml
new file mode 100644
index 000000000..4b69f266a
--- /dev/null
+++ b/containments/homescreens/folio/qml/AppDrawerAppGrid.qml
@@ -0,0 +1,62 @@
+/*
+    SPDX-FileCopyrightText: 2023 Devin Lin <[email protected]>
+    SPDX-FileCopyrightText: 2026 Micah Stanley <[email protected]>
+
+    SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+import QtQuick
+import org.kde.kirigami as Kirigami
+import org.kde.plasma.private.mobileshell as MobileShell
+import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio
+import "./delegate"
+import "./private"
+
+AppDrawerGrid {
+    id: root
+
+    readonly property int columns: baseColumns
+
+    cellWidth: Math.floor(effectiveContentWidth / columns)
+    cellHeight: Math.max(folio.FolioSettings.delegateIconSize + folio.HomeScreenState.pageDelegateLabelHeight + Kirigami.Units.gridUnit * 2, cellWidth * 0.75)
+
+    // separate margins for portrait mode as aesthetically it does not look great to have excessive padding when the screen height is larger then the width
+    readonly property real __portraitHorizontalMargin: Math.max(Kirigami.Units.largeSpacing, horizontalMargin * 0.25)
+
+    leftMargin: Screen.height > Screen.width ? __portraitHorizontalMargin : horizontalMargin
+    rightMargin: leftMargin
+
+    MobileShell.HapticsEffect {
+        id: haptics
+    }
+
+    delegate: AppDelegate {
+        folio: root.folio
+        shadow: false
+        application: model.delegate.application
+        width: root.cellWidth
+        height: root.cellHeight
+
+        onPressAndHold: {
+            // prevent editing if lock layout is enabled
+            if (folio.FolioSettings.lockLayout) return;
+
+            const mappedCoords = root.homeScreen.prepareStartDelegateDrag(model.delegate, delegateItem, true, true);
+            folio.HomeScreenState.closeAppDrawer();
+
+            haptics.buttonVibrate();
+
+            // we need to adjust because app drawer delegates have a different size than regular homescreen delegates
+            const centerX = mappedCoords.x + root.cellWidth / 2;
+            const centerY = mappedCoords.y + root.cellHeight / 2;
+
+            folio.HomeScreenState.startDelegateAppDrawerDrag(
+                centerX - folio.HomeScreenState.pageCellWidth / 2,
+                centerY - folio.HomeScreenState.pageCellHeight / 2,
+                pressPosition.x * (folio.HomeScreenState.pageCellWidth / root.cellWidth),
+                pressPosition.y * (folio.HomeScreenState.pageCellHeight / root.cellHeight),
+                model.delegate.application.storageId
+            );
+        }
+    }
+}
diff --git a/containments/homescreens/folio/qml/FolioHomeScreen.qml b/containments/homescreens/folio/qml/FolioHomeScreen.qml
index cff22dbf2..da4067f25 100644
--- a/containments/homescreens/folio/qml/FolioHomeScreen.qml
+++ b/containments/homescreens/folio/qml/FolioHomeScreen.qml
@@ -599,7 +599,7 @@ Item {
 
                     function onAppDrawerClosed() {
                         // reset app drawer position when closed
-                        appDrawer.flickable.contentY = 0;
+                        appDrawer.reset();
                     }
                 }
             }
diff --git a/containments/homescreens/folio/qml/AppDrawerGrid.qml b/containments/homescreens/folio/qml/private/AppDrawerGrid.qml
similarity index 55%
rename from containments/homescreens/folio/qml/AppDrawerGrid.qml
rename to containments/homescreens/folio/qml/private/AppDrawerGrid.qml
index 2b698d60e..615820bed 100644
--- a/containments/homescreens/folio/qml/AppDrawerGrid.qml
+++ b/containments/homescreens/folio/qml/private/AppDrawerGrid.qml
@@ -13,42 +13,47 @@ import org.kde.plasma.private.mobileshell as MobileShell
 import org.kde.plasma.private.mobileshell.state as MobileShellState
 import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio
 
-import "./delegate"
-
 MobileShell.GridView {
     id: root
+
     property Folio.HomeScreen folio
+    property var homeScreen
 
     cacheBuffer: cellHeight * 20
     reuseItems: true
     layer.enabled: true
-
     keyNavigationEnabled: true
     highlightMoveDuration: 0
     highlight: null // We supply our own highlight from the delegate
+    boundsBehavior: Flickable.DragAndOvershootBounds
 
-    property var homeScreen
-    property real headerHeight
-
-    readonly property int reservedSpaceForLabel: folio.HomeScreenState.pageDelegateLabelHeight
-    readonly property real effectiveContentWidth: width - leftMargin - rightMargin
-    readonly property real horizontalMargin: Math.round(width * 0.05)
-
-    leftMargin: horizontalMargin
-    rightMargin: horizontalMargin
+    // HACK: the first swipe from the top of the app drawer is done from HomeScreenState, not the flickable
+    //       due to issues with Flickable getting its swipe stolen by SwipeArea
+    interactive: (dragging || !atYBeginning) && folio.HomeScreenState.swipeState !== Folio.HomeScreenState.SwipingAppDrawerGrid
 
-    cellWidth: effectiveContentWidth / Math.min(Math.floor(effectiveContentWidth / (folio.FolioSettings.delegateIconSize + Kirigami.Units.largeSpacing * 3.5)), 8)
-    cellHeight: cellWidth + reservedSpaceForLabel
+    readonly property real __iconCellPadding: Kirigami.Units.largeSpacing * 5 // extra space reserved around the icons to fit comfortably within the grid
+    readonly property real __horizontalMarginLowerLimit: Kirigami.Units.largeSpacing
+    readonly property real __horizontalMarginUpperLimit: Kirigami.Units.gridUnit * 26
 
-    boundsBehavior: Flickable.DragAndOvershootBounds
+    // this value represent how many app icons can comfortably fit on the screen with a lower limit of the homescreen column value and a upper limit of 8
+    // we add a portion of the `horizontalMargin` value to the icon size to make sure the column value does not grow as much for the wider screen sizes
+    readonly property int baseColumns: Math.min(Math.max(Math.round(width / (folio.FolioSettings.delegateIconSize + __iconCellPadding + horizontalMargin * 0.5)), folio.FolioSettings.homeScreenColumns), 8)
+    readonly property real effectiveContentWidth: width - leftMargin - rightMargin
+    // make sure we set a lower limit for the `baseHorizontalMargin` and `horizontalMargin` so it never goes under `__horizontalMarginLowerLimit`
+    readonly property real baseHorizontalMargin: Math.max(Math.round(width * 0.125) - Kirigami.Units.gridUnit * 2.25, __horizontalMarginLowerLimit)
+    // we set an upper limit for the horizontal margins, as aesthetically for a grid full of apps, it looks better to not let the padding get too exessive
+    readonly property real horizontalMargin: Math.min(Math.max((root.width - __horizontalMarginUpperLimit) * 0.5, __horizontalMarginLowerLimit), baseHorizontalMargin)
 
-    readonly property int columns: Math.floor(effectiveContentWidth / cellWidth)
-    readonly property int rows: Math.ceil(root.count / columns)
+    // Keyboard focus on app delegate when it is the selected item
+    onCurrentItemChanged: {
+        if (currentItem) {
+            currentItem.keyboardFocus();
+        }
+    }
 
-    // HACK: the first swipe from the top of the app drawer is done from HomeScreenState, not the flickable
-    //       due to issues with Flickable getting its swipe stolen by SwipeArea
-    interactive: (dragging || !atYBeginning) // allow us to drag to the top
-                    && folio.HomeScreenState.swipeState !== Folio.HomeScreenState.SwipingAppDrawerGrid
+    Component.onCompleted: Qt.callLater(() => {
+        root.contentY = 0 - root.topMargin
+    })
 
     Connections {
         target: folio.HomeScreenState
@@ -82,51 +87,6 @@ MobileShell.GridView {
         id: velocityCalculator
     }
 
-    MobileShell.HapticsEffect {
-        id: haptics
-    }
-
-    model: folio.ApplicationListSearchModel
-
-    // Keyboard focus on app delegate when it is the selected item
-    onCurrentItemChanged: {
-        if (currentItem) {
-            currentItem.keyboardFocus();
-        }
-    }
-
-    delegate: AppDelegate {
-        id: appDelegate
-
-        folio: root.folio
-        shadow: false
-        application: model.delegate.application
-
-        width: root.cellWidth
-        height: root.cellHeight
-
-        onPressAndHold: {
-            // prevent editing if lock layout is enabled
-            if (folio.FolioSettings.lockLayout) return;
-
-            const mappedCoords = root.homeScreen.prepareStartDelegateDrag(model.delegate, appDelegate.delegateItem, true, true);
-            folio.HomeScreenState.closeAppDrawer();
-            haptics.buttonVibrate();
-
-            // we need to adjust because app drawer delegates have a different size than regular homescreen delegates
-            const centerX = mappedCoords.x + root.cellWidth / 2;
-            const centerY = mappedCoords.y + root.cellHeight / 2;
-
-            folio.HomeScreenState.startDelegateAppDrawerDrag(
-                centerX - folio.HomeScreenState.pageCellWidth / 2,
-                centerY - folio.HomeScreenState.pageCellHeight / 2,
-                appDelegate.pressPosition.x * (folio.HomeScreenState.pageCellWidth / root.cellWidth),
-                appDelegate.pressPosition.y * (folio.HomeScreenState.pageCellHeight / root.cellHeight),
-                model.delegate.application.storageId
-            );
-        }
-    }
-
     PC3.ScrollBar.vertical: PC3.ScrollBar {
         id: scrollBar
         interactive: true
@@ -139,7 +99,6 @@ MobileShell.GridView {
                 easing.type: Easing.InOutQuad
             }
         }
-
         contentItem: Rectangle {
             radius: width / 2
             color: Qt.rgba(1, 1, 1, 0.3)
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.