mirror of
https://gitgud.io/wackyideas/aerothemeplasma.git
synced 2024-08-15 00:43:43 +00:00
362 lines
16 KiB
QML
362 lines
16 KiB
QML
/*
|
|
SPDX-FileCopyrightText: 2012 Marco Martin <mart@kde.org>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
import QtQuick 2.15
|
|
import QtQuick.Window 2.15
|
|
import QtQuick.Layouts 1.1
|
|
import QtQml 2.15
|
|
|
|
import org.kde.plasma.core as PlasmaCore
|
|
import org.kde.ksvg 1.0 as KSvg
|
|
import org.kde.taskmanager 0.1 as TaskManager
|
|
import org.kde.kwindowsystem 1.0
|
|
import org.kde.kirigami 2.20 as Kirigami
|
|
import org.kde.plasma.shell.panel 0.1 as Panel
|
|
|
|
import org.kde.plasma.plasmoid 2.0
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property Item containment
|
|
property bool floatingPrefix: floatingPanelSvg.usedPrefix === "floating"
|
|
readonly property bool verticalPanel: containment?.plasmoid?.formFactor === PlasmaCore.Types.Vertical
|
|
|
|
readonly property real spacingAtMinSize: Math.round(Math.max(1, (verticalPanel ? root.width : root.height) - Kirigami.Units.iconSizes.smallMedium)/2)
|
|
KSvg.FrameSvgItem {
|
|
id: thickPanelSvg
|
|
visible: false
|
|
prefix: 'thick'
|
|
imagePath: "widgets/panel-background"
|
|
}
|
|
KSvg.FrameSvgItem {
|
|
id: floatingPanelSvg
|
|
prefix: ['floating', '']
|
|
imagePath: "widgets/panel-background"
|
|
}
|
|
|
|
// NOTE: Many of the properties in this file are accessed directly in C++ PanelView!
|
|
// If you change these, make sure to also correct the related code in panelview.cpp.
|
|
|
|
readonly property bool topEdge: containment?.plasmoid?.location === PlasmaCore.Types.TopEdge
|
|
readonly property bool leftEdge: containment?.plasmoid?.location === PlasmaCore.Types.LeftEdge
|
|
readonly property bool rightEdge: containment?.plasmoid?.location === PlasmaCore.Types.RightEdge
|
|
readonly property bool bottomEdge: containment?.plasmoid?.location === PlasmaCore.Types.BottomEdge
|
|
|
|
readonly property int topPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.top + Kirigami.Units.smallSpacing, spacingAtMinSize));
|
|
readonly property int bottomPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.bottom + Kirigami.Units.smallSpacing, spacingAtMinSize));
|
|
readonly property int leftPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.left + Kirigami.Units.smallSpacing, spacingAtMinSize));
|
|
readonly property int rightPadding: Math.round(Math.min(thickPanelSvg.fixedMargins.right + Kirigami.Units.smallSpacing, spacingAtMinSize));
|
|
|
|
readonly property int fixedBottomFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.bottom : 8)
|
|
readonly property int fixedLeftFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.left : 8)
|
|
readonly property int fixedRightFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.right : 8)
|
|
readonly property int fixedTopFloatingPadding: floating && (floatingPrefix ? floatingPanelSvg.fixedMargins.top : 8)
|
|
|
|
readonly property int bottomFloatingPadding: Math.round(fixedBottomFloatingPadding * floatingness)
|
|
readonly property int leftFloatingPadding: Math.round(fixedLeftFloatingPadding * floatingness)
|
|
readonly property int rightFloatingPadding: Math.round(fixedRightFloatingPadding * floatingness)
|
|
readonly property int topFloatingPadding: Math.round(fixedTopFloatingPadding * floatingness)
|
|
|
|
readonly property int minPanelHeight: translucentItem.minimumDrawingHeight
|
|
readonly property int minPanelWidth: translucentItem.minimumDrawingWidth
|
|
|
|
TaskManager.VirtualDesktopInfo {
|
|
id: virtualDesktopInfo
|
|
}
|
|
|
|
TaskManager.ActivityInfo {
|
|
id: activityInfo
|
|
}
|
|
|
|
// We need to have a little gap between the raw visibleWindowsModel count
|
|
// and actually determining if a window is touching.
|
|
// This is because certain dialog windows start off with a position of (screenwidth/2, screenheight/2)
|
|
// and they register as "touching" in the split-second before KWin can place them correctly.
|
|
// This avoids the panel flashing if it is auto-hide etc and such a window is shown.
|
|
// Examples of such windows: properties of a file on desktop, or portal "open with" dialog
|
|
property bool touchingWindow: false
|
|
property bool touchingWindowDirect: visibleWindowsModel.count > 0
|
|
property bool showingDesktop: KWindowSystem.showingDesktop
|
|
Timer {
|
|
id: touchingWindowDebounceTimer
|
|
interval: 10 // ms, I find that this value is enough while not causing unresponsiveness while dragging windows close
|
|
onTriggered: root.touchingWindow = !KWindowSystem.showingDesktop && root.touchingWindowDirect
|
|
}
|
|
onTouchingWindowDirectChanged: touchingWindowDebounceTimer.start()
|
|
onShowingDesktopChanged: touchingWindowDebounceTimer.start()
|
|
|
|
TaskManager.TasksModel {
|
|
id: visibleWindowsModel
|
|
filterByVirtualDesktop: true
|
|
filterByActivity: true
|
|
filterByScreen: false
|
|
filterByRegion: TaskManager.RegionFilterMode.Intersect
|
|
filterHidden: true
|
|
filterMinimized: true
|
|
|
|
screenGeometry: panel.screenGeometry
|
|
virtualDesktop: virtualDesktopInfo.currentDesktop
|
|
activity: activityInfo.currentActivity
|
|
|
|
groupMode: TaskManager.TasksModel.GroupDisabled
|
|
|
|
Binding on regionGeometry {
|
|
delayed: true
|
|
value: panel.width, panel.height, panel.x, panel.y, panel.dogdeGeometryByDistance(panel.visibilityMode === Panel.Global.DodgeWindows ? -1 : 1) // +1 is for overlap detection, -1 is for snapping to panel
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: root.containment?.plasmoid ?? null
|
|
function onActivated() {
|
|
if (root.containment.plasmoid.status === PlasmaCore.Types.AcceptingInputStatus) {
|
|
root.containment.plasmoid.status = PlasmaCore.Types.PassiveStatus;
|
|
} else {
|
|
root.containment.plasmoid.status = PlasmaCore.Types.AcceptingInputStatus;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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
|
|
readonly property int floatingnessAnimationDuration: Kirigami.Units.longDuration
|
|
property double floatingnessTarget: 0.0 // The animation is handled in panelview.cpp for efficiency
|
|
property double floatingness: 0.0
|
|
|
|
// 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
|
|
property double panelOpacity
|
|
Behavior on panelOpacity {
|
|
NumberAnimation {
|
|
duration: Kirigami.Units.longDuration
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
// This value is read from panelview.cpp and disables shadow for floating panels, as they'd be detached from the panel
|
|
property bool hasShadows: floatingness < 0.5
|
|
property var panelMask: floatingness === 0 ? (panelOpacity === 1 ? opaqueItem.mask : translucentItem.mask) : (panelOpacity === 1 ? floatingOpaqueItem.mask : floatingTranslucentItem.mask)
|
|
|
|
// The point is read from panelview.cpp and is used as an offset for the mask
|
|
readonly property point floatingTranslucentItemOffset: Qt.point(floatingTranslucentItem.x, floatingTranslucentItem.y)
|
|
|
|
KSvg.FrameSvgItem {
|
|
id: translucentItem
|
|
visible: floatingness === 0 && panelOpacity !== 1
|
|
enabledBorders: panel.enabledBorders
|
|
anchors.fill: floatingTranslucentItem
|
|
imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "widgets/panel-background"
|
|
}
|
|
KSvg.FrameSvgItem {
|
|
id: floatingTranslucentItem
|
|
visible: floatingness !== 0 && panelOpacity !== 1
|
|
x: root.leftEdge ? fixedLeftFloatingPadding + fixedRightFloatingPadding * (1 - floatingness) : leftFloatingPadding
|
|
y: root.topEdge ? fixedTopFloatingPadding + fixedBottomFloatingPadding * (1 - floatingness) : topFloatingPadding
|
|
width: verticalPanel ? panel.thickness : parent.width - leftFloatingPadding - rightFloatingPadding
|
|
height: verticalPanel ? parent.height - topFloatingPadding - bottomFloatingPadding : panel.thickness
|
|
|
|
imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "widgets/panel-background"
|
|
}
|
|
KSvg.FrameSvgItem {
|
|
id: floatingOpaqueItem
|
|
visible: floatingness !== 0 && panelOpacity !== 0
|
|
opacity: panelOpacity
|
|
anchors.fill: floatingTranslucentItem
|
|
imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "solid/widgets/panel-background"
|
|
}
|
|
KSvg.FrameSvgItem {
|
|
id: opaqueItem
|
|
visible: panelOpacity !== 0 && floatingness === 0
|
|
opacity: panelOpacity
|
|
enabledBorders: panel.enabledBorders
|
|
anchors.fill: floatingTranslucentItem
|
|
imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "solid/widgets/panel-background"
|
|
}
|
|
KSvg.FrameSvgItem {
|
|
id: floatingShadow
|
|
visible: !hasShadows
|
|
z: -100
|
|
imagePath: containment?.plasmoid?.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "solid/widgets/panel-background"
|
|
prefix: "shadow"
|
|
anchors {
|
|
fill: floatingTranslucentItem
|
|
topMargin: -floatingShadow.margins.top
|
|
leftMargin: -floatingShadow.margins.left
|
|
rightMargin: -floatingShadow.margins.right
|
|
bottomMargin: -floatingShadow.margins.bottom
|
|
}
|
|
}
|
|
|
|
Keys.onEscapePressed: {
|
|
root.parent.focus = false
|
|
}
|
|
|
|
property bool isOpaque: panel.opacityMode === Panel.Global.Opaque
|
|
property bool isTransparent: panel.opacityMode === Panel.Global.Translucent
|
|
property bool isAdaptive: panel.opacityMode === Panel.Global.Adaptive
|
|
property bool floating: panel.floating
|
|
property bool hasCompositing: KWindowSystem.isPlatformX11 ? KX11Extras.compositingActive : true
|
|
readonly property bool screenCovered: touchingWindow && panel.visibilityMode == Panel.Global.NormalPanel
|
|
property var stateTriggers: [floating, screenCovered, isOpaque, isAdaptive, isTransparent, hasCompositing, containment]
|
|
onStateTriggersChanged: {
|
|
let opaqueApplets = false
|
|
let floatingApplets = false
|
|
if ((!floating || screenCovered) && (isOpaque || (screenCovered && isAdaptive))) {
|
|
panelOpacity = 1
|
|
opaqueApplets = true
|
|
floatingnessTarget = 0
|
|
} else if ((!floating || screenCovered) && (isTransparent || (!screenCovered && isAdaptive))) {
|
|
panelOpacity = 0
|
|
floatingnessTarget = 0
|
|
} else if ((floating && !screenCovered) && (isTransparent || isAdaptive)) {
|
|
panelOpacity = 0
|
|
floatingnessTarget = 1
|
|
floatingApplets = true
|
|
} else if (floating && !screenCovered && isOpaque) {
|
|
panelOpacity = 1
|
|
opaqueApplets = true
|
|
floatingnessTarget = 1
|
|
floatingApplets = true
|
|
}
|
|
if (!KWindowSystem.isPlatformWayland && !KX11Extras.compositingActive) {
|
|
opaqueApplets = false
|
|
panelOpacity = 0
|
|
}
|
|
// Not using panelOpacity to check as it has a NumberAnimation, and it will thus
|
|
// be still read as the initial value here, before the animation starts.
|
|
if (containment) {
|
|
if (opaqueApplets) {
|
|
containment.plasmoid.containmentDisplayHints |= PlasmaCore.Types.ContainmentPrefersOpaqueBackground
|
|
} else {
|
|
containment.plasmoid.containmentDisplayHints &= ~PlasmaCore.Types.ContainmentPrefersOpaqueBackground
|
|
}
|
|
if (floatingApplets) {
|
|
containment.plasmoid.containmentDisplayHints |= PlasmaCore.Types.ContainmentPrefersFloatingApplets
|
|
} else {
|
|
containment.plasmoid.containmentDisplayHints &= ~PlasmaCore.Types.ContainmentPrefersFloatingApplets
|
|
}
|
|
}
|
|
}
|
|
|
|
function adjustPrefix() {
|
|
if (!containment) {
|
|
return "";
|
|
}
|
|
var pre;
|
|
switch (containment.plasmoid.location) {
|
|
case PlasmaCore.Types.LeftEdge:
|
|
pre = "west";
|
|
break;
|
|
case PlasmaCore.Types.TopEdge:
|
|
pre = "north";
|
|
break;
|
|
case PlasmaCore.Types.RightEdge:
|
|
pre = "east";
|
|
break;
|
|
case PlasmaCore.Types.BottomEdge:
|
|
pre = "south";
|
|
break;
|
|
default:
|
|
pre = "";
|
|
break;
|
|
}
|
|
translucentItem.prefix = opaqueItem.prefix = floatingTranslucentItem.prefix = floatingOpaqueItem.prefix = [pre, ""];
|
|
}
|
|
|
|
onContainmentChanged: {
|
|
if (!containment) {
|
|
return;
|
|
}
|
|
containment.parent = containmentParent;
|
|
containment.visible = true;
|
|
containment.anchors.fill = containmentParent;
|
|
containment.plasmoid.locationChanged.connect(adjustPrefix);
|
|
adjustPrefix();
|
|
}
|
|
|
|
Binding {
|
|
target: panel
|
|
property: "length"
|
|
when: containment
|
|
value: {
|
|
if (!containment) {
|
|
return;
|
|
}
|
|
if (verticalPanel) {
|
|
return containment.Layout.preferredHeight
|
|
} else {
|
|
return containment.Layout.preferredWidth
|
|
}
|
|
}
|
|
restoreMode: Binding.RestoreBinding
|
|
}
|
|
|
|
Binding {
|
|
target: panel
|
|
property: "backgroundHints"
|
|
when: containment
|
|
value: {
|
|
if (!containment) {
|
|
return;
|
|
}
|
|
|
|
return containment.plasmoid.backgroundHints;
|
|
}
|
|
restoreMode: Binding.RestoreBinding
|
|
}
|
|
|
|
KSvg.FrameSvgItem {
|
|
|
|
Accessible.name: i18n("Panel Focus Indicator")
|
|
|
|
x: root.verticalPanel || !panel.activeFocusItem
|
|
? translucentItem.x
|
|
: Math.max(panel.activeFocusItem.Kirigami.ScenePosition.x, panel.activeFocusItem.Kirigami.ScenePosition.x)
|
|
y: root.verticalPanel && panel.activeFocusItem
|
|
? Math.max(panel.activeFocusItem.Kirigami.ScenePosition.y, panel.activeFocusItem.Kirigami.ScenePosition.y)
|
|
: translucentItem.y
|
|
|
|
width: panel.activeFocusItem
|
|
? (root.verticalPanel ? translucentItem.width : Math.min(panel.activeFocusItem.width, panel.activeFocusItem.width))
|
|
: 0
|
|
height: panel.activeFocusItem
|
|
? (root.verticalPanel ? Math.min(panel.activeFocusItem.height, panel.activeFocusItem.height) : translucentItem.height)
|
|
: 0
|
|
|
|
visible: panel.active && panel.activeFocusItem
|
|
|
|
imagePath: "widgets/tabbar"
|
|
prefix: {
|
|
if (!root.containment) {
|
|
return "";
|
|
}
|
|
var prefix = ""
|
|
switch (root.containment.plasmoid.location) {
|
|
case PlasmaCore.Types.LeftEdge:
|
|
prefix = "west-active-tab";
|
|
break;
|
|
case PlasmaCore.Types.TopEdge:
|
|
prefix = "north-active-tab";
|
|
break;
|
|
case PlasmaCore.Types.RightEdge:
|
|
prefix = "east-active-tab";
|
|
break;
|
|
default:
|
|
prefix = "south-active-tab";
|
|
}
|
|
if (!hasElementPrefix(prefix)) {
|
|
prefix = "active-tab";
|
|
}
|
|
return prefix;
|
|
}
|
|
}
|
|
Item {
|
|
id: containmentParent
|
|
anchors.fill: isOpaque ? floatingOpaqueItem : floatingTranslucentItem
|
|
anchors.leftMargin: root.verticalPanel ? 0 : -Kirigami.Units.smallSpacing
|
|
width: root.verticalPanel ? panel.thickness : root.width - fixedLeftFloatingPadding - fixedRightFloatingPadding
|
|
height: root.verticalPanel ? root.height - fixedBottomFloatingPadding - fixedTopFloatingPadding : panel.thickness
|
|
}
|
|
}
|