mirror of
https://gitgud.io/wackyideas/aerothemeplasma.git
synced 2024-08-15 00:43:43 +00:00
Very early KDE 6 release.
This commit is contained in:
parent
7cc4ccabbc
commit
686046d4f7
6272 changed files with 140920 additions and 529657 deletions
381
plasma/shells/org.kde.plasma.desktop/contents/views/Desktop.qml
Normal file
381
plasma/shells/org.kde.plasma.desktop/contents/views/Desktop.qml
Normal file
|
@ -0,0 +1,381 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2012 Marco Martin <mart@kde.org>
|
||||
SPDX-FileCopyrightText: 2014 David Edmundson <davidedmundson@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.components as PC
|
||||
import org.kde.kwindowsystem 1.0
|
||||
import org.kde.plasma.activityswitcher as ActivitySwitcher
|
||||
import "../activitymanager"
|
||||
import "../explorer"
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property Item containment
|
||||
|
||||
property QtObject widgetExplorer
|
||||
|
||||
Connections {
|
||||
target: ActivitySwitcher.Backend
|
||||
function onShouldShowSwitcherChanged() {
|
||||
if (ActivitySwitcher.Backend.shouldShowSwitcher) {
|
||||
if (sidePanelStack.state != "activityManager") {
|
||||
root.toggleActivityManager();
|
||||
}
|
||||
|
||||
} else {
|
||||
if (sidePanelStack.state == "activityManager") {
|
||||
root.toggleActivityManager();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleWidgetExplorer(containment) {
|
||||
|
||||
if (sidePanelStack.state == "widgetExplorer") {
|
||||
sidePanelStack.state = "closed";
|
||||
} else {
|
||||
sidePanelStack.state = "widgetExplorer";
|
||||
sidePanelStack.setSource(Qt.resolvedUrl("../explorer/WidgetExplorer.qml"), {"containment": containment, "sidePanel": sidePanel});
|
||||
}
|
||||
}
|
||||
|
||||
function toggleActivityManager() {
|
||||
if (sidePanelStack.state == "activityManager") {
|
||||
sidePanelStack.state = "closed";
|
||||
} else {
|
||||
sidePanelStack.state = "activityManager";
|
||||
sidePanelStack.setSource(Qt.resolvedUrl("../activitymanager/ActivityManager.qml"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
readonly property rect editModeRect: {
|
||||
if (!containment) {
|
||||
return Qt.rect(0,0,0,0);
|
||||
}
|
||||
let screenRect = containment.plasmoid.availableScreenRect;
|
||||
let panelConfigRect = Qt.rect(0,0,0,0);
|
||||
|
||||
if (containment.plasmoid.corona.panelBeingConfigured
|
||||
&& containment.plasmoid.corona.panelBeingConfigured.screenToFollow === desktop.screenToFollow) {
|
||||
panelConfigRect = containment.plasmoid.corona.panelBeingConfigured.relativeConfigRect;
|
||||
}
|
||||
|
||||
if (panelConfigRect.width <= 0) {
|
||||
; // Do nothing
|
||||
} else if (panelConfigRect.x > width - (panelConfigRect.x + panelConfigRect.width)) {
|
||||
screenRect = Qt.rect(screenRect.x, screenRect.y, panelConfigRect.x - screenRect.x, screenRect.height);
|
||||
} else {
|
||||
const diff = Math.max(0, panelConfigRect.x + panelConfigRect.width - screenRect.x);
|
||||
screenRect = Qt.rect(Math.max(screenRect.x, panelConfigRect.x + panelConfigRect.width), screenRect.y, screenRect.width - diff, screenRect.height);
|
||||
}
|
||||
|
||||
if (sidePanel.visible) {
|
||||
if (Qt.application.layoutDirection === Qt.RightToLeft) {
|
||||
screenRect = Qt.rect(screenRect.x, screenRect.y, screenRect.width - sidePanel.width, screenRect.height);
|
||||
} else {
|
||||
screenRect = Qt.rect(screenRect.x + sidePanel.width, screenRect.y, screenRect.width - sidePanel.width, screenRect.height);
|
||||
}
|
||||
}
|
||||
return screenRect;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: containment.plasmoid.corona.editMode = false
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: containmentParent
|
||||
x: editModeLoader.active ? editModeLoader.item.centerX - width / 2 : 0
|
||||
y: editModeLoader.active ? editModeLoader.item.centerY - height / 2 : 0
|
||||
width: root.width
|
||||
height: root.height
|
||||
readonly property real extraScale: desktop.configuredPanel || sidePanel.visible ? 0.95 : 0.9
|
||||
property real scaleFactor: Math.min(editModeRect.width/root.width, editModeRect.height/root.height) * extraScale
|
||||
scale: containment?.plasmoid.corona.editMode ? scaleFactor : 1
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: editModeLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: DesktopEditMode {}
|
||||
active: containment?.plasmoid.corona.editMode || editModeUiTimer.running
|
||||
Timer {
|
||||
id: editModeUiTimer
|
||||
property bool editMode: containment?.plasmoid.corona.editMode || false
|
||||
onEditModeChanged: restart()
|
||||
interval: Kirigami.Units.longDuration
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: wallpaperColors
|
||||
|
||||
active: root.containment && root.containment.wallpaper && desktop.usedInAccentColor
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: Kirigami.ImageColors {
|
||||
id: imageColors
|
||||
source: root.containment.wallpaper
|
||||
|
||||
readonly property color backgroundColor: Kirigami.Theme.backgroundColor
|
||||
readonly property color textColor: Kirigami.Theme.textColor
|
||||
|
||||
// Ignore the initial dominant color
|
||||
onPaletteChanged: {
|
||||
if (!Qt.colorEqual(root.containment.wallpaper.accentColor, "transparent")) {
|
||||
desktop.accentColor = root.containment.wallpaper.accentColor;
|
||||
}
|
||||
if (this.palette.length === 0) {
|
||||
desktop.accentColor = "transparent";
|
||||
} else {
|
||||
desktop.accentColor = this.dominant;
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.backgroundColor: backgroundColor
|
||||
Kirigami.Theme.textColor: textColor
|
||||
|
||||
onBackgroundColorChanged: Qt.callLater(update)
|
||||
onTextColorChanged: Qt.callLater(update)
|
||||
|
||||
property Connections repaintConnection: Connections {
|
||||
target: root.containment.wallpaper
|
||||
function onAccentColorChanged() {
|
||||
if (Qt.colorEqual(root.containment.wallpaper.accentColor, "transparent")) {
|
||||
imageColors.update();
|
||||
} else {
|
||||
imageColors.paletteChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: pendingUninstallTimer
|
||||
// keeps track of the applets the user wants to uninstall
|
||||
property var applets: []
|
||||
function uninstall() {
|
||||
for (var i = 0, length = applets.length; i < length; ++i) {
|
||||
widgetExplorer.uninstall(applets[i])
|
||||
}
|
||||
applets = []
|
||||
|
||||
if (sidePanelStack.state !== "widgetExplorer" && widgetExplorer) {
|
||||
widgetExplorer.destroy()
|
||||
widgetExplorer = null
|
||||
}
|
||||
}
|
||||
|
||||
interval: 60000 // one minute
|
||||
onTriggered: uninstall()
|
||||
}
|
||||
|
||||
PlasmaCore.Dialog {
|
||||
id: sidePanel
|
||||
location: Qt.application.layoutDirection === Qt.RightToLeft ? PlasmaCore.Types.RightEdge : PlasmaCore.Types.LeftEdge
|
||||
type: PlasmaCore.Dialog.Dock
|
||||
flags: Qt.WindowStaysOnTopHint
|
||||
|
||||
hideOnWindowDeactivate: true
|
||||
|
||||
x: {
|
||||
var result = desktop.x;
|
||||
if (!containment) {
|
||||
return result;
|
||||
}
|
||||
|
||||
var rect = containment.plasmoid.availableScreenRect;
|
||||
result += rect.x;
|
||||
|
||||
if (Qt.application.layoutDirection === Qt.RightToLeft) {
|
||||
result += rect.width - sidePanel.width;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
y: desktop.y + (containment ? containment.plasmoid.availableScreenRect.y : 0)
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
// If was called from a panel, open the panel config
|
||||
if (sidePanelStack.item && sidePanelStack.item.containment
|
||||
&& sidePanelStack.item.containment != containment.plasmoid
|
||||
&& !item.containment.userConfiguring
|
||||
) {
|
||||
Qt.callLater(sidePanelStack.item.containment.internalAction("configure").trigger);
|
||||
}
|
||||
sidePanelStack.state = "closed";
|
||||
ActivitySwitcher.Backend.shouldShowSwitcher = false;
|
||||
}
|
||||
}
|
||||
|
||||
mainItem: Loader {
|
||||
id: sidePanelStack
|
||||
asynchronous: true
|
||||
width: item ? item.width: 0
|
||||
height: containment ? containment.plasmoid.availableScreenRect.height - sidePanel.margins.top - sidePanel.margins.bottom : 1000
|
||||
state: "closed"
|
||||
|
||||
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
onLoaded: {
|
||||
if (sidePanelStack.item) {
|
||||
item.closed.connect(function(){sidePanelStack.state = "closed";});
|
||||
|
||||
if (sidePanelStack.state == "activityManager") {
|
||||
sidePanelStack.item.showSwitcherOnly =
|
||||
ActivitySwitcher.Backend.shouldShowSwitcher
|
||||
sidePanel.hideOnWindowDeactivate = Qt.binding(function() {
|
||||
return !ActivitySwitcher.Backend.shouldShowSwitcher
|
||||
&& !sidePanelStack.item.showingDialog;
|
||||
})
|
||||
sidePanelStack.item.forceActiveFocus();
|
||||
} else if (sidePanelStack.state == "widgetExplorer"){
|
||||
sidePanel.hideOnWindowDeactivate = Qt.binding(function() { return sidePanelStack.item && !sidePanelStack.item.preventWindowHide; })
|
||||
sidePanel.opacity = Qt.binding(function() { return sidePanelStack.item ? sidePanelStack.item.opacity : 1 })
|
||||
sidePanel.outputOnly = Qt.binding(function() { return sidePanelStack.item && sidePanelStack.item.outputOnly })
|
||||
} else {
|
||||
sidePanel.hideOnWindowDeactivate = true;
|
||||
}
|
||||
}
|
||||
sidePanel.visible = true;
|
||||
if (KWindowSystem.isPlatformX11) {
|
||||
KX11Extras.forceActiveWindow(sidePanel);
|
||||
}
|
||||
}
|
||||
onStateChanged: {
|
||||
if (sidePanelStack.state == "closed") {
|
||||
sidePanel.visible = false;
|
||||
sidePanelStack.source = ""; //unload all elements
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: containment?.plasmoid ?? null
|
||||
function onAvailableScreenRectChanged() {
|
||||
if (sidePanel.visible) {
|
||||
sidePanel.requestActivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onContainmentChanged: {
|
||||
if (containment == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
containment.parent = containmentParent
|
||||
|
||||
if (switchAnim.running) {
|
||||
//If the animation was still running, stop it and reset
|
||||
//everything so that a consistent state can be kept
|
||||
switchAnim.running = false;
|
||||
internal.newContainment.visible = false;
|
||||
internal.oldContainment.visible = false;
|
||||
internal.oldContainment = null;
|
||||
}
|
||||
|
||||
internal.newContainment = containment;
|
||||
containment.visible = true;
|
||||
|
||||
if (internal.oldContainment != null && internal.oldContainment != containment) {
|
||||
switchAnim.running = true;
|
||||
} else {
|
||||
containment.anchors.left = containmentParent.left;
|
||||
containment.anchors.top = containmentParent.top;
|
||||
containment.anchors.right = containmentParent.right;
|
||||
containment.anchors.bottom = containmentParent.bottom;
|
||||
if (internal.oldContainment) {
|
||||
internal.oldContainment.visible = false;
|
||||
}
|
||||
internal.oldContainment = containment;
|
||||
}
|
||||
}
|
||||
|
||||
//some properties that shouldn't be accessible from elsewhere
|
||||
QtObject {
|
||||
id: internal;
|
||||
|
||||
property Item oldContainment: null;
|
||||
property Item newContainment: null;
|
||||
}
|
||||
|
||||
SequentialAnimation {
|
||||
id: switchAnim
|
||||
ScriptAction {
|
||||
script: {
|
||||
if (containment) {
|
||||
containment.z = 1;
|
||||
containment.x = root.width;
|
||||
}
|
||||
if (internal.oldContainment) {
|
||||
internal.oldContainment.z = 0;
|
||||
internal.oldContainment.x = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
ParallelAnimation {
|
||||
NumberAnimation {
|
||||
target: internal.oldContainment
|
||||
properties: "x"
|
||||
to: internal.newContainment != null ? -root.width : 0
|
||||
duration: Kirigami.Units.veryLongDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
NumberAnimation {
|
||||
target: internal.newContainment
|
||||
properties: "x"
|
||||
to: 0
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
ScriptAction {
|
||||
script: {
|
||||
if (internal.oldContainment) {
|
||||
internal.oldContainment.visible = false;
|
||||
}
|
||||
if (containment) {
|
||||
internal.oldContainment = containment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: previewBannerLoader
|
||||
readonly property point pos: root.containment?.plasmoid.availableScreenRegion,
|
||||
active ? root.containment.adjustToAvailableScreenRegion(
|
||||
root.containment.width + root.containment.x - item.width - Kirigami.Units.largeSpacing,
|
||||
root.containment.height + root.containment.y - item.height - Kirigami.Units.largeSpacing,
|
||||
item.width + Kirigami.Units.largeSpacing,
|
||||
item.height + Kirigami.Units.largeSpacing)
|
||||
: Qt.point(0, 0)
|
||||
x: pos.x
|
||||
y: pos.y
|
||||
z: Number(root.containment?.z) + 1
|
||||
active: root.containment && Boolean(desktop.showPreviewBanner)
|
||||
visible: active
|
||||
source: "PreviewBanner.qml"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 Marco Martin <mart@kde.org>
|
||||
SPDX-FileCopyrightText: 2014 David Edmundson <davidedmundson@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.components as PC
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
import org.kde.kcmutils as KCM
|
||||
|
||||
Item {
|
||||
property real centerX: Math.round(editModeUi.x + editModeUi.width/2)
|
||||
property real centerY: Math.round(editModeUi.y + editModeUi.height/2)
|
||||
property real roundedRootWidth: Math.round(root.width)
|
||||
property real roundedRootHeight: Math.round(root.height)
|
||||
|
||||
property bool open: false
|
||||
Component.onCompleted: {
|
||||
open = Qt.binding(() => {return containment.plasmoid.corona.editMode})
|
||||
}
|
||||
|
||||
// Those 2 elements have the same parameters as the overview effect
|
||||
MultiEffect {
|
||||
source: containment
|
||||
anchors.fill: parent
|
||||
blurEnabled: true
|
||||
blurMax: 64
|
||||
blur: 1.0
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
opacity: 0.7
|
||||
}
|
||||
|
||||
Item {
|
||||
id: editModeUi
|
||||
visible: open || xAnim.running
|
||||
x: Math.round(open ? editModeRect.x + editModeRect.width/2 - zoomedWidth/2 : 0)
|
||||
y: Math.round(open ? editModeRect.y + editModeRect.height/2 - zoomedHeight/2 + toolBar.height/2 : 0)
|
||||
width: open ? zoomedWidth : roundedRootWidth
|
||||
height: open ? zoomedHeight : roundedRootHeight
|
||||
property real zoomedWidth: Math.round(root.width * containmentParent.scaleFactor)
|
||||
property real zoomedHeight: Math.round(root.height * containmentParent.scaleFactor)
|
||||
|
||||
Kirigami.ShadowedRectangle {
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
width: Math.round(parent.width)
|
||||
height: Math.round(parent.height + toolBar.height + Kirigami.Units.largeSpacing)
|
||||
y: - toolBar.height - Kirigami.Units.largeSpacing
|
||||
|
||||
radius: open ? Kirigami.Units.cornerRadius : 0
|
||||
Behavior on radius {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
shadow {
|
||||
size: Kirigami.Units.gridUnit * 2
|
||||
color: Qt.rgba(0, 0, 0, 0.3)
|
||||
yOffset: 3
|
||||
}
|
||||
RowLayout {
|
||||
id: toolBar
|
||||
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||
LayoutMirroring.childrenInherit: true
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
margins: Kirigami.Units.smallSpacing
|
||||
}
|
||||
Flow {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: implicitHeight
|
||||
PC.ToolButton {
|
||||
id: addWidgetButton
|
||||
property QtObject qAction: containment?.plasmoid.internalAction("add widgets") || null
|
||||
text: qAction?.text
|
||||
icon.name: "list-add"
|
||||
onClicked: qAction.trigger()
|
||||
}
|
||||
|
||||
PC.ToolButton {
|
||||
id: addPanelButton
|
||||
height: addWidgetButton.height
|
||||
property QtObject qAction: containment?.plasmoid.corona.action("add panel") || null
|
||||
text: qAction?.text
|
||||
icon.name: "list-add"
|
||||
Accessible.role: Accessible.ButtonMenu
|
||||
onClicked: containment.plasmoid.corona.showAddPanelContextMenu(mapToGlobal(0, height))
|
||||
}
|
||||
|
||||
PC.ToolButton {
|
||||
id: configureButton
|
||||
property QtObject qAction: containment?.plasmoid.internalAction("configure") || null
|
||||
text: qAction?.text
|
||||
icon.name: "preferences-desktop-wallpaper"
|
||||
onClicked: qAction.trigger()
|
||||
}
|
||||
|
||||
PC.ToolButton {
|
||||
id: themeButton
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Global Themes")
|
||||
icon.name: "preferences-desktop-theme-global"
|
||||
onClicked: KCM.KCMLauncher.openSystemSettings("kcm_lookandfeel")
|
||||
}
|
||||
|
||||
PC.ToolButton {
|
||||
id: displaySettingsButton
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Display Configuration")
|
||||
icon.name: "preferences-desktop-display"
|
||||
onClicked: KCM.KCMLauncher.openSystemSettings("kcm_kscreen")
|
||||
}
|
||||
|
||||
PC.ToolButton {
|
||||
id: manageContainmentsButton
|
||||
property QtObject qAction: containment?.plasmoid.corona.action("manage-containments") || null
|
||||
text: qAction?.text
|
||||
visible: qAction?.visible || false
|
||||
icon.name: "preferences-system-windows-effect-fadedesktop"
|
||||
onClicked: qAction.trigger()
|
||||
}
|
||||
}
|
||||
|
||||
PC.ToolButton {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
visible: Kirigami.Settings.hasTransientTouchInput || Kirigami.Settings.tabletMode
|
||||
|
||||
icon.name: "overflow-menu"
|
||||
text: i18ndc("plasma_shell_org.kde.plasma.desktop", "@action:button", "More")
|
||||
|
||||
onClicked: {
|
||||
containment.openContextMenu(mapToGlobal(0, height));
|
||||
}
|
||||
}
|
||||
PC.ToolButton {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
icon.name: "window-close"
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Exit Edit Mode")
|
||||
onClicked: containment.plasmoid.corona.editMode = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on x {
|
||||
NumberAnimation {
|
||||
id: xAnim
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on y {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on height {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
MultiEffect {
|
||||
anchors.fill: parent
|
||||
source: containment
|
||||
layer.enabled: true
|
||||
layer.smooth: true
|
||||
layer.effect: Kirigami.ShadowedTexture {
|
||||
width: roundedRootWidth
|
||||
height: roundedRootHeight
|
||||
color: "transparent"
|
||||
|
||||
radius: open ? Kirigami.Units.cornerRadius : 0
|
||||
Behavior on radius {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
362
plasma/shells/org.kde.plasma.desktop/contents/views/Panel.qml
Normal file
362
plasma/shells/org.kde.plasma.desktop/contents/views/Panel.qml
Normal file
|
@ -0,0 +1,362 @@
|
|||
/*
|
||||
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
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2023 Fushan Wen <qydwhotmail@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
|
||||
import org.kde.plasma.extras as PlasmaExtras
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
Item {
|
||||
// Using childrenRect.width causes a binding loop since we can only get the
|
||||
// actual width, not the implicitWidth--which is what we would want
|
||||
width: Math.max(title.implicitWidth, subtitle.implicitWidth)
|
||||
height: childrenRect.height
|
||||
|
||||
HoverHandler {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
onTapped: Qt.openUrlExternally("https://bugs.kde.org/")
|
||||
}
|
||||
|
||||
PlasmaExtras.ShadowedLabel {
|
||||
id: title
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
}
|
||||
z: 2
|
||||
text: desktop.previewBannerTitle
|
||||
// Emulate the size of a level 1 heading
|
||||
font.pointSize: Math.round(Kirigami.Theme.defaultFont.pointSize * 1.35)
|
||||
}
|
||||
|
||||
PlasmaExtras.ShadowedLabel {
|
||||
id: subtitle
|
||||
anchors {
|
||||
top: title.bottom
|
||||
right: parent.right
|
||||
}
|
||||
z: 2
|
||||
text: desktop.previewBannerText
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue