mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-06-25 07:37:42 +00:00
Compare commits
No commits in common. "30e3006e3fa539897ffe38b04397cae3b48db324" and "d9943d2e7a2db4c9dc83ea8d1e437f9c4a304569" have entirely different histories.
30e3006e3f
...
d9943d2e7a
33 changed files with 314 additions and 810 deletions
|
|
@ -56,13 +56,6 @@ MobileShell.SwipeArea {
|
|||
|
||||
anchors.fill: parent
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
hoverEnabled: true
|
||||
cursorShape: ShellSettings.Settings.convergenceModeEnabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
|
||||
onSwipeStarted: (point) => startSwipeWithPoint(point)
|
||||
onSwipeEnded: endSwipe()
|
||||
onSwipeMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => updateOffset(deltaY);
|
||||
|
|
|
|||
|
|
@ -6,12 +6,10 @@ import QtQuick.Controls 2.15
|
|||
import QtQuick.Window 2.2
|
||||
import QtQuick.Layouts
|
||||
|
||||
import org.kde.plasma.clock
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||
import org.kde.plasma.private.mobileshell as MobileShell
|
||||
import org.kde.plasma.components 3.0 as PC3
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.plasma.workspace.calendar as PlasmaCalendar
|
||||
import org.kde.plasma.private.mobileshell.quicksettingsplugin as QS
|
||||
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
|
||||
|
||||
|
|
@ -30,21 +28,12 @@ Item {
|
|||
readonly property bool swipeAreaMoving: swipeAreaBase.moving || swipeAreaPortrait.moving
|
||||
readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled
|
||||
readonly property real convergenceFrameThickness: MobileShell.Constants.convergenceWorkspaceFrameThickness
|
||||
readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight + convergenceFrameThickness
|
||||
readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight
|
||||
readonly property real convergenceSurfaceBottomInset: MobileShell.Constants.convergenceDockHeight + convergenceFrameThickness
|
||||
readonly property real convergenceSurfaceSideInset: 0
|
||||
readonly property real convergenceSurfaceWidth: Math.max(0, width - convergenceSurfaceSideInset * 2)
|
||||
readonly property real convergenceSurfaceHeight: Math.max(0, height - convergenceSurfaceTopInset - convergenceSurfaceBottomInset)
|
||||
readonly property real convergenceFloatingMargin: Kirigami.Units.gridUnit
|
||||
readonly property real convergenceClickAwayGutter: Kirigami.Units.largeSpacing
|
||||
readonly property real convergenceBottomClickAwayHeight: Kirigami.Units.gridUnit * 2
|
||||
readonly property real convergenceLeftSurfaceBottomInset: convergenceSurfaceBottomInset + convergenceBottomClickAwayHeight
|
||||
readonly property real convergenceQuickSettingsLeft: contentContainerLoader.item ? contentContainerLoader.item.quickSettingsPanelLeft : convergenceSurfaceWidth * 0.5
|
||||
readonly property real convergenceNotificationRightMargin: Math.max(convergenceSurfaceSideInset, width - Math.max(convergenceSurfaceSideInset, convergenceQuickSettingsLeft - convergenceClickAwayGutter))
|
||||
readonly property real convergenceLeftSurfaceTopInset: convergenceSurfaceTopInset + convergenceFloatingMargin
|
||||
readonly property real convergenceLeftSurfaceLeftInset: convergenceSurfaceSideInset + convergenceFloatingMargin
|
||||
readonly property real convergenceLeftSurfaceRightInset: convergenceNotificationRightMargin + convergenceFloatingMargin
|
||||
readonly property real convergenceLeftSurfaceBottomMargin: convergenceLeftSurfaceBottomInset + convergenceFloatingMargin
|
||||
readonly property real convergenceNotificationRightMargin: Math.max(convergenceSurfaceSideInset, width - (convergenceSurfaceSideInset + convergenceSurfaceWidth * 0.5))
|
||||
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
|
||||
Kirigami.Theme.inherit: false
|
||||
|
|
@ -110,28 +99,6 @@ Item {
|
|||
LayoutItemProxy { target: contentContainerLoader }
|
||||
}
|
||||
|
||||
Item {
|
||||
id: convergenceLeftSurface
|
||||
|
||||
visible: root.isConvergence && actionDrawer.mode != MobileShell.ActionDrawer.Portrait
|
||||
opacity: Math.max(0, Math.min(root.brightnessPressedValue, actionDrawer.offsetResistance / root.minimizedQuickSettingsOffset))
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
topMargin: root.convergenceLeftSurfaceTopInset
|
||||
leftMargin: root.convergenceLeftSurfaceLeftInset
|
||||
rightMargin: root.convergenceLeftSurfaceRightInset
|
||||
bottomMargin: root.convergenceLeftSurfaceBottomMargin
|
||||
}
|
||||
|
||||
MobileShell.PanelBackground {
|
||||
anchors.fill: parent
|
||||
panelType: MobileShell.PanelBackground.PanelType.Drawer
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse area for dismissing action drawer in portrait mode when background is clicked.
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
|
@ -151,8 +118,8 @@ Item {
|
|||
|
||||
anchors {
|
||||
topMargin: notificationDrawer.y + notificationDrawer.height + 1
|
||||
leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (notificationDrawer.isConvergence ? root.convergenceLeftSurfaceLeftInset : 10)
|
||||
rightMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (notificationDrawer.isConvergence ? root.convergenceLeftSurfaceRightInset : notificationDrawer.notificationWidget.anchors.rightMargin + Kirigami.Units.gridUnit - notificationDrawer.anchors.leftMargin + 370)
|
||||
leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (notificationDrawer.isConvergence ? root.convergenceSurfaceSideInset : 10)
|
||||
rightMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (notificationDrawer.isConvergence ? root.convergenceNotificationRightMargin : notificationDrawer.notificationWidget.anchors.rightMargin + Kirigami.Units.gridUnit - notificationDrawer.anchors.leftMargin + 370)
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
|
|
@ -198,67 +165,6 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: convergenceMediaPanel
|
||||
|
||||
visible: root.isConvergence
|
||||
&& actionDrawer.mode != MobileShell.ActionDrawer.Portrait
|
||||
&& root.mediaControlsWidget.visible
|
||||
opacity: Math.max(0, Math.min(root.brightnessPressedValue, actionDrawer.offsetResistance / root.minimizedQuickSettingsOffset))
|
||||
height: visible ? root.mediaControlsWidget.implicitHeight : 0
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
topMargin: notificationDrawer.hasNotifications
|
||||
? toolButtons.y + toolButtons.height + Kirigami.Units.smallSpacing
|
||||
: notificationDrawer.y + notificationDrawer.height + Kirigami.Units.largeSpacing
|
||||
leftMargin: root.convergenceLeftSurfaceLeftInset + Kirigami.Units.largeSpacing
|
||||
rightMargin: root.convergenceLeftSurfaceRightInset + Kirigami.Units.largeSpacing
|
||||
}
|
||||
|
||||
LayoutItemProxy {
|
||||
anchors.fill: parent
|
||||
target: root.mediaControlsWidget
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: convergenceCalendarPanel
|
||||
|
||||
visible: root.isConvergence && actionDrawer.mode != MobileShell.ActionDrawer.Portrait
|
||||
opacity: Math.max(0, Math.min(root.brightnessPressedValue, actionDrawer.offsetResistance / root.minimizedQuickSettingsOffset))
|
||||
clip: true
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
topMargin: convergenceMediaPanel.visible
|
||||
? convergenceMediaPanel.y + convergenceMediaPanel.height + Kirigami.Units.largeSpacing
|
||||
: notificationDrawer.hasNotifications
|
||||
? toolButtons.y + toolButtons.height + Kirigami.Units.largeSpacing
|
||||
: notificationDrawer.y + notificationDrawer.height + Kirigami.Units.largeSpacing
|
||||
leftMargin: root.convergenceLeftSurfaceLeftInset + Kirigami.Units.largeSpacing
|
||||
rightMargin: root.convergenceLeftSurfaceRightInset + Kirigami.Units.largeSpacing
|
||||
bottomMargin: root.convergenceLeftSurfaceBottomMargin + Kirigami.Units.largeSpacing
|
||||
}
|
||||
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
Kirigami.Theme.inherit: false
|
||||
|
||||
PlasmaCalendar.MonthView {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Kirigami.Units.smallSpacing
|
||||
|
||||
borderOpacity: 0.25
|
||||
today: calendarClock.dateTime
|
||||
eventPluginsManager: eventPluginsManager
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// notification drawer ui
|
||||
|
|
@ -267,6 +173,7 @@ Item {
|
|||
id: notificationDrawer
|
||||
|
||||
readonly property bool isConvergence: root.isConvergence
|
||||
|
||||
swipeArea: swipeAreaPortrait
|
||||
actionDrawer: root.actionDrawer
|
||||
mediaControlsWidget: root.mediaControlsWidget
|
||||
|
|
@ -280,12 +187,13 @@ Item {
|
|||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
topMargin: isConvergence ? root.convergenceLeftSurfaceTopInset : 0
|
||||
rightMargin: root.actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (isConvergence ? root.convergenceLeftSurfaceRightInset : 360)
|
||||
leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (isConvergence ? root.convergenceLeftSurfaceLeftInset : notificationDrawer.minWidthHeight * 0.06)
|
||||
topMargin: isConvergence ? root.convergenceSurfaceTopInset : 0
|
||||
rightMargin: root.actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (isConvergence ? root.convergenceNotificationRightMargin : 360)
|
||||
leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (isConvergence ? root.convergenceSurfaceSideInset : notificationDrawer.minWidthHeight * 0.06)
|
||||
}
|
||||
|
||||
maximumHeight: isConvergence ? root.convergenceSurfaceHeight * 0.32 : -1
|
||||
// In convergence, cap the height so it doesn't stretch full-screen
|
||||
maximumHeight: isConvergence ? root.convergenceSurfaceHeight * 0.6 : -1
|
||||
toolButtonsItem: toolButtons
|
||||
}
|
||||
|
||||
|
|
@ -393,12 +301,4 @@ Item {
|
|||
id: mediaWidget
|
||||
opacity: brightnessPressedValue
|
||||
}
|
||||
|
||||
Clock {
|
||||
id: calendarClock
|
||||
}
|
||||
|
||||
PlasmaCalendar.EventPluginsManager {
|
||||
id: eventPluginsManager
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls as QQC2
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Shapes 1.8
|
||||
import QtQuick.Window
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
|
@ -30,14 +29,13 @@ Item {
|
|||
readonly property real maximizedQuickSettingsOffset: height
|
||||
readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled
|
||||
readonly property real convergenceFrameThickness: MobileShell.Constants.convergenceWorkspaceFrameThickness
|
||||
readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight + convergenceFrameThickness
|
||||
readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight
|
||||
readonly property real convergenceSurfaceBottomInset: MobileShell.Constants.convergenceDockHeight + convergenceFrameThickness
|
||||
readonly property real convergenceSurfaceSideInset: 0
|
||||
readonly property real convergenceSurfaceWidth: Math.max(0, width - convergenceSurfaceSideInset * 2)
|
||||
readonly property real convergenceSurfaceHeight: Math.max(0, height - convergenceSurfaceTopInset - convergenceSurfaceBottomInset)
|
||||
readonly property bool isOnLargeScreen: width > quickSettingsPanel.width * 2.5
|
||||
readonly property real minWidthHeight: Math.min(root.width, root.height)
|
||||
readonly property real quickSettingsPanelLeft: quickSettingsPanel.x
|
||||
readonly property real opacityValue: Math.max(0, Math.min(1, actionDrawer.offsetResistance / root.minimizedQuickSettingsOffset))
|
||||
readonly property double brightnessPressedValue: quickSettings.brightnessPressedValue
|
||||
|
||||
|
|
@ -50,48 +48,9 @@ Item {
|
|||
// dismiss drawer when background is clicked
|
||||
onClicked: root.actionDrawer.close();
|
||||
|
||||
Shape {
|
||||
id: actionDrawerSurface
|
||||
x: quickSettingsPanel.x - cornerRadius
|
||||
y: quickSettingsPanel.y
|
||||
width: bodyWidth + cornerRadius
|
||||
height: quickSettingsPanel.height
|
||||
opacity: root.isConvergence ? quickSettingsPanel.opacity * root.brightnessPressedValue : 0
|
||||
visible: opacity > 0 && bodyWidth > 0 && height > 0
|
||||
z: 0
|
||||
preferredRendererType: Shape.CurveRenderer
|
||||
asynchronous: true
|
||||
enabled: false
|
||||
|
||||
readonly property real bodyWidth: quickSettingsPanel.width
|
||||
readonly property real cornerRadius: Math.min(MobileShell.Constants.convergenceWorkspaceFrameRadius,
|
||||
Math.max(0.01, Math.min(bodyWidth, height) / 2))
|
||||
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
|
||||
ShapePath {
|
||||
id: actionDrawerSurfacePath
|
||||
readonly property real cornerRadius: actionDrawerSurface.cornerRadius
|
||||
|
||||
fillColor: Kirigami.Theme.backgroundColor
|
||||
strokeWidth: 0
|
||||
startX: actionDrawerSurface.width
|
||||
startY: 0
|
||||
|
||||
PathLine { x: 0; y: 0 }
|
||||
PathArc { x: actionDrawerSurfacePath.cornerRadius; y: actionDrawerSurfacePath.cornerRadius; radiusX: actionDrawerSurfacePath.cornerRadius; radiusY: actionDrawerSurfacePath.cornerRadius; direction: PathArc.Clockwise }
|
||||
PathLine { x: actionDrawerSurfacePath.cornerRadius; y: actionDrawerSurface.height - actionDrawerSurfacePath.cornerRadius }
|
||||
PathArc { x: 0; y: actionDrawerSurface.height; radiusX: actionDrawerSurfacePath.cornerRadius; radiusY: actionDrawerSurfacePath.cornerRadius; direction: PathArc.Clockwise }
|
||||
PathLine { x: actionDrawerSurface.width; y: actionDrawerSurface.height }
|
||||
PathLine { x: actionDrawerSurface.width; y: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
// right sidebar
|
||||
MobileShell.QuickSettingsPanel {
|
||||
id: quickSettingsPanel
|
||||
z: 1
|
||||
height: Math.min(quickSettingsPanel.contentImplicitHeight + quickSettingsPanel.topPadding + quickSettingsPanel.bottomPadding, quickSettingsPanel.availableHeight)
|
||||
width: Math.min(intendedWidth, quickSettingsPanel.availableWidth)
|
||||
|
||||
|
|
|
|||
|
|
@ -46,15 +46,8 @@ Item {
|
|||
|
||||
height: {
|
||||
let toolH = toolButtonsItem ? toolButtonsItem.height : 0;
|
||||
let avail = actionDrawer.height - toolH;
|
||||
let content = notificationWidget.listView.contentHeight + Kirigami.Units.largeSpacing + topMargin;
|
||||
// When empty, reserve the external cap so the placeholder has room;
|
||||
// when populated, hug content so the clear-all toolbar sits below the list.
|
||||
if (maximumHeight > 0 && !hasNotifications) {
|
||||
return Math.min(avail, maximumHeight);
|
||||
}
|
||||
let cap = maximumHeight > 0 ? Math.min(avail, maximumHeight) : avail;
|
||||
return Math.min(cap, content);
|
||||
let h = Math.min(actionDrawer.height - toolH, notificationWidget.listView.contentHeight + Kirigami.Units.largeSpacing + topMargin);
|
||||
return maximumHeight > 0 ? Math.min(h, maximumHeight) : h;
|
||||
}
|
||||
|
||||
// time source for the time and date whenin landscape mode
|
||||
|
|
@ -70,11 +63,10 @@ Item {
|
|||
// margin adjusted to fit and position into the action drawer
|
||||
MobileShell.NotificationsWidget {
|
||||
id: notificationWidget
|
||||
readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: root.topMargin + (isConvergence ? Kirigami.Units.gridUnit : 0)
|
||||
anchors.rightMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (isConvergence ? Kirigami.Units.gridUnit : Math.max(root.width - Kirigami.Units.gridUnit * 25, 0))
|
||||
anchors.leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (isConvergence ? Kirigami.Units.gridUnit : -Kirigami.Units.gridUnit)
|
||||
anchors.topMargin: root.topMargin
|
||||
anchors.rightMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : Math.max(root.width - Kirigami.Units.gridUnit * 25, 0)
|
||||
anchors.leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : -Kirigami.Units.gridUnit
|
||||
|
||||
historyModel: actionDrawer.notificationModel
|
||||
historyModelType: actionDrawer.notificationModelType
|
||||
|
|
@ -83,8 +75,6 @@ Item {
|
|||
onUnlockRequested: actionDrawer.permissionsRequested()
|
||||
topPadding: root.topPadding
|
||||
showHeader: actionDrawer.mode != MobileShell.ActionDrawer.Portrait
|
||||
&& !ShellSettings.Settings.convergenceModeEnabled
|
||||
emptyText: ShellSettings.Settings.convergenceModeEnabled ? i18n("No notifications") : ""
|
||||
listView.interactive: !actionDrawer.dragging && root.listOverflowing
|
||||
|
||||
cardColorScheme: Kirigami.Theme.View
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ MobileShell.BaseItem {
|
|||
background: MobileShell.PanelBackground {
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.isConvergence ? 0 : Kirigami.Units.largeSpacing
|
||||
visible: !root.isConvergence
|
||||
panelType: root.isConvergence ? MobileShell.PanelBackground.PanelType.Flat : MobileShell.PanelBackground.PanelType.Base
|
||||
radius: root.isConvergence ? 0 : Kirigami.Units.cornerRadius
|
||||
opacity: brightnessPressedValue
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ Item {
|
|||
property Item contentItem: Item {}
|
||||
property Item background: Item {}
|
||||
|
||||
implicitHeight: topPadding + bottomPadding + (contentItem ? contentItem.implicitHeight : 0)
|
||||
implicitWidth: leftPadding + rightPadding + (contentItem ? contentItem.implicitWidth : 0)
|
||||
implicitHeight: topPadding + bottomPadding + contentItem.implicitHeight
|
||||
implicitWidth: leftPadding + rightPadding + contentItem.implicitWidth
|
||||
|
||||
onContentItemChanged: {
|
||||
if (contentItem !== null && contentItem !== undefined) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ Item {
|
|||
// 'popupWidth' and 'openOffset' is set by the 'notificationPopupManager'
|
||||
property int popupWidth
|
||||
property real openOffset
|
||||
property real convergenceBottomInset: openOffset
|
||||
property bool isConvergence: false
|
||||
readonly property int primaryAnimationDuration: Math.round(MobileShell.Motion.duration(MobileShell.Motion.SpatialSlow) * 1.5)
|
||||
readonly property int secondaryAnimationDuration: MobileShell.Motion.duration(MobileShell.Motion.SpatialSlow)
|
||||
|
|
@ -36,7 +35,7 @@ Item {
|
|||
|
||||
// In convergence the popup enters from the bottom-right corner
|
||||
readonly property real effectiveOpenOffset: isConvergence
|
||||
? (Screen.height - convergenceBottomInset - popupHeight)
|
||||
? (Screen.height - openOffset - popupHeight)
|
||||
: openOffset
|
||||
readonly property real effectiveClosedOffset: isConvergence
|
||||
? (Screen.height + Kirigami.Units.smallSpacing)
|
||||
|
|
|
|||
|
|
@ -33,8 +33,9 @@ Window {
|
|||
readonly property real openOffset: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 3
|
||||
readonly property int longestLength: Math.max(Screen.width, Screen.height)
|
||||
readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled
|
||||
readonly property real convergencePopupMargin: MobileShell.Constants.convergenceWorkspaceFrameThickness + Kirigami.Units.largeSpacing
|
||||
readonly property real convergencePopupBottomInset: MobileShell.Constants.convergenceDockHeight + MobileShell.Constants.convergenceWorkspaceFrameThickness + Kirigami.Units.largeSpacing
|
||||
// Margin between popup and screen edge in convergence mode; used in both
|
||||
// the delegate x position and the input-region calculation so they stay in sync.
|
||||
readonly property real convergencePopupMargin: Kirigami.Units.gridUnit * 2
|
||||
readonly property int popupAnimationDuration: Math.round(MobileShell.Motion.duration(MobileShell.Motion.SpatialSlow) * 1.5)
|
||||
property var keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
|
||||
|
||||
|
|
@ -103,9 +104,9 @@ Window {
|
|||
}
|
||||
|
||||
if (isConvergence) {
|
||||
let regionX = notificationPopupManager.width - notificationPopupManager.popupWidth - notificationPopupManager.convergencePopupMargin - Kirigami.Units.gridUnit / 2;
|
||||
let regionY = (currentPopup ? currentPopup.effectiveOpenOffset : Screen.height - notificationPopupManager.convergencePopupBottomInset - popupHeight) - Kirigami.Units.gridUnit / 2;
|
||||
ShellUtil.setInputRegion(notificationPopupManager, Qt.rect(regionX, regionY, notificationPopupManager.popupWidth + Kirigami.Units.gridUnit, popupHeight + Kirigami.Units.gridUnit));
|
||||
let regionX = notificationPopupManager.width - notificationPopupManager.popupWidth - notificationPopupManager.convergencePopupMargin;
|
||||
let regionY = openOffset;
|
||||
ShellUtil.setInputRegion(notificationPopupManager, Qt.rect(regionX, regionY, notificationPopupManager.popupWidth + Kirigami.Units.gridUnit * 2, popupHeight + Kirigami.Units.gridUnit * 2));
|
||||
} else {
|
||||
ShellUtil.setInputRegion(notificationPopupManager, Qt.rect((notificationPopupManager.width - notificationPopupManager.popupWidth - Kirigami.Units.gridUnit) / 2, openOffset - Kirigami.Units.gridUnit / 2, notificationPopupManager.popupWidth + Kirigami.Units.gridUnit, popupHeight + Kirigami.Units.gridUnit * ((notifications.count - notifications.currentPopupIndex > 1) ? 4 : 1)));
|
||||
}
|
||||
|
|
@ -206,14 +207,13 @@ Window {
|
|||
id: popup
|
||||
|
||||
x: notificationPopupManager.isConvergence
|
||||
? (notificationPopupManager.width - width - notificationPopupManager.convergencePopupMargin)
|
||||
: (notificationPopupManager.width - width) / 2
|
||||
? (parent.width - width - notificationPopupManager.convergencePopupMargin)
|
||||
: (parent.width - width) / 2
|
||||
z: notifications.count - index
|
||||
|
||||
isConvergence: notificationPopupManager.isConvergence
|
||||
popupWidth: notificationPopupManager.popupWidth
|
||||
openOffset: notificationPopupManager.openOffset
|
||||
convergenceBottomInset: notificationPopupManager.convergencePopupBottomInset
|
||||
|
||||
keyboardInteractivity: notificationPopupManager.keyboardInteractivity
|
||||
popupNotifications: notifications
|
||||
|
|
|
|||
|
|
@ -78,12 +78,10 @@ Item {
|
|||
signal dragEnd()
|
||||
|
||||
onContentItemChanged: {
|
||||
if (!contentItem) {
|
||||
return;
|
||||
}
|
||||
contentItem.parent = contentParent;
|
||||
contentItem.anchors.fill = contentParent;
|
||||
contentItem.anchors.margins = Kirigami.Units.largeSpacing;
|
||||
contentParent.children.push(contentItem);
|
||||
}
|
||||
|
||||
implicitHeight: contentParent.implicitHeight
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls as Controls
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
|
|
@ -59,6 +58,7 @@ BaseNotificationItem {
|
|||
onDismissRequested: {
|
||||
model.resident = false;
|
||||
notificationItem.dismissRequested();
|
||||
notificationItem.close();
|
||||
}
|
||||
|
||||
onDragStart: notificationItem.dragStart()
|
||||
|
|
@ -116,17 +116,6 @@ BaseNotificationItem {
|
|||
time: notificationItem.time
|
||||
clockSource: notificationItem.clockSource
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
visible: notificationItem.closable
|
||||
icon.name: "window-close"
|
||||
text: i18n("Dismiss")
|
||||
display: Controls.AbstractButton.IconOnly
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
|
||||
Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium
|
||||
onClicked: mainCard.dismissRequested()
|
||||
}
|
||||
}
|
||||
|
||||
// notification contents
|
||||
|
|
|
|||
|
|
@ -86,8 +86,6 @@ Item {
|
|||
*/
|
||||
property bool showHeader: false
|
||||
|
||||
property string emptyText: ""
|
||||
|
||||
/**
|
||||
* Gives access to the notification list view outside of the notification widget.
|
||||
*/
|
||||
|
|
@ -181,32 +179,6 @@ Item {
|
|||
id: clock
|
||||
}
|
||||
|
||||
// Empty-state placeholders centred in the full widget rather than the
|
||||
// (possibly tiny) ListView so they don't clip out of view.
|
||||
PlasmaExtras.PlaceholderMessage {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - (Kirigami.Units.gridUnit * 4)
|
||||
|
||||
text: i18n("Notification service not available")
|
||||
visible: list.count === 0 && !NotificationManager.Server.valid && historyModelType === NotificationsModelType.NotificationsModel
|
||||
|
||||
PlasmaComponents3.Label {
|
||||
readonly property NotificationManager.ServerInfo currentOwner: !NotificationManager.Server.valid ? NotificationManager.Server.currentOwner : null
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
text: currentOwner ? i18nc("Vendor and product name", "Notifications are currently provided by '%1 %2'", currentOwner.vendor, currentOwner.name) : ""
|
||||
visible: currentOwner && currentOwner.vendor && currentOwner.name
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaExtras.PlaceholderMessage {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - (Kirigami.Units.gridUnit * 4)
|
||||
|
||||
text: root.emptyText
|
||||
visible: list.count === 0 && root.emptyText.length > 0 && NotificationManager.Server.valid
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: list
|
||||
model: historyModel
|
||||
|
|
@ -278,6 +250,24 @@ Item {
|
|||
criteria: ViewSection.FullString
|
||||
}
|
||||
|
||||
PlasmaExtras.PlaceholderMessage {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - (Kirigami.Units.gridUnit * 4)
|
||||
|
||||
text: i18n("Notification service not available")
|
||||
visible: list.count === 0 && !NotificationManager.Server.valid && historyModelType === NotificationsModelType.NotificationsModel
|
||||
|
||||
PlasmaComponents3.Label {
|
||||
// Checking valid to avoid creating ServerInfo object if everything is alright
|
||||
readonly property NotificationManager.ServerInfo currentOwner: !NotificationManager.Server.valid ? NotificationManager.Server.currentOwner : null
|
||||
// PlasmaExtras.PlaceholderMessage is internally a ColumnLayout, so we can use Layout.whatever properties here
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
text: currentOwner ? i18nc("Vendor and product name", "Notifications are currently provided by '%1 %2'", currentOwner.vendor, currentOwner.name) : ""
|
||||
visible: currentOwner && currentOwner.vendor && currentOwner.name
|
||||
}
|
||||
}
|
||||
|
||||
// Run every time an item is visually added to the list, thus when `Show n more` button is clicked as well.
|
||||
add: Transition {
|
||||
MobileShell.MotionNumberAnimation { property: "opacity"; from: 0; to: 1; duration: list.animationDuration; type: MobileShell.Motion.Standard }
|
||||
|
|
|
|||
|
|
@ -121,22 +121,12 @@ void ShellUtil::setWindowLayer(QQuickWindow *window, LayerShellQt::Window::Layer
|
|||
}
|
||||
|
||||
void ShellUtil::setInputRegion(QWindow *window, const QRect ®ion)
|
||||
{
|
||||
setInputRegions(window, region.isEmpty() ? QVariantList{} : QVariantList{region});
|
||||
}
|
||||
|
||||
void ShellUtil::setInputRegions(QWindow *window, const QVariantList ®ions)
|
||||
{
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto handle = window->handle();
|
||||
if (!handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(handle);
|
||||
auto waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(window->handle());
|
||||
if (!waylandWindow) {
|
||||
qWarning() << "Failed to retrieve Wayland window handle.";
|
||||
return;
|
||||
|
|
@ -160,17 +150,12 @@ void ShellUtil::setInputRegions(QWindow *window, const QVariantList ®ions)
|
|||
return;
|
||||
}
|
||||
|
||||
if (regions.isEmpty()) {
|
||||
if (region.isEmpty()) {
|
||||
wl_surface_set_input_region(surface, nullptr);
|
||||
} else {
|
||||
wl_region *inputRegion = wl_compositor_create_region(compositorResource);
|
||||
|
||||
for (const QVariant &value : regions) {
|
||||
const QRect region = value.toRect();
|
||||
if (!region.isEmpty()) {
|
||||
wl_region_add(inputRegion, region.x(), region.y(), region.width(), region.height());
|
||||
}
|
||||
}
|
||||
wl_region_add(inputRegion, region.x(), region.y(), region.width(), region.height());
|
||||
wl_surface_set_input_region(surface, inputRegion);
|
||||
wl_region_destroy(inputRegion);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include <QObject>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWindow>
|
||||
#include <QVariantList>
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
#include <KConfigWatcher>
|
||||
|
|
@ -85,13 +84,6 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE void setInputRegion(QWindow *window, const QRect ®ion);
|
||||
|
||||
/**
|
||||
* Sets multiple regions where inputs will get registered on a window.
|
||||
* Inputs outside the regions will pass through to the surface below.
|
||||
* Set this to an empty list to fill the whole window again.
|
||||
*/
|
||||
Q_INVOKABLE void setInputRegions(QWindow *window, const QVariantList ®ions);
|
||||
|
||||
/**
|
||||
* Converts rich text to plain text.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -9,48 +9,14 @@
|
|||
#include <KWindowSystem>
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusReply>
|
||||
#include <QDBusVariant>
|
||||
#include <QDebug>
|
||||
#include <QQmlEngine>
|
||||
#include <QQmlExtensionPlugin>
|
||||
#include <QQuickItem>
|
||||
#include <QTimer>
|
||||
|
||||
K_PLUGIN_CLASS_WITH_JSON(HomeScreen, "metadata.json")
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const QString s_kwinService = QStringLiteral("org.kde.KWin");
|
||||
const QString s_kwinEffectsPath = QStringLiteral("/Effects");
|
||||
const QString s_kwinEffectsInterface = QStringLiteral("org.kde.kwin.Effects");
|
||||
const QString s_dbusPropertiesInterface = QStringLiteral("org.freedesktop.DBus.Properties");
|
||||
|
||||
QStringList effectListFromVariant(const QVariant &value)
|
||||
{
|
||||
QVariant effectValue = value;
|
||||
if (effectValue.canConvert<QDBusVariant>()) {
|
||||
effectValue = effectValue.value<QDBusVariant>().variant();
|
||||
}
|
||||
|
||||
if (effectValue.canConvert<QStringList>()) {
|
||||
return effectValue.toStringList();
|
||||
}
|
||||
|
||||
QStringList effects;
|
||||
const QVariantList effectList = effectValue.toList();
|
||||
effects.reserve(effectList.size());
|
||||
for (const QVariant &effect : effectList) {
|
||||
effects.append(effect.toString());
|
||||
}
|
||||
return effects;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
|
||||
: Plasma::Containment{parent, data, args}
|
||||
, m_folioSettings{new FolioSettings{this}}
|
||||
|
|
@ -68,20 +34,6 @@ HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVari
|
|||
|
||||
connect(KWindowSystem::self(), &KWindowSystem::showingDesktopChanged, this, &HomeScreen::showingDesktopChanged);
|
||||
|
||||
updateOverviewActive();
|
||||
QDBusConnection::sessionBus().connect(s_kwinService,
|
||||
s_kwinEffectsPath,
|
||||
s_dbusPropertiesInterface,
|
||||
QStringLiteral("PropertiesChanged"),
|
||||
this,
|
||||
SLOT(onOverviewEffectsChanged(QString, QVariantMap, QStringList)));
|
||||
|
||||
auto overviewRefreshTimer = new QTimer(this);
|
||||
overviewRefreshTimer->setInterval(250);
|
||||
overviewRefreshTimer->setTimerType(Qt::CoarseTimer);
|
||||
connect(overviewRefreshTimer, &QTimer::timeout, this, &HomeScreen::updateOverviewActive);
|
||||
overviewRefreshTimer->start();
|
||||
|
||||
connect(this, &Plasma::Containment::appletAdded, this, &HomeScreen::onAppletAdded);
|
||||
connect(this, &Plasma::Containment::appletAboutToBeRemoved, this, &HomeScreen::onAppletAboutToBeRemoved);
|
||||
}
|
||||
|
|
@ -139,58 +91,8 @@ PageListModel *HomeScreen::pageListModel()
|
|||
return m_pageListModel;
|
||||
}
|
||||
|
||||
bool HomeScreen::overviewActive() const
|
||||
void HomeScreen::triggerOverview() const
|
||||
{
|
||||
return m_overviewActive;
|
||||
}
|
||||
|
||||
void HomeScreen::setOverviewActive(bool overviewActive)
|
||||
{
|
||||
if (m_overviewActive == overviewActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_overviewActive = overviewActive;
|
||||
Q_EMIT overviewActiveChanged();
|
||||
}
|
||||
|
||||
void HomeScreen::updateOverviewActive()
|
||||
{
|
||||
QDBusInterface propIface(s_kwinService, s_kwinEffectsPath, s_dbusPropertiesInterface, QDBusConnection::sessionBus());
|
||||
if (!propIface.isValid()) {
|
||||
setOverviewActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusReply<QDBusVariant> activeEffectsReply = propIface.call(QStringLiteral("Get"), s_kwinEffectsInterface, QStringLiteral("activeEffects"));
|
||||
if (!activeEffectsReply.isValid()) {
|
||||
setOverviewActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setOverviewActive(effectListFromVariant(activeEffectsReply.value().variant()).contains(QStringLiteral("overview")));
|
||||
}
|
||||
|
||||
void HomeScreen::onOverviewEffectsChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated)
|
||||
{
|
||||
if (interface != s_kwinEffectsInterface) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (changed.contains(QStringLiteral("activeEffects"))) {
|
||||
setOverviewActive(effectListFromVariant(changed.value(QStringLiteral("activeEffects"))).contains(QStringLiteral("overview")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (invalidated.contains(QStringLiteral("activeEffects"))) {
|
||||
updateOverviewActive();
|
||||
}
|
||||
}
|
||||
|
||||
void HomeScreen::triggerOverview()
|
||||
{
|
||||
setOverviewActive(true);
|
||||
|
||||
QDBusMessage message = QDBusMessage::createMethodCall("org.kde.kglobalaccel", "/component/kwin", "org.kde.kglobalaccel.Component", "invokeShortcut");
|
||||
message.setArguments({QStringLiteral("Overview")});
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ class HomeScreen : public Plasma::Containment
|
|||
Q_PROPERTY(ApplicationListSearchModel *ApplicationListSearchModel READ applicationListSearchModel CONSTANT)
|
||||
Q_PROPERTY(FavouritesModel *FavouritesModel READ favouritesModel CONSTANT)
|
||||
Q_PROPERTY(PageListModel *PageListModel READ pageListModel CONSTANT)
|
||||
Q_PROPERTY(bool overviewActive READ overviewActive NOTIFY overviewActiveChanged)
|
||||
|
||||
public:
|
||||
HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args);
|
||||
|
|
@ -51,7 +50,7 @@ public:
|
|||
|
||||
void configChanged() override;
|
||||
|
||||
Q_INVOKABLE void triggerOverview();
|
||||
Q_INVOKABLE void triggerOverview() const;
|
||||
Q_INVOKABLE void triggerMinimizeAll() const;
|
||||
Q_INVOKABLE void activateVirtualDesktop(const QVariant &desktop) const;
|
||||
Q_INVOKABLE void createVirtualDesktop() const;
|
||||
|
|
@ -65,21 +64,15 @@ public:
|
|||
ApplicationListSearchModel *applicationListSearchModel();
|
||||
FavouritesModel *favouritesModel();
|
||||
PageListModel *pageListModel();
|
||||
bool overviewActive() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void overviewActiveChanged();
|
||||
void showingDesktopChanged(bool showingDesktop);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onOverviewEffectsChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated);
|
||||
void onAppletAdded(Plasma::Applet *applet, const QRectF &geometryHint);
|
||||
void onAppletAboutToBeRemoved(Plasma::Applet *applet);
|
||||
|
||||
private:
|
||||
void setOverviewActive(bool overviewActive);
|
||||
void updateOverviewActive();
|
||||
|
||||
FolioSettings *m_folioSettings{nullptr};
|
||||
HomeScreenState *m_homeScreenState{nullptr};
|
||||
WidgetsManager *m_widgetsManager{nullptr};
|
||||
|
|
@ -87,5 +80,4 @@ private:
|
|||
ApplicationListSearchModel *m_applicationListSearchModel{nullptr};
|
||||
FavouritesModel *m_favouritesModel{nullptr};
|
||||
PageListModel *m_pageListModel{nullptr};
|
||||
bool m_overviewActive{false};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Controls
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import org.kde.plasma.components 3.0 as PC3
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
|
@ -36,6 +37,24 @@ Item {
|
|||
// Convergence popup background
|
||||
readonly property bool isPopup: ShellSettings.Settings.convergenceModeEnabled
|
||||
|
||||
Rectangle {
|
||||
visible: root.isPopup
|
||||
anchors.fill: parent
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
opacity: 0.95
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 2
|
||||
radius: 12
|
||||
samples: 25
|
||||
color: Qt.rgba(0, 0, 0, 0.4)
|
||||
}
|
||||
}
|
||||
|
||||
// Keyboard navigation
|
||||
Keys.onPressed: (event) => {
|
||||
if (event.key === Qt.Key_Escape || event.key === Qt.Key_Back) {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ Rectangle {
|
|||
// Emitted when the user taps a tile.
|
||||
signal categorySelected(string categoryId)
|
||||
|
||||
color: "transparent"
|
||||
radius: 0
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
|
||||
// Swallow clicks so the dismiss area underneath is not triggered.
|
||||
MouseArea { anchors.fill: parent }
|
||||
|
|
|
|||
|
|
@ -358,7 +358,6 @@ Item {
|
|||
// don't show in settings mode
|
||||
opacity: 1 - folio.HomeScreenState.settingsOpenProgress
|
||||
visible: folio.FolioSettings.showFavouritesBarBackground
|
||||
&& !ShellSettings.Settings.convergenceModeEnabled
|
||||
|
||||
anchors.top: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? favouritesBar.top : parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ Item {
|
|||
filterByScreen: true
|
||||
filterHidden: false
|
||||
activity: activityInfo.currentActivity
|
||||
groupMode: TaskManager.TasksModel.GroupDisabled
|
||||
groupMode: TaskManager.TasksModel.GroupApplications
|
||||
}
|
||||
|
||||
TaskManager.TasksModel {
|
||||
|
|
@ -117,15 +117,26 @@ Item {
|
|||
filterHidden: false
|
||||
virtualDesktop: virtualDesktopInfo.currentDesktop
|
||||
activity: activityInfo.currentActivity
|
||||
groupMode: TaskManager.TasksModel.GroupDisabled
|
||||
groupMode: TaskManager.TasksModel.GroupApplications
|
||||
sortMode: root.sortByName ? TaskManager.TasksModel.SortAlpha : TaskManager.TasksModel.SortLastActivated
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: panelShadow
|
||||
anchors.fill: panelBackground
|
||||
anchors.topMargin: 2
|
||||
radius: panelBackground.radius
|
||||
color: Qt.rgba(0, 0, 0, 0.35)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: panelBackground
|
||||
anchors.fill: parent
|
||||
radius: 0
|
||||
color: "transparent"
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
border.width: 1
|
||||
border.pixelAligned: false
|
||||
border.color: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.14)
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
|
|
@ -418,6 +429,7 @@ Item {
|
|||
const action = root.dynamicTilingMoveToDesktopAction(desktopId, desktopIndex)
|
||||
if (action !== "") {
|
||||
ShellSettings.Settings.requestDynamicTilingWindowAction(taskCard.windowId, action)
|
||||
return
|
||||
}
|
||||
}
|
||||
tasksModel.requestVirtualDesktops(taskCard.modelIndex, [desktopId])
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import QtQuick.Window
|
|||
import QtQuick.Layouts
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Shapes 1.8
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
|
|
@ -270,44 +271,33 @@ ContainmentItem {
|
|||
opacity: folio.HomeScreenState.settingsOpenProgress
|
||||
}
|
||||
|
||||
// Unified convergence chrome — renders the visible top bar, workspace
|
||||
// frame, and dock in one mapped surface so they appear together.
|
||||
// Invisible reserver surfaces in the panel/taskpanel containments still
|
||||
// provide the exclusive zones that shrink KWin's MaximizeArea.
|
||||
// Dock overlay window — renders the favourites bar above application
|
||||
// windows in convergence mode. LayerTop sits above normal windows but
|
||||
// below LayerOverlay (notifications, volume OSD). The exclusive zone
|
||||
// that reserves screen space is handled by the dockSpaceReserver in the
|
||||
// task panel containment; this window only provides the visible dock.
|
||||
Window {
|
||||
id: convergenceChrome
|
||||
readonly property bool active: ShellSettings.Settings.convergenceModeEnabled
|
||||
&& !ShellSettings.Settings.gamingModeEnabled
|
||||
&& !folio.overviewActive
|
||||
id: dockOverlay
|
||||
readonly property bool active: ShellSettings.Settings.convergenceModeEnabled && !ShellSettings.Settings.gamingModeEnabled
|
||||
|
||||
visible: active
|
||||
opacity: active ? 1 : 0
|
||||
color: "transparent"
|
||||
width: Screen.width
|
||||
height: Screen.height
|
||||
height: MobileShell.Constants.convergenceDockHeight
|
||||
|
||||
LayerShell.Window.scope: "convergence-chrome"
|
||||
LayerShell.Window.scope: "dock-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.anchors: LayerShell.Window.AnchorBottom | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight
|
||||
LayerShell.Window.exclusionZone: shouldReserveSpace ? dockHeight : -1
|
||||
LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityOnDemand
|
||||
|
||||
// Auto-hide: slide dock content off-screen when a window is
|
||||
// maximized. The reveal strip at the screen edge brings it back.
|
||||
property real dockOffset: 0
|
||||
property bool inputRegionInitialized: false
|
||||
readonly property real topBarHeight: MobileShell.Constants.topPanelHeight
|
||||
readonly property real dockHeight: MobileShell.Constants.convergenceDockHeight
|
||||
readonly property real frameThickness: MobileShell.Constants.convergenceWorkspaceFrameThickness
|
||||
readonly property real topBarHitHeight: topBarHeight + frameThickness
|
||||
readonly property real frameRadius: Math.min(MobileShell.Constants.convergenceWorkspaceFrameRadius, Math.max(0, Math.min(workAreaWidth, workAreaHeight) / 2))
|
||||
readonly property real workAreaX: frameThickness
|
||||
readonly property real workAreaY: topBarHitHeight
|
||||
readonly property real workAreaWidth: Math.max(0, width - frameThickness * 2)
|
||||
readonly property real workAreaHeight: Math.max(0, height - topBarHeight - dockHeight - frameThickness * 2)
|
||||
readonly property color chromeColor: Kirigami.Theme.backgroundColor
|
||||
readonly property color edgeColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1)
|
||||
readonly property int dockAnimationDuration: MobileShell.Motion.duration(MobileShell.Motion.SpatialDefault)
|
||||
readonly property int dockFadeDuration: MobileShell.Motion.duration(MobileShell.Motion.EffectsFast)
|
||||
|
||||
// Height of the input-receive strip kept at the screen edge when
|
||||
// the dock is hidden. Matches the navigation panel convention.
|
||||
|
|
@ -318,31 +308,24 @@ ContainmentItem {
|
|||
|
||||
readonly property bool shouldHide: ShellSettings.Settings.autoHidePanelsEnabled
|
||||
&& windowMaximizedTracker.showingWindow && !hoverRevealing
|
||||
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
readonly property bool shouldReserveSpace: ShellSettings.Settings.autoHidePanelsEnabled
|
||||
&& windowMaximizedTracker.showingWindow && hoverRevealing
|
||||
|
||||
function updateInputRegion() {
|
||||
const topBarRegion = Qt.rect(0, 0, width, topBarHitHeight)
|
||||
if (shouldHide && dockOffset >= dockHeight) {
|
||||
MobileShell.ShellUtil.setInputRegions(convergenceChrome, [
|
||||
topBarRegion,
|
||||
Qt.rect(0, height - revealStripHeight, width, revealStripHeight)
|
||||
])
|
||||
MobileShell.ShellUtil.setInputRegion(dockOverlay,
|
||||
Qt.rect(0, dockOverlay.height - revealStripHeight,
|
||||
dockOverlay.width, revealStripHeight))
|
||||
} else {
|
||||
MobileShell.ShellUtil.setInputRegions(convergenceChrome, [
|
||||
topBarRegion,
|
||||
Qt.rect(0, height - dockHeight, width, dockHeight)
|
||||
])
|
||||
MobileShell.ShellUtil.setInputRegion(dockOverlay, Qt.rect(0, 0, 0, 0))
|
||||
}
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
hoverRevealTimer.stop()
|
||||
hoverRevealing = false
|
||||
inputRegionInitialized = false
|
||||
dockOffset = shouldHide ? dockHeight : 0
|
||||
inputRegionTimer.restart()
|
||||
updateInputRegion()
|
||||
}
|
||||
|
||||
onShouldHideChanged: {
|
||||
|
|
@ -351,30 +334,17 @@ ContainmentItem {
|
|||
} else {
|
||||
dockOffset = 0
|
||||
}
|
||||
inputRegionTimer.restart()
|
||||
updateInputRegion()
|
||||
}
|
||||
|
||||
// Narrow the input region to a strip at the screen edge when hidden
|
||||
// so that app controls near the bottom edge are not accidentally
|
||||
// intercepted. Mirrors the same pattern used by NavigationPanel.
|
||||
onDockOffsetChanged: {
|
||||
inputRegionTimer.restart()
|
||||
}
|
||||
onWidthChanged: inputRegionTimer.restart()
|
||||
onHeightChanged: inputRegionTimer.restart()
|
||||
onFrameSwapped: {
|
||||
if (!inputRegionInitialized) {
|
||||
inputRegionInitialized = true
|
||||
inputRegionTimer.restart()
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: inputRegionTimer
|
||||
interval: 0
|
||||
repeat: false
|
||||
onTriggered: convergenceChrome.updateInputRegion()
|
||||
updateInputRegion()
|
||||
}
|
||||
onWidthChanged: updateInputRegion()
|
||||
onHeightChanged: updateInputRegion()
|
||||
|
||||
// Delay reveal briefly so a quick edge graze does not pop the
|
||||
// dock up mid-interaction with the underlying application.
|
||||
|
|
@ -382,111 +352,53 @@ ContainmentItem {
|
|||
id: hoverRevealTimer
|
||||
interval: Kirigami.Units.shortDuration
|
||||
repeat: false
|
||||
onTriggered: convergenceChrome.hoverRevealing = true
|
||||
onTriggered: dockOverlay.hoverRevealing = true
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: dockHoverHandler
|
||||
onHoveredChanged: {
|
||||
if (hovered) {
|
||||
hoverRevealTimer.start()
|
||||
} else {
|
||||
hoverRevealTimer.stop()
|
||||
dockOverlay.hoverRevealing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on dockOffset {
|
||||
MobileShell.MotionNumberAnimation {
|
||||
type: MobileShell.Motion.SpatialDefault
|
||||
duration: convergenceChrome.dockAnimationDuration
|
||||
duration: dockOverlay.dockAnimationDuration
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
MobileShell.MotionNumberAnimation { type: MobileShell.Motion.EffectsFast; duration: dockOverlay.dockFadeDuration }
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: topBarSurface
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: convergenceChrome.topBarHeight
|
||||
color: convergenceChrome.chromeColor
|
||||
|
||||
MobileShell.StatusBar {
|
||||
anchors.fill: parent
|
||||
showSecondRow: false
|
||||
showTime: true
|
||||
backgroundColor: "transparent"
|
||||
}
|
||||
}
|
||||
|
||||
Shape {
|
||||
id: workspaceFrame
|
||||
anchors.fill: parent
|
||||
|
||||
ShapePath {
|
||||
fillColor: convergenceChrome.chromeColor
|
||||
fillRule: ShapePath.OddEvenFill
|
||||
strokeWidth: 0
|
||||
|
||||
startX: 0
|
||||
startY: convergenceChrome.topBarHeight
|
||||
PathLine { x: convergenceChrome.width; y: convergenceChrome.topBarHeight }
|
||||
PathLine { x: convergenceChrome.width; y: convergenceChrome.height - convergenceChrome.dockHeight }
|
||||
PathLine { x: 0; y: convergenceChrome.height - convergenceChrome.dockHeight }
|
||||
PathLine { x: 0; y: convergenceChrome.topBarHeight }
|
||||
|
||||
PathMove { x: convergenceChrome.workAreaX + convergenceChrome.frameRadius; y: convergenceChrome.workAreaY }
|
||||
PathLine { x: convergenceChrome.workAreaX + convergenceChrome.workAreaWidth - convergenceChrome.frameRadius; y: convergenceChrome.workAreaY }
|
||||
PathArc { x: convergenceChrome.workAreaX + convergenceChrome.workAreaWidth; y: convergenceChrome.workAreaY + convergenceChrome.frameRadius; radiusX: convergenceChrome.frameRadius; radiusY: convergenceChrome.frameRadius }
|
||||
PathLine { x: convergenceChrome.workAreaX + convergenceChrome.workAreaWidth; y: convergenceChrome.workAreaY + convergenceChrome.workAreaHeight - convergenceChrome.frameRadius }
|
||||
PathArc { x: convergenceChrome.workAreaX + convergenceChrome.workAreaWidth - convergenceChrome.frameRadius; y: convergenceChrome.workAreaY + convergenceChrome.workAreaHeight; radiusX: convergenceChrome.frameRadius; radiusY: convergenceChrome.frameRadius }
|
||||
PathLine { x: convergenceChrome.workAreaX + convergenceChrome.frameRadius; y: convergenceChrome.workAreaY + convergenceChrome.workAreaHeight }
|
||||
PathArc { x: convergenceChrome.workAreaX; y: convergenceChrome.workAreaY + convergenceChrome.workAreaHeight - convergenceChrome.frameRadius; radiusX: convergenceChrome.frameRadius; radiusY: convergenceChrome.frameRadius }
|
||||
PathLine { x: convergenceChrome.workAreaX; y: convergenceChrome.workAreaY + convergenceChrome.frameRadius }
|
||||
PathArc { x: convergenceChrome.workAreaX + convergenceChrome.frameRadius; y: convergenceChrome.workAreaY; radiusX: convergenceChrome.frameRadius; radiusY: convergenceChrome.frameRadius }
|
||||
}
|
||||
visible: !dockOverlay.shouldHide || dockOverlay.dockOffset < dockOverlay.dockHeight
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
x: convergenceChrome.workAreaX
|
||||
y: convergenceChrome.workAreaY
|
||||
width: convergenceChrome.workAreaWidth
|
||||
height: convergenceChrome.workAreaHeight
|
||||
radius: convergenceChrome.frameRadius
|
||||
color: "transparent"
|
||||
border.width: 1
|
||||
border.color: convergenceChrome.edgeColor
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: dockSurface
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
height: convergenceChrome.dockHeight
|
||||
color: "transparent"
|
||||
|
||||
HoverHandler {
|
||||
id: dockHoverHandler
|
||||
onHoveredChanged: {
|
||||
if (hovered) {
|
||||
hoverRevealTimer.start()
|
||||
} else {
|
||||
hoverRevealTimer.stop()
|
||||
convergenceChrome.hoverRevealing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: !convergenceChrome.shouldHide || convergenceChrome.dockOffset < convergenceChrome.dockHeight
|
||||
color: convergenceChrome.chromeColor
|
||||
}
|
||||
|
||||
FavouritesBar {
|
||||
id: dockOverlayBar
|
||||
anchors.fill: parent
|
||||
folio: root.folio
|
||||
maskManager: root.maskManager
|
||||
homeScreen: folioHomeScreen
|
||||
suppressRunningTasks: runningAppsPanel.visible
|
||||
transform: Translate { y: convergenceChrome.dockOffset }
|
||||
// Dock is an opaque panel — use Window colorset so all content
|
||||
// (labels, hover highlights, icon tints) follows the system theme
|
||||
// instead of the containment's Complementary wallpaper context.
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
}
|
||||
FavouritesBar {
|
||||
id: dockOverlayBar
|
||||
anchors.fill: parent
|
||||
folio: root.folio
|
||||
maskManager: root.maskManager
|
||||
homeScreen: folioHomeScreen
|
||||
suppressRunningTasks: runningAppsPanel.visible
|
||||
transform: Translate { y: dockOverlay.dockOffset }
|
||||
// Dock is an opaque panel — use Window colorset so all content
|
||||
// (labels, hover highlights, icon tints) follows the system theme
|
||||
// instead of the containment's Complementary wallpaper context.
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -523,10 +435,9 @@ ContainmentItem {
|
|||
|
||||
readonly property real popupWidth: Math.min(Kirigami.Units.gridUnit * 28, parent.width * 0.5)
|
||||
readonly property real dockHeight: MobileShell.Constants.convergenceDockHeight
|
||||
readonly property real sideInset: MobileShell.Constants.convergenceWorkspaceFrameThickness
|
||||
readonly property real connectedPanelGap: 0
|
||||
readonly property real popupTopY: MobileShell.Constants.topPanelHeight
|
||||
+ MobileShell.Constants.convergenceWorkspaceFrameThickness
|
||||
+ Kirigami.Units.smallSpacing
|
||||
readonly property real popupBottomY: parent.height
|
||||
- dockHeight
|
||||
- MobileShell.Constants.convergenceWorkspaceFrameThickness
|
||||
|
|
@ -540,7 +451,7 @@ ContainmentItem {
|
|||
|
||||
property real animationY: (1 - folio.HomeScreenState.appDrawerOpenProgress) * (Kirigami.Units.gridUnit * 2)
|
||||
|
||||
x: sideInset
|
||||
x: Kirigami.Units.smallSpacing
|
||||
y: (opacity > 0)
|
||||
? popupTopY + animationY
|
||||
: parent.height
|
||||
|
|
@ -574,13 +485,35 @@ ContainmentItem {
|
|||
}
|
||||
}
|
||||
|
||||
// Drop shadow rendered separately so categoryPanel itself needs no
|
||||
// layer FBO (which would rasterize and blur the icons inside).
|
||||
Rectangle {
|
||||
id: categoryPanelShadow
|
||||
width: categoryPanel.width
|
||||
height: categoryPanel.height
|
||||
x: categoryPanel.x
|
||||
y: categoryPanel.y
|
||||
radius: categoryPanel.radius
|
||||
color: categoryPanel.color
|
||||
opacity: categoryPanel.opacity
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 2
|
||||
radius: 12
|
||||
samples: 25
|
||||
color: Qt.rgba(0, 0, 0, 0.4)
|
||||
}
|
||||
}
|
||||
|
||||
CategoryPanel {
|
||||
id: categoryPanel
|
||||
folio: root.folio
|
||||
|
||||
width: Kirigami.Units.gridUnit * 9
|
||||
height: overlayDrawer.popupHeight
|
||||
x: overlayDrawer.x + overlayDrawer.width + overlayDrawer.connectedPanelGap
|
||||
x: overlayDrawer.x + overlayDrawer.width + Kirigami.Units.smallSpacing
|
||||
y: overlayDrawer.y
|
||||
opacity: overlayDrawer.opacity
|
||||
|
||||
|
|
@ -590,6 +523,28 @@ ContainmentItem {
|
|||
}
|
||||
}
|
||||
|
||||
// Drop shadow rendered separately so powerPanel itself needs no layer FBO,
|
||||
// which would rasterize and blur the icons inside.
|
||||
Rectangle {
|
||||
id: powerPanelShadow
|
||||
width: powerPanel.width
|
||||
height: powerPanel.height
|
||||
x: powerPanel.x
|
||||
y: powerPanel.y
|
||||
radius: powerPanel.radius
|
||||
color: powerPanel.color
|
||||
opacity: powerPanel.opacity
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 2
|
||||
radius: 12
|
||||
samples: 25
|
||||
color: Qt.rgba(0, 0, 0, 0.4)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: powerPanel
|
||||
|
||||
|
|
@ -599,12 +554,12 @@ ContainmentItem {
|
|||
width: tileSize
|
||||
height: overlayDrawer.popupHeight
|
||||
x: runningAppsPanel.visible
|
||||
? runningAppsPanel.x + runningAppsPanel.width + overlayDrawer.connectedPanelGap
|
||||
: categoryPanel.x + categoryPanel.width + overlayDrawer.connectedPanelGap
|
||||
? runningAppsPanel.x + runningAppsPanel.width + Kirigami.Units.smallSpacing
|
||||
: categoryPanel.x + categoryPanel.width + Kirigami.Units.smallSpacing
|
||||
y: overlayDrawer.y
|
||||
opacity: overlayDrawer.opacity
|
||||
radius: 0
|
||||
color: "transparent"
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
|
@ -833,50 +788,15 @@ ContainmentItem {
|
|||
id: runningAppsPanel
|
||||
folio: root.folio
|
||||
|
||||
x: categoryPanel.x + categoryPanel.width + overlayDrawer.connectedPanelGap
|
||||
x: categoryPanel.x + categoryPanel.width + Kirigami.Units.smallSpacing
|
||||
y: overlayDrawer.y
|
||||
width: Math.max(0, parent.width - x - powerPanel.width - overlayDrawer.sideInset - overlayDrawer.connectedPanelGap)
|
||||
width: Math.max(0, parent.width - x - powerPanel.width - Kirigami.Units.smallSpacing * 2)
|
||||
height: overlayDrawer.popupHeight
|
||||
opacity: overlayDrawer.opacity
|
||||
visible: hasTasks && opacity > 0
|
||||
|
||||
onTaskActivated: folio.HomeScreenState.closeAppDrawer()
|
||||
}
|
||||
|
||||
Shape {
|
||||
id: drawerSurface
|
||||
x: overlayDrawer.x
|
||||
y: overlayDrawer.y
|
||||
width: bodyWidth + cornerRadius
|
||||
height: overlayDrawer.popupHeight
|
||||
opacity: overlayDrawer.opacity
|
||||
visible: opacity > 0 && bodyWidth > 0 && height > 0
|
||||
z: -1
|
||||
preferredRendererType: Shape.CurveRenderer
|
||||
asynchronous: true
|
||||
enabled: false
|
||||
|
||||
readonly property real bodyWidth: Math.max(0, powerPanel.x + powerPanel.width - overlayDrawer.x)
|
||||
readonly property real cornerRadius: Math.min(MobileShell.Constants.convergenceWorkspaceFrameRadius,
|
||||
Math.max(0.01, Math.min(bodyWidth, height) / 2))
|
||||
|
||||
ShapePath {
|
||||
id: drawerSurfacePath
|
||||
readonly property real cornerRadius: drawerSurface.cornerRadius
|
||||
|
||||
fillColor: Kirigami.Theme.backgroundColor
|
||||
strokeWidth: 0
|
||||
startX: 0
|
||||
startY: 0
|
||||
|
||||
PathLine { x: drawerSurface.bodyWidth + drawerSurfacePath.cornerRadius; y: 0 }
|
||||
PathArc { x: drawerSurface.bodyWidth; y: drawerSurfacePath.cornerRadius; radiusX: drawerSurfacePath.cornerRadius; radiusY: drawerSurfacePath.cornerRadius; direction: PathArc.Counterclockwise }
|
||||
PathLine { x: drawerSurface.bodyWidth; y: drawerSurface.height - drawerSurfacePath.cornerRadius }
|
||||
PathArc { x: drawerSurface.bodyWidth + drawerSurfacePath.cornerRadius; y: drawerSurface.height; radiusX: drawerSurfacePath.cornerRadius; radiusY: drawerSurfacePath.cornerRadius; direction: PathArc.Counterclockwise }
|
||||
PathLine { x: 0; y: drawerSurface.height }
|
||||
PathLine { x: 0; y: 0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Game Center overlay — full-screen grid of games shown when gaming mode
|
||||
|
|
@ -959,6 +879,65 @@ ContainmentItem {
|
|||
onHomeTriggered: root.homeAction()
|
||||
|
||||
contentItem: Item {
|
||||
Item {
|
||||
id: workspaceFrame
|
||||
anchors.fill: parent
|
||||
visible: ShellSettings.Settings.convergenceModeEnabled && !ShellSettings.Settings.gamingModeEnabled
|
||||
z: -1
|
||||
|
||||
readonly property real frameThickness: MobileShell.Constants.convergenceWorkspaceFrameThickness
|
||||
readonly property real frameRadius: Math.min(MobileShell.Constants.convergenceWorkspaceFrameRadius, Math.max(0, Math.min(workAreaWidth, workAreaHeight) / 2))
|
||||
readonly property real topReservedHeight: MobileShell.Constants.topPanelHeight
|
||||
readonly property real bottomReservedHeight: MobileShell.Constants.convergenceDockHeight
|
||||
readonly property real workAreaX: frameThickness
|
||||
readonly property real workAreaY: topReservedHeight + frameThickness
|
||||
readonly property real workAreaWidth: Math.max(0, width - frameThickness * 2)
|
||||
readonly property real workAreaHeight: Math.max(0, height - topReservedHeight - bottomReservedHeight - frameThickness * 2)
|
||||
readonly property color frameColor: Kirigami.Theme.backgroundColor
|
||||
readonly property color edgeColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1)
|
||||
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
|
||||
Shape {
|
||||
anchors.fill: parent
|
||||
|
||||
ShapePath {
|
||||
fillColor: workspaceFrame.frameColor
|
||||
fillRule: ShapePath.OddEvenFill
|
||||
strokeWidth: 0
|
||||
|
||||
startX: 0
|
||||
startY: workspaceFrame.topReservedHeight
|
||||
PathLine { x: workspaceFrame.width; y: workspaceFrame.topReservedHeight }
|
||||
PathLine { x: workspaceFrame.width; y: workspaceFrame.height - workspaceFrame.bottomReservedHeight }
|
||||
PathLine { x: 0; y: workspaceFrame.height - workspaceFrame.bottomReservedHeight }
|
||||
PathLine { x: 0; y: workspaceFrame.topReservedHeight }
|
||||
|
||||
PathMove { x: workspaceFrame.workAreaX + workspaceFrame.frameRadius; y: workspaceFrame.workAreaY }
|
||||
PathLine { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth - workspaceFrame.frameRadius; y: workspaceFrame.workAreaY }
|
||||
PathArc { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth; y: workspaceFrame.workAreaY + workspaceFrame.frameRadius; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
|
||||
PathLine { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight - workspaceFrame.frameRadius }
|
||||
PathArc { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth - workspaceFrame.frameRadius; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
|
||||
PathLine { x: workspaceFrame.workAreaX + workspaceFrame.frameRadius; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight }
|
||||
PathArc { x: workspaceFrame.workAreaX; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight - workspaceFrame.frameRadius; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
|
||||
PathLine { x: workspaceFrame.workAreaX; y: workspaceFrame.workAreaY + workspaceFrame.frameRadius }
|
||||
PathArc { x: workspaceFrame.workAreaX + workspaceFrame.frameRadius; y: workspaceFrame.workAreaY; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
x: workspaceFrame.workAreaX
|
||||
y: workspaceFrame.workAreaY
|
||||
width: workspaceFrame.workAreaWidth
|
||||
height: workspaceFrame.workAreaHeight
|
||||
radius: workspaceFrame.frameRadius
|
||||
color: "transparent"
|
||||
border.width: 1
|
||||
border.color: workspaceFrame.edgeColor
|
||||
}
|
||||
}
|
||||
|
||||
// homescreen component
|
||||
FolioHomeScreen {
|
||||
id: folioHomeScreen
|
||||
|
|
|
|||
|
|
@ -64,9 +64,7 @@ Item {
|
|||
screen: Plasmoid.screen
|
||||
maximizedTracker: containmentItem.windowMaximizedTracker
|
||||
|
||||
visible: !MobileShellState.LockscreenDBusClient.lockscreenActive
|
||||
&& !containmentItem.fullscreen
|
||||
&& !ShellSettings.Settings.convergenceModeEnabled
|
||||
visible: !MobileShellState.LockscreenDBusClient.lockscreenActive && !containmentItem.fullscreen
|
||||
}
|
||||
|
||||
// Status bar component
|
||||
|
|
@ -76,8 +74,6 @@ Item {
|
|||
StatusBarWrapper {
|
||||
id: statusBarWrapper
|
||||
z: 1
|
||||
visible: !ShellSettings.Settings.convergenceModeEnabled
|
||||
enabled: visible
|
||||
anchors.fill: parent
|
||||
|
||||
statusPanelHeight: MobileShell.Constants.topPanelHeight
|
||||
|
|
@ -187,28 +183,25 @@ Item {
|
|||
|
||||
actionDrawer.restrictedPermissions: MobileShellState.LockscreenDBusClient.lockscreenActive
|
||||
|
||||
actionDrawer.notificationSettings: NotificationManager.Settings {
|
||||
id: notificationSettings
|
||||
}
|
||||
actionDrawer.notificationSettings: NotificationManager.Settings {}
|
||||
actionDrawer.notificationModel: NotificationManager.Notifications {
|
||||
showExpired: true
|
||||
showDismissed: true
|
||||
showJobs: notificationSettings.jobsInNotifications
|
||||
showJobs: drawer.actionDrawer.notificationSettings.jobsInNotifications
|
||||
sortMode: NotificationManager.Notifications.SortByTypeAndUrgency
|
||||
groupMode: NotificationManager.Notifications.GroupApplicationsFlat
|
||||
groupLimit: 2
|
||||
expandUnread: true
|
||||
// Strip "@other" from the blacklist: Plasma's default config blocks
|
||||
// notifications from unregistered/non-configurable sources, which on
|
||||
// a mobile/convergence shell silently hides anything not shipping a
|
||||
// .desktop entry (e.g. third-party DBus senders). Shift surfaces all
|
||||
// notifications and lets the user blacklist individual apps later.
|
||||
blacklistedDesktopEntries: notificationSettings.historyBlacklistedApplications
|
||||
.filter(function(e) { return e !== "@other"; })
|
||||
blacklistedNotifyRcNames: notificationSettings.historyBlacklistedServices
|
||||
urgencies: NotificationManager.Notifications.CriticalUrgency
|
||||
| NotificationManager.Notifications.NormalUrgency
|
||||
| NotificationManager.Notifications.LowUrgency
|
||||
blacklistedDesktopEntries: drawer.actionDrawer.notificationSettings.historyBlacklistedApplications
|
||||
blacklistedNotifyRcNames: drawer.actionDrawer.notificationSettings.historyBlacklistedServices
|
||||
urgencies: {
|
||||
var urgencies = NotificationManager.Notifications.CriticalUrgency
|
||||
| NotificationManager.Notifications.NormalUrgency;
|
||||
if (drawer.actionDrawer.notificationSettings.lowPriorityHistory) {
|
||||
urgencies |= NotificationManager.Notifications.LowUrgency;
|
||||
}
|
||||
return urgencies;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
|
|
|||
|
|
@ -75,28 +75,22 @@ ContainmentItem {
|
|||
}
|
||||
}
|
||||
|
||||
readonly property real topBarHeight: gamingMode ? 0 : MobileShell.Constants.topPanelHeight
|
||||
readonly property real panelHeight: gamingMode ? 0 : MobileShell.Constants.topPanelHeight
|
||||
readonly property real convergenceWorkspaceFrameThickness: ShellSettings.Settings.convergenceModeEnabled && !gamingMode
|
||||
? MobileShell.Constants.convergenceWorkspaceFrameThickness
|
||||
: 0
|
||||
readonly property real topBarInputHeight: topBarHeight + convergenceWorkspaceFrameThickness
|
||||
readonly property real panelHeight: gamingMode
|
||||
? 0
|
||||
: (ShellSettings.Settings.convergenceModeEnabled ? topBarInputHeight : MobileShell.Constants.topPanelHeight)
|
||||
onPanelHeightChanged: setWindowProperties()
|
||||
|
||||
function setWindowProperties() {
|
||||
if (root.panel) {
|
||||
root.panel.floating = false;
|
||||
root.panel.maximize(); // maximize first, then we can apply offsets (otherwise they are overridden)
|
||||
root.panel.location = PlasmaCore.Types.TopEdge;
|
||||
root.panel.offset = 0;
|
||||
|
||||
// HACK: set thickness twice, sometimes it doesn't set the first time??
|
||||
root.panel.thickness = root.panelHeight;
|
||||
root.panel.thickness = root.panelHeight;
|
||||
|
||||
root.panel.visibilityMode = (!ShellSettings.Settings.convergenceModeEnabled && ShellSettings.Settings.autoHidePanelsEnabled) ? 3 : 0;
|
||||
root.panel.visibilityMode = (ShellSettings.Settings.autoHidePanelsEnabled || ShellSettings.Settings.convergenceModeEnabled) ? 3 : 0;
|
||||
MobileShell.ShellUtil.setWindowLayer(root.panel, LayerShell.Window.LayerOverlay)
|
||||
root.updateTouchArea();
|
||||
}
|
||||
|
|
@ -106,9 +100,7 @@ ContainmentItem {
|
|||
function updateTouchArea() {
|
||||
const hiddenTouchAreaThickness = Kirigami.Units.gridUnit;
|
||||
|
||||
if (ShellSettings.Settings.convergenceModeEnabled) {
|
||||
MobileShell.ShellUtil.setInputRegion(root.panel, Qt.rect(0, 0, root.panel.width, root.panel.height));
|
||||
} else if (MobileShellState.ShellDBusClient.panelState == "hidden") {
|
||||
if (MobileShellState.ShellDBusClient.panelState == "hidden") {
|
||||
MobileShell.ShellUtil.setInputRegion(root.panel, Qt.rect(0, 0, root.panel.width, hiddenTouchAreaThickness));
|
||||
} else {
|
||||
MobileShell.ShellUtil.setInputRegion(root.panel, Qt.rect(0, 0, 0, 0));
|
||||
|
|
@ -152,21 +144,22 @@ ContainmentItem {
|
|||
}
|
||||
|
||||
// Invisible layer-shell surface that reserves screen space for the
|
||||
// status bar in convergence mode. The visible convergence top bar is
|
||||
// rendered by Folio's unified chrome surface; this window only shrinks
|
||||
// KWin's MaximizeArea.
|
||||
// status bar in convergence mode. The panel itself uses WindowsGoBelow
|
||||
// (exclusiveZone -1) so it stays above windows; this separate surface
|
||||
// at LayerBottom provides the actual exclusive zone so KWin shrinks
|
||||
// MaximizeArea by the panel height.
|
||||
Window {
|
||||
id: topBarSpaceReserver
|
||||
visible: ShellSettings.Settings.convergenceModeEnabled && !ShellSettings.Settings.gamingModeEnabled
|
||||
color: "transparent"
|
||||
flags: Qt.FramelessWindowHint | Qt.WindowTransparentForInput
|
||||
height: Math.max(1, root.topBarInputHeight)
|
||||
height: Math.max(1, root.panelHeight + root.convergenceWorkspaceFrameThickness)
|
||||
width: 1
|
||||
|
||||
LayerShell.Window.scope: "topbar-space"
|
||||
LayerShell.Window.layer: LayerShell.Window.LayerBottom
|
||||
LayerShell.Window.anchors: LayerShell.Window.AnchorTop | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight
|
||||
LayerShell.Window.exclusionZone: Math.max(1, root.topBarInputHeight)
|
||||
LayerShell.Window.exclusionZone: Math.max(1, root.panelHeight + root.convergenceWorkspaceFrameThickness)
|
||||
LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ ContainmentItem {
|
|||
screen: Plasmoid.screen
|
||||
maximizedTracker: windowMaximizedTracker
|
||||
|
||||
visible: !root.fullscreen && !ShellSettings.Settings.convergenceModeEnabled
|
||||
visible: !root.fullscreen
|
||||
}
|
||||
|
||||
Item {
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
window-close-symbolic.svg
|
||||
|
|
@ -1 +0,0 @@
|
|||
window-close.svg
|
||||
|
|
@ -1 +1 @@
|
|||
window-close-symbolic.svg
|
||||
trash-empty.svg
|
||||
|
|
@ -1 +1 @@
|
|||
window-close.svg
|
||||
trash-empty.svg
|
||||
|
|
@ -1 +0,0 @@
|
|||
window-close-symbolic.svg
|
||||
|
|
@ -1 +1 @@
|
|||
window-close.svg
|
||||
trash-empty.svg
|
||||
|
|
@ -8,27 +8,13 @@ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|||
|
||||
constants="$repo_root/components/mobileshell/qml/components/Constants.qml"
|
||||
panel="$repo_root/containments/panel/qml/main.qml"
|
||||
status_panel="$repo_root/containments/panel/qml/StatusPanel.qml"
|
||||
status_bar_template="$repo_root/layout-templates/org.kde.plasma.mobile.defaultStatusBar/contents/layout.js"
|
||||
taskpanel="$repo_root/containments/taskpanel/qml/main.qml"
|
||||
folio_main="$repo_root/containments/homescreens/folio/qml/main.qml"
|
||||
shellutil_header="$repo_root/components/mobileshell/shellutil.h"
|
||||
shellutil_cpp="$repo_root/components/mobileshell/shellutil.cpp"
|
||||
folio_home="$repo_root/containments/homescreens/folio/qml/FolioHomeScreen.qml"
|
||||
folio_backend="$repo_root/containments/homescreens/folio/homescreen.h"
|
||||
folio_backend_cpp="$repo_root/containments/homescreens/folio/homescreen.cpp"
|
||||
action_content="$repo_root/components/mobileshell/qml/actiondrawer/private/ContentContainer.qml"
|
||||
action_open_surface="$repo_root/components/mobileshell/qml/actiondrawer/ActionDrawerOpenSurface.qml"
|
||||
action_landscape="$repo_root/components/mobileshell/qml/actiondrawer/private/LandscapeContentContainer.qml"
|
||||
quick_settings="$repo_root/components/mobileshell/qml/actiondrawer/private/QuickSettings.qml"
|
||||
quick_settings_panel="$repo_root/components/mobileshell/qml/actiondrawer/private/QuickSettingsPanel.qml"
|
||||
base_item="$repo_root/components/mobileshell/qml/components/BaseItem.qml"
|
||||
notification_popup_manager="$repo_root/components/mobileshell/qml/popups/notifications/NotificationPopupManager.qml"
|
||||
notification_popup="$repo_root/components/mobileshell/qml/popups/notifications/NotificationPopup.qml"
|
||||
notification_popup_item="$repo_root/components/mobileshell/qml/widgets/notifications/NotificationPopupItem.qml"
|
||||
notification_card="$repo_root/components/mobileshell/qml/widgets/notifications/NotificationCard.qml"
|
||||
notification_drawer="$repo_root/components/mobileshell/qml/actiondrawer/private/NotificationDrawer.qml"
|
||||
notifications_widget="$repo_root/components/mobileshell/qml/widgets/notifications/NotificationsWidget.qml"
|
||||
|
||||
require_line() {
|
||||
local file="$1"
|
||||
|
|
@ -46,42 +32,16 @@ require_line "$constants" "readonly property real convergenceWorkspaceFrameThick
|
|||
require_line "$constants" "readonly property real convergenceWorkspaceFrameRadius:"
|
||||
|
||||
require_line "$panel" "readonly property real convergenceWorkspaceFrameThickness:"
|
||||
require_line "$panel" "root.panel.location = PlasmaCore.Types.TopEdge"
|
||||
require_line "$panel" "root.panel.offset = 0"
|
||||
require_line "$panel" "root.panel.visibilityMode = (!ShellSettings.Settings.convergenceModeEnabled && ShellSettings.Settings.autoHidePanelsEnabled) ? 3 : 0"
|
||||
require_line "$panel" "readonly property real topBarHeight: gamingMode ? 0 : MobileShell.Constants.topPanelHeight"
|
||||
require_line "$panel" "readonly property real topBarInputHeight: topBarHeight + convergenceWorkspaceFrameThickness"
|
||||
require_line "$panel" "? 0"
|
||||
require_line "$panel" ": (ShellSettings.Settings.convergenceModeEnabled ? topBarInputHeight : MobileShell.Constants.topPanelHeight)"
|
||||
require_line "$panel" "MobileShell.ShellUtil.setInputRegion(root.panel, Qt.rect(0, 0, root.panel.width, root.panel.height));"
|
||||
require_line "$panel" "height: Math.max(1, root.topBarInputHeight)"
|
||||
require_line "$panel" "LayerShell.Window.exclusionZone: Math.max(1, root.topBarInputHeight)"
|
||||
require_line "$panel" "visible: !ShellSettings.Settings.gamingModeEnabled"
|
||||
|
||||
require_line "$status_panel" "&& !ShellSettings.Settings.convergenceModeEnabled"
|
||||
require_line "$status_panel" "visible: !ShellSettings.Settings.convergenceModeEnabled"
|
||||
require_line "$status_panel" "MobileShell.ActionDrawerOpenSurface {"
|
||||
require_line "$action_open_surface" "MouseArea {"
|
||||
require_line "$action_open_surface" "acceptedButtons: Qt.NoButton"
|
||||
require_line "$action_open_surface" "hoverEnabled: true"
|
||||
require_line "$action_open_surface" "cursorShape: ShellSettings.Settings.convergenceModeEnabled ? Qt.PointingHandCursor : Qt.ArrowCursor"
|
||||
|
||||
require_line "$status_bar_template" "panel.location = \"top\";"
|
||||
require_line "$panel" "height: Math.max(1, root.panelHeight + root.convergenceWorkspaceFrameThickness)"
|
||||
require_line "$panel" "LayerShell.Window.exclusionZone: Math.max(1, root.panelHeight + root.convergenceWorkspaceFrameThickness)"
|
||||
|
||||
require_line "$taskpanel" "readonly property real convergenceWorkspaceFrameThickness:"
|
||||
require_line "$taskpanel" "height: MobileShell.Constants.convergenceDockHeight + root.convergenceWorkspaceFrameThickness"
|
||||
require_line "$taskpanel" "LayerShell.Window.exclusionZone: MobileShell.Constants.convergenceDockHeight + root.convergenceWorkspaceFrameThickness"
|
||||
require_line "$taskpanel" "visible: !root.fullscreen && !ShellSettings.Settings.convergenceModeEnabled"
|
||||
require_line "$taskpanel" "LayerShell.Window.scope: \"workspace-frame-left\""
|
||||
require_line "$taskpanel" "LayerShell.Window.scope: \"workspace-frame-right\""
|
||||
|
||||
require_line "$folio_main" "id: convergenceChrome"
|
||||
require_line "$folio_main" "LayerShell.Window.scope: \"convergence-chrome\""
|
||||
require_line "$folio_main" "height: Screen.height"
|
||||
require_line "$folio_main" "MobileShell.StatusBar {"
|
||||
require_line "$folio_main" "MobileShell.ShellUtil.setInputRegions(convergenceChrome, ["
|
||||
require_line "$folio_main" "readonly property real topBarHitHeight: topBarHeight + frameThickness"
|
||||
require_line "$folio_main" "const topBarRegion = Qt.rect(0, 0, width, topBarHitHeight)"
|
||||
require_line "$folio_main" "height: MobileShell.Constants.convergenceDockHeight"
|
||||
require_line "$folio_main" "readonly property real dockHeight: MobileShell.Constants.convergenceDockHeight"
|
||||
require_line "$folio_main" "readonly property real revealStripHeight: MobileShell.Constants.convergenceDockRevealHeight"
|
||||
require_line "$folio_main" "import QtQuick.Shapes 1.8"
|
||||
|
|
@ -89,93 +49,32 @@ require_line "$folio_main" "id: workspaceFrame"
|
|||
require_line "$folio_main" "readonly property real frameThickness: MobileShell.Constants.convergenceWorkspaceFrameThickness"
|
||||
require_line "$folio_main" "readonly property real frameRadius:"
|
||||
require_line "$folio_main" "readonly property real workAreaX: frameThickness"
|
||||
require_line "$folio_main" "readonly property real workAreaY: topBarHitHeight"
|
||||
require_line "$folio_main" "readonly property real workAreaY: topReservedHeight + frameThickness"
|
||||
require_line "$folio_main" "readonly property real workAreaWidth: Math.max(0, width - frameThickness * 2)"
|
||||
require_line "$folio_main" "readonly property real workAreaHeight: Math.max(0, height - topBarHeight - dockHeight - frameThickness * 2)"
|
||||
require_line "$folio_main" "readonly property real workAreaHeight: Math.max(0, height - topReservedHeight - bottomReservedHeight - frameThickness * 2)"
|
||||
require_line "$folio_main" "fillRule: ShapePath.OddEvenFill"
|
||||
require_line "$folio_main" "PathLine { x: convergenceChrome.width; y: convergenceChrome.height - convergenceChrome.dockHeight }"
|
||||
require_line "$folio_main" "PathLine { x: 0; y: convergenceChrome.height - convergenceChrome.dockHeight }"
|
||||
require_line "$folio_main" "PathArc { x: convergenceChrome.workAreaX + convergenceChrome.workAreaWidth - convergenceChrome.frameRadius; y: convergenceChrome.workAreaY + convergenceChrome.workAreaHeight; radiusX: convergenceChrome.frameRadius; radiusY: convergenceChrome.frameRadius }"
|
||||
require_line "$folio_main" "PathArc { x: convergenceChrome.workAreaX; y: convergenceChrome.workAreaY + convergenceChrome.workAreaHeight - convergenceChrome.frameRadius; radiusX: convergenceChrome.frameRadius; radiusY: convergenceChrome.frameRadius }"
|
||||
require_line "$shellutil_header" "Q_INVOKABLE void setInputRegions(QWindow *window, const QVariantList ®ions);"
|
||||
require_line "$shellutil_cpp" "void ShellUtil::setInputRegions(QWindow *window, const QVariantList ®ions)"
|
||||
require_line "$shellutil_cpp" "for (const QVariant &value : regions)"
|
||||
require_line "$folio_main" "PathLine { x: workspaceFrame.width; y: workspaceFrame.height - workspaceFrame.bottomReservedHeight }"
|
||||
require_line "$folio_main" "PathLine { x: 0; y: workspaceFrame.height - workspaceFrame.bottomReservedHeight }"
|
||||
require_line "$folio_main" "PathArc { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth - workspaceFrame.frameRadius; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }"
|
||||
require_line "$folio_main" "PathArc { x: workspaceFrame.workAreaX; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight - workspaceFrame.frameRadius; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }"
|
||||
require_line "$folio_main" "readonly property real popupTopY: MobileShell.Constants.topPanelHeight"
|
||||
require_line "$folio_main" "+ MobileShell.Constants.convergenceWorkspaceFrameThickness"
|
||||
require_line "$folio_main" "readonly property real popupBottomY: parent.height"
|
||||
require_line "$folio_main" "- MobileShell.Constants.convergenceWorkspaceFrameThickness"
|
||||
require_line "$folio_main" "readonly property real popupHeight: Math.max(0, popupBottomY - popupTopY)"
|
||||
require_line "$folio_main" "? popupTopY + animationY"
|
||||
require_line "$folio_main" "id: drawerSurface"
|
||||
require_line "$folio_main" "readonly property real bodyWidth: Math.max(0, powerPanel.x + powerPanel.width - overlayDrawer.x)"
|
||||
require_line "$folio_main" "readonly property real cornerRadius: Math.min(MobileShell.Constants.convergenceWorkspaceFrameRadius"
|
||||
require_line "$folio_main" "PathArc { x: drawerSurface.bodyWidth; y: drawerSurfacePath.cornerRadius; radiusX: drawerSurfacePath.cornerRadius; radiusY: drawerSurfacePath.cornerRadius; direction: PathArc.Counterclockwise }"
|
||||
require_line "$folio_main" "PathArc { x: drawerSurface.bodyWidth + drawerSurfacePath.cornerRadius; y: drawerSurface.height; radiusX: drawerSurfacePath.cornerRadius; radiusY: drawerSurfacePath.cornerRadius; direction: PathArc.Counterclockwise }"
|
||||
require_line "$folio_home" "height: ShellSettings.Settings.convergenceModeEnabled ? MobileShell.Constants.convergenceDockHeight : Kirigami.Units.gridUnit * 6"
|
||||
require_line "$folio_home" "&& !ShellSettings.Settings.convergenceModeEnabled"
|
||||
require_line "$folio_backend" "Q_PROPERTY(bool overviewActive READ overviewActive NOTIFY overviewActiveChanged)"
|
||||
|
||||
overview_hide_guards="$(grep -F "&& !folio.overviewActive" "$folio_main" | wc -l)"
|
||||
if [[ "$overview_hide_guards" -ne 1 ]]; then
|
||||
echo "Expected Folio convergence chrome to hide during KWin Overview; found $overview_hide_guards overview guards" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! awk '
|
||||
/void HomeScreen::triggerOverview\(\)/ { in_trigger = 1; next }
|
||||
in_trigger && /setOverviewActive\(true\);/ { saw_pre_hide = 1; next }
|
||||
in_trigger && /createMethodCall/ {
|
||||
if (saw_pre_hide) {
|
||||
found = 1
|
||||
exit 0
|
||||
}
|
||||
exit 1
|
||||
}
|
||||
in_trigger && /^}/ { exit 1 }
|
||||
END { if (!found) exit 1 }
|
||||
' "$folio_backend_cpp"; then
|
||||
echo "Expected Folio to hide convergence chrome before invoking KWin Overview" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
require_line "$action_content" "readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight + convergenceFrameThickness"
|
||||
require_line "$action_content" "readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight"
|
||||
require_line "$action_content" "readonly property real convergenceSurfaceBottomInset: MobileShell.Constants.convergenceDockHeight + convergenceFrameThickness"
|
||||
require_line "$action_content" "readonly property real convergenceSurfaceSideInset: 0"
|
||||
require_line "$action_content" "readonly property real convergenceFloatingMargin: Kirigami.Units.gridUnit"
|
||||
require_line "$action_content" "readonly property real convergenceClickAwayGutter: Kirigami.Units.largeSpacing"
|
||||
require_line "$action_content" "readonly property real convergenceLeftSurfaceBottomInset: convergenceSurfaceBottomInset + convergenceBottomClickAwayHeight"
|
||||
require_line "$action_content" "readonly property real convergenceQuickSettingsLeft: contentContainerLoader.item ? contentContainerLoader.item.quickSettingsPanelLeft"
|
||||
require_line "$action_content" "readonly property real convergenceLeftSurfaceTopInset: convergenceSurfaceTopInset + convergenceFloatingMargin"
|
||||
require_line "$action_content" "readonly property real convergenceLeftSurfaceLeftInset: convergenceSurfaceSideInset + convergenceFloatingMargin"
|
||||
require_line "$action_content" "readonly property real convergenceLeftSurfaceRightInset: convergenceNotificationRightMargin + convergenceFloatingMargin"
|
||||
require_line "$action_content" "readonly property real convergenceLeftSurfaceBottomMargin: convergenceLeftSurfaceBottomInset + convergenceFloatingMargin"
|
||||
require_line "$action_content" "id: convergenceLeftSurface"
|
||||
require_line "$action_content" "id: convergenceMediaPanel"
|
||||
require_line "$action_content" "PlasmaCalendar.MonthView {"
|
||||
require_line "$action_content" "visible: actionDrawer.intendedToBeVisible"
|
||||
require_line "$action_content" "topMargin: isConvergence ? root.convergenceLeftSurfaceTopInset : 0"
|
||||
require_line "$action_content" "leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (isConvergence ? root.convergenceLeftSurfaceLeftInset"
|
||||
require_line "$action_content" "maximumHeight: isConvergence ? root.convergenceSurfaceHeight * 0.32 : -1"
|
||||
require_line "$action_content" "topMargin: isConvergence ? root.convergenceSurfaceTopInset : 0"
|
||||
require_line "$action_content" "leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (isConvergence ? root.convergenceSurfaceSideInset"
|
||||
require_line "$action_content" "maximumHeight: isConvergence ? root.convergenceSurfaceHeight * 0.6 : -1"
|
||||
|
||||
if grep -Fq "visible: !isConvergence" "$action_content"; then
|
||||
echo "NotificationDrawer must remain visible in convergence so the action drawer shows notification history" >&2
|
||||
exit 1
|
||||
fi
|
||||
if grep -Fq "visible: actionDrawer.intendedToBeVisible && !root.isConvergence" "$action_content"; then
|
||||
echo "Clear-all notification toolbar must remain visible in convergence" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
require_line "$action_landscape" "readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight + convergenceFrameThickness"
|
||||
require_line "$action_landscape" "readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight"
|
||||
require_line "$action_landscape" "readonly property real convergenceSurfaceBottomInset: MobileShell.Constants.convergenceDockHeight + convergenceFrameThickness"
|
||||
require_line "$action_landscape" "readonly property real convergenceSurfaceSideInset: 0"
|
||||
require_line "$action_landscape" "readonly property real quickSettingsPanelLeft: quickSettingsPanel.x"
|
||||
require_line "$action_landscape" "import QtQuick.Shapes 1.8"
|
||||
require_line "$action_landscape" "id: actionDrawerSurface"
|
||||
require_line "$action_landscape" "x: quickSettingsPanel.x - cornerRadius"
|
||||
require_line "$action_landscape" "readonly property real bodyWidth: quickSettingsPanel.width"
|
||||
require_line "$action_landscape" "PathArc { x: actionDrawerSurfacePath.cornerRadius; y: actionDrawerSurfacePath.cornerRadius; radiusX: actionDrawerSurfacePath.cornerRadius; radiusY: actionDrawerSurfacePath.cornerRadius; direction: PathArc.Clockwise }"
|
||||
require_line "$action_landscape" "PathArc { x: 0; y: actionDrawerSurface.height; radiusX: actionDrawerSurfacePath.cornerRadius; radiusY: actionDrawerSurfacePath.cornerRadius; direction: PathArc.Clockwise }"
|
||||
require_line "$action_landscape" "anchors.topMargin: isConvergence ? restingTopMargin"
|
||||
require_line "$action_landscape" "anchors.rightMargin: isConvergence ? root.convergenceSurfaceSideInset : 0"
|
||||
require_line "$action_landscape" "fullScreenHeight: quickSettingsPanel.availableHeight"
|
||||
|
|
@ -183,53 +82,15 @@ require_line "$action_landscape" "fullScreenHeight: quickSettingsPanel.available
|
|||
require_line "$quick_settings_panel" "readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled"
|
||||
require_line "$quick_settings_panel" "readonly property real panelPadding: isConvergence ? Kirigami.Units.smallSpacing : Kirigami.Units.smallSpacing * 4"
|
||||
require_line "$quick_settings_panel" "anchors.margins: root.isConvergence ? 0 : Kirigami.Units.largeSpacing"
|
||||
require_line "$quick_settings_panel" "visible: !root.isConvergence"
|
||||
require_line "$quick_settings_panel" "panelType: root.isConvergence ? MobileShell.PanelBackground.PanelType.Flat : MobileShell.PanelBackground.PanelType.Base"
|
||||
require_line "$quick_settings_panel" "radius: root.isConvergence ? 0 : Kirigami.Units.cornerRadius"
|
||||
|
||||
require_line "$base_item" "implicitHeight: topPadding + bottomPadding + (contentItem ? contentItem.implicitHeight : 0)"
|
||||
require_line "$base_item" "implicitWidth: leftPadding + rightPadding + (contentItem ? contentItem.implicitWidth : 0)"
|
||||
|
||||
require_line "$quick_settings" "id: convergenceFlow"
|
||||
require_line "$quick_settings" "visible: root.isConvergence"
|
||||
require_line "$quick_settings" "visible: !root.isConvergence"
|
||||
require_line "$quick_settings" "active: !root.isConvergence && swipeView.count > 1 ? true: false"
|
||||
|
||||
if grep -Fq "id: convergenceNotificationHistory" "$quick_settings"; then
|
||||
echo "Convergence notification history must not consume quick-settings stack height" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if grep -Fq "NotificationHistoryPopup" "$quick_settings"; then
|
||||
echo "Notification history must use the in-drawer NotificationDrawer, not a separate popup" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
require_line "$notification_popup_manager" "readonly property real convergencePopupMargin: MobileShell.Constants.convergenceWorkspaceFrameThickness + Kirigami.Units.largeSpacing"
|
||||
require_line "$notification_popup_manager" "readonly property real convergencePopupBottomInset: MobileShell.Constants.convergenceDockHeight + MobileShell.Constants.convergenceWorkspaceFrameThickness + Kirigami.Units.largeSpacing"
|
||||
require_line "$notification_popup_manager" "let regionY = (currentPopup ? currentPopup.effectiveOpenOffset : Screen.height - notificationPopupManager.convergencePopupBottomInset - popupHeight)"
|
||||
require_line "$notification_popup_manager" "convergenceBottomInset: notificationPopupManager.convergencePopupBottomInset"
|
||||
require_line "$notification_popup_manager" "? (notificationPopupManager.width - width - notificationPopupManager.convergencePopupMargin)"
|
||||
require_line "$notification_popup" "property real convergenceBottomInset: openOffset"
|
||||
require_line "$notification_popup" "? (Screen.height - convergenceBottomInset - popupHeight)"
|
||||
require_line "$notification_popup_item" "icon.name: \"window-close\""
|
||||
require_line "$notification_popup_item" "text: i18n(\"Dismiss\")"
|
||||
require_line "$notification_card" "if (!contentItem) {"
|
||||
require_line "$notification_drawer" "&& !ShellSettings.Settings.convergenceModeEnabled"
|
||||
require_line "$notification_drawer" "emptyText: ShellSettings.Settings.convergenceModeEnabled ? i18n(\"No notifications\") : \"\""
|
||||
require_line "$notifications_widget" "property string emptyText: \"\""
|
||||
|
||||
if grep -Fq "notificationItem.close();" "$notification_popup_item"; then
|
||||
echo "Popup dismissals must expire the popup instead of closing notification history" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if grep -Fq "contentParent.children.push(contentItem);" "$notification_card"; then
|
||||
echo "NotificationCard content is already parented by assignment; do not push it into children again" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
frame_arc_count="$(grep -F "PathArc { x: convergenceChrome." "$folio_main" | wc -l || true)"
|
||||
frame_arc_count="$(grep -F "PathArc {" "$folio_main" | wc -l)"
|
||||
if [[ "$frame_arc_count" -ne 4 ]]; then
|
||||
echo "Expected the workspace frame cutout to have four rounded inner corners; found $frame_arc_count arcs" >&2
|
||||
exit 1
|
||||
|
|
@ -240,8 +101,8 @@ if grep -Fq "convergenceWallpaperLayer" "$folio_main"; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
dock_offset_transforms="$(grep -F "transform: Translate { y: convergenceChrome.dockOffset }" "$folio_main" | wc -l || true)"
|
||||
dock_offset_transforms="$(grep -F "transform: Translate { y: dockOverlay.dockOffset }" "$folio_main" | wc -l)"
|
||||
if [[ "$dock_offset_transforms" -ne 1 ]]; then
|
||||
echo "Expected only dock contents to slide with convergenceChrome.dockOffset; found $dock_offset_transforms transforms" >&2
|
||||
echo "Expected only dock contents to slide with dockOverlay.dockOffset; found $dock_offset_transforms transforms" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ effect_metadata="$repo_root/kwin/effects/shift-tile-preview/metadata.json"
|
|||
effects_cmake="$repo_root/kwin/effects/CMakeLists.txt"
|
||||
tiling_script="$repo_root/kwin/scripts/shift-tiling/contents/ui/main.qml"
|
||||
decoration_qml="$repo_root/kwin/decorations/org.shift.decoration/contents/ui/main.qml"
|
||||
running_apps_panel="$repo_root/containments/homescreens/folio/qml/RunningAppsPanel.qml"
|
||||
env_config="$repo_root/envmanager/config.h"
|
||||
|
||||
require_line() {
|
||||
|
|
@ -126,23 +125,6 @@ require_line "$decoration_qml" "borders.bottom = normalCornerRadius;"
|
|||
require_line "$decoration_qml" "PathArc { x: root.width - root.cornerRadius; y: root.height; radiusX: root.cornerRadius; radiusY: root.cornerRadius }"
|
||||
require_line "$decoration_qml" "PathArc { x: 0; y: root.height - root.cornerRadius; radiusX: root.cornerRadius; radiusY: root.cornerRadius }"
|
||||
|
||||
running_panel_group_disabled_count="$(grep -F "groupMode: TaskManager.TasksModel.GroupDisabled" "$running_apps_panel" | wc -l)"
|
||||
if [[ "$running_panel_group_disabled_count" -ne 2 ]]; then
|
||||
echo "Expected the Folio Running panel to disable grouping for both task models; found $running_panel_group_disabled_count" >&2
|
||||
exit 1
|
||||
fi
|
||||
reject_line "$running_apps_panel" "groupMode: TaskManager.TasksModel.GroupApplications"
|
||||
|
||||
if awk '
|
||||
/ShellSettings\.Settings\.requestDynamicTilingWindowAction\(taskCard\.windowId, action\)/ { seen = 1; next }
|
||||
seen && /return/ { exit 0 }
|
||||
seen && /tasksModel\.requestVirtualDesktops\(taskCard\.modelIndex, \[desktopId\]\)/ { exit 1 }
|
||||
END { exit 1 }
|
||||
' "$running_apps_panel"; then
|
||||
echo "Expected the Folio Running panel desktop drop to fall through to TaskManager after notifying dynamic tiling" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
reject_line "$tiling_script" "targetKey = lastLeafKey(rootNode)"
|
||||
reject_line "$tiling_script" "function lastLeafKey(node)"
|
||||
reject_line "$tiling_script" "win.output.name !== outputName"
|
||||
|
|
|
|||
|
|
@ -181,20 +181,6 @@ require_line "$theme_dir/index.theme" '^\[apps/scalable\]$' \
|
|||
"org.shift.icons index.theme is missing [apps/scalable]"
|
||||
require_line "$theme_dir/index.theme" '^\[preferences/scalable\]$' \
|
||||
"org.shift.icons index.theme is missing [preferences/scalable]"
|
||||
|
||||
[[ "$(readlink "$theme_dir/actions/symbolic/delete.svg")" == "window-close.svg" ]] \
|
||||
|| fail "delete must resolve to the X close glyph for KWin Overview's virtual desktop delete button"
|
||||
[[ "$(readlink "$theme_dir/actions/symbolic/delete-symbolic.svg")" == "window-close-symbolic.svg" ]] \
|
||||
|| fail "delete-symbolic must resolve to the symbolic X close glyph for KWin Overview's virtual desktop delete button"
|
||||
[[ "$(readlink "$theme_dir/actions/symbolic/edit-delete.svg")" == "window-close.svg" ]] \
|
||||
|| fail "edit-delete must resolve to the X close glyph for KWin Overview's virtual desktop delete button"
|
||||
[[ "$(readlink "$theme_dir/actions/symbolic/edit-delete-symbolic.svg")" == "window-close-symbolic.svg" ]] \
|
||||
|| fail "edit-delete-symbolic must resolve to the symbolic X close glyph for KWin Overview's virtual desktop delete button"
|
||||
[[ "$(readlink "$theme_dir/actions/symbolic/edit-delete-remove.svg")" == "window-close.svg" ]] \
|
||||
|| fail "edit-delete-remove must resolve to the X close glyph for KWin Overview's virtual desktop delete button"
|
||||
[[ "$(readlink "$theme_dir/actions/symbolic/edit-delete-remove-symbolic.svg")" == "window-close-symbolic.svg" ]] \
|
||||
|| fail "edit-delete-remove-symbolic must resolve to the symbolic X close glyph for KWin Overview's virtual desktop delete button"
|
||||
|
||||
check_systemsettings_category_icons
|
||||
check_systemsettings_module_icons
|
||||
|
||||
|
|
|
|||
|
|
@ -111,27 +111,22 @@ require_line lookandfeel/contents/logout/Logout.qml 'plasma_lookandfeel_org\.shi
|
|||
require_line lookandfeel/Messages.sh 'plasma_lookandfeel_org\.shift\.mobile\.pot' \
|
||||
"look-and-feel Messages.sh must generate the Shift translation domain"
|
||||
|
||||
if [[ -f preview.sh ]]; then
|
||||
require_line preview.sh 'PLASMA_THEME=shift-light' \
|
||||
"preview light mode must select the Shift light Plasma desktop theme"
|
||||
require_line preview.sh 'PLASMA_THEME=shift-dark' \
|
||||
"preview dark mode must select the Shift dark Plasma desktop theme"
|
||||
reject_line preview.sh 'PLASMA_THEME=breeze-' \
|
||||
"preview must not select Breeze Plasma desktop themes"
|
||||
require_line preview.sh 'Shift does not ship a QQC2 style plugin yet' \
|
||||
"preview must document the Breeze QQC2 fallback"
|
||||
reject_line preview.sh 'QT_QUICK_CONTROLS_STYLE=org\.shift|QT_QUICK_CONTROLS_STYLE=SHIFT|QT_QUICK_CONTROLS_STYLE=Shift' \
|
||||
"preview must not reference a non-existent Shift QQC2 style"
|
||||
else
|
||||
require_line .gitignore '^preview[.]sh$' \
|
||||
"preview.sh is a local developer script and must remain ignored when absent from CI"
|
||||
fi
|
||||
require_line preview.sh 'PLASMA_THEME=shift-light' \
|
||||
"preview light mode must select the Shift light Plasma desktop theme"
|
||||
require_line preview.sh 'PLASMA_THEME=shift-dark' \
|
||||
"preview dark mode must select the Shift dark Plasma desktop theme"
|
||||
reject_line preview.sh 'PLASMA_THEME=breeze-' \
|
||||
"preview must not select Breeze Plasma desktop themes"
|
||||
require_line preview.sh 'Shift does not ship a QQC2 style plugin yet' \
|
||||
"preview must document the Breeze QQC2 fallback"
|
||||
require_line bin/startplasmamobile.in 'Shift does not ship a QQC2 style plugin yet' \
|
||||
"runtime launcher must document the Breeze QQC2 fallback"
|
||||
require_line HACKING.md 'Shift does not ship a QQC2 style plugin yet' \
|
||||
"HACKING.md must document the Breeze QQC2 fallback"
|
||||
require_line .kde-ci.yml 'plasma/qqc2-breeze-style' \
|
||||
"CI must keep the Breeze QQC2 runtime dependency until Shift ships a QQC2 style"
|
||||
reject_line preview.sh 'QT_QUICK_CONTROLS_STYLE=org\.shift|QT_QUICK_CONTROLS_STYLE=SHIFT|QT_QUICK_CONTROLS_STYLE=Shift' \
|
||||
"preview must not reference a non-existent Shift QQC2 style"
|
||||
reject_line bin/startplasmamobile.in 'QT_QUICK_CONTROLS_STYLE=org\.shift|QT_QUICK_CONTROLS_STYLE=SHIFT|QT_QUICK_CONTROLS_STYLE=Shift' \
|
||||
"runtime launcher must not reference a non-existent Shift QQC2 style"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue