From ee24a44cc4daee685343adb40dc6f3f2215c1212 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Thu, 7 Dec 2023 16:51:43 +0200 Subject: [PATCH] tabbox/switchers/thumbnail_grid: Load Plasma.Dialog on demand This avoids keeping old and creating new window thumbnails after the task switcher is hidden. --- .../thumbnail_grid/contents/ui/main.qml | 373 +++++++++--------- 1 file changed, 188 insertions(+), 185 deletions(-) diff --git a/src/tabbox/switchers/thumbnail_grid/contents/ui/main.qml b/src/tabbox/switchers/thumbnail_grid/contents/ui/main.qml index 8700f04c91..a906d4704b 100644 --- a/src/tabbox/switchers/thumbnail_grid/contents/ui/main.qml +++ b/src/tabbox/switchers/thumbnail_grid/contents/ui/main.qml @@ -20,205 +20,208 @@ KWin.TabBoxSwitcher { id: tabBox currentIndex: thumbnailGridView.currentIndex - PlasmaCore.Dialog { - location: PlasmaCore.Types.Floating - visible: tabBox.visible - flags: Qt.X11BypassWindowManagerHint - x: tabBox.screenGeometry.x + tabBox.screenGeometry.width * 0.5 - dialogMainItem.width * 0.5 - y: tabBox.screenGeometry.y + tabBox.screenGeometry.height * 0.5 - dialogMainItem.height * 0.5 - - mainItem: Item { - id: dialogMainItem - - focus: true - - property int maxWidth: tabBox.screenGeometry.width * 0.9 - property int maxHeight: tabBox.screenGeometry.height * 0.7 - property real screenFactor: tabBox.screenGeometry.width / tabBox.screenGeometry.height - property int maxGridColumnsByWidth: Math.floor(maxWidth / thumbnailGridView.cellWidth) - - property int gridColumns: { // Simple greedy algorithm - // respect screenGeometry - const c = Math.min(thumbnailGridView.count, maxGridColumnsByWidth); - const residue = thumbnailGridView.count % c; - if (residue == 0) { - return c; - } - // start greedy recursion - return columnCountRecursion(c, c, c - residue); - } - - property int gridRows: Math.ceil(thumbnailGridView.count / gridColumns) - property int optimalWidth: thumbnailGridView.cellWidth * gridColumns - property int optimalHeight: thumbnailGridView.cellHeight * gridRows - width: Math.min(Math.max(thumbnailGridView.cellWidth, optimalWidth), maxWidth) - height: Math.min(Math.max(thumbnailGridView.cellHeight, optimalHeight), maxHeight) - - clip: true - - // Step for greedy algorithm - function columnCountRecursion(prevC, prevBestC, prevDiff) { - const c = prevC - 1; - - // don't increase vertical extent more than horizontal - // and don't exceed maxHeight - if (prevC * prevC <= thumbnailGridView.count + prevDiff || - maxHeight < Math.ceil(thumbnailGridView.count / c) * thumbnailGridView.cellHeight) { - return prevBestC; - } - const residue = thumbnailGridView.count % c; - // halts algorithm at some point - if (residue == 0) { - return c; + Instantiator { + active: tabBox.visible + delegate: PlasmaCore.Dialog { + location: PlasmaCore.Types.Floating + visible: true + flags: Qt.X11BypassWindowManagerHint + x: tabBox.screenGeometry.x + tabBox.screenGeometry.width * 0.5 - dialogMainItem.width * 0.5 + y: tabBox.screenGeometry.y + tabBox.screenGeometry.height * 0.5 - dialogMainItem.height * 0.5 + + mainItem: Item { + id: dialogMainItem + + focus: true + + property int maxWidth: tabBox.screenGeometry.width * 0.9 + property int maxHeight: tabBox.screenGeometry.height * 0.7 + property real screenFactor: tabBox.screenGeometry.width / tabBox.screenGeometry.height + property int maxGridColumnsByWidth: Math.floor(maxWidth / thumbnailGridView.cellWidth) + + property int gridColumns: { // Simple greedy algorithm + // respect screenGeometry + const c = Math.min(thumbnailGridView.count, maxGridColumnsByWidth); + const residue = thumbnailGridView.count % c; + if (residue == 0) { + return c; + } + // start greedy recursion + return columnCountRecursion(c, c, c - residue); } - // empty slots - const diff = c - residue; - - // compare it to previous count of empty slots - if (diff < prevDiff) { - return columnCountRecursion(c, c, diff); - } else if (diff == prevDiff) { - // when it's the same try again, we'll stop early enough thanks to the landscape mode condition + + property int gridRows: Math.ceil(thumbnailGridView.count / gridColumns) + property int optimalWidth: thumbnailGridView.cellWidth * gridColumns + property int optimalHeight: thumbnailGridView.cellHeight * gridRows + width: Math.min(Math.max(thumbnailGridView.cellWidth, optimalWidth), maxWidth) + height: Math.min(Math.max(thumbnailGridView.cellHeight, optimalHeight), maxHeight) + + clip: true + + // Step for greedy algorithm + function columnCountRecursion(prevC, prevBestC, prevDiff) { + const c = prevC - 1; + + // don't increase vertical extent more than horizontal + // and don't exceed maxHeight + if (prevC * prevC <= thumbnailGridView.count + prevDiff || + maxHeight < Math.ceil(thumbnailGridView.count / c) * thumbnailGridView.cellHeight) { + return prevBestC; + } + const residue = thumbnailGridView.count % c; + // halts algorithm at some point + if (residue == 0) { + return c; + } + // empty slots + const diff = c - residue; + + // compare it to previous count of empty slots + if (diff < prevDiff) { + return columnCountRecursion(c, c, diff); + } else if (diff == prevDiff) { + // when it's the same try again, we'll stop early enough thanks to the landscape mode condition + return columnCountRecursion(c, prevBestC, diff); + } + // when we've found a local minimum choose this one (greedy) return columnCountRecursion(c, prevBestC, diff); } - // when we've found a local minimum choose this one (greedy) - return columnCountRecursion(c, prevBestC, diff); - } - - // Just to get the margin sizes - KSvg.FrameSvgItem { - id: hoverItem - imagePath: "widgets/viewitem" - prefix: "hover" - visible: false - } - - GridView { - id: thumbnailGridView - anchors.fill: parent - focus: true - model: tabBox.model - - readonly property int iconSize: Kirigami.Units.iconSizes.huge - readonly property int captionRowHeight: Kirigami.Units.gridUnit * 2 - readonly property int columnSpacing: Kirigami.Units.gridUnit - readonly property int thumbnailWidth: Kirigami.Units.gridUnit * 16 - readonly property int thumbnailHeight: thumbnailWidth * (1.0/dialogMainItem.screenFactor) - cellWidth: hoverItem.margins.left + thumbnailWidth + hoverItem.margins.right - cellHeight: hoverItem.margins.top + captionRowHeight + thumbnailHeight + hoverItem.margins.bottom - - keyNavigationWraps: true - highlightMoveDuration: 0 - - delegate: MouseArea { - id: thumbnailGridItem - width: thumbnailGridView.cellWidth - height: thumbnailGridView.cellHeight - focus: GridView.isCurrentItem - hoverEnabled: true - - Accessible.name: model.caption - Accessible.role: Accessible.ListItem - - onClicked: { - thumbnailGridView.currentIndex = index; - } - ColumnLayout { - id: columnLayout - z: 0 - spacing: thumbnailGridView.columnSpacing - anchors.fill: parent - anchors.leftMargin: hoverItem.margins.left * 2 - anchors.topMargin: hoverItem.margins.top * 2 - anchors.rightMargin: hoverItem.margins.right * 2 - anchors.bottomMargin: hoverItem.margins.bottom * 2 - - - // KWin.WindowThumbnail needs a container - // otherwise it will be drawn the same size as the parent ColumnLayout - Item { - Layout.fillWidth: true - Layout.fillHeight: true - - KWin.WindowThumbnail { - anchors.fill: parent - wId: windowId - } + // Just to get the margin sizes + KSvg.FrameSvgItem { + id: hoverItem + imagePath: "widgets/viewitem" + prefix: "hover" + visible: false + } - Kirigami.Icon { - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.bottom - anchors.verticalCenterOffset: Math.round(-thumbnailGridView.iconSize / 4) - width: thumbnailGridView.iconSize - height: thumbnailGridView.iconSize + GridView { + id: thumbnailGridView + anchors.fill: parent + focus: true + model: tabBox.model + + readonly property int iconSize: Kirigami.Units.iconSizes.huge + readonly property int captionRowHeight: Kirigami.Units.gridUnit * 2 + readonly property int columnSpacing: Kirigami.Units.gridUnit + readonly property int thumbnailWidth: Kirigami.Units.gridUnit * 16 + readonly property int thumbnailHeight: thumbnailWidth * (1.0/dialogMainItem.screenFactor) + cellWidth: hoverItem.margins.left + thumbnailWidth + hoverItem.margins.right + cellHeight: hoverItem.margins.top + captionRowHeight + thumbnailHeight + hoverItem.margins.bottom + + keyNavigationWraps: true + highlightMoveDuration: 0 + + delegate: MouseArea { + id: thumbnailGridItem + width: thumbnailGridView.cellWidth + height: thumbnailGridView.cellHeight + focus: GridView.isCurrentItem + hoverEnabled: true + + Accessible.name: model.caption + Accessible.role: Accessible.ListItem + + onClicked: { + thumbnailGridView.currentIndex = index; + } - source: model.icon - } + ColumnLayout { + id: columnLayout + z: 0 + spacing: thumbnailGridView.columnSpacing + anchors.fill: parent + anchors.leftMargin: hoverItem.margins.left * 2 + anchors.topMargin: hoverItem.margins.top * 2 + anchors.rightMargin: hoverItem.margins.right * 2 + anchors.bottomMargin: hoverItem.margins.bottom * 2 + + + // KWin.WindowThumbnail needs a container + // otherwise it will be drawn the same size as the parent ColumnLayout + Item { + Layout.fillWidth: true + Layout.fillHeight: true + + KWin.WindowThumbnail { + anchors.fill: parent + wId: windowId + } + + Kirigami.Icon { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.bottom + anchors.verticalCenterOffset: Math.round(-thumbnailGridView.iconSize / 4) + width: thumbnailGridView.iconSize + height: thumbnailGridView.iconSize - PlasmaComponents3.ToolButton { - id: closeButton - anchors { - right: parent.right - top: parent.top - // Deliberately touch the inner edges of the frame - rightMargin: -columnLayout.anchors.rightMargin - topMargin: -columnLayout.anchors.topMargin + source: model.icon } - visible: model.closeable && typeof tabBox.model.close !== 'undefined' && - (thumbnailGridItem.containsMouse - || closeButton.hovered - || thumbnailGridItem.focus - || Kirigami.Settings.tabletMode - || Kirigami.Settings.hasTransientTouchInput - ) - icon.name: 'window-close-symbolic' - onClicked: { - tabBox.model.close(index); + + PlasmaComponents3.ToolButton { + id: closeButton + anchors { + right: parent.right + top: parent.top + // Deliberately touch the inner edges of the frame + rightMargin: -columnLayout.anchors.rightMargin + topMargin: -columnLayout.anchors.topMargin + } + visible: model.closeable && typeof tabBox.model.close !== 'undefined' && + (thumbnailGridItem.containsMouse + || closeButton.hovered + || thumbnailGridItem.focus + || Kirigami.Settings.tabletMode + || Kirigami.Settings.hasTransientTouchInput + ) + icon.name: 'window-close-symbolic' + onClicked: { + tabBox.model.close(index); + } } } - } - PlasmaComponents3.Label { - Layout.fillWidth: true - text: model.caption - font.weight: thumbnailGridItem.focus ? Font.Bold : Font.Normal - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - textFormat: Text.PlainText - elide: Text.ElideRight + PlasmaComponents3.Label { + Layout.fillWidth: true + text: model.caption + font.weight: thumbnailGridItem.focus ? Font.Bold : Font.Normal + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + textFormat: Text.PlainText + elide: Text.ElideRight + } } - } - } // GridView.delegate + } // GridView.delegate - highlight: KSvg.FrameSvgItem { - imagePath: "widgets/viewitem" - prefix: "hover" - } + highlight: KSvg.FrameSvgItem { + imagePath: "widgets/viewitem" + prefix: "hover" + } - Connections { - target: tabBox - function onCurrentIndexChanged() { - thumbnailGridView.currentIndex = tabBox.currentIndex; + Connections { + target: tabBox + function onCurrentIndexChanged() { + thumbnailGridView.currentIndex = tabBox.currentIndex; + } + } + } // GridView + + Keys.onPressed: { + if (event.key == Qt.Key_Left) { + thumbnailGridView.moveCurrentIndexLeft(); + } else if (event.key == Qt.Key_Right) { + thumbnailGridView.moveCurrentIndexRight(); + } else if (event.key == Qt.Key_Up) { + thumbnailGridView.moveCurrentIndexUp(); + } else if (event.key == Qt.Key_Down) { + thumbnailGridView.moveCurrentIndexDown(); + } else { + return; } - } - } // GridView - - Keys.onPressed: { - if (event.key == Qt.Key_Left) { - thumbnailGridView.moveCurrentIndexLeft(); - } else if (event.key == Qt.Key_Right) { - thumbnailGridView.moveCurrentIndexRight(); - } else if (event.key == Qt.Key_Up) { - thumbnailGridView.moveCurrentIndexUp(); - } else if (event.key == Qt.Key_Down) { - thumbnailGridView.moveCurrentIndexDown(); - } else { - return; - } - thumbnailGridView.currentIndexChanged(thumbnailGridView.currentIndex); - } - } // Dialog.mainItem - } // Dialog + thumbnailGridView.currentIndexChanged(thumbnailGridView.currentIndex); + } + } // Dialog.mainItem + } // Dialog + } // Instantiator }