Warning, /plasma/plasma-desktop/applets/taskmanager/package/contents/ui/GroupDialog.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2012-2013 Eike Hein <hein@kde.org> 0003 SPDX-FileCopyrightText: 2021 Fushan Wen <qydwhotmail@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 import QtQuick 2.15 0009 // Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6. 0010 import QtQml 2.15 0011 import QtQml.Models 2.15 0012 import QtQuick.Window 2.15 0013 0014 import org.kde.plasma.core as PlasmaCore 0015 import org.kde.plasma.components 3.0 as PlasmaComponents3 0016 import org.kde.draganddrop 2.0 0017 import org.kde.kirigami 2.20 as Kirigami 0018 import org.kde.plasma.plasmoid 2.0 0019 0020 import "code/layout.js" as LayoutManager 0021 0022 PlasmaCore.Dialog { 0023 id: groupDialog 0024 visible: true 0025 0026 type: PlasmaCore.Dialog.PopupMenu 0027 flags: Qt.WindowStaysOnTopHint 0028 hideOnWindowDeactivate: true 0029 location: Plasmoid.location 0030 0031 readonly property real preferredWidth: Screen.width / (3 * Screen.devicePixelRatio) 0032 readonly property real preferredHeight: Screen.height / (2 * Screen.devicePixelRatio) 0033 readonly property real contentWidth: mainItem.width // No padding here to avoid text elide. 0034 0035 property alias overflowing: scrollView.overflowing 0036 property var _oldAppletStatus: PlasmaCore.Types.UnknownStatus 0037 0038 function findActiveTaskIndex() { 0039 if (!tasksModel.activeTask) { 0040 return; 0041 } 0042 for (let i = 0; i < groupListView.count; i++) { 0043 if (tasksModel.makeModelIndex(visualParent.index, i) === tasksModel.activeTask) { 0044 groupListView.positionViewAtIndex(i, ListView.Contain); // Prevent visual glitches 0045 groupListView.currentIndex = i; 0046 return; 0047 } 0048 } 0049 } 0050 0051 mainItem: MouseHandler { 0052 id: mouseHandler 0053 width: Math.min(groupDialog.preferredWidth, Math.max(groupListView.maxWidth, groupDialog.visualParent.width)) 0054 height: Math.min(groupDialog.preferredHeight, groupListView.maxHeight) 0055 0056 target: groupListView 0057 handleWheelEvents: !scrollView.overflowing 0058 isGroupDialog: true 0059 0060 Keys.onEscapePressed: groupDialog.visible = false 0061 0062 function moveRow(event, insertAt) { 0063 if (!(event.modifiers & Qt.ControlModifier) || !(event.modifiers & Qt.ShiftModifier)) { 0064 event.accepted = false; 0065 return; 0066 } else if (insertAt < 0 || insertAt >= groupListView.count) { 0067 return; 0068 } 0069 0070 const parentModelIndex = tasksModel.makeModelIndex(groupDialog.visualParent.index); 0071 const status = tasksModel.move(groupListView.currentIndex, insertAt, parentModelIndex); 0072 if (!status) { 0073 return; 0074 } 0075 0076 groupListView.currentIndex = insertAt; 0077 } 0078 0079 PlasmaComponents3.ScrollView { 0080 id: scrollView 0081 anchors.fill: parent 0082 readonly property bool overflowing: leftPadding > 0 || rightPadding > 0 // Scrollbar is visible 0083 0084 ListView { 0085 id: groupListView 0086 0087 readonly property real maxWidth: groupFilter.maxTextWidth 0088 + LayoutManager.horizontalMargins() 0089 + Kirigami.Units.iconSizes.medium 0090 + 2 * (LayoutManager.labelMargin + LayoutManager.iconMargin) 0091 + scrollView.leftPadding + scrollView.rightPadding 0092 // Use groupFilter.count because sometimes count is not updated in time (BUG 446105) 0093 readonly property real maxHeight: groupFilter.count * (LayoutManager.verticalMargins() + Math.max(Kirigami.Units.iconSizes.sizeForLabels, Kirigami.Units.iconSizes.medium)) 0094 0095 model: DelegateModel { 0096 id: groupFilter 0097 0098 readonly property TextMetrics textMetrics: TextMetrics {} 0099 property real maxTextWidth: 0 0100 0101 model: tasksModel 0102 rootIndex: tasksModel.makeModelIndex(groupDialog.visualParent.index) 0103 delegate: Task { 0104 width: groupListView.width 0105 visible: true 0106 inPopup: true 0107 0108 ListView.onRemove: Qt.callLater(groupFilter.updateMaxTextWidth) 0109 Connections { 0110 enabled: index < 20 // 20 is based on performance considerations. 0111 0112 function onLabelTextChanged() { // ListView.onAdd included 0113 if (groupFilter.maxTextWidth === 0) { 0114 // Update immediately to avoid shrinking 0115 groupFilter.updateMaxTextWidth(); 0116 } else { 0117 Qt.callLater(groupFilter.updateMaxTextWidth); 0118 } 0119 } 0120 } 0121 } 0122 0123 function updateMaxTextWidth() { 0124 let tempMaxTextWidth = 0; 0125 // 20 is based on performance considerations. 0126 for (let i = 0; i < Math.min(count, 20); i++) { 0127 textMetrics.text = items.get(i).model.display; 0128 if (textMetrics.boundingRect.width > tempMaxTextWidth) { 0129 tempMaxTextWidth = textMetrics.boundingRect.width; 0130 } 0131 } 0132 maxTextWidth = tempMaxTextWidth; 0133 } 0134 } 0135 0136 reuseItems: false 0137 0138 Keys.onUpPressed: mouseHandler.moveRow(event, groupListView.currentIndex - 1); 0139 Keys.onDownPressed: mouseHandler.moveRow(event, groupListView.currentIndex + 1); 0140 0141 onCountChanged: { 0142 if (count > 0) { 0143 backend.cancelHighlightWindows() 0144 } else { 0145 groupDialog.visible = false; 0146 } 0147 } 0148 } 0149 } 0150 } 0151 0152 onVisibleChanged: { 0153 if (visible) { 0154 _oldAppletStatus = Plasmoid.status; 0155 Plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus; 0156 0157 groupDialog.requestActivate(); 0158 groupListView.forceActiveFocus(); // Active focus on ListView so keyboard navigation can work. 0159 Qt.callLater(findActiveTaskIndex); 0160 } else { 0161 Plasmoid.status = _oldAppletStatus; 0162 tasks.groupDialog = null; 0163 destroy(); 0164 } 0165 } 0166 }