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