diff --git a/components/mobileshell/qml/homescreen/HomeScreen.qml b/components/mobileshell/qml/homescreen/HomeScreen.qml index 57b37750..86fec21c 100644 --- a/components/mobileshell/qml/homescreen/HomeScreen.qml +++ b/components/mobileshell/qml/homescreen/HomeScreen.qml @@ -80,6 +80,13 @@ Item { target: MobileShellState.ShellDBusClient function onOpenHomeScreenRequested() { + if (ShellSettings.Settings.convergenceModeEnabled) { + // In convergence mode let the containment handle everything + // via homeTriggered → homeAction() without touching windows. + root.homeTriggered(); + return; + } + if (windowMaximizedTracker.showingWindow) { itemContainer.zoomIn(); } diff --git a/containments/homescreens/folio/qml/FolioHomeScreen.qml b/containments/homescreens/folio/qml/FolioHomeScreen.qml index 01ae9804..379f6b37 100644 --- a/containments/homescreens/folio/qml/FolioHomeScreen.qml +++ b/containments/homescreens/folio/qml/FolioHomeScreen.qml @@ -515,26 +515,22 @@ Item { transform: Translate { y: folderView.opacity > 0 ? 0 : folderView.height } } - // Click-to-dismiss overlay for popup drawer in convergence mode + // Click-to-dismiss overlay (mobile only; convergence uses layer-shell overlay) MouseArea { anchors.fill: parent - anchors.bottomMargin: ShellSettings.Settings.convergenceModeEnabled ? favouritesBar.height : 0 - visible: ShellSettings.Settings.convergenceModeEnabled && homeScreenState.appDrawerOpenProgress > 0 + visible: !ShellSettings.Settings.convergenceModeEnabled + && homeScreenState.appDrawerOpenProgress > 0 onClicked: folio.HomeScreenState.closeAppDrawer() } - // bottom app drawer + // bottom app drawer (mobile only; convergence uses layer-shell overlay) AppDrawer { id: appDrawer folio: root.folio + visible: !ShellSettings.Settings.convergenceModeEnabled - // Convergence: popup above dock; mobile: full-screen - property bool isPopup: ShellSettings.Settings.convergenceModeEnabled - property real popupWidth: Math.min(Kirigami.Units.gridUnit * 28, parent.width * 0.5) - property real popupHeight: Math.min(Kirigami.Units.gridUnit * 32, parent.height * 0.7) - - width: isPopup ? popupWidth : parent.width - height: isPopup ? popupHeight : parent.height + width: parent.width + height: parent.height homeScreen: root @@ -544,20 +540,11 @@ Item { // position for animation property real animationY: (1 - homeScreenState.appDrawerOpenProgress) * (Kirigami.Units.gridUnit * 2) - // Convergence popup position: above dock, left-aligned - property real popupX: root.leftMargin + Kirigami.Units.smallSpacing - property real popupY: (opacity > 0) - ? parent.height - favouritesBar.height - popupHeight - Kirigami.Units.smallSpacing + animationY - : parent.height - // Full-screen position - property real fullX: 0 - property real fullY: (opacity > 0) ? animationY : parent.height + x: 0 + y: (opacity > 0) ? animationY : parent.height - x: isPopup ? popupX : fullX - y: isPopup ? popupY : fullY - - headerHeight: Math.round(Kirigami.Units.gridUnit * (appDrawer.isPopup ? 3 : 4)) + headerHeight: Math.round(Kirigami.Units.gridUnit * 4) headerItem: AppDrawerHeader { id: appDrawerHeader folio: root.folio @@ -565,11 +552,11 @@ Item { onReleaseFocusRequested: appDrawer.forceActiveFocus() } - // Account for panels (popup handles its own margins) - topPadding: appDrawer.isPopup ? 0 : root.topMargin - bottomPadding: appDrawer.isPopup ? 0 : root.bottomMargin - leftPadding: appDrawer.isPopup ? 0 : root.leftMargin - rightPadding: appDrawer.isPopup ? 0 : root.rightMargin + // Account for panels + topPadding: root.topMargin + bottomPadding: root.bottomMargin + leftPadding: root.leftMargin + rightPadding: root.rightMargin // Forward keyboard text to the search bar Keys.onPressed: (event) => { diff --git a/containments/homescreens/folio/qml/main.qml b/containments/homescreens/folio/qml/main.qml index c5a897e7..8729c886 100644 --- a/containments/homescreens/folio/qml/main.qml +++ b/containments/homescreens/folio/qml/main.qml @@ -85,19 +85,36 @@ ContainmentItem { MobileShellState.ShellDBusClient.closeActionDrawer(); } - if (isInWindow) { - // Only minimize windows and go to homescreen when not in docked mode - if (!ShellSettings.Settings.convergenceModeEnabled) { - folio.HomeScreenState.closeFolder(); - folio.HomeScreenState.closeSearchWidget(); - folio.HomeScreenState.closeAppDrawer(); - folio.HomeScreenState.goToPage(0, false); - - WindowPlugin.WindowUtil.minimizeAll(); - } else { - // In convergence mode, toggle "show desktop" (minimize all to reveal homescreen) - WindowPlugin.WindowUtil.minimizeAll(); + if (ShellSettings.Settings.convergenceModeEnabled) { + // Convergence: toggle the app drawer as a layer-shell overlay + // without disturbing open windows. + switch (folio.HomeScreenState.viewState) { + case Folio.HomeScreenState.AppDrawerView: + folio.HomeScreenState.closeAppDrawer(); + break; + case Folio.HomeScreenState.FolderView: + folio.HomeScreenState.closeFolder(); + break; + case Folio.HomeScreenState.SearchWidgetView: + folio.HomeScreenState.closeSearchWidget(); + break; + case Folio.HomeScreenState.SettingsView: + folio.HomeScreenState.closeSettingsView(); + break; + default: + folio.HomeScreenState.openAppDrawer(); + break; } + return; + } + + if (isInWindow) { + folio.HomeScreenState.closeFolder(); + folio.HomeScreenState.closeSearchWidget(); + folio.HomeScreenState.closeAppDrawer(); + folio.HomeScreenState.goToPage(0, false); + + WindowPlugin.WindowUtil.minimizeAll(); // Always ensure settings view is closed if (folio.HomeScreenState.viewState == Folio.HomeScreenState.SettingsView) { @@ -107,7 +124,7 @@ ContainmentItem { } else { // If we are already on the homescreen switch (folio.HomeScreenState.viewState) { case Folio.HomeScreenState.PageView: - if (ShellSettings.Settings.convergenceModeEnabled || folio.HomeScreenState.currentPage === 0) { + if (folio.HomeScreenState.currentPage === 0) { folio.HomeScreenState.openAppDrawer(); } else { folio.HomeScreenState.goToPage(0, false); @@ -221,6 +238,82 @@ ContainmentItem { } } + // App-drawer overlay — renders the popup drawer above application + // windows in convergence mode. Same pattern as the dock overlay: + // a fullscreen layer-shell surface at LayerTop so that it appears + // over normal windows without minimizing them. + Window { + id: drawerOverlay + visible: ShellSettings.Settings.convergenceModeEnabled + && folio.HomeScreenState.appDrawerOpenProgress > 0 + color: "transparent" + width: Screen.width + height: Screen.height + + LayerShell.Window.scope: "drawer-overlay" + LayerShell.Window.layer: LayerShell.Window.LayerTop + LayerShell.Window.anchors: LayerShell.Window.AnchorTop | LayerShell.Window.AnchorBottom + | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight + LayerShell.Window.exclusionZone: -1 + LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityOnDemand + + // Click outside the popup to dismiss + MouseArea { + anchors.fill: parent + onClicked: folio.HomeScreenState.closeAppDrawer() + } + + AppDrawer { + id: overlayDrawer + folio: root.folio + homeScreen: folioHomeScreen + + readonly property real popupWidth: Math.min(Kirigami.Units.gridUnit * 28, parent.width * 0.5) + readonly property real popupHeight: Math.min(Kirigami.Units.gridUnit * 32, parent.height * 0.7) + readonly property real dockHeight: Kirigami.Units.gridUnit * 3 + + width: popupWidth + height: popupHeight + + opacity: folio.HomeScreenState.appDrawerOpenProgress < 0.5 + ? 0 : (folio.HomeScreenState.appDrawerOpenProgress - 0.5) * 2 + + property real animationY: (1 - folio.HomeScreenState.appDrawerOpenProgress) * (Kirigami.Units.gridUnit * 2) + + x: Kirigami.Units.smallSpacing + y: (opacity > 0) + ? parent.height - dockHeight - popupHeight - Kirigami.Units.smallSpacing + animationY + : parent.height + + headerHeight: Math.round(Kirigami.Units.gridUnit * 3) + headerItem: AppDrawerHeader { + id: overlayDrawerHeader + folio: root.folio + onReleaseFocusRequested: overlayDrawer.forceActiveFocus() + } + + Keys.onPressed: (event) => { + if (event.text.trim().length > 0) { + overlayDrawerHeader.addSearchText(event.text); + overlayDrawerHeader.forceActiveFocus(); + event.accepted = true; + } else if (event.key === Qt.Key_Left || event.key === Qt.Key_Right + || event.key === Qt.Key_Up || event.key === Qt.Key_Down) { + overlayDrawerHeader.forceActiveFocus(); + event.accepted = true; + } + } + + Connections { + target: folio.HomeScreenState + + function onAppDrawerOpened() { + overlayDrawer.forceActiveFocus(); + } + } + } + } + MobileShell.HomeScreen { id: homeScreen anchors.fill: parent