diff --git a/containment/package/contents/config/main.xml b/containment/package/contents/config/main.xml
index 73184e10..ee2e1699 100644
--- a/containment/package/contents/config/main.xml
+++ b/containment/package/contents/config/main.xml
@@ -1,335 +1,346 @@
0
10
64
0.2
20
0
false
-1
false
true
6
true
false
100
false
true
true
true
true
false
false
false
0
0
-1
-1
2
0
70
30
080808
false
100
0
false
6
2
0
0
0
1
0
false
true
2
true
true
true
true
true
0
false
false
true
false
false
true
true
true
true
true
true
true
-
+
false
+
+ true
+
+
+
+
+
+
+
+ 1
+
true
diff --git a/containment/package/contents/ui/main.qml b/containment/package/contents/ui/main.qml
index 2df91911..cb83f269 100644
--- a/containment/package/contents/ui/main.qml
+++ b/containment/package/contents/ui/main.qml
@@ -1,1855 +1,1858 @@
/*
* Copyright 2016 Smith AR
* Michail Vourlakos
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import QtQuick 2.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.kquickcontrolsaddons 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.latte 0.2 as Latte
import "applet" as Applet
import "colorizer" as Colorizer
import "editmode" as EditMode
import "indicators" as Indicators
import "layouts" as Layouts
import "../code/LayoutManager.js" as LayoutManager
Item {
id: root
objectName: "containmentViewLayout"
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft && !root.isVertical
LayoutMirroring.childrenInherit: true
//// BEGIN SIGNALS
signal clearZoomSignal();
signal destroyInternalViewSplitters();
signal emptyAreasWheel(QtObject wheel);
signal separatorsUpdated();
signal signalActivateEntryAtIndex(int entryIndex);
signal signalNewInstanceForEntryAtIndex(int entryIndex);
signal updateEffectsArea();
signal updateIndexes();
signal updateScale(int delegateIndex, real newScale, real step);
signal broadcastedToApplet(string pluginName, string action, variant value);
//// END SIGNALS
////BEGIN properties
property bool debugMode: Qt.application.arguments.indexOf("--graphics")>=0
property bool debugModeSpacers: Qt.application.arguments.indexOf("--spacers")>=0
property bool debugModeTimers: Qt.application.arguments.indexOf("--timers")>=0
property bool debugModeWindow: Qt.application.arguments.indexOf("--with-window")>=0
property bool debugModeOverloadedIcons: Qt.application.arguments.indexOf("--overloaded-icons")>=0
property bool globalDirectRender: false //it is used as a globalDirectRender for all elements in the dock
property int directRenderAnimationTime: 0
property bool addLaunchersMessage: false
property bool addLaunchersInTaskManager: plasmoid.configuration.addLaunchersInTaskManager
// when there are only plasma style task managers OR any applets that fill width or height
// the automatic icon size algorithm should better be disabled
property bool autoDecreaseIconSize: !containsOnlyPlasmaTasks && layoutsContainer.fillApplets<=0
property bool backgroundOnlyOnMaximized: plasmoid.configuration.backgroundOnlyOnMaximized
property bool behaveAsPlasmaPanel: {
if (!latteView || !latteView.visibility) {
return false;
}
return (visibilityManager.panelIsBiggerFromIconSize && (maxZoomFactor === 1.0)
&& (latteView.visibility.mode === Latte.Types.AlwaysVisible || latteView.visibility.mode === Latte.Types.WindowsGoBelow)
&& (plasmoid.configuration.panelPosition === Latte.Types.Justify)
&& !root.editMode);
}
property int viewType: {
if ((plasmoid.configuration.panelPosition === Latte.Types.Justify)
&& (plasmoid.configuration.useThemePanel)
&& (plasmoid.configuration.panelSize === 100)
&& (maxZoomFactor === 1.0)) {
return Latte.Types.PanelView;
}
return Latte.Types.DockView;
}
property bool blurEnabled: plasmoid.configuration.blurEnabled && (!forceTransparentPanel || forcePanelForBusyBackground)
readonly property Item dragInfo: Item {
property bool entered: backDropArea.dragInfo.entered || foreDropArea.dragInfo.entered
property bool isTask: backDropArea.dragInfo.isTask || foreDropArea.dragInfo.isTask
property bool isPlasmoid: backDropArea.dragInfo.isPlasmoid || foreDropArea.dragInfo.isPlasmoid
property bool isSeparator: backDropArea.dragInfo.isSeparator || foreDropArea.dragInfo.isSeparator
property bool isLatteTasks: backDropArea.dragInfo.isLatteTasks || foreDropArea.dragInfo.isLatteTasks
property bool onlyLaunchers: backDropArea.dragInfo.onlyLaunchers || foreDropArea.dragInfo.onlyLaunchers
// onIsPlasmoidChanged: console.log("isPlasmoid :: " + backDropArea.dragInfo.isPlasmoid + " _ " + foreDropArea.dragInfo.isPlasmoid );
// onEnteredChanged: console.log("entered :: " + backDropArea.dragInfo.entered + " _ " + foreDropArea.dragInfo.entered );
}
property bool containsOnlyPlasmaTasks: false //this is flag to indicate when from tasks only a plasma based one is found
property bool dockContainsMouse: latteView && latteView.visibility ? latteView.visibility.containsMouse : false
property bool disablePanelShadowMaximized: plasmoid.configuration.disablePanelShadowForMaximized && Latte.WindowSystem.compositingActive
property bool drawShadowsExternal: panelShadowsActive && behaveAsPlasmaPanel && !visibilityManager.inTempHiding
property bool editMode: editModeVisual.inEditMode
property bool windowIsTouching: latteView && latteView.windowsTracker
&& (latteView.windowsTracker.activeWindowTouching || hasExpandedApplet)
property bool forceSolidPanel: (latteView && latteView.visibility
&& Latte.WindowSystem.compositingActive
&& !inConfigureAppletsMode
&& userShowPanelBackground
&& ( (plasmoid.configuration.solidBackgroundForMaximized
&& !(hasExpandedApplet && !plasmaBackgroundForPopups)
&& latteView.windowsTracker.existsWindowTouching)
|| (hasExpandedApplet && plasmaBackgroundForPopups) ))
|| !Latte.WindowSystem.compositingActive
property bool forceTransparentPanel: root.backgroundOnlyOnMaximized
&& latteView && latteView.visibility
&& Latte.WindowSystem.compositingActive
&& !inConfigureAppletsMode
&& !forceSolidPanel
&& !(windowColors === Latte.Types.TouchingWindowColors && latteView.windowsTracker.activeWindowTouching)
&& !(windowColors === Latte.Types.ActiveWindowColors && latteView.windowsTracker.existsWindowActive)
property bool forcePanelForBusyBackground: userShowPanelBackground && root.forceTransparentPanel
&& colorizerManager.mustBeShown && colorizerManager.backgroundIsBusy
property int themeColors: plasmoid.configuration.themeColors
property int windowColors: plasmoid.configuration.windowColors
property bool colorizerEnabled: themeColors !== Latte.Types.PlasmaThemeColors || windowColors !== Latte.Types.NoneWindowColors
property bool plasmaBackgroundForPopups: plasmoid.configuration.plasmaBackgroundForPopups
readonly property bool hasExpandedApplet: plasmoid.applets.some(function (item) {
return (item.status >= PlasmaCore.Types.NeedsAttentionStatus && item.status !== PlasmaCore.Types.HiddenStatus
&& item.pluginName !== root.plasmoidName
&& item.pluginName !== "org.kde.plasma.appmenu"
&& item.pluginName !== "org.kde.windowappmenu"
&& item.pluginName !== "org.kde.activeWindowControl");
})
readonly property bool hasUserSpecifiedBackground: (latteView && latteView.layout && latteView.layout.background.startsWith("/")) ?
true : false
readonly property bool inConfigureAppletsMode: root.editMode && (plasmoid.configuration.inConfigureAppletsMode || !Latte.WindowSystem.compositingActive)
readonly property bool parabolicEffectEnabled: zoomFactor>1 && !inConfigureAppletsMode
property bool dockIsShownCompletely: !(dockIsHidden || inSlidingIn || inSlidingOut) && !root.editMode
property bool dragActiveWindowEnabled: plasmoid.configuration.dragActiveWindowEnabled
property bool immutable: plasmoid.immutable
property bool inFullJustify: (plasmoid.configuration.panelPosition === Latte.Types.Justify) && (plasmoid.configuration.maxLength===100)
property bool inSlidingIn: visibilityManager ? visibilityManager.inSlidingIn : false
property bool inSlidingOut: visibilityManager ? visibilityManager.inSlidingOut : false
property bool inStartup: true
property bool isHalfShown: false //is used to disable the zoom hovering effect at sliding in-out the dock
property bool isHorizontal: plasmoid.formFactor === PlasmaCore.Types.Horizontal
property bool isReady: !(dockIsHidden || inSlidingIn || inSlidingOut)
property bool isVertical: !isHorizontal
property bool isHovered: latteApplet ? ((latteAppletHoveredIndex !== -1) || (layoutsContainer.hoveredIndex !== -1)) //|| wholeArea.containsMouse
: (layoutsContainer.hoveredIndex !== -1) //|| wholeArea.containsMouse
property bool mouseWheelActions: plasmoid.configuration.mouseWheelActions
property bool onlyAddingStarup: true //is used for the initialization phase in startup where there aren't removals, this variable provides a way to grow icon size
property bool shrinkThickMargins: plasmoid.configuration.shrinkThickMargins
property bool showLatteShortcutBadges: false
property bool showAppletShortcutBadges: false
property bool showMetaBadge: false
property int applicationLauncherId: -1
//FIXME: possibly this is going to be the default behavior, this user choice
//has been dropped from the Dock Configuration Window
//property bool smallAutomaticIconJumps: plasmoid.configuration.smallAutomaticIconJumps
property bool smallAutomaticIconJumps: true
property bool userShowPanelBackground: Latte.WindowSystem.compositingActive ? plasmoid.configuration.useThemePanel : true
property bool useThemePanel: noApplets === 0 || !Latte.WindowSystem.compositingActive ?
true : (plasmoid.configuration.useThemePanel || plasmoid.configuration.solidBackgroundForMaximized)
property alias hoveredIndex: layoutsContainer.hoveredIndex
property alias directRenderDelayerIsRunning: directRenderDelayerForEnteringTimer.running
property int actionsBlockHiding: 0 //actions that block hiding
property int animationsNeedBothAxis:0 //animations need space in both axes, e.g zooming a task
property int animationsNeedLength: 0 // animations need length, e.g. adding a task
property int animationsNeedThickness: 0 // animations need thickness, e.g. bouncing animation
readonly property bool thickAnimated: animationsNeedBothAxis>0 || animationsNeedThickness>0
property int animationTime: durationTime*2.8*units.longDuration
property int automaticIconSizeBasedSize: -1 //it is not set, this is the defautl
//what is the highest icon size based on what icon size is used, screen calculated or user specified
property int maxIconSize: proportionIconSize!==-1 ? proportionIconSize : plasmoid.configuration.iconSize
property int iconSize: automaticIconSizeBasedSize > 0 && autoDecreaseIconSize ?
Math.min(automaticIconSizeBasedSize, root.maxIconSize) :
root.maxIconSize
property int proportionIconSize: { //icon size based on screen height
if ((plasmoid.configuration.proportionIconSize===-1) || !latteView)
return -1;
return Math.max(16,Math.round(latteView.screenGeometry.height * plasmoid.configuration.proportionIconSize/100/8)*8);
}
property int iconStep: 8
property int latteAppletPos: -1
property int maxLength: {
if (root.isHorizontal) {
return behaveAsPlasmaPanel ? width : width * (plasmoid.configuration.maxLength/100)
} else {
return behaveAsPlasmaPanel ? height : height * (plasmoid.configuration.maxLength/100)
}
}
property int leftClickAction: plasmoid.configuration.leftClickAction
property int middleClickAction: plasmoid.configuration.middleClickAction
property int hoverAction: plasmoid.configuration.hoverAction
property int modifier: plasmoid.configuration.modifier
property int modifierClickAction: plasmoid.configuration.modifierClickAction
property int modifierClick: plasmoid.configuration.modifierClick
property int scrollAction: plasmoid.configuration.scrollAction
property bool panelOutline: plasmoid.configuration.panelOutline
property int panelEdgeSpacing: Math.max(panelBoxBackground.lengthMargins, 1.5*appShadowSize)
property int panelTransparency: plasmoid.configuration.panelTransparency //user set
property int currentPanelTransparency: 0 //application override
readonly property real currentPanelOpacity: currentPanelTransparency/100
property bool panelShadowsActive: {
if (!userShowPanelBackground) {
return false;
}
if (inConfigureAppletsMode) {
return plasmoid.configuration.panelShadows;
}
//! Draw shadows for isBusy state only when current panelTransparency is greater than 40%
if (plasmoid.configuration.panelShadows && root.forcePanelForBusyBackground && currentPanelTransparency>40) {
return true;
}
if (( (plasmoid.configuration.panelShadows && !root.backgroundOnlyOnMaximized)
|| (plasmoid.configuration.panelShadows && root.backgroundOnlyOnMaximized && !root.forceTransparentPanel))
&& !(disablePanelShadowMaximized && latteView && latteView.windowsTracker
&& latteView.windowsTracker.activeWindowMaximized)) {
return true;
}
if (hasExpandedApplet && plasmaBackgroundForPopups) {
return true;
}
return false;
}
property int appShadowOpacity: (plasmoid.configuration.shadowOpacity/100) * 255
property int appShadowSize: enableShadows ? (0.5*root.iconSize) * (plasmoid.configuration.shadowSize/100) : 0
property int appShadowSizeOriginal: enableShadows ? (0.5*maxIconSize) * (plasmoid.configuration.shadowSize/100) : 0
property string appChosenShadowColor: {
if (plasmoid.configuration.shadowColorType === Latte.Types.ThemeColorShadow) {
var strC = String(theme.textColor);
return strC.indexOf("#") === 0 ? strC.substr(1) : strC;
} else if (plasmoid.configuration.shadowColorType === Latte.Types.UserColorShadow) {
return plasmoid.configuration.shadowColor;
}
// default shadow color
return "080808";
}
property string appShadowColor: "#" + decimalToHex(appShadowOpacity) + appChosenShadowColor
property string appShadowColorSolid: "#" + appChosenShadowColor
property int totalPanelEdgeSpacing: 0 //this is set by PanelBox
//FIXME: this is not needed any more probably
property int previousAllTasks: -1 //is used to forbid updateAutomaticIconSize when hovering
property int offset: {
if (behaveAsPlasmaPanel) {
return 0;
}
if (root.isHorizontal) {
return width * (plasmoid.configuration.offset/100);
} else {
height * (plasmoid.configuration.offset/100)
}
}
//center the layout correctly when the user uses an offset
property int offsetFixed: (offset===0 || panelAlignment === Latte.Types.Center || plasmoid.configuration.panelPosition === Latte.Types.Justify)?
offset : offset+panelMarginLength/2+totalPanelEdgeSpacing/2
property int realPanelSize: 0
property int realPanelLength: 0
property int realPanelThickness: 0
//this is set by the PanelBox
property int panelThickMarginBase: 0
property int panelThickMarginHigh: 0
property int panelMarginLength: 0
property int panelShadow: 0 //shadowsSize
property int editShadow: {
if (!Latte.WindowSystem.compositingActive) {
return 0;
} else if (latteView && latteView.screenGeometry) {
return latteView.screenGeometry.height/90;
} else {
return 7;
}
}
property int themePanelThickness: {
var panelBase = root.panelThickMarginHigh;
var margin = shrinkThickMargins ? 0 : thickMargins;
var maxPanelSize = (iconSize + margin) - panelBase;
var percentage = Latte.WindowSystem.compositingActive ? plasmoid.configuration.panelSize/100 : 1;
return Math.max(panelBase, panelBase + percentage*maxPanelSize);
}
property int lengthIntMargin: lengthIntMarginFactor * root.iconSize
property int lengthExtMargin: lengthExtMarginFactor * root.iconSize
property real lengthIntMarginFactor: indicators.isEnabled ? indicators.padding : 0
property real lengthExtMarginFactor: plasmoid.configuration.lengthExtMargin / 100
property real thickMarginFactor: {
if (shrinkThickMargins) {
return indicators.info.minThicknessPadding;
}
//0.075 old statesLineSize and 0.06 old default thickMargin
return Math.max(indicators.info.minThicknessPadding, plasmoid.configuration.thickMargin / 100)
}
property int thickMargin: thickMarginFactor * root.iconSize
//! thickness margins are always two and equal in order for items
//! to be always correctly centered
property int thickMargins: 2 * thickMargin
//it is used in order to not break the calculations for the thickness placement
//especially in automatic icon sizes calculations
property int maxThickMargin: thickMarginFactor * maxIconSize
property int lengthMargin: lengthIntMargin + lengthExtMargin
property int lengthMargins: 2 * lengthMargin
property int widthMargins: root.isVertical ? thickMargins : lengthMargins
property int heightMargins: root.isHorizontal ? thickMargins : lengthMargins
property int internalWidthMargins: root.isVertical ? thickMargins : 2 * lengthIntMargin
property int internalHeightMargins: root.isHorizontal ? thickMargins : 2 * lengthIntMargin
///FIXME: I can't remember why this is needed, maybe for the anchorings!!! In order for the Double Layout to not mess the anchorings...
//property int layoutsContainer.mainLayoutPosition: !plasmoid.immutable ? Latte.Types.Center : (root.isVertical ? Latte.Types.Top : Latte.Types.Left)
//property int panelAlignment: plasmoid.configuration.panelPosition !== Latte.Types.Justify ? plasmoid.configuration.panelPosition : layoutsContainer.mainLayoutPosition
property int panelAlignment: !root.inConfigureAppletsMode ? plasmoid.configuration.panelPosition :
( plasmoid.configuration.panelPosition === Latte.Types.Justify ?
Latte.Types.Center : plasmoid.configuration.panelPosition )
property int panelUserSetAlignment: plasmoid.configuration.panelPosition
property real zoomFactor: Latte.WindowSystem.compositingActive && root.animationsEnabled ? ( 1 + (plasmoid.configuration.zoomLevel / 20) ) : 1
readonly property string plasmoidName: "org.kde.latte.plasmoid"
property var badgesForActivate: {
if (!shortcutsEngine) {
return ['1','2','3','4','5','6','7','8','9','0', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.'];
}
return shortcutsEngine.badgesForActivate;
}
property var iconsArray: [16, 22, 32, 48, 64, 96, 128, 256]
property Item dragOverlay
property Item toolBox
property Item latteAppletContainer
property Item latteApplet
readonly property Item indicatorsManager: indicators
readonly property Item parabolicManager: _parabolicManager
readonly property Item maskManager: visibilityManager
readonly property Item layoutsContainerItem: layoutsContainer
property QtObject latteView: null
property QtObject shortcutsEngine: null
property QtObject themeExtended: null
property QtObject universalSettings: null
property QtObject layoutsManager: null
property QtObject viewLayout: latteView && latteView.layout ? latteView.layout : null
// TO BE DELETED, if not needed: property int counter:0;
///BEGIN properties provided to Latte Plasmoid
//shadows for applets, it should be removed as the appleitems don't need it any more
property bool enableShadows: plasmoid.configuration.shadows || (root.forceTransparentPanel && plasmoid.configuration.shadows>0)
property bool dockIsHidden: latteView ? latteView.visibility.isHidden : true
property bool groupTasksByDefault: plasmoid.configuration.groupTasksByDefault
property bool showInfoBadge: plasmoid.configuration.showInfoBadge
property bool showProgressBadge: plasmoid.configuration.showProgressBadge
property bool showAudioBadge: plasmoid.configuration.showAudioBadge
property bool audioBadgeActionsEnabled: plasmoid.configuration.audioBadgeActionsEnabled
- property bool scrollingTasksEnabled: plasmoid.configuration.scrollingTasksEnabled
+ property bool scrollTasksEnabled: plasmoid.configuration.scrollTasksEnabled
+ property bool autoScrollTasksEnabled: plasmoid.configuration.autoScrollTasksEnabled
+ property int manualScrollTasksType: plasmoid.configuration.manualScrollTasksType
+
property bool showWindowActions: plasmoid.configuration.showWindowActions
property bool showWindowsOnlyFromLaunchers: plasmoid.configuration.showWindowsOnlyFromLaunchers
property bool showOnlyCurrentScreen: plasmoid.configuration.showOnlyCurrentScreen
property bool showOnlyCurrentDesktop: plasmoid.configuration.showOnlyCurrentDesktop
property bool showOnlyCurrentActivity: plasmoid.configuration.showOnlyCurrentActivity
property bool titleTooltips: plasmoid.configuration.titleTooltips
property bool unifiedGlobalShortcuts: plasmoid.configuration.unifiedGlobalShortcuts
readonly property bool hasInternalSeparator: latteApplet ? latteApplet.hasInternalSeparator : false
property int animationStep: {
if (!universalSettings || universalSettings.mouseSensitivity === Latte.Types.HighSensitivity) {
return 1;
} else if (universalSettings.mouseSensitivity === Latte.Types.MediumSensitivity) {
return Math.max(3, root.iconSize / 18);
} else if (universalSettings.mouseSensitivity === Latte.Types.LowSensitivity) {
return Math.max(5, root.iconSize / 10);
}
}
property int latteAppletHoveredIndex: latteApplet ? latteApplet.hoveredIndex : -1
property int launchersGroup: plasmoid.configuration.launchersGroup
property int tasksCount: latteApplet ? latteApplet.tasksCount : 0
//! Animations
property bool animationsEnabled: plasmoid.configuration.animationsEnabled && Latte.WindowSystem.compositingActive
property bool animationLauncherBouncing: animationsEnabled && latteApplet && plasmoid.configuration.animationLauncherBouncing
property bool animationWindowInAttention: animationsEnabled && latteApplet && plasmoid.configuration.animationWindowInAttention
property bool animationNewWindowSliding: animationsEnabled && latteApplet && plasmoid.configuration.animationNewWindowSliding
property bool animationWindowAddedInGroup: animationsEnabled && latteApplet && plasmoid.configuration.animationWindowAddedInGroup
property bool animationWindowRemovedFromGroup: animationsEnabled && latteApplet && plasmoid.configuration.animationWindowRemovedFromGroup
property real appliedDurationTime: animationsEnabled ? durationTime : 2
property real durationTime: {
if (!animationsEnabled) {
return 0;
}
/*if ((latteView && latteView.effects && latteView.effects.animationsBlocked)
|| !animationsEnabled) {
return 0;
}*/
if (plasmoid.configuration.durationTime === 0 || plasmoid.configuration.durationTime === 2 )
return plasmoid.configuration.durationTime;
if (plasmoid.configuration.durationTime === 1)
return 1.65;
else if (plasmoid.configuration.durationTime === 3)
return 2.35;
return 2;
}
property real animationsZoomFactor : {
if (!animationsEnabled) {
return 1;
}
if (latteApplet && (animationLauncherBouncing || animationWindowInAttention || animationWindowAddedInGroup)) {
return 1.65;
}
return 1;
}
property real maxZoomFactor: Math.max(zoomFactor, animationsZoomFactor)
property rect screenGeometry: latteView ? latteView.screenGeometry : plasmoid.screenGeometry
readonly property color minimizedDotColor: colorizerManager.minimizedDotColor
///END properties from latteApplet
Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground
//// BEGIN properties in functions
property int noApplets: {
var count1 = 0;
var count2 = 0;
count1 = layoutsContainer.mainLayout.children.length;
var tempLength = layoutsContainer.mainLayout.children.length;
for (var i=tempLength-1; i>=0; --i) {
var applet = layoutsContainer.mainLayout.children[i];
if (applet && (applet === dndSpacer || applet === lastSpacer || applet.isInternalViewSplitter))
count1--;
}
count2 = layoutsContainer.endLayout.children.length;
tempLength = layoutsContainer.endLayout.children.length;
for (var i=tempLength-1; i>=0; --i) {
var applet = layoutsContainer.endLayout.children[i];
if (applet && (applet === dndSpacer || applet === lastSpacer || applet.isInternalViewSplitter))
count2--;
}
return (count1 + count2);
}
///The index of user's current icon size
property int currentIconIndex:{
for(var i=iconsArray.length-1; i>=0; --i){
if(iconsArray[i] === iconSize){
return i;
}
}
return 3;
}
//// END properties in functions
////////////////END properties
//// BEGIN OF Behaviors
Behavior on thickMargin {
NumberAnimation {
duration: 0.8 * root.animationTime
easing.type: Easing.OutCubic
}
}
Behavior on lengthIntMargin {
NumberAnimation {
duration: 0.8 * root.animationTime
easing.type: Easing.OutCubic
}
}
Behavior on lengthExtMargin {
NumberAnimation {
duration: 0.8 * root.animationTime
easing.type: Easing.OutCubic
}
}
Behavior on iconSize {
enabled: !(root.editMode && root.behaveAsPlasmaPanel)
NumberAnimation {
duration: 0.8 * root.animationTime
onRunningChanged: {
if (!running) {
delayUpdateMaskArea.start();
}
}
}
}
Behavior on offset {
enabled: editModeVisual.editAnimationInFullThickness
NumberAnimation {
id: offsetAnimation
duration: 0.8 * root.animationTime
easing.type: Easing.OutCubic
}
}
//// END OF Behaviors
//////////////START OF CONNECTIONS
onContainsOnlyPlasmaTasksChanged: updateAutomaticIconSize();
onEditModeChanged: {
if (editMode) {
visibilityManager.updateMaskArea();
updateAutomaticIconSize();
clearZoom();
} else {
updateAutomaticIconSize();
layoutsContainer.updateSizeForAppletsInFill();
}
//! This is used in case the dndspacer has been left behind
//! e.g. the user drops a folder and a context menu is appearing
//! but the user decides to not make a choice for the applet type
if (dndSpacer.parent !== root) {
dndSpacer.parent = root;
}
}
onInConfigureAppletsModeChanged: {
if (inConfigureAppletsMode && panelUserSetAlignment===Latte.Types.Justify) {
joinLayoutsToMainLayout();
} else if (!inConfigureAppletsMode) {
splitMainLayoutToLayouts();
}
updateIndexes();
}
//! It is used only when the user chooses different alignment types
//! and not during startup
onPanelUserSetAlignmentChanged: {
if (!root.editMode) {
return;
}
if (!inConfigureAppletsMode){
if (panelUserSetAlignment===Latte.Types.Justify) {
addInternalViewSplitters();
splitMainLayoutToLayouts();
} else {
joinLayoutsToMainLayout();
root.destroyInternalViewSplitters();
}
} else {
if (panelUserSetAlignment===Latte.Types.Justify) {
addInternalViewSplitters();
} else {
root.destroyInternalViewSplitters();
}
}
LayoutManager.save();
updateIndexes();
}
onLatteViewChanged: {
if (latteView) {
latteView.onXChanged.connect(visibilityManager.updateMaskArea);
latteView.onYChanged.connect(visibilityManager.updateMaskArea);
latteView.onWidthChanged.connect(visibilityManager.updateMaskArea);
latteView.onHeightChanged.connect(visibilityManager.updateMaskArea);
latteView.positioner.hideDockDuringLocationChangeStarted.connect(visibilityManager.slotHideDockDuringLocationChange);
latteView.positioner.showDockAfterLocationChangeFinished.connect(visibilityManager.slotShowDockAfterLocationChange);
latteView.positioner.hideDockDuringScreenChangeStarted.connect(visibilityManager.slotHideDockDuringLocationChange);
latteView.positioner.showDockAfterScreenChangeFinished.connect(visibilityManager.slotShowDockAfterLocationChange);
latteView.positioner.hideDockDuringMovingToLayoutStarted.connect(visibilityManager.slotHideDockDuringLocationChange);
latteView.positioner.showDockAfterMovingToLayoutFinished.connect(visibilityManager.slotShowDockAfterLocationChange);
latteView.visibility.onContainsMouseChanged.connect(visibilityManager.slotContainsMouseChanged);
latteView.visibility.onMustBeHide.connect(visibilityManager.slotMustBeHide);
latteView.visibility.onMustBeShown.connect(visibilityManager.slotMustBeShown);
updateContainsOnlyPlasmaTasks();
}
}
onDockContainsMouseChanged: {
if (!dockContainsMouse) {
initializeHoveredIndexes();
}
}
onMaxLengthChanged: {
layoutsContainer.updateSizeForAppletsInFill();
if (root.editMode) {
updateAutomaticIconSize();
}
}
onToolBoxChanged: {
if (toolBox) {
toolBox.visible = false;
}
}
property bool automaticSizeAnimation: false;
onAutomaticIconSizeBasedSizeChanged: {
if (!automaticSizeAnimation) {
automaticSizeAnimation = true;
slotAnimationsNeedBothAxis(1);
}
}
onIconSizeChanged: {
if (((iconSize === automaticIconSizeBasedSize) || (iconSize === root.maxIconSize)) && automaticSizeAnimation){
slotAnimationsNeedBothAxis(-1);
automaticSizeAnimation=false;
}
}
onIsReadyChanged: {
if (isReady && !titleTooltipDialog.visible && titleTooltipDialog.activeItemHovered){
titleTooltipDialog.show(titleTooltipDialog.activeItem, titleTooltipDialog.activeItemText);
}
}
onIsVerticalChanged: {
if (isVertical) {
if (plasmoid.configuration.panelPosition === Latte.Types.Left)
plasmoid.configuration.panelPosition = Latte.Types.Top;
else if (plasmoid.configuration.panelPosition === Latte.Types.Right)
plasmoid.configuration.panelPosition = Latte.Types.Bottom;
} else {
if (plasmoid.configuration.panelPosition === Latte.Types.Top)
plasmoid.configuration.panelPosition = Latte.Types.Left;
else if (plasmoid.configuration.panelPosition === Latte.Types.Bottom)
plasmoid.configuration.panelPosition = Latte.Types.Right;
}
}
onProportionIconSizeChanged: {
if (proportionIconSize!==-1)
updateAutomaticIconSize();
}
// onIconSizeChanged: console.log("Icon Size Changed:"+iconSize);
Component.onCompleted: {
// currentLayout.isLayoutHorizontal = isHorizontal
LayoutManager.plasmoid = plasmoid;
LayoutManager.root = root;
LayoutManager.layout = layoutsContainer.mainLayout;
LayoutManager.layoutS = layoutsContainer.startLayout;
LayoutManager.layoutE = layoutsContainer.endLayout;
LayoutManager.lastSpacer = lastSpacer;
LayoutManager.restore();
plasmoid.action("configure").visible = !plasmoid.immutable;
plasmoid.action("configure").enabled = !plasmoid.immutable;
inStartupTimer.start();
}
Component.onDestruction: {
console.debug("Destroying Latte Dock Containment ui...");
if (latteView) {
latteView.onXChanged.disconnect(visibilityManager.updateMaskArea);
latteView.onYChanged.disconnect(visibilityManager.updateMaskArea);
latteView.onWidthChanged.disconnect(visibilityManager.updateMaskArea);
latteView.onHeightChanged.disconnect(visibilityManager.updateMaskArea);
latteView.positioner.hideDockDuringLocationChangeStarted.disconnect(visibilityManager.slotHideDockDuringLocationChange);
latteView.positioner.showDockAfterLocationChangeFinished.disconnect(visibilityManager.slotShowDockAfterLocationChange);
latteView.positioner.hideDockDuringScreenChangeStarted.disconnect(visibilityManager.slotHideDockDuringLocationChange);
latteView.positioner.showDockAfterScreenChangeFinished.disconnect(visibilityManager.slotShowDockAfterLocationChange);
latteView.positioner.hideDockDuringMovingToLayoutStarted.disconnect(visibilityManager.slotHideDockDuringLocationChange);
latteView.positioner.showDockAfterMovingToLayoutFinished.disconnect(visibilityManager.slotShowDockAfterLocationChange);
if (latteView.visibility) {
latteView.visibility.onContainsMouseChanged.disconnect(visibilityManager.slotContainsMouseChanged);
latteView.visibility.onMustBeHide.disconnect(visibilityManager.slotMustBeHide);
latteView.visibility.onMustBeShown.disconnect(visibilityManager.slotMustBeShown);
}
}
}
Containment.onAppletAdded: {
addApplet(applet, x, y);
console.log(applet.pluginName);
LayoutManager.save();
updateIndexes();
}
Containment.onAppletRemoved: {
LayoutManager.removeApplet(applet);
var flexibleFound = false;
for (var i = 0; i < layoutsContainer.mainLayout.children.length; ++i) {
var applet = layoutsContainer.mainLayout.children[i].applet;
if (applet && ((root.isHorizontal && applet.Layout.fillWidth) ||
(!root.isHorizontal && applet.Layout.fillHeight)) &&
applet.visible) {
flexibleFound = true;
break
}
}
if (!flexibleFound) {
lastSpacer.parent = layoutsContainer.mainLayout;
}
console.log(applet.pluginName);
LayoutManager.save();
updateIndexes();
updateContainsOnlyPlasmaTasks();
}
Plasmoid.onUserConfiguringChanged: {
if (plasmoid.immutable) {
if (dragOverlay) {
dragOverlay.destroy();
}
return;
}
// console.debug("user configuring", plasmoid.userConfiguring)
if (plasmoid.userConfiguring) {
latteView.setBlockHiding(true);
// console.log("applets------");
for (var i = 0; i < plasmoid.applets.length; ++i) {
// console.log("applet:"+i);
plasmoid.applets[i].expanded = false;
}
if (!dragOverlay) {
var component = Qt.createComponent("editmode/ConfigOverlay.qml");
if (component.status == Component.Ready) {
dragOverlay = component.createObject(root);
} else {
console.log("Could not create ConfigOverlay");
console.log(component.errorString());
}
component.destroy();
} else {
dragOverlay.visible = true;
}
} else {
latteView.setBlockHiding(false);
if (latteView.visibility.isHidden) {
latteView.visibility.mustBeShown();
}
if (dragOverlay) {
dragOverlay.visible = false;
dragOverlay.destroy();
}
}
}
Plasmoid.onImmutableChanged: {
plasmoid.action("configure").visible = !plasmoid.immutable;
plasmoid.action("configure").enabled = !plasmoid.immutable;
///Set Preferred Sizes///
///Notice: they are set here because if they are set with a binding
///they break the !immutable experience, the latteView becomes too small
///to add applets
/* if (plasmoid.immutable) {
if(root.isHorizontal) {
root.Layout.preferredWidth = (plasmoid.configuration.panelPosition === Latte.Types.Justify ?
layoutsContainer.width + 0.5*iconMargin : layoutsContainer.mainLayout.width + iconMargin);
} else {
root.Layout.preferredHeight = (plasmoid.configuration.panelPosition === Latte.Types.Justify ?
layoutsContainer.height + 0.5*iconMargin : layoutsContainer.mainLayout.height + iconMargin);
}
} else {
if (root.isHorizontal) {
root.Layout.preferredWidth = Screen.width;
} else {
root.Layout.preferredHeight = Screen.height;
}
}*/
visibilityManager.updateMaskArea();
}
//////////////END OF CONNECTIONS
//////////////START OF FUNCTIONS
function addApplet(applet, x, y) {
var container = appletContainerComponent.createObject(dndSpacer.parent)
container.applet = applet;
applet.parent = container.appletWrapper;
applet.anchors.fill = container.appletWrapper;
applet.visible = true;
// don't show applet if it chooses to be hidden but still make it
// accessible in the panelcontroller
container.visible = Qt.binding(function() {
return applet.status !== PlasmaCore.Types.HiddenStatus || (!plasmoid.immutable && root.inConfigureAppletsMode)
})
addContainerInLayout(container, applet, x, y);
updateContainsOnlyPlasmaTasks();
}
function addContainerInLayout(container, applet, x, y){
// Is there a DND placeholder? Replace it!
if ( (dndSpacer.parent === layoutsContainer.mainLayout)
|| (dndSpacer.parent === layoutsContainer.startLayout)
|| (dndSpacer.parent===layoutsContainer.endLayout)) {
LayoutManager.insertBeforeForLayout(dndSpacer.parent, dndSpacer, container);
dndSpacer.parent = root;
return;
// If the provided position is valid, use it.
} else if (x >= 0 && y >= 0) {
var index = LayoutManager.insertAtCoordinates2(container, x , y);
// Fall through to determining an appropriate insert position.
} else {
var before = null;
container.animationsEnabled = false;
if (lastSpacer.parent === layoutsContainer.mainLayout) {
before = lastSpacer;
}
// Insert icons to the left of whatever is at the center (usually a Task Manager),
// if it exists.
// FIXME TODO: This is a real-world fix to produce a sensible initial position for
// launcher icons added by launcher menu applets. The basic approach has been used
// since Plasma 1. However, "add launcher to X" is a generic-enough concept and
// frequent-enough occurrence that we'd like to abstract it further in the future
// and get rid of the ugliness of parties external to the containment adding applets
// of a specific type, and the containment caring about the applet type. In a better
// system the containment would be informed of requested launchers, and determine by
// itself what it wants to do with that information.
if (applet.pluginName == "org.kde.plasma.icon") {
var middle = layoutsContainer.mainLayout.childAt(root.width / 2, root.height / 2);
if (middle) {
before = middle;
}
// Otherwise if lastSpacer is here, enqueue before it.
}
if (before) {
LayoutManager.insertBefore(before, container);
// Fall through to adding at the end.
} else {
container.parent = layoutsContainer.mainLayout;
}
}
//Important, removes the first children of the layoutsContainer.mainLayout after the first
//applet has been added
lastSpacer.parent = root;
updateIndexes();
}
function addInternalViewSplitters(){
if (internalViewSplittersCount() === 0) {
addInternalViewSplitter(plasmoid.configuration.splitterPosition);
addInternalViewSplitter(plasmoid.configuration.splitterPosition2);
}
}
function addInternalViewSplitter(pos){
var splittersCount = internalViewSplittersCount();
if(splittersCount<2){
var container = appletContainerComponent.createObject(root);
container.internalSplitterId = splittersCount+1;
container.visible = true;
if(pos>=0 ){
LayoutManager.insertAtIndex(container, pos);
} else {
LayoutManager.insertAtIndex(container, Math.floor(layoutsContainer.mainLayout.count / 2));
}
}
}
//! it is used in order to check the right click position
//! the only way to take into account the visual appearance
//! of the applet (including its spacers)
function appletContainsPos(appletId, pos){
for (var i = 0; i < layoutsContainer.startLayout.children.length; ++i) {
var child = layoutsContainer.startLayout.children[i];
if (child && child.applet && child.applet.id === appletId && child.containsPos(pos))
return true;
}
for (var i = 0; i < layoutsContainer.mainLayout.children.length; ++i) {
var child = layoutsContainer.mainLayout.children[i];
if (child && child.applet && child.applet.id === appletId && child.containsPos(pos))
return true;
}
for (var i = 0; i < layoutsContainer.endLayout.children.length; ++i) {
var child = layoutsContainer.endLayout.children[i];
if (child && child.applet && child.applet.id === appletId && child.containsPos(pos))
return true;
}
return false;
}
function checkLastSpacer() {
lastSpacer.parent = root
var expands = false;
if (isHorizontal) {
for (var container in layoutsContainer.mainLayout.children) {
var item = layoutsContainer.mainLayout.children[container];
if (item.Layout && item.Layout.fillWidth) {
expands = true;
}
}
} else {
for (var container in layoutsContainer.mainLayout.children) {
var item = layoutsContainer.mainLayout.children[container];
if (item.Layout && item.Layout.fillHeight) {
expands = true;
}
}
}
if (!expands) {
lastSpacer.parent = layoutsContainer.mainLayout
}
}
function clearZoom(){
if (latteApplet){
latteApplet.clearZoom();
}
root.clearZoomSignal();
}
function containmentActions(){
return latteView.containmentActions();
}
function decimalToHex(d, padding) {
var hex = Number(d).toString(16);
padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;
while (hex.length < padding) {
hex = "0" + hex;
}
return hex;
}
function disableDirectRender(){
// root.globalDirectRender = false;
}
function internalViewSplittersCount(){
var splitters = 0;
for (var container in layoutsContainer.startLayout.children) {
var item = layoutsContainer.startLayout.children[container];
if(item && item.isInternalViewSplitter) {
splitters = splitters + 1;
}
}
for (var container in layoutsContainer.mainLayout.children) {
var item = layoutsContainer.mainLayout.children[container];
if(item && item.isInternalViewSplitter) {
splitters = splitters + 1;
}
}
for (var container in layoutsContainer.endLayout.children) {
var item = layoutsContainer.endLayout.children[container];
if(item && item.isInternalViewSplitter) {
splitters = splitters + 1;
}
}
return splitters;
}
function initializeHoveredIndexes() {
layoutsContainer.hoveredIndex = -1;
layoutsContainer.currentSpot = -1000;
if (latteApplet) {
latteApplet.initializeHoveredIndex();
}
}
function layoutManager() {
return LayoutManager;
}
function layoutManagerInsertBefore(place, item) {
LayoutManager.insertBefore(place, item);
}
function layoutManagerInsertAfter(place, item) {
LayoutManager.insertAfter(place, item);
}
function layoutManagerSave() {
LayoutManager.save();
}
function layoutManagerSaveOptions() {
LayoutManager.saveOptions();
}
function mouseInCanBeHoveredApplet(){
if (latteApplet && latteApplet.containsMouse())
return true;
var applets = layoutsContainer.startLayout.children;
for(var i=0; i=0; --i){
if(iconsArray[i] === size){
return true;
}
}
return false;
}
function slotAnimationsNeedBothAxis(step) {
if (step === 0) {
return;
}
animationsNeedBothAxis = Math.max(animationsNeedBothAxis + step, 0);
visibilityManager.updateMaskArea();
}
function slotAnimationsNeedLength(step) {
if (step === 0) {
return;
}
animationsNeedLength = Math.max(animationsNeedLength + step, 0);
//when need length animations are ended it would be a good idea
//to update the tasks geometries in the plasmoid
if(animationsNeedLength === 0 && latteApplet) {
latteApplet.publishTasksGeometries();
}
visibilityManager.updateMaskArea();
}
function slotAnimationsNeedThickness(step) {
if (step === 0) {
return;
}
animationsNeedThickness = Math.max(animationsNeedThickness + step, 0);
visibilityManager.updateMaskArea();
}
//this is used when dragging a task in order to not hide the dock
//and also by the menu appearing from tasks for the same reason
function slotActionsBlockHiding(step) {
//if (root.editMode) {
// return;
// }
if ((step === 0) || (!latteView)) {
return;
}
actionsBlockHiding = Math.max(actionsBlockHiding + step, 0);
if (actionsBlockHiding > 0){
latteView.setBlockHiding(true);
} else {
if (!root.editMode)
latteView.setBlockHiding(false);
}
}
function slotPreviewsShown(){
if (latteView) {
latteView.deactivateApplets();
}
}
function startCheckRestoreZoomTimer(){
checkRestoreZoom.start();
}
function stopCheckRestoreZoomTimer(){
checkRestoreZoom.stop();
}
function startDirectRenderDelayerDuringEntering(){
directRenderDelayerForEnteringTimer.start();
}
function setGlobalDirectRender(value) {
if (latteApplet && latteApplet.tasksExtendedManager.waitingLaunchersLength() > 0)
return;
if (value === true) {
if (mouseInCanBeHoveredApplet()) {
root.globalDirectRender = true;
} else {
// console.log("direct render true ignored...");
}
} else {
root.globalDirectRender = false;
}
}
function updateAutomaticIconSize() {
if ( !blockAutomaticUpdateIconSize.running && !visibilityManager.inTempHiding
&& ((visibilityManager.normalState || root.editMode)
&& (root.autoDecreaseIconSize || (!root.autoDecreaseIconSize && root.iconSize!=root.maxIconSize)))
&& (iconSize===root.maxIconSize || iconSize === automaticIconSizeBasedSize) ) {
blockAutomaticUpdateIconSize.start();
var layoutLength;
var maxLength = root.maxLength;
//console.log("------Entered check-----");
//console.log("max length: "+ maxLength);
if (root.isVertical) {
layoutLength = (plasmoid.configuration.panelPosition === Latte.Types.Justify) ?
layoutsContainer.startLayout.height+layoutsContainer.mainLayout.height+layoutsContainer.endLayout.height : layoutsContainer.mainLayout.height
} else {
layoutLength = (plasmoid.configuration.panelPosition === Latte.Types.Justify) ?
layoutsContainer.startLayout.width+layoutsContainer.mainLayout.width+layoutsContainer.endLayout.width : layoutsContainer.mainLayout.width
}
var toShrinkLimit = maxLength-((root.zoomFactor-1)*(iconSize + thickMargins));
var toGrowLimit = maxLength-1.5*((root.zoomFactor-1)*(iconSize + thickMargins));
var newIconSizeFound = false;
if (layoutLength > toShrinkLimit) { //must shrink
// console.log("step3");
var nextIconSize = root.maxIconSize;
do {
nextIconSize = nextIconSize - iconStep;
var factor = nextIconSize / iconSize;
var nextLength = factor * layoutLength;
} while ( (nextLength>toShrinkLimit) && (nextIconSize !== 16));
automaticIconSizeBasedSize = nextIconSize;
newIconSizeFound = true;
console.log("Step 3 - found:"+automaticIconSizeBasedSize);
} else if ((layoutLength 0) {
if (foundGoodSize === root.maxIconSize) {
automaticIconSizeBasedSize = -1;
} else {
automaticIconSizeBasedSize = foundGoodSize;
}
newIconSizeFound = true
// console.log("Step 4 - found:"+automaticIconSizeBasedSize);
} else {
// console.log("Step 4 - did not found...");
}
}
}
}
function updateContainsOnlyPlasmaTasks() {
if (latteView) {
root.containsOnlyPlasmaTasks = (latteView.tasksPresent() && !latteApplet);
} else {
root.containsOnlyPlasmaTasks = false;
}
}
function updateSizeForAppletsInFill() {
layoutsContainer.updateSizeForAppletsInFill();
}
function splitMainLayoutToLayouts() {
if (internalViewSplittersCount() === 2) {
console.log("LAYOUTS: Moving applets from MAIN to THREE Layouts mode...");
var splitter = -1;
var splitter2 = -1;
var totalChildren = layoutsContainer.mainLayout.children.length;
for (var i=0; i=0 && splitter2 === -1) {
splitter2 = i;
}
}
// console.log("update layouts 1:"+splitter + " - "+splitter2);
for (var i=0; i<=splitter; ++i){
var item = layoutsContainer.mainLayout.children[0];
item.parent = layoutsContainer.startLayout;
}
splitter2 = splitter2 - splitter - 1;
// console.log("update layouts 2:"+splitter + " - "+splitter2);
totalChildren = layoutsContainer.mainLayout.children.length;
for (var i=splitter2+1; i=0; --i) {
var item1 = layoutsContainer.mainLayout.children[0];
item1.parent = layoutsContainer.startLayout;
}
var totalChildren2 = layoutsContainer.endLayout.children.length;
for (var i=totalChildren2-1; i>=0; --i) {
var item2 = layoutsContainer.endLayout.children[0];
item2.parent = layoutsContainer.startLayout;
}
var totalChildrenL = layoutsContainer.startLayout.children.length;
for (var i=totalChildrenL-1; i>=0; --i) {
var itemL = layoutsContainer.startLayout.children[0];
itemL.parent = layoutsContainer.mainLayout;
}
}
//END functions
////BEGIN interfaces
Connections {
target: Latte.WindowSystem
onCompositingActiveChanged: {
visibilityManager.updateMaskArea();
}
}
Connections {
target: latteView
onWidthChanged:{
if (root.isHorizontal && proportionIconSize!==-1)
updateAutomaticIconSize();
}
onHeightChanged:{
if (root.isVertical && proportionIconSize!==-1)
updateAutomaticIconSize();
}
onContextMenuIsShownChanged: {
if (!latteView.contextMenuIsShown) {
checkRestoreZoom.start();
} else {
root.setGlobalDirectRender(false);
}
}
}
Connections{
target: latteView && latteView.visibility ? latteView.visibility : root
ignoreUnknownSignals : true
onContainsMouseChanged: {
if (mouseInHoverableArea()) {
stopCheckRestoreZoomTimer();
} else {
startCheckRestoreZoomTimer();
}
}
}
Connections{
target: layoutsContainer
onHoveredIndexChanged: {
if (latteApplet && layoutsContainer.hoveredIndex>-1){
latteApplet.setHoveredIndex(-1);
}
if (latteApplet && latteApplet.windowPreviewIsShown && layoutsContainer.hoveredIndex>-1) {
latteApplet.hidePreview();
}
}
}
////END interfaces
/////BEGIN: Title Tooltip///////////
PlasmaCore.Dialog{
id: titleTooltipDialog
type: PlasmaCore.Dialog.Tooltip
flags: Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.ToolTip
location: plasmoid.location
mainItem: RowLayout{
Layout.fillWidth: true
Layout.fillHeight: true
PlasmaComponents.Label{
id:titleLbl
Layout.leftMargin: 4
Layout.rightMargin: 4
Layout.topMargin: 2
Layout.bottomMargin: 2
text: titleTooltipDialog.title
}
}
visible: false
property string title: ""
property bool activeItemHovered: false
property Item activeItem: null
property Item activeItemTooltipParent: null
property string activeItemText: ""
Component.onCompleted: {
root.clearZoomSignal.connect(titleTooltipDialog.hide);
}
Component.onDestruction: {
root.clearZoomSignal.disconnect(titleTooltipDialog.hide);
}
function hide(debug){
if (!root.titleTooltips)
return;
activeItemHovered = false;
hideTitleTooltipTimer.start();
}
function show(taskItem, text){
if (!root.titleTooltips || (latteApplet && latteApplet.contextMenu)){
return;
}
activeItemHovered = true;
if (activeItem !== taskItem) {
activeItem = taskItem;
activeItemTooltipParent = taskItem.tooltipVisualParent;
activeItemText = text;
}
if (isReady) {
showTitleTooltipTimer.start();
}
}
function update() {
activeItemHovered = true
title = activeItemText;
visualParent = activeItemTooltipParent;
if (latteApplet && latteApplet.windowPreviewIsShown) {
latteApplet.hidePreview();
}
visible = true;
}
}
Timer {
id: showTitleTooltipTimer
interval: 100
onTriggered: {
if (latteView && latteView.visibility && latteView.visibility.containsMouse) {
titleTooltipDialog.update();
}
if (titleTooltipDialog.visible) {
titleTooltipCheckerToNotShowTimer.start();
}
if (root.debugModeTimers) {
console.log("containment timer: showTitleTooltipTimer called...");
}
}
}
Timer {
id: hideTitleTooltipTimer
interval: 200
onTriggered: {
if (!titleTooltipDialog.activeItemHovered) {
titleTooltipDialog.visible = false;
}
if (root.debugModeTimers) {
console.log("containment timer: hideTitleTooltipTimer called...");
}
}
}
//! Timer to fix #811, rare cases that both a window preview and context menu are
//! shown
Timer {
id: titleTooltipCheckerToNotShowTimer
interval: 250
onTriggered: {
if (titleTooltipDialog.visible && latteApplet && (latteApplet.contextMenu || latteApplet.windowPreviewIsShown)) {
titleTooltipDialog.visible = false;
}
}
}
/////END: Title Tooltip///////////
///////////////BEGIN components
Component {
id: appletContainerComponent
Applet.AppletItem{}
}
ParabolicManager{
id: _parabolicManager
}
Indicators.Manager{
id: indicators
}
///////////////END components
PlasmaCore.ColorScope{
id: colorScopePalette
}
///////////////BEGIN UI elements
//it is used to check if the mouse is outside the layoutsContainer borders,
//so in that case the onLeave event behavior should be trigerred
RootMouseArea{
id: rootMouseArea
}
Loader{
active: root.debugModeWindow
sourceComponent: DebugWindow{}
}
//! Load a sepia background in order to avoid black background
Loader{
anchors.fill: parent
active: !Latte.WindowSystem.compositingActive
sourceComponent: Image{
anchors.fill: parent
fillMode: Image.Tile
source: root.hasUserSpecifiedBackground ? latteView.layout.background : "../icons/wheatprint.jpg"
}
}
EditMode.Visual{
id:editModeVisual
// z: root.behaveAsPlasmaPanel ? 1 : 0
}
Item {
id: lastSpacer
parent: layoutsContainer.mainLayout
Layout.fillWidth: true
Layout.fillHeight: true
z:10
Rectangle{
anchors.fill: parent
color: "transparent"
border.color: "yellow"
border.width: 1
}
}
Loader{
anchors.fill: parent
active: root.debugMode
z:10
sourceComponent: Item{
Rectangle{
anchors.fill: parent
color: "yellow"
opacity: 0.06
}
}
}
VisibilityManager{ id: visibilityManager }
DragDropArea {
id: backDropArea
anchors.fill: parent
Item{
id: panelBox
anchors.fill: layoutsContainer
PanelBox{
id: panelBoxBackground
}
}
Layouts.LayoutsContainer {
id: layoutsContainer
}
DragDropArea {
id: foreDropArea
anchors.fill: parent
visible: latteView && latteView.containsDrag
&& ((root.dragInfo.isPlasmoid && !root.dragInfo.isSeparator)
|| (root.addLaunchersInTaskManager && root.dragInfo.onlyLaunchers))
isForeground: true
/* Rectangle {
anchors.fill: parent
color: "blue"
opacity: 0.5
}*/
}
}
Colorizer.Manager {
id: colorizerManager
}
Item {
id: dndSpacer
width: root.isHorizontal ? length : thickness
height: root.isHorizontal ? thickness : length
readonly property int length: root.iconSize + root.lengthMargins
readonly property int thickness: root.iconSize + root.thickMargins
Layout.preferredWidth: width
Layout.preferredHeight: height
opacity: 0
z:1500
AddWidgetVisual{}
}
///////////////END UI elements
///////////////BEGIN TIMER elements
//Timer to check if the mouse is still outside the latteView in order to restore zooms to 1.0
Timer{
id:checkRestoreZoom
interval: 90
onTriggered: {
if (latteApplet && (latteApplet.previewContainsMouse() || latteApplet.contextMenu))
return;
if (latteView.contextMenuIsShown)
return;
if (!mouseInHoverableArea()) {
setGlobalDirectRender(false);
root.initializeHoveredIndexes();
root.clearZoom();
}
if (root.debugModeTimers) {
console.log("containment timer: checkRestoreZoom called...");
}
}
}
//! Delayer in order to not activate directRendering when the mouse
//! enters until the timer has ended. This way we make sure that the
//! zoom-in animations will have ended.
Timer{
id:directRenderDelayerForEnteringTimer
interval: 3.2 * root.durationTime * units.shortDuration
}
//this is a delayer to update mask area, it is used in cases
//that animations can not catch up with animations signals
//e.g. the automaicIconSize case
Timer{
id:delayUpdateMaskArea
repeat:false;
interval:300;
onTriggered: {
if (layoutsContainer.animationSent) {
root.slotAnimationsNeedLength(-1);
layoutsContainer.animationSent = false;
}
visibilityManager.updateMaskArea();
if (root.debugModeTimers) {
console.log("containment timer: delayUpdateMaskArea called...");
}
}
}
// This function is very costly! This timer makes sure that it can be called
// only once every 1sec.
Timer{
id:blockAutomaticUpdateIconSize
interval: 1000
repeat: false
onTriggered: root.updateAutomaticIconSize();
}
//! It is used in order to slide-in the latteView on startup
Timer{
id: inStartupTimer
interval: 1500
repeat: false
onTriggered: {
if (inStartup) {
visibilityManager.slotMustBeShown();
}
}
}
///////////////END TIMER elements
}
diff --git a/liblatte2/types.h b/liblatte2/types.h
index 7e819b45..78e0e2d5 100644
--- a/liblatte2/types.h
+++ b/liblatte2/types.h
@@ -1,237 +1,245 @@
/*
* Copyright 2016 Smith AR
* Michail Vourlakos
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef TYPES_H
#define TYPES_H
// Qt
#include
#include
#include
namespace Latte {
class Types
{
Q_GADGET
public:
Types() = delete;
~Types() {}
enum ViewType
{
DockView = 0,
PanelView
};
Q_ENUM(ViewType);
enum Visibility
{
None = -1,
AlwaysVisible = 0,
AutoHide,
DodgeActive,
DodgeMaximized,
DodgeAllWindows,
WindowsGoBelow
};
Q_ENUM(Visibility);
enum Alignment
{
Center = 0,
Left,
Right,
Top,
Bottom,
Justify = 10
};
Q_ENUM(Alignment);
enum EdgesAndAlignments
{
BottomEdgeCenterAlign = 0,
BottomEdgeLeftAlign,
BottomEdgeRightAlign,
TopEdgeCenterAlign,
TopEdgeLeftAlign,
TopEdgeRightAlign,
LeftEdgeCenterAlign,
LeftEdgeTopAlign,
LeftEdgeBottomAlign,
RightEdgeCenterAlign,
RightEdgeTopAlign,
RightEdgeBottomAlign
};
Q_ENUM(EdgesAndAlignments);
enum SessionType
{
DefaultSession = 0,
AlternativeSession
};
Q_ENUM(SessionType)
enum Modifier
{
Shift = 0,
Ctrl,
Alt,
Meta
};
Q_ENUM(Modifier);
enum ClickAction
{
LeftClick = 0,
MiddleClick,
RightClick
};
Q_ENUM(ClickAction);
+ enum ManualScrollType
+ {
+ ManualScrollDisabled = 0,
+ ManualScrollOnlyParallel,
+ ManualScrollVerticalHorizontal
+ };
+ Q_ENUM(ManualScrollType);
+
enum ScrollAction
{
ScrollNone = 0,
ScrollDesktops,
ScrollActivities,
ScrollTasks
};
Q_ENUM(ScrollAction);
enum TaskAction
{
NoneAction = 0,
Close,
NewInstance,
ToggleMinimized,
CycleThroughTasks,
ToggleGrouping,
PresentWindows,
PreviewWindows,
HighlightWindows,
PreviewAndHighlightWindows
};
Q_ENUM(TaskAction);
enum IndicatorStyle
{
LatteIndicator = 0,
PlasmaIndicator,
UnityIndicator
};
Q_ENUM(IndicatorStyle);
enum ActiveIndicatorType
{
LineIndicator = 0,
DotIndicator = 1
};
Q_ENUM(ActiveIndicatorType);
enum LaunchersGroup
{
UniqueLaunchers = 0,
LayoutLaunchers = 1,
GlobalLaunchers = 2
};
Q_ENUM(LaunchersGroup);
enum GlowGroup
{
GlowNone = -1,
GlowOnlyOnActive = 0,
GlowAll = 1
};
Q_ENUM(GlowGroup);
enum ShadowGroup
{
NoneAppletShadow = 0,
LockedAppletsShadow, /* DEPRECATED, apply shadow only to locked applets */
AllAppletsShadow
};
Q_ENUM(ShadowGroup);
enum ShadowColorGroup
{
DefaultColorShadow = 0,
ThemeColorShadow,
UserColorShadow
};
Q_ENUM(ShadowColorGroup);
enum ThemeColorsGroup
{
PlasmaThemeColors = 0,
ReverseThemeColors,
SmartThemeColors
};
Q_ENUM(ThemeColorsGroup);
enum WindowColorsGroup
{
NoneWindowColors = 0,
ActiveWindowColors,
TouchingWindowColors
};
Q_ENUM(WindowColorsGroup);
enum LayoutsMemoryUsage
{
SingleLayout = 0, /* a single Layout is loaded in each time */
MultipleLayouts /* multiple layouts are loaded on runtime,based on Activities and one central layout for the rest unassigned Activities */
};
Q_ENUM(LayoutsMemoryUsage);
enum MouseSensitivity
{
LowSensitivity = 0,
MediumSensitivity,
HighSensitivity
};
Q_ENUM(MouseSensitivity);
enum LatteConfigPage
{
LayoutPage = 0,
PreferencesPage
};
Q_ENUM(LatteConfigPage);
enum SettingsComplexity
{
BasicSettings = 0,
AdvancedSettings = 2,
ExpertSettings = 4
};
Q_ENUM(SettingsComplexity);
enum ImportExportState
{
Failed = 0,
Updated = 2,
Installed = 4
};
Q_ENUM(ImportExportState);
};
}//end of namespace
#endif
diff --git a/plasmoid/package/contents/ui/main.qml b/plasmoid/package/contents/ui/main.qml
index e561ea26..94823323 100644
--- a/plasmoid/package/contents/ui/main.qml
+++ b/plasmoid/package/contents/ui/main.qml
@@ -1,2199 +1,2202 @@
/*
* Copyright 2016 Smith AR
* Michail Vourlakos
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.plasmoid 2.0
import org.kde.taskmanager 0.1 as TaskManager
import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet
import org.kde.activities 0.1 as Activities
import org.kde.latte 0.2 as Latte
import "previews" as Previews
import "task" as Task
import "taskslayout" as TasksLayout
import "../code/tools.js" as TaskTools
import "../code/activitiesTools.js" as ActivitiesTools
import "../code/ColorizerTools.js" as ColorizerTools
Item {
id:root
Layout.fillWidth: scrollingEnabled && !root.vertical ? true : false
Layout.fillHeight: scrollingEnabled && root.vertical ? true : false
///IMPORTANT: These values must be tested when the Now Dock Panel support
///also the four new anchors. A small issue is shown between the animation
/// of the now dock plasmoid and the neighbour widgets...
Layout.minimumWidth: -1 //(userPanelPosition !== 0)&&(!latteView) ? clearWidth : -1
Layout.minimumHeight: -1 //(userPanelPosition !== 0)&&(!latteView) ? clearHeight : -1
Layout.preferredWidth: tasksWidth //(userPanelPosition !== 0)&&(!latteView) ? tasksWidth : tasksWidth
Layout.preferredHeight: tasksHeight //(userPanelPosition !== 0)&&(!latteView) ? tasksHeight : tasksHeight
Layout.maximumWidth: -1
Layout.maximumHeight: -1
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft && !root.vertical
LayoutMirroring.childrenInherit: true
property bool debugLocation: false
//it is used to check both the applet and the containment for direct render
property bool globalDirectRender: latteView ? latteView.globalDirectRender : icList.directRender
property bool plasma515: Latte.WindowSystem.plasmaDesktopVersion >= Latte.WindowSystem.makeVersion(5,14,90)
property bool editMode: latteView ? latteView.editMode : plasmoid.userConfiguring
property bool inConfigureAppletsMode: latteView ? latteView.inConfigureAppletsMode : true
property bool disableRestoreZoom: false //blocks restore animation in rightClick
property bool disableAllWindowsFunctionality: root.showWindowsOnlyFromLaunchers && !indicators.isEnabled
property bool dropNewLauncher: false
readonly property bool hasInternalSeparator: parabolicManager.hasInternalSeparator
property bool inActivityChange: false
property bool inDraggingPhase: false
property bool initializationStep: false //true
property bool isHovered: false
property bool showBarLine: plasmoid.configuration.showBarLine
property bool showTaskShortcutBadges: false
property int tasksBaseIndex: 0
property bool useThemePanel: plasmoid.configuration.useThemePanel
property bool taskInAnimation: noTasksInAnimation > 0 ? true : false
property bool transparentPanel: plasmoid.configuration.transparentPanel
property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical ? true : false
property int clearWidth
property int clearHeight
property int newLocationDebugUse: PlasmaCore.Types.BottomPositioned
property int newDroppedPosition: -1
property int noInitCreatedBuffers: 0
property int noTasksInAnimation: 0
property int themePanelSize: plasmoid.configuration.panelSize
property int position : PlasmaCore.Types.BottomPositioned
property int tasksStarting: 0
///Don't use Math.floor it adds one pixel in animations and creates glitches
property int widthMargins: root.vertical ? thickMargins : lengthMargins
property int heightMargins: !root.vertical ? thickMargins : lengthMargins
property int internalWidthMargins: root.vertical ? thickMargins : 2 * lengthIntMargin
property int internalHeightMargins: !root.vertical ? thickMargins : 2 * lengthIntMargin
property real textColorBrightness: ColorizerTools.colorBrightness(themeTextColor)
property color minimizedDotColor: {
if (latteView) {
return latteView.minimizedDotColor;
}
return textColorBrightness > 127.5 ? Qt.darker(themeTextColor, 1.7) : Qt.lighter(themeBackgroundColor, 7)
}
property color themeTextColor: theme.textColor
property color themeBackgroundColor: theme.backgroundColor
property color lightTextColor: textColorBrightness > 127.5 ? themeTextColor : themeBackgroundColor
//a small badgers record (id,value)
//in order to track badgers when there are changes
//in launcher reference from libtaskmanager
property variant badgers:[]
property variant launchersOnActivities: []
//global plasmoid reference to the context menu
property QtObject contextMenu: null
property QtObject contextMenuComponent: Qt.createComponent("ContextMenu.qml");
property Item dragSource: null
property Item parabolicManager: _parabolicManager
property Item tasksExtendedManager: _tasksExtendedManager
//separator calculations based on audoban's design
property int maxSeparatorLength: {
if (root.vertical)
return 5 + heightMargins;
else
return 5 + widthMargins;
}
property real missingSeparatorLength: {
if (!root.isVertical)
return ((iconSize + widthMargins) * zoomFactor) - maxSeparatorLength;
else
return ((iconSize + heightMargins) * zoomFactor) - maxSeparatorLength;
}
readonly property alias containsDrag: mouseHandler.containsDrag
readonly property bool dragAreaEnabled: latteView ? (root.dragSource !== null
|| latteView.dragInfo.isSeparator
|| latteView.dragInfo.isTask
|| !latteView.dragInfo.isPlasmoid)
: true
//! it is used to play the animation correct when the user removes a launcher
property string launcherForRemoval: ""
//BEGIN Latte Dock properties
property bool dockIsShownCompletely: latteView ? latteView.dockIsShownCompletely : true
property bool enableShadows: latteView ? latteView.enableShadows > 0 : plasmoid.configuration.showShadows
property bool forceHidePanel: false
property bool directRenderDelayerIsRunning: latteView ? latteView.directRenderDelayerIsRunning : directRenderDelayerForEnteringTimer.running
property bool disableLeftSpacer: false
property bool disableRightSpacer: false
property bool dockIsHidden: latteView ? latteView.dockIsHidden : false
property bool groupTasksByDefault: latteView ? latteView.groupTasksByDefault: true
property bool highlightWindows: latteView ? latteView.hoverAction === Latte.Types.HighlightWindows || latteView.hoverAction === Latte.Types.PreviewAndHighlightWindows :
plasmoid.configuration.highlightWindows
property bool mouseWheelActions: latteView ? latteView.mouseWheelActions : true
property bool parabolicEffectEnabled: latteView ? latteView.parabolicEffectEnabled : zoomFactor>1 && !root.editMode
- property bool scrollingEnabled: latteView ? latteView.scrollingTasksEnabled : false
+ property bool scrollingEnabled: latteView ? latteView.scrollTasksEnabled : false
+ property bool autoScrollTasksEnabled: latteView ? (scrollingEnabled && latteView.autoScrollTasksEnabled) : false
+ property bool manualScrollTasksEnabled: latteView ? (scrollingEnabled && manualScrollTasksType !== Latte.Types.ManualScrollDisabled) : Latte.Types.ManualScrollDisabled
+ property int manualScrollTasksType: latteView ? latteView.manualScrollTasksType : 0
property bool showInfoBadge: latteView ? latteView.showInfoBadge : plasmoid.configuration.showInfoBadge
property bool showProgressBadge: latteView ? latteView.showProgressBadge : plasmoid.configuration.showInfoBadge
property bool showAudioBadge: latteView ? latteView.showAudioBadge : plasmoid.configuration.showAudioBadge
property bool audioBadgeActionsEnabled: latteView ? latteView.audioBadgeActionsEnabled : true
property bool showOnlyCurrentScreen: latteView ? latteView.showOnlyCurrentScreen : plasmoid.configuration.showOnlyCurrentScreen
property bool showOnlyCurrentDesktop: latteView ? latteView.showOnlyCurrentDesktop : plasmoid.configuration.showOnlyCurrentDesktop
property bool showOnlyCurrentActivity: latteView ? latteView.showOnlyCurrentActivity : plasmoid.configuration.showOnlyCurrentActivity
property bool showPreviews: latteView ? latteView.hoverAction === Latte.Types.PreviewWindows || latteView.hoverAction === Latte.Types.PreviewAndHighlightWindows :
plasmoid.configuration.showToolTips
property bool showWindowActions: latteView ? latteView.showWindowActions : plasmoid.configuration.showWindowActions
property bool showWindowsOnlyFromLaunchers: latteView ? latteView.showWindowsOnlyFromLaunchers : false
property bool titleTooltips: latteView ? latteView.titleTooltips : false
property alias windowPreviewIsShown: windowsPreviewDlg.visible
property int animationStep: latteView ? latteView.animationStep : 1
property int directRenderAnimationTime: latteView ? latteView.directRenderAnimationTime : 0
property int dockHoveredIndex : latteView ? latteView.hoveredIndex : -1
property int iconSize: latteView ? latteView.iconSize : Math.max(plasmoid.configuration.iconSize, 16)
property int maxIconSize: latteView ? latteView.maxIconSize : iconSize
property int leftClickAction: latteView ? latteView.leftClickAction : Latte.Types.PresentWindows
property int middleClickAction: latteView ? latteView.middleClickAction : plasmoid.configuration.middleClickAction
property int hoverAction: latteView ? latteView.hoverAction : Latte.Types.NoneAction
property int modifier: latteView ? latteView.modifier : -1
property int modifierClickAction: latteView ? latteView.modifierClickAction : -1
property int modifierClick: latteView ? latteView.modifierClick : -1
property int modifierQt:{
if (modifier === Latte.Types.Shift)
return Qt.ShiftModifier;
else if (modifier === Latte.Types.Ctrl)
return Qt.ControlModifier;
else if (modifier === Latte.Types.Alt)
return Qt.AltModifier;
else if (modifier === Latte.Types.Meta)
return Qt.MetaModifier;
else return -1;
}
property int thickMargin: latteView ? latteView.thickMargin : 0.16*iconSize
property int thickMargins: 2 * thickMargin
property int lengthIntMargin: latteView ? latteView.lengthIntMargin : 0.04*iconSize
property int lengthExtMargin: latteView ? latteView.lengthExtMargin : 0.1 * iconSize
property int lengthMargin: lengthIntMargin + lengthExtMargin
property int lengthMargins: 2 * lengthMargin
property int tasksHeight: mouseHandler.height
property int tasksWidth: mouseHandler.width
//updated from Binding
property int userPanelPosition
readonly property real currentPanelOpacity: latteView ? latteView.currentPanelTransparency / 100 : 1
//! Animations
property bool animationsEnabled: latteView ? latteView.animationsEnabled : durationTime !== 0
property bool animationLauncherBouncing: latteView ? latteView.animationLauncherBouncing : durationTime !== 0
property bool animationWindowInAttention: latteView ? latteView.animationWindowInAttention : durationTime !== 0
property bool animationNewWindowSliding: latteView ? latteView.animationNewWindowSliding : durationTime !== 0
property bool animationWindowAddedInGroup: latteView ? latteView.animationWindowAddedInGroup : durationTime !== 0
property bool animationWindowRemovedFromGroup: latteView ? latteView.animationWindowRemovedFromGroup : durationTime !== 0
property real animationsZoomFactor: latteView ? latteView.animationsZoomFactor : durationTime === 0 ? 1 : 1.65
property real maxZoomFactor: latteView ? latteView.maxZoomFactor : Math.max(zoomFactor, animationsZoomFactor)
property real appliedDurationTime: animationsEnabled ? durationTime : 2
property real durationTime: latteView ? latteView.durationTime : plasmoid.configuration.durationTime
property real zoomFactor: latteView ? latteView.zoomFactor : ( 1 + (plasmoid.configuration.zoomLevel / 20) )
property int appShadowSize: latteView ? latteView.appShadowSize : Math.ceil(0.12*iconSize)
property string appShadowColor: latteView ? latteView.appShadowColor : "#ff080808"
property string appShadowColorSolid: latteView ? latteView.appShadowColorSolid : "#ff080808"
property alias tasksCount: tasksModel.count
property alias hoveredIndex: icList.hoveredIndex
readonly property rect screenGeometry: latteView ? latteView.screenGeometry : plasmoid.screenGeometry
readonly property bool viewLayoutIsCurrent: latteView && viewLayout && latteView.layoutsManager
&& viewLayout.name === latteView.layoutsManager.currentLayoutName
readonly property string viewLayoutName: viewLayout ? viewLayout.name : ""
readonly property QtObject viewLayout : latteView && latteView.viewLayout ? latteView.viewLayout : null
property var badgesForActivate: latteView ? latteView.badgesForActivate : []
property Item latteView: null
readonly property Item indicators: latteView ? latteView.indicatorsManager : indicatorsStandaloneLoader.item
//END Latte Dock Panel properties
//BEGIN Latte Dock Communicator
property QtObject latteBridge: null
onLatteBridgeChanged: {
if (latteBridge) {
latteBridge.actions.setProperty(plasmoid.id, "latteSideColoringEnabled", false);
}
}
//END Latte Dock Communicator
//BEGIN Latte based properties
readonly property bool enforceLattePalette: latteBridge && latteBridge.applyPalette && latteBridge.palette
readonly property bool latteInEditMode: latteBridge && latteBridge.inEditMode
//END Latte based properties
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground
signal clearZoomSignal();
signal draggingFinished();
signal hiddenTasksUpdated();
signal launchersUpdatedFor(string launcher);
signal presentWindows(variant winIds);
signal requestLayout;
signal separatorsUpdated();
signal signalActionsBlockHiding(int value);
signal signalAnimationsNeedBothAxis(int value);
signal signalAnimationsNeedLength(int value);
signal signalAnimationsNeedThickness(int value);
signal signalPreviewsShown();
//signal signalDraggingState(bool value);
signal showPreviewForTasks(QtObject group);
//trigger updating scaling of neighbour delegates of zoomed delegate
signal updateScale(int delegateIndex, real newScale, real step)
signal mimicEnterForParabolic();
signal publishTasksGeometries();
signal windowsHovered(variant winIds, bool hovered)
//onAnimationsChanged: console.log(animations);
/* Rectangle{
anchors.fill: parent
border.width: 1
border.color: "red"
color: "white"
} */
onLatteViewChanged: {
if (latteView) {
plasmoid.action("configure").visible = false;
plasmoid.action("remove").visible = false;
plasmoid.configuration.isInLatteDock = true;
} else {
plasmoid.configuration.isInLatteDock = false;
}
}
Connections {
target: plasmoid
onLocationChanged: {
root.updatePosition();
iconGeometryTimer.start();
}
}
Connections {
target: plasmoid.configuration
// onLaunchersChanged: tasksModel.launcherList = plasmoid.configuration.launchers
onGroupingAppIdBlacklistChanged: tasksModel.groupingAppIdBlacklist = plasmoid.configuration.groupingAppIdBlacklist;
onGroupingLauncherUrlBlacklistChanged: tasksModel.groupingLauncherUrlBlacklist = plasmoid.configuration.groupingLauncherUrlBlacklist;
}
Connections{
target: latteView
onDockIsHiddenChanged:{
if (latteView.dockIsHidden) {
windowsPreviewDlg.hide("3.3");
}
}
onLaunchersGroupChanged:{
if( latteView && latteView.editMode) {
tasksModel.updateLaunchersList();
}
}
}
Connections{
target: latteView && latteView.layoutsManager ? latteView.layoutsManager : null
onCurrentLayoutNameChanged: root.publishTasksGeometries();
}
Connections{
target: icList
onHoveredIndexChanged:{
if (latteView && icList.hoveredIndex>-1){
latteView.setHoveredIndex(-1);
}
}
}
/////
PlasmaCore.ColorScope{
id: colorScopePalette
}
Loader {
id: indicatorsStandaloneLoader
active: !latteView && !plasmoid.configuration.isInLatteDock
source: "indicators/Manager.qml"
}
Binding {
target: root
property: "userPanelPosition"
value: {
if (latteView) {
if (latteView.panelUserSetAlignment === -1) {
return;
}
if (inConfigureAppletsMode) {
return Latte.Types.Center;
} else if (latteView.panelUserSetAlignment === Latte.Types.Justify) {
if (latteView.latteAppletPos>=0 && latteView.latteAppletPos<100) {
return plasmoid.formFactor === PlasmaCore.Types.Horizontal ? Latte.Types.Left : Latte.Types.Top;
} else if (latteView.latteAppletPos>=100 && latteView.latteAppletPos<200) {
return Latte.Types.Center;
} else if (latteView.latteAppletPos>=200) {
return plasmoid.formFactor === PlasmaCore.Types.Horizontal ? Latte.Types.Right : Latte.Types.Bottom;
}
return Latte.Types.Center;
}
return latteView.panelUserSetAlignment;
}
return plasmoid.configuration.plasmoidPosition;
}
}
/////
function initializeHoveredIndex() {
icList.hoveredIndex = -1;
icList.currentSpot = -1000;
}
function launchersDropped(urls){
mouseHandler.urlsDropped(urls);
}
///UPDATE
function launcherExists(url) {
return (ActivitiesTools.getIndex(url, tasksModel.launcherList)>=0);
}
function taskExists(url) {
var tasks = icList.contentItem.children;
for(var i=0; i -1) {
launch.push(explicitLauncher);
}
}
}
return launch;
}
function currentListViewLauncherList() {
var launch = [];
var tasks = icList.contentItem.children;
for(var i=0; i= Latte.Types.LayoutLaunchers) {
latteView.layoutsManager.launchersSignals.validateLaunchersOrder(root.viewLayoutName,
plasmoid.id,
latteView.launchersGroup,
currentLauncherList());
}
}
} else {
plasmoid.configuration.launchers59 = launcherList;
}
} else {
plasmoid.configuration.launchers59 = launcherList;
}
}
onGroupingAppIdBlacklistChanged: {
plasmoid.configuration.groupingAppIdBlacklist = groupingAppIdBlacklist;
}
onGroupingLauncherUrlBlacklistChanged: {
plasmoid.configuration.groupingLauncherUrlBlacklist = groupingLauncherUrlBlacklist;
}
onAnyTaskDemandsAttentionChanged: {
if (anyTaskDemandsAttention){
plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus;
attentionTimerComponent.createObject(root);
}
}
Component.onCompleted: {
ActivitiesTools.launchersOnActivities = root.launchersOnActivities
ActivitiesTools.currentActivity = String(activityInfo.currentActivity);
ActivitiesTools.plasmoid = plasmoid;
//var loadedLaunchers = ActivitiesTools.restoreLaunchers();
ActivitiesTools.importLaunchersToNewArchitecture();
if (viewLayout && latteView.universalSettings
&& (latteView.launchersGroup === Latte.Types.LayoutLaunchers
|| latteView.launchersGroup === Latte.Types.GlobalLaunchers)) {
if (latteView.launchersGroup === Latte.Types.LayoutLaunchers) {
launcherList = latteView.viewLayout.launchers;
} else if (latteView.launchersGroup === Latte.Types.GlobalLaunchers) {
launcherList = latteView.universalSettings.launchers;
}
} else {
launcherList = plasmoid.configuration.launchers59;
}
groupingAppIdBlacklist = plasmoid.configuration.groupingAppIdBlacklist;
groupingLauncherUrlBlacklist = plasmoid.configuration.groupingLauncherUrlBlacklist;
icList.model = tasksModel;
tasksStarting = count;
///Plasma 5.9 enforce grouping at all cases
if (Latte.WindowSystem.plasmaDesktopVersion >= Latte.WindowSystem.makeVersion(5,9,0)) {
groupingWindowTasksThreshold = -1;
}
}
}
//! TaskManagerBackend required a groupDialog setting otherwise it crashes. This patch
//! sets one just in order not to crash TaskManagerBackend
PlasmaCore.Dialog {
//ghost group Dialog to not crash TaskManagerBackend
id: groupDialogGhost
visible: false
type: PlasmaCore.Dialog.PopupMenu
flags: Qt.WindowStaysOnTopHint
hideOnWindowDeactivate: true
location: plasmoid.location
}
TaskManagerApplet.Backend {
id: backend
taskManagerItem: root
toolTipItem: toolTipDelegate
highlightWindows: root.highlightWindows
onAddLauncher: {
tasksModel.requestAddLauncher(url);
}
Component.onCompleted: {
//! In Plasma 5.9 TaskManagerBackend required a groupDialog setting
//! otherwise it crashes.
//! frameworks 5.29.0 provide id 335104
//! work only after Plasma 5.9 and frameworks 5.29
//! + added a check for groupDialog also when it is present
//! in plasma 5.8 (that was introduced after 5.8.5)
if (Latte.WindowSystem.frameworksVersion >= 335104 || (groupDialog !== undefined)) {
groupDialog = groupDialogGhost;
}
}
}
TaskManagerApplet.DragHelper {
id: dragHelper
dragIconSize: units.iconSizes.medium
}
TaskManager.VirtualDesktopInfo {
id: virtualDesktopInfo
}
TaskManager.ActivityInfo {
id: activityInfo
property string previousActivity: ""
onCurrentActivityChanged: {
root.inActivityChange = true;
activityChangeDelayer.start();
}
Component.onCompleted: previousActivity = currentActivity;
}
PlasmaCore.DataSource {
id: mpris2Source
engine: "mpris2"
connectedSources: sources
function sourceNameForLauncherUrl(launcherUrl, pid) {
if (!launcherUrl || launcherUrl == "") {
return "";
}
// MPRIS spec explicitly mentions that "DesktopEntry" is with .desktop extension trimmed
// Moreover, remove URL parameters, like wmClass (part after the question mark)
var desktopFileName = launcherUrl.toString().split('/').pop().split('?')[0].replace(".desktop", "")
if (desktopFileName.indexOf("applications:") === 0) {
desktopFileName = desktopFileName.substr(13)
}
for (var i = 0, length = connectedSources.length; i < length; ++i) {
var source = connectedSources[i];
// we intend to connect directly, otherwise the multiplexer steals the connection away
if (source === "@multiplex") {
continue;
}
var sourceData = data[source];
if (!sourceData || sourceData.DesktopEntry !== desktopFileName) {
continue;
}
if (pid === undefined || sourceData.InstancePid === pid) {
return source;
}
var metadata = sourceData.Metadata;
if (metadata) {
var kdePid = metadata["kde:pid"];
if (kdePid && pid === kdePid) {
return source;
}
}
}
return ""
}
function startOperation(source, op) {
var service = serviceForSource(source)
var operation = service.operationDescription(op)
return service.startOperationCall(operation)
}
function goPrevious(source) {
startOperation(source, "Previous");
}
function goNext(source) {
startOperation(source, "Next");
}
function playPause(source) {
startOperation(source, "PlayPause");
}
function stop(source) {
startOperation(source, "Stop");
}
function raise(source) {
startOperation(source, "Raise");
}
function quit(source) {
startOperation(source, "Quit");
}
}
Loader {
id: pulseAudio
source: "PulseAudio.qml"
active: root.showAudioBadge
}
ParabolicManager{
id: _parabolicManager
}
TasksExtendedManager {
id: _tasksExtendedManager
}
/* IconsModel{
id: iconsmdl
}*/
Component{
id: attentionTimerComponent
Timer{
id: attentionTimer
interval:8500
onTriggered: {
plasmoid.status = PlasmaCore.Types.PassiveStatus;
destroy();
if (latteView && latteView.debugModeTimers) {
console.log("plasmoid timer: attentionTimer called...");
}
}
Component.onCompleted: {
start();
}
}
}
//Timer to check if the mouse is still inside the ListView
//IMPORTANT ::: This timer should be used only when the Latte plasmoid
//is not inside a Latte dock
Timer{
id:checkListHovered
repeat:false;
interval: 120
property int normalInterval: Math.max(120, 2 * (root.durationTime * 1.2 * units.shortDuration) + 50)
onTriggered: {
if(root.latteView)
console.log("Plasmoid, checkListHoveredTimer was called, even though it shouldn't...");
if (!root.containsMouse()) {
icList.directRender = false;
root.clearZoom();
}
interval = normalInterval;
if (latteView && latteView.debugModeTimers) {
console.log("plasmoid timer: checkListHovered called...");
}
}
function startNormal(){
interval = normalInterval;
start();
}
function startDuration( duration){
interval = duration;
start();
}
}
//! Delayer in order to not activate directRendering when the mouse
//! enters until the timer has ended. This way we make sure that the
//! zoom-in animations will have ended.
Timer{
id:directRenderDelayerForEnteringTimer
interval: 3.2 * root.durationTime * units.shortDuration
}
//this timer restores the draggingPhase flag to false
//after a dragging has finished... This delay is needed
//in order to not animate any tasks are added after a
//dragging
Timer {
id: restoreDraggingPhaseTimer
interval: 150
onTriggered: inDraggingPhase = false;
}
///Red Liner!!! show the upper needed limit for animations
Rectangle{
anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined
anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined
width: root.vertical ? 1 : 2 * root.iconSize
height: root.vertical ? 2 * root.iconSize : 1
color: "red"
x: (root.position === PlasmaCore.Types.LeftPositioned) ? neededSpace : parent.width - neededSpace
y: (root.position === PlasmaCore.Types.TopPositioned) ? neededSpace : parent.height - neededSpace
visible: plasmoid.configuration.zoomHelper
property int neededSpace: zoomFactor*(iconSize+lengthMargins)
}
Item{
id:barLine
width: ( icList.orientation === Qt.Horizontal ) ? icList.width + spacing : smallSize
height: ( icList.orientation === Qt.Vertical ) ? icList.height + spacing : smallSize
property int spacing: latteView ? 0 : root.iconSize / 2
property int smallSize: Math.max(0.10 * root.iconSize, 16)
Behavior on opacity{
NumberAnimation { duration: root.durationTime*units.longDuration }
}
/// plasmoid's default panel
BorderImage{
anchors.fill:parent
source: "../images/panel-west.png"
border { left:8; right:8; top:8; bottom:8 }
opacity: (plasmoid.configuration.showBarLine && !plasmoid.configuration.useThemePanel && !root.forceHidePanel) ? 1 : 0
visible: (opacity == 0) ? false : true
horizontalTileMode: BorderImage.Stretch
verticalTileMode: BorderImage.Stretch
Behavior on opacity{
NumberAnimation { duration: root.durationTime*units.longDuration }
}
}
/// item which is used as anchors for the plasma's theme
Item{
id:belower
width: (root.position === PlasmaCore.Types.LeftPositioned) ? shadowsSvgItem.margins.left : shadowsSvgItem.margins.right
height: (root.position === PlasmaCore.Types.BottomPositioned)? shadowsSvgItem.margins.bottom : shadowsSvgItem.margins.top
anchors.top: (root.position === PlasmaCore.Types.BottomPositioned) ? parent.bottom : undefined
anchors.bottom: (root.position === PlasmaCore.Types.TopPositioned) ? parent.top : undefined
anchors.right: (root.position === PlasmaCore.Types.LeftPositioned) ? parent.left : undefined
anchors.left: (root.position === PlasmaCore.Types.RightPositioned) ? parent.right : undefined
}
/// the current theme's panel
PlasmaCore.FrameSvgItem{
id: shadowsSvgItem
anchors.bottom: (root.position === PlasmaCore.Types.BottomPositioned) ? belower.bottom : undefined
anchors.top: (root.position === PlasmaCore.Types.TopPositioned) ? belower.top : undefined
anchors.left: (root.position === PlasmaCore.Types.LeftPositioned) ? belower.left : undefined
anchors.right: (root.position === PlasmaCore.Types.RightPositioned) ? belower.right : undefined
anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined
anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined
width: root.vertical ? panelSize + margins.left + margins.right: parent.width
height: root.vertical ? parent.height : panelSize + margins.top + margins.bottom
imagePath: "translucent/widgets/panel-background"
prefix:"shadow"
opacity: (plasmoid.configuration.showBarLine && plasmoid.configuration.useThemePanel && !root.forceHidePanel) ? 1 : 0
visible: (opacity == 0) ? false : true
property int panelSize: ((root.position === PlasmaCore.Types.BottomPositioned) ||
(root.position === PlasmaCore.Types.TopPositioned)) ?
plasmoid.configuration.panelSize + belower.height:
plasmoid.configuration.panelSize + belower.width
Behavior on opacity{
NumberAnimation { duration: root.durationTime*units.longDuration }
}
PlasmaCore.FrameSvgItem{
anchors.margins: belower.width-1
anchors.fill:parent
imagePath: plasmoid.configuration.transparentPanel ? "translucent/widgets/panel-background" :
"widgets/panel-background"
}
}
TasksLayout.MouseHandler {
id: mouseHandler
anchors.bottom: (root.position === PlasmaCore.Types.BottomPositioned) ? scrollableList.bottom : undefined
anchors.top: (root.position === PlasmaCore.Types.TopPositioned) ? scrollableList.top : undefined
anchors.left: (root.position === PlasmaCore.Types.LeftPositioned) ? scrollableList.left : undefined
anchors.right: (root.position === PlasmaCore.Types.RightPositioned) ? scrollableList.right : undefined
anchors.horizontalCenter: !root.vertical ? scrollableList.horizontalCenter : undefined
anchors.verticalCenter: root.vertical ? scrollableList.verticalCenter : undefined
width: root.vertical ? maxSize : icList.width
height: root.vertical ? icList.height : maxSize
target: icList
visible: root.dragAreaEnabled
property int maxSize: (((root.hoveredIndex>=0 || dockHoveredIndex>=0 ) || windowPreviewIsShown) && !root.dragSource) ?
root.zoomFactor * (root.iconSize + root.thickMargins) :
root.iconSize + root.thickMargins
function onlyLaunchersInList(list){
return list.every(function (item) {
return backend.isApplication(item)
});
}
function urlsDroppedOnArea(urls){
// If all dropped URLs point to application desktop files, we'll add a launcher for each of them.
if (onlyLaunchersInList(urls)) {
urls.forEach(function (item) {
addLauncher(item);
});
return;
}
if (!hoveredItem) {
return;
}
// DeclarativeMimeData urls is a QJsonArray but requestOpenUrls expects a proper QList.
var urlsList = backend.jsonArrayToUrlList(urls);
// Otherwise we'll just start a new instance of the application with the URLs as argument,
// as you probably don't expect some of your files to open in the app and others to spawn launchers.
tasksModel.requestOpenUrls(hoveredItem.modelIndex(), urlsList);
}
onUrlsDropped: {
//! inform synced docks for new dropped launchers
if (latteView && latteView.launchersGroup >= Latte.Types.LayoutLaunchers && onlyLaunchersInList(urls)) {
latteView.layoutsManager.launchersSignals.urlsDropped(root.viewLayoutName,
latteView.launchersGroup, urls);
return;
}
//! if the list does not contain only launchers then just open the corresponding
//! urls with the relevant app
urlsDroppedOnArea(urls);
}
}
/* Rectangle {
anchors.fill: scrollableList
color: "transparent"
border.width: 1
border.color: "blue"
} */
TasksLayout.ScrollableList {
id: scrollableList
width: !root.vertical ? Math.min(root.width, icList.width) : thickness
height: root.vertical ? Math.min(root.height, icList.height) : thickness
contentWidth: icList.width
contentHeight: icList.height
property int thickness: {
if (latteView) {
return !latteView.thickAnimated ? latteView.maskManager.thicknessNormal : latteView.maskManager.thicknessZoom;
}
return (root.thickMargins + root.iconSize) * root.zoomFactor;
}
//onCurrentPosChanged: console.log("CP :: "+ currentPos + " icW:"+icList.width + " rw: "+root.width + " w:" +width);
layer.enabled: contentsExceed && root.scrollingEnabled
layer.effect: OpacityMask {
maskSource: TasksLayout.ScrollOpacityMask{
width: scrollableList.width
height: scrollableList.height
}
}
TasksLayout.ScrollPositioner {
id: listViewBase
ListView {
id:icList
width: !root.vertical ? contentWidth : mouseHandler.maxSize
height: root.vertical ? contentHeight : mouseHandler.maxSize
boundsBehavior: Flickable.StopAtBounds
orientation: Qt.Horizontal
delegate: Task.TaskItem{}
property int currentSpot : -1000
property int hoveredIndex : -1
property int previousCount : 0
property int tasksCount: tasksModel.count
property bool directRender: false
//the duration of this animation should be as small as possible
//it fixes a small issue with the dragging an item to change it's
//position, if the duration is too big there is a point in the
//list that an item is going back and forth too fast
//more of a trouble
moveDisplaced: Transition {
NumberAnimation { properties: "x,y"; duration: root.durationTime*units.longDuration; easing.type: Easing.Linear }
}
///this transition can not be used with dragging !!!! I breaks
///the lists indexes !!!!!
///move: Transition {
/// NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.Linear }
///}
function childAtPos(x, y){
var tasks = icList.contentItem.children;
for(var i=0; i=choords.x) && (x<=choords.x+task.width)
&& (y>=choords.y) && (y<=choords.y+task.height)){
return task;
}
}
return null;
}
function childAtIndex(position) {
var tasks = icList.contentItem.children;
if (position < 0)
return;
for(var i=0; i=0; --i) {
if (currentLaunchers[i] !== launchers[i]) {
var p = launcherValidPos(currentLaunchers[i]);
if (p === -1) {
console.log("No pos found for :"+currentLaunchers[i] + " at: "+launchers);
restart();
return;
}
var launcherModelIndex = icList.launcherModelIndex(currentLaunchers[i]);
if (launcherModelIndex === -1) {
console.log(" launcher was not found in model, syncing stopped...");
stop();
return;
}
console.log(" moving:" +launcherModelIndex + " _ " + p );
tasksModel.move(launcherModelIndex, p);
restart();
return;
}
}
}
console.log("why we reached ??? ");
console.log("CURRENT ::: " + currentLaunchers);
console.log("VALID ::: " + launchers);
}
}
}
/////////
//// functions
function movePanel(obj, newPosition){
var bLine = obj;
if (newPosition === PlasmaCore.Types.BottomPositioned){
bLine.anchors.horizontalCenter = bLine.parent.horizontalCenter;
bLine.anchors.verticalCenter = undefined;
bLine.anchors.bottom = bLine.parent.bottom;
bLine.anchors.top = undefined;
bLine.anchors.left = undefined;
bLine.anchors.right = undefined;
}
else if (newPosition === PlasmaCore.Types.TopPositioned){
bLine.anchors.horizontalCenter = bLine.parent.horizontalCenter;
bLine.anchors.verticalCenter = undefined;
bLine.anchors.bottom = undefined;
bLine.anchors.top = bLine.parent.top;
bLine.anchors.left = undefined;
bLine.anchors.right = undefined;
}
else if (newPosition === PlasmaCore.Types.LeftPositioned){
bLine.anchors.horizontalCenter = undefined;
bLine.anchors.verticalCenter = bLine.parent.verticalCenter;
bLine.anchors.bottom = undefined;
bLine.anchors.top = undefined;
bLine.anchors.left = bLine.parent.left;
bLine.anchors.right = undefined;
}
else if (newPosition === PlasmaCore.Types.RightPositioned){
bLine.anchors.horizontalCenter = undefined;
bLine.anchors.verticalCenter = bLine.parent.verticalCenter;
bLine.anchors.bottom = undefined;
bLine.anchors.top = undefined;
bLine.anchors.left =undefined;
bLine.anchors.right = bLine.parent.right;
}
}
property int ncounter:0
function updateImplicits(){
if(icList.previousCount !== icList.count){
icList.previousCount = icList.count;
var zoomedLength = Math.floor( 1.2 * (iconSize+thickMargins) * (root.zoomFactor));
var bigAxis = (tasksModel.count-1) * (iconSize+thickMargins) + zoomedLength;
var smallAxis = zoomedLength;
var clearBigAxis = tasksModel.count * (iconSize+thickMargins) + (barLine.spacing/2);
var clearSmallAxis = iconSize+thickMargins;
// debugging code
// ncounter++;
// console.log("Implicits______ "+ncounter+". - "+tasksModel.count);
if (root.vertical){
root.implicitWidth = smallAxis;
root.implicitHeight = bigAxis;
root.clearWidth = clearSmallAxis;
root.clearHeight = clearBigAxis;
}
else{
root.implicitWidth = bigAxis;
root.implicitHeight = smallAxis;
root.clearWidth = clearBigAxis;
root.clearHeight = clearSmallAxis;
}
iconGeometryTimer.restart();
}
}
PlasmaComponents.Button{
id: orientationBtn
text:"Orientation"
anchors.centerIn: parent
visible: root.debugLocation
onClicked:{
switch(root.position){
case PlasmaCore.Types.BottomPositioned:
root.newLocationDebugUse = PlasmaCore.Types.LeftEdge;
break;
case PlasmaCore.Types.LeftPositioned:
root.newLocationDebugUse = PlasmaCore.Types.TopEdge;
break;
case PlasmaCore.Types.TopPositioned:
root.newLocationDebugUse = PlasmaCore.Types.RightEdge;
break;
case PlasmaCore.Types.RightPositioned:
root.newLocationDebugUse = PlasmaCore.Types.BottomEdge;
break;
}
updatePosition();
}
}
function addInternalSeparatorAtPos(pos) {
var separatorName = parabolicManager.freeAvailableSeparatorName();
if (separatorName !== "") {
tasksExtendedManager.addLauncherToBeMoved(separatorName, Math.max(0,pos));
if (latteView && latteView.launchersGroup >= Latte.Types.LayoutLaunchers) {
latteView.layoutsManager.launchersSignals.addLauncher(root.viewLayoutName,
latteView.launchersGroup, separatorName);
} else {
tasksModel.requestAddLauncher(separatorName);
}
}
}
// This is called by dockcorona in response to a Meta+number shortcut.
function activateTaskAtIndex(index) {
if (typeof index !== "number") {
return;
}
var tasks = icList.contentItem.children;
//! this is used to bypass the internal separators if they exist
var confirmedIndex = parabolicManager.realTaskIndex(index - 1);
for(var i=0; i=0 ? ident1.substring(n + 1) : identifier;
for(var i=0; i= 0) {
return badgers[i];
}
}
}
function updateBadge(identifier, value) {
var tasks = icList.contentItem.children;
var identifierF = identifier.concat(".desktop");
for(var i=0; i= 0) {
task.badgeIndicator = value === "" ? 0 : Number(value);
var badge = getBadger(identifierF);
if (badge) {
badge.value = value;
} else {
badgers.push({id: identifierF, value: value});
}
}
}
}
function getLauncherList() {
return plasmoid.configuration.launchers59;
}
//! BEGIN ::: external launchers signals in order to update the tasks model
function extSignalAddLauncher(group, launcher) {
if (group === latteView.launchersGroup) {
tasksModel.requestAddLauncher(launcher);
launchersUpdatedFor(launcher);
tasksModel.syncLaunchers();
}
}
function extSignalRemoveLauncher(group, launcher) {
if (group === latteView.launchersGroup) {
root.launcherForRemoval = launcher;
tasksModel.requestRemoveLauncher(launcher);
launchersUpdatedFor(launcher);
tasksModel.syncLaunchers();
}
}
function extSignalAddLauncherToActivity(group, launcher, activity) {
if (group === latteView.launchersGroup) {
var launcherActivities = tasksModel.launcherActivities(launcher);
if (activity !== tasksModel.activity && (launcherActivities[0] === "00000000-0000-0000-0000-000000000000")) {
root.launcherForRemoval = launcher;
}
tasksModel.requestAddLauncherToActivity(launcher, activity);
launchersUpdatedFor(launcher);
tasksModel.syncLaunchers();
}
}
function extSignalRemoveLauncherFromActivity(group, launcher, activity) {
if (group === latteView.launchersGroup) {
if (activity === tasksModel.activity) {
root.launcherForRemoval = launcher;
}
tasksModel.requestRemoveLauncherFromActivity(launcher, activity);
launchersUpdatedFor(launcher);
tasksModel.syncLaunchers();
}
}
function extSignalUrlsDropped(group, urls) {
if (group === latteView.launchersGroup) {
mouseHandler.urlsDroppedOnArea(urls);
}
}
function extSignalMoveTask(group, from, to) {
if (group === latteView.launchersGroup && !root.dragSource) {
tasksModel.move(from, to);
parabolicManager.updateTasksEdgesIndexes();
root.separatorsUpdated();
tasksModel.syncLaunchers();
}
}
function extSignalValidateLaunchersOrder(group, launchers) {
if (group === latteView.launchersGroup && !root.dragSource) {
launchersOrderValidatorTimer.stop();
launchersOrderValidatorTimer.launchers = launchers;
launchersOrderValidatorTimer.start();
}
}
//! END ::: external launchers signals in order to update the tasks model
//! it is used to add the fake desktop file which represents
//! the separator (fake launcher)
function addSeparator(pos){
var separatorName = parabolicManager.freeAvailableSeparatorName();
if (separatorName !== "") {
tasksExtendedManager.addLauncherToBeMoved(separatorName, Math.max(0,pos));
if (latteView && latteView.launchersGroup >= Latte.Types.LayoutLaunchers) {
latteView.layoutsManager.launchersSignals.addLauncher(latteView.launchersGroup, separatorName);
} else {
tasksModel.requestAddLauncher(separatorName);
}
}
}
function removeLastSeparator(){
var separatorName = parabolicManager.lastPresentSeparatorName();
if (separatorName !== "") {
if (latteView && latteView.launchersGroup >= Latte.Types.LayoutLaunchers) {
latteView.layoutsManager.launchersSignals.removeLauncher(root.viewLayoutName,
latteView.launchersGroup, separatorName);
} else {
root.launcherForRemoval = separatorName;
tasksModel.requestRemoveLauncher(separatorName);
}
}
}
//! show/hide tasks numbered badges e.g. from global shortcuts
function setShowTaskShortcutBadges(showBadges){
showTaskShortcutBadges = showBadges;
}
//! setup the tasks first index based on the fact that this is a plasmoid
//! and applets could exist before it
function setTasksBaseIndex(base){
tasksBaseIndex = base;
}
function previewContainsMouse() {
if(toolTipDelegate && toolTipDelegate.containsMouse && toolTipDelegate.parentTask) {
return true;
} else {
return false;
}
}
function containsMouse(){
//console.log("s1...");
if (disableRestoreZoom && (root.contextMenu || windowsPreviewDlg.visible)) {
return;
} else {
disableRestoreZoom = false;
}
//if (previewContainsMouse())
// windowsPreviewDlg.hide(4);
if (previewContainsMouse())
return true;
//console.log("s3...");
var tasks = icList.contentItem.children;
for(var i=0; i0) {
url = url.substring( 0, url.indexOf("?iconData=" ) );
}
var path = url;
var filename = path.split("/").pop();
tasksExtendedManager.addToBeAddedLauncher(filename);
tasksModel.requestAddLauncher(url);
launchersUpdatedFor(url);
tasksModel.syncLaunchers();
}
function resetDragSource() {
dragSource.z = 0;
dragSource = null;
}
function setGlobalDirectRender(value) {
if (tasksExtendedManager.waitingLaunchersLength() > 0)
return;
if (latteView) {
latteView.setGlobalDirectRender(value);
} else {
if (value === true) {
if (root.containsMouse()) {
icList.directRender = true;
} else {
// console.log("direct render true ignored...");
}
} else {
icList.directRender = false;
}
}
}
function startCheckRestoreZoomTimer(duration) {
if (latteView) {
latteView.startCheckRestoreZoomTimer();
} else {
if (duration > 0) {
checkListHovered.startDuration(duration);
} else {
checkListHovered.startNormal();
}
}
}
function stopCheckRestoreZoomTimer() {
if (latteView) {
latteView.stopCheckRestoreZoomTimer();
} else {
checkListHovered.stop();
}
}
function startDirectRenderDelayerDuringEntering(){
if (latteView) {
latteView.startDirectRenderDelayerDuringEntering();
} else {
directRenderDelayerForEnteringTimer.start();
}
}
///REMOVE
/*function createContextMenu(task) {
var menu = root.contextMenuComponent.createObject(task);
menu.visualParent = task;
menu.mpris2Source = mpris2Source;
menu.activitiesCount = activityModelInstance.count;
return menu;
}*/
function createContextMenu(rootTask, modelIndex, args) {
var initialArgs = args || {}
initialArgs.visualParent = rootTask;
initialArgs.modelIndex = modelIndex;
initialArgs.mpris2Source = mpris2Source;
initialArgs.backend = backend;
root.contextMenu = root.contextMenuComponent.createObject(rootTask, initialArgs);
return root.contextMenu;
}
Component.onCompleted: {
updatePosition();
root.presentWindows.connect(backend.presentWindows);
root.windowsHovered.connect(backend.windowsHovered);
dragHelper.dropped.connect(resetDragSource);
}
Component.onDestruction: {
root.presentWindows.disconnect(backend.presentWindows);
root.windowsHovered.disconnect(backend.windowsHovered);
dragHelper.dropped.disconnect(resetDragSource);
}
//BEGIN states
//user set Panel Positions
// 0-Center, 1-Left, 2-Right, 3-Top, 4-Bottom
states: [
///Bottom Edge
State {
name: "bottomCenter"
when: ((plasmoid.location===PlasmaCore.Types.BottomEdge || plasmoid.location===PlasmaCore.Types.Floating)
&& root.userPanelPosition===Latte.Types.Center)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
AnchorChanges {
target: icList
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
},
State {
name: "bottomLeft"
when: ((plasmoid.location===PlasmaCore.Types.BottomEdge || plasmoid.location===PlasmaCore.Types.Floating)
&& root.userPanelPosition===Latte.Types.Left)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: icList
anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "bottomRight"
when: ((plasmoid.location===PlasmaCore.Types.BottomEdge || plasmoid.location===PlasmaCore.Types.Floating)
&& root.userPanelPosition===Latte.Types.Right)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: icList
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
},
///Top Edge
State {
name: "topCenter"
when: (plasmoid.location===PlasmaCore.Types.TopEdge && root.userPanelPosition===Latte.Types.Center)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
AnchorChanges {
target: icList
anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
},
State {
name: "topLeft"
when: (plasmoid.location===PlasmaCore.Types.TopEdge && root.userPanelPosition===Latte.Types.Left)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: icList
anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "topRight"
when: (plasmoid.location===PlasmaCore.Types.TopEdge && root.userPanelPosition===Latte.Types.Right)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: icList
anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
},
////Left Edge
State {
name: "leftCenter"
when: (plasmoid.location===PlasmaCore.Types.LeftEdge && root.userPanelPosition===Latte.Types.Center)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
AnchorChanges {
target: icList
anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
},
State {
name: "leftTop"
when: (plasmoid.location===PlasmaCore.Types.LeftEdge && root.userPanelPosition===Latte.Types.Top)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: icList
anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "leftBottom"
when: (plasmoid.location===PlasmaCore.Types.LeftEdge && root.userPanelPosition===Latte.Types.Bottom)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: icList
anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
},
///Right Edge
State {
name: "rightCenter"
when: (plasmoid.location===PlasmaCore.Types.RightEdge && root.userPanelPosition===Latte.Types.Center)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
AnchorChanges {
target: icList
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
},
State {
name: "rightTop"
when: (plasmoid.location===PlasmaCore.Types.RightEdge && root.userPanelPosition===Latte.Types.Top)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: icList
anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "rightBottom"
when: (plasmoid.location===PlasmaCore.Types.RightEdge && root.userPanelPosition===Latte.Types.Bottom)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: icList
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
}
]
//END states
}
diff --git a/plasmoid/package/contents/ui/task/TaskItem.qml b/plasmoid/package/contents/ui/task/TaskItem.qml
index dbceede5..7ed8a861 100644
--- a/plasmoid/package/contents/ui/task/TaskItem.qml
+++ b/plasmoid/package/contents/ui/task/TaskItem.qml
@@ -1,1610 +1,1635 @@
/*
* Copyright 2016 Smith AR
* Michail Vourlakos
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet
import org.kde.latte 0.2 as Latte
import "animations" as TaskAnimations
import "indicator" as Indicator
MouseArea{
id: taskItem
visible: false //true//(isStartup && root.durationTime !== 0) ? false : true
anchors.bottom: (root.position === PlasmaCore.Types.BottomPositioned) ? parent.bottom : undefined
anchors.top: (root.position === PlasmaCore.Types.TopPositioned) ? parent.top : undefined
anchors.left: (root.position === PlasmaCore.Types.LeftPositioned) ? parent.left : undefined
anchors.right: (root.position === PlasmaCore.Types.RightPositioned) ? parent.right : undefined
objectName: "TaskItem"
width: {
if (!visible)
return 0;
if (isSeparator)
return root.vertical ? root.iconSize + root.thickMargins : (root.dragSource || !root.parabolicEffectEnabled ? 5+root.lengthMargins : 0);
if (root.vertical) {
return wrapper.width;
} else {
return hiddenSpacerLeft.width+wrapper.width+hiddenSpacerRight.width;
}
}
/*onWidthChanged: {
console.log("T: " + itemIndex + " - " + launcherUrl + " - " + width + " _ "+ hiddenSpacerLeft.width + " _ " + wrapper.width + " _ " + hiddenSpacerRight.width);
}*/
height: {
if (!visible)
return 0;
if (isSeparator)
return !root.vertical ? root.iconSize + root.thickMargins : (root.dragSource || !root.parabolicEffectEnabled ? 5+root.lengthMargins: 0);
if (root.vertical) {
return hiddenSpacerLeft.height + wrapper.height + hiddenSpacerRight.height;
} else {
return wrapper.height;
}
}
acceptedButtons: Qt.LeftButton | Qt.MidButton | Qt.RightButton
hoverEnabled: visible && (!inAnimation) && (!IsStartup) && (!root.taskInAnimation)
&&(!inBouncingAnimation) && !isSeparator
// hoverEnabled: false
//opacity : isSeparator && (hiddenSpacerLeft.neighbourSeparator || hiddenSpacerRight.neighbourSeparator) ? 0 : 1
property bool buffersAreReady: false
property bool delayingRemove: ListView.delayRemove
property bool scalesUpdatedOnce: false
//states that exist in windows in a Group of windows
property bool hasActive: isActive
property bool hasMinimized: (IsGroupParent === true) ? subWindows.hasMinimized : isMinimized
property bool hasShown: (IsGroupParent === true) ? subWindows.hasShown : !isMinimized && isWindow
property bool inAttention: isDemandingAttention && plasmoid.status === PlasmaCore.Types.RequiresAttentionStatus ? true : false
/*animations flags*/
property bool inAnimation: true
property bool inAddRemoveAnimation: true
property bool inAttentionAnimation: false
property bool inBlockingAnimation: false
property bool inBouncingAnimation: false
property bool inFastRestoreAnimation: false
property bool inMimicParabolicAnimation: false
property bool inNewWindowAnimation: false
property real mimicParabolicScale: -1
property bool inPopup: false
property bool inRemoveStage: false
property bool isAbleToShowPreview: true
property bool isActive: (IsActive === true) ? true : false
property bool isDemandingAttention: (IsDemandingAttention === true) ? true : false
property bool isDragged: false
property bool isGroupable: (IsGroupable === true) ? true : false
property bool isGroupParent: (IsGroupParent === true) ? true : false
property bool isForcedHidden: false
property bool isLauncher: (IsLauncher === true) ? true : false
property bool isMinimized: (IsMinimized === true) ? true : false
property bool isSeparator: false
property bool isStartup: (IsStartup === true) ? true : false
property bool isWindow: (IsWindow === true) ? true : false
property bool isZoomed: false
property bool canPublishGeometries: (isWindow || isStartup || isGroupParent) && visible && width>=root.iconSize && height>=root.iconSize
&& !taskItem.delayingRemove
&& (wrapper.mScale===1 || wrapper.mScale===root.zoomFactor) //don't publish during zoomFactor
property bool pressed: false
property bool wheelIsBlocked: false
property int animationTime: (animationsEnabled ? root.durationTime : 2) * (1.2 *units.shortDuration)
property int badgeIndicator: 0 //it is used from external apps
property int hoveredIndex: icList.hoveredIndex
property int itemIndex: index
property int lastValidIndex: -1 //used for the removal animation
property int lastButtonClicked: -1;
property int pressX: -1
property int pressY: -1
property int resistanceDelay: 450
property int spacersMaxSize: Math.max(0,Math.ceil(0.55*root.iconSize) - root.lengthMargins)
property int windowsCount: subWindows.windowsCount
property int windowsMinimizedCount: subWindows.windowsMinimized
property string activity: tasksModel.activity
readonly property var m: model
readonly property int pid: model && model.AppPid ? model.AppPid : -1
readonly property string appName: model && model.AppName ? model.AppName : ""
property string modelLauncherUrl: (LauncherUrlWithoutIcon && LauncherUrlWithoutIcon !== null) ? LauncherUrlWithoutIcon : ""
property string modelLauncherUrlWithIcon: (LauncherUrl && LauncherUrl !== null) ? LauncherUrl : ""
property string launcherUrl: ""
property string launcherUrlWithIcon: ""
property string launcherName: ""
property Item tooltipVisualParent: wrapper.titleTooltipVisualParent
property Item previewsVisualParent: wrapper.previewsTooltipVisualParent
property Item wrapperAlias: wrapper
onModelLauncherUrlChanged: {
if (modelLauncherUrl !== ""){
launcherUrl = modelLauncherUrl;
//!extract the launcherName if possible
var nameStarts = launcherUrl.lastIndexOf("/");
if (nameStarts === -1){
nameStarts = launcherUrl.lastIndexOf(":");
}
var nameEnds = launcherUrl.lastIndexOf(".desktop");
if (nameStarts!==-1 && nameEnds!==-1 && nameStarts 0 && !isLauncher
readonly property bool playingAudio: hasAudioStream && audioStreams.some(function (item) {
return !item.corked
})
readonly property bool muted: hasAudioStream && audioStreams.every(function (item) {
return item.muted
})
readonly property int volume: {
if (!hasAudioStream){
return 0;
}
var maxVolume = 0;
for (var i=0; i maxVolume)
maxVolume = audioStreams[i].volume;
}
return maxVolume;
}
//////
property QtObject contextMenu: null
property QtObject draggingResistaner: null
property QtObject hoveredTimerObj: null
signal groupWindowAdded();
signal groupWindowRemoved();
signal checkWindowsStates();
Behavior on opacity {
// NumberAnimation { duration: (IsStartup || (IsLauncher) ) ? 0 : 400 }
NumberAnimation { duration: root.durationTime*units.longDuration }
}
Loader{
anchors.fill: parent
active: latteView && latteView.debugMode
sourceComponent: Rectangle{
anchors.fill: parent
color: "transparent"
border.color: "blue"
border.width: 1
}
}
SubWindows{
id: subWindows
property int previousCount: 0
onWindowsCountChanged: {
if (root.showWindowsOnlyFromLaunchers && !root.indicatorsEnabled) {
return;
}
if ((windowsCount >= 2) && (windowsCount > previousCount)
&& !(taskItem.containsMouse || parabolicManager.neighbourIsHovered(itemIndex)) ){
if(root.dragSource == null)
taskItem.groupWindowAdded();
}
else if ((windowsCount >=1) &&(windowsCount < previousCount)){
//sometimes this is triggered in dragging with no reason
if(root.dragSource == null && !taskItem.delayingRemove)
taskItem.groupWindowRemoved();
}
if (windowsCount>=1) {
taskItem.slotPublishGeometries();
}
//! workaround in order to update correctly the previousCount
//! windowsCount can not return to zero because is such case
//! the window task is removed and the launcher is added from
//! libtaskmanager
if (windowsCount>=1) {
previousCount = windowsCount;
}
}
}
Loader {
id: isSeparatorRectangle
active: (opacityN>0)
width: taskItem.width
height: taskItem.height
anchors.centerIn: separatorItem
property real opacityN: isSeparator && root.contextMenu && root.contextMenu.visualParent === taskItem ? 1 : 0
Behavior on opacityN {
NumberAnimation { duration: root.durationTime*units.longDuration }
}
sourceComponent: Rectangle{
anchors.fill: parent
opacity: isSeparatorRectangle.opacityN
radius: 3
property color tempColor: theme.highlightColor
color: tempColor
border.width: 1
border.color: theme.highlightColor
onTempColorChanged: tempColor.a = 0.35;
}
}
Item{
id:separatorItem
anchors.centerIn: parent
opacity: separatorShadow.active || forceHiddenState ? 0 : 0.4
visible: taskItem.isSeparator
width: root.vertical ? root.iconSize : (root.dragSource || root.editMode) ? 5+root.lengthMargins: 1
height: !root.vertical ? root.iconSize : (root.dragSource || root.editMode) ? 5+root.lengthMargins: 1
property bool forceHiddenState: false
Behavior on opacity {
NumberAnimation { duration: root.durationTime*units.longDuration }
}
function updateForceHiddenState() {
if (!isSeparator || root.editMode || root.dragSource) {
forceHiddenState = false;
} else {
var firstPosition = (index>=0) && (index < parabolicManager.firstRealTaskIndex);
var sepNeighbour = taskItem.hasNeighbourSeparator(index-1, false);
var firstSepFromLastSeparatorsGroup = (index>=0) && (index > parabolicManager.lastRealTaskIndex);
forceHiddenState = (firstPosition || sepNeighbour || firstSepFromLastSeparatorsGroup);
}
}
Component.onCompleted: {
updateForceHiddenState();
root.hiddenTasksUpdated.connect(updateForceHiddenState);
}
Component.onDestruction: {
root.hiddenTasksUpdated.disconnect(updateForceHiddenState);
}
onForceHiddenStateChanged: root.separatorsUpdated();
Connections{
target: root
onEditModeChanged: separatorItem.updateForceHiddenState();
onDragSourceChanged: separatorItem.updateForceHiddenState();
onSeparatorsUpdated: separatorItem.updateForceHiddenState();
//! During dock sliding-in because the parabolic effect isnt trigerred
//! immediately but we wait first the dock to go to its final normal
//! place we might miss the activation of the parabolic effect.
//! By catching that signal we are trying to solve this.
onDockIsShownCompletelyChanged: {
if (dockIsShownCompletely && taskItem.containsMouse) {
if (root.vertical) {
taskItem.mousePosChanged(taskItem.mouseY);
} else {
taskItem.mousePosChanged(taskItem.mouseX);
}
}
}
onGlobalDirectRenderChanged:{
if (root.globalDirectRender && restoreAnimation.running) {
// console.log("Cleat Task Scale !!!!");
restoreAnimation.stop();
}
}
onShowWindowsOnlyFromLaunchersChanged: {
if (!root.editMode) {
return;
}
taskItem.updateVisibilityBasedOnLaunchers();
}
onInActivityChangeChanged: {
if (root.showWindowsOnlyFromLaunchers && !root.inActivityChange) {
taskItem.updateVisibilityBasedOnLaunchers();
}
}
}
Rectangle {
anchors.centerIn: parent
width: root.vertical ? root.iconSize - 4 : 1
height: !root.vertical ? root.iconSize - 4 : 1
color: enforceLattePalette ? latteBridge.palette.textColor : theme.textColor
}
}
///Shadow in tasks
Loader{
id: separatorShadow
anchors.fill: separatorItem
active: root.enableShadows && isSeparator
opacity: separatorItem.forceHiddenState ? 0 : 0.4
Behavior on opacity {
NumberAnimation { duration: root.durationTime*units.longDuration }
}
sourceComponent: DropShadow{
anchors.fill: parent
color: root.appShadowColor
fast: true
samples: 2 * radius
source: separatorItem
radius: root.appShadowSize
verticalOffset: 2
}
}
/* Rectangle{
anchors.fill: parent
color: "transparent"
border.width: 1
border.color: "blue"
} */
Flow{
id: taskFlow
width: parent.width
height: parent.height
// a hidden spacer for the first element to add stability
// IMPORTANT: hidden spacers must be tested on vertical !!!
HiddenSpacer{ id:hiddenSpacerLeft;}
Item{
width: wrapper.width
height: wrapper.height
Indicator.Bridge{
id: indicatorBridge
}
Indicator.Loader{
id: indicatorBackLayer
level: Indicator.LevelOptions {
isBackground: true
bridge: indicatorBridge
}
}
Wrapper{id: wrapper}
Indicator.Loader{
id: indicatorFrontLayer
level: Indicator.LevelOptions {
isForeground: true
bridge: indicatorBridge
}
}
}
// a hidden spacer on the right for the last item to add stability
HiddenSpacer{ id:hiddenSpacerRight; rightSpacer: true }
}// Flow with hidden spacers inside
/*Rectangle{
anchors.fill: taskFlow
color: "transparent"
border.width: 1
border.color: "blue"
}*/
Component {
id: taskInitComponent
Timer {
id: timer
interval: 800
repeat: false
onTriggered: {
// taskItem.hoverEnabled = true;
slotPublishGeometries();
if (latteView && latteView.debugModeTimers) {
console.log("plasmoid timer: taskInitComponentTimer called...");
}
timer.destroy();
}
Component.onCompleted: timer.start()
}
}
////// Values Changes /////
//restore scales when there is no zoom factor for that item or
//the mouse is out of the ListView
// onItemIndexChanged: {
// }
onAppNameChanged: updateAudioStreams()
onPidChanged: updateAudioStreams()
onHasAudioStreamChanged: updateAudioStreams()
onCanPublishGeometriesChanged: {
if (canPublishGeometries) {
slotPublishGeometries();
taskInitComponent.createObject(taskItem);
}
}
onHoveredIndexChanged: {
var distanceFromHovered = Math.abs(index - icList.hoveredIndex);
/*if( (distanceFromHovered > 1) && (hoveredIndex !== -1)){
if(!isDragged)
wrapper.mScale = 1;
}*/
if (distanceFromHovered >= 1 && !inAttentionAnimation && !inFastRestoreAnimation && !inMimicParabolicAnimation) {
hiddenSpacerLeft.nScale = 0;
hiddenSpacerRight.nScale = 0;
}
}
onItemIndexChanged: {
if (isSeparator) {
root.separatorsUpdated();
}
if (itemIndex>=0)
lastValidTimer.start();
}
onLastValidIndexChanged: {
if (lastValidIndex>=0 && lastValidIndex parabolicManager.lastRealTaskIndex)) {
parabolicManager.updateTasksEdgesIndexes();
}
}
if (parabolicManager.hasInternalSeparator) {
root.separatorsUpdated();
}
}
onIsDraggedChanged: {
if(isDragged && (!root.inConfigureAppletsMode)){
root.dragSource = taskItem;
dragHelper.startDrag(taskItem, model.MimeType, model.MimeData,
model.LauncherUrlWithoutIcon, model.decoration);
pressX = -1;
pressY = -1;
}
}
onIsMinimizedChanged: {
checkWindowsStates();
}
onIsActiveChanged: {
checkWindowsStates();
if (isActive) {
scrollableList.focusOn(taskItem);
}
}
onIsForcedHiddenChanged: root.hiddenTasksUpdated();
onIsSeparatorChanged: {
if (isSeparator) {
root.separatorsUpdated();
if (tasksExtendedManager.isLauncherToBeMoved(launcherUrl) && itemIndex>=0) {
parabolicManager.moveLauncherToCorrectPos(launcherUrl, itemIndex);
}
} else {
root.separatorsUpdated();
}
}
onLauncherUrlChanged: updateBadge();
////// End of Values Changes /////
///////////////// Mouse Area Events ///////////////////
onEntered: {
root.stopCheckRestoreZoomTimer();
if (restoreAnimation.running) {
restoreAnimation.stop();
}
if (icList.hoveredIndex === -1 && root.dockHoveredIndex ===-1) {
root.startDirectRenderDelayerDuringEntering();
}
if ((icList.hoveredIndex !== itemIndex) && isLauncher && windowsPreviewDlg.visible) {
windowsPreviewDlg.hide(1);
}
if (!latteView || (latteView && !(latteView.dockIsHidden || latteView.inSlidingIn || latteView.inSlidingOut))){
icList.hoveredIndex = index;
}
if (root.latteView && !root.showPreviews && root.titleTooltips){
showTitleTooltip();
}
//! show previews if enabled
if(isAbleToShowPreview && ((root.showPreviews && windowsPreviewDlg.activeItem !== taskItem) || root.highlightWindows)){
if (hoveredTimerObj) {
//! don't delay showing preview in normal states,
//! that is when the dock wasn't hidden
if (!hoveredTimerObj.running) {
hoveredTimerObj.start();
}
} else {
if (!root.disableAllWindowsFunctionality) {
hoveredTimerObj = hoveredTimerComponent.createObject(taskItem);
}
}
}
- scrollableList.autoScrollFor(taskItem);
+ if (root.autoScrollTasksEnabled) {
+ scrollableList.autoScrollFor(taskItem);
+ }
if (root.latteView && root.latteView.isHalfShown) {
return;
}
}
// IMPORTANT: This must be improved ! even for small milliseconds it reduces performance
onExited: {
scalesUpdatedOnce = false;
isAbleToShowPreview = true;
if (root.latteView && (!root.showPreviews || (root.showPreviews && isLauncher))){
root.latteView.hideTooltipLabel();
}
if(taskItem.contextMenu && taskItem.contextMenu.status == PlasmaComponents.DialogStatus.Open){
///don't check to restore zooms
}
else{
if(!inAnimation){
root.startCheckRestoreZoomTimer();
}
}
/* if(draggingResistaner != null){
draggingResistaner.destroy();
draggingResistaner = null;
isDragged = false;
}*/
}
//! mouseX-Y values are delayed to be updated onEntered events and at the same time
//! onPositionChanged signal may be delayed. we can fix this by don't delay at all
//! when mouseX-Y is updated based on the plasmoid formFactor
function mousePosChanged(mousePos) {
if (mousePos<0 ||
(inBlockingAnimation && !(inAttentionAnimation||inFastRestoreAnimation||inMimicParabolicAnimation)))
return;
root.stopCheckRestoreZoomTimer();
if (root.latteView && root.latteView.isHalfShown) {
return;
}
if((inAnimation == false)&&(!root.taskInAnimation)&&(!root.disableRestoreZoom) && hoverEnabled){
if (icList.hoveredIndex === -1 && root.dockHoveredIndex ===-1) {
root.startDirectRenderDelayerDuringEntering();
}
if (!latteView || (latteView && !(latteView.dockIsHidden || latteView.inSlidingIn || latteView.inSlidingOut))){
icList.hoveredIndex = index;
}
if (!root.globalDirectRender && !root.directRenderDelayerIsRunning) {
root.setGlobalDirectRender(true);
}
if( ((wrapper.mScale == 1 || wrapper.mScale === root.zoomFactor) && !root.globalDirectRender)
|| root.globalDirectRender || !scalesUpdatedOnce) {
if(root.dragSource == null){
var step = Math.abs(icList.currentSpot-mousePos);
if (step >= root.animationStep){
icList.currentSpot = mousePos;
wrapper.calculateScales(mousePos);
}
}
}
}
}
onMouseXChanged: {
if (!root.vertical) {
mousePosChanged(mouseX);
}
}
onMouseYChanged: {
if (root.vertical) {
mousePosChanged(mouseY);
}
}
onPositionChanged: {
if ((inBlockingAnimation && !(inAttentionAnimation||inFastRestoreAnimation||inMimicParabolicAnimation)))
return;
if (root.latteView && root.latteView.isHalfShown) {
return;
}
if((inAnimation == false)&&(!root.taskInAnimation)&&(!root.disableRestoreZoom) && hoverEnabled){
// mouse.button is always 0 here, hence checking with mouse.buttons
if (pressX != -1 && mouse.buttons == Qt.LeftButton
&& isDragged
&& dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y) ) {
root.dragSource = taskItem;
dragHelper.startDrag(taskItem, model.MimeType, model.MimeData,
model.LauncherUrlWithoutIcon, model.decoration);
pressX = -1;
pressY = -1;
}
}
}
onContainsMouseChanged:{
if(!containsMouse && !inAnimation) {
pressed=false;
}
////disable hover effect///
if (isWindow && root.highlightWindows && !containsMouse) {
root.windowsHovered( root.plasma515 ? model.WinIdList : model.LegacyWinIdList , false);
}
}
onPressed: {
//console.log("Pressed Task Delegate..");
if (Latte.WindowSystem.compositingActive && !Latte.WindowSystem.isPlatformWayland) {
if(root.leftClickAction !== Latte.Types.PreviewWindows) {
isAbleToShowPreview = false;
windowsPreviewDlg.hide(2);
}
}
slotPublishGeometries();
var modAccepted = modifierAccepted(mouse);
if ((mouse.button == Qt.LeftButton)||(mouse.button == Qt.MidButton) || modAccepted) {
lastButtonClicked = mouse.button;
pressed = true;
pressX = mouse.x;
pressY = mouse.y;
if(draggingResistaner == null && !modAccepted)
draggingResistaner = resistanerTimerComponent.createObject(taskItem);
}
else if (mouse.button == Qt.RightButton && !modAccepted){
// When we're a launcher, there's no window controls, so we can show all
// places without the menu getting super huge.
if (model.IsLauncher === true && !isSeparator) {
showContextMenu({showAllPlaces: true})
} else {
showContextMenu();
}
}
}
onReleased: {
//console.log("Released Task Delegate...");
if (draggingResistaner != null){
draggingResistaner.destroy();
draggingResistaner = null;
}
if(pressed && (!inBlockingAnimation || inAttentionAnimation) && !isSeparator){
if (modifierAccepted(mouse) && !root.disableAllWindowsFunctionality){
if( !taskItem.isLauncher){
if (root.modifierClickAction == Latte.Types.NewInstance) {
tasksModel.requestNewInstance(modelIndex());
} else if (root.modifierClickAction == Latte.Types.Close) {
tasksModel.requestClose(modelIndex());
} else if (root.modifierClickAction == Latte.Types.ToggleMinimized) {
tasksModel.requestToggleMinimized(modelIndex());
} else if ( root.modifierClickAction == Latte.Types.CycleThroughTasks) {
if (isGroupParent)
subWindows.activateNextTask();
else
activateTask();
} else if (root.modifierClickAction == Latte.Types.ToggleGrouping) {
tasksModel.requestToggleGrouping(modelIndex());
}
} else {
activateTask();
}
} else if (mouse.button == Qt.MidButton && !root.disableAllWindowsFunctionality){
if( !taskItem.isLauncher){
if (root.middleClickAction == Latte.Types.NewInstance) {
tasksModel.requestNewInstance(modelIndex());
} else if (root.middleClickAction == Latte.Types.Close) {
tasksModel.requestClose(modelIndex());
} else if (root.middleClickAction == Latte.Types.ToggleMinimized) {
tasksModel.requestToggleMinimized(modelIndex());
} else if ( root.middleClickAction == Latte.Types.CycleThroughTasks) {
if (isGroupParent)
subWindows.activateNextTask();
else
activateTask();
} else if (root.middleClickAction == Latte.Types.ToggleGrouping) {
tasksModel.requestToggleGrouping(modelIndex());
}
} else {
activateTask();
}
} else if (mouse.button == Qt.LeftButton){
if( !taskItem.isLauncher){
if (root.leftClickAction === Latte.Types.PresentWindows && !(isGroupParent && !Latte.WindowSystem.compositingActive)) {
activateTask();
} else if (root.leftClickAction === Latte.Types.CycleThroughTasks) {
if (isGroupParent)
subWindows.activateNextTask();
else
activateTask();
} else if (root.leftClickAction === Latte.Types.PreviewWindows || !Latte.WindowSystem.compositingActive) {
if(windowsPreviewDlg.activeItem !== taskItem){
showPreviewWindow();
} else {
hidePreviewWindow();
}
}
} else {
activateTask();
}
}
backend.cancelHighlightWindows();
}
pressed = false;
if(!inAnimation) {
startCheckRestoreZoomTimer(3*units.longDuration);
}
}
- onWheel: {
- if (isSeparator || !root.mouseWheelActions || wheelIsBlocked || inBouncingAnimation
+ onWheel: {
+ if (isSeparator
+ || wheelIsBlocked
+ || !(root.mouseWheelActions || manualScrollTasksEnabled)
+ || inBouncingAnimation
|| (latteView && (latteView.dockIsHidden || latteView.inSlidingIn || latteView.inSlidingOut))){
return;
}
- var angle = wheel.angleDelta.y / 8;
+ var angleVertical = wheel.angleDelta.y / 8;
+ var angleHorizontal = wheel.angleDelta.x / 8;
wheelIsBlocked = true;
scrollDelayer.start();
- //positive direction
- if (angle > 12) {
+ var verticalDirection = (Math.abs(angleVertical) > Math.abs(angleHorizontal));
+ var mainAngle = verticalDirection ? angleVertical : angleHorizontal;
+
+ var positiveDirection = (mainAngle > 12);
+ var negativeDirection = (mainAngle < -12);
+
+ var parallelScrolling = (verticalDirection && plasmoid.formFactor === PlasmaCore.Types.Vertical)
+ || (!verticalDirection && plasmoid.formFactor === PlasmaCore.Types.Horizontal);
+
+ if (positiveDirection) {
slotPublishGeometries();
- if (root.scrollingEnabled && scrollableList.contentsExceed) {
+ var overflowScrollingAccepted = (root.manualScrollTasksEnabled
+ && scrollableList.contentsExceed
+ && (root.manualScrollTasksType === Latte.Types.ManualScrollVerticalHorizontal
+ || (root.manualScrollTasksType === Latte.Types.ManualScrollOnlyParallel && parallelScrolling)) );
+
+
+ if (overflowScrollingAccepted) {
scrollableList.increasePos();
- } else {
+ } else if (root.mouseWheelActions){
if (isLauncher || root.disableAllWindowsFunctionality) {
wrapper.runLauncherAnimation();
} else if (isGroupParent) {
subWindows.activateNextTask();
} else {
var taskIndex = modelIndex();
if (isMinimized) {
tasksModel.requestToggleMinimized(taskIndex);
}
tasksModel.requestActivate(taskIndex);
}
hidePreviewWindow();
}
- } else if (angle < -12) {
+ } else if (negativeDirection) {
slotPublishGeometries();
- //negative direction
- if (root.scrollingEnabled && scrollableList.contentsExceed) {
+ var overflowScrollingAccepted = (root.manualScrollTasksEnabled
+ && scrollableList.contentsExceed
+ && (root.manualScrollTasksType === Latte.Types.ManualScrollVerticalHorizontal
+ || (root.manualScrollTasksType === Latte.Types.ManualScrollOnlyParallel && parallelScrolling)) );
+
+
+ if (overflowScrollingAccepted) {
scrollableList.decreasePos();
- } else {
+ } else if (root.mouseWheelActions){
if (isLauncher || root.disableAllWindowsFunctionality) {
// do nothing
} else if (isGroupParent) {
subWindows.activatePreviousTask();
} else {
var taskIndex = modelIndex();
if (isMinimized) {
tasksModel.requestToggleMinimized(taskIndex);
}
tasksModel.requestActivate(taskIndex);
}
hidePreviewWindow();
}
}
}
//! A timer is needed in order to handle also touchpads that probably
//! send too many signals very fast. This way the signals per sec are limited.
//! The user needs to have a steady normal scroll in order to not
//! notice a annoying delay
Timer{
id: scrollDelayer
interval: 400
onTriggered: taskItem.wheelIsBlocked = false;
}
///////////////// End Of Mouse Area Events ///////////////////
///// Handlers for Signals /////
function animationStarted(){
// console.log("Animation started: " + index);
inAnimation = true;
}
function animationEnded(){
// console.log("Animation ended: " + index);
inAnimation = false;
}
function clearZoom(){
if(!root)
return;
if (root.hoveredIndex === -1 && root.dockHoveredIndex === -1) {
restoreAnimation.start();
}
}
function handlerDraggingFinished(){
isDragged = false;
}
///// End of Handlers //////
///// Helper functions /////
function activateNextTask() {
subWindows.activateNextTask();
}
function activateTask() {
if( taskItem.isLauncher || root.disableAllWindowsFunctionality){
if (Latte.WindowSystem.compositingActive) {
wrapper.runLauncherAnimation();
} else {
launcherAction();
}
}
else{
if (model.IsGroupParent) {
if (Latte.WindowSystem.compositingActive && backend.canPresentWindows()) {
root.presentWindows(root.plasma515 ? model.WinIdList: model.LegacyWinIdList );
}
} else {
if (IsMinimized === true) {
var i = modelIndex();
tasksModel.requestToggleMinimized(i);
tasksModel.requestActivate(i);
} else if (IsActive === true) {
tasksModel.requestToggleMinimized(modelIndex());
} else {
tasksModel.requestActivate(modelIndex());
}
}
}
}
function hasNeighbourSeparator(ind, positive) {
var cursor = ind;
while (((!positive && cursor>=0) || (positive && cursor<=root.tasksCount-1))
&& parabolicManager.taskIsForcedHidden(cursor) ) {
cursor = positive ? cursor + 1 : cursor - 1;
}
return parabolicManager.taskIsSeparator(cursor);
}
function showPreviewWindow() {
if (root.disableAllWindowsFunctionality || !isAbleToShowPreview) {
return;
}
if(windowsPreviewDlg.activeItem !== taskItem){
if (!root.latteView
|| (root.latteView && !root.latteView.isHalfShown && !root.latteView.inSlidingIn && !root.latteView.inSlidingOut)) {
if (root.latteView && root.titleTooltips) {
root.latteView.hideTooltipLabel();
}
taskItem.preparePreviewWindow(false);
windowsPreviewDlg.show(taskItem);
}
}
}
function showTitleTooltip() {
if (root.latteView && root.titleTooltips){
var displayText = isWindow ? model.display : model.AppName;
var maxCharacters = 80;
var fixedDisplayText = displayText.length>maxCharacters ? displayText.substring(0,maxCharacters-1) + "..." : displayText;
root.latteView.showTooltipLabel(taskItem, fixedDisplayText);
}
}
function hidePreviewWindow() {
if(windowsPreviewDlg.activeItem === taskItem){
windowsPreviewDlg.hide("14.1");
if (root.latteView && root.titleTooltips && containsMouse) {
showTitleTooltip();
}
}
}
function preparePreviewWindow(hideClose){
windowsPreviewDlg.visualParent = previewsVisualParent;
toolTipDelegate.parentTask = taskItem;
toolTipDelegate.rootIndex = tasksModel.makeModelIndex(itemIndex, -1);
toolTipDelegate.hideCloseButtons = hideClose;
toolTipDelegate.appName = Qt.binding(function() {
return model.AppName;
});
if (!isLauncher) {
toolTipDelegate.pidParent = Qt.binding(function() {
return model.AppPid;
});
} else {
toolTipDelegate.pidParent = -1;
}
toolTipDelegate.windows = Qt.binding(function() {
return root.plasma515 ? model.WinIdList : model.LegacyWinIdList ;
});
toolTipDelegate.isGroup = Qt.binding(function() {
return model.IsGroupParent == true;
});
toolTipDelegate.icon = Qt.binding(function() {
return model.decoration;
});
toolTipDelegate.launcherUrl = Qt.binding(function() {
return model.LauncherUrlWithoutIcon;
});
toolTipDelegate.isLauncher = Qt.binding(function() {
return model.IsLauncher == true;
});
toolTipDelegate.isMinimizedParent = Qt.binding(function() {
return model.IsMinimized == true;
});
toolTipDelegate.displayParent = Qt.binding(function() {
return model.display;
});
toolTipDelegate.genericName = Qt.binding(function() {
return model.GenericName;
});
toolTipDelegate.virtualDesktopParent = Qt.binding(function() {
return (model.VirtualDesktops !== undefined && model.VirtualDesktops.length === 0) ? model.VirtualDesktops : [0];
});
toolTipDelegate.isOnAllVirtualDesktopsParent = Qt.binding(function() {
return model.IsOnAllVirtualDesktops == true;
});
toolTipDelegate.activitiesParent = Qt.binding(function() {
return model.Activities;
});
}
function launcherAction(){
// if ((lastButtonClicked == Qt.LeftButton)||(lastButtonClicked == Qt.MidButton)){
if (Latte.WindowSystem.compositingActive) {
inBouncingAnimation = true;
tasksExtendedManager.addWaitingLauncher(taskItem.launcherUrl);
}
if (root.disableAllWindowsFunctionality) {
tasksModel.requestNewInstance(modelIndex());
} else {
tasksModel.requestActivate(modelIndex());
}
}
///window previews///
function generateSubText(task) {
var subTextEntries = new Array();
if (!plasmoid.configuration.showOnlyCurrentDesktop
&& virtualDesktopInfo.numberOfDesktops > 1
&& model.IsOnAllVirtualDesktops !== true
&& model.VirtualDesktop != -1
&& model.VirtualDesktop != undefined) {
subTextEntries.push(i18n("On %1", virtualDesktopInfo.desktopNames[model.VirtualDesktop - 1]));
}
if (model.Activities == undefined) {
return subTextEntries.join("\n");
}
if (model.Activities.length == 0 && activityInfo.numberOfRunningActivities > 1) {
subTextEntries.push(i18nc("Which virtual desktop a window is currently on",
"Available on all activities"));
} else if (model.Activities.length > 0) {
var activityNames = new Array();
for (var i = 0; i < model.Activities.length; i++) {
var activity = model.Activities[i];
if (plasmoid.configuration.showOnlyCurrentActivity) {
if (activity != activityInfo.currentActivity) {
activityNames.push(activityInfo.activityName(model.Activities[i]));
}
} else if (activity != activityInfo.currentActivity) {
activityNames.push(activityInfo.activityName(model.Activities[i]));
}
}
if (plasmoid.configuration.showOnlyCurrentActivity) {
if (activityNames.length > 0) {
subTextEntries.push(i18nc("Activities a window is currently on (apart from the current one)",
"Also available on %1", activityNames.join(", ")));
}
} else if (activityNames.length > 0) {
subTextEntries.push(i18nc("Which activities a window is currently on",
"Available on %1", activityNames.join(", ")));
}
}
return subTextEntries.join("\n");
}
///window previews////
function modelIndex(){
return tasksModel.makeModelIndex(index);
}
function showContextMenu(args) {
if (isSeparator && !root.editMode)
return;
if (!root.contextMenu) {
contextMenu = root.createContextMenu(taskItem, modelIndex(), args);
contextMenu.show();
} else {
//! make sure that context menu isnt deleted multiple times and creates a crash
//! bug case: 397635
var cMenu = root.contextMenu;
root.contextMenu = null;
cMenu.destroy();
}
}
function modifierAccepted(mouse){
if (mouse.modifiers & root.modifierQt){
if ((mouse.button === Qt.LeftButton && root.modifierClick === Latte.Types.LeftClick)
|| (mouse.button === Qt.MiddleButton && root.modifierClick === Latte.Types.MiddleClick)
|| (mouse.button === Qt.RightButton && root.modifierClick === Latte.Types.RightClick))
return true;
}
return false;
}
function setBlockingAnimation(value){
inBlockingAnimation = value;
}
function slotMimicEnterForParabolic(){
if (containsMouse) {
if (inMimicParabolicAnimation) {
mimicParabolicScale = root.zoomFactor;
}
wrapper.calculateScales(icList.currentSpot);
}
}
function slotShowPreviewForTasks(group) {
if (group === taskItem && !windowsPreviewDlg.visible) {
preparePreviewWindow(true);
windowsPreviewDlg.show(taskItem);
}
}
function slotPublishGeometries() {
//! this way we make sure that layouts that are in different activities that the current layout
//! don't publish their geometries
if ( canPublishGeometries && (!latteView || root.viewLayoutIsCurrent)) {
var globalChoords = backend.globalRect(wrapper.visualIconItem);
var limits = backend.globalRect(scrollableList);
//! Limit the published geometries boundaries at scrolling area boundaries
var adjX = Math.min(limits.x+limits.width, Math.max(limits.x, globalChoords.x));
var adjY = Math.min(limits.y+limits.height, Math.max(limits.y, globalChoords.y));
var length = root.iconSize * wrapper.mScale;
//! Magic Lamp effect doesn't like coordinates outside the screen and
//! width,heights of zero value... So we now normalize the geometries
//! sent in order to avoid such circumstances
if (root.vertical) {
if (adjY !== globalChoords.y) {
if (((globalChoords.y+globalChoords.height) < limits.y) || (globalChoords.y)>(limits.y+limits.height)) {
//! totally out of boundaries
length = 4;
} else {
//! semi-part out of boundaries
length = Math.max(4, Math.abs(adjY - globalChoords.y));
}
}
globalChoords.width = 1;
globalChoords.height = length;
} else {
if (adjX !== globalChoords.x) {
if (((globalChoords.x+globalChoords.width) < limits.x) || (globalChoords.x)>(limits.x+limits.width)) {
//! totally out of boundaries
length = 4;
} else {
//! semi-part out of boundaries
length = Math.max(4, Math.abs(adjX - globalChoords.x));
}
}
globalChoords.height = 1;
globalChoords.width = length;
}
globalChoords.x = adjX;
globalChoords.y = adjY;
if (root.position === PlasmaCore.Types.BottomPositioned) {
globalChoords.y = root.screenGeometry.y+root.screenGeometry.height-1;
} else if (root.position === PlasmaCore.Types.TopPositioned) {
globalChoords.y = root.screenGeometry.y+1;
} else if (root.position === PlasmaCore.Types.LeftPositioned) {
globalChoords.x = root.screenGeometry.x+1;
} else if (root.position === PlasmaCore.Types.RightPositioned) {
globalChoords.x = root.screenGeometry.x+root.screenGeometry.width - 1;
}
tasksModel.requestPublishDelegateGeometry(taskItem.modelIndex(), globalChoords, taskItem);
}
}
function slotWaitingLauncherRemoved(launch) {
if ((isWindow || isStartup || isLauncher) && !visible && launch === launcherUrl) {
wrapper.mScale = 1;
visible = true;
}
}
function updateAudioStreams() {
if (root.dragSource !== null) {
audioStreams = [];
return;
}
var pa = pulseAudio.item;
if (!pa) {
audioStreams = [];
return;
}
var streams = pa.streamsForPid(taskItem.pid);
if (streams.length) {
pa.registerPidMatch(taskItem.appName);
} else {
// We only want to fall back to appName matching if we never managed to map
// a PID to an audio stream window. Otherwise if you have two instances of
// an application, one playing and the other not, it will look up appName
// for the non-playing instance and erroneously show an indicator on both.
if (!pa.hasPidMatch(taskItem.appName)) {
var streams_result;
streams_result = pa.streamsForAppName(taskItem.appName);
if (streams_result.length===0 && launcherName !== "") {
streams_result = pa.streamsForAppName(launcherName);
}
streams = streams_result;
}
}
// fix a binding loop concerning audiostreams, the audiostreams
// should be updated only when they have changed
var changed = false;
if (streams.length !== audioStreams.length) {
changed = true;
} else {
for(var i=0; i= 0){
taskItem.lastValidIndex = taskItem.itemIndex;
if (root.showWindowsOnlyFromLaunchers) {
parabolicManager.updateTasksEdgesIndexes();
}
}
if (latteView && latteView.debugModeTimers) {
console.log("plasmoid timer: lastValidTimer called...");
}
}
}
///Item's Removal Animation
ListView.onRemove: TaskAnimations.RealRemovalAnimation{ id: taskRealRemovalAnimation }
}// main Item
diff --git a/plasmoid/package/contents/ui/taskslayout/ScrollableList.qml b/plasmoid/package/contents/ui/taskslayout/ScrollableList.qml
index 164ad0bf..e4099993 100644
--- a/plasmoid/package/contents/ui/taskslayout/ScrollableList.qml
+++ b/plasmoid/package/contents/ui/taskslayout/ScrollableList.qml
@@ -1,396 +1,396 @@
/*
* Copyright 2019 Michail Vourlakos
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import QtQuick 2.7
import QtQuick.Controls 1.4
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.latte 0.2 as Latte
Flickable{
id: flickableContainer
clip: false
flickableDirection: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? Flickable.HorizontalFlick : Flickable.VerticalFlick
interactive: false
property int offset: 0
readonly property bool animationsFinished: !horizontalAnimation.running && !verticalAnimation.running
readonly property bool centered: userPanelPosition === Latte.Types.Center
readonly property bool reversed: Qt.application.layoutDirection === Qt.RightToLeft
readonly property bool contentsExceed: !root.vertical ? Math.floor(contentWidth) > width : Math.floor(contentHeight) > height
readonly property int contentsExtraSpace: {
if (contentsExceed) {
if (!root.vertical) {
return contentWidth - width;
} else {
return contentHeight - height;
}
}
return 0;
}
readonly property int scrollFirstPos: 0
readonly property int scrollLastPos: contentsExtraSpace
readonly property int scrollStep: root.iconSize * 1.5
readonly property int currentPos: !root.vertical ? contentX : contentY
readonly property int autoScrollTriggerLength: root.iconSize + root.lengthMargins/2
readonly property int alignment: {
if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
if (centered) return Latte.Types.LeftEdgeCenterAlign;
if (userPanelPosition === Latte.Types.Top) return Latte.Types.LeftEdgeTopAlign;
if (userPanelPosition === Latte.Types.Bottom) return Latte.Types.LeftEdgeBottomAlign;
}
if (plasmoid.location === PlasmaCore.Types.RightEdge) {
if (centered) return Latte.Types.RightEdgeCenterAlign;
if (userPanelPosition === Latte.Types.Top) return Latte.Types.RightEdgeTopAlign;
if (userPanelPosition === Latte.Types.Bottom) return Latte.Types.RightEdgeBottomAlign;
}
if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
if (centered) return Latte.Types.BottomEdgeCenterAlign;
if ((userPanelPosition === Latte.Types.Left && !reversed)
|| (userPanelPosition === Latte.Types.Right && reversed)) {
return Latte.Types.BottomEdgeLeftAlign;
}
if ((userPanelPosition === Latte.Types.Right && !reversed)
|| (userPanelPosition === Latte.Types.Left && reversed)) {
return Latte.Types.BottomEdgeRightAlign;
}
}
if (plasmoid.location === PlasmaCore.Types.TopEdge) {
if (centered) return Latte.Types.TopEdgeCenterAlign;
if ((userPanelPosition === Latte.Types.Left && !reversed)
|| (userPanelPosition === Latte.Types.Right && reversed)) {
return Latte.Types.TopEdgeLeftAlign;
}
if ((userPanelPosition === Latte.Types.Right && !reversed)
|| (userPanelPosition === Latte.Types.Left && reversed)) {
return Latte.Types.TopEdgeRightAlign;
}
}
return Latte.Types.BottomEdgeCenterAlign;
}
function increasePos() {
increasePosWithStep(scrollStep);
}
function decreasePos() {
decreasePosWithStep(scrollStep);
}
function increasePosWithStep(step) {
if (!root.vertical) {
contentX = Math.min(scrollLastPos, contentX + step);
} else {
contentY = Math.min(scrollLastPos, contentY + step);
}
}
function decreasePosWithStep(step) {
if (!root.vertical) {
contentX = Math.max(scrollFirstPos, contentX - step);
} else {
contentY = Math.max(scrollFirstPos, contentY - step);
}
}
function focusOn(task) {
if (!contentsExceed) {
return;
}
var cP = task.mapToItem(scrollableList, 0, 0);
var distance = 0;
if (!root.vertical) {
if (cP.x < 0) {
distance = Math.abs(cP.x - root.iconSize);
decreasePosWithStep(distance);
} else if ((cP.x+task.width) > scrollableList.width) {
distance = Math.abs(cP.x - scrollableList.width + task.width + root.iconSize);
increasePosWithStep(distance);
}
} else {
if (cP.y < 0) {
distance = Math.abs(cP.y - root.iconSize);
decreasePosWithStep(distance);
} else if ((cP.y+task.height) > scrollableList.height) {
distance = Math.abs(cP.y - scrollableList.height + task.height + root.iconSize);
increasePosWithStep(distance);
}
}
}
function autoScrollFor(task) {
//! It has TWO IN-QUESTION issues that may have been solved by the
//! initial checks
//! 1. when the user uses the mouse wheel at the first or the last task
//! the autoscrolling forcefully returns the view to boundaries
//! 2. when parabolic effect is activated the experience is not that smooth
//! at the view boundaries, parabolic effect AND autoscroll at the
//! boundaries create animation breakage
- if (!contentsExceed || root.tasksCount < 3
+ if (!root.autoScrollTasksEnabled || !contentsExceed || root.tasksCount < 3
|| (task.itemIndex===parabolicManager.lastRealTaskIndex && root.zoomFactor>1)) {
//last task with parabolic effect breaks the autoscolling behavior
return;
}
var cP = task.mapToItem(scrollableList, 0, 0);
if (!root.vertical) {
if (currentPos !== scrollFirstPos && cP.x < autoScrollTriggerLength) {
decreasePosWithStep(root.iconSize*1.5);
} else if (currentPos !== scrollLastPos && (cP.x+task.width > (scrollableList.width-autoScrollTriggerLength))) {
increasePosWithStep(root.iconSize*1.5);
}
} else {
if (currentPos !== scrollFirstPos && cP.y < autoScrollTriggerLength) {
decreasePosWithStep(root.iconSize*1.5);
} else if (currentPos !== scrollLastPos && (cP.y+task.height > (scrollableList.height-autoScrollTriggerLength))) {
increasePosWithStep(root.iconSize*1.5);
}
}
}
onContentsExtraSpaceChanged: {
if (!root.vertical) {
if (contentX < scrollFirstPos) {
contentX = scrollFirstPos;
} else if (contentX > scrollLastPos) {
contentX = scrollLastPos;
}
} else {
if (contentY < scrollFirstPos) {
contentY = scrollFirstPos;
} else if (contentY > scrollLastPos) {
contentY = scrollLastPos;
}
}
}
Behavior on contentX {
NumberAnimation {
id: horizontalAnimation
duration: root.durationTime*1.7*units.longDuration
easing.type: Easing.OutQuad
}
}
Behavior on contentY {
NumberAnimation {
id: verticalAnimation
duration: root.durationTime*1.7*units.longDuration
easing.type: Easing.OutQuad
}
}
//////////////////////////BEGIN states
//user set Panel Positions
// 0-Center, 1-Left, 2-Right, 3-Top, 4-Bottom
states: [
///Left Edge
State {
name: "leftCenter"
when: flickableContainer.alignment === Latte.Types.LeftEdgeCenterAlign
AnchorChanges {
target: flickableContainer
anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:0;
anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: flickableContainer.offset;
}
},
State {
name: "leftTop"
when: flickableContainer.alignment === Latte.Types.LeftEdgeTopAlign
AnchorChanges {
target: flickableContainer
anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:flickableContainer.offset; anchors.bottomMargin:flickableContainer.lastMargin;
anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
}
},
State {
name: "leftBottom"
when: flickableContainer.alignment === Latte.Types.LeftEdgeBottomAlign
AnchorChanges {
target: flickableContainer
anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:flickableContainer.lastMargin; anchors.bottomMargin:flickableContainer.offset;
anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
}
},
///Right Edge
State {
name: "rightCenter"
when: flickableContainer.alignment === Latte.Types.RightEdgeCenterAlign
AnchorChanges {
target: flickableContainer
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:0;
anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: flickableContainer.offset;
}
},
State {
name: "rightTop"
when: flickableContainer.alignment === Latte.Types.RightEdgeTopAlign
AnchorChanges {
target: flickableContainer
anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:flickableContainer.offset; anchors.bottomMargin:flickableContainer.lastMargin;
anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
}
},
State {
name: "rightBottom"
when: flickableContainer.alignment === Latte.Types.RightEdgeBottomAlign
AnchorChanges {
target: flickableContainer
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:flickableContainer.lastMargin; anchors.bottomMargin:flickableContainer.offset;
anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
}
},
///Bottom Edge
State {
name: "bottomCenter"
when: flickableContainer.alignment === Latte.Types.BottomEdgeCenterAlign
AnchorChanges {
target: flickableContainer
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:0;
anchors.horizontalCenterOffset: flickableContainer.offset; anchors.verticalCenterOffset: 0;
}
},
State {
name: "bottomLeft"
when: flickableContainer.alignment === Latte.Types.BottomEdgeLeftAlign
AnchorChanges {
target: flickableContainer
anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: flickableContainer.offset; anchors.rightMargin:flickableContainer.lastMargin; anchors.topMargin:0; anchors.bottomMargin:0;
anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
}
},
State {
name: "bottomRight"
when: flickableContainer.alignment === Latte.Types.BottomEdgeRightAlign
AnchorChanges {
target: flickableContainer
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: flickableContainer.lastMargin; anchors.rightMargin:flickableContainer.offset; anchors.topMargin:0; anchors.bottomMargin:0;
anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
}
},
///Top Edge
State {
name: "topCenter"
when: flickableContainer.alignment === Latte.Types.TopEdgeCenterAlign
AnchorChanges {
target: flickableContainer
anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:0;
anchors.horizontalCenterOffset: flickableContainer.offset; anchors.verticalCenterOffset: 0;
}
},
State {
name: "topLeft"
when: flickableContainer.alignment === Latte.Types.TopEdgeLeftAlign
AnchorChanges {
target: flickableContainer
anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: flickableContainer.offset; anchors.rightMargin:flickableContainer.lastMargin; anchors.topMargin:0; anchors.bottomMargin:0;
anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
}
},
State {
name: "topRight"
when: flickableContainer.alignment === Latte.Types.TopEdgeRightAlign
AnchorChanges {
target: flickableContainer
anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
PropertyChanges{
target: flickableContainer;
anchors.leftMargin: flickableContainer.lastMargin; anchors.rightMargin:flickableContainer.offset; anchors.topMargin:0; anchors.bottomMargin:0;
anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
}
}
]
}
diff --git a/shell/package/contents/configuration/pages/TasksConfig.qml b/shell/package/contents/configuration/pages/TasksConfig.qml
index defc80d1..4fa84070 100644
--- a/shell/package/contents/configuration/pages/TasksConfig.qml
+++ b/shell/package/contents/configuration/pages/TasksConfig.qml
@@ -1,554 +1,625 @@
/*
* Copyright 2016 Smith AR
* Michail Vourlakos
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.plasmoid 2.0
import org.kde.latte 0.2 as Latte
import org.kde.latte.components 1.0 as LatteComponents
PlasmaComponents.Page {
Layout.maximumWidth: content.width + content.Layout.leftMargin * 2
Layout.maximumHeight: content.height + units.smallSpacing * 2
property bool disableAllWindowsFunctionality: plasmoid.configuration.showWindowsOnlyFromLaunchers
&& plasmoid.configuration.activeIndicator === Latte.Types.NoneIndicator
ColumnLayout {
id: content
width: (dialog.appliedWidth - units.smallSpacing * 2) - Layout.leftMargin * 2
spacing: dialog.subGroupSpacing
anchors.horizontalCenter: parent.horizontalCenter
Layout.leftMargin: units.smallSpacing * 2
Layout.rightMargin: units.smallSpacing * 2
//! BEGIN: Badges
ColumnLayout {
spacing: units.smallSpacing
Layout.topMargin: units.smallSpacing
visible: dialog.highLevel
LatteComponents.Header {
text: i18n("Badges")
}
LatteComponents.CheckBoxesColumn {
Layout.leftMargin: units.smallSpacing * 2
Layout.rightMargin: units.smallSpacing * 2
LatteComponents.CheckBox {
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Unread messages from tasks")
checked: plasmoid.configuration.showInfoBadge
tooltip: i18n("Show unread messages or notifications from tasks")
onClicked: {
plasmoid.configuration.showInfoBadge = checked
}
}
LatteComponents.CheckBox {
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Progress information for tasks")
checked: plasmoid.configuration.showProgressBadge
tooltip: i18n("Show a progress animation for tasks e.g. when copying files with Dolphin")
onClicked: {
plasmoid.configuration.showProgressBadge = checked
}
}
LatteComponents.CheckBox {
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Audio playing from tasks")
checked: plasmoid.configuration.showAudioBadge
tooltip: i18n("Show audio playing from tasks")
onClicked: {
plasmoid.configuration.showAudioBadge = checked
}
}
LatteComponents.CheckBox {
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Change volume when scrolling audio badge")
checked: plasmoid.configuration.audioBadgeActionsEnabled
enabled: plasmoid.configuration.showAudioBadge
tooltip: i18n("The user is able to mute/unmute with click or change the volume with mouse wheel")
onClicked: {
plasmoid.configuration.audioBadgeActionsEnabled = checked
}
}
}
}
//! END: Badges
//! BEGIN: Tasks Interaction
ColumnLayout {
Layout.topMargin: dialog.basicLevel ? units.smallSpacing : 0
spacing: units.smallSpacing
LatteComponents.Header {
text: i18n("Interaction")
}
LatteComponents.CheckBoxesColumn {
Layout.leftMargin: units.smallSpacing * 2
Layout.rightMargin: units.smallSpacing * 2
LatteComponents.CheckBox {
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Add launchers only in the Tasks Area")
checked: plasmoid.configuration.addLaunchersInTaskManager
tooltip: i18n("Launchers are added only in the taskmanager and not as plasma applets")
onClicked: {
plasmoid.configuration.addLaunchersInTaskManager = checked;
}
}
- LatteComponents.CheckBox {
- Layout.maximumWidth: dialog.optionsWidth
- text: i18n("Support scrolling when items overflow")
- checked: plasmoid.configuration.scrollingTasksEnabled
- tooltip: i18n("When items overflow the user is able to scroll between them.\nTake note that automatic icon decrease mechanism will be disabled.")
- visible: dialog.highLevel
-
- onClicked: {
- plasmoid.configuration.scrollingTasksEnabled = !plasmoid.configuration.scrollingTasksEnabled;
- }
- }
-
LatteComponents.CheckBox {
id: windowActionsChk
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Window actions in the context menu")
checked: plasmoid.configuration.showWindowActions
visible: dialog.highLevel
enabled: !disableAllWindowsFunctionality
onClicked: {
plasmoid.configuration.showWindowActions = checked
}
}
LatteComponents.CheckBox {
id: unifyGlobalShortcutsChk
Layout.maximumWidth: dialog.optionsWidth
text: i18n("🅰 Based on position shortcuts apply only for tasks")
checked: !plasmoid.configuration.unifiedGlobalShortcuts
tooltip: i18n("Based on position global shortcuts are enabled only for tasks and not for applets")
visible: dialog.highLevel
enabled: latteView.isPreferredForShortcuts || (!latteView.layout.preferredForShortcutsTouched && latteView.isHighestPriorityView())
onClicked: {
plasmoid.configuration.unifiedGlobalShortcuts = !checked
}
}
}
}
//! END: Tasks Interaction
//! BEGIN: Tasks Filters
ColumnLayout {
spacing: units.smallSpacing
LatteComponents.Header {
text: i18n("Filters")
}
LatteComponents.CheckBoxesColumn {
Layout.leftMargin: units.smallSpacing * 2
Layout.rightMargin: units.smallSpacing * 2
LatteComponents.CheckBox {
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Show only tasks from the current screen")
checked: plasmoid.configuration.showOnlyCurrentScreen
onClicked: {
plasmoid.configuration.showOnlyCurrentScreen = checked
}
}
LatteComponents.CheckBox {
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Show only tasks from the current desktop")
checked: plasmoid.configuration.showOnlyCurrentDesktop
onClicked: {
plasmoid.configuration.showOnlyCurrentDesktop = checked
}
}
LatteComponents.CheckBox {
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Show only tasks from the current activity")
checked: plasmoid.configuration.showOnlyCurrentActivity
onClicked: {
plasmoid.configuration.showOnlyCurrentActivity = checked
}
}
LatteComponents.CheckBox {
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Show only tasks from launchers")
checked: plasmoid.configuration.showWindowsOnlyFromLaunchers
visible: dialog.highLevel
onClicked: {
plasmoid.configuration.showWindowsOnlyFromLaunchers = checked
}
}
LatteComponents.CheckBox {
Layout.maximumWidth: dialog.optionsWidth
text: i18n("Group tasks of the same application")
checked: plasmoid.configuration.groupTasksByDefault
tooltip: i18n("By default group tasks of the same application")
visible: dialog.highLevel
onClicked: {
plasmoid.configuration.groupTasksByDefault = checked
}
}
}
}
//! END: Tasks Filters
//! BEGIN: Launchers Group
ColumnLayout {
spacing: units.smallSpacing
LatteComponents.Header {
text: i18n("Launchers")
}
ColumnLayout {
Layout.leftMargin: units.smallSpacing * 2
Layout.rightMargin: units.smallSpacing * 2
spacing: 0
LatteComponents.SubHeader {
isFirstSubCategory: true
text: i18nc("launchers group", "Group");
}
RowLayout {
Layout.fillWidth: true
spacing: 2
property int group: plasmoid.configuration.launchersGroup
readonly property int buttonsCount: layoutGroupButton.visible ? 3 : 2
readonly property int buttonSize: (dialog.optionsWidth - (spacing * buttonsCount-1)) / buttonsCount
ExclusiveGroup {
id: launchersGroup
onCurrentChanged: {
if (current.checked) {
viewConfig.updateLaunchersForGroup(current.group);
plasmoid.configuration.launchersGroup = current.group;
}
}
}
PlasmaComponents.Button {
Layout.minimumWidth: parent.buttonSize
Layout.maximumWidth: Layout.minimumWidth
text: i18nc("unique launchers group","Unique")
checked: parent.group === group
checkable: true
exclusiveGroup: launchersGroup
tooltip: i18n("Use a unique set of launchers for this view which is independent from any other view")
readonly property int group: Latte.Types.UniqueLaunchers
}
PlasmaComponents.Button {
id: layoutGroupButton
Layout.minimumWidth: parent.buttonSize
Layout.maximumWidth: Layout.minimumWidth
text: i18nc("layout launchers group","Layout")
checked: parent.group === group
checkable: true
exclusiveGroup: launchersGroup
tooltip: i18n("Use the current layout set of launchers for this latteView. This group provides launchers synchronization between different views in the same layout")
//! it is shown only when the user has activated that option manually from the text layout file
visible: plasmoid.configuration.launchersGroup === group
readonly property int group: Latte.Types.LayoutLaunchers
}
PlasmaComponents.Button {
Layout.minimumWidth: parent.buttonSize
Layout.maximumWidth: Layout.minimumWidth
text: i18nc("global launchers group","Global")
checked: parent.group === group
checkable: true
exclusiveGroup: launchersGroup
tooltip: i18n("Use the global set of launchers for this latteView. This group provides launchers synchronization between different views and between different layouts")
readonly property int group: Latte.Types.GlobalLaunchers
}
}
}
}
//! END: Launchers Group
+ //! BEGIN: Scrolling
+ ColumnLayout {
+ spacing: units.smallSpacing
+ visible: dialog.expertLevel
+
+ LatteComponents.HeaderSwitch {
+ id: scrollingHeader
+ Layout.minimumWidth: dialog.optionsWidth + 2 *units.smallSpacing
+ Layout.maximumWidth: Layout.minimumWidth
+ Layout.minimumHeight: implicitHeight
+ Layout.bottomMargin: units.smallSpacing
+ enabled: Latte.WindowSystem.compositingActive
+
+ checked: plasmoid.configuration.scrollTasksEnabled
+ text: i18n("Scrolling")
+ tooltip: i18n("Enable tasks scrolling when they overflow and exceed the available space");
+
+ onPressed: {
+ plasmoid.configuration.scrollTasksEnabled = !plasmoid.configuration.scrollTasksEnabled;;
+ }
+ }
+
+ ColumnLayout {
+ Layout.leftMargin: units.smallSpacing * 2
+ Layout.rightMargin: units.smallSpacing * 2
+ spacing: 0
+ enabled: scrollingHeader.checked
+
+ GridLayout {
+ columns: 2
+ Layout.minimumWidth: dialog.optionsWidth
+ Layout.maximumWidth: Layout.minimumWidth
+
+ Layout.topMargin: units.smallSpacing
+
+ PlasmaComponents.Label {
+ Layout.fillWidth: true
+ text: i18n("Manual")
+ }
+
+ LatteComponents.ComboBox {
+ id: manualScrolling
+ Layout.minimumWidth: leftClickAction.width
+ Layout.maximumWidth: leftClickAction.width
+ model: [i18nc("disabled manual scrolling", "Disabled scrolling"),
+ dialog.panelIsVertical ? i18n("Only vertical scrolling") : i18n("Only horizontal scrolling"),
+ i18n("Horizonal and vertical scrolling")]
+
+ currentIndex: plasmoid.configuration.manualScrollTasksType
+ onCurrentIndexChanged: plasmoid.configuration.manualScrollTasksType = currentIndex;
+ }
+
+ PlasmaComponents.Label {
+ id: autoScrollText
+ Layout.fillWidth: true
+ text: i18n("Automatic")
+ }
+
+ LatteComponents.ComboBox {
+ id: autoScrolling
+ Layout.minimumWidth: leftClickAction.width
+ Layout.maximumWidth: leftClickAction.width
+ model: [
+ i18n("Disabled"),
+ i18n("Enabled")
+ ]
+
+ currentIndex: plasmoid.configuration.autoScrollTasksEnabled
+ onCurrentIndexChanged: {
+ if (currentIndex === 0) {
+ plasmoid.configuration.autoScrollTasksEnabled = false;
+ } else {
+ plasmoid.configuration.autoScrollTasksEnabled = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ //! END: Scolling
+
+
//! BEGIN: Actions
ColumnLayout {
spacing: units.smallSpacing
visible: dialog.expertLevel
LatteComponents.Header {
text: i18n("Actions")
}
ColumnLayout {
Layout.leftMargin: units.smallSpacing * 2
Layout.rightMargin: units.smallSpacing * 2
spacing: 0
GridLayout {
columns: 2
Layout.minimumWidth: dialog.optionsWidth
Layout.maximumWidth: Layout.minimumWidth
Layout.topMargin: units.smallSpacing
enabled: !disableAllWindowsFunctionality
PlasmaComponents.Label {
+ id: leftClickLbl
text: i18n("Left Click")
}
LatteComponents.ComboBox {
id: leftClickAction
Layout.fillWidth: true
model: [i18nc("present windows action", "Present Windows"),
i18n("Cycle Through Tasks"),
i18n("Preview Windows")]
currentIndex: {
switch(plasmoid.configuration.leftClickAction) {
case Latte.Types.PresentWindows:
return 0;
case Latte.Types.CycleThroughTasks:
return 1;
case Latte.Types.PreviewWindows:
return 2;
}
return 0;
}
onCurrentIndexChanged: {
switch(currentIndex) {
case 0:
plasmoid.configuration.leftClickAction = Latte.Types.PresentWindows;
break;
case 1:
plasmoid.configuration.leftClickAction = Latte.Types.CycleThroughTasks;
break;
case 2:
plasmoid.configuration.leftClickAction = Latte.Types.PreviewWindows;
break;
}
}
}
PlasmaComponents.Label {
id: middleClickText
text: i18n("Middle Click")
}
LatteComponents.ComboBox {
id: middleClickAction
Layout.fillWidth: true
model: [
i18nc("The click action", "None"),
i18n("Close Window or Group"),
i18n("New Instance"),
i18n("Minimize/Restore Window or Group"),
i18n("Cycle Through Tasks"),
i18n("Toggle Task Grouping")
]
currentIndex: plasmoid.configuration.middleClickAction
onCurrentIndexChanged: plasmoid.configuration.middleClickAction = currentIndex
}
PlasmaComponents.Label {
text: i18n("Hover")
}
LatteComponents.ComboBox {
id: hoverAction
Layout.fillWidth: true
model: [
i18nc("none action", "None"),
i18n("Preview Windows"),
i18n("Highlight Windows"),
i18n("Preview and Highlight Windows"),
]
currentIndex: {
switch(plasmoid.configuration.hoverAction) {
case Latte.Types.NoneAction:
return 0;
case Latte.Types.PreviewWindows:
return 1;
case Latte.Types.HighlightWindows:
return 2;
case Latte.Types.PreviewAndHighlightWindows:
return 3;
}
return 0;
}
onCurrentIndexChanged: {
switch(currentIndex) {
case 0:
plasmoid.configuration.hoverAction = Latte.Types.NoneAction;
break;
case 1:
plasmoid.configuration.hoverAction = Latte.Types.PreviewWindows;
break;
case 2:
plasmoid.configuration.hoverAction = Latte.Types.HighlightWindows;
break;
case 3:
plasmoid.configuration.hoverAction = Latte.Types.PreviewAndHighlightWindows;
break;
}
}
}
RowLayout {
spacing: units.smallSpacing
enabled: !disableAllWindowsFunctionality
Layout.minimumWidth: middleClickText.width
Layout.maximumWidth: middleClickText.width
LatteComponents.ComboBox {
id: modifier
Layout.fillWidth: true
model: ["Shift", "Ctrl", "Alt", "Meta"]
currentIndex: plasmoid.configuration.modifier
onCurrentIndexChanged: plasmoid.configuration.modifier = currentIndex
}
PlasmaComponents.Label {
text: "+"
}
}
RowLayout {
spacing: units.smallSpacing
enabled: !disableAllWindowsFunctionality
readonly property int maxSize: 0.4 * dialog.optionsWidth
LatteComponents.ComboBox {
id: modifierClick
Layout.preferredWidth: 0.7 * parent.maxSize
Layout.maximumWidth: parent.maxSize
model: [i18n("Left Click"), i18n("Middle Click"), i18n("Right Click")]
currentIndex: plasmoid.configuration.modifierClick
onCurrentIndexChanged: plasmoid.configuration.modifierClick = currentIndex
}
PlasmaComponents.Label {
text: "="
}
LatteComponents.ComboBox {
id: modifierClickAction
Layout.fillWidth: true
model: [i18nc("The click action", "None"), i18n("Close Window or Group"),
i18n("New Instance"), i18n("Minimize/Restore Window or Group"), i18n("Cycle Through Tasks"), i18n("Toggle Task Grouping")]
currentIndex: plasmoid.configuration.modifierClickAction
onCurrentIndexChanged: plasmoid.configuration.modifierClickAction = currentIndex
}
}
}
RowLayout {
Layout.minimumWidth: dialog.optionsWidth
Layout.maximumWidth: Layout.minimumWidth
Layout.topMargin: units.smallSpacing
spacing: units.smallSpacing
enabled: !disableAllWindowsFunctionality
}
}
}
//! END: Actions
//! BEGIN: Recycling
ColumnLayout {
spacing: units.smallSpacing
visible: dialog.expertLevel
LatteComponents.Header {
text: i18n("Recycling")
}
PlasmaComponents.Button {
Layout.minimumWidth: dialog.optionsWidth
Layout.maximumWidth: Layout.minimumWidth
Layout.leftMargin: units.smallSpacing * 2
Layout.rightMargin: units.smallSpacing * 2
Layout.topMargin: units.smallSpacing
text: i18n("Remove Latte Tasks Applet")
enabled: latteView.latteTasksArePresent
tooltip: i18n("Remove Latte Tasks plasmoid")
onClicked: {
latteView.removeTasksPlasmoid();
}
}
}
//! Bottom spacer
PlasmaComponents.Label{
id: bottomMarginSpacer
text:" "
}
}
}