Warning, /plasma/plasma-desktop/applets/taskmanager/package/contents/ui/MouseHandler.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2012-2016 Eike Hein <hein@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 import QtQuick
0008 
0009 import org.kde.taskmanager 0.1 as TaskManager
0010 import org.kde.plasma.plasmoid 2.0
0011 
0012 import "code/tools.js" as TaskTools
0013 
0014 DropArea {
0015     id: dropArea
0016     signal urlsDropped(var urls)
0017 
0018     property Item target
0019     property Item ignoredItem
0020     property Item hoveredItem
0021     property bool isGroupDialog: false
0022     property bool moved: false
0023 
0024     property alias handleWheelEvents: wheelHandler.handleWheelEvents
0025 
0026     function insertIndexAt(above, x, y) {
0027         if (above) {
0028             return above.index;
0029         } else {
0030             var distance = tasks.vertical ? x : y;
0031             var step = tasks.vertical ? LayoutManager.taskWidth() : LayoutManager.taskHeight();
0032             var stripe = Math.ceil(distance / step);
0033 
0034             if (stripe === LayoutManager.calculateStripes()) {
0035                 return tasks.tasksModel.count - 1;
0036             } else {
0037                 return stripe * LayoutManager.tasksPerStripe();
0038             }
0039         }
0040     }
0041 
0042     //ignore anything that is neither internal to TaskManager or a URL list
0043     onEntered: event => {
0044         if (event.formats.indexOf("text/x-plasmoidservicename") >= 0) {
0045             event.accepted = false;
0046         }
0047     }
0048 
0049     onPositionChanged: event => {
0050         if (target.animating) {
0051             return;
0052         }
0053 
0054         let above;
0055         if (isGroupDialog) {
0056             above = target.itemAt(event.x, event.y);
0057         } else {
0058             above = target.childAt(event.x, event.y);
0059         }
0060 
0061         if (!above) {
0062             hoveredItem = null;
0063             activationTimer.stop();
0064 
0065             return;
0066         }
0067 
0068         // If we're mixing launcher tasks with other tasks and are moving
0069         // a (small) launcher task across a non-launcher task, don't allow
0070         // the latter to be the move target twice in a row for a while, as
0071         // it will naturally be moved underneath the cursor as result of the
0072         // initial move, due to being far larger than the launcher delegate.
0073         // TODO: This restriction (minus the timer, which improves things)
0074         // has been proven out in the EITM fork, but could be improved later
0075         // by tracking the cursor movement vector and allowing the drag if
0076         // the movement direction has reversed, establishing user intent to
0077         // move back.
0078         if (!Plasmoid.configuration.separateLaunchers && tasks.dragSource != null
0079                 && tasks.dragSource.model.IsLauncher && !above.model.IsLauncher
0080                 && above === ignoredItem) {
0081             return;
0082         } else {
0083             ignoredItem = null;
0084         }
0085 
0086         if (tasksModel.sortMode === TaskManager.TasksModel.SortManual && tasks.dragSource) {
0087             // Reject drags between different TaskList instances.
0088             if (tasks.dragSource.parent !== above.parent) {
0089                 return;
0090             }
0091 
0092             var insertAt = insertIndexAt(above, event.x, event.y);
0093 
0094             if (tasks.dragSource !== above && tasks.dragSource.index !== insertAt) {
0095                 if (!!tasks.groupDialog) {
0096                     tasksModel.move(tasks.dragSource.index, insertAt,
0097                         tasksModel.makeModelIndex(tasks.groupDialog.visualParent.index));
0098                 } else {
0099                     tasksModel.move(tasks.dragSource.index, insertAt);
0100                 }
0101 
0102                 ignoredItem = above;
0103                 ignoreItemTimer.restart();
0104             }
0105         } else if (!tasks.dragSource && hoveredItem !== above) {
0106             hoveredItem = above;
0107             activationTimer.restart();
0108         }
0109     }
0110 
0111     onExited: {
0112         hoveredItem = null;
0113         activationTimer.stop();
0114     }
0115 
0116     onDropped: event => {
0117         // Reject internal drops.
0118         if (event.formats.indexOf("application/x-orgkdeplasmataskmanager_taskbuttonitem") >= 0) {
0119             event.accepted = false;
0120             return;
0121         }
0122 
0123         // Reject plasmoid drops.
0124         if (event.formats.indexOf("text/x-plasmoidservicename") >= 0) {
0125             event.accepted = false;
0126             return;
0127         }
0128 
0129         if (event.hasUrls) {
0130             urlsDropped(event.urls);
0131             return;
0132         }
0133     }
0134 
0135     Connections {
0136         target: tasks
0137 
0138         function onDragSourceChanged() {
0139             if (!dragSource) {
0140                 ignoredItem = null;
0141                 ignoreItemTimer.stop();
0142             }
0143         }
0144     }
0145 
0146     Timer {
0147         id: ignoreItemTimer
0148 
0149         repeat: false
0150         interval: 750
0151 
0152         onTriggered: {
0153             ignoredItem = null;
0154         }
0155     }
0156 
0157     Timer {
0158         id: activationTimer
0159 
0160         interval: 250
0161         repeat: false
0162 
0163         onTriggered: {
0164             if (parent.hoveredItem.model.IsGroupParent) {
0165                 TaskTools.createGroupDialog(parent.hoveredItem, tasks);
0166             } else if (!parent.hoveredItem.model.IsLauncher) {
0167                 tasksModel.requestActivate(parent.hoveredItem.modelIndex());
0168             }
0169         }
0170     }
0171 
0172     WheelHandler {
0173         id: wheelHandler
0174 
0175         acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
0176 
0177         property bool handleWheelEvents: true
0178 
0179         enabled: handleWheelEvents && Plasmoid.configuration.wheelEnabled
0180 
0181         onWheel: event => {
0182             // magic number 15 for common "one scroll"
0183             // See https://doc.qt.io/qt-6/qml-qtquick-wheelhandler.html#rotation-prop
0184             let increment = 0;
0185             while (rotation >= 15) {
0186                 rotation -= 15;
0187                 increment++;
0188             }
0189             while (rotation <= -15) {
0190                 rotation += 15;
0191                 increment--;
0192             }
0193             const anchor = dropArea.target.childAt(event.x, event.y);
0194             while (increment !== 0) {
0195                 TaskTools.activateNextPrevTask(anchor, increment < 0, Plasmoid.configuration.wheelSkipMinimized, tasks);
0196                 increment += (increment < 0) ? 1 : -1;
0197             }
0198         }
0199     }
0200 }