Warning, /plasma/plasma-mobile/shell/contents/views/Panel.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 * SPDX-FileCopyrightText: 2012 Marco Martin <mart@kde.org>
0003 *
0004 * SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006
0007 import QtQuick 2.15
0008 import QtQuick.Window 2.15
0009 import QtQuick.Layouts 1.1
0010 import QtQml 2.15
0011
0012 import org.kde.plasma.core as PlasmaCore
0013 import org.kde.ksvg 1.0 as KSvg
0014 import org.kde.taskmanager 0.1 as TaskManager
0015 import org.kde.kwindowsystem 1.0
0016 import org.kde.kirigami 2.20 as Kirigami
0017 import org.kde.plasma.shell.panel 0.1 as Panel
0018
0019 import org.kde.plasma.plasmoid 2.0
0020
0021 Item {
0022 id: root
0023
0024 // NOTE: Plasma Mobile specific:
0025 Connections {
0026 target: root
0027
0028 function onContainmentChanged() {
0029 // HACK: add PanelView into the containment so that it can be used
0030 if (containment.panel !== undefined) {
0031 containment.panel = panel;
0032 }
0033 if (containment.tabBar !== undefined) {
0034 containment.tabBar = tabBar;
0035 }
0036 }
0037 }
0038
0039 // NOTE: Below is taken straight out of Plasma Desktop so that we can
0040 // support desktop panels properly, try to keep it in sync:
0041 // plasma-desktop/desktoppackage/contents/views/Panel.qml
0042
0043 property Item containment
0044
0045 property bool floatingPrefix: floatingPanelSvg.usedPrefix === "floating"
0046 readonly property bool verticalPanel: containment?.plasmoid?.formFactor === PlasmaCore.Types.Vertical
0047
0048 readonly property real spacingAtMinSize: Math.round(Math.max(1, (verticalPanel ? root.width : root.height) - Kirigami.Units.iconSizes.smallMedium)/2)
0049 KSvg.FrameSvgItem {
0050 id: thickPanelSvg
0051 visible: false
0052 prefix: 'thick'
0053 imagePath: "widgets/panel-background"
0054 }
0055 KSvg.FrameSvgItem {
0056 id: floatingPanelSvg
0057 visible: false
0058 prefix: ['floating', '']
0059 imagePath: "widgets/panel-background"
0060 }
0061
0062 readonly property bool topEdge: containment?.plasmoid?.location === PlasmaCore.Types.TopEdge
0063 readonly property bool leftEdge: containment?.plasmoid?.location === PlasmaCore.Types.LeftEdge
0064 readonly property bool rightEdge: containment?.plasmoid?.location === PlasmaCore.Types.RightEdge
0065 readonly property bool bottomEdge: containment?.plasmoid?.location === PlasmaCore.Types.BottomEdge
0066
0067 readonly property int topPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.top + Kirigami.Units.smallSpacing, spacingAtMinSize));
0068 readonly property int bottomPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.bottom + Kirigami.Units.smallSpacing, spacingAtMinSize));
0069 readonly property int leftPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.left + Kirigami.Units.smallSpacing, spacingAtMinSize));
0070 readonly property int rightPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.right + Kirigami.Units.smallSpacing, spacingAtMinSize));
0071
0072 readonly property int fixedBottomFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.bottom : 8)
0073 readonly property int fixedLeftFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.left : 8)
0074 readonly property int fixedRightFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.right : 8)
0075 readonly property int fixedTopFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.top : 8)
0076
0077 readonly property int bottomFloatingPadding: Math.round(fixedBottomFloatingPadding * floatingness)
0078 readonly property int leftFloatingPadding: Math.round(fixedLeftFloatingPadding * floatingness)
0079 readonly property int rightFloatingPadding: Math.round(fixedRightFloatingPadding * floatingness)
0080 readonly property int topFloatingPadding: Math.round(fixedTopFloatingPadding * floatingness)
0081
0082 readonly property int minPanelHeight: translucentItem.minimumDrawingHeight
0083 readonly property int minPanelWidth: translucentItem.minimumDrawingWidth
0084
0085 TaskManager.VirtualDesktopInfo {
0086 id: virtualDesktopInfo
0087 }
0088
0089 TaskManager.ActivityInfo {
0090 id: activityInfo
0091 }
0092
0093 property bool touchingWindow: visibleWindowsModel.count > 0
0094
0095 TaskManager.TasksModel {
0096 id: visibleWindowsModel
0097 filterByVirtualDesktop: true
0098 filterByActivity: true
0099 filterByScreen: true
0100 filterByRegion: TaskManager.RegionFilterMode.Intersect
0101 filterHidden: true
0102 filterMinimized: true
0103
0104 screenGeometry: panel.screenGeometry
0105 virtualDesktop: virtualDesktopInfo.currentDesktop
0106 activity: activityInfo.currentActivity
0107
0108 groupMode: TaskManager.TasksModel.GroupDisabled
0109
0110 Binding on regionGeometry {
0111 delayed: true
0112 property real verticalMargin: (fixedTopFloatingPadding + fixedBottomFloatingPadding) * (1 - floatingness)
0113 property real horizontalMargin: (fixedLeftFloatingPadding + fixedRightFloatingPadding) * (1 - floatingness)
0114 // This makes the panel de-float when a window is 6px from it or less.
0115 // 6px is chosen to avoid any potential issue with kwin snapping behavior,
0116 // and it looks like the panel hides away from the active window.
0117 value: floatingness, panel.width, panel.height, panel.x, panel.y, panel.geometryByDistance(6 + (verticalPanel ? horizontalMargin : verticalMargin))
0118 }
0119 }
0120
0121 Connections {
0122 target: containment
0123 function onActivated() {
0124 // BUG 472909: status changes to PassiveStatus or ActiveStatus after applet shortcut is pressed for the second time
0125 if (containment.status === PlasmaCore.Types.PassiveStatus /*After pressing panel shortcut*/ || containment.status === PlasmaCore.Types.ActiveStatus) {
0126 containment.status = PlasmaCore.Types.AcceptingInputStatus;
0127 // BUG 472909: if applet shortcut is pressed, panel also gets activated, but status will change to RequiresAttentionStatus after applet has focus
0128 } else /* Panel has focus, or applet has focus */ {
0129 containment.status = PlasmaCore.Types.PassiveStatus;
0130 }
0131 }
0132 }
0133
0134 // Floatingness is a value in [0, 1] that's multiplied to the floating margin; 0: not floating, 1: floating, between 0 and 1: animation between the two states
0135 property double floatingness
0136 // PanelOpacity is a value in [0, 1] that's used as the opacity of the opaque elements over the transparent ones; values between 0 and 1 are used for animations
0137 property double panelOpacity
0138 Behavior on floatingness {
0139 NumberAnimation {
0140 duration: Kirigami.Units.longDuration
0141 easing.type: Easing.OutCubic
0142 }
0143 }
0144 Behavior on panelOpacity {
0145 NumberAnimation {
0146 duration: Kirigami.Units.longDuration
0147 easing.type: Easing.OutCubic
0148 }
0149 }
0150
0151 // This value is read from panelview.cpp and disables shadow for floating panels, as they'd be detached from the panel
0152 property bool hasShadows: floatingness < 0.5
0153 property var panelMask: floatingness === 0 ? (panelOpacity === 1 ? opaqueItem.mask : translucentItem.mask) : (panelOpacity === 1 ? floatingOpaqueItem.mask : floatingTranslucentItem.mask)
0154
0155 // These two values are read from panelview.cpp and are used as an offset for the mask
0156 property int maskOffsetX: floatingTranslucentItem.x
0157 property int maskOffsetY: floatingTranslucentItem.y
0158
0159 KSvg.FrameSvgItem {
0160 id: translucentItem
0161 visible: floatingness === 0 && panelOpacity !== 1
0162 enabledBorders: panel.enabledBorders
0163 anchors.fill: floatingTranslucentItem
0164 imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "widgets/panel-background"
0165 }
0166 KSvg.FrameSvgItem {
0167 id: floatingTranslucentItem
0168 visible: floatingness !== 0 && panelOpacity !== 1
0169 x: root.leftEdge ? fixedLeftFloatingPadding + fixedRightFloatingPadding * (1 - floatingness) : leftFloatingPadding
0170 y: root.topEdge ? fixedTopFloatingPadding + fixedBottomFloatingPadding * (1 - floatingness) : topFloatingPadding
0171 width: verticalPanel ? panel.thickness : parent.width - leftFloatingPadding - rightFloatingPadding
0172 height: verticalPanel ? parent.height - topFloatingPadding - bottomFloatingPadding : panel.thickness
0173
0174 imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "widgets/panel-background"
0175 }
0176 KSvg.FrameSvgItem {
0177 id: floatingOpaqueItem
0178 visible: floatingness !== 0 && panelOpacity !== 0
0179 opacity: panelOpacity
0180 anchors.fill: floatingTranslucentItem
0181 imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "solid/widgets/panel-background"
0182 }
0183 KSvg.FrameSvgItem {
0184 id: opaqueItem
0185 visible: panelOpacity !== 0 && floatingness === 0
0186 opacity: panelOpacity
0187 enabledBorders: panel.enabledBorders
0188 anchors.fill: floatingTranslucentItem
0189 imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "solid/widgets/panel-background"
0190 }
0191 KSvg.FrameSvgItem {
0192 id: floatingShadow
0193 visible: !hasShadows
0194 z: -100
0195 imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "solid/widgets/panel-background"
0196 prefix: "shadow"
0197 anchors {
0198 fill: floatingTranslucentItem
0199 topMargin: -floatingShadow.margins.top
0200 leftMargin: -floatingShadow.margins.left
0201 rightMargin: -floatingShadow.margins.right
0202 bottomMargin: -floatingShadow.margins.bottom
0203 }
0204 }
0205
0206 Keys.onEscapePressed: {
0207 root.parent.focus = false
0208 }
0209
0210 property bool isOpaque: panel.opacityMode === Panel.Global.Opaque
0211 property bool isTransparent: panel.opacityMode === Panel.Global.Translucent
0212 property bool isAdaptive: panel.opacityMode === Panel.Global.Adaptive
0213 property bool floating: panel.floating
0214 readonly property bool screenCovered: !KWindowSystem.showingDesktop && touchingWindow && panel.visibilityMode == Panel.Global.NormalPanel
0215 property var stateTriggers: [floating, screenCovered, isOpaque, isAdaptive, isTransparent, KX11Extras.compositingActive]
0216 onStateTriggersChanged: {
0217 let opaqueApplets = false
0218 let floatingApplets = false
0219 if ((!floating || screenCovered) && (isOpaque || (screenCovered && isAdaptive))) {
0220 panelOpacity = 1
0221 opaqueApplets = true
0222 floatingness = 0
0223 } else if ((!floating || screenCovered) && (isTransparent || (!screenCovered && isAdaptive))) {
0224 panelOpacity = 0
0225 floatingness = 0
0226 } else if ((floating && !screenCovered) && (isTransparent || isAdaptive)) {
0227 panelOpacity = 0
0228 floatingness = 1
0229 floatingApplets = true
0230 } else if (floating && !screenCovered && isOpaque) {
0231 panelOpacity = 1
0232 opaqueApplets = true
0233 floatingness = 1
0234 floatingApplets = true
0235 }
0236 if (!KWindowSystem.isPlatformWayland && !KX11Extras.compositingActive) {
0237 opaqueApplets = false
0238 panelOpacity = 0
0239 }
0240 // Not using panelOpacity to check as it has a NumberAnimation, and it will thus
0241 // be still read as the initial value here, before the animation starts.
0242 if (containment) {
0243 if (opaqueApplets) {
0244 containment.plasmoid.containmentDisplayHints |= PlasmaCore.Types.ContainmentPrefersOpaqueBackground
0245 } else {
0246 containment.plasmoid.containmentDisplayHints &= ~PlasmaCore.Types.ContainmentPrefersOpaqueBackground
0247 }
0248 if (floatingApplets) {
0249 containment.plasmoid.containmentDisplayHints |= PlasmaCore.Types.ContainmentPrefersFloatingApplets
0250 } else {
0251 containment.plasmoid.containmentDisplayHints &= ~PlasmaCore.Types.ContainmentPrefersFloatingApplets
0252 }
0253 }
0254 }
0255
0256 function adjustPrefix() {
0257 if (!containment) {
0258 return "";
0259 }
0260 var pre;
0261 switch (containment.plasmoid.location) {
0262 case PlasmaCore.Types.LeftEdge:
0263 pre = "west";
0264 break;
0265 case PlasmaCore.Types.TopEdge:
0266 pre = "north";
0267 break;
0268 case PlasmaCore.Types.RightEdge:
0269 pre = "east";
0270 break;
0271 case PlasmaCore.Types.BottomEdge:
0272 pre = "south";
0273 break;
0274 default:
0275 pre = "";
0276 break;
0277 }
0278 translucentItem.prefix = opaqueItem.prefix = floatingTranslucentItem.prefix = floatingOpaqueItem.prefix = [pre, ""];
0279 }
0280
0281 onContainmentChanged: {
0282 if (!containment) {
0283 return;
0284 }
0285 containment.parent = containmentParent;
0286 containment.visible = true;
0287 containment.anchors.fill = containmentParent;
0288 containment.plasmoid.locationChanged.connect(adjustPrefix);
0289 adjustPrefix();
0290 }
0291
0292 Binding {
0293 target: panel
0294 property: "length"
0295 when: containment
0296 delayed: true
0297 value: {
0298 if (!containment) {
0299 return;
0300 }
0301 if (verticalPanel) {
0302 return containment.Layout.preferredHeight
0303 } else {
0304 return containment.Layout.preferredWidth
0305 }
0306 }
0307 restoreMode: Binding.RestoreBinding
0308 }
0309
0310 Binding {
0311 target: panel
0312 property: "backgroundHints"
0313 when: containment
0314 value: {
0315 if (!containment) {
0316 return;
0317 }
0318
0319 return containment.plasmoid.backgroundHints;
0320 }
0321 restoreMode: Binding.RestoreBinding
0322 }
0323
0324 KSvg.FrameSvgItem {
0325 id: tabBar
0326 x: root.verticalPanel || !panel.activeFocusItem
0327 ? 0
0328 : Math.max(panel.activeFocusItem.Kirigami.ScenePosition.x, panel.activeFocusItem.Kirigami.ScenePosition.x)
0329 y: root.verticalPanel && panel.activeFocusItem
0330 ? Math.max(panel.activeFocusItem.Kirigami.ScenePosition.y, panel.activeFocusItem.Kirigami.ScenePosition.y)
0331 : 0
0332
0333 width: panel.activeFocusItem
0334 ? (root.verticalPanel ? root.width : Math.min(panel.activeFocusItem.width, panel.activeFocusItem.width))
0335 : 0
0336 height: panel.activeFocusItem
0337 ? (root.verticalPanel ? Math.min(panel.activeFocusItem.height, panel.activeFocusItem.height) : root.height)
0338 : 0
0339
0340 visible: panel.active && panel.activeFocusItem
0341
0342 imagePath: "widgets/tabbar"
0343 prefix: {
0344 if (!root.containment) {
0345 return "";
0346 }
0347 var prefix = ""
0348 switch (root.containment.plasmoid.location) {
0349 case PlasmaCore.Types.LeftEdge:
0350 prefix = "west-active-tab";
0351 break;
0352 case PlasmaCore.Types.TopEdge:
0353 prefix = "north-active-tab";
0354 break;
0355 case PlasmaCore.Types.RightEdge:
0356 prefix = "east-active-tab";
0357 break;
0358 default:
0359 prefix = "south-active-tab";
0360 }
0361 if (!hasElementPrefix(prefix)) {
0362 prefix = "active-tab";
0363 }
0364 return prefix;
0365 }
0366 }
0367 Item {
0368 id: containmentParent
0369 anchors.centerIn: isOpaque ? floatingOpaqueItem : floatingTranslucentItem
0370 width: root.verticalPanel ? panel.thickness : root.width - root.floatingness * (fixedLeftFloatingPadding + fixedRightFloatingPadding)
0371 height: root.verticalPanel ? root.height - root.floatingness * (fixedBottomFloatingPadding - fixedTopFloatingPadding) : panel.thickness
0372 }
0373
0374 }