Warning, /plasma/plasma-desktop/desktoppackage/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     property Item containment
0025 
0026     property bool floatingPrefix: floatingPanelSvg.usedPrefix === "floating"
0027     readonly property bool verticalPanel: containment?.plasmoid?.formFactor === PlasmaCore.Types.Vertical
0028 
0029     readonly property real spacingAtMinSize: Math.round(Math.max(1, (verticalPanel ? root.width : root.height) - Kirigami.Units.iconSizes.smallMedium)/2)
0030     KSvg.FrameSvgItem {
0031         id: thickPanelSvg
0032         visible: false
0033         prefix: 'thick'
0034         imagePath: "widgets/panel-background"
0035     }
0036     KSvg.FrameSvgItem {
0037         id: floatingPanelSvg
0038         visible: false
0039         prefix: ['floating', '']
0040         imagePath: "widgets/panel-background"
0041     }
0042 
0043     // NOTE: Many of the properties in this file are accessed directly in C++ PanelView!
0044     // If you change these, make sure to also correct the related code in panelview.cpp.
0045 
0046     readonly property bool topEdge: containment?.plasmoid?.location === PlasmaCore.Types.TopEdge
0047     readonly property bool leftEdge: containment?.plasmoid?.location === PlasmaCore.Types.LeftEdge
0048     readonly property bool rightEdge: containment?.plasmoid?.location === PlasmaCore.Types.RightEdge
0049     readonly property bool bottomEdge: containment?.plasmoid?.location === PlasmaCore.Types.BottomEdge
0050 
0051     readonly property int topPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.top + Kirigami.Units.smallSpacing, spacingAtMinSize));
0052     readonly property int bottomPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.bottom + Kirigami.Units.smallSpacing, spacingAtMinSize));
0053     readonly property int leftPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.left + Kirigami.Units.smallSpacing, spacingAtMinSize));
0054     readonly property int rightPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.right + Kirigami.Units.smallSpacing, spacingAtMinSize));
0055 
0056     readonly property int fixedBottomFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.bottom : 8)
0057     readonly property int fixedLeftFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.left   : 8)
0058     readonly property int fixedRightFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.right  : 8)
0059     readonly property int fixedTopFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.top    : 8)
0060 
0061     readonly property int bottomFloatingPadding: Math.round(fixedBottomFloatingPadding * floatingness)
0062     readonly property int leftFloatingPadding: Math.round(fixedLeftFloatingPadding * floatingness)
0063     readonly property int rightFloatingPadding: Math.round(fixedRightFloatingPadding * floatingness)
0064     readonly property int topFloatingPadding: Math.round(fixedTopFloatingPadding * floatingness)
0065 
0066     readonly property int minPanelHeight: translucentItem.minimumDrawingHeight
0067     readonly property int minPanelWidth: translucentItem.minimumDrawingWidth
0068 
0069     TaskManager.VirtualDesktopInfo {
0070         id: virtualDesktopInfo
0071     }
0072 
0073     TaskManager.ActivityInfo {
0074         id: activityInfo
0075     }
0076 
0077     // We need to have a little gap between the raw visibleWindowsModel count
0078     // and actually determining if a window is touching.
0079     // This is because certain dialog windows start off with a position of (screenwidth/2, screenheight/2)
0080     // and they register as "touching" in the split-second before KWin can place them correctly.
0081     // This avoids the panel flashing if it is auto-hide etc and such a window is shown.
0082     // Examples of such windows: properties of a file on desktop, or portal "open with" dialog
0083     property bool touchingWindow: false
0084     property bool touchingWindowDirect: visibleWindowsModel.count > 0
0085     property bool showingDesktop: KWindowSystem.showingDesktop
0086     Timer {
0087         id: touchingWindowDebounceTimer
0088         interval: 10  // ms, I find that this value is enough while not causing unresponsiveness while dragging windows close
0089         onTriggered: root.touchingWindow = !KWindowSystem.showingDesktop && root.touchingWindowDirect
0090     }
0091     onTouchingWindowDirectChanged: touchingWindowDebounceTimer.start()
0092     onShowingDesktopChanged: touchingWindowDebounceTimer.start()
0093 
0094     TaskManager.TasksModel {
0095         id: visibleWindowsModel
0096         filterByVirtualDesktop: true
0097         filterByActivity: true
0098         filterByScreen: false
0099         filterByRegion: TaskManager.RegionFilterMode.Intersect
0100         filterHidden: true
0101         filterMinimized: true
0102 
0103         screenGeometry: panel.screenGeometry
0104         virtualDesktop: virtualDesktopInfo.currentDesktop
0105         activity: activityInfo.currentActivity
0106 
0107         groupMode: TaskManager.TasksModel.GroupDisabled
0108 
0109         Binding on regionGeometry {
0110             delayed: true
0111             property real verticalMargin: (fixedTopFloatingPadding + fixedBottomFloatingPadding) * (1 - floatingness)
0112             property real horizontalMargin: (fixedLeftFloatingPadding + fixedRightFloatingPadding) * (1 - floatingness)
0113 
0114             // This makes the panel de-float when a window is 12px from it or less.
0115             // 12px 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             property int defloatDistance: 12 + (verticalPanel ? horizontalMargin : verticalMargin)
0118             // Instead, we will only dodge an active panel if the panel is covered by it,
0119             // i.e. if the window touches at least one pixel of the panel
0120             property int dodgeDistance: -1
0121             // We don't have to worry about dealing with both at the same time since
0122             // dodge-window panels never de-float.
0123 
0124             value: floatingness, panel.width, panel.height, panel.x, panel.y, panel.geometryByDistance(panel.visibilityMode === Panel.Global.DodgeWindows ? dodgeDistance : defloatDistance)
0125         }
0126     }
0127 
0128     Connections {
0129         target: root.containment?.plasmoid ?? null
0130         function onActivated() {
0131             if (root.containment.plasmoid.status === PlasmaCore.Types.AcceptingInputStatus) {
0132                 root.containment.plasmoid.status = PlasmaCore.Types.PassiveStatus;
0133             } else {
0134                 root.containment.plasmoid.status = PlasmaCore.Types.AcceptingInputStatus;
0135             }
0136         }
0137     }
0138 
0139     // 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
0140     property double floatingness
0141     // 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
0142     property double panelOpacity
0143     Behavior on floatingness {
0144         NumberAnimation {
0145             duration: Kirigami.Units.longDuration
0146             easing.type: Easing.OutCubic
0147         }
0148     }
0149     Behavior on panelOpacity {
0150         NumberAnimation {
0151             duration: Kirigami.Units.longDuration
0152             easing.type: Easing.OutCubic
0153         }
0154     }
0155 
0156     // This value is read from panelview.cpp and disables shadow for floating panels, as they'd be detached from the panel
0157     property bool hasShadows: floatingness < 0.5
0158     property var panelMask: floatingness === 0 ? (panelOpacity === 1 ? opaqueItem.mask : translucentItem.mask) : (panelOpacity === 1 ? floatingOpaqueItem.mask : floatingTranslucentItem.mask)
0159 
0160     // These two values are read from panelview.cpp and are used as an offset for the mask
0161     property int maskOffsetX: floatingTranslucentItem.x
0162     property int maskOffsetY: floatingTranslucentItem.y
0163 
0164     KSvg.FrameSvgItem {
0165         id: translucentItem
0166         visible: floatingness === 0 && panelOpacity !== 1
0167         enabledBorders: panel.enabledBorders
0168         anchors.fill: floatingTranslucentItem
0169         imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "widgets/panel-background"
0170     }
0171     KSvg.FrameSvgItem {
0172         id: floatingTranslucentItem
0173         visible: floatingness !== 0 && panelOpacity !== 1
0174         x: root.leftEdge ? fixedLeftFloatingPadding + fixedRightFloatingPadding * (1 - floatingness) : leftFloatingPadding
0175         y: root.topEdge ? fixedTopFloatingPadding + fixedBottomFloatingPadding * (1 - floatingness) : topFloatingPadding
0176         width: verticalPanel ? panel.thickness : parent.width - leftFloatingPadding - rightFloatingPadding
0177         height: verticalPanel ? parent.height - topFloatingPadding - bottomFloatingPadding : panel.thickness
0178 
0179         imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "widgets/panel-background"
0180     }
0181     KSvg.FrameSvgItem {
0182         id: floatingOpaqueItem
0183         visible: floatingness !== 0 && panelOpacity !== 0
0184         opacity: panelOpacity
0185         anchors.fill: floatingTranslucentItem
0186         imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "solid/widgets/panel-background"
0187     }
0188     KSvg.FrameSvgItem {
0189         id: opaqueItem
0190         visible: panelOpacity !== 0 && floatingness === 0
0191         opacity: panelOpacity
0192         enabledBorders: panel.enabledBorders
0193         anchors.fill: floatingTranslucentItem
0194         imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "solid/widgets/panel-background"
0195     }
0196     KSvg.FrameSvgItem {
0197         id: floatingShadow
0198         visible: !hasShadows
0199         z: -100
0200         imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "solid/widgets/panel-background"
0201         prefix: "shadow"
0202         anchors {
0203             fill: floatingTranslucentItem
0204             topMargin: -floatingShadow.margins.top
0205             leftMargin: -floatingShadow.margins.left
0206             rightMargin: -floatingShadow.margins.right
0207             bottomMargin: -floatingShadow.margins.bottom
0208         }
0209     }
0210 
0211     Keys.onEscapePressed: {
0212         root.parent.focus = false
0213     }
0214 
0215     property bool isOpaque: panel.opacityMode === Panel.Global.Opaque
0216     property bool isTransparent: panel.opacityMode === Panel.Global.Translucent
0217     property bool isAdaptive: panel.opacityMode === Panel.Global.Adaptive
0218     property bool floating: panel.floating
0219     property bool hasCompositing: KWindowSystem.isPlatformX11 ? KX11Extras.compositingActive : true
0220     readonly property bool screenCovered: touchingWindow && panel.visibilityMode == Panel.Global.NormalPanel
0221     property var stateTriggers: [floating, screenCovered, isOpaque, isAdaptive, isTransparent, hasCompositing, containment]
0222     onStateTriggersChanged: {
0223         let opaqueApplets = false
0224         let floatingApplets = false
0225         if ((!floating || screenCovered) && (isOpaque || (screenCovered && isAdaptive))) {
0226             panelOpacity = 1
0227             opaqueApplets = true
0228             floatingness = 0
0229         } else if ((!floating || screenCovered) && (isTransparent || (!screenCovered && isAdaptive))) {
0230             panelOpacity = 0
0231             floatingness = 0
0232         } else if ((floating && !screenCovered) && (isTransparent || isAdaptive)) {
0233             panelOpacity = 0
0234             floatingness = 1
0235             floatingApplets = true
0236         } else if (floating && !screenCovered && isOpaque) {
0237             panelOpacity = 1
0238             opaqueApplets = true
0239             floatingness = 1
0240             floatingApplets = true
0241         }
0242         if (!KWindowSystem.isPlatformWayland && !KX11Extras.compositingActive) {
0243             opaqueApplets = false
0244             panelOpacity = 0
0245         }
0246         // Not using panelOpacity to check as it has a NumberAnimation, and it will thus
0247         // be still read as the initial value here, before the animation starts.
0248         if (containment) {
0249             if (opaqueApplets) {
0250                 containment.plasmoid.containmentDisplayHints |= PlasmaCore.Types.ContainmentPrefersOpaqueBackground
0251             } else {
0252                 containment.plasmoid.containmentDisplayHints &= ~PlasmaCore.Types.ContainmentPrefersOpaqueBackground
0253             }
0254             if (floatingApplets) {
0255                 containment.plasmoid.containmentDisplayHints |= PlasmaCore.Types.ContainmentPrefersFloatingApplets
0256             } else {
0257                 containment.plasmoid.containmentDisplayHints &= ~PlasmaCore.Types.ContainmentPrefersFloatingApplets
0258             }
0259         }
0260     }
0261 
0262     function adjustPrefix() {
0263         if (!containment) {
0264             return "";
0265         }
0266         var pre;
0267         switch (containment.plasmoid.location) {
0268         case PlasmaCore.Types.LeftEdge:
0269             pre = "west";
0270             break;
0271         case PlasmaCore.Types.TopEdge:
0272             pre = "north";
0273             break;
0274         case PlasmaCore.Types.RightEdge:
0275             pre = "east";
0276             break;
0277         case PlasmaCore.Types.BottomEdge:
0278             pre = "south";
0279             break;
0280         default:
0281             pre = "";
0282             break;
0283         }
0284         translucentItem.prefix = opaqueItem.prefix = floatingTranslucentItem.prefix = floatingOpaqueItem.prefix = [pre, ""];
0285     }
0286 
0287     onContainmentChanged: {
0288         if (!containment) {
0289             return;
0290         }
0291         containment.parent = containmentParent;
0292         containment.visible = true;
0293         containment.anchors.fill = containmentParent;
0294         containment.plasmoid.locationChanged.connect(adjustPrefix);
0295         adjustPrefix();
0296     }
0297 
0298     Binding {
0299         target: panel
0300         property: "length"
0301         when: containment
0302         value: {
0303             if (!containment) {
0304                 return;
0305             }
0306             if (verticalPanel) {
0307                 return containment.Layout.preferredHeight
0308             } else {
0309                 return containment.Layout.preferredWidth
0310             }
0311         }
0312         restoreMode: Binding.RestoreBinding
0313     }
0314 
0315     Binding {
0316         target: panel
0317         property: "backgroundHints"
0318         when: containment
0319         value: {
0320             if (!containment) {
0321                 return;
0322             }
0323 
0324             return containment.plasmoid.backgroundHints;
0325         }
0326         restoreMode: Binding.RestoreBinding
0327     }
0328 
0329     KSvg.FrameSvgItem {
0330         x: root.verticalPanel || !panel.activeFocusItem
0331             ? 0
0332             : Math.max(panel.activeFocusItem.Kirigami.ScenePosition.x, panel.activeFocusItem.Kirigami.ScenePosition.x)
0333         y: root.verticalPanel && panel.activeFocusItem
0334             ? Math.max(panel.activeFocusItem.Kirigami.ScenePosition.y, panel.activeFocusItem.Kirigami.ScenePosition.y)
0335             : 0
0336 
0337         width: panel.activeFocusItem
0338             ? (root.verticalPanel ? root.width : Math.min(panel.activeFocusItem.width, panel.activeFocusItem.width))
0339             : 0
0340         height: panel.activeFocusItem
0341             ? (root.verticalPanel ?  Math.min(panel.activeFocusItem.height, panel.activeFocusItem.height) : root.height)
0342             : 0
0343 
0344         visible: panel.active && panel.activeFocusItem
0345 
0346         imagePath: "widgets/tabbar"
0347         prefix: {
0348             if (!root.containment) {
0349                 return "";
0350             }
0351             var prefix = ""
0352             switch (root.containment.plasmoid.location) {
0353                 case PlasmaCore.Types.LeftEdge:
0354                     prefix = "west-active-tab";
0355                     break;
0356                 case PlasmaCore.Types.TopEdge:
0357                     prefix = "north-active-tab";
0358                     break;
0359                 case PlasmaCore.Types.RightEdge:
0360                     prefix = "east-active-tab";
0361                     break;
0362                 default:
0363                     prefix = "south-active-tab";
0364             }
0365             if (!hasElementPrefix(prefix)) {
0366                 prefix = "active-tab";
0367             }
0368             return prefix;
0369         }
0370     }
0371     Item {
0372         id: containmentParent
0373         anchors.centerIn: isOpaque ? floatingOpaqueItem : floatingTranslucentItem
0374         width: root.verticalPanel ? panel.thickness : root.width - fixedLeftFloatingPadding - fixedRightFloatingPadding
0375         height: root.verticalPanel ? root.height - fixedBottomFloatingPadding - fixedTopFloatingPadding : panel.thickness
0376     }
0377 }