File indexing completed on 2025-01-26 05:06:18
0001 /* 0002 SPDX-FileCopyrightText: 2012-2016 Eike Hein <hein@kde.org> 0003 SPDX-FileCopyrightText: 2020 Nate Graham <nate@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 .pragma library 0009 0010 .import org.kde.taskmanager 0.1 as TaskManager 0011 .import org.kde.plasma.core as PlasmaCore // Needed by TaskManager 0012 0013 var windowViewAvailable = false; 0014 var taskManagerInstanceCount = 0; 0015 0016 function activateNextPrevTask(anchor, next, wheelSkipMinimized, tasks) { 0017 // FIXME TODO: Unnecessarily convoluted and costly; optimize. 0018 0019 var taskIndexList = []; 0020 var activeTaskIndex = tasks.tasksModel.activeTask; 0021 0022 for (var i = 0; i < tasks.taskList.children.length - 1; ++i) { 0023 var task = tasks.taskList.children[i]; 0024 var modelIndex = task.modelIndex(i); 0025 0026 if (!task.model.IsLauncher && !task.model.IsStartup) { 0027 if (task.model.IsGroupParent) { 0028 if (task == anchor) { // If the anchor is a group parent, collect only windows within the group. 0029 taskIndexList = []; 0030 } 0031 0032 for (var j = 0; j < tasks.tasksModel.rowCount(modelIndex); ++j) { 0033 const childModelIndex = tasks.tasksModel.makeModelIndex(i, j); 0034 const childHidden = tasks.tasksModel.data(childModelIndex, TaskManager.AbstractTasksModel.IsHidden); 0035 if (!wheelSkipMinimized || !childHidden) { 0036 taskIndexList.push(childModelIndex); 0037 } 0038 } 0039 0040 if (task == anchor) { // See above. 0041 break; 0042 } 0043 } else { 0044 if (!wheelSkipMinimized || !task.model.IsHidden) { 0045 taskIndexList.push(modelIndex); 0046 } 0047 } 0048 } 0049 } 0050 0051 if (!taskIndexList.length) { 0052 return; 0053 } 0054 0055 var target = taskIndexList[0]; 0056 0057 for (var i = 0; i < taskIndexList.length; ++i) { 0058 if (taskIndexList[i] === activeTaskIndex) 0059 { 0060 if (next && i < (taskIndexList.length - 1)) { 0061 target = taskIndexList[i + 1]; 0062 } else if (!next) { 0063 if (i) { 0064 target = taskIndexList[i - 1]; 0065 } else { 0066 target = taskIndexList[taskIndexList.length - 1]; 0067 } 0068 } 0069 0070 break; 0071 } 0072 } 0073 0074 tasks.tasksModel.requestActivate(target); 0075 } 0076 0077 function activateTask(index, model, modifiers, task, plasmoid, tasks) { 0078 if (modifiers & Qt.ShiftModifier) { 0079 tasks.tasksModel.requestNewInstance(index); 0080 return; 0081 } 0082 // Publish delegate geometry again if there are more than one task manager instance 0083 if (taskManagerInstanceCount >= 2) { 0084 tasks.tasksModel.requestPublishDelegateGeometry(task.modelIndex(), tasks.backend.globalRect(task), task); 0085 } 0086 0087 if (model.IsGroupParent) { 0088 // Option 1 (default): Cycle through this group's tasks 0089 // ==================================================== 0090 // If the grouped task does not include the currently active task, bring 0091 // forward the most recently used task in the group according to the 0092 // Stacking order. 0093 // Otherwise cycle through all tasks in the group without paying attention 0094 // to the stacking order, which otherwise would change with every click 0095 if (plasmoid.configuration.groupedTaskVisualization === 0) { 0096 let childTaskList = []; 0097 let highestStacking = -1; 0098 let lastUsedTask = undefined; 0099 0100 // Build list of child tasks and get stacking order data for them 0101 for (let i = 0; i < tasks.tasksModel.rowCount(task.modelIndex(index)); ++i) { 0102 const childTaskModelIndex = tasks.tasksModel.makeModelIndex(task.index, i); 0103 childTaskList.push(childTaskModelIndex); 0104 const stacking = tasks.tasksModel.data(childTaskModelIndex, TaskManager.AbstractTasksModel.StackingOrder); 0105 if (stacking > highestStacking) { 0106 highestStacking = stacking; 0107 lastUsedTask = childTaskModelIndex; 0108 } 0109 } 0110 0111 // If the active task is from a different app from the group that 0112 // was clicked on switch to the last-used task from that app. 0113 if (!childTaskList.some(index => tasks.tasksModel.data(index, TaskManager.AbstractTasksModel.IsActive))) { 0114 tasks.tasksModel.requestActivate(lastUsedTask); 0115 } else { 0116 // If the active task is already among in the group that was 0117 // activated, cycle through all tasks according to the order of 0118 // the immutable model index so the order doesn't change with 0119 // every click. 0120 for (let j = 0; j < childTaskList.length; ++j) { 0121 const childTask = childTaskList[j]; 0122 if (tasks.tasksModel.data(childTask, TaskManager.AbstractTasksModel.IsActive)) { 0123 // Found the current task. Activate the next one 0124 let nextTask = j + 1; 0125 if (nextTask >= childTaskList.length) { 0126 nextTask = 0; 0127 } 0128 tasks.tasksModel.requestActivate(childTaskList[nextTask]); 0129 break; 0130 } 0131 } 0132 } 0133 } 0134 0135 // Option 2: show tooltips for all child tasks 0136 // =========================================== 0137 else if (plasmoid.configuration.groupedTaskVisualization === 1) { 0138 if (tasks.toolTipOpenedByClick) { 0139 task.hideImmediately(); 0140 } else { 0141 tasks.toolTipOpenedByClick = task; 0142 task.updateMainItemBindings(); // BUG 452187 0143 task.showToolTip(); 0144 } 0145 } 0146 0147 // Option 3: show Window View for all child tasks 0148 // ================================================== 0149 // Make sure the Window View effect is are actually enabled though; 0150 // if not, fall through to the next option. 0151 else if (plasmoid.configuration.groupedTaskVisualization === 2 && windowViewAvailable) { 0152 task.hideToolTip(); 0153 tasks.activateWindowView(model.WinIdList); 0154 } 0155 0156 // Option 4: show group dialog/textual list 0157 // ======================================== 0158 // This is also the final fallback option if Window View 0159 // is chosen but not actually available 0160 else { 0161 if (!!tasks.groupDialog) { 0162 task.hideToolTip(); 0163 tasks.groupDialog.visible = false; 0164 } else { 0165 createGroupDialog(task, tasks); 0166 } 0167 } 0168 } else { 0169 if (model.IsMinimized) { 0170 tasks.tasksModel.requestToggleMinimized(index); 0171 tasks.tasksModel.requestActivate(index); 0172 } else if (model.IsActive && plasmoid.configuration.minimizeActiveTaskOnClick) { 0173 tasks.tasksModel.requestToggleMinimized(index); 0174 } else { 0175 tasks.tasksModel.requestActivate(index); 0176 } 0177 } 0178 } 0179 0180 function taskPrefix(prefix, location) { 0181 var effectivePrefix; 0182 0183 switch (location) { 0184 case PlasmaCore.Types.LeftEdge: 0185 effectivePrefix = "west-" + prefix; 0186 break; 0187 case PlasmaCore.Types.TopEdge: 0188 effectivePrefix = "north-" + prefix; 0189 break; 0190 case PlasmaCore.Types.RightEdge: 0191 effectivePrefix = "east-" + prefix; 0192 break; 0193 default: 0194 effectivePrefix = "south-" + prefix; 0195 } 0196 return [effectivePrefix, prefix]; 0197 } 0198 0199 function taskPrefixHovered(prefix, location) { 0200 return [ 0201 ...taskPrefix((prefix || "launcher") + "-hover", location), 0202 ...prefix ? taskPrefix("hover", location) : [], 0203 ...taskPrefix(prefix, location) 0204 ]; 0205 } 0206 0207 function createGroupDialog(visualParent, tasks) { 0208 if (!visualParent) { 0209 return; 0210 } 0211 0212 if (!!tasks.groupDialog) { 0213 tasks.groupDialog.visualParent = visualParent; 0214 return; 0215 } 0216 0217 tasks.groupDialog = tasks.groupDialogComponent.createObject(tasks, 0218 { 0219 visualParent: visualParent, 0220 } 0221 ); 0222 }