aerothemeplasma/Plasma/Plasma Widgets/User/Task Icons/org.kde.plasma.seventasks/contents/ui/Task.qml
wackyideas 165fa81da4 Fixes incorrect behaviour when using SevenTasks while it is configured to sort tasks manually.
Expected behaviour:

1. Dragging pinned tasks around should update their position correctly and keep that position permanently
2. Dragging items that are NOT tasks should focus the task that is being hovered over for easier drag and drop functionality

Actual behaviour:

1. Dragging pinned tasks around seemingly works, until the task manager is updated in any kind of way, at which point the positions are reverted back to the original state.
2. Dragging items that aren't tasks will only focus the hovered task if previous dragging actions didn't occur between two or more tasks. After that, trying to drag items onto the taskbar will cause the task that was dragged last time to move around according to the mouse's position.
2022-09-12 20:37:06 +02:00

976 lines
37 KiB
QML

/*
SPDX-FileCopyrightText: 2012-2013 Eike Hein <hein@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.draganddrop 2.0
import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet
import "code/layout.js" as LayoutManager
import "code/tools.js" as TaskTools
import QtGraphicalEffects 1.15
MouseArea {
id: task
width: groupDialog.contentWidth
height: Math.max(theme.mSize(theme.defaultFont).height, PlasmaCore.Units.iconSizes.medium) + LayoutManager.verticalMargins()
visible: true
hoverEnabled: true
preventStealing: true
propagateComposedEvents: true
z: 2
LayoutMirroring.enabled: (Qt.application.layoutDirection == Qt.RightToLeft)
LayoutMirroring.childrenInherit: (Qt.application.layoutDirection == Qt.RightToLeft)
readonly property var m: model
readonly property int pid: model.AppPid !== undefined ? model.AppPid : 0
readonly property string appName: model.AppName
readonly property variant winIdList: model.WinIdList
property int itemIndex: index
property bool inPopup: false
property bool isWindow: model.IsWindow === true
property int childCount: model.ChildCount !== undefined ? model.ChildCount : 0
property int previousChildCount: 0
property alias labelText: label.text
property bool pressed: false
property int pressX: -1
property int pressY: -1
property QtObject contextMenu: null
property int wheelDelta: 0
readonly property bool smartLauncherEnabled: !inPopup && model.IsStartup !== true
property QtObject smartLauncherItem: null
property alias toolTipAreaItem: toolTipArea
property alias audioStreamIconLoaderItem: audioStreamIconLoader
property color hoverColor
property real taskWidth: 0
property real taskHeight: 0
property string previousState: ""
property Item audioStreamOverlay
property var audioStreams: []
property bool delayAudioStreamIndicator: false
readonly property bool audioIndicatorsEnabled: plasmoid.configuration.indicateAudioStreams
readonly property bool hasAudioStream: audioStreams.length > 0
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 bool highlighted: (inPopup && activeFocus) || (!inPopup && containsMouse)
|| (task.contextMenu && task.contextMenu.status === PlasmaComponents.DialogStatus.Open)
|| (groupDialog.visible && groupDialog.visualParent === task)
onHighlightedChanged: {
// ensure it doesn't get stuck with a window highlighted
backend.cancelHighlightWindows();
}
function closeTask() {
closingAnimation.start();
}
function showToolTip() {
toolTipArea.showToolTip();
}
function hideToolTipTemporarily() {
toolTipArea.hideToolTip();
}
function updateHoverColor() {
hoverColor = plasmoid.nativeInterface.getDominantColor(icon.source);
hoverGradient.verticalRadius = LayoutManager.taskHeight();
hoverGradient.horizontalRadius = LayoutManager.taskWidth();
}
function updateMousePosition(pos) {
//console.log(frame.width), console.log(frame.height);
if(!model.IsStartup)
hoverGradient.horizontalOffset = pos - hoverRect.width/2;
}
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MidButton | Qt.BackButton | Qt.ForwardButton
onPidChanged: updateAudioStreams({delay: false})
onAppNameChanged: updateAudioStreams({delay: false})
onIsWindowChanged: {
if (isWindow) {
taskInitComponent.createObject(task);
}
hoverEnabled = true;
}
onChildCountChanged: {
if (!childCount && groupDialog.visualParent == task) {
groupDialog.visible = false;
return;
}
if (containsMouse) {
groupDialog.activeTask = null;
}
if (childCount > previousChildCount) {
tasksModel.requestPublishDelegateGeometry(modelIndex(), backend.globalRect(task), task);
}
previousChildCount = childCount;
hoverEnabled = true;
}
onItemIndexChanged: {
hideToolTipTemporarily();
if (!inPopup && !tasks.vertical
&& (LayoutManager.calculateStripes() > 1 || !plasmoid.configuration.separateLaunchers)) {
tasks.requestLayout();
}
hoverEnabled = true;
taskList.updateHoverFunc();
}
onContainsMouseChanged: {
updateMousePosition(ma.mouseX);
if(taskList.firstTimeHover === false) {
taskList.updateHoverFunc();
taskList.firstTimeHover = true;
}
if (containsMouse) {
if (inPopup) {
forceActiveFocus();
}
} else {
pressed = false;
//if(!ma.pressed) tasks.dragSource = null;
}
hoverEnabled = true;
}
onPressed: {
if (mouse.button == Qt.LeftButton || mouse.button == Qt.MidButton || mouse.button === Qt.BackButton || mouse.button === Qt.ForwardButton) {
pressed = true;
pressX = mouse.x;
pressY = mouse.y;
} else if (mouse.button == Qt.RightButton) {
// 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) {
showContextMenu({showAllPlaces: true})
} else {
showContextMenu();
}
}
hoverEnabled = true;
}
onReleased: {
if (pressed) {
if (mouse.button == Qt.MidButton) {
if (plasmoid.configuration.middleClickAction === TaskManagerApplet.Backend.NewInstance) {
hoverRect.state = "startup";
tasksModel.requestNewInstance(modelIndex());
} else if (plasmoid.configuration.middleClickAction === TaskManagerApplet.Backend.Close) {
tasks.taskClosedWithMouseMiddleButton = winIdList.slice()
tasksModel.requestClose(modelIndex());
} else if (plasmoid.configuration.middleClickAction === TaskManagerApplet.Backend.ToggleMinimized) {
tasksModel.requestToggleMinimized(modelIndex());
} else if (plasmoid.configuration.middleClickAction === TaskManagerApplet.Backend.ToggleGrouping) {
tasksModel.requestToggleGrouping(modelIndex());
} else if (plasmoid.configuration.middleClickAction === TaskManagerApplet.Backend.BringToCurrentDesktop) {
tasksModel.requestVirtualDesktops(modelIndex(), [virtualDesktopInfo.currentDesktop]);
}
} else if (mouse.button == Qt.LeftButton) {
if (plasmoid.configuration.showToolTips && toolTipArea.active) {
hideToolTipTemporarily();
}
TaskTools.activateTask(modelIndex(), model, mouse.modifiers, task);
} else if (mouse.button === Qt.BackButton || mouse.button === Qt.ForwardButton) {
var sourceName = mpris2Source.sourceNameForLauncherUrl(model.LauncherUrlWithoutIcon, model.AppPid);
if (sourceName) {
if (mouse.button === Qt.BackButton) {
mpris2Source.goPrevious(sourceName);
} else {
mpris2Source.goNext(sourceName);
}
} else {
mouse.accepted = false;
}
}
backend.cancelHighlightWindows();
}
pressed = false;
pressX = -1;
pressY = -1;
hoverEnabled = true;
}
onPressAndHold: {
}
onPositionChanged: { //hoverEnabled: true, but this event still doesn't fire at all
//unless i am pressing the left mouse button for a short period of time
if (pressX != -1 && mouse.buttons == Qt.LeftButton && dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) {
tasks.dragSource = task;
dragHelper.startDrag(task, model.MimeType, model.MimeData,
model.LauncherUrlWithoutIcon, model.decoration);
pressX = -1;
pressY = -1;
return;
}
else
{
tasks.dragSource = null;
}
//code for dragging the task around
}
onWheel: {
if (plasmoid.configuration.wheelEnabled && (!inPopup || !groupDialog.overflowing)) {
wheelDelta = TaskTools.wheelActivateNextPrevTask(task, wheelDelta, wheel.angleDelta.y);
} else {
wheel.accepted = false;
}
}
onSmartLauncherEnabledChanged: {
if (smartLauncherEnabled && !smartLauncherItem) {
var smartLauncher = Qt.createQmlObject("
import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet;
TaskManagerApplet.SmartLauncherItem { }", task);
smartLauncher.launcherUrl = Qt.binding(function() { return model.LauncherUrlWithoutIcon; });
smartLauncherItem = smartLauncher;
}
}
onHasAudioStreamChanged: {
audioStreamIconLoader.active = hasAudioStream && audioIndicatorsEnabled;
}
onAudioIndicatorsEnabledChanged: {
audioStreamIconLoader.active = hasAudioStream && audioIndicatorsEnabled;
}
Keys.onReturnPressed: TaskTools.activateTask(modelIndex(), model, event.modifiers, task)
Keys.onEnterPressed: Keys.onReturnPressed(event);
function modelIndex() {
return (inPopup ? tasksModel.makeModelIndex(groupDialog.visualParent.itemIndex, index)
: tasksModel.makeModelIndex(index));
}
function showContextMenu(args) {
toolTipArea.hideImmediately();
contextMenu = tasks.createContextMenu(task, modelIndex(), args);
contextMenu.show();
}
function updateAudioStreams(args) {
if (args) {
// When the task just appeared (e.g. virtual desktop switch), show the audio indicator
// right away. Only when audio streams change during the lifetime of this task, delay
// showing that to avoid distraction.
delayAudioStreamIndicator = !!args.delay;
}
var pa = pulseAudio.item;
if (!pa) {
task.audioStreams = [];
return;
}
var streams = pa.streamsForPid(task.pid);
if (streams.length) {
pa.registerPidMatch(task.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(task.appName)) {
streams = pa.streamsForAppName(task.appName);
}
}
task.audioStreams = streams;
}
function toggleMuted() {
if (muted) {
task.audioStreams.forEach(function (item) { item.unmute(); });
} else {
task.audioStreams.forEach(function (item) { item.mute(); });
}
}
Connections {
target: pulseAudio.item
ignoreUnknownSignals: true // Plasma-PA might not be available
function onStreamsChanged() {
task.updateAudioStreams({delay: true})
}
}
Component {
id: taskInitComponent
Timer {
id: timer
interval: PlasmaCore.Units.longDuration
repeat: false
onTriggered: {
//parent.hoverEnabled = true;
if (parent.isWindow) {
tasksModel.requestPublishDelegateGeometry(parent.modelIndex(),
backend.globalRect(parent), parent);
}
timer.destroy();
}
Component.onCompleted: {
taskList.updateHoverFunc();
timer.start();
}
}
}
NumberAnimation {
id: closingAnimation
target: frame
properties: "opacity"
from: 1
to: 0
duration: 200
onRunningChanged: { if(!closingAnimation.running) {
opacity: 1;
//tasksModel.requestClose(modelIndex());
}
}
}
PlasmaCore.FrameSvgItem {
id: frame
z: -1
anchors {
fill: parent
topMargin: (!tasks.vertical && taskList.rows > 1) ? PlasmaCore.Units.smallSpacing / 4 : 0
bottomMargin: (!tasks.vertical && taskList.rows > 1) ? PlasmaCore.Units.smallSpacing / 4 : 0
leftMargin: ((inPopup || tasks.vertical) && taskList.columns > 1) ? PlasmaCore.Units.smallSpacing / 4 : PlasmaCore.Units.smallSpacing / 4
rightMargin: ((inPopup || tasks.vertical) && taskList.columns > 1) ? PlasmaCore.Units.smallSpacing / 4 : PlasmaCore.Units.smallSpacing / 4
}
PlasmaCore.FrameSvgItem {
id: stackFirst
z: 2
imagePath: "widgets/tasks"
anchors.fill: parent
visible: frame.basePrefix != "active-tab"
opacity: {
if(childCount == 0) return 1;
else if(childCount == 2) return 0.6;
else return 0.25;
}
//imagePath: (frame.isHovered && frame.basePrefix === "active-tab") ? "widgets/tabbar" : "widgets/tasks"
prefix: childCount == 0 ? frame.prefix : TaskTools.taskPrefix("stacked+" + ((pressed) ? "focus" : frame.basePrefix));
}
PlasmaCore.FrameSvgItem {
id: stackSecond
imagePath: "widgets/tasks"
prefix: frame.prefix
anchors.fill: parent
opacity: 1
visible: childCount >= 2 ? true : false
anchors.rightMargin: PlasmaCore.Units.smallSpacing * (childCount >= 3 ? 2 : 1.2);
}
PlasmaCore.FrameSvgItem {
id: stackThird
imagePath: "widgets/tasks"
prefix: TaskTools.taskPrefix("stacked+" + ((pressed) ? "focus" : frame.basePrefix))
anchors.fill: parent
opacity: 0.6
visible: childCount >= 3 ? true : false
anchors.rightMargin: PlasmaCore.Units.smallSpacing
enabledBorders: Plasma.FrameSvg.EnabledBorders.RightBorder
}
LinearGradient {
id: highlightGradient
opacity: (pressed && frame.isHovered && frame.basePrefix === "active-tab") ? 1 : 0
anchors.fill: parent
anchors.leftMargin: 3
anchors.rightMargin: 3
anchors.topMargin: 2
start: Qt.point(3, 3)
end: Qt.point(3, parent.height-3)
gradient: Gradient {
GradientStop { position: 0.0; color: "#00000000"; }
GradientStop { position: 0.5; color: "#66000000"; }
GradientStop { position: 1.0; color: "#00000000"; }
}
}
imagePath: (frame.isHovered && frame.basePrefix === "active-tab") ? "widgets/tabbar" : ""//"widgets/tasks"
property bool isHovered: task.highlighted && plasmoid.configuration.taskHoverEffect
property string basePrefix: "normal"
//prefix: isHovered ? (TaskTools.taskPrefixHovered(basePrefix)) : TaskTools.taskPrefix(basePrefix)
//prefix: TaskTools.taskPrefix(basePrefix)
prefix: {
if(pressed && frame.basePrefix != "active-tab") return TaskTools.taskPrefix("focus");
else if(isHovered && (basePrefix === "normal" || basePrefix === "minimized")) { return TaskTools.taskPrefix("hover"); }
else return TaskTools.taskPrefix(basePrefix);
}
//prefix: ((pressed) && frame.basePrefix != "active-tab") ? TaskTools.taskPrefix("focus") : TaskTools.taskPrefix(basePrefix)
Rectangle {
id: hoverRect
anchors {
fill: parent
topMargin: (!tasks.vertical && taskList.rows > 1) ? PlasmaCore.Units.smallSpacing / 4 +1 : 1
bottomMargin: (!tasks.vertical && taskList.rows > 1) ? PlasmaCore.Units.smallSpacing / 4+1 : 1
leftMargin: ((inPopup || tasks.vertical) && taskList.columns > 1) ? PlasmaCore.Units.smallSpacing / 4+1 : 1
rightMargin: ((inPopup || tasks.vertical) && taskList.columns > 1) ? PlasmaCore.Units.smallSpacing / 4+1 : 1
}
z: -5
clip: true
states: [
State {
name: "startup"; when: (model.IsStartup === true)
PropertyChanges { target: hoverRect; opacity: 1}
StateChangeScript {
script: {
if(previousState === "startup") {
hoverGradient.verticalRadius = LayoutManager.taskHeight();
hoverGradient.horizontalRadius = LayoutManager.taskWidth();
}
previousState = "startup";
//console.log("\nTurned to startup state\n" + previousState);
}
}
},
State {
name: "startup-finished"; when: (model.IsStartup === false)
PropertyChanges { target: hoverRect; opacity: 1}
StateChangeScript {
script: {
if(previousState === "startup") {
hoverGradient.verticalRadius = LayoutManager.taskHeight();
hoverGradient.horizontalRadius = LayoutManager.taskWidth();
}
previousState = "startup";
}
}
},
State {
name: "mouse-over"; when: ((frame.isHovered && frame.basePrefix != "active-tab"))
PropertyChanges { target: hoverRect; opacity: 1}
StateChangeScript {
script: {
if(previousState === "startup") {
hoverGradient.verticalRadius = LayoutManager.taskHeight();
hoverGradient.horizontalRadius = LayoutManager.taskWidth();
}
previousState = "mouse-over";
//console.log("\nTurned to mouseover state\n" + previousState);
}
}
},
State {
name: "";
PropertyChanges { target: hoverRect; opacity: 0 }
StateChangeScript {
script: {
if(previousState === "startup") {
hoverGradient.verticalRadius = LayoutManager.taskHeight();
hoverGradient.horizontalRadius = LayoutManager.taskWidth();
}
previousState = "";
//console.log("\nTurned to default state\n" + previousState);
}
}
}
]
transitions: [ Transition {
from: "*"; to: "*";
NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad; duration: 250 }
},
Transition {
from: "*"; to: "startup";
NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad; duration: 250 }
SequentialAnimation {
id: horizRad
NumberAnimation {
id: horizRad1
target: hoverGradient
property: "horizontalRadius"
from: 0; to: LayoutManager.taskWidth();//task.height + taskFrame.margins.left + taskFrame.margins.right;
easing.type: Easing.OutQuad; duration: 400
}
/*NumberAnimation {
id: horizRad11
target: hoverGradient
property: "horizontalRadius"
from: LayoutManager.taskWidth(); to: LayoutManager.taskWidth();//task.height + taskFrame.margins.left + taskFrame.margins.right;
easing.type: Easing.Linear; duration:
}*/
NumberAnimation {
id: horizRad2
target: hoverGradient
property: "horizontalRadius"
//to: 0;
from: LayoutManager.taskWidth()/*task.height + taskFrame.margins.left + taskFrame.margins.right*/; to: 0;
easing.type: Easing.InQuad; duration: 550
}
NumberAnimation {
id: horizRad3
target: hoverGradient
property: "horizontalRadius"
//to: 0;
from: 0; to: 0; //LayoutManager.taskWidth()/*task.height + taskFrame.margins.left + taskFrame.margins.right*/; to: 0;
easing.type: Easing.Linear; duration: 3600
}
NumberAnimation {
id: frameOpacity
target: task
property: "opacity"
from: 1; to: 0;
easing.type: Easing.OutCubic; duration: 650
}
//loops: 3
}
SequentialAnimation {
id: vertiRad
NumberAnimation {
id: vertiRad1
target: hoverGradient
property: "verticalRadius"
from: 0; to: LayoutManager.taskHeight();
easing.type: Easing.OutQuad; duration: 400
}
/*NumberAnimation {
id: vertiRad11
target: hoverGradient
property: "verticalRadius"
from: LayoutManager.taskHeight(); to: LayoutManager.taskHeight();
easing.type: Easing.Linear; duration: 50
}*/
NumberAnimation {
id: vertiRad2
target: hoverGradient
property: "verticalRadius"
from: LayoutManager.taskHeight(); to: 0;
easing.type: Easing.InQuad; duration: 550
}
NumberAnimation {
id: vertiRad3
target: hoverGradient
property: "verticalRadius"
from: 0; to: 0;
easing.type: Easing.Linear; duration: 1250
}
NumberAnimation {
id: hoverBorder
target: hoverRect
property: "opacity"
from: 1; to: 0;
easing.type: Easing.Linear; duration: 550
}
//loops: 3
}
} ]
opacity: 0//(frame.isHovered && frame.basePrefix != "") ? 1.0 : 0
color: "#00000000"
Rectangle {
id: borderRect
anchors {
fill: parent
topMargin: (!tasks.vertical && taskList.rows > 1) ? PlasmaCore.Units.smallSpacing / 4 : 0
bottomMargin: (!tasks.vertical && taskList.rows > 1) ? PlasmaCore.Units.smallSpacing / 4 : 0
leftMargin: ((inPopup || tasks.vertical) && taskList.columns > 1) ? PlasmaCore.Units.smallSpacing / 4 : 0
rightMargin: ((inPopup || tasks.vertical) && taskList.columns > 1) ? PlasmaCore.Units.smallSpacing / 4 : 0
}
z: -5
border.color: Qt.rgba(hoverColor.r, hoverColor.g, hoverColor.b, 0.4);
//border.color: Qt.tint(hoverColor, "#22777777")
border.width: 2
radius: 2
color: "#00000000"
}
RadialGradient {
id: hoverGradient
z: -3
anchors {
fill: parent
topMargin: -2 * PlasmaCore.Units.smallSpacing
leftMargin: -2 * PlasmaCore.Units.smallSpacing
bottomMargin: -2 * PlasmaCore.Units.smallSpacing
rightMargin: -2 * PlasmaCore.Units.smallSpacing
/*topMargin: (!tasks.vertical && taskList.rows > 1) ? -PlasmaCore.Units.smallSpacing / 4 : 0
bottomMargin: (!tasks.vertical && taskList.rows > 1) ? -PlasmaCore.Units.smallSpacing / 4 : 0
leftMargin: ((inPopup || tasks.vertical) && taskList.columns > 1) ? PlasmaCore.Units.smallSpacing / 4 : 0
rightMargin: ((inPopup || tasks.vertical) && taskList.columns > 1) ? -PlasmaCore.Units.smallSpacing / 4 : 0*/
}
gradient: Gradient {
id: radialGrad
GradientStop { position: 0.0; color: Qt.tint(hoverColor, "#CFF8F8F8") }
GradientStop { position: 0.4; color: Qt.rgba(hoverColor.r, hoverColor.g, hoverColor.b, 0.75) }
//GradientStop { position: 0.4; color: Qt.tint(hoverColor, "#55AAAAAA") }
GradientStop { position: 0.85; color: Qt.rgba(hoverColor.r, hoverColor.g, hoverColor.b, 0.2) }
}
verticalOffset: hoverRect.height/2.2
horizontalOffset: 0
//hoverGradient.horizontalOffset = task.mouseX - hoverRect.width/2
}
Blend {
anchors.fill: borderRect
source: borderRect
foregroundSource: hoverGradient
mode: "addition"
}
//z: -1
}
PlasmaCore.ToolTipArea {
id: toolTipArea
z: -1
//backgroundHints: "SolidBackground"
MouseArea {
id: ma
hoverEnabled: true
propagateComposedEvents: true
anchors.fill: parent
onPositionChanged: {
task.updateMousePosition(ma.mouseX);
task.positionChanged(mouse);
//var xtr = toolTipArea.backgroundHints();
}
onContainsMouseChanged: {
task.updateMousePosition(ma.mouseX);
//task.onContainsMouseChanged();
//toolTipArea.onContainsMouseChanged();
//mouse.accepted = false;
}
onPressed: mouse.accepted = false;
onReleased: mouse.accepted = false;
onWheel: wheel.accepted = false;
//onExited: { hoverGradient.horizontalOffset = 0;
//task.onExited();
//}
}
anchors.fill: parent
location: plasmoid.location
active: !inPopup && !groupDialog.visible && plasmoid.configuration.showToolTips
interactive: model.IsWindow === true
mainItem: (model.IsWindow === true) ? openWindowToolTipDelegate : pinnedAppToolTipDelegate
property alias mainToolTip: toolTipArea.mainItem
onContainsMouseChanged: {
if (containsMouse) {
mainItem.parentTask = task;
mainItem.rootIndex = tasksModel.makeModelIndex(itemIndex, -1);
/*mainItem.isWindowActive = Qt.binding(function() {
return false;
});*/
mainItem.appName = Qt.binding(function() {
return model.AppName;
});
mainItem.pidParent = Qt.binding(function() {
return model.AppPid !== undefined ? model.AppPid : 0;
});
mainItem.windows = Qt.binding(function() {
return model.WinIdList;
});
mainItem.isGroup = Qt.binding(function() {
return model.IsGroupParent === true;
});
mainItem.icon = Qt.binding(function() {
return model.decoration;
});
mainItem.launcherUrl = Qt.binding(function() {
return model.LauncherUrlWithoutIcon;
});
mainItem.isLauncher = Qt.binding(function() {
return model.IsLauncher === true;
});
mainItem.isMinimizedParent = Qt.binding(function() {
return model.IsMinimized === true;
});
mainItem.displayParent = Qt.binding(function() {
return model.display;
});
mainItem.genericName = Qt.binding(function() {
return model.GenericName;
});
mainItem.virtualDesktopParent = Qt.binding(function() {
return (model.VirtualDesktops !== undefined && model.VirtualDesktops.length > 0) ? model.VirtualDesktops : [0];
});
mainItem.isOnAllVirtualDesktopsParent = Qt.binding(function() {
return model.IsOnAllVirtualDesktops === true;
});
mainItem.activitiesParent = Qt.binding(function() {
return model.Activities;
});
mainItem.smartLauncherCountVisible = Qt.binding(function() {
return task.smartLauncherItem && task.smartLauncherItem.countVisible;
});
mainItem.smartLauncherCount = Qt.binding(function() {
return mainItem.smartLauncherCountVisible ? task.smartLauncherItem.count : 0;
});
}
}
}
}
Loader {
anchors.fill: frame
asynchronous: true
source: "TaskProgressOverlay.qml"
active: task.isWindow && task.smartLauncherItem && task.smartLauncherItem.progressVisible
}
Item {
id: iconBox
anchors {
left: parent.left
leftMargin: adjustMargin(true, parent.width, taskFrame.margins.left);
top: parent.top
topMargin: adjustMargin(false, parent.height, taskFrame.margins.top)
}
width: height
height: (parent.height - adjustMargin(false, parent.height, taskFrame.margins.top)
- adjustMargin(false, parent.height, taskFrame.margins.bottom))
function adjustMargin(vert, size, margin) {
if (!size) {
return margin;
}
var margins = vert ? LayoutManager.horizontalMargins() : LayoutManager.verticalMargins();
if ((size - margins) < PlasmaCore.Units.iconSizes.small) {
return Math.ceil((margin * (PlasmaCore.Units.iconSizes.small / size)) / 2);
}
return margin;
}
//width: inPopup ? PlasmaCore.Units.iconSizes.small : Math.min(height, parent.width - LayoutManager.horizontalMargins())
PlasmaCore.IconItem {
id: icon
anchors.fill: parent
anchors.leftMargin: ((pressed) ? PlasmaCore.Units.smallSpacing / 5 : 0) - ((childCount > 0) ? PlasmaCore.Units.smallSpacing * ((childCount > 2) ? 2 : 1.2) : 0)
anchors.topMargin: ((pressed) ? PlasmaCore.Units.smallSpacing / 5 : 0)
//active: task.highlighted
enabled: true
usesPlasmaTheme: false
source: model.decoration
onSourceChanged: {
//if(!icon.valid || icon.source == "" /*&& !model.IsLauncher && !model.IsStartup*/) icon.source = "application-x-executable";
updateHoverColor();
}
}
/*Loader {
// QTBUG anchors.fill in conjunction with the Loader doesn't reliably work on creation:
// have a window with a badge, move it from one screen to another, the new task item on the
// other screen will now have a glitched out badge mask.
width: parent.width
height: parent.height
asynchronous: true
source: "TaskBadgeOverlay.qml"
active: height >= PlasmaCore.Units.iconSizes.small
&& task.smartLauncherItem && task.smartLauncherItem.countVisible
}*/
states: [
// Using a state transition avoids a binding loop between label.visible and
// the text label margin, which derives from the icon width.
State {
name: "standalone"
when: !label.visible
AnchorChanges {
target: iconBox
anchors.left: undefined
anchors.horizontalCenter: parent.horizontalCenter
}
PropertyChanges {
target: iconBox
anchors.leftMargin: 0
width: parent.width - adjustMargin(true, task.width, taskFrame.margins.left)
- adjustMargin(true, task.width, taskFrame.margins.right)
}
}
]
/*Loader {
anchors.fill: parent
active: model.IsStartup === true
sourceComponent: busyIndicator
}
Component {
id: busyIndicator
PlasmaComponents.BusyIndicator { anchors.fill: parent }
}*/
}
Loader {
id: audioStreamIconLoader
readonly property bool shown: item && item.visible
readonly property var indicatorScale: 1.2
source: "AudioStream.qml"
width: Math.min(Math.min(iconBox.width, iconBox.height) * 0.4, PlasmaCore.Units.iconSizes.smallMedium)
height: width
anchors {
right: frame.right
top: frame.top
rightMargin: taskFrame.margins.right
topMargin: Math.round(taskFrame.margins.top * indicatorScale)
}
}
PlasmaComponents.Label {
id: label
visible: (inPopup || !iconsOnly && model.IsLauncher !== true
&& (parent.width - iconBox.height - PlasmaCore.Units.smallSpacing) >= (theme.mSize(theme.defaultFont).width * LayoutManager.minimumMColumns()))
anchors {
fill: parent
leftMargin: taskFrame.margins.left + iconBox.width + PlasmaCore.Units.smallSpacing
topMargin: taskFrame.margins.top
rightMargin: taskFrame.margins.right + (audioStreamIconLoader.shown ? (audioStreamIconLoader.width + PlasmaCore.Units.smallSpacing) : 0)
bottomMargin: taskFrame.margins.bottom
}
text: model.display
wrapMode: (maximumLineCount == 1) ? Text.NoWrap : Text.Wrap
elide: Text.ElideRight
textFormat: Text.PlainText
verticalAlignment: Text.AlignVCenter
maximumLineCount: plasmoid.configuration.maxTextLines || undefined
style: Text.Outline
styleColor: "#20404040"
/*layer.enabled: true
layer.effect: DropShadow {
anchors.fill: parent
source: parent
verticalOffset: 1
horizontalOffset: 1
color: "#80000000"
radius: 0
}*/
}
states: [
State {
name: "launcher"
when: model.IsLauncher === true
PropertyChanges {
target: frame
basePrefix: "active-tab"
}
},
State {
name: "attention"
when: model.IsDemandingAttention === true || (task.smartLauncherItem && task.smartLauncherItem.urgent)
PropertyChanges {
target: frame
basePrefix: "attention"
}
},
State {
name: "minimized"
when: model.IsMinimized === true
PropertyChanges {
target: frame
basePrefix: "minimized"
}
},
State {
name: "active"
when: model.IsActive === true
PropertyChanges {
target: frame
basePrefix: "focus"
}
}
]
Component.onCompleted: {
/*if (!inPopup && model.IsWindow === true) {
var component = Qt.createComponent("GroupExpanderOverlay.qml");
component.createObject(task);
}*/
if (!inPopup && model.IsWindow !== true) {
taskInitComponent.createObject(task);
}
taskList.updateHoverFunc();
updateAudioStreams({delay: false});
//toolTipArea.setBackgroundHints(2);
}
}