Warning, /plasma/latte-dock/plasmoid/package/contents/ui/main.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2016 Smith AR <audoban@openmailbox.org>
0003     SPDX-FileCopyrightText: 2016 Michail Vourlakos <mvourlakos@gmail.com>
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 import QtQuick 2.8
0008 import QtQuick.Layouts 1.1
0009 
0010 import QtGraphicalEffects 1.0
0011 
0012 import org.kde.plasma.core 2.0 as PlasmaCore
0013 import org.kde.plasma.components 2.0 as PlasmaComponents
0014 import org.kde.plasma.plasmoid 2.0
0015 
0016 import org.kde.taskmanager 0.1 as TaskManager
0017 import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet
0018 
0019 import org.kde.activities 0.1 as Activities
0020 
0021 import org.kde.latte.core 0.2 as LatteCore
0022 import org.kde.latte.components 1.0 as LatteComponents
0023 
0024 import org.kde.latte.private.tasks 0.1 as LatteTasks
0025 
0026 import "abilities" as Ability
0027 import "previews" as Previews
0028 import "task" as Task
0029 import "taskslayout" as TasksLayout
0030 import "../code/tools.js" as TaskTools
0031 import "../code/activitiesTools.js" as ActivitiesTools
0032 import "../code/ColorizerTools.js" as ColorizerTools
0033 
0034 Item {
0035     id:root
0036     Layout.fillWidth: scrollingEnabled && !root.vertical
0037     Layout.fillHeight: scrollingEnabled && root.vertical
0038 
0039     Layout.minimumWidth: inPlasma && root.isHorizontal ? minimumLength : -1
0040     Layout.minimumHeight: inPlasma && !root.isHorizontal ? minimumLength : -1
0041     Layout.preferredWidth: tasksWidth
0042     Layout.preferredHeight: tasksHeight
0043     Layout.maximumWidth: -1
0044     Layout.maximumHeight: -1
0045 
0046     LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft && !root.vertical
0047     LayoutMirroring.childrenInherit: true
0048 
0049     property bool plasma515: LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,15,0)
0050     property bool plasma518: LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,18,0)
0051     property bool plasma520: LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,20,0)
0052     property bool plasmaGreaterThan522: LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,21,75)
0053     property bool plasmaAtLeast524: LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,24,0)
0054     property bool plasmaAtLeast525: LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,24,75)
0055     property bool plasmaAtLeast526: LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,25,75)
0056 
0057     property bool disableRestoreZoom: false //blocks restore animation in rightClick
0058     property bool disableAllWindowsFunctionality: plasmoid.configuration.hideAllTasks
0059     property bool inActivityChange: false
0060     property bool inDraggingPhase: false
0061     property bool initializationStep: false //true
0062     property bool isHovered: false
0063     property bool showBarLine: plasmoid.configuration.showBarLine
0064     property bool useThemePanel: plasmoid.configuration.useThemePanel
0065     property bool taskInAnimation: noTasksInAnimation > 0 ? true : false
0066     property bool transparentPanel: plasmoid.configuration.transparentPanel
0067     property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical ? true : false
0068     property bool isHorizontal: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? true : false
0069 
0070     property bool hasTaskDemandingAttention: false
0071 
0072     property int clearWidth
0073     property int clearHeight
0074 
0075     property int newDroppedPosition: -1
0076     property int noTasksInAnimation: 0
0077     property int themePanelSize: plasmoid.configuration.panelSize
0078 
0079     property int location : {
0080         if (plasmoid.location === PlasmaCore.Types.LeftEdge
0081                 || plasmoid.location === PlasmaCore.Types.RightEdge
0082                 || plasmoid.location === PlasmaCore.Types.TopEdge) {
0083             return plasmoid.location;
0084         }
0085 
0086         return PlasmaCore.Types.BottomEdge;
0087     }
0088 
0089     ///Don't use Math.floor it adds one pixel in animations and creates glitches
0090     property int widthMargins: root.vertical ? appletAbilities.metrics.totals.thicknessEdges : appletAbilities.metrics.totals.lengthEdges
0091     property int heightMargins: !root.vertical ? appletAbilities.metrics.totals.thicknessEdges : appletAbilities.metrics.totals.lengthEdges
0092 
0093     property int internalWidthMargins: root.vertical ? appletAbilities.metrics.totals.thicknessEdges : appletAbilities.metrics.totals.lengthPaddings
0094     property int internalHeightMargins: !root.vertical ? appletAbilities.metrics.totals.thicknessEdges : appletAbilities.metrics.totals.lengthPaddings
0095 
0096     readonly property int minimumLength: inPlasma ? (root.isHorizontal ? tasksWidth : tasksHeight) : -1;
0097 
0098     property real textColorBrightness: ColorizerTools.colorBrightness(themeTextColor)
0099 
0100     property color themeTextColor: theme.textColor
0101     property color themeBackgroundColor: theme.backgroundColor
0102 
0103     property color lightTextColor: textColorBrightness > 127.5 ? themeTextColor : themeBackgroundColor
0104 
0105     //a small badgers record (id,value)
0106     //in order to track badgers when there are changes
0107     //in launcher reference from libtaskmanager
0108     property variant badgers:[]
0109     property variant launchersOnActivities: []
0110 
0111     //global plasmoid reference to the context menu
0112     property QtObject contextMenu: null
0113     property QtObject contextMenuComponent: Qt.createComponent("ContextMenu.qml");
0114     property Item dragSource: null
0115 
0116     property Item tasksExtendedManager: _tasksExtendedManager
0117     readonly property alias appletAbilities: _appletAbilities
0118 
0119     readonly property alias containsDrag: mouseHandler.containsDrag
0120 
0121     //! Animations
0122     readonly property bool launcherBouncingEnabled: appletAbilities.animations.active && plasmoid.configuration.animationLauncherBouncing
0123     readonly property bool newWindowSlidingEnabled: appletAbilities.animations.active && plasmoid.configuration.animationNewWindowSliding
0124     readonly property bool windowInAttentionEnabled: appletAbilities.animations.active && plasmoid.configuration.animationWindowInAttention
0125     readonly property bool windowAddedInGroupEnabled: appletAbilities.animations.active && plasmoid.configuration.animationWindowAddedInGroup
0126     readonly property bool windowRemovedFromGroupEnabled: appletAbilities.animations.active && plasmoid.configuration.animationWindowRemovedFromGroup
0127 
0128     readonly property bool hasHighThicknessAnimation: launcherBouncingEnabled || windowInAttentionEnabled || windowAddedInGroupEnabled
0129 
0130     //BEGIN properties
0131     property bool groupTasksByDefault: plasmoid.configuration.groupTasksByDefault
0132     property bool highlightWindows: hoverAction === LatteTasks.Types.HighlightWindows || hoverAction === LatteTasks.Types.PreviewAndHighlightWindows
0133 
0134     property bool scrollingEnabled: plasmoid.configuration.scrollTasksEnabled
0135     property bool autoScrollTasksEnabled: scrollingEnabled && plasmoid.configuration.autoScrollTasksEnabled
0136     property bool manualScrollTasksEnabled: scrollingEnabled &&  manualScrollTasksType !== LatteTasks.Types.ManualScrollDisabled
0137     property int manualScrollTasksType: plasmoid.configuration.manualScrollTasksType
0138 
0139     property bool showInfoBadge: plasmoid.configuration.showInfoBadge
0140     property bool showProgressBadge: plasmoid.configuration.showProgressBadge
0141     property bool showAudioBadge: plasmoid.configuration.showAudioBadge
0142     property bool infoBadgeProminentColorEnabled: plasmoid.configuration.infoBadgeProminentColorEnabled
0143     property bool audioBadgeActionsEnabled: plasmoid.configuration.audioBadgeActionsEnabled
0144     property bool showOnlyCurrentScreen: plasmoid.configuration.showOnlyCurrentScreen
0145     property bool showOnlyCurrentDesktop: plasmoid.configuration.showOnlyCurrentDesktop
0146     property bool showOnlyCurrentActivity: plasmoid.configuration.showOnlyCurrentActivity
0147     property bool showPreviews:  hoverAction === LatteTasks.Types.PreviewWindows || hoverAction === LatteTasks.Types.PreviewAndHighlightWindows
0148     property bool showWindowActions: plasmoid.configuration.showWindowActions && !disableAllWindowsFunctionality
0149     property bool showWindowsOnlyFromLaunchers: plasmoid.configuration.showWindowsOnlyFromLaunchers && !disableAllWindowsFunctionality
0150 
0151     property alias windowPreviewIsShown: windowsPreviewDlg.visible
0152 
0153     property int leftClickAction: plasmoid.configuration.leftClickAction
0154     property int middleClickAction: plasmoid.configuration.middleClickAction
0155     property int hoverAction: plasmoid.configuration.hoverAction
0156     property int modifier: plasmoid.configuration.modifier
0157     property int modifierClickAction: plasmoid.configuration.modifierClickAction
0158     property int modifierClick: plasmoid.configuration.modifierClick
0159     property int modifierQt:{
0160         if (modifier === LatteTasks.Types.Shift)
0161             return Qt.ShiftModifier;
0162         else if (modifier === LatteTasks.Types.Ctrl)
0163             return Qt.ControlModifier;
0164         else if (modifier === LatteTasks.Types.Alt)
0165             return Qt.AltModifier;
0166         else if (modifier === LatteTasks.Types.Meta)
0167             return Qt.MetaModifier;
0168         else return -1;
0169     }
0170     property int taskScrollAction: plasmoid.configuration.taskScrollAction
0171 
0172     onTaskScrollActionChanged: {
0173         if (taskScrollAction > LatteTasks.Types.ScrollToggleMinimized) {
0174             //! migrating scroll action to LatteTasks.Types.ScrollAction
0175             plasmoid.configuration.taskScrollAction = plasmoid.configuration.taskScrollAction-LatteTasks.Types.ScrollToggleMinimized;
0176         }
0177     }
0178 
0179     //! Real properties are need in order for parabolic effect to be 1px precise perfect.
0180     //! This way moving from Tasks to Applets and vice versa is pretty stable when hovering with parabolic effect.
0181     property real tasksHeight:  mouseHandler.height
0182     property real tasksWidth: mouseHandler.width
0183     property real tasksLength: root.vertical ? mouseHandler.height : mouseHandler.width
0184 
0185     readonly property int alignment: appletAbilities.containment.alignment
0186 
0187     property alias tasksCount: tasksModel.count
0188 
0189     //END Latte Dock Panel properties
0190 
0191     readonly property bool inEditMode: latteInEditMode || plasmoid.userConfiguring
0192 
0193     //BEGIN Latte Dock Communicator
0194     property QtObject latteBridge: null
0195 
0196     readonly property bool inPlasma: latteBridge === null
0197     readonly property bool inPlasmaDesktop: inPlasma && !inPlasmaPanel
0198     readonly property bool inPlasmaPanel: inPlasma && (plasmoid.location === PlasmaCore.Types.LeftEdge
0199                                                        || plasmoid.location === PlasmaCore.Types.RightEdge
0200                                                        || plasmoid.location === PlasmaCore.Types.BottomEdge
0201                                                        || plasmoid.location === PlasmaCore.Types.TopEdge)
0202     readonly property bool latteInEditMode: latteBridge && latteBridge.inEditMode
0203     //END  Latte Dock Communicator
0204 
0205     Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
0206     Plasmoid.backgroundHints: inPlasmaDesktop ? PlasmaCore.Types.StandardBackground : PlasmaCore.Types.NoBackground
0207 
0208     signal draggingFinished();
0209     signal hiddenTasksUpdated();
0210     signal presentWindows(variant winIds);
0211     signal activateWindowView(variant winIds);
0212     signal requestLayout;
0213     signal signalPreviewsShown();
0214     //signal signalDraggingState(bool value);
0215     signal showPreviewForTasks(QtObject group);
0216     //trigger updating scaling of neighbour delegates of zoomed delegate
0217     signal updateScale(int delegateIndex, real newScale, real step)
0218     signal publishTasksGeometries();
0219     signal windowsHovered(variant winIds, bool hovered)
0220 
0221 
0222     onScrollingEnabledChanged: {
0223         updateListViewParent();
0224     }
0225 
0226     Connections {
0227         target: plasmoid
0228         onLocationChanged: {
0229             iconGeometryTimer.start();
0230         }
0231     }
0232 
0233     Connections {
0234         target: plasmoid.configuration
0235 
0236         // onLaunchersChanged: tasksModel.launcherList = plasmoid.configuration.launchers
0237         onGroupingAppIdBlacklistChanged: tasksModel.groupingAppIdBlacklist = plasmoid.configuration.groupingAppIdBlacklist;
0238         onGroupingLauncherUrlBlacklistChanged: tasksModel.groupingLauncherUrlBlacklist = plasmoid.configuration.groupingLauncherUrlBlacklist;
0239     }
0240 
0241 
0242     Connections {
0243         target: appletAbilities.myView
0244         onIsHiddenChanged: {
0245             if (appletAbilities.myView.isHidden) {
0246                 windowsPreviewDlg.hide("3.3");
0247             }
0248         }
0249 
0250         onIsReadyChanged: {
0251             if (appletAbilities.myView.isReady) {
0252                 plasmoid.action("configure").visible = false;
0253                 plasmoid.configuration.isInLatteDock = true;
0254             }
0255         }
0256     }
0257 
0258     Binding {
0259         target: plasmoid
0260         property: "status"
0261         value: {
0262             var hastaskinattention = root.hasTaskDemandingAttention && tasksModel.anyTaskDemandsAttentionInValidTime;
0263             return (hastaskinattention || root.dragSource) ? PlasmaCore.Types.NeedsAttentionStatus : PlasmaCore.Types.PassiveStatus;
0264         }
0265     }
0266 
0267     Binding {
0268         target: root
0269         property: "hasTaskDemandingAttention"
0270         when: appletAbilities.indexer.isReady
0271         value: {
0272             for (var i=0; i<appletAbilities.indexer.layout.children.length; ++i){
0273                 var item = appletAbilities.indexer.layout.children[i];
0274                 if (item && item.isDemandingAttention) {
0275                     return true;
0276                 }
0277             }
0278 
0279             return false;
0280         }
0281     }
0282 
0283     /////
0284     PlasmaCore.ColorScope{
0285         id: colorScopePalette
0286     }
0287 
0288     ///UPDATE
0289     function updateListViewParent() {
0290         if (scrollingEnabled) {
0291             icList.parent = listViewBase;
0292         } else {
0293             icList.parent = barLine;
0294         }
0295     }
0296 
0297     function launcherExists(url) {
0298         return (ActivitiesTools.getIndex(url, tasksModel.launcherList)>=0);
0299     }
0300 
0301     function taskExists(url) {
0302         var tasks = icList.contentItem.children;
0303         for(var i=0; i<tasks.length; ++i){
0304             var task = tasks[i];
0305 
0306             if (task.launcherUrl===url && task.isWindow) {
0307                 return true;
0308             }
0309         }
0310         return false;
0311     }
0312 
0313 
0314     function forcePreviewsHiding(debug) {
0315         // console.log(" org.kde.latte   Tasks: Force hide previews event called: "+debug);
0316         windowsPreviewDlg.activeItem = null;
0317         windowsPreviewDlg.visible = false;
0318     }
0319 
0320     function hidePreview(){
0321         windowsPreviewDlg.hide(11);
0322     }
0323 
0324     onDragSourceChanged: {
0325         if (dragSource == null) {
0326             root.draggingFinished();
0327             tasksModel.syncLaunchers();
0328 
0329             restoreDraggingPhaseTimer.start();
0330         } else {
0331             inDraggingPhase = true;
0332         }
0333     }
0334 
0335     /////Window previews///////////
0336 
0337     Previews.ToolTipDelegate2 {
0338         id: toolTipDelegate
0339         visible: false
0340     }
0341 
0342     ////BEGIN interfaces
0343 
0344     LatteCore.Dialog{
0345         id: windowsPreviewDlg
0346         type: plasmoid.configuration.previewWindowAsPopup ? PlasmaCore.Dialog.PopupMenu : PlasmaCore.Dialog.Tooltip
0347         flags: plasmoid.configuration.previewWindowAsPopup ? Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.Popup :
0348                                                              Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.ToolTip
0349         location: root.location
0350         edge: root.location
0351         mainItem: toolTipDelegate
0352         visible: false
0353 
0354         property bool signalSent: false
0355         property Item activeItem: null
0356 
0357         Component.onCompleted: mainItem.visible = true;
0358 
0359         onContainsMouseChanged: {
0360             //! Orchestrate restore zoom and previews window hiding. Both should be
0361             //! triggered together.
0362             if (containsMouse) {
0363                 hidePreviewWinTimer.stop();
0364                 appletAbilities.parabolic.setDirectRenderingEnabled(false);
0365             } else {
0366                 hide(7.3);
0367             }
0368         }
0369 
0370         function hide(debug){
0371             //console.log("   Tasks: hide previews event called: "+debug);
0372             if (containsMouse || !visible) {
0373                 return;
0374             }
0375 
0376             if (appletAbilities.myView.isReady && signalSent) {
0377                 //it is used to unblock dock hiding
0378                 signalSent = false;
0379             }
0380 
0381             if (!root.contextMenu) {
0382                 root.disableRestoreZoom = false;
0383             }
0384 
0385             hidePreviewWinTimer.start();
0386         }
0387 
0388         function show(taskItem){
0389             if (root.disableAllWindowsFunctionality) {
0390                 return;
0391             }
0392 
0393             hidePreviewWinTimer.stop();
0394 
0395             // console.log("preview show called...");
0396             if ((!activeItem || (activeItem !== taskItem)) && !root.contextMenu) {
0397                 //console.log("preview show called: accepted...");
0398 
0399                 //this can be used from others to hide their appearance
0400                 //e.g but applets from the dock to hide themselves
0401                 if (!visible) {
0402                     root.signalPreviewsShown();
0403                 }
0404 
0405                 activeItem = taskItem;
0406                 toolTipDelegate.parentTask = taskItem;
0407 
0408                 if (appletAbilities.myView.isReady && !signalSent) {
0409                     //it is used to block dock hiding
0410                     signalSent = true;
0411                 }
0412 
0413                 //! Workaround in order to update properly the previews thumbnails
0414                 //! when switching between single thumbnail to another single thumbnail
0415                 //! maybe is not needed any more, let's disable it
0416                 //mainItem.visible = false;
0417                 visible = true;
0418                 //mainItem.visible = true;
0419             }
0420         }
0421     }
0422 
0423     //! Delay windows previews hiding
0424     Timer {
0425         id: hidePreviewWinTimer
0426         interval: 300
0427         onTriggered: {
0428             //! Orchestrate restore zoom and previews window hiding. Both should be
0429             //! triggered together.
0430             var contains = (windowsPreviewDlg.containsMouse
0431                             || (windowsPreviewDlg.activeItem && windowsPreviewDlg.activeItem.containsMouse) /*main task*/
0432                             || (windowsPreviewDlg.activeItem /*dragging file(s) from outside*/
0433                                 && mouseHandler.hoveredItem
0434                                 && !root.dragSource
0435                                 && mouseHandler.hoveredItem === windowsPreviewDlg.activeItem));
0436 
0437             if (!contains) {
0438                 root.forcePreviewsHiding(9.9);
0439             }
0440         }
0441     }
0442 
0443     //! Timer to fix #811, rare cases that both a window preview and context menu are
0444     //! shown. It is mostly used under wayland in order to avoid crashes. When the context
0445     //! menu will be shown there is a chance that previews window has already appeared in that
0446     //! case the previews window must become hidden
0447     Timer {
0448         id: windowsPreviewCheckerToNotShowTimer
0449         interval: 250
0450 
0451         onTriggered: {
0452             if (windowsPreviewDlg.visible && root.contextMenu) {
0453                 windowsPreviewDlg.hide("8.2");
0454             }
0455         }
0456     }
0457 
0458     //! Timer to delay the removal of the window through the context menu in case the
0459     //! the window is zoomed
0460     Timer{
0461         id: delayWindowRemovalTimer
0462         //this is the animation time needed in order for tasks to restore their zoom first
0463         interval: 7 * (appletAbilities.animations.speedFactor.current * appletAbilities.animations.duration.small)
0464 
0465         property var modelIndex
0466 
0467         onTriggered: {
0468             tasksModel.requestClose(delayWindowRemovalTimer.modelIndex)
0469 
0470             if (appletAbilities.debug.timersEnabled) {
0471                 console.log("plasmoid timer: delayWindowRemovalTimer called...");
0472             }
0473         }
0474     }
0475 
0476     Timer {
0477         id: activityChangeDelayer
0478         interval: 150
0479         onTriggered: {
0480             root.inActivityChange = false;
0481             root.publishTasksGeometries();
0482             activityInfo.previousActivity = activityInfo.currentActivity;
0483 
0484             if (appletAbilities.debug.timersEnabled) {
0485                 console.log("plasmoid timer: activityChangeDelayer called...");
0486             }
0487         }
0488     }
0489 
0490     /////Window Previews/////////
0491 
0492 
0493     TaskManager.TasksModel {
0494         id: tasksModel
0495 
0496         virtualDesktop: virtualDesktopInfo.currentDesktop
0497         screenGeometry: appletAbilities.myView.screenGeometry
0498         // comment in order to support LTS Plasma 5.8
0499         // screen: plasmoid.screen
0500         activity: appletAbilities.myView.isReady ? appletAbilities.myView.lastUsedActivity : activityInfo.currentActivity
0501 
0502         filterByVirtualDesktop: root.showOnlyCurrentDesktop
0503         filterByScreen: root.showOnlyCurrentScreen
0504         filterByActivity: root.showOnlyCurrentActivity
0505 
0506         launchInPlace: true
0507         separateLaunchers: true
0508         groupInline: false
0509 
0510         groupMode: groupTasksByDefault ? TaskManager.TasksModel.GroupApplications : TaskManager.TasksModel.GroupDisabled
0511         sortMode: TaskManager.TasksModel.SortManual
0512 
0513         property bool anyTaskDemandsAttentionInValidTime: false
0514 
0515         onActivityChanged: {
0516             ActivitiesTools.currentActivity = String(activity);
0517         }
0518 
0519         onGroupingAppIdBlacklistChanged: {
0520             plasmoid.configuration.groupingAppIdBlacklist = groupingAppIdBlacklist;
0521         }
0522 
0523         onGroupingLauncherUrlBlacklistChanged: {
0524             plasmoid.configuration.groupingLauncherUrlBlacklist = groupingLauncherUrlBlacklist;
0525         }
0526 
0527         onAnyTaskDemandsAttentionChanged: {
0528             anyTaskDemandsAttentionInValidTime = anyTaskDemandsAttention;
0529 
0530             if (anyTaskDemandsAttention){
0531                 attentionTimer.start();
0532             } else {
0533                 attentionTimer.stop();
0534             }
0535         }
0536 
0537         Component.onCompleted: {
0538             ActivitiesTools.launchersOnActivities = root.launchersOnActivities
0539             ActivitiesTools.currentActivity = String(activityInfo.currentActivity);
0540             ActivitiesTools.plasmoid = plasmoid;
0541 
0542             //var loadedLaunchers = ActivitiesTools.restoreLaunchers();
0543             ActivitiesTools.importLaunchersToNewArchitecture();
0544 
0545             appletAbilities.launchers.importLauncherListInModel();
0546 
0547             groupingAppIdBlacklist = plasmoid.configuration.groupingAppIdBlacklist;
0548             groupingLauncherUrlBlacklist = plasmoid.configuration.groupingLauncherUrlBlacklist;
0549 
0550             ///Plasma 5.9 enforce grouping at all cases
0551             if (LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,9,0)) {
0552                 groupingWindowTasksThreshold = -1;
0553             }
0554         }
0555     }
0556 
0557     //! TaskManagerBackend required a groupDialog setting otherwise it crashes. This patch
0558     //! sets one just in order not to crash TaskManagerBackend
0559     PlasmaCore.Dialog {
0560         //ghost group Dialog to not crash TaskManagerBackend
0561         id: groupDialogGhost
0562         visible: false
0563 
0564         type: PlasmaCore.Dialog.PopupMenu
0565         flags: Qt.WindowStaysOnTopHint
0566         hideOnWindowDeactivate: true
0567         location: root.location
0568     }
0569 
0570 
0571     TaskManagerApplet.Backend {
0572         id: backend
0573         taskManagerItem: root
0574         highlightWindows: root.highlightWindows
0575 
0576         onAddLauncher: {
0577             tasksModel.requestAddLauncher(url);
0578         }
0579 
0580         Component.onCompleted: {
0581             //! In Plasma 5.9 TaskManagerBackend required a groupDialog setting
0582             //! otherwise it crashes.
0583             //! frameworks 5.29.0 provide id 335104
0584             //! work only after Plasma 5.9 and frameworks 5.29
0585             //! + added a check for groupDialog also when it is present
0586             //!   in plasma 5.8 (that was introduced after 5.8.5)
0587             if (LatteCore.Environment.frameworksVersion >= 335104 || (groupDialog !== undefined)) {
0588                 groupDialog = groupDialogGhost;
0589             }
0590 
0591             //! In Plasma 5.22 toolTipItem was dropped
0592             if (!root.plasmaGreaterThan522) {
0593                 toolTipItem = toolTipDelegate;
0594             }
0595         }
0596     }
0597 
0598     Item {
0599         id: dragHelper
0600 
0601         Drag.dragType: Drag.Automatic
0602         Drag.supportedActions: Qt.CopyAction | Qt.MoveAction | Qt.LinkAction
0603         Drag.onDragFinished: root.dragSource = null;
0604     }
0605 
0606     TaskManager.VirtualDesktopInfo {
0607         id: virtualDesktopInfo
0608     }
0609 
0610     TaskManager.ActivityInfo {
0611         id: activityInfo
0612 
0613         property string previousActivity: ""
0614         onCurrentActivityChanged: {
0615             root.inActivityChange = true;
0616             activityChangeDelayer.start();
0617         }
0618 
0619         Component.onCompleted: previousActivity = currentActivity;
0620     }
0621 
0622     PlasmaCore.DataSource {
0623         id: mpris2Source
0624         engine: "mpris2"
0625         connectedSources: sources
0626         function sourceNameForLauncherUrl(launcherUrl, pid) {
0627             if (!launcherUrl || launcherUrl === "") {
0628                 return "";
0629             }
0630 
0631             // MPRIS spec explicitly mentions that "DesktopEntry" is with .desktop extension trimmed
0632             // Moreover, remove URL parameters, like wmClass (part after the question mark)
0633             var desktopFileName = launcherUrl.toString().split('/').pop().split('?')[0].replace(".desktop", "")
0634             if (desktopFileName.indexOf("applications:") === 0) {
0635                 desktopFileName = desktopFileName.substr(13)
0636             }
0637 
0638             for (var i = 0, length = connectedSources.length; i < length; ++i) {
0639                 var source = connectedSources[i];
0640                 // we intend to connect directly, otherwise the multiplexer steals the connection away
0641                 if (source === "@multiplex") {
0642                     continue;
0643                 }
0644 
0645                 var sourceData = data[source];
0646                 if (!sourceData) {
0647                     continue;
0648                 }
0649 
0650                 if (sourceData.DesktopEntry === desktopFileName || (pid && sourceData.InstancePid === pid)) {
0651                     return source;
0652                 }
0653 
0654                 var metadata = sourceData.Metadata;
0655                 if (metadata) {
0656                     var kdePid = metadata["kde:pid"];
0657                     if (kdePid && pid === kdePid) {
0658                         return source;
0659                     }
0660                 }
0661             }
0662 
0663             return ""
0664         }
0665 
0666         function startOperation(source, op) {
0667             var service = serviceForSource(source)
0668             var operation = service.operationDescription(op)
0669             return service.startOperationCall(operation)
0670         }
0671 
0672         function goPrevious(source) {
0673             startOperation(source, "Previous");
0674         }
0675         function goNext(source) {
0676             startOperation(source, "Next");
0677         }
0678         function play(source) {
0679             startOperation(source, "Play");
0680         }
0681         function pause(source) {
0682             startOperation(source, "Pause");
0683         }
0684         function playPause(source) {
0685             startOperation(source, "PlayPause");
0686         }
0687         function stop(source) {
0688             startOperation(source, "Stop");
0689         }
0690         function raise(source) {
0691             startOperation(source, "Raise");
0692         }
0693         function quit(source) {
0694             startOperation(source, "Quit");
0695         }
0696     }
0697 
0698     Loader {
0699         id: pulseAudio
0700         source: "PulseAudio.qml"
0701         active: root.showAudioBadge
0702     }
0703 
0704     TasksExtendedManager {
0705         id: _tasksExtendedManager
0706     }
0707 
0708     AppletAbilities {
0709         id: _appletAbilities
0710         bridge: latteBridge
0711         layout: icList.contentItem
0712         tasksModel: tasksModel
0713 
0714         animations.local.speedFactor.current: plasmoid.configuration.durationTime
0715         animations.local.requirements.zoomFactor: hasHighThicknessAnimation && LatteCore.WindowSystem.compositingActive ? 1.65 : 1.0
0716 
0717         indexer.updateIsBlocked: root.inDraggingPhase || root.inActivityChange || tasksExtendedManager.launchersInPausedStateCount>0
0718 
0719         indicators.local.isEnabled: !plasmoid.configuration.isInLatteDock
0720 
0721         launchers.group: plasmoid.configuration.launchersGroup
0722         launchers.isStealingDroppedLaunchers: plasmoid.configuration.isPreferredForDroppedLaunchers
0723         launchers.syncer.isBlocked: inDraggingPhase
0724 
0725         metrics.local.iconSize: inPlasmaDesktop ? maxIconSizeInPlasma : (inPlasmaPanel ? Math.max(16, panelThickness - metrics.margin.tailThickness - metrics.margin.headThickness) : maxIconSizeInPlasma)
0726         metrics.local.backgroundThickness: metrics.totals.thickness
0727         metrics.local.margin.length: 0.1 * metrics.iconSize
0728         metrics.local.margin.tailThickness: inPlasmaDesktop ? 0.16 * metrics.iconSize : Math.max(2, (panelThickness - maxIconSizeInPlasma) / 2)
0729         metrics.local.margin.headThickness: metrics.local.margin.tailThickness
0730         metrics.local.padding.length: 0.04 * metrics.iconSize
0731 
0732         myView.local.isHidingBlocked: root.contextMenu || root.windowPreviewIsShown
0733         myView.local.itemShadow.isEnabled: plasmoid.configuration.showShadows
0734         myView.local.itemShadow.size: Math.ceil(0.12*appletAbilities.metrics.iconSize)
0735 
0736         parabolic.local.isEnabled: (!root.inPlasma || root.inPlasmaDesktop) && parabolic.local.factor.zoom > 1.0
0737         parabolic.local.factor.zoom: parabolic.isEnabled ? ( 1 + (plasmoid.configuration.zoomLevel / 20) ) : 1.0
0738         parabolic.local.factor.maxZoom: parabolic.isEnabled ? Math.max(parabolic.local.factor.zoom, 1.6) : 1.0
0739         parabolic.local.restoreZoomIsBlocked: root.contextMenu || windowsPreviewDlg.containsMouse
0740 
0741         shortcuts.isStealingGlobalPositionShortcuts: plasmoid.configuration.isPreferredForPositionShortcuts
0742 
0743         requires.activeIndicatorEnabled: false
0744         requires.lengthMarginsEnabled: false
0745         requires.latteSideColoringEnabled: false
0746         requires.screenEdgeMarginSupported: true
0747 
0748         thinTooltip.local.showIsBlocked: root.contextMenu || root.windowPreviewIsShown
0749     }
0750 
0751     Timer{
0752         id: attentionTimer
0753         interval:8500
0754         onTriggered: {
0755             tasksModel.anyTaskDemandsAttentionInValidTime = false;
0756 
0757             if (appletAbilities.debug.timersEnabled) {
0758                 console.log("plasmoid timer: attentionTimer called...");
0759             }
0760         }
0761     }
0762 
0763     //this timer restores the draggingPhase flag to false
0764     //after a dragging has finished... This delay is needed
0765     //in order to not animate any tasks are added after a
0766     //dragging
0767     Timer {
0768         id: restoreDraggingPhaseTimer
0769         interval: 150
0770         onTriggered: inDraggingPhase = false;
0771     }
0772 
0773     ///Red Liner!!! show the upper needed limit for animations
0774     Rectangle{
0775         anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined
0776         anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined
0777 
0778         width: root.vertical ? 1 : 2 * appletAbilities.metrics.iconSize
0779         height: root.vertical ? 2 * appletAbilities.metrics.iconSize : 1
0780         color: "red"
0781         x: (root.location === PlasmaCore.Types.LeftEdge) ? neededSpace : parent.width - neededSpace
0782         y: (root.location === PlasmaCore.Types.TopEdge) ? neededSpace : parent.height - neededSpace
0783 
0784         visible: plasmoid.configuration.zoomHelper
0785 
0786         property int neededSpace: appletAbilities.parabolic.factor.zoom*appletAbilities.metrics.totals.length
0787     }
0788 
0789     Item{
0790         id:barLine
0791         anchors.bottom: (root.location === PlasmaCore.Types.BottomEdge) ? parent.bottom : undefined
0792         anchors.top: (root.location === PlasmaCore.Types.TopEdge) ? parent.top : undefined
0793         anchors.left: (root.location === PlasmaCore.Types.LeftEdge) ? parent.left : undefined
0794         anchors.right: (root.location === PlasmaCore.Types.RightEdge) ? parent.right : undefined
0795 
0796         anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined
0797         anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined
0798 
0799         width: ( icList.orientation === Qt.Horizontal ) ? icList.width + spacing : smallSize
0800         height: ( icList.orientation === Qt.Vertical ) ? icList.height + spacing : smallSize
0801 
0802         property int spacing: latteBridge ? 0 : appletAbilities.metrics.iconSize / 2
0803         property int smallSize: Math.max(0.10 * appletAbilities.metrics.iconSize, 16)
0804 
0805         Behavior on opacity{
0806             NumberAnimation { duration: appletAbilities.animations.speedFactor.current * appletAbilities.animations.duration.large }
0807         }
0808 
0809         /// plasmoid's default panel
0810         BorderImage{
0811             anchors.fill:parent
0812             source: "../images/panel-west.png"
0813             border { left:8; right:8; top:8; bottom:8 }
0814 
0815             opacity: (plasmoid.configuration.showBarLine && !plasmoid.configuration.useThemePanel && inPlasma) ? 1 : 0
0816 
0817             visible: (opacity == 0) ? false : true
0818 
0819             horizontalTileMode: BorderImage.Stretch
0820             verticalTileMode: BorderImage.Stretch
0821 
0822             Behavior on opacity{
0823                 NumberAnimation { duration: appletAbilities.animations.speedFactor.current * appletAbilities.animations.duration.large }
0824             }
0825         }
0826 
0827 
0828         /// item which is used as anchors for the plasma's theme
0829         Item{
0830             id:belower
0831 
0832             width: (root.location === PlasmaCore.Types.LeftEdge) ? shadowsSvgItem.margins.left : shadowsSvgItem.margins.right
0833             height: (root.location === PlasmaCore.Types.BottomEdge)? shadowsSvgItem.margins.bottom : shadowsSvgItem.margins.top
0834 
0835             anchors.top: (root.location === PlasmaCore.Types.BottomEdge) ? parent.bottom : undefined
0836             anchors.bottom: (root.location === PlasmaCore.Types.TopEdge) ? parent.top : undefined
0837             anchors.right: (root.location === PlasmaCore.Types.LeftEdge) ? parent.left : undefined
0838             anchors.left: (root.location === PlasmaCore.Types.RightEdge) ? parent.right : undefined
0839         }
0840 
0841 
0842         /// the current theme's panel
0843         PlasmaCore.FrameSvgItem{
0844             id: shadowsSvgItem
0845 
0846             anchors.bottom: (root.location === PlasmaCore.Types.BottomEdge) ? belower.bottom : undefined
0847             anchors.top: (root.location === PlasmaCore.Types.TopEdge) ? belower.top : undefined
0848             anchors.left: (root.location === PlasmaCore.Types.LeftEdge) ? belower.left : undefined
0849             anchors.right: (root.location === PlasmaCore.Types.RightEdge) ? belower.right : undefined
0850 
0851             anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined
0852             anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined
0853 
0854             width: root.vertical ? panelSize + margins.left + margins.right: parent.width
0855             height: root.vertical ? parent.height : panelSize + margins.top + margins.bottom
0856 
0857             imagePath: "translucent/widgets/panel-background"
0858             prefix:"shadow"
0859 
0860             opacity: (plasmoid.configuration.showBarLine && plasmoid.configuration.useThemePanel && inPlasma) ? 1 : 0
0861             visible: (opacity == 0) ? false : true
0862 
0863             property int panelSize: ((root.location === PlasmaCore.Types.BottomEdge) ||
0864                                      (root.location === PlasmaCore.Types.TopEdge)) ?
0865                                         plasmoid.configuration.panelSize + belower.height:
0866                                         plasmoid.configuration.panelSize + belower.width
0867 
0868             Behavior on opacity{
0869                 NumberAnimation { duration: appletAbilities.animations.speedFactor.current * appletAbilities.animations.duration.large }
0870             }
0871 
0872 
0873             PlasmaCore.FrameSvgItem{
0874                 anchors.margins: belower.width-1
0875                 anchors.fill:parent
0876                 imagePath: plasmoid.configuration.transparentPanel ? "translucent/widgets/panel-background" :
0877                                                                      "widgets/panel-background"
0878             }
0879         }
0880 
0881 
0882         TasksLayout.MouseHandler {
0883             id: mouseHandler
0884             anchors.bottom: (root.location === PlasmaCore.Types.BottomEdge) ? scrollableList.bottom : undefined
0885             anchors.top: (root.location === PlasmaCore.Types.TopEdge) ? scrollableList.top : undefined
0886             anchors.left: (root.location === PlasmaCore.Types.LeftEdge) ? scrollableList.left : undefined
0887             anchors.right: (root.location === PlasmaCore.Types.RightEdge) ? scrollableList.right : undefined
0888 
0889             anchors.horizontalCenter: !root.vertical ? scrollableList.horizontalCenter : undefined
0890             anchors.verticalCenter: root.vertical ? scrollableList.verticalCenter : undefined
0891 
0892             width: root.vertical ? maxThickness : icList.width
0893             height: root.vertical ? icList.height : maxThickness
0894 
0895             target: icList
0896 
0897             property int maxThickness: ((appletAbilities.parabolic.isEnabled && appletAbilities.parabolic.isHovered)
0898                                         || (appletAbilities.parabolic.isEnabled && windowPreviewIsShown)
0899                                         || appletAbilities.animations.hasThicknessAnimation) ?
0900                                            appletAbilities.metrics.mask.thickness.maxZoomedForItems : // dont clip bouncing tasks when zoom=1
0901                                            appletAbilities.metrics.mask.thickness.normalForItems
0902 
0903             function onlyLaunchersInDroppedList(list){
0904                 return list.every(function (item) {
0905                     return backend.isApplication(item)
0906                 });
0907             }
0908 
0909             onUrlsDropped: {
0910                 //! inform synced docks for new dropped launchers
0911                 if (onlyLaunchersInDroppedList(urls)) {
0912                     appletAbilities.launchers.addDroppedLaunchers(urls);
0913                     return;
0914                 }
0915 
0916                 //! if the list does not contain only launchers then just open the corresponding
0917                 //! urls with the relevant app
0918 
0919                 if (!hoveredItem) {
0920                     return;
0921                 }
0922 
0923                 // DeclarativeMimeData urls is a QJsonArray but requestOpenUrls expects a proper QList<QUrl>.
0924                 var urlsList = backend.jsonArrayToUrlList(urls);
0925 
0926                 // Otherwise we'll just start a new instance of the application with the URLs as argument,
0927                 // as you probably don't expect some of your files to open in the app and others to spawn launchers.
0928                 tasksModel.requestOpenUrls(hoveredItem.modelIndex(), urlsList);
0929             }
0930         }
0931 
0932         /* Rectangle {
0933             anchors.fill: scrollableList
0934             color: "transparent"
0935             border.width: 1
0936             border.color: "blue"
0937         } */
0938 
0939         TasksLayout.ScrollableList {
0940             id: scrollableList
0941             width: !root.vertical ? length : thickness
0942             height: root.vertical ? length : thickness
0943             contentWidth: icList.width
0944             contentHeight: icList.height
0945 
0946             //onCurrentPosChanged: console.log("CP :: "+ currentPos + " icW:"+icList.width + " rw: "+root.width + " w:" +width);
0947 
0948             layer.enabled: contentsExceed && root.scrollingEnabled
0949             layer.effect: OpacityMask {
0950                 maskSource: TasksLayout.ScrollOpacityMask{
0951                     width: scrollableList.width
0952                     height: scrollableList.height
0953                 }
0954             }
0955 
0956             Binding {
0957                 target: scrollableList
0958                 property: "thickness"
0959                 when: !appletAbilities.myView.inRelocationHiding
0960                 value: {
0961                     if (appletAbilities.myView.isReady) {
0962                         return appletAbilities.animations.hasThicknessAnimation ? appletAbilities.metrics.mask.thickness.zoomed : appletAbilities.metrics.mask.thickness.normal;
0963                     }
0964 
0965                     return appletAbilities.metrics.totals.thickness * appletAbilities.parabolic.factor.zoom;
0966                 }
0967             }
0968 
0969             Binding {
0970                 target: scrollableList
0971                 property: "length"
0972                 when: !appletAbilities.myView.inRelocationHiding
0973                 value: root.vertical ? Math.min(root.height, root.tasksLength) : Math.min(root.width, root.tasksLength)
0974             }
0975 
0976             TasksLayout.ScrollPositioner {
0977                 id: listViewBase
0978 
0979                 ListView {
0980                     id:icList
0981                     model: tasksModel
0982                     delegate: Task.TaskItem{
0983                         abilities: appletAbilities
0984                     }
0985 
0986                     property int currentSpot : -1000
0987                     property int previousCount : 0
0988 
0989                     property int tasksCount: tasksModel.count
0990 
0991                     //the duration of this animation should be as small as possible
0992                     //it fixes a small issue with the dragging an item to change it's
0993                     //position, if the duration is too big there is a point in the
0994                     //list that an item is going back and forth too fast
0995 
0996                     //more of a trouble
0997                     moveDisplaced: Transition {
0998                         NumberAnimation { properties: "x,y"; duration: appletAbilities.animations.speedFactor.current * appletAbilities.animations.duration.large; easing.type: Easing.Linear }
0999                     }
1000 
1001                     ///this transition can not be used with dragging !!!! I breaks
1002                     ///the lists indexes !!!!!
1003                     ///move: Transition {
1004                     ///    NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.Linear }
1005                     ///}
1006 
1007                     function childAtPos(x, y){
1008                         var tasks = icList.contentItem.children;
1009 
1010                         for(var i=0; i<tasks.length; ++i){
1011                             var task = tasks[i];
1012 
1013                             var choords = mapFromItem(task,0, 0);
1014 
1015                             if( (task.objectName==="TaskItem") && (x>=choords.x) && (x<=choords.x+task.width)
1016                                     && (y>=choords.y) && (y<=choords.y+task.height)){
1017                                 return task;
1018                             }
1019                         }
1020 
1021                         return null;
1022                     }
1023 
1024                     function childAtIndex(position) {
1025                         var tasks = icList.contentItem.children;
1026 
1027                         if (position < 0)
1028                             return;
1029 
1030                         for(var i=0; i<tasks.length; ++i){
1031                             var task = tasks[i];
1032 
1033                             if (task.lastValidIndex === position
1034                                     || (task.lastValidIndex === -1 && task.itemIndex === position )) {
1035                                 return task;
1036                             }
1037                         }
1038 
1039                         return undefined;
1040                     }
1041                 }
1042             } // ScrollPositioner
1043         } // ScrollableList
1044 
1045         TasksLayout.ScrollEdgeShadows {
1046             id: scrollShadows
1047             width: !root.vertical ? scrollableList.width : thickness
1048             height: !root.vertical ? thickness : scrollableList.height
1049             visible: scrollableList.contentsExceed
1050 
1051             flickable: scrollableList
1052         } // ScrollEdgeShadows
1053 
1054         LatteComponents.AddingArea {
1055             id: newDroppedLauncherVisual
1056             width: root.vertical ? appletAbilities.metrics.totals.thickness : scrollableList.length
1057             height: root.vertical ? scrollableList.length : appletAbilities.metrics.totals.thickness
1058 
1059             visible: backgroundOpacity > 0
1060             radius: appletAbilities.metrics.iconSize/10
1061             backgroundOpacity: mouseHandler.isDroppingOnlyLaunchers || appletAbilities.launchers.isShowingAddLaunchersMessage ? 0.75 : 0
1062             duration: appletAbilities.animations.speedFactor.current
1063             iconSize: appletAbilities.metrics.iconSize
1064             z: 99
1065 
1066             title: i18n("Tasks Area")
1067 
1068             states: [
1069                 ///Bottom Edge
1070                 State {
1071                     name: "left"
1072                     when: root.location===PlasmaCore.Types.LeftEdge
1073 
1074                     AnchorChanges {
1075                         target: newDroppedLauncherVisual
1076                         anchors{ top:undefined; bottom:undefined; left:scrollableList.left; right:undefined;
1077                             horizontalCenter:undefined; verticalCenter:scrollableList.verticalCenter}
1078                     }
1079 
1080                     PropertyChanges {
1081                         target: newDroppedLauncherVisual
1082                         anchors{ topMargin:0; bottomMargin:0; leftMargin: appletAbilities.metrics.margin.screenEdge; rightMargin:0;}
1083                     }
1084                 },
1085                 State {
1086                     name: "right"
1087                     when: root.location===PlasmaCore.Types.RightEdge
1088 
1089                     AnchorChanges {
1090                         target: newDroppedLauncherVisual
1091                         anchors{ top:undefined; bottom:undefined; left:undefined; right:scrollableList.right;
1092                             horizontalCenter:undefined; verticalCenter:scrollableList.verticalCenter}
1093                     }
1094 
1095                     PropertyChanges {
1096                         target: newDroppedLauncherVisual
1097                         anchors{ topMargin:0; bottomMargin:0; leftMargin:0; rightMargin: appletAbilities.metrics.margin.screenEdge;}
1098                     }
1099                 },
1100                 State {
1101                     name: "top"
1102                     when: root.location===PlasmaCore.Types.TopEdge
1103 
1104                     AnchorChanges {
1105                         target: newDroppedLauncherVisual
1106                         anchors{ top:scrollableList.top; bottom:undefined; left:undefined; right:undefined;
1107                             horizontalCenter:scrollableList.horizontalCenter; verticalCenter:undefined}
1108                     }
1109 
1110                     PropertyChanges {
1111                         target: newDroppedLauncherVisual
1112                         anchors{ topMargin: appletAbilities.metrics.margin.screenEdge; bottomMargin:0; leftMargin:0; rightMargin:0;}
1113                     }
1114                 },
1115                 State {
1116                     name: "bottom"
1117                     when: root.location!==PlasmaCore.Types.TopEdge
1118                           && root.location !== PlasmaCore.Types.LeftEdge
1119                           && root.location !== PlasmaCore.Types.RightEdge
1120 
1121                     AnchorChanges {
1122                         target: newDroppedLauncherVisual
1123                         anchors{ top:undefined; bottom:scrollableList.bottom; left:undefined; right:undefined;
1124                             horizontalCenter:scrollableList.horizontalCenter; verticalCenter:undefined}
1125                     }
1126 
1127                     PropertyChanges {
1128                         target: newDroppedLauncherVisual
1129                         anchors{ topMargin:0; bottomMargin: appletAbilities.metrics.margin.screenEdge; leftMargin:0; rightMargin:0;}
1130                     }
1131                 }
1132             ]
1133         }
1134     }
1135 
1136     //// helpers
1137 
1138     Timer {
1139         id: iconGeometryTimer
1140         // INVESTIGATE: such big interval but unfortunately it does not work otherwise
1141         interval: 500
1142         repeat: false
1143 
1144         onTriggered: {
1145             root.publishTasksGeometries();
1146 
1147             if (appletAbilities.debug.timersEnabled) {
1148                 console.log("plasmoid timer: iconGeometryTimer called...");
1149             }
1150         }
1151     }
1152 
1153 
1154     ///REMOVE
1155     ////Activities List
1156     ////it can be used to cleanup the launchers from garbage-deleted activities....
1157     Item{
1158         id: activityModelInstance
1159         property int count: activityModelRepeater.count
1160 
1161         Repeater {
1162             id:activityModelRepeater
1163             model: Activities.ActivityModel {
1164                 id: activityModel
1165                 //  shownStates: "Running"
1166             }
1167             delegate: Item {
1168                 visible: false
1169                 property string activityId: model.id
1170                 property string activityName: model.name
1171             }
1172         }
1173 
1174         function activities(){
1175             var activitiesResult = [];
1176 
1177             for(var i=0; i<activityModelInstance.count; ++i){
1178                 console.log(children[i].activityId);
1179                 activitiesResult.push(children[i].activityId);
1180             }
1181 
1182             return activitiesResult;
1183         }
1184 
1185         ///REMOVE
1186         onCountChanged: {
1187             /*  if(activityInfo.currentActivity != "00000000-0000-0000-0000-000000000000"){
1188                 console.log("----------- Latte Plasmoid Signal: Activities number was changed ---------");
1189                 var allActivities = activities();
1190                 ActivitiesTools.cleanupRecords(allActivities);
1191                 console.log("----------- Latte Plasmoid Signal End ---------");
1192             }*/
1193         }
1194     }
1195 
1196     /////////
1197 
1198     //// functions
1199     function activateTaskAtIndex(index) {
1200         // This is called with Meta+number shortcuts by plasmashell when Tasks are in a plasma panel.
1201         appletAbilities.shortcuts.sglActivateEntryAtIndex(index);
1202     }
1203 
1204     function newInstanceForTaskAtIndex(index) {
1205         // This is called with Meta+Alt+number shortcuts by plasmashell when Tasks are in a plasma panel.
1206         appletAbilities.shortcuts.sglNewInstanceForEntryAtIndex(index);
1207     }
1208 
1209     function getBadger(identifier) {
1210         var ident1 = identifier;
1211         var n = ident1.lastIndexOf('/');
1212 
1213         var result = n>=0 ? ident1.substring(n + 1) : identifier;
1214 
1215         for(var i=0; i<badgers.length; ++i) {
1216             if (result.indexOf(badgers[i].id) >= 0) {
1217                 return badgers[i];
1218             }
1219         }
1220     }
1221 
1222     function updateBadge(identifier, value) {
1223         var tasks = icList.contentItem.children;
1224         var identifierF = identifier.concat(".desktop");
1225 
1226         for(var i=0; i<tasks.length; ++i){
1227             var task = tasks[i];
1228 
1229             if (task && task.launcherUrl && task.launcherUrl.indexOf(identifierF) >= 0) {
1230                 task.badgeIndicator = value === "" ? 0 : Number(value);
1231                 var badge = getBadger(identifierF);
1232                 if (badge) {
1233                     badge.value = value;
1234                 } else {
1235                     badgers.push({id: identifierF, value: value});
1236                 }
1237             }
1238         }
1239     }
1240 
1241     function getLauncherList() {
1242         return plasmoid.configuration.launchers59;
1243     }
1244 
1245     function previewContainsMouse() {
1246         return windowsPreviewDlg.containsMouse;
1247     }
1248 
1249     function containsMouse(){
1250         //console.log("s1...");
1251         if (disableRestoreZoom && (root.contextMenu || windowsPreviewDlg.visible)) {
1252             return;
1253         } else {
1254             disableRestoreZoom = false;
1255         }
1256 
1257         //if (previewContainsMouse())
1258         //  windowsPreviewDlg.hide(4);
1259 
1260         if (previewContainsMouse())
1261             return true;
1262 
1263         //console.log("s3...");
1264         var tasks = icList.contentItem.children;
1265 
1266         for(var i=0; i<tasks.length; ++i){
1267             var task = tasks[i];
1268 
1269             if(task && task.containsMouse){
1270                 // console.log("Checking "+i+" - "+task.index+" - "+task.containsMouse);
1271                 return true;
1272             }
1273         }
1274 
1275         return false;
1276     }
1277 
1278     ///REMOVE
1279     /*function createContextMenu(task) {
1280         var menu = root.contextMenuComponent.createObject(task);
1281         menu.visualParent = task;
1282         menu.mpris2Source = mpris2Source;
1283         menu.activitiesCount = activityModelInstance.count;
1284         return menu;
1285     }*/
1286 
1287     function createContextMenu(rootTask, modelIndex, args) {
1288         var initialArgs = args || {}
1289         initialArgs.visualParent = rootTask;
1290         initialArgs.modelIndex = modelIndex;
1291         initialArgs.mpris2Source = mpris2Source;
1292         initialArgs.backend = backend;
1293 
1294         root.contextMenu = root.contextMenuComponent.createObject(rootTask, initialArgs);
1295 
1296         return root.contextMenu;
1297     }
1298 
1299     Component.onCompleted:  {
1300         if (root.plasmaAtLeast525) {
1301             root.activateWindowView.connect(backend.activateWindowView);
1302         } else {
1303             root.presentWindows.connect(backend.presentWindows);
1304         }
1305 
1306         root.windowsHovered.connect(backend.windowsHovered);
1307         updateListViewParent();
1308     }
1309 
1310     Component.onDestruction: {
1311         if (root.plasmaAtLeast525) {
1312             root.activateWindowView.disconnect(backend.activateWindowView);
1313         } else {
1314             root.presentWindows.disconnect(backend.presentWindows);
1315         }
1316 
1317         root.windowsHovered.disconnect(backend.windowsHovered);
1318     }
1319 
1320     //BEGIN states
1321     // Alignments
1322     // 0-Center, 1-Left, 2-Right, 3-Top, 4-Bottom
1323     states: [
1324         ///Bottom Edge
1325         State {
1326             name: "bottomCenter"
1327             when: (root.location===PlasmaCore.Types.BottomEdge && root.alignment===LatteCore.Types.Center)
1328 
1329             AnchorChanges {
1330                 target: barLine
1331                 anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
1332             }
1333         },
1334         State {
1335             name: "bottomLeft"
1336             when: (root.location===PlasmaCore.Types.BottomEdge && root.alignment===LatteCore.Types.Left)
1337 
1338             AnchorChanges {
1339                 target: barLine
1340                 anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
1341             }
1342         },
1343         State {
1344             name: "bottomRight"
1345             when: (root.location===PlasmaCore.Types.BottomEdge && root.alignment===LatteCore.Types.Right)
1346 
1347             AnchorChanges {
1348                 target: barLine
1349                 anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
1350             }
1351         },
1352         ///Top Edge
1353         State {
1354             name: "topCenter"
1355             when: (root.location===PlasmaCore.Types.TopEdge && root.alignment===LatteCore.Types.Center)
1356 
1357             AnchorChanges {
1358                 target: barLine
1359                 anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
1360             }
1361         },
1362         State {
1363             name: "topLeft"
1364             when: (root.location===PlasmaCore.Types.TopEdge && root.alignment===LatteCore.Types.Left)
1365 
1366             AnchorChanges {
1367                 target: barLine
1368                 anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
1369             }
1370         },
1371         State {
1372             name: "topRight"
1373             when: (root.location===PlasmaCore.Types.TopEdge && root.alignment===LatteCore.Types.Right)
1374 
1375             AnchorChanges {
1376                 target: barLine
1377                 anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
1378             }
1379         },
1380         ////Left Edge
1381         State {
1382             name: "leftCenter"
1383             when: (root.location===PlasmaCore.Types.LeftEdge && root.alignment===LatteCore.Types.Center)
1384 
1385             AnchorChanges {
1386                 target: barLine
1387                 anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
1388             }
1389         },
1390         State {
1391             name: "leftTop"
1392             when: (root.location===PlasmaCore.Types.LeftEdge && root.alignment===LatteCore.Types.Top)
1393 
1394             AnchorChanges {
1395                 target: barLine
1396                 anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
1397             }
1398         },
1399         State {
1400             name: "leftBottom"
1401             when: (root.location===PlasmaCore.Types.LeftEdge && root.alignment===LatteCore.Types.Bottom)
1402 
1403             AnchorChanges {
1404                 target: barLine
1405                 anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
1406             }
1407         },
1408         ///Right Edge
1409         State {
1410             name: "rightCenter"
1411             when: (root.location===PlasmaCore.Types.RightEdge && root.alignment===LatteCore.Types.Center)
1412 
1413             AnchorChanges {
1414                 target: barLine
1415                 anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
1416             }
1417         },
1418         State {
1419             name: "rightTop"
1420             when: (root.location===PlasmaCore.Types.RightEdge && root.alignment===LatteCore.Types.Top)
1421 
1422             AnchorChanges {
1423                 target: barLine
1424                 anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
1425             }
1426         },
1427         State {
1428             name: "rightBottom"
1429             when: (root.location===PlasmaCore.Types.RightEdge && root.alignment===LatteCore.Types.Bottom)
1430 
1431             AnchorChanges {
1432                 target: barLine
1433                 anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
1434             }
1435         }
1436 
1437     ]
1438     //END states
1439 
1440 }