/*SPDX-FileCopyrightText: 2013 Sebastian KΓΌgler <sebas@kde.org>SPDX-FileCopyrightText: 2014 Martin GrΓ€Γlin <mgraesslin@kde.org>SPDX-FileCopyrightText: 2016 Kai Uwe Broulik <kde@privat.broulik.de>SPDX-FileCopyrightText: 2017 Roman Gilg <subdiff@gmail.com>SPDX-FileCopyrightText: 2024 Nate Graham <nate@kde.org>SPDX-License-Identifier: LGPL-2.0-or-later*/pragma ComponentBehavior: Boundimport QtQml.Modelsimport QtQuickimport org.kde.plasma.core as PlasmaCoreimport org.kde.plasma.components as PlasmaComponents3import org.kde.plasma.private.mpris as Mprisimport org.kde.kirigami as Kirigamiimport org.kde.plasma.plasmoidLoader {id: toolTipDelegateproperty Task parentTaskproperty /*QModelIndex*/var rootIndexproperty string appNameproperty int pidParentproperty bool isGroupproperty /*list<WId> where WId = int|string*/ var windows: []readonly property bool isWin: windows.length > 0property /*QIcon*/ var iconproperty url launcherUrlproperty bool isLauncherproperty bool isMinimizedproperty bool isReadyForPaintingproperty bool isExcludedFromCapture// Needed for generateSubtext()property string displayproperty string genericNameproperty /*list<var>*/ var virtualDesktops: [] // Can't use list<var> because of QTBUG-127600property bool isOnAllVirtualDesktopsproperty list<string> activities: []property bool smartLauncherCountVisibleproperty int smartLauncherCountproperty bool blockingUpdates: falsereadonly property bool isVerticalPanel: Plasmoid.formFactor === PlasmaCore.Types.Vertical// This number controls the overall size of the window tooltipsreadonly property int tooltipInstanceMaximumWidth: Kirigami.Units.gridUnit * 16// These properties are required to make tooltip interactive when there is a player but no window is present.readonly property Mpris.PlayerContainer playerData: mpris2Source.playerForLauncherUrl(launcherUrl, pidParent)LayoutMirroring.enabled: Application.layoutDirection === Qt.RightToLeftLayoutMirroring.childrenInherit: trueactive: !blockingUpdates && rootIndex !== undefined && ((parentTask && parentTask.containsMouse) || Window.visibility !== Window.Hidden)asynchronous: truesourceComponent: isGroup ? groupToolTip : singleTooltipComponent {id: singleTooltipToolTipInstance {index: 0 // TODO: maybe set to -1, because that's what the component checks against?submodelIndex: toolTipDelegate.rootIndexappPid: toolTipDelegate.pidParentdisplay: toolTipDelegate.displayisMinimized: toolTipDelegate.isMinimizedisReadyForPainting: toolTipDelegate.isReadyForPaintingisExcludedFromCapture: toolTipDelegate.isExcludedFromCaptureisOnAllVirtualDesktops: toolTipDelegate.isOnAllVirtualDesktopsvirtualDesktops: toolTipDelegate.virtualDesktopsactivities: toolTipDelegate.activitiesmodel: null}}Component {id: groupToolTipPlasmaComponents3.ScrollView {id: scrollView// 2 * Kirigami.Units.smallSpacing is for the margin of tooltipDialogreadonly property real maximumWidth: Screen.desktopAvailableWidth - 2 * Kirigami.Units.smallSpacingreadonly property real maximumHeight: Screen.desktopAvailableWidth - 2 * Kirigami.Units.smallSpacingimplicitWidth: {// when vertical, all delegates have the same fixed width, but with an extra// gridUnit when thumbnails are disabled to match the default tooltip marginslet listContentWidth = groupToolTipListView.orientation == ListView.Vertical? toolTipDelegate.tooltipInstanceMaximumWidth + (toolTipDelegate.isWin && Plasmoid.configuration.showToolTips ? 0 : Kirigami.Units.gridUnit): groupToolTipListView.contentWidthreturn leftPadding + rightPadding + Math.min(maximumWidth, Math.max(delegateModel.estimatedWidth, listContentWidth))}implicitHeight: {// not using bottomPadding; in PC3 it's either 0 or the scrollbar height, and here// this causes binding loops when turning it off - manually computing the width// avoids this.let scrollBarRequired = groupToolTipListView.contentWidth > maximumWidthlet scrollBarHeight = scrollBarRequired ? PlasmaComponents3.ScrollBar.horizontal.height : 0// currentItem is never unloaded, so we use it for sizing. Default to the same value// that estimatedHeight while it's not availablelet listContentHeight = groupToolTipListView.orientation == ListView.Vertical? groupToolTipListView.contentHeight: groupToolTipListView.currentItem?.implicitHeight ?? toolTipDelegate.tooltipInstanceMaximumWidthreturn Math.min(maximumHeight, Math.max(delegateModel.estimatedHeight, listContentHeight + scrollBarHeight))}ListView {id: groupToolTipListViewmodel: delegateModelorientation: toolTipDelegate.isVerticalPanel || !Plasmoid.configuration.showToolTips ? ListView.Vertical : ListView.HorizontalreuseItems: true// Lots of spacing with no thumbnails looks badspacing: Plasmoid.configuration.showToolTips ? Kirigami.Units.gridUnit : 0// Required to know whether to display the media player buttons on the first window or notproperty bool hasTrackInATitle: {var found = falsefor (var i=0; i<model.items.count && !found; i++) {found = model.items.get(i).model.display.includes(toolTipDelegate.playerData?.track)}return found}Component.onCompleted: if (parentTask.model.IsActive) {groupToolTipListView.positionViewAtIndex(tasksModel.activeTask.row, ListView.Center)}}DelegateModel {id: delegateModel// On Wayland, a tooltip has a significant resizing process, so estimate the size first.readonly property real estimatedWidth: (toolTipDelegate.isVerticalPanel || !Plasmoid.configuration.showToolTips ? 1 : count) * (toolTipDelegate.tooltipInstanceMaximumWidth + Kirigami.Units.gridUnit) - Kirigami.Units.gridUnitreadonly property real estimatedHeight: (toolTipDelegate.isVerticalPanel || !Plasmoid.configuration.showToolTips ? count : 1) * (Plasmoid.configuration.showToolTips ? (toolTipDelegate.tooltipInstanceMaximumWidth / 2 + Kirigami.Units.gridUnit) : Kirigami.Units.gridUnit * 2) - Kirigami.Units.gridUnitmodel: tasksModelrootIndex: toolTipDelegate.rootIndexonRootIndexChanged: {if (parentTask.model.IsActive) {groupToolTipListView.positionViewAtIndex(tasksModel.activeTask.row, ListView.Center)} else {groupToolTipListView.positionViewAtBeginning() // Fix a visual glitch (when the mouse moves from a tooltip with a moved scrollbar to another tooltip without a scrollbar)}}delegate: ToolTipInstance {id: delegatesubmodelIndex: tasksModel.makeModelIndex(toolTipDelegate.rootIndex.row, index)appPid: model.AppPid// 'display' is required alreadyisMinimized: model.IsMinimizedisReadyForPainting: model.IsMappedisExcludedFromCapture: model.IsExcludedFromCaptureisOnAllVirtualDesktops: model.IsOnAllVirtualDesktopsvirtualDesktops: model.VirtualDesktopsactivities: model.ActivitieshasTrackInATitle: groupToolTipListView.hasTrackInATitleorientation: groupToolTipListView.orientationKirigami.WheelHandler {property real accumulatedDeltaY: 0target: scrollView.contentItemonWheel: event => {if (toolTipDelegate.isVerticalPanel || event.angleDelta.x != 0) {return}accumulatedDeltaY += event.angleDelta.yif (accumulatedDeltaY >= 120) {accumulatedDeltaY = 0scrollLeft()} else if (accumulatedDeltaY <= -120) {accumulatedDeltaY = 0scrollRight()}event.accepted = true}}}}}}}