Warning, /plasma/latte-dock/plasmoid/package/contents/ui/task/TaskItem.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.0
0008 import QtQuick.Layouts 1.1
0009 import QtGraphicalEffects 1.0
0010
0011 import org.kde.plasma.core 2.0 as PlasmaCore
0012 import org.kde.plasma.components 2.0 as PlasmaComponents
0013 import org.kde.plasma.plasmoid 2.0
0014
0015 import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet
0016
0017 import org.kde.latte.core 0.2 as LatteCore
0018 import org.kde.latte.private.tasks 0.1 as LatteTasks
0019
0020 import org.kde.latte.abilities.items 0.1 as AbilityItem
0021
0022 import "animations" as TaskAnimations
0023
0024 AbilityItem.BasicItem {
0025 id: taskItem
0026 visible: false
0027 objectName: "TaskItem"
0028
0029 isHidden: !visible || isForcedHidden
0030
0031 isHiddenSpacerForcedShow: taskItem.inAttentionBuiltinAnimation
0032 isHiddenSpacerAnimated: showWindowAnimation.running
0033 || root.inActivityChange
0034 || taskItem.inRemoveStage
0035 || (taskItem.containsMouse && inAttentionBuiltinAnimation && taskItem.parabolicItem.zoom!==taskItem.abilities.parabolic.factor.zoom)
0036
0037 isMonochromaticForcedContentItem: plasmoid.configuration.forceMonochromaticIcons
0038 monochromizedItem: taskIcon.monochromizedItem
0039
0040 isSeparatorHidden: isSeparator && (lastValidIndex > taskItem.abilities.indexer.lastVisibleItemIndex)
0041 isSeparatorInRealLength: isSeparator && root.dragSource
0042
0043 containsMouse: taskMouseArea.containsMouse || parabolicAreaContainsMouse
0044 thinTooltipText: {
0045 if (root.showPreviews && !isLauncher) {
0046 return "";
0047 }
0048
0049 return isWindow ? model.display : model.AppName;
0050 }
0051
0052 preserveIndicatorInInitialPosition: inBouncingAnimation || inAttentionBuiltinAnimation || inNewWindowBuiltinAnimation
0053
0054 parabolicItem.isParabolicEventBlocked: root.dragSource
0055 || !hoverEnabled
0056 || !taskItem.abilities.myView.isShownFully
0057 || inAnimation
0058 || (inBlockingAnimation && !inAttentionBuiltinAnimation)
0059 parabolicItem.isUpdatingOnlySpacers: inAttentionBuiltinAnimation || inBouncingAnimation
0060
0061 property alias hoverEnabled: taskMouseArea.hoverEnabled
0062 property alias pressed: taskMouseArea.pressed
0063
0064 property bool delayingRemove: ListView.delayRemove
0065 //states that exist in windows in a Group of windows
0066 property bool hasActive: isActive
0067 property bool hasMinimized: (IsGroupParent === true) ? subWindows.hasMinimized : isMinimized
0068 property bool hasShown: (IsGroupParent === true) ? subWindows.hasShown : !isMinimized && isWindow
0069 property bool inAttention: isDemandingAttention && plasmoid.status === PlasmaCore.Types.NeedsAttentionStatus ? true : false
0070
0071 /*animations flags*/
0072 property bool inAnimation: true
0073 property bool inAddRemoveAnimation: true
0074 property bool inAttentionBuiltinAnimation: false
0075 property bool inBlockingAnimation: false
0076 property bool inBouncingAnimation: false
0077 property bool inNewWindowBuiltinAnimation: false
0078 property bool inPopup: false
0079 property bool inRemoveStage: false
0080
0081 property bool isLauncherBuiltinAnimationRunning: false
0082 property bool isLauncherAnimationRunning: isLauncherBuiltinAnimationRunning
0083 || (taskItem.abilities.indicators.info.providesTaskLauncherAnimation && isIndicatorTaskLauncherAnimationRunning)
0084
0085 //! after clicking to show/hide preview enter events are trigerred even though the should not
0086 property bool showPreviewsIsBlockedFromReleaseEvent: false
0087
0088 property bool isAbleToShowPreview: true
0089 property bool isActive: (IsActive === true) ? true : false
0090 property bool isDemandingAttention: (IsDemandingAttention === true) ? true : false
0091 property bool isDragged: false
0092 property bool isGroupable: (IsGroupable === true) ? true : false
0093 property bool isGroupParent: (IsGroupParent === true) ? true : false
0094 property bool isForcedHidden: false
0095 property bool isLauncher: (IsLauncher === true) ? true : false
0096 property bool hasShownLauncher: (taskItem.abilities.launchers.inCurrentActivity(taskItem.launcherUrl)
0097 || taskItem.abilities.launchers.inCurrentActivity(taskItem.launcherUrlWithIcon))
0098 && !root.inActivityChange /*update trigger when changing current activity*/
0099 property bool isMinimized: (IsMinimized === true) ? true : false
0100 property bool isStartup: (IsStartup === true) ? true : false
0101 property bool isWindow: (IsWindow === true) ? true : false
0102
0103 property bool canPublishGeometries: (isWindow || isStartup || isGroupParent) && visible && width>=taskItem.abilities.metrics.iconSize && height>=taskItem.abilities.metrics.iconSize
0104 && !taskItem.delayingRemove
0105 && (taskItem.parabolicItem.zoom===1 || taskItem.parabolicItem.zoom===taskItem.abilities.parabolic.factor.zoom) //don't publish during zoom animation
0106
0107 property bool hoveredFromDragging: (mouseHandler.hoveredItem === taskItem) || (mouseHandler.ignoredItem === taskItem)
0108
0109 property bool wheelIsBlocked: false
0110 property bool hasAddedWaitingLauncher: false
0111
0112 property int badgeIndicator: 0 //it is used from external apps
0113 property int lastValidIndex: -1 //used for the removal animation
0114 property int lastButtonClicked: -1;
0115 property int pressX: -1
0116 property int pressY: -1
0117 property int resistanceDelay: 450
0118 property int windowsCount: subWindows.windowsCount
0119 property int windowsMinimizedCount: subWindows.windowsMinimized
0120
0121 property string activity: tasksModel.activity
0122
0123 readonly property var m: model
0124 readonly property int pid: model && model.AppPid ? model.AppPid : -1
0125 readonly property string appName: model && model.AppName ? model.AppName : ""
0126
0127 property string modelLauncherUrl: (LauncherUrlWithoutIcon && LauncherUrlWithoutIcon !== null) ? LauncherUrlWithoutIcon : ""
0128 property string modelLauncherUrlWithIcon: (LauncherUrl && LauncherUrl !== null) ? LauncherUrl : ""
0129 property string launcherUrl: ""
0130 property string launcherUrlWithIcon: ""
0131 property string launcherName: ""
0132
0133 readonly property alias hoveredTimer: taskMouseArea.hoveredTimer
0134 readonly property alias mouseArea: taskMouseArea
0135 readonly property alias subWindows: subWindows
0136
0137 readonly property alias showWindowAnimation: _showWindowAnimation
0138
0139 //! Indicator Properties
0140 indicator.isTask: true
0141 indicator.isLauncher: taskItem.isLauncher || root.disableAllWindowsFunctionality
0142 indicator.isStartup: !root.disableAllWindowsFunctionality && taskItem.isStartup
0143 indicator.isWindow: !root.disableAllWindowsFunctionality && taskItem.isWindow
0144
0145 indicator.isActive: !root.disableAllWindowsFunctionality && (taskItem.hasActive
0146 || (root.showPreviews
0147 && (taskItem.isWindow || taskItem.isGroupParent)
0148 && windowsPreviewDlg.activeItem
0149 && (windowsPreviewDlg.activeItem === taskItem)) )
0150
0151 indicator.isGroup: !root.disableAllWindowsFunctionality && taskItem.isGroupParent
0152 indicator.isHovered: taskItem.containsMouse || (windowsPreviewDlg.containsMouse && (toolTipDelegate.parentTask === taskItem))
0153 indicator.isMinimized: !root.disableAllWindowsFunctionality && taskItem.isMinimized
0154 indicator.isPressed: taskItem.pressed
0155 indicator.inAttention: !root.disableAllWindowsFunctionality && taskItem.inAttention
0156 indicator.inRemoving: taskItem.inRemoveStage
0157
0158 indicator.isSquare: true
0159
0160 indicator.hasActive: !root.disableAllWindowsFunctionality && taskItem.hasActive
0161 indicator.hasMinimized: !root.disableAllWindowsFunctionality && taskItem.hasMinimized
0162 indicator.hasShown: !root.disableAllWindowsFunctionality && taskItem.hasShown
0163 indicator.windowsCount: !root.disableAllWindowsFunctionality ? taskItem.windowsCount : 0
0164 indicator.windowsMinimizedCount: !root.disableAllWindowsFunctionality ? taskItem.windowsMinimizedCount : 0
0165
0166 indicator.scaleFactor: taskItem.parabolicItem.zoom
0167 indicator.panelOpacity: taskItem.abilities.myView.backgroundOpacity
0168 indicator.shadowColor: taskItem.abilities.myView.itemShadow.shadowSolidColor
0169
0170 indicator.progressVisible: taskIcon.progressVisible /*since 0.9.2*/
0171 indicator.progress: taskIcon.progress /*since 0.9.2*/
0172
0173 indicator.palette: taskItem.abilities.myView.palette
0174
0175 indicator.iconBackgroundColor: taskIcon.backgroundColor
0176 indicator.iconGlowColor: taskIcon.glowColor
0177 //! Indicator Properties
0178
0179 onModelLauncherUrlChanged: {
0180 if (modelLauncherUrl !== ""){
0181 launcherUrl = modelLauncherUrl;
0182
0183 //!extract the launcherName if possible
0184 var nameStarts = launcherUrl.lastIndexOf("/");
0185 if (nameStarts === -1){
0186 nameStarts = launcherUrl.lastIndexOf(":");
0187 }
0188
0189 var nameEnds = launcherUrl.lastIndexOf(".desktop");
0190
0191 if (nameStarts!==-1 && nameEnds!==-1 && nameStarts<nameEnds) {
0192 launcherName = launcherUrl.substring(nameStarts+1,nameEnds);
0193 }
0194 }
0195
0196 if (taskItem.abilities.launchers.isSeparator(modelLauncherUrl)){
0197 isSeparator = true;
0198 } else {
0199 isSeparator = false;
0200 }
0201 }
0202
0203 onModelLauncherUrlWithIconChanged: {
0204 if (modelLauncherUrlWithIcon !== ""){
0205 launcherUrlWithIcon = modelLauncherUrlWithIcon;
0206 }
0207 }
0208
0209 onHoveredFromDraggingChanged: {
0210 if (hoveredFromDragging) {
0211 scrollableList.autoScrollFor(taskItem, true);
0212 }
0213 }
0214
0215 ////// Audio streams //////
0216 property Item audioStreamOverlay
0217 property var audioStreams: []
0218 readonly property bool hasAudioStream: root.showAudioBadge && audioStreams.length > 0 && !isLauncher
0219 readonly property bool playingAudio: hasAudioStream && audioStreams.some(function (item) {
0220 return !item.corked
0221 })
0222
0223 readonly property bool muted: hasAudioStream && audioStreams.every(function (item) {
0224 return item.muted
0225 })
0226
0227 readonly property int volume: {
0228 if (!hasAudioStream){
0229 return 0;
0230 }
0231
0232 var maxVolume = 0;
0233 for (var i=0; i<audioStreams.length; ++i){
0234 if (audioStreams[i].volume > maxVolume)
0235 maxVolume = audioStreams[i].volume;
0236 }
0237
0238 return maxVolume;
0239 }
0240
0241 //! Content Item
0242 contentItem: TaskIcon{
0243 id:taskIcon
0244 }
0245 //////
0246
0247 property QtObject contextMenu: null
0248
0249 signal checkWindowsStates();
0250
0251 SubWindows{
0252 id: subWindows
0253
0254 property int previousCount: 0
0255
0256 onWindowsCountChanged: {
0257 if (root.disableAllWindowsFunctionality) {
0258 return;
0259 }
0260
0261 if ((windowsCount >= 2)
0262 && (windowsCount > previousCount)
0263 && !(taskItem.containsMouse)
0264 && !root.dragSource ){
0265 taskItem.taskGroupedWindowAdded();
0266 } else if ((windowsCount >= 1)
0267 && (windowsCount < previousCount)
0268 && !root.dragSource
0269 && !taskItem.delayingRemove){
0270 //sometimes this is triggered in dragging with no reason
0271 taskItem.taskGroupedWindowRemoved();
0272 }
0273
0274 if (windowsCount>=1) {
0275 taskItem.slotPublishGeometries();
0276 }
0277
0278 //! workaround in order to update correctly the previousCount
0279 //! windowsCount can not return to zero because is such case
0280 //! the window task is removed and the launcher is added from
0281 //! libtaskmanager
0282 if (windowsCount>=1) {
0283 previousCount = windowsCount;
0284 }
0285 }
0286 }
0287
0288 TaskMouseArea {
0289 id: taskMouseArea
0290 }
0291
0292 Timer {
0293 id: publishGeometryTimer
0294 interval: 800
0295 repeat: false
0296
0297 onTriggered: {
0298 slotPublishGeometries();
0299
0300 if (taskItem.abilities.debug.timersEnabled) {
0301 console.log("plasmoid timer: publishGeometryTimer called...");
0302 }
0303 }
0304 }
0305
0306 ////// Values Changes /////
0307 //restore scales when there is no zoom factor for that item or
0308 //the mouse is out of the ListView
0309 // onItemIndexChanged: {
0310 // }
0311
0312 onAppNameChanged: updateAudioStreams()
0313 onPidChanged: updateAudioStreams()
0314 onHasAudioStreamChanged: updateAudioStreams()
0315
0316 onCanPublishGeometriesChanged: {
0317 if (canPublishGeometries) {
0318 slotPublishGeometries();
0319 publishGeometryTimer.start();
0320 }
0321 }
0322
0323 onItemIndexChanged: {
0324 if (itemIndex>=0) {
0325 lastValidTimer.start();
0326 }
0327 }
0328
0329 onIsDraggedChanged: {
0330 if (isDragged){
0331 taskItem.contentItem.monochromizedItem.grabToImage((result) => {
0332 root.dragSource = taskItem;
0333 dragHelper.Drag.imageSource = result.url;
0334 dragHelper.Drag.mimeData = backend.generateMimeData(model.MimeType, model.MimeData, model.LauncherUrlWithoutIcon);
0335 dragHelper.Drag.active = true;
0336 });
0337 } else {
0338 dragHelper.Drag.active = false;
0339 dragHelper.Drag.imageSource = "";
0340 pressX = -1;
0341 pressY = -1;
0342 }
0343 }
0344
0345 onIsMinimizedChanged: {
0346 checkWindowsStates();
0347 }
0348
0349 onIsActiveChanged: {
0350 checkWindowsStates();
0351 if (isActive) {
0352 scrollableList.focusOn(taskItem);
0353 }
0354 }
0355
0356 onIsSeparatorChanged: {
0357 if (isSeparator) {
0358 if (tasksExtendedManager.isLauncherToBeMoved(launcherUrl) && itemIndex>=0) {
0359 tasksExtendedManager.moveLauncherToCorrectPos(launcherUrl, itemIndex);
0360 }
0361 }
0362 }
0363
0364 onLauncherUrlChanged: updateBadge();
0365
0366 onShortcutRequestedActivate: {
0367 if (taskItem.isGroupParent) {
0368 taskItem.activateNextTask();
0369 } else {
0370 taskItem.activateTask();
0371 }
0372 }
0373
0374 onShortcutRequestedNewInstance: {
0375 tasksModel.requestNewInstance(taskItem.modelIndex());
0376 }
0377
0378 ////// End of Values Changes and Signals /////
0379
0380
0381 //! A timer is needed in order to handle also touchpads that probably
0382 //! send too many signals very fast. This way the signals per sec are limited.
0383 //! The user needs to have a steady normal scroll in order to not
0384 //! notice a annoying delay
0385 Timer{
0386 id: scrollDelayer
0387
0388 interval: 400
0389
0390 onTriggered: taskItem.wheelIsBlocked = false;
0391 }
0392
0393 ///////////////// End Of Mouse Area Events ///////////////////
0394
0395 ///// Handlers for Signals /////
0396 function animationStarted(){
0397 // console.log("Animation started: " + index);
0398 inAnimation = true;
0399 }
0400
0401 function animationEnded(){
0402 // console.log("Animation ended: " + index);
0403 inAnimation = false;
0404 }
0405
0406 function handlerDraggingFinished(){
0407 isDragged = false;
0408 }
0409 ///// End of Handlers //////
0410
0411
0412
0413 ///// Helper functions /////
0414 function activateNextTask() {
0415 subWindows.activateNextTask();
0416 }
0417
0418 function activateLauncher() {
0419 if (LatteCore.WindowSystem.compositingActive) {
0420 taskItem.taskLauncherActivated();
0421 hasAddedWaitingLauncher = true;
0422 tasksExtendedManager.addWaitingLauncher(taskItem.launcherUrl);
0423 }
0424
0425 if (root.disableAllWindowsFunctionality) {
0426 tasksModel.requestNewInstance(modelIndex());
0427 } else {
0428 tasksModel.requestActivate(modelIndex());
0429 }
0430 }
0431
0432 function activateTask() {
0433 if( taskItem.isLauncher || root.disableAllWindowsFunctionality){
0434 activateLauncher();
0435 } else{
0436 if (model.IsGroupParent) {
0437 if (root.plasmaAtLeast525) {
0438 //! At least Plasma 5.25 case
0439 var isWindowViewAvailable = LatteCore.WindowSystem.compositingActive && backend.windowViewAvailable;
0440 if (isWindowViewAvailable) {
0441 root.activateWindowView(model.WinIdList);
0442 }
0443 } else {
0444 //! Plasma 5.24 case
0445 var isPresentWindowsAvailable = LatteCore.WindowSystem.compositingActive && backend.canPresentWindows;
0446 if (isPresentWindowsAvailable) {
0447 root.presentWindows(model.WinIdList);
0448 }
0449 }
0450 } else {
0451 if (windowsPreviewDlg.visible) {
0452 forceHidePreview(8.3);
0453 }
0454
0455 if (isMinimized) {
0456 var i = modelIndex();
0457 tasksModel.requestToggleMinimized(i);
0458 tasksModel.requestActivate(i);
0459 } else if (isActive) {
0460 tasksModel.requestToggleMinimized(modelIndex());
0461 } else {
0462 tasksModel.requestActivate(modelIndex());
0463 }
0464 }
0465 }
0466 }
0467
0468 function forceHidePreview(debugtext) {
0469 showPreviewsIsBlockedFromReleaseEvent = true;
0470 hoveredTimer.stop();
0471
0472 root.forcePreviewsHiding(debugtext);
0473 }
0474
0475 function showPreviewWindow() {
0476 if (root.disableAllWindowsFunctionality || !isAbleToShowPreview) {
0477 return;
0478 }
0479
0480 if(windowsPreviewDlg.activeItem !== taskItem){
0481 if (!taskItem.abilities.myView.isReady
0482 || (taskItem.abilities.myView.isReady && taskItem.abilities.myView.isShownFully)) {
0483 taskItem.preparePreviewWindow(false);
0484 windowsPreviewDlg.show(taskItem);
0485 }
0486 }
0487 }
0488
0489 function hidePreviewWindow() {
0490 if(windowsPreviewDlg.activeItem === taskItem){
0491 windowsPreviewDlg.hide("14.1");
0492 }
0493 }
0494
0495 function preparePreviewWindow(hideClose){
0496 windowsPreviewDlg.visualParent = tooltipVisualParent;
0497 toolTipDelegate.parentTask = taskItem;
0498 toolTipDelegate.rootIndex = tasksModel.makeModelIndex(itemIndex, -1);
0499
0500 toolTipDelegate.hideCloseButtons = hideClose;
0501
0502 toolTipDelegate.appName = Qt.binding(function() {
0503 return model.AppName;
0504 });
0505
0506 if (!isLauncher) {
0507 toolTipDelegate.pidParent = Qt.binding(function() {
0508 return model.AppPid;
0509 });
0510 } else {
0511 toolTipDelegate.pidParent = -1;
0512 }
0513
0514 toolTipDelegate.windows = Qt.binding(function() {
0515 return root.plasma515 ? model.WinIdList : model.LegacyWinIdList ;
0516 });
0517 toolTipDelegate.isGroup = Qt.binding(function() {
0518 return model.IsGroupParent == true;
0519 });
0520 toolTipDelegate.icon = Qt.binding(function() {
0521 return model.decoration;
0522 });
0523 toolTipDelegate.launcherUrl = Qt.binding(function() {
0524 return model.LauncherUrlWithoutIcon;
0525 });
0526 toolTipDelegate.isLauncher = Qt.binding(function() {
0527 return model.IsLauncher == true;
0528 });
0529 toolTipDelegate.isMinimizedParent = Qt.binding(function() {
0530 return model.IsMinimized == true;
0531 });
0532 toolTipDelegate.displayParent = Qt.binding(function() {
0533 return model.display;
0534 });
0535 toolTipDelegate.genericName = Qt.binding(function() {
0536 return model.GenericName;
0537 });
0538 toolTipDelegate.virtualDesktopParent = Qt.binding(function() {
0539 return (model.VirtualDesktops !== undefined && model.VirtualDesktops.length > 0) ? model.VirtualDesktops : [0];
0540 });
0541 toolTipDelegate.isOnAllVirtualDesktopsParent = Qt.binding(function() {
0542 return model.IsOnAllVirtualDesktops == true;
0543 });
0544 toolTipDelegate.activitiesParent = Qt.binding(function() {
0545 return model.Activities;
0546 });
0547 }
0548
0549 ///window previews///
0550 function generateSubText(task) {
0551 var subTextEntries = new Array();
0552
0553 if (!plasmoid.configuration.showOnlyCurrentDesktop
0554 && virtualDesktopInfo.numberOfDesktops > 1
0555 && model.IsOnAllVirtualDesktops !== true
0556 && model.VirtualDesktop != -1
0557 && model.VirtualDesktop != undefined) {
0558 subTextEntries.push(i18n("On %1", virtualDesktopInfo.desktopNames[model.VirtualDesktop - 1]));
0559 }
0560
0561 if (model.Activities == undefined) {
0562 return subTextEntries.join("\n");
0563 }
0564
0565 if (model.Activities.length == 0 && activityInfo.numberOfRunningActivities > 1) {
0566 subTextEntries.push(i18nc("Which virtual desktop a window is currently on",
0567 "Available on all activities"));
0568 } else if (model.Activities.length > 0) {
0569 var activityNames = new Array();
0570
0571 for (var i = 0; i < model.Activities.length; i++) {
0572 var activity = model.Activities[i];
0573
0574 if (plasmoid.configuration.showOnlyCurrentActivity) {
0575 if (activity != activityInfo.currentActivity) {
0576 activityNames.push(activityInfo.activityName(model.Activities[i]));
0577 }
0578 } else if (activity != activityInfo.currentActivity) {
0579 activityNames.push(activityInfo.activityName(model.Activities[i]));
0580 }
0581 }
0582
0583 if (plasmoid.configuration.showOnlyCurrentActivity) {
0584 if (activityNames.length > 0) {
0585 subTextEntries.push(i18nc("Activities a window is currently on (apart from the current one)",
0586 "Also available on %1", activityNames.join(", ")));
0587 }
0588 } else if (activityNames.length > 0) {
0589 subTextEntries.push(i18nc("Which activities a window is currently on",
0590 "Available on %1", activityNames.join(", ")));
0591 }
0592 }
0593
0594 return subTextEntries.join("\n");
0595 }
0596 ///window previews////
0597
0598 function modelIndex(){
0599 return tasksModel.makeModelIndex(index);
0600 }
0601
0602 function showContextMenu(args) {
0603 if (isSeparator && !root.inEditMode)
0604 return;
0605
0606 if (!root.contextMenu) {
0607 contextMenu = root.createContextMenu(taskItem, modelIndex(), args);
0608 contextMenu.show();
0609 } else {
0610 //! make sure that context menu isnt deleted multiple times and creates a crash
0611 //! bug case: 397635
0612 var cMenu = root.contextMenu;
0613 root.contextMenu = null;
0614 cMenu.destroy();
0615 }
0616 }
0617
0618 function modifierAccepted(mouse){
0619 if (mouse.modifiers & root.modifierQt){
0620 if ((mouse.button === Qt.LeftButton && root.modifierClick === LatteTasks.Types.LeftClick)
0621 || (mouse.button === Qt.MiddleButton && root.modifierClick === LatteTasks.Types.MiddleClick)
0622 || (mouse.button === Qt.RightButton && root.modifierClick === LatteTasks.Types.RightClick))
0623 return true;
0624 }
0625
0626 return false;
0627 }
0628
0629 function setBlockingAnimation(value){
0630 inBlockingAnimation = value;
0631 }
0632
0633 function slotShowPreviewForTasks(group) {
0634 if (group === taskItem && !windowsPreviewDlg.visible) {
0635 preparePreviewWindow(true);
0636 windowsPreviewDlg.show(taskItem);
0637 }
0638 }
0639
0640 function slotPublishGeometries() {
0641 //! this way we make sure that layouts that are in different activities that the current layout
0642 //! don't publish their geometries
0643 if ( canPublishGeometries && (!taskItem.abilities.myView.isReady || (taskItem.abilities.myView.isReady && taskItem.abilities.myView.inCurrentLayout()))) {
0644 var globalChoords = backend.globalRect(taskItem.parabolicItem.contentItemContainer);
0645 var limits = backend.globalRect(scrollableList);
0646
0647 //! Limit the published geometries boundaries at scrolling area boundaries
0648 var adjX = Math.min(limits.x+limits.width, Math.max(limits.x, globalChoords.x));
0649 var adjY = Math.min(limits.y+limits.height, Math.max(limits.y, globalChoords.y));
0650
0651 var length = taskItem.abilities.metrics.iconSize * taskItem.parabolicItem.zoom;
0652 var thickness = length;
0653
0654 //! Magic Lamp effect doesn't like coordinates outside the screen and
0655 //! width,heights of zero value... So we now normalize the geometries
0656 //! sent in order to avoid such circumstances
0657 if (root.vertical) {
0658 if (adjY !== globalChoords.y) {
0659 if (((globalChoords.y+globalChoords.height) < limits.y) || (globalChoords.y)>(limits.y+limits.height)) {
0660 //! totally out of boundaries
0661 length = 4;
0662 } else {
0663 //! semi-part out of boundaries
0664 length = Math.max(4, Math.abs(adjY - globalChoords.y));
0665 }
0666
0667 globalChoords.height = length;
0668 }
0669 } else {
0670 if (adjX !== globalChoords.x) {
0671 if (((globalChoords.x+globalChoords.width) < limits.x) || (globalChoords.x)>(limits.x+limits.width)) {
0672 //! totally out of boundaries
0673 length = 4;
0674 } else {
0675 //! semi-part out of boundaries
0676 length = Math.max(4, Math.abs(adjX - globalChoords.x));
0677 }
0678
0679 globalChoords.width = length;
0680 }
0681 }
0682
0683 globalChoords.x = adjX;
0684 globalChoords.y = adjY;
0685
0686 if (taskItem.abilities.myView.isHidden) {
0687 if (root.location === PlasmaCore.Types.BottomEdge) {
0688 globalChoords.y = taskItem.abilities.myView.screenGeometry.y + taskItem.abilities.myView.screenGeometry.height-1;
0689 globalChoords.height = 1;
0690 } else if (root.location === PlasmaCore.Types.TopEdge) {
0691 globalChoords.y = taskItem.abilities.myView.screenGeometry.y+1;
0692 globalChoords.height = 1;
0693 } else if (root.location === PlasmaCore.Types.LeftEdge) {
0694 globalChoords.x = taskItem.abilities.myView.screenGeometry.x+1;
0695 globalChoords.width = 1;
0696 } else if (root.location === PlasmaCore.Types.RightEdge) {
0697 globalChoords.x = taskItem.abilities.myView.screenGeometry.x + taskItem.abilities.myView.screenGeometry.width - 1;
0698 globalChoords.width = 1;
0699 }
0700 }
0701
0702 tasksModel.requestPublishDelegateGeometry(taskItem.modelIndex(), globalChoords, taskItem);
0703 }
0704 }
0705
0706 function slotWaitingLauncherRemoved(launch) {
0707 if ((isWindow || isStartup || isLauncher) && !visible && launch === launcherUrl) {
0708 if (!taskItem.abilities.indicators.info.providesTaskLauncherAnimation) {
0709 //! this is needed only from in-built launcher animation to restore zoom smoothly
0710 taskItem.parabolicItem.zoom = 1;
0711 }
0712 visible = true;
0713 }
0714 }
0715
0716
0717 function updateAudioStreams() {
0718 if (root.dragSource !== null) {
0719 audioStreams = [];
0720 return;
0721 }
0722
0723 var pa = pulseAudio.item;
0724 if (!pa) {
0725 audioStreams = [];
0726 return;
0727 }
0728
0729 var streams = pa.streamsForPid(taskItem.pid);
0730 if (streams.length) {
0731 pa.registerPidMatch(taskItem.appName);
0732 } else {
0733 // We only want to fall back to appName matching if we never managed to map
0734 // a PID to an audio stream window. Otherwise if you have two instances of
0735 // an application, one playing and the other not, it will look up appName
0736 // for the non-playing instance and erroneously show an indicator on both.
0737 if (!pa.hasPidMatch(taskItem.appName)) {
0738 streams = pa.streamsForAppName(taskItem.appName);
0739 }
0740 }
0741
0742 // fix a binding loop concerning audiostreams, the audiostreams
0743 // should be updated only when they have changed
0744 var changed = false;
0745
0746 if (streams.length !== audioStreams.length) {
0747 changed = true;
0748 } else {
0749 for(var i=0; i<streams.length; ++i) {
0750 if (streams[i] !== audioStreams[i]) {
0751 changed = true;
0752 break;
0753 }
0754 }
0755 }
0756
0757 if (changed) {
0758 taskItem.audioStreams = streams;
0759 }
0760 }
0761
0762 function onLauncherChanged(launcher) {
0763 if ((root.showWindowsOnlyFromLaunchers || root.disableAllWindowsFunctionality) && launcher === launcherUrl) {
0764 updateVisibilityBasedOnLaunchers()
0765 }
0766 }
0767
0768 function updateVisibilityBasedOnLaunchers(){
0769 var launcherExists = !(((tasksModel.launcherPosition(taskItem.launcherUrl) == -1)
0770 && (tasksModel.launcherPosition(taskItem.launcherUrlWithIcon) == -1) )
0771 || !taskItem.abilities.launchers.inCurrentActivity(taskItem.launcherUrl));
0772
0773 if (root.showWindowsOnlyFromLaunchers || root.disableAllWindowsFunctionality) {
0774 var hideWindow = !launcherExists && (taskItem.isWindow || root.disableAllWindowsFunctionality);
0775
0776 if (hideWindow) {
0777 isForcedHidden = true;
0778 taskRealRemovalAnimation.start();
0779 } else if (launcherExists && taskItem.isWindow && !taskItem.isVisible) {
0780 showWindowAnimation.showWindow();
0781 isForcedHidden = false;
0782 }
0783 } else {
0784 var showWindow = !launcherExists && taskItem.isWindow;
0785
0786 if (showWindow) {
0787 showWindowAnimation.showWindow();
0788 isForcedHidden = false;
0789 }
0790 }
0791 }
0792
0793 function toggleMuted() {
0794 if (muted) {
0795 taskItem.audioStreams.forEach(function (item) { item.unmute(); });
0796 } else {
0797 taskItem.audioStreams.forEach(function (item) { item.mute(); });
0798 }
0799 }
0800
0801 function increaseVolume() {
0802 taskItem.audioStreams.forEach(function (item) { item.increaseVolume(); });
0803 }
0804
0805 function decreaseVolume() {
0806 taskItem.audioStreams.forEach(function (item) { item.decreaseVolume(); });
0807 }
0808
0809 function updateBadge() {
0810 var badger = root.getBadger(launcherUrl);
0811
0812 if (badger) {
0813 badgeIndicator = parseInt(badger.value);
0814 } else {
0815 badgeIndicator = 0;
0816 }
0817 }
0818
0819 Connections {
0820 target: pulseAudio.item
0821 ignoreUnknownSignals: true // Plasma-PA might not be available
0822 onStreamsChanged: taskItem.updateAudioStreams()
0823 }
0824
0825 //fix bug #478, when changing form factor sometimes the tasks are not positioned
0826 //correctly, in such case we make a fast reinitialization for the sizes
0827 Connections {
0828 target: plasmoid
0829 onFormFactorChanged:{
0830 taskItem.inAddRemoveAnimation = false;
0831 }
0832 }
0833
0834 Connections {
0835 target: root
0836 //trying to fix #440, showing the audio icon indicator to irrelevant tasks
0837 //after dragging an existent task with audio
0838 onDragSourceChanged: taskItem.updateAudioStreams()
0839 onShowAudioBadgeChanged: taskItem.updateAudioStreams()
0840
0841 onDisableAllWindowsFunctionalityChanged: {
0842 if (!root.inEditMode) {
0843 return;
0844 }
0845
0846 taskItem.updateVisibilityBasedOnLaunchers();
0847 }
0848
0849 onShowWindowsOnlyFromLaunchersChanged: {
0850 if (!root.inEditMode) {
0851 return;
0852 }
0853
0854 taskItem.updateVisibilityBasedOnLaunchers();
0855 }
0856
0857 onInActivityChangeChanged: {
0858 if ((root.showWindowsOnlyFromLaunchers || root.disableAllWindowsFunctionality) && !root.inActivityChange) {
0859 taskItem.updateVisibilityBasedOnLaunchers();
0860 }
0861 }
0862 }
0863
0864 Connections {
0865 target: scrollableList
0866 onAnimationsFinishedChanged: {
0867 if (scrollableList.animationsFinished) {
0868 taskItem.slotPublishGeometries();
0869 }
0870 }
0871 }
0872
0873 Connections {
0874 target: taskItem.abilities.myView
0875 onIsHiddenChanged: {
0876 if (taskItem.abilities.myView.isHidden) {
0877 taskItem.slotPublishGeometries();
0878 }
0879 }
0880
0881 onIsShownFullyChanged: {
0882 if (taskItem.abilities.myView.isShownFully) {
0883 taskItem.slotPublishGeometries();
0884 }
0885 }
0886 }
0887
0888 ///// End of Helper functions ////
0889
0890 Component.onCompleted: {
0891 parabolicItem.opacity = 0;
0892
0893 root.draggingFinished.connect(handlerDraggingFinished);
0894 root.publishTasksGeometries.connect(slotPublishGeometries);
0895 root.showPreviewForTasks.connect(slotShowPreviewForTasks);
0896
0897 taskItem.abilities.launchers.launcherChanged.connect(onLauncherChanged);
0898 taskItem.abilities.launchers.launcherRemoved.connect(onLauncherChanged);
0899
0900 //startup without launcher
0901 var hideStartup = ((!hasShownLauncher || !taskItem.abilities.launchers.inCurrentActivity(taskItem.launcherUrl))
0902 && taskItem.isStartup);
0903
0904 if (!LatteCore.WindowSystem.compositingActive) {
0905 visible = true;
0906 } else if ( (isWindow || isStartup || isLauncher) && tasksExtendedManager.waitingLauncherExists(launcherUrl)) {
0907 tasksExtendedManager.waitingLauncherRemoved.connect(slotWaitingLauncherRemoved);
0908 visible = false;
0909 } else if (hideStartup){
0910 visible = false;
0911 } else {
0912 visible = true;
0913 }
0914
0915 showWindowAnimation.showWindow();
0916 updateAudioStreams();
0917 }
0918
0919 Component.onDestruction: {
0920 root.draggingFinished.disconnect(handlerDraggingFinished);
0921 root.publishTasksGeometries.disconnect(slotPublishGeometries);
0922 root.showPreviewForTasks.disconnect(slotShowPreviewForTasks);
0923
0924 taskItem.abilities.launchers.launcherChanged.disconnect(onLauncherChanged);
0925 taskItem.abilities.launchers.launcherRemoved.disconnect(onLauncherChanged);
0926
0927 tasksExtendedManager.waitingLauncherRemoved.disconnect(slotWaitingLauncherRemoved);
0928
0929 taskItem.parabolicItem.sendEndOfNeedBothAxisAnimation();
0930 }
0931
0932 /////Animations
0933 TaskAnimations.ShowWindowAnimation{ id: _showWindowAnimation }
0934
0935 // when changing activities and desktops the index of the tasks
0936 // is updated immediately to -1, this timer protects this indexing
0937 // change in order to provide a beautiful removal tasks animation
0938 Timer {
0939 id: lastValidTimer
0940 interval: 100 ///the interval does not follow the animations timing
0941 repeat: false
0942
0943 onTriggered: {
0944 if (taskItem.itemIndex >= 0){
0945 taskItem.lastValidIndex = taskItem.itemIndex;
0946 }
0947
0948 if (taskItem.abilities.debug.timersEnabled) {
0949 console.log("plasmoid timer: lastValidTimer called...");
0950 }
0951 }
0952 }
0953
0954 ///Item's Removal Animation
0955 ListView.onRemove: TaskAnimations.RealRemovalAnimation{ id: taskRealRemovalAnimation }
0956
0957 onIsLauncherAnimationRunningChanged: {
0958 if (!isLauncherAnimationRunning && taskRealRemovalAnimation.paused) {
0959 taskRealRemovalAnimation.resume();
0960 }
0961 }
0962 }// main Item
0963