/*SPDX-FileCopyrightText: 2016 Eike Hein <hein@kde.org>SPDX-FileCopyrightText: 2022 Carson Black <uhhadd@gmail.com>SPDX-License-Identifier: GPL-2.0-or-later*/pragma ComponentBehavior: Boundimport QtQuickimport QtQuick.Layoutsimport org.kde.plasma.plasmoidimport org.kde.plasma.core as PlasmaCoreimport org.kde.plasma.components as PlasmaComponentsimport org.kde.plasma.extras as PlasmaExtrasimport org.kde.kirigami as Kirigamiimport org.kde.taskmanager as TaskManagerPlasmoidItem {id: rootPlasmoid.constraintHints: Plasmoid.CanFillAreacompactRepresentation: windowListButtonfullRepresentation: windowListswitchWidth: Kirigami.Units.gridUnit * 8switchHeight: Kirigami.Units.gridUnit * 6TaskManager.VirtualDesktopInfo {id: virtualDesktopInfo}TaskManager.ActivityInfo {id: activityInforeadonly property string nullUuid: "00000000-0000-0000-0000-000000000000"}TaskManager.TasksModel {id: tasksModelvirtualDesktop: virtualDesktopInfo.currentDesktopscreenGeometry: Plasmoid.containment.screenGeometryactivity: activityInfo.currentActivitysortMode: TaskManager.TasksModel.SortVirtualDesktopgroupMode: TaskManager.TasksModel.GroupDisabledfilterByVirtualDesktop: Plasmoid.configuration.showOnlyCurrentDesktopfilterByScreen: Plasmoid.configuration.showOnlyCurrentScreenfilterByActivity: Plasmoid.configuration.showOnlyCurrentActivityfilterNotMinimized: Plasmoid.configuration.showOnlyMinimized}Component {id: windowListListView {id: windowListViewclip: trueLayout.preferredWidth: Kirigami.Units.gridUnit * 10Layout.preferredHeight: Kirigami.Units.gridUnit * 12model: tasksModelConnections {target: rootfunction onExpandedChanged(expanded) {if (expanded) {windowListView.currentIndex = -1}}}// focus is needed to receive key events on desktop containment works in panel without this.focus: truekeyNavigationWraps: truehighlight: PlasmaExtras.Highlight {visible: windowListView.currentItemactive: windowListView.focuspressed: windowListView.currentItem && windowListView.currentItem.pressed}highlightMoveDuration: 0highlightResizeDuration: 0Keys.onEnterPressed: {if (currentIndex >= 0 && currentIndex < windowListView.count) {tasksModel.requestActivate(tasksModel.makeModelIndex(currentIndex));}}Keys.onReturnPressed: {if (currentIndex >= 0 && currentIndex < windowListView.count) {tasksModel.requestActivate(tasksModel.makeModelIndex(currentIndex));}}Keys.onTabPressed: {incrementCurrentIndex();}Keys.onBacktabPressed: {decrementCurrentIndex();}delegate: PlasmaComponents.ItemDelegate {id: delegaterequired property var modelrequired property var decorationwidth: ListView.view.widthhighlighted: ListView.isCurrentItemcontentItem: RowLayout {spacing: Kirigami.Units.smallSpacingKirigami.Icon {id: iconItemsource: delegate.decorationvisible: source !== "" && iconItem.validimplicitWidth: Kirigami.Units.iconSizes.sizeForLabelsimplicitHeight: Kirigami.Units.iconSizes.sizeForLabels}// Fall back to a generic icon if the application doesn't provide a valid oneKirigami.Icon {source: "preferences-system-windows"visible: !iconItem.validimplicitWidth: Kirigami.Units.iconSizes.sizeForLabelsimplicitHeight: Kirigami.Units.iconSizes.sizeForLabels}PlasmaComponents.Label {Layout.fillWidth: truetext: delegate.model.displaytextFormat: Text.PlainTextelide: Text.ElideRight}}onHoveredChanged: {if (hovered) {windowListView.currentIndex = model.index}}onClicked: {windowListView.currentIndex = model.indextasksModel.requestActivate(tasksModel.makeModelIndex(model.index))}}Kirigami.PlaceholderMessage {anchors.centerIn: parentwidth: parent.width - (Kirigami.Units.largeSpacing * 2)visible: windowListView.count === 0icon.source: "edit-none"text: i18nc("@info:placeholder", "No open windows")}}}// Only exists because the default CompactRepresentation doesn't expose the// ability to show text below or beside the icon.// TODO remove once it gains that feature.Component {id: windowListButtonMenuButton {id: menuButtonLayout.minimumWidth: implicitWidthLayout.maximumWidth: implicitWidthLayout.fillHeight: Plasmoid.formFactor === PlasmaCore.Types.HorizontalLayout.fillWidth: Plasmoid.formFactor === PlasmaCore.Types.VerticalonClicked: tasksMenu.openRelative()down: pressed || tasksMenu.status === PlasmaExtras.Menu.OpenAccessible.name: Plasmoid.titleAccessible.description: root.toolTipSubTexttext: if (tasksModel.activeTask.valid) {return tasksModel.data(tasksModel.activeTask, TaskManager.AbstractTasksModel.AppName) ||tasksModel.data(tasksModel.activeTask, 0 /* display name, window title if app name not present */)} else {return i18nc("@title:window title shown e.g. for desktop and expanded widgets", "Plasma Desktop")}iconSource: if (tasksModel.activeTask.valid) {return tasksModel.data(tasksModel.activeTask, 1 /* decorationrole */)} else {return "start-here-kde-symbolic"}PlasmaExtras.ModelContextMenu {id: tasksMenuvisualParent: menuButtonplacement: {if (Plasmoid.location === PlasmaCore.Types.LeftEdge) {return PlasmaExtras.Menu.RightPosedTopAlignedPopup} else if (Plasmoid.location === PlasmaCore.Types.TopEdge) {return PlasmaExtras.Menu.BottomPosedLeftAlignedPopup} else if (Plasmoid.location === PlasmaCore.Types.RightEdge) {return PlasmaExtras.Menu.LeftPosedTopAlignedPopup} else {return PlasmaExtras.Menu.TopPosedLeftAlignedPopup}}property ListModel noWindowModel: ListModel {ListElement {display: "" // filled by Component.onCompleteddecoration: "edit-none"}Component.onCompleted: tasksMenu.noWindowModel.setProperty(0, "display", i18nc("@info:placeholder", "No open windows"))}model: tasksModel.count === 0 ? noWindowModel : tasksModelonClicked: (model) => {if (tasksModel.count > 0) {tasksModel.requestActivate(tasksModel.makeModelIndex(model.index));}}}Timer {id: hoverOpenTimerinterval: Plasmoid?.configuration?.hoverOpenDelay ?? 300repeat: falseonTriggered: {if (tasksMenu?.status === PlasmaExtras.Menu.Closed) {tasksMenu.openRelative()}}}onHoveredChanged: {if (hovered && Plasmoid.configuration.openOnHover) {hoverOpenTimer.start()} else {hoverOpenTimer.stop()}}}}}