Very early KDE 6 release.

This commit is contained in:
wackyideas 2024-08-09 03:20:25 +02:00
parent 7cc4ccabbc
commit 686046d4f7
6272 changed files with 140920 additions and 529657 deletions

View file

@ -0,0 +1,308 @@
/*
SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
SPDX-FileCopyrightText: 2014 Marco Martin <mart@kde.org>
SPDX-FileCopyrightText: 2019 Konrad Materka <materka@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.Controls as QQC2
import QtQuick.Layouts 1.3
import org.kde.plasma.plasmoid 2.0
import org.kde.kquickcontrols 2.0 as KQC
import org.kde.kirigami 2.10 as Kirigami
import org.kde.kitemmodels 1.0
import org.kde.kcmutils as KCM
KCM.ScrollViewKCM {
id: iconsPage
signal configurationChanged
property var cfg_shownItems: []
property var cfg_hiddenItems: []
property var cfg_extraItems: []
property alias cfg_showAllItems: showAllCheckBox.checked
function categoryName(category) {
switch (category) {
case "ApplicationStatus":
return i18n("Application Status")
case "Communications":
return i18n("Communications")
case "SystemServices":
return i18n("System Services")
case "Hardware":
return i18n("Hardware Control")
case "UnknownCategory":
default:
return i18n("Miscellaneous")
}
}
header: Kirigami.SearchField {
id: filterField
}
view: ListView {
id: itemsList
property real visibilityColumnWidth: Kirigami.Units.iconSizes.small
property real keySequenceColumnWidth: Kirigami.Units.iconSizes.small
readonly property int iconSize: Kirigami.Units.iconSizes.smallMedium
clip: true
model: KSortFilterProxyModel {
sourceModel: Plasmoid.configSystemTrayModel
filterString: filterField.text
filterCaseSensitivity: Qt.CaseInsensitive
}
reuseItems: true
header: RowLayout {
width: itemsList.width
spacing: Kirigami.Units.smallSpacing
Item {
implicitWidth: itemsList.iconSize + 2 * Kirigami.Units.smallSpacing
}
Kirigami.Heading {
text: i18nc("Name of the system tray entry", "Entry")
level: 2
elide: Text.ElideRight
Layout.fillWidth: true
}
Kirigami.Heading {
text: i18n("Visibility")
level: 2
Layout.preferredWidth: itemsList.visibilityColumnWidth
Component.onCompleted: itemsList.visibilityColumnWidth = Math.max(implicitWidth, itemsList.visibilityColumnWidth)
}
Kirigami.Heading {
text: i18n("Keyboard Shortcut")
level: 2
Layout.preferredWidth: itemsList.keySequenceColumnWidth
Component.onCompleted: itemsList.keySequenceColumnWidth = Math.max(implicitWidth, itemsList.keySequenceColumnWidth)
}
QQC2.Button { // Configure button column
icon.name: "configure"
enabled: false
opacity: 0
Layout.rightMargin: 2 * Kirigami.Units.smallSpacing
}
}
section {
property: "category"
delegate: Kirigami.ListSectionHeader {
label: categoryName(section)
width: itemsList.width
}
}
delegate: QQC2.ItemDelegate {
id: listItem
width: itemsList.width
// Don't need highlight, hover, or pressed effects
highlighted: false
hoverEnabled: false
down: false
readonly property bool isPlasmoid: model.itemType === "Plasmoid"
contentItem: FocusScope {
implicitHeight: childrenRect.height
onActiveFocusChanged: if (activeFocus) {
listItem.ListView.view.positionViewAtIndex(index, ListView.Contain);
}
RowLayout {
width: parent.width
spacing: Kirigami.Units.smallSpacing
Kirigami.Icon {
implicitWidth: itemsList.iconSize
implicitHeight: itemsList.iconSize
source: model.decoration
animated: false
}
QQC2.Label {
Layout.fillWidth: true
text: model.display
elide: Text.ElideRight
QQC2.ToolTip {
visible: listItem.hovered && parent.truncated
text: parent.text
}
}
QQC2.ComboBox {
id: visibilityComboBox
property real contentWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitWidth: Math.max(contentWidth, itemsList.visibilityColumnWidth)
Component.onCompleted: itemsList.visibilityColumnWidth = Math.max(implicitWidth, itemsList.visibilityColumnWidth)
enabled: (!showAllCheckBox.checked || isPlasmoid) && itemId
textRole: "text"
valueRole: "value"
model: comboBoxModel()
currentIndex: {
let value
if (cfg_shownItems.indexOf(itemId) !== -1) {
value = "shown"
} else if (cfg_hiddenItems.indexOf(itemId) !== -1) {
value = "hidden"
} else if (isPlasmoid && cfg_extraItems.indexOf(itemId) === -1) {
value = "disabled"
} else {
value = "auto"
}
for (let i = 0; i < model.length; i++) {
if (model[i].value === value) {
return i
}
}
return 0
}
onActivated: {
const shownIndex = cfg_shownItems.indexOf(itemId)
const hiddenIndex = cfg_hiddenItems.indexOf(itemId)
const extraIndex = cfg_extraItems.indexOf(itemId)
switch (currentValue) {
case "auto":
if (shownIndex > -1) {
cfg_shownItems.splice(shownIndex, 1)
}
if (hiddenIndex > -1) {
cfg_hiddenItems.splice(hiddenIndex, 1)
}
if (extraIndex === -1) {
cfg_extraItems.push(itemId)
}
break
case "shown":
if (shownIndex === -1) {
cfg_shownItems.push(itemId)
}
if (hiddenIndex > -1) {
cfg_hiddenItems.splice(hiddenIndex, 1)
}
if (extraIndex === -1) {
cfg_extraItems.push(itemId)
}
break
case "hidden":
if (shownIndex > -1) {
cfg_shownItems.splice(shownIndex, 1)
}
if (hiddenIndex === -1) {
cfg_hiddenItems.push(itemId)
}
if (extraIndex === -1) {
cfg_extraItems.push(itemId)
}
break
case "disabled":
if (shownIndex > -1) {
cfg_shownItems.splice(shownIndex, 1)
}
if (hiddenIndex > -1) {
cfg_hiddenItems.splice(hiddenIndex, 1)
}
if (extraIndex > -1) {
cfg_extraItems.splice(extraIndex, 1)
}
break
}
iconsPage.configurationChanged()
}
function comboBoxModel() {
const autoElement = {"value": "auto", "text": i18n("Shown when relevant")}
const shownElement = {"value": "shown", "text": i18n("Always shown")}
const hiddenElement = {"value": "hidden", "text": i18n("Always hidden")}
const disabledElement = {"value": "disabled", "text": i18n("Disabled")}
if (showAllCheckBox.checked) {
if (isPlasmoid) {
return [autoElement, disabledElement]
} else {
return [shownElement]
}
} else {
if (isPlasmoid) {
return [autoElement, shownElement, hiddenElement, disabledElement]
} else {
return [autoElement, shownElement, hiddenElement]
}
}
}
}
KQC.KeySequenceItem {
id: keySequenceItem
Layout.minimumWidth: itemsList.keySequenceColumnWidth
Layout.preferredWidth: itemsList.keySequenceColumnWidth
Component.onCompleted: itemsList.keySequenceColumnWidth = Math.max(implicitWidth, itemsList.keySequenceColumnWidth)
visible: isPlasmoid
enabled: visibilityComboBox.currentValue !== "disabled"
keySequence: model.applet ? model.applet.plasmoid.globalShortcut : ""
onCaptureFinished: {
if (model.applet && keySequence !== model.applet.plasmoid.globalShortcut) {
model.applet.plasmoid.globalShortcut = keySequence
itemsList.keySequenceColumnWidth = Math.max(implicitWidth, itemsList.keySequenceColumnWidth)
}
}
}
// Placeholder for when KeySequenceItem is not visible
Item {
Layout.minimumWidth: itemsList.keySequenceColumnWidth
Layout.maximumWidth: itemsList.keySequenceColumnWidth
visible: !keySequenceItem.visible
}
QQC2.Button {
readonly property QtObject configureAction: (model.applet && model.applet.plasmoid.internalAction("configure")) || null
Accessible.name: configureAction ? configureAction.text : ""
icon.name: "configure"
enabled: configureAction && configureAction.visible && configureAction.enabled
// Still reserve layout space, so not setting visible to false
opacity: enabled ? 1 : 0
onClicked: configureAction.trigger()
QQC2.ToolTip {
// Strip out ampersands right before non-whitespace characters, i.e.
// those used to determine the alt key shortcut
text: parent.Accessible.name.replace(/&(?=\S)/g, "")
}
}
}
}
}
}
footer: QQC2.CheckBox {
id: showAllCheckBox
text: i18n("Always show all entries")
Layout.alignment: Qt.AlignVCenter
}
}

View file

@ -0,0 +1,87 @@
/*
SPDX-FileCopyrightText: 2020 Konrad Materka <materka@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.14
import QtQuick.Controls 2.14 as QQC2
import QtQuick.Layouts 1.13
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core as PlasmaCore
import org.kde.kirigami 2.13 as Kirigami
import org.kde.kcmutils as KCM
KCM.SimpleKCM {
property bool cfg_scaleIconsToFit
property int cfg_iconSpacing
Kirigami.FormLayout {
Layout.fillHeight: true
QQC2.RadioButton {
Kirigami.FormData.label: i18nc("The arrangement of system tray icons in the Panel", "Panel icon size:")
enabled: !Kirigami.Settings.tabletMode
text: i18n("Small")
checked: cfg_scaleIconsToFit == false && !Kirigami.Settings.tabletMode
onToggled: cfg_scaleIconsToFit = !checked
}
QQC2.RadioButton {
id: automaticRadioButton
enabled: !Kirigami.Settings.tabletMode
text: Plasmoid.formFactor === PlasmaCore.Types.Horizontal ? i18n("Scale with Panel height")
: i18n("Scale with Panel width")
checked: cfg_scaleIconsToFit == true || Kirigami.Settings.tabletMode
onToggled: cfg_scaleIconsToFit = checked
}
QQC2.Label {
visible: Kirigami.Settings.tabletMode
text: i18n("Automatically enabled when in Touch Mode")
font: Kirigami.Theme.smallFont
}
Item {
Kirigami.FormData.isSection: true
}
QQC2.ComboBox {
Kirigami.FormData.label: i18nc("@label:listbox The spacing between system tray icons in the Panel", "Panel icon spacing:")
model: [
{
"label": i18nc("@item:inlistbox Icon spacing", "Small"),
"spacing": 1
},
{
"label": i18nc("@item:inlistbox Icon spacing", "Normal"),
"spacing": 2
},
{
"label": i18nc("@item:inlistbox Icon spacing", "Large"),
"spacing": 6
}
]
textRole: "label"
enabled: !Kirigami.Settings.tabletMode
currentIndex: {
if (Kirigami.Settings.tabletMode) {
return 2; // Large
}
switch (cfg_iconSpacing) {
case 1: return 0; // Small
case 2: return 1; // Normal
case 6: return 2; // Large
}
}
onActivated: cfg_iconSpacing = model[currentIndex]["spacing"];
}
QQC2.Label {
visible: Kirigami.Settings.tabletMode
text: i18nc("@info:usagetip under a combobox when Touch Mode is on", "Automatically set to Large when in Touch Mode")
font: Kirigami.Theme.smallFont
}
}
}

View file

@ -0,0 +1,180 @@
/*
SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.15
import org.kde.plasma.core as PlasmaCore
import org.kde.kirigami 2.20 as Kirigami
import org.kde.ksvg 1.0 as KSvg
import org.kde.plasma.plasmoid 2.0
KSvg.FrameSvgItem {
id: currentItemHighLight
property int location
property bool animationEnabled: true
property var highlightedItem: null
property var containerMargins: {
return 0;
let item = currentItemHighLight;
while (item.parent) {
item = item.parent;
if (item.isAppletContainer) {
return item.getMargins;
}
}
return undefined;
}
z: -1 // always draw behind icons
opacity: systemTrayState.expanded ? 0.8 : 0
imagePath: Qt.resolvedUrl("svgs/tabbar.svgz")
prefix: {
let prefix;
switch (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;
}
// update when System Tray is expanded - applet activated or hidden icons shown
Connections {
target: systemTrayState
function onActiveAppletChanged() {
Qt.callLater(updateHighlightedItem);
}
function onExpandedChanged() {
Qt.callLater(updateHighlightedItem);
}
}
// update when applet changes parent (e.g. moves from active to hidden icons)
Connections {
target: systemTrayState.activeApplet
function onParentChanged() {
Qt.callLater(updateHighlightedItem);
}
}
// update when System Tray size changes
Connections {
target: parent
function onWidthChanged() {
Qt.callLater(updateHighlightedItem);
}
function onHeightChanged() {
Qt.callLater(updateHighlightedItem);
}
}
// update when scale of newly added tray item changes (check 'add' animation in GridView in main.qml)
Connections {
target: !!highlightedItem && highlightedItem.parent ? highlightedItem.parent : null
function onScaleChanged() {
Qt.callLater(updateHighlightedItem);
}
}
function updateHighlightedItem() {
if (systemTrayState.expanded) {
if (systemTrayState.activeApplet && systemTrayState.activeApplet.parent && systemTrayState.activeApplet.parent.inVisibleLayout) {
changeHighlightedItem(systemTrayState.activeApplet.parent.container, /*forceEdgeHighlight*/false);
} else { // 'Show hidden items' popup
changeHighlightedItem(parent, /*forceEdgeHighlight*/true);
width = 0;
height = 0;
}
} else {
highlightedItem = null;
}
}
function changeHighlightedItem(nextItem, forceEdgeHighlight) {
// do not animate the first appearance
// or when the property value of a highlighted item changes
if (!highlightedItem || (highlightedItem === nextItem)) {
animationEnabled = false;
}
const p = parent.mapFromItem(nextItem, 0, 0);
if (containerMargins && (parent.oneRowOrColumn || forceEdgeHighlight)) {
x = p.x - containerMargins('left', /*returnAllMargins*/true);
y = p.y - containerMargins('top', /*returnAllMargins*/true);
width = nextItem.width + containerMargins('left', /*returnAllMargins*/true) + containerMargins('right', /*returnAllMargins*/true);
height = nextItem.height + containerMargins('bottom', /*returnAllMargins*/true) + containerMargins('top', /*returnAllMargins*/true);
} else {
x = p.x;
y = p.y;
width = nextItem.width
height = nextItem.height
}
highlightedItem = nextItem;
animationEnabled = true;
}
Behavior on opacity {
NumberAnimation {
duration: Kirigami.Units.longDuration
easing.type: Easing.Linear
}
}
/*Behavior on x {
id: xAnim
enabled: animationEnabled
NumberAnimation {
duration: Kirigami.Units.longDuration
easing.type: Easing.InOutCubic
}
}
Behavior on y {
id: yAnim
enabled: animationEnabled
NumberAnimation {
duration: Kirigami.Units.longDuration
easing.type: Easing.InOutCubic
}
}
Behavior on width {
id: widthAnim
enabled: animationEnabled
NumberAnimation {
duration: Kirigami.Units.longDuration
easing.type: Easing.InOutCubic
}
}
Behavior on height {
id: heightAnim
enabled: animationEnabled
NumberAnimation {
duration: Kirigami.Units.longDuration
easing.type: Easing.InOutCubic
}
}*/
}

View file

@ -0,0 +1,251 @@
/*
SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
SPDX-FileCopyrightText: 2020 Nate Graham <nate@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick
import QtQuick.Layouts 1.12
import QtQuick.Window 2.15
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.plasmoid 2.0
import org.kde.kirigami 2.20 as Kirigami
Item {
id: popup
property int flyoutWidth: hiddenItemsView.visible ? hiddenItemsView.width + Kirigami.Units.smallSpacing*2 : (intendedWidth != -1 ? intendedWidth : Kirigami.Units.iconSizes.small * 19)
property int flyoutHeight: hiddenItemsView.visible ?
hiddenItemsView.implicitHeight + trayHeading.height + Kirigami.Units.largeSpacing :
(container.flyoutImplicitHeight > (Kirigami.Units.iconSizes.small * 19 - trayHeading.height - Kirigami.Units.largeSpacing) ? container.flyoutImplicitHeight + container.headingHeight + container.footerHeight + trayHeading.height + Kirigami.Units.largeSpacing*4 : Kirigami.Units.iconSizes.small*19)
//: Kirigami.Units.iconSizes.small * 19
Layout.minimumWidth: flyoutWidth
Layout.minimumHeight: flyoutHeight
Layout.maximumWidth: flyoutWidth
Layout.maximumHeight: flyoutHeight
function updateHeight() {
//console.log(container.flyoutImplicitHeight + " " + (Kirigami.Units.iconSizes.small * 19 - trayHeading.height - Kirigami.Units.largeSpacing));
//console.log(container.flyoutImplicitHeight + container.headingHeight + container.footerHeight + trayHeading.height + Kirigami.Units.largeSpacing*4 + " new height")
flyoutHeight = Qt.binding(() => hiddenItemsView.visible ?
hiddenItemsView.implicitHeight + trayHeading.height + Kirigami.Units.largeSpacing :
(container.flyoutImplicitHeight > (Kirigami.Units.iconSizes.small * 19 - trayHeading.height - Kirigami.Units.largeSpacing) ? container.flyoutImplicitHeight + container.headingHeight + container.footerHeight + trayHeading.height + Kirigami.Units.largeSpacing*4 : Kirigami.Units.iconSizes.small*19))
popup.Layout.minimumHeight = Qt.binding(() => flyoutHeight);
popup.Layout.maximumHeight = Qt.binding(() => flyoutHeight);
}
property bool shownDialog: dialog.visible
//property bool changedItems: false
property int intendedWidth: container.activeApplet ? (typeof container.activeApplet.fullRepresentationItem.flyoutIntendedWidth !== "undefined" ? container.activeApplet.fullRepresentationItem.flyoutIntendedWidth : -1) : -1
onShownDialogChanged: {
//changedItems = false;
updateHeight();
}
property alias hiddenLayout: hiddenItemsView.layout
property alias plasmoidContainer: container
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
// Header
ToolButton {
id: pinButton
visible: !hiddenItemsView.visible
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.bottomMargin: Kirigami.Units.largeSpacing
anchors.rightMargin: Kirigami.Units.largeSpacing
width: Kirigami.Units.iconSizes.small+1;
height: Kirigami.Units.iconSizes.small;
checkable: true
checked: Plasmoid.configuration.pin
onClicked: (mouse) => {
Plasmoid.configuration.pin = !Plasmoid.configuration.pin;
}
buttonIcon: "pin"
z: 9999
//KeyNavigation.down: backButton.KeyNavigation.down
//KeyNavigation.left: configureButton.visible ? configureButton : configureButton.KeyNavigation.left
/*PlasmaComponents.ToolTip {
* text: parent.text
}*/
}
// Main content layout
ColumnLayout {
id: expandedRepresentation
anchors {
top: parent.top
bottom: trayHeading.top
left: parent.left
right: parent.right
bottomMargin: 0
}
//anchors.top: parent.top
anchors.margins: Kirigami.Units.smallSpacing
// TODO: remove this so the scrollview fully touches the header;
// add top padding internally
spacing: Kirigami.Units.smallSpacing
// Grid view of all available items
HiddenItemsView {
id: hiddenItemsView
Layout.preferredWidth: hiddenItemsView.width
//Layout.minimumHeight: hiddenItemsView.flyoutHeight
//Layout.maximumHeight: hiddenItemsView.flyoutHeight
visible: !systemTrayState.activeApplet
/*property int previousItemCount: 0
onHiddenItemsCountChanged: {
if(shownDialog) {
var itemCount = hiddenItemsView.hiddenItemsCount
if(itemCount > previousItemCount) {
if(itemCount % 3 == 1) {
console.log("big change " + hiddenItemsView.flyoutHeight + " " + hiddenItemsView.implicitHeight)
changedItems = true;
}
} else if(itemCount < previousItemCount) {
if(itemCount % 3 == 0) {
changedItems = true;
}
}
}
previousItemCount = hiddenItemsView.hiddenItemsCount;
}*/
onVisibleChanged: {
if (visible) {
layout.forceActiveFocus();
systemTrayState.oldVisualIndex = systemTrayState.newVisualIndex = -1;
}
}
}
// Container for currently visible item
PlasmoidPopupsContainer {
id: container
Layout.fillWidth: true
Layout.fillHeight: true
//Layout.topMargin: -dummyItem.height
visible: systemTrayState.activeApplet
// We need to add margin on the top so it matches the dialog's own margin
Layout.margins: Kirigami.Units.smallSpacing //mergeHeadings ? 0 : dialog.topPadding
Layout.bottomMargin: Kirigami.Units.mediumSpacing
//clip: true
KeyNavigation.up: pinButton
KeyNavigation.backtab: pinButton
/*Rectangle {
id: rectxd
color: "red"
anchors.fill: parent
}*/
onVisibleChanged: {
if (visible) {
forceActiveFocus();
}
}
}
}
// Header content layout
RowLayout {
id: trayHeading
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
/*leftMargin: dialogSvg.margins.left
rightMargin: dialogSvg.margins.right
bottomMargin: dialogSvg.margins.bottom*/
}
property QtObject applet: systemTrayState.activeApplet || root
visible: trayHeading.applet && trayHeading.applet.plasmoid.internalAction("configure")
height: 40
Item {
id: paddingLeft
Layout.fillWidth: true
}
Text {
id: headingLabel
color: "#0066cc"
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
Layout.bottomMargin: Kirigami.Units.smallSpacing
text: (systemTrayState.activeApplet ? systemTrayState.activeApplet.plasmoid.title : i18n("Customize..."))
elide: Text.ElideRight
font.underline: ma.containsMouse
Item { // I don't know why the f*ck this works but it works
id: rect
anchors.fill: parent
MouseArea {
id: ma
anchors.fill: parent
hoverEnabled: true
//enabled: parent.hoveredLink
cursorShape: Qt.PointingHandCursor
onClicked: {
trayHeading.applet.plasmoid.internalAction("configure").trigger();
}
//z: 9999
}
}
}
Item {
id: paddingRight
Layout.fillWidth: true
}
}
Rectangle {
id: plasmoidFooter
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
/*leftMargin: dialogSvg.margins.left
rightMargin: dialogSvg.margins.right
bottomMargin: dialogSvg.margins.bottom*/
}
visible: trayHeading.visible
//visible: container.appletHasFooter
height: trayHeading.height + Kirigami.Units.smallSpacing / 2 //+ container.footerHeight + Kirigami.Units.smallSpacing
//height: trayHeading.height + container.headingHeight + (container.headingHeight === 0 ? 0 : Kirigami.Units.smallSpacing/2)
color: "#f1f5fb"
Rectangle {
id: plasmoidFooterBorder
anchors {
top: parent.top
left: parent.left
right: parent.right
}
gradient: Gradient {
GradientStop { position: 0.0; color: "#ccd9ea" }
GradientStop { position: 1.0; color: "#f1f5fb" }
}
height: Kirigami.Units.smallSpacing
}
z: -9999
}
}

View file

@ -0,0 +1,157 @@
/*
SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.15
import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core as PlasmaCore
import org.kde.kirigami 2.20 as Kirigami
import org.kde.ksvg as KSvg
PlasmaCore.ToolTipArea {
id: tooltip
readonly property int arrowAnimationDuration: Kirigami.Units.shortDuration
property bool vertical: Plasmoid.formFactor === PlasmaCore.Types.Vertical
property int iconSize: Kirigami.Units.smallMedium
property int expanderSize: Kirigami.Units.iconSizes.smallMedium - Kirigami.Units.smallSpacing / 2
implicitWidth: expanderSize+1
implicitHeight: expanderSize
activeFocusOnTab: true
Accessible.name: subText
Accessible.description: i18n("Show all the items in the system tray in a popup")
Accessible.role: Accessible.Button
Accessible.onPressAction: systemTrayState.expanded = !systemTrayState.expanded
Keys.onPressed: event => {
switch (event.key) {
case Qt.Key_Space:
case Qt.Key_Enter:
case Qt.Key_Return:
case Qt.Key_Select:
systemTrayState.expanded = !systemTrayState.expanded;
}
}
subText: systemTrayState.expanded ? i18n("Close popup") : i18n("Show hidden icons")
property bool wasExpanded
property bool flyoutExpanded: systemTrayState.expanded
onFlyoutExpandedChanged: {
if(flyoutExpanded) {
tooltip.hideImmediately();
}
}
TapHandler {
onPressedChanged: {
if (pressed) {
tooltip.wasExpanded = systemTrayState.expanded;
}
}
onTapped: {
systemTrayState.expanded = !tooltip.wasExpanded;
expandedRepresentation.hiddenLayout.currentIndex = -1;
}
}
KSvg.SvgItem {
id: arrow
z: -1
anchors.centerIn: parent
width: expanderSize +1
height: expanderSize
//width: Math.min(parent.width, parent.height)+1
//height: width-1
// This is the Aero styled button texture used for the system tray expander.
KSvg.FrameSvgItem {
id: hoverButton
z: -1 // To prevent layout issues with the MouseArea.
anchors.fill: parent
imagePath: Qt.resolvedUrl("svgs/systray.svg")
prefix: {
if(tooltip.containsPress || (systemTrayState.expanded && expandedRepresentation.hiddenLayout.visible)) return "pressed";
if(tooltip.containsMouse) return "hover";
return "normal"; // The normal state actually just makes the button invisible.
}
}
imagePath: "widgets/arrows"
//svg: arrowSvg
elementId: {
// Depending on the taskbar orientation, choose different arrow orientation from the SVG.
if (Plasmoid.location === PlasmaCore.Types.TopEdge) {
return "down-arrow";
} else if (Plasmoid.location === PlasmaCore.Types.LeftEdge) {
return "right-arrow";
} else if (Plasmoid.location === PlasmaCore.Types.RightEdge) {
return "left-arrow";
} else {
return "up-arrow";
}
}
}
/*Kirigami.Icon {
anchors.fill: parent
rotation: systemTrayState.expanded ? 180 : 0
Behavior on rotation {
RotationAnimation {
duration: tooltip.arrowAnimationDuration
}
}
opacity: systemTrayState.expanded ? 0 : 1
Behavior on opacity {
NumberAnimation {
duration: tooltip.arrowAnimationDuration
}
}
source: {
if (Plasmoid.location === PlasmaCore.Types.TopEdge) {
return "arrow-down";
} else if (Plasmoid.location === PlasmaCore.Types.LeftEdge) {
return "arrow-right";
} else if (Plasmoid.location === PlasmaCore.Types.RightEdge) {
return "arrow-left";
} else {
return "arrow-up";
}
}
}
Kirigami.Icon {
anchors.fill: parent
rotation: systemTrayState.expanded ? 0 : -180
Behavior on rotation {
RotationAnimation {
duration: tooltip.arrowAnimationDuration
}
}
opacity: systemTrayState.expanded ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: tooltip.arrowAnimationDuration
}
}
source: {
if (Plasmoid.location === PlasmaCore.Types.TopEdge) {
return "arrow-up";
} else if (Plasmoid.location === PlasmaCore.Types.LeftEdge) {
return "arrow-left";
} else if (Plasmoid.location === PlasmaCore.Types.RightEdge) {
return "arrow-right";
} else {
return "arrow-down";
}
}
}*/
}

View file

@ -0,0 +1,118 @@
/*
SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
SPDX-FileCopyrightText: 2020 Konrad Materka <materka@gmail.com>
SPDX-FileCopyrightText: 2020 Nate Graham <nate@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.15
import QtQuick.Layouts 1.1
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.plasmoid 2.0
import org.kde.kitemmodels 1.0 as KItemModels
import org.kde.kirigami 2.20 as Kirigami
import "items"
import org.kde.plasma.extras 2.0 as PlasmaExtras
ScrollView {
id: hiddenTasksView
property alias hiddenItemsCount: hiddenTasks.count
property alias cellWidth: hiddenTasks.cellWidth
property alias cellHeight: hiddenTasks.cellHeight
//property int hiddenTasksWidth: 3 * hiddenTasks.cellWidth + Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing / 2 - 1 + hiddenTasksView.padding*2
//property int hiddenTasksHeight: Math.ceil(hiddenTasks.count / 3) * (hiddenTasks.cellHeight + Kirigami.Units.smallSpacing) + 40 + Kirigami.Units.largeSpacing*2 + hiddenTasksView.padding*2
property alias layout: hiddenTasks
property int flyoutHeight: Math.ceil(hiddenTasks.count / 3) * (hiddenTasks.cellHeight + Kirigami.Units.smallSpacing) + Kirigami.Units.smallSpacing*2
width: (hiddenTasks.cellWidth+Kirigami.Units.smallSpacing) * 3 - Kirigami.Units.smallSpacing/2 - 1
//topPadding: 0
padding: Kirigami.Units.mediumSpacing
leftPadding: Kirigami.Units.smallSpacing
bottomPadding: Kirigami.Units.mediumSpacing + Kirigami.Units.smallSpacing
rightPadding: 0
hoverEnabled: true
onHoveredChanged: if (!hovered) {
hiddenTasks.currentIndex = -1;
}
background: null
GridView {
id: hiddenTasks
readonly property int maximumColumns: 3
readonly property int minimumRows: 4
readonly property int minimumColumns: 4
cellWidth: Kirigami.Units.iconSizes.medium //Math.floor(Math.min(hiddenTasksView.availableWidth, popup.Layout.minimumWidth) / minimumRows)
cellHeight: Kirigami.Units.iconSizes.medium //Math.floor(popup.Layout.minimumHeight / minimumColumns)
currentIndex: -1
//highlight: PlasmaExtras.Highlight {}
highlightMoveDuration: 0
pixelAligned: true
readonly property int itemCount: model.count
//! This is used in order to identify the minimum required label height in order for all
//! labels to be aligned properly at all items. At the same time this approach does not
//! enforce labels with 3 lines at all cases so translations that require only one or two
//! lines will always look consistent with no too much padding
readonly property int minLabelHeight: {
var minHeight = 0;
for(let i in contentItem.children){
var gridItem = contentItem.children[i];
if (!gridItem || !gridItem.hasOwnProperty("item") || !gridItem.item.hasOwnProperty("labelHeight")) {
continue;
}
if (gridItem.item.labelHeight > minHeight) {
minHeight = gridItem.item.labelHeight;
}
}
return minHeight;
}
model: KItemModels.KSortFilterProxyModel {
sourceModel: Plasmoid.systemTrayModel
filterRoleName: "effectiveStatus"
filterRowCallback: (sourceRow, sourceParent) => {
let value = sourceModel.data(sourceModel.index(sourceRow, 0, sourceParent), filterRole);
return value === PlasmaCore.Types.PassiveStatus
}
}
delegate: ItemLoader {
id: itemloader
GridView.onRemove: SequentialAnimation {
PropertyAction { target: itemloader; property: "GridView.delayRemove"; value: true }
NumberAnimation { target: itemloader; property: "opacity"; to: 0; duration: 25; easing.type: Easing.InOutQuad }
PropertyAction { target: itemloader; property: "GridView.delayRemove"; value: false }
}
//GridView.delayRemove: true
width: hiddenTasks.cellWidth
height: hiddenTasks.cellHeight
minLabelHeight: 0//hiddenTasks.minLabelHeight
}
keyNavigationEnabled: true
activeFocusOnTab: true
KeyNavigation.up: hiddenTasksView.KeyNavigation.up
onActiveFocusChanged: {
if (activeFocus && currentIndex === -1) {
currentIndex = 0
} else if (!activeFocus && currentIndex >= 0) {
currentIndex = -1
}
}
}
}

View file

@ -0,0 +1,106 @@
/*
SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.kirigami 2.20 as Kirigami
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.plasmoid 2.0
StackView {
id: mainStack
focus: true
/*Layout.minimumWidth: Kirigami.Units.iconSizes.small * 12
Layout.minimumHeight: Kirigami.Units.iconSizes.small * 12*/
readonly property Item activeApplet: systemTrayState.activeApplet
/* Heading */
property bool appletHasHeading: false
property bool mergeHeadings: appletHasHeading && activeApplet.fullRepresentationItem.header.visible
property int headingHeight: mergeHeadings ? activeApplet.fullRepresentationItem.header.height : 0
/* Footer */
property bool appletHasFooter: false
property bool mergeFooters: appletHasFooter && activeApplet.fullRepresentationItem.footer.visible
property int footerHeight: mergeFooters ? activeApplet.fullRepresentationItem.footer.height : 0
readonly property int flyoutImplicitHeight: activeApplet ? activeApplet.fullRepresentationItem.implicitHeight : 0
onFlyoutImplicitHeightChanged: {
popup.updateHeight();
}
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
onActiveAppletChanged: {
mainStack.appletHasHeading = false
mainStack.appletHasFooter = false
if (activeApplet != null && activeApplet.fullRepresentationItem && !activeApplet.preferredRepresentation) {
//reset any potential anchor
activeApplet.fullRepresentationItem.anchors.left = undefined;
activeApplet.fullRepresentationItem.anchors.top = undefined;
activeApplet.fullRepresentationItem.anchors.right = undefined;
activeApplet.fullRepresentationItem.anchors.bottom = undefined;
activeApplet.fullRepresentationItem.anchors.centerIn = undefined;
activeApplet.fullRepresentationItem.anchors.fill = undefined;
if (activeApplet.fullRepresentationItem instanceof PlasmaComponents3.Page ||
activeApplet.fullRepresentationItem instanceof PlasmaExtras.Representation) {
if (activeApplet.fullRepresentationItem.header && activeApplet.fullRepresentationItem.header instanceof PlasmaExtras.PlasmoidHeading) {
mainStack.appletHasHeading = true;
activeApplet.fullRepresentationItem.header.background.visible = false;
activeApplet.fullRepresentationItem.header.Kirigami.Theme.colorSet = Kirigami.Theme.View;
activeApplet.fullRepresentationItem.header.Kirigami.Theme.inherit = false;
}
if (activeApplet.fullRepresentationItem.footer && activeApplet.fullRepresentationItem.footer instanceof PlasmaExtras.PlasmoidHeading) {
mainStack.appletHasFooter = true;
activeApplet.fullRepresentationItem.footer.background.visible = false;
activeApplet.fullRepresentationItem.footer.Kirigami.Theme.colorSet = Kirigami.Theme.View;
activeApplet.fullRepresentationItem.footer.Kirigami.Theme.inherit = false;
}
}
let unFlipped = systemTrayState.oldVisualIndex < systemTrayState.newVisualIndex;
if (Qt.application.layoutDirection !== Qt.LeftToRight) {
unFlipped = !unFlipped;
}
const isTransitionEnabled = false; //systemTrayState.expanded;
(mainStack.empty ? mainStack.push : mainStack.replace)(activeApplet.fullRepresentationItem, {
"Kirigami.Theme.colorSet": Kirigami.Theme.View,
"Kirigami.Theme.inherit": false,
"width": Qt.binding(() => mainStack.width),
"height": Qt.binding(() => mainStack.height),
"x": 0,
"focus": Qt.binding(() => !mainStack.busy), // QTBUG-44043: retrigger binding after StackView is ready to restore focus
"opacity": 1,
"KeyNavigation.up": mainStack.KeyNavigation.up,
"KeyNavigation.backtab": mainStack.KeyNavigation.backtab,
}, isTransitionEnabled ? (unFlipped ? StackView.PushTransition : StackView.PopTransition) : StackView.Immediate);
} else {
mainStack.clear();
}
}
onCurrentItemChanged: {
if (currentItem !== null && root.expanded) {
currentItem.forceActiveFocus();
}
}
Connections {
target: Plasmoid
function onAppletRemoved(applet) {
if (applet === systemTrayState.activeApplet) {
mainStack.clear();
}
}
}
}

View file

@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2017 Marco Martin <mart@kde.org>
* SPDX-FileCopyrightText: 2017 The Qt Company Ltd.
*
* SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-or-later
*/
import QtQuick
import QtQuick.Templates as T
import QtQml
import org.kde.kirigami as Kirigami
import org.kde.plasma.components as PlasmaComponents3
T.ScrollView {
id: controlRoot
clip: true
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
contentHeight + topPadding + bottomPadding)
leftPadding: mirrored && T.ScrollBar.vertical.visible && !Kirigami.Settings.isMobile ? T.ScrollBar.vertical.width : 0
rightPadding: !mirrored && T.ScrollBar.vertical.visible && !Kirigami.Settings.isMobile ? T.ScrollBar.vertical.width : 0
bottomPadding: T.ScrollBar.horizontal.visible && !Kirigami.Settings.isMobile ? T.ScrollBar.horizontal.height : 0
data: [
Kirigami.WheelHandler {
target: controlRoot.contentItem
// `Qt.styleHints.wheelScrollLines * 20` is the default scroll speed.
horizontalStepSize: Qt.styleHints.wheelScrollLines * 20
verticalStepSize: Qt.styleHints.wheelScrollLines * 20
},
Binding { // TODO KF6: remove, Qt6 has this behavior by default
target: controlRoot.contentItem // always instanceof Flickable
property: 'clip'
value: true
restoreMode: Binding.RestoreBindingOrValue
}
]
/*T.ScrollBar.vertical: PlasmaComponents3.ScrollBar {
parent: controlRoot
x: controlRoot.mirrored ? 0 : controlRoot.width - width
y: controlRoot.topPadding
height: controlRoot.availableHeight
active: controlRoot.T.ScrollBar.horizontal.active
}
T.ScrollBar.horizontal: PlasmaComponents3.ScrollBar {
parent: controlRoot
x: controlRoot.leftPadding
y: controlRoot.height - height
width: controlRoot.availableWidth
active: controlRoot.T.ScrollBar.vertical.active
}*/
}

View file

@ -0,0 +1,100 @@
/*
SPDX-FileCopyrightText: 2020 Konrad Materka <materka@gmail.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.12
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.plasmoid 2.0
//This object contains state of the SystemTray, mainly related to the 'expanded' state
QtObject {
//true if System Tray is 'expanded'. It may be when:
// - there is an active applet or
// - 'Status and Notification' with hidden items is shown
property bool expanded: false
//set when there is an applet selected
property Item activeApplet
//allow expanded change only when activated at least once
//this is to suppress expanded state change during Plasma startup
property bool acceptExpandedChange: false
// These properties allow us to keep track of where the expanded applet
// was and is on the panel, allowing PlasmoidPopupContainer.qml to animate
// depending on their locations.
property int oldVisualIndex: -1
property int newVisualIndex: -1
function setActiveApplet(applet, visualIndex) {
if (visualIndex === undefined) {
oldVisualIndex = -1
newVisualIndex = -1
} else {
oldVisualIndex = (activeApplet && activeApplet.status === PlasmaCore.Types.PassiveStatus) ? 9999 : newVisualIndex
newVisualIndex = visualIndex
}
const oldApplet = activeApplet
if (applet && !applet.preferredRepresentation) {
applet.expanded = true;
}
if (!applet || !applet.preferredRepresentation) {
activeApplet = applet;
}
if (oldApplet && oldApplet !== applet) {
oldApplet.expanded = false
}
if (applet && !applet.preferredRepresentation) {
expanded = true
}
}
onExpandedChanged: {
if (expanded) {
Plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus
} else {
Plasmoid.status = PlasmaCore.Types.PassiveStatus;
if (activeApplet) {
// if not expanded we don't have an active applet anymore
activeApplet.expanded = false
activeApplet = null
}
}
acceptExpandedChange = false
root.expanded = expanded
}
//listen on SystemTray AppletInterface signals
property Connections plasmoidConnections: Connections {
target: Plasmoid
//emitted when activation is requested, for example by using a global keyboard shortcut
function onActivated() {
acceptExpandedChange = true
}
}
property Connections rootConnections: Connections {
function onExpandedChanged() {
if (acceptExpandedChange) {
expanded = root.expanded
} else {
root.expanded = expanded
}
}
}
property Connections activeAppletConnections: Connections {
target: activeApplet && activeApplet
function onExpandedChanged() {
if (activeApplet && !activeApplet.expanded) {
expanded = false
}
}
}
}

View file

@ -0,0 +1,57 @@
/*import QtQuick 2.6
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import QtQml.Models 2.2
import org.kde.plasma.core 2.0 as PlasmaCore
// for Highlight
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons
*/
import QtQuick 2.5
import QtQuick.Layouts 1.1
import QtQuick.Window 2.15
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.plasmoid 2.0
import org.kde.ksvg 1.0 as KSvg
import org.kde.kirigami 2.5 as Kirigami // For Settings.tabletMode
MouseArea {
id: toolButton
Layout.maximumWidth: Kirigami.Units.iconSizes.small+1;
Layout.maximumHeight: Kirigami.Units.iconSizes.small;
Layout.preferredWidth: Kirigami.Units.iconSizes.small+1;
Layout.preferredHeight: Kirigami.Units.iconSizes.small;
//signal clicked
property string buttonIcon: ""
property bool checkable: false
property bool checked: false
hoverEnabled: true
KSvg.FrameSvgItem {
id: normalButton
imagePath: Qt.resolvedUrl("svgs/button.svgz")
anchors.fill: parent
prefix: {
if(parent.containsPress || (checkable && checked)) return "toolbutton-pressed";
else return "toolbutton-hover";
}
visible: parent.containsMouse || (checkable && checked)
}
KSvg.SvgItem {
id: buttonIconSvg
svg: buttonIcons
elementId: buttonIcon
width: 10;
height: 10;
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
}

View file

@ -0,0 +1,257 @@
/*
SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
SPDX-FileCopyrightText: 2020 Konrad Materka <materka@gmail.com>
SPDX-FileCopyrightText: 2020 Nate Graham <nate@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.2
import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.kirigami 2.20 as Kirigami
import org.kde.ksvg 1.0 as KSvg
PlasmaCore.ToolTipArea {
id: abstractItem
property var model: itemModel
property string itemId
property alias text: label.text
property alias labelHeight: label.implicitHeight
property alias iconContainer: iconContainer
property int /*PlasmaCore.Types.ItemStatus*/ status: model.status || PlasmaCore.Types.UnknownStatus
property int /*PlasmaCore.Types.ItemStatus*/ effectiveStatus: model.effectiveStatus || PlasmaCore.Types.UnknownStatus
property bool effectivePressed: false
property real minLabelHeight: 0
readonly property bool inHiddenLayout: effectiveStatus === PlasmaCore.Types.PassiveStatus
readonly property bool inVisibleLayout: effectiveStatus === PlasmaCore.Types.ActiveStatus
// input agnostic way to trigger the main action
signal activated(var pos)
// proxy signals for MouseArea
signal clicked(var mouse)
signal pressed(var mouse)
signal wheel(var wheel)
signal contextMenu(var mouse)
/* subclasses need to assign to this tooltip properties
mainText:
subText:
*/
location: {
if (inHiddenLayout) {
if (LayoutMirroring.enabled && Plasmoid.location !== PlasmaCore.Types.RightEdge) {
return PlasmaCore.Types.LeftEdge;
} else if (Plasmoid.location !== PlasmaCore.Types.LeftEdge) {
return PlasmaCore.Types.RightEdge;
}
}
return Plasmoid.location;
}
/*PulseAnimation {
targetItem: iconContainer
running: (abstractItem.status === PlasmaCore.Types.NeedsAttentionStatus
|| abstractItem.status === PlasmaCore.Types.RequiresAttentionStatus)
&& Kirigami.Units.longDuration > 0
}*/
KSvg.FrameSvgItem {
id: itemHighLight
anchors.fill: parent
//property int location
property bool animationEnabled: true
property var highlightedItem: null
z: -1 // always draw behind icons
opacity: mouseArea.containsMouse ? 1 : 0
imagePath: Qt.resolvedUrl("../svgs/tabbar.svgz")
//imagePath: "widgets/tabbar"
prefix: {
var 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;
}
Behavior on opacity {
NumberAnimation {
duration: Kirigami.Units.longDuration
easing.type: Easing.InOutQuad
}
}
Rectangle {
id: pressRect
property alias activatedPress: pressRect.opacity
anchors.fill: parent
anchors.leftMargin: Kirigami.Units.smallSpacing / 2; // We don't want the rectangle to draw over the highlight texture itself.
anchors.rightMargin: Kirigami.Units.smallSpacing / 2;
gradient: Gradient {
// The first and last gradient stops are offset by +/-0.1 to avoid a sudden gradient "cutoff".
GradientStop { position: 0.1; color: "transparent"; }
GradientStop { position: 0.5; color: "#66000000"; }
GradientStop { position: 0.9; color: "transparent"; }
}
opacity: mouseArea.containsPress ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: 150;
easing.type: Easing.InOutQuad
}
}
}
}
MouseArea {
id: mouseArea
propagateComposedEvents: true
// This needs to be above applets when it's in the grid hidden area
// so that it can receive hover events while the mouse is over an applet,
// but below them on regular systray, so collapsing works
//z: inHiddenLayout ? 1 : 0
z: 1
anchors.fill: abstractItem
hoverEnabled: true
drag.filterChildren: true
// Necessary to make the whole delegate area forward all mouse events
acceptedButtons: Qt.AllButtons
// Using onPositionChanged instead of onEntered because changing the
// index in a scrollable view also changes the view position.
// onEntered will change the index while the items are scrolling,
// making it harder to scroll.
onContainsMouseChanged: {
if(inHiddenLayout && !mouseArea.containsMouse) {
root.hiddenLayout.currentIndex = -1;
}
}
onPositionChanged: if (inHiddenLayout) {
root.hiddenLayout.currentIndex = index
}
onClicked: mouse => { abstractItem.clicked(mouse) }
onPressed: mouse => {
if (inHiddenLayout) {
root.hiddenLayout.currentIndex = index
}
abstractItem.hideImmediately()
abstractItem.pressed(mouse)
}
onPressAndHold: mouse => {
if (mouse.button === Qt.LeftButton) {
abstractItem.contextMenu(mouse)
}
}
onWheel: wheel => {
abstractItem.wheel(wheel);
//Don't accept the event in order to make the scrolling by mouse wheel working
//for the parent scrollview this icon is in.
wheel.accepted = false;
}
}
ColumnLayout {
anchors.fill: abstractItem
spacing: 0
FocusScope {
id: iconContainer
//scale: (abstractItem.effectivePressed || mouseArea.containsPress) ? 0.8 : 1
Kirigami.Theme.colorSet: abstractItem.inHiddenLayout ? Kirigami.Theme.Tooltip : Kirigami.Theme.Window
Kirigami.Theme.inherit: false
activeFocusOnTab: true
focus: true // Required in HiddenItemsView so keyboard events can be forwarded to this item
Accessible.name: abstractItem.text
Accessible.description: abstractItem.subText
Accessible.role: Accessible.Button
Accessible.onPressAction: abstractItem.activated(Plasmoid.popupPosition(iconContainer, iconContainer.width/2, iconContainer.height/2));
/*Behavior on scale {
ScaleAnimator {
duration: Kirigami.Units.longDuration
easing.type: (effectivePressed || mouseArea.containsPress) ? Easing.OutCubic : Easing.InCubic
}
}*/
Keys.onPressed: event => {
switch (event.key) {
case Qt.Key_Space:
case Qt.Key_Enter:
case Qt.Key_Return:
case Qt.Key_Select:
abstractItem.activated(Qt.point(width/2, height/2));
break;
case Qt.Key_Menu:
abstractItem.contextMenu(null);
event.accepted = true;
break;
}
}
property alias container: abstractItem
property alias inVisibleLayout: abstractItem.inVisibleLayout
readonly property int size: abstractItem.inVisibleLayout ? root.itemSize : Kirigami.Units.iconSizes.small
Layout.alignment: Qt.Bottom | Qt.AlignHCenter
Layout.fillHeight: abstractItem.inHiddenLayout ? true : false
implicitWidth: root.vertical && abstractItem.inVisibleLayout ? abstractItem.width : size
implicitHeight: !root.vertical && abstractItem.inVisibleLayout ? abstractItem.height : size
//Layout.topMargin: abstractItem.inHiddenLayout ? Kirigami.Units.mediumSpacing : 0
}
PlasmaComponents3.Label {
id: label
Layout.fillWidth: true
Layout.fillHeight: abstractItem.inHiddenLayout ? true : false
//! Minimum required height for all labels is used in order for all
//! labels to be aligned properly at all items. At the same time this approach does not
//! enforce labels with 3 lines at all cases so translations that require only one or two
//! lines will always look consistent with no too much padding
Layout.minimumHeight: abstractItem.inHiddenLayout ? abstractItem.minLabelHeight : 0
Layout.leftMargin: abstractItem.inHiddenLayout ? Kirigami.Units.smallSpacing : 0
Layout.rightMargin: abstractItem.inHiddenLayout ? Kirigami.Units.smallSpacing : 0
Layout.bottomMargin: abstractItem.inHiddenLayout ? Kirigami.Units.smallSpacing : 0
visible: false //abstractItem.inHiddenLayout
verticalAlignment: Text.AlignTop
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
wrapMode: Text.Wrap
maximumLineCount: 3
opacity: visible ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: Kirigami.Units.longDuration
easing.type: Easing.InOutQuad
}
}
}
}
}

View file

@ -0,0 +1,31 @@
/*
SPDX-FileCopyrightText: 2020 Konrad Materka <materka@gmail.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.0
Loader {
id: itemLoader
property real minLabelHeight: 0
z: x+1 // always be above what it's on top of, even for x==0
property var itemModel: model
Binding {
target: item
property: "minLabelHeight"
value: itemLoader.minLabelHeight
}
source: {
if (model.itemType === "Plasmoid" && model.hasApplet) {
return Qt.resolvedUrl("PlasmoidItem.qml")
} else if (model.itemType === "StatusNotifier") {
return Qt.resolvedUrl("StatusNotifierItem.qml")
}
console.warn("SystemTray ItemLoader: Invalid state, cannot determine source!")
return ""
}
}

View file

@ -0,0 +1,185 @@
/*
SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
SPDX-FileCopyrightText: 2022 ivan tkachenko <me@ratijas.tk>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.15
import QtQml 2.15
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
AbstractItem {
id: plasmoidContainer
property Item applet: model.applet || null
text: applet ? applet.plasmoid.title : ""
itemId: applet ? applet.plasmoid.pluginName : ""
mainText: applet ? applet.toolTipMainText : ""
subText: applet ? applet.toolTipSubText : ""
mainItem: applet && applet.toolTipItem ? applet.toolTipItem : null
textFormat: applet ? applet.toolTipTextFormat : 0 /* Text.AutoText, the default value */
active: systemTrayState.activeApplet !== applet
// FIXME: Use an input type agnostic way to activate whatever the primary
// action of a plasmoid is supposed to be, even if it's just expanding the
// Plasmoid. Not all plasmoids are supposed to expand and not all plasmoids
// do anything with onActivated.
onActivated: {
if (applet) {
applet.plasmoid.activated()
}
}
onClicked: mouse => {
if (!applet) {
return
}
//forward click event to the applet
var appletItem = applet.compactRepresentationItem ?? applet.fullRepresentationItem
const mouseArea = findMouseArea(appletItem)
if (mouseArea && mouse.button !== Qt.RightButton) {
var temp = applet.expanded;
mouseArea.clicked(mouse);
if(mouse.button === Qt.LeftButton && inVisibleLayout && applet.expanded && temp) {
applet.expanded = false;
}
} else if (mouse.button === Qt.LeftButton) {//fallback
activated(null)
}
}
onPressed: mouse => {
// Only Plasmoids can show context menu on the mouse pressed event.
// SNI has few problems, for example legacy applications that still use XEmbed require mouse to be released.
if (mouse.button === Qt.RightButton) {
contextMenu(mouse);
} /*else {
const appletItem = applet.compactRepresentationItem ?? applet.fullRepresentationItem
const mouseArea = findMouseArea(appletItem)
}*/
}
onContextMenu: if (applet) {
effectivePressed = false;
Plasmoid.showPlasmoidMenu(applet, 0, inHiddenLayout ? applet.height : 0);
}
onWheel: (wheel) => {
if (!applet) {
return
}
//forward wheel event to the applet
var appletItem = applet.compactRepresentationItem ?? applet.fullRepresentationItem
const mouseArea = findMouseArea(appletItem)
if (mouseArea) {
mouseArea.wheel(wheel)
}
}
//some heuristics to find MouseArea
function findMouseArea(item: Item): MouseArea {
if (!item) {
return null
}
if (item instanceof MouseArea) {
return item
}
for (var i = 0; i < item.children.length; i++) {
const child = item.children[i]
if (child instanceof MouseArea && child.enabled) {
//check if MouseArea covers the entire item
if (child.anchors.fill === item || (child.x === 0 && child.y === 0 && child.height === item.height && child.width === item.width)) {
return child
}
}
}
return null
}
//This is to make preloading effective, minimizes the scene changes
function preloadFullRepresentationItem(fullRepresentationItem) {
if (fullRepresentationItem && fullRepresentationItem.parent === null) {
fullRepresentationItem.width = expandedRepresentation.width
fullRepresentationItem.height = expandedRepresentation.height
fullRepresentationItem.parent = preloadedStorage;
}
}
onAppletChanged: {
if (applet) {
applet.parent = iconContainer
applet.anchors.fill = applet.parent
applet.visible = true
preloadFullRepresentationItem(applet.fullRepresentationItem)
}
}
Connections {
enabled: plasmoidContainer.applet !== null
target: findMouseArea(
plasmoidContainer.applet?.compactRepresentationItem ??
plasmoidContainer.applet?.fullRepresentationItem ??
plasmoidContainer.applet
)
function onContainsPressChanged() {
plasmoidContainer.effectivePressed = target.containsPress;
}
// TODO For touch/stylus only, since the feature is not desired for mouse users
function onPressAndHold(mouse) {
if (mouse.button === Qt.LeftButton) {
plasmoidContainer.contextMenu(mouse)
}
}
}
Connections {
target: plasmoidContainer.applet?.plasmoid ?? null
//activation using global keyboard shortcut
function onActivated() {
plasmoidContainer.effectivePressed = true;
Qt.callLater(() => {
plasmoidContainer.effectivePressed = false;
});
}
}
Connections {
target: plasmoidContainer.applet
function onFullRepresentationItemChanged(fullRepresentationItem) {
preloadFullRepresentationItem(fullRepresentationItem)
}
function onExpandedChanged(expanded) {
if (expanded) {
systemTrayState.setActiveApplet(plasmoidContainer.applet, model.row)
effectivePressed = false;
}
}
}
/*PlasmaComponents3.BusyIndicator {
anchors.fill: parent
z: 999
running: plasmoidContainer.applet?.plasmoid.busy ?? false
}*/
Binding {
property: "hideOnWindowDeactivate"
value: !Plasmoid.configuration.pin
target: plasmoidContainer.applet
when: plasmoidContainer.applet !== null
restoreMode: Binding.RestoreBinding
}
}

View file

@ -0,0 +1,40 @@
/*
SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
SPDX-FileCopyrightText: 2015 Kai Uwe Broulik <kde@privat.broulik.de>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.2
import org.kde.kirigami 2.20 as Kirigami
SequentialAnimation {
id: pulseAnimation
objectName: "pulseAnimation"
property Item targetItem
readonly property int duration: Kirigami.Units.veryLongDuration * 5
loops: Animation.Infinite
alwaysRunToEnd: true
ScaleAnimator {
target: targetItem
from: 1
to: 1.2
duration: pulseAnimation.duration * 0.15
easing.type: Easing.InQuad
}
ScaleAnimator {
target: targetItem
from: 1.2
to: 1
duration: pulseAnimation.duration * 0.15
easing.type: Easing.InQuad
}
PauseAnimation {
duration: pulseAnimation.duration * 0.7
}
}

View file

@ -0,0 +1,112 @@
/*
SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core as PlasmaCore
import org.kde.kirigami 2.20 as Kirigami
AbstractItem {
id: taskIcon
itemId: model.Id
text: model.Title || model.ToolTipTitle
mainText: model.ToolTipTitle !== "" ? model.ToolTipTitle : model.Title
subText: model.ToolTipSubTitle
textFormat: Text.AutoText
Kirigami.Icon {
id: iconItem
parent: taskIcon.iconContainer
anchors.fill: iconItem.parent
source: {
if (model.status === PlasmaCore.Types.NeedsAttentionStatus) {
if (model.AttentionIcon) {
return model.AttentionIcon
}
if (model.AttentionIconName) {
return model.AttentionIconName
}
}
return model.Icon || model.IconName
}
active: taskIcon.containsMouse
}
onActivated: pos => {
const service = model.Service;
const operation = service.operationDescription("Activate");
operation.x = pos.x; //mouseX
operation.y = pos.y; //mouseY
const job = service.startOperationCall(operation);
job.finished.connect(() => {
if (!job.result) {
// On error try to invoke the context menu.
// Workaround primarily for apps using libappindicator.
openContextMenu(pos);
}
})
}
onContextMenu: mouse => {
if (mouse === null) {
openContextMenu(Plasmoid.popupPosition(taskIcon, taskIcon.width / 2, taskIcon.height / 2));
} else {
openContextMenu(Plasmoid.popupPosition(taskIcon, mouse.x, mouse.y));
}
}
onClicked: mouse => {
var pos = Plasmoid.popupPosition(taskIcon, mouse.x, mouse.y);
switch (mouse.button) {
case Qt.LeftButton:
taskIcon.activated(pos)
break;
case Qt.RightButton:
openContextMenu(pos);
break;
case Qt.MiddleButton:
const service = model.Service;
const operation = service.operationDescription("SecondaryActivate");
operation.x = pos.x;
operation.y = pos.y;
service.startOperationCall(operation);
break;
}
}
function openContextMenu(pos = Qt.point(width/2, height/2)) {
const service = model.Service;
const operation = service.operationDescription("ContextMenu");
operation.x = pos.x;
operation.y = pos.y;
const job = service.startOperationCall(operation);
job.finished.connect(() => {
Plasmoid.showStatusNotifierContextMenu(job, taskIcon);
});
}
onWheel: wheel => {
//don't send activateVertScroll with a delta of 0, some clients seem to break (kmix)
if (wheel.angleDelta.y !== 0) {
const service = model.Service;
const operation = service.operationDescription("Scroll");
operation.delta = wheel.angleDelta.y;
operation.direction = "Vertical";
service.startOperationCall(operation);
}
if (wheel.angleDelta.x !== 0) {
const service = model.Service;
const operation = service.operationDescription("Scroll");
operation.delta = wheel.angleDelta.x;
operation.direction = "Horizontal";
service.startOperationCall(operation);
}
}
}

View file

@ -0,0 +1,356 @@
/*
SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org>
SPDX-FileCopyrightText: 2020 Konrad Materka <materka@gmail.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.5
import QtQuick.Layouts 1.1
import QtQuick.Window 2.15
import org.kde.plasma.core as PlasmaCore
import org.kde.ksvg 1.0 as KSvg
import org.kde.plasma.plasmoid 2.0
import org.kde.draganddrop 2.0 as DnD
import org.kde.kirigami 2.5 as Kirigami // For Settings.tabletMode
import org.kde.kitemmodels 1.0 as KItemModels
import "items"
ContainmentItem {
id: root
readonly property bool vertical: Plasmoid.formFactor === PlasmaCore.Types.Vertical
Layout.minimumWidth: vertical ? Kirigami.Units.iconSizes.small : mainLayout.implicitWidth + Kirigami.Units.smallSpacing
Layout.minimumHeight: vertical ? mainLayout.implicitHeight + Kirigami.Units.smallSpacing : Kirigami.Units.iconSizes.small
LayoutMirroring.enabled: !vertical && Qt.application.layoutDirection === Qt.RightToLeft
LayoutMirroring.childrenInherit: true
readonly property alias systemTrayState: systemTrayState
readonly property alias itemSize: tasksGrid.itemSize
readonly property alias visibleLayout: tasksGrid
readonly property alias hiddenLayout: expandedRepresentation.hiddenLayout
readonly property bool oneRowOrColumn: tasksGrid.rowsOrColumns === 1
KSvg.Svg {
id: buttonIcons
imagePath: Qt.resolvedUrl("svgs/icons.svg");
}
KSvg.FrameSvgItem {
id : dialogSvg
visible: false
imagePath: "solid/dialogs/background"
}
MouseArea {
anchors.fill: parent
onWheel: {
// Don't propagate unhandled wheel events
wheel.accepted = true;
}
SystemTrayState {
id: systemTrayState
}
//being there forces the items to fully load, and they will be reparented in the popup one by one, this item is *never* visible
Item {
id: preloadedStorage
visible: false
}
CurrentItemHighLight {
id: currentHighlight
location: Plasmoid.location
parent: root
onHighlightedItemChanged: {
if(dialog.visible) dialog.setDialogPosition();
}
}
DnD.DropArea {
anchors.fill: parent
preventStealing: true
/** Extracts the name of the system tray applet in the drag data if present
* otherwise returns null*/
function systemTrayAppletName(event) {
if (event.mimeData.formats.indexOf("text/x-plasmoidservicename") < 0) {
return null;
}
const plasmoidId = event.mimeData.getDataAsByteArray("text/x-plasmoidservicename");
if (!Plasmoid.isSystemTrayApplet(plasmoidId)) {
return null;
}
return plasmoidId;
}
onDragEnter: {
if (!systemTrayAppletName(event)) {
event.ignore();
}
}
onDrop: {
const plasmoidId = systemTrayAppletName(event);
if (!plasmoidId) {
event.ignore();
return;
}
if (Plasmoid.configuration.extraItems.indexOf(plasmoidId) < 0) {
const extraItems = Plasmoid.configuration.extraItems;
extraItems.push(plasmoidId);
Plasmoid.configuration.extraItems = extraItems;
}
}
}
//Main Layout
GridLayout {
id: mainLayout
rowSpacing: 0
columnSpacing: 0
anchors.fill: parent
flow: vertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
ExpanderArrow {
id: expander
Layout.fillWidth: vertical
Layout.fillHeight: !vertical
Layout.alignment: vertical ? Qt.AlignVCenter : Qt.AlignHCenter
iconSize: tasksGrid.itemSize
visible: root.hiddenLayout.itemCount > 0
}
GridView {
id: tasksGrid
Layout.alignment: Qt.AlignCenter
interactive: false //disable features we don't need
flow: vertical ? GridView.LeftToRight : GridView.TopToBottom
// The icon size to display when not using the auto-scaling setting
readonly property int smallIconSize: Kirigami.Units.iconSizes.small
// Automatically use autoSize setting when in tablet mode, if it's
// not already being used
readonly property bool autoSize: Plasmoid.configuration.scaleIconsToFit || Kirigami.Settings.tabletMode
readonly property int gridThickness: root.vertical ? root.width : root.height
// Should change to 2 rows/columns on a 56px panel (in standard DPI)
readonly property int rowsOrColumns: autoSize ? 1 : Math.max(1, Math.min(count, Math.floor(gridThickness / (smallIconSize + Kirigami.Units.smallSpacing))))
// Add margins only if the panel is larger than a small icon (to avoid large gaps between tiny icons)
readonly property int cellSpacing: Kirigami.Units.smallSpacing * (Kirigami.Settings.tabletMode ? 6 : Plasmoid.configuration.iconSpacing)
readonly property int smallSizeCellLength: gridThickness < smallIconSize ? smallIconSize : smallIconSize + cellSpacing
cellHeight: {
if (root.vertical) {
return autoSize ? itemSize + (gridThickness < itemSize ? 0 : cellSpacing) : smallSizeCellLength
} else {
return autoSize ? root.height : Math.floor(root.height / rowsOrColumns)
}
}
cellWidth: {
if (root.vertical) {
return autoSize ? root.width : Math.floor(root.width / rowsOrColumns)
} else {
return autoSize ? itemSize + (gridThickness < itemSize ? 0 : cellSpacing) : smallSizeCellLength
}
}
//depending on the form factor, we are calculating only one dimension, second is always the same as root/parent
implicitHeight: root.vertical ? cellHeight * Math.ceil(count / rowsOrColumns) : root.height
implicitWidth: !root.vertical ? cellWidth * Math.ceil(count / rowsOrColumns) : root.width
readonly property int itemSize: {
if (autoSize) {
return Kirigami.Units.iconSizes.roundedIconSize(Math.min(Math.min(root.width, root.height) / rowsOrColumns, Kirigami.Units.iconSizes.enormous))
} else {
return smallIconSize
}
}
model: KItemModels.KSortFilterProxyModel {
sourceModel: Plasmoid.systemTrayModel
filterRoleName: "effectiveStatus"
filterRowCallback: (sourceRow, sourceParent) => {
let value = sourceModel.data(sourceModel.index(sourceRow, 0, sourceParent), filterRole);
return value === PlasmaCore.Types.ActiveStatus;
}
}
delegate: ItemLoader {
id: delegate
width: tasksGrid.cellWidth
height: tasksGrid.cellHeight
minLabelHeight: 0
// We need to recalculate the stacking order of the z values due to how keyboard navigation works
// the tab order depends exclusively from this, so we redo it as the position in the list
// ensuring tab navigation focuses the expected items
Component.onCompleted: {
let item = tasksGrid.itemAtIndex(index - 1);
if (item) {
Plasmoid.stackItemBefore(delegate, item)
} else {
item = tasksGrid.itemAtIndex(index + 1);
}
if (item) {
Plasmoid.stackItemAfter(delegate, item)
}
}
}
add: Transition {
enabled: itemSize > 0 && Component.status == Component.Ready
NumberAnimation {
property: "scale"
from: 0
to: 1
easing.type: Easing.InOutQuad
duration: Kirigami.Units.longDuration
}
}
displaced: Transition {
//ensure scale value returns to 1.0
//https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html#handling-interrupted-animations
enabled: Component.status == Component.Ready
NumberAnimation {
property: "scale"
to: 1
easing.type: Easing.InOutQuad
duration: Kirigami.Units.longDuration
}
}
move: Transition {
NumberAnimation {
properties: "x,y"
easing.type: Easing.InOutQuad
duration: Kirigami.Units.longDuration
}
}
}
}
Timer {
id: expandedSync
interval: 100
onTriggered: systemTrayState.expanded = dialog.visible;
}
//Main popup
PlasmaCore.Dialog {
id: dialog
objectName: "popupWindow"
//visualParent: root
flags: Qt.WindowStaysOnTopHint
/*popupDirection: switch (Plasmoid.location) {
case PlasmaCore.Types.TopEdge:
return Qt.BottomEdge
case PlasmaCore.Types.LeftEdge:
return Qt.RightEdge
case PlasmaCore.Types.RightEdge:
return Qt.LeftEdge
default:
return Qt.TopEdge
}
//margin: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing/2 //(Plasmoid.containmentDisplayHints & PlasmaCore.Types.ContainmentPrefersFloatingApplets) ? Kirigami.Units.largeSpacing :
animated: false*/
//floating: true //Plasmoid.location == PlasmaCore.Desktop
//location: PlasmaCore.Dialog.Floating
location: "Floating"//Plasmoid.location
x: 0
y: 0
//floating: 1
property int flyoutMargin: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing/2
property bool firstTimePopup: false
/*removeBorderStrategy: PlasmaCore.AppletPopup.Never */ /*Plasmoid.location === PlasmaCore.Types.Floating
? PlasmaCore.AppletPopup.AtScreenEdges
: PlasmaCore.AppletPopup.AtScreenEdges | PlasmaCore.AppletPopup.AtPanelEdges*/
/*minimumWidth: expandedRepresentation.flyoutWidth
maximumWidth: minimumWidth*/
/*minimumHeight: expandedRepresentation.flyoutHeight
maximumHeight: expandedRepresentation.flyoutHeight*/
hideOnWindowDeactivate: !Plasmoid.configuration.pin
visible: systemTrayState.expanded
appletInterface: root
//flags: Qt.Dialog | Qt.FramelessWindowHint
backgroundHints: PlasmaCore.Dialog.SolidBackground //(Plasmoid.containmentDisplayHints & PlasmaCore.Types.ContainmentPrefersOpaqueBackground) ? PlasmaCore.AppletPopup.SolidBackground : PlasmaCore.AppletPopup.StandardBackground
onWidthChanged: setDialogPosition();
onHeightChanged: setDialogPosition();
function setDialogPosition() {
var pos = root.mapToGlobal(root.x, root.y);
pos = root.mapToGlobal(currentHighlight.x, currentHighlight.y);
var availScreen = Plasmoid.containment.availableScreenRect;
x = pos.x - width / 2 + (expandedRepresentation.hiddenLayout.visible ? flyoutMargin + Kirigami.Units.smallSpacing/2 : currentHighlight.width / 2);
y = pos.y - height;
if(x <= 0) x += flyoutMargin;
if(x + dialog.width >= availScreen.width) {
x = availScreen.width - dialog.width - flyoutMargin;
}
if(y <= 0) y += flyoutMargin;
if(y + dialog.height >= availScreen.height) {
y = availScreen.height - dialog.height - flyoutMargin;
}
/*if(root.vertical) {
if(pos.x > dialog.x) dialog.x -= flyoutMargin;
else dialog.x += flyoutMargin;
} else {
if(pos.y > dialog.y) dialog.y -= flyoutMargin;
else dialog.y += flyoutMargin;
}*/
}
onYChanged: {
if(!firstTimePopup) { setDialogPosition(); }
firstTimePopup = true;
}
onVisibleChanged: {
if(visible) {
setDialogPosition();
}
if (!visible) {
expandedSync.restart();
} else {
if (expandedRepresentation.plasmoidContainer.visible) {
expandedRepresentation.plasmoidContainer.forceActiveFocus();
} else if (expandedRepresentation.hiddenLayout.visible) {
expandedRepresentation.hiddenLayout.forceActiveFocus();
}
}
}
mainItem: ExpandedRepresentation {
id: expandedRepresentation
Keys.onEscapePressed: {
systemTrayState.expanded = false
}
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
LayoutMirroring.childrenInherit: true
}
}
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 150 KiB