mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
Open app drawer over windows in convergence mode
Drawer is inside the homescreen, which sits behind windows. Home button minimized everything to reach it. Render it in a LayerTop window instead and skip the blanket minimizeAll in the D-Bus handler.
This commit is contained in:
parent
c61642265b
commit
7fa2c20ab4
3 changed files with 128 additions and 41 deletions
|
|
@ -80,6 +80,13 @@ Item {
|
||||||
target: MobileShellState.ShellDBusClient
|
target: MobileShellState.ShellDBusClient
|
||||||
|
|
||||||
function onOpenHomeScreenRequested() {
|
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) {
|
if (windowMaximizedTracker.showingWindow) {
|
||||||
itemContainer.zoomIn();
|
itemContainer.zoomIn();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -515,26 +515,22 @@ Item {
|
||||||
transform: Translate { y: folderView.opacity > 0 ? 0 : folderView.height }
|
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 {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.bottomMargin: ShellSettings.Settings.convergenceModeEnabled ? favouritesBar.height : 0
|
visible: !ShellSettings.Settings.convergenceModeEnabled
|
||||||
visible: ShellSettings.Settings.convergenceModeEnabled && homeScreenState.appDrawerOpenProgress > 0
|
&& homeScreenState.appDrawerOpenProgress > 0
|
||||||
onClicked: folio.HomeScreenState.closeAppDrawer()
|
onClicked: folio.HomeScreenState.closeAppDrawer()
|
||||||
}
|
}
|
||||||
|
|
||||||
// bottom app drawer
|
// bottom app drawer (mobile only; convergence uses layer-shell overlay)
|
||||||
AppDrawer {
|
AppDrawer {
|
||||||
id: appDrawer
|
id: appDrawer
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
visible: !ShellSettings.Settings.convergenceModeEnabled
|
||||||
|
|
||||||
// Convergence: popup above dock; mobile: full-screen
|
width: parent.width
|
||||||
property bool isPopup: ShellSettings.Settings.convergenceModeEnabled
|
height: parent.height
|
||||||
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
|
|
||||||
|
|
||||||
homeScreen: root
|
homeScreen: root
|
||||||
|
|
||||||
|
|
@ -544,20 +540,11 @@ Item {
|
||||||
// position for animation
|
// position for animation
|
||||||
property real animationY: (1 - homeScreenState.appDrawerOpenProgress) * (Kirigami.Units.gridUnit * 2)
|
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
|
// Full-screen position
|
||||||
property real fullX: 0
|
x: 0
|
||||||
property real fullY: (opacity > 0) ? animationY : parent.height
|
y: (opacity > 0) ? animationY : parent.height
|
||||||
|
|
||||||
x: isPopup ? popupX : fullX
|
headerHeight: Math.round(Kirigami.Units.gridUnit * 4)
|
||||||
y: isPopup ? popupY : fullY
|
|
||||||
|
|
||||||
headerHeight: Math.round(Kirigami.Units.gridUnit * (appDrawer.isPopup ? 3 : 4))
|
|
||||||
headerItem: AppDrawerHeader {
|
headerItem: AppDrawerHeader {
|
||||||
id: appDrawerHeader
|
id: appDrawerHeader
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
|
@ -565,11 +552,11 @@ Item {
|
||||||
onReleaseFocusRequested: appDrawer.forceActiveFocus()
|
onReleaseFocusRequested: appDrawer.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account for panels (popup handles its own margins)
|
// Account for panels
|
||||||
topPadding: appDrawer.isPopup ? 0 : root.topMargin
|
topPadding: root.topMargin
|
||||||
bottomPadding: appDrawer.isPopup ? 0 : root.bottomMargin
|
bottomPadding: root.bottomMargin
|
||||||
leftPadding: appDrawer.isPopup ? 0 : root.leftMargin
|
leftPadding: root.leftMargin
|
||||||
rightPadding: appDrawer.isPopup ? 0 : root.rightMargin
|
rightPadding: root.rightMargin
|
||||||
|
|
||||||
// Forward keyboard text to the search bar
|
// Forward keyboard text to the search bar
|
||||||
Keys.onPressed: (event) => {
|
Keys.onPressed: (event) => {
|
||||||
|
|
|
||||||
|
|
@ -85,19 +85,36 @@ ContainmentItem {
|
||||||
MobileShellState.ShellDBusClient.closeActionDrawer();
|
MobileShellState.ShellDBusClient.closeActionDrawer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInWindow) {
|
if (ShellSettings.Settings.convergenceModeEnabled) {
|
||||||
// Only minimize windows and go to homescreen when not in docked mode
|
// Convergence: toggle the app drawer as a layer-shell overlay
|
||||||
if (!ShellSettings.Settings.convergenceModeEnabled) {
|
// without disturbing open windows.
|
||||||
folio.HomeScreenState.closeFolder();
|
switch (folio.HomeScreenState.viewState) {
|
||||||
folio.HomeScreenState.closeSearchWidget();
|
case Folio.HomeScreenState.AppDrawerView:
|
||||||
folio.HomeScreenState.closeAppDrawer();
|
folio.HomeScreenState.closeAppDrawer();
|
||||||
folio.HomeScreenState.goToPage(0, false);
|
break;
|
||||||
|
case Folio.HomeScreenState.FolderView:
|
||||||
WindowPlugin.WindowUtil.minimizeAll();
|
folio.HomeScreenState.closeFolder();
|
||||||
} else {
|
break;
|
||||||
// In convergence mode, toggle "show desktop" (minimize all to reveal homescreen)
|
case Folio.HomeScreenState.SearchWidgetView:
|
||||||
WindowPlugin.WindowUtil.minimizeAll();
|
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
|
// Always ensure settings view is closed
|
||||||
if (folio.HomeScreenState.viewState == Folio.HomeScreenState.SettingsView) {
|
if (folio.HomeScreenState.viewState == Folio.HomeScreenState.SettingsView) {
|
||||||
|
|
@ -107,7 +124,7 @@ ContainmentItem {
|
||||||
} else { // If we are already on the homescreen
|
} else { // If we are already on the homescreen
|
||||||
switch (folio.HomeScreenState.viewState) {
|
switch (folio.HomeScreenState.viewState) {
|
||||||
case Folio.HomeScreenState.PageView:
|
case Folio.HomeScreenState.PageView:
|
||||||
if (ShellSettings.Settings.convergenceModeEnabled || folio.HomeScreenState.currentPage === 0) {
|
if (folio.HomeScreenState.currentPage === 0) {
|
||||||
folio.HomeScreenState.openAppDrawer();
|
folio.HomeScreenState.openAppDrawer();
|
||||||
} else {
|
} else {
|
||||||
folio.HomeScreenState.goToPage(0, false);
|
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 {
|
MobileShell.HomeScreen {
|
||||||
id: homeScreen
|
id: homeScreen
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue