melawy-plasma-plasmoid-win7.../org.kde.plasma.win7showdesktop/contents/ui/main.qml

409 lines
11 KiB
QML

/*
SPDX-FileCopyrightText: 2014 Ashish Madeti <ashishmadeti@gmail.com>
SPDX-FileCopyrightText: 2016 Kai Uwe Broulik <kde@privat.broulik.de>
SPDX-FileCopyrightText: 2019 Chris Holland <zrenfire@gmail.com>
SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko <me@ratijas.tk>
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.15
import QtQuick.Layouts 1.3
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.plasma5support as Plasma5Support
import org.kde.kirigami as Kirigami
import org.kde.ksvg as KSvg
import org.kde.plasma.plasmoid
PlasmoidItem {
id: root
preferredRepresentation: fullRepresentation
toolTipSubText: activeController.description
AppletConfig {
id: config
}
Plasmoid.icon: "transform-move"
Plasmoid.title: activeController.title
Plasmoid.onActivated: {
if (isPeeking) {
isPeeking = false;
peekController.toggle();
}
activeController.toggle();
}
Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground
Layout.minimumWidth: Kirigami.Units.iconSizes.medium
Layout.minimumHeight: Kirigami.Units.iconSizes.medium
Layout.maximumWidth: vertical ? Layout.minimumWidth : Math.max(1, Plasmoid.configuration.size)
Layout.maximumHeight: vertical ? Math.max(1, Plasmoid.configuration.size) : Layout.minimumHeight
Layout.preferredWidth: Layout.maximumWidth
Layout.preferredHeight: Layout.maximumHeight
Plasmoid.constraintHints: Plasmoid.CanFillArea
readonly property bool inPanel: [PlasmaCore.Types.TopEdge, PlasmaCore.Types.RightEdge, PlasmaCore.Types.BottomEdge, PlasmaCore.Types.LeftEdge]
.includes(Plasmoid.location)
readonly property bool vertical: Plasmoid.location === PlasmaCore.Types.RightEdge || Plasmoid.location === PlasmaCore.Types.LeftEdge
readonly property Controller primaryController: {
if (Plasmoid.configuration.click_action == "minimizeall") {
return minimizeAllController;
} else if (Plasmoid.configuration.click_action == "showdesktop") {
return peekController;
} else {
return commandController;
}
}
readonly property Controller activeController: {
if (minimizeAllController.active) {
return minimizeAllController;
} else {
return primaryController;
}
}
property bool isPeeking: false
MouseArea {
id: mouseArea
anchors.fill: parent
activeFocusOnTab: true
hoverEnabled: true
onClicked: Plasmoid.activated();
onEntered: {
if (Plasmoid.configuration.peekingEnabled)
peekTimer.start();
}
onExited: {
peekTimer.stop();
if (isPeeking) {
isPeeking = false;
peekController.toggle();
}
}
// org.kde.plasma.volume
property int wheelDelta: 0
onWheel: wheel => {
const delta = (wheel.inverted ? -1 : 1) * (wheel.angleDelta.y ? wheel.angleDelta.y : -wheel.angleDelta.x);
wheelDelta += delta;
// Magic number 120 for common "one click"
// See: https://qt-project.org/doc/qt-5/qml-qtquick-wheelevent.html#angleDelta-prop
while (wheelDelta >= 120) {
wheelDelta -= 120;
performMouseWheelUp();
}
while (wheelDelta <= -120) {
wheelDelta += 120;
performMouseWheelDown();
}
}
Keys.onPressed: {
switch (event.key) {
case Qt.Key_Space:
case Qt.Key_Enter:
case Qt.Key_Return:
case Qt.Key_Select:
Plasmoid.activated();
break;
}
}
Accessible.name: Plasmoid.title
Accessible.description: toolTipSubText
Accessible.role: Accessible.Button
PeekController {
id: peekController
}
MinimizeAllController {
id: minimizeAllController
}
CommandController {
id: commandController
}
Kirigami.Icon {
anchors.fill: parent
active: mouseArea.containsMouse || activeController.active
visible: Plasmoid.containment.corona.editMode
source: Plasmoid.icon
}
// also activate when dragging an item over the plasmoid so a user can easily drag data to the desktop
DropArea {
anchors.fill: parent
onEntered: activateTimer.start()
onExited: activateTimer.stop()
}
Timer {
id: activateTimer
interval: 250 // to match TaskManager
onTriggered: Plasmoid.activated()
}
Timer {
id: peekTimer
interval: Plasmoid.configuration.peekingThreshold
onTriggered: {
if (!minimizeAllController.active && !peekController.active) {
isPeeking = true;
peekController.toggle();
}
}
}
state: {
if (mouseArea.containsPress) {
return "pressed";
} else if (mouseArea.containsMouse || mouseArea.activeFocus) {
return "hover";
} else {
return "normal";
}
}
component ButtonSurface : Rectangle {
property var containerMargins: {
let item = this;
while (item.parent) {
item = item.parent;
if (item.isAppletContainer) {
return item.getMargins;
}
}
return undefined;
}
anchors {
fill: parent
property bool returnAllMargins: true
// The above makes sure margin is returned even for side margins
// that would be otherwise turned off.
topMargin: !vertical && containerMargins ? -containerMargins('top', returnAllMargins) : 0
leftMargin: vertical && containerMargins ? -containerMargins('left', returnAllMargins) : 0
rightMargin: vertical && containerMargins ? -containerMargins('right', returnAllMargins) : 0
bottomMargin: !vertical && containerMargins ? -containerMargins('bottom', returnAllMargins) : 0
}
Behavior on opacity { OpacityAnimator { duration: Kirigami.Units.longDuration; easing.type: Easing.OutCubic } }
}
ButtonSurface {
id: hoverSurface
color: Plasmoid.configuration.hoveredColor
opacity: mouseArea.state === "hover" ? 1 : 0
}
ButtonSurface {
id: pressedSurface
color: Plasmoid.configuration.pressedColor
opacity: mouseArea.state === "pressed" ? 1 : 0
}
ButtonSurface {
id: edgeLine
color: "transparent"
border.color: Plasmoid.configuration.edgeColor
border.width: 1
}
// Active/not active indicator
KSvg.FrameSvgItem {
property var containerMargins: {
let item = this;
while (item.parent) {
item = item.parent;
if (item.isAppletContainer) {
return item.getMargins;
}
}
return undefined;
}
anchors {
fill: parent
property bool returnAllMargins: true
// The above makes sure margin is returned even for side margins
// that would be otherwise turned off.
topMargin: !vertical && containerMargins ? -containerMargins('top', returnAllMargins) : 0
leftMargin: vertical && containerMargins ? -containerMargins('left', returnAllMargins) : 0
rightMargin: vertical && containerMargins ? -containerMargins('right', returnAllMargins) : 0
bottomMargin: !vertical && containerMargins ? -containerMargins('bottom', returnAllMargins) : 0
}
imagePath: "widgets/tabbar"
visible: opacity > 0
prefix: {
let prefix;
switch (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;
}
opacity: activeController.active ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: Kirigami.Units.shortDuration
easing.type: Easing.InOutQuad
}
}
}
PlasmaCore.ToolTipArea {
id: toolTip
anchors.fill: parent
mainText: Plasmoid.title
subText: toolTipSubText
textFormat: Text.PlainText
}
}
// https://invent.kde.org/plasma/plasma5support/-/tree/master/src/declarativeimports/datasource.h
Plasma5Support.DataSource {
id: executeSource
engine: "executable"
connectedSources: []
property var listeners: ({}) // Empty Map
signal exited(string cmd, int exitCode, int exitStatus, string stdout, string stderr)
function getUniqueId(cmd) {
// Note: we assume that 'cmd' is executed quickly so that a previous call
// with the same 'cmd' has already finished (otherwise no new cmd will be
// added because it is already in the list)
// Workaround: We append spaces onto the user's command to workaround this.
var cmd2 = cmd
for (var i = 0; i < 10; i++) {
if (connectedSources.includes(cmd2)) {
cmd2 += ' '
}
}
return cmd2
}
function exec(cmd, callback) {
const cmdId = getUniqueId(cmd)
if (typeof callback === 'function') {
if (listeners[cmdId]) {
exited.disconnect(listeners[cmdId])
delete listeners[cmdId]
}
var listener = execCallback.bind(executeSource, callback)
listeners[cmdId] = listener
}
connectSource(cmdId)
}
function execCallback(callback, cmd, exitCode, exitStatus, stdout, stderr) {
delete listeners[cmd]
callback(cmd, exitCode, exitStatus, stdout, stderr)
}
onNewData: function(sourceName, data) {
const cmd = sourceName
const exitCode = data["exit code"]
const exitStatus = data["exit status"]
const stdout = data["stdout"]
const stderr = data["stderr"]
const listener = listeners[cmd]
if (listener) {
listener(cmd, exitCode, exitStatus, stdout, stderr)
}
exited(cmd, exitCode, exitStatus, stdout, stderr)
disconnectSource(sourceName) // cmd finished
}
}
function exec(cmd) {
let cmd2 = executeSource.getUniqueId(cmd)
if (config.isOpenSUSE) {
cmd2 = cmd2.replace(/^qdbus /, 'qdbus6 ')
}
executeSource.connectSource(cmd2)
}
function performMouseWheelUp() {
root.exec(Plasmoid.configuration.mousewheel_up)
}
function performMouseWheelDown() {
root.exec(Plasmoid.configuration.mousewheel_down)
}
Plasmoid.contextualActions: [
PlasmaCore.Action {
visible: Plasmoid.immutability != PlasmaCore.Types.SystemImmutable
readonly property bool isLocked: Plasmoid.immutability != PlasmaCore.Types.Mutable
text: isLocked ? i18n("Unlock Widgets") : i18n("Lock Widgets")
icon.name: isLocked ? "object-unlocked" : "object-locked"
onTriggered: {
if (Plasmoid.immutability == PlasmaCore.Types.Mutable) {
Plasmoid.containment.corona.setImmutability(PlasmaCore.Types.UserImmutable)
} else if (Plasmoid.immutability == PlasmaCore.Types.UserImmutable) {
Plasmoid.containment.corona.setImmutability(PlasmaCore.Types.Mutable)
} else {
// ignore SystemImmutable
}
}
},
PlasmaCore.Action {
text: minimizeAllController.titleInactive
checkable: true
checked: minimizeAllController.active
toolTip: minimizeAllController.description
enabled: !peekController.active
onTriggered: minimizeAllController.toggle()
},
PlasmaCore.Action {
text: peekController.titleInactive
checkable: true
checked: peekController.active
toolTip: peekController.description
enabled: !minimizeAllController.active
onTriggered: peekController.toggle()
}
]
function detectSUSE() {
executeSource.exec('env | grep VENDOR', function(cmd, exitCode, exitStatus, stdout, stderr) {
if (stdout.replace(/\n/g, ' ').trim() == 'VENDOR=suse') {
config.isOpenSUSE = true
}
// console.log('config.isOpenSUSE', config.isOpenSUSE)
})
}
Component.onCompleted: {
detectSUSE()
}
}