windowview: Use asynchronous instantiators instead of repeaters

We don't need the features of Repeater here and can instead just use an
Instantiator, which allows us to use asynchronous creation for the
window delegates, reducing the time needed to activate the effect.
This commit is contained in:
Arjen Hiemstra 2022-11-22 12:04:01 +01:00
parent cf583aa367
commit 8242584b6e
2 changed files with 42 additions and 33 deletions

View file

@ -23,9 +23,9 @@ FocusScope {
Down Down
} }
property alias model: windowsRepeater.model property alias model: windowsInstantiator.model
property alias delegate: windowsRepeater.delegate property alias delegate: windowsInstantiator.delegate
readonly property alias count: windowsRepeater.count readonly property alias count: windowsInstantiator.count
readonly property bool activeEmpty: { readonly property bool activeEmpty: {
var children = expoLayout.visibleChildren; var children = expoLayout.visibleChildren;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < children.length; i++) {
@ -55,7 +55,7 @@ FocusScope {
signal windowClicked(QtObject window, EventPoint eventPoint) signal windowClicked(QtObject window, EventPoint eventPoint)
function activateIndex(index) { function activateIndex(index) {
KWinComponents.Workspace.activeClient = windowsRepeater.itemAt(index).client; KWinComponents.Workspace.activeClient = windowsInstantiator.objectAt(index).client;
activated(); activated();
} }
@ -131,33 +131,36 @@ FocusScope {
fillGaps: true fillGaps: true
spacing: PlasmaCore.Units.smallSpacing * 5 spacing: PlasmaCore.Units.smallSpacing * 5
Repeater { Instantiator {
id: windowsRepeater id: windowsInstantiator
onItemAdded: (index, item) => { asynchronous: true
// restore/reparent from drop
var key = item.client.internalId; delegate: WindowHeapDelegate {
windowHeap: heap
}
onObjectAdded: (index, object) => {
object.parent = expoLayout
var key = object.client.internalId;
if (heap.containsDND(key)) { if (heap.containsDND(key)) {
expoLayout.forceLayout(); expoLayout.forceLayout();
var oldGlobalRect = heap.restoreDND(key); var oldGlobalRect = heap.restoreDND(key);
item.restoreDND(oldGlobalRect); object.restoreDND(oldGlobalRect);
heap.deleteDND(key); heap.deleteDND(key);
} else if (heap.effectiveOrganized) { } else if (heap.effectiveOrganized) {
// New window has opened in the middle of a running effect. // New window has opened in the middle of a running effect.
// Make sure it is positioned before enabling its animations. // Make sure it is positioned before enabling its animations.
expoLayout.forceLayout(); expoLayout.forceLayout();
} }
item.animationEnabled = true; object.animationEnabled = true;
}
delegate: WindowHeapDelegate {
windowHeap: heap
} }
} }
} }
function findFirstItem() { function findFirstItem() {
for (let candidateIndex = 0; candidateIndex < windowsRepeater.count; ++candidateIndex) { for (let candidateIndex = 0; candidateIndex < windowsInstantiator.count; ++candidateIndex) {
const candidateItem = windowsRepeater.itemAt(candidateIndex); const candidateItem = windowsInstantiator.objectAt(candidateIndex);
if (!candidateItem.hidden) { if (!candidateItem.hidden) {
return candidateIndex; return candidateIndex;
} }
@ -170,13 +173,13 @@ FocusScope {
return findFirstItem(); return findFirstItem();
} }
const selectedItem = windowsRepeater.itemAt(selectedIndex); const selectedItem = windowsInstantiator.objectAt(selectedIndex);
let nextIndex = -1; let nextIndex = -1;
switch (direction) { switch (direction) {
case WindowHeap.Direction.Left: case WindowHeap.Direction.Left:
for (let candidateIndex = 0; candidateIndex < windowsRepeater.count; ++candidateIndex) { for (let candidateIndex = 0; candidateIndex < windowsInstantiator.count; ++candidateIndex) {
const candidateItem = windowsRepeater.itemAt(candidateIndex); const candidateItem = windowsInstantiator.objectAt(candidateIndex);
if (candidateItem.hidden) { if (candidateItem.hidden) {
continue; continue;
} }
@ -191,7 +194,7 @@ FocusScope {
if (nextIndex === -1) { if (nextIndex === -1) {
nextIndex = candidateIndex; nextIndex = candidateIndex;
} else { } else {
const nextItem = windowsRepeater.itemAt(nextIndex); const nextItem = windowsInstantiator.objectAt(nextIndex);
if (candidateItem.x + candidateItem.width > nextItem.x + nextItem.width) { if (candidateItem.x + candidateItem.width > nextItem.x + nextItem.width) {
nextIndex = candidateIndex; nextIndex = candidateIndex;
} }
@ -200,8 +203,8 @@ FocusScope {
} }
break; break;
case WindowHeap.Direction.Right: case WindowHeap.Direction.Right:
for (let candidateIndex = 0; candidateIndex < windowsRepeater.count; ++candidateIndex) { for (let candidateIndex = 0; candidateIndex < windowsInstantiator.count; ++candidateIndex) {
const candidateItem = windowsRepeater.itemAt(candidateIndex); const candidateItem = windowsInstantiator.objectAt(candidateIndex);
if (candidateItem.hidden) { if (candidateItem.hidden) {
continue; continue;
} }
@ -216,7 +219,7 @@ FocusScope {
if (nextIndex === -1) { if (nextIndex === -1) {
nextIndex = candidateIndex; nextIndex = candidateIndex;
} else { } else {
const nextItem = windowsRepeater.itemAt(nextIndex); const nextItem = windowsInstantiator.objectAt(nextIndex);
if (nextIndex === -1 || candidateItem.x < nextItem.x) { if (nextIndex === -1 || candidateItem.x < nextItem.x) {
nextIndex = candidateIndex; nextIndex = candidateIndex;
} }
@ -225,8 +228,8 @@ FocusScope {
} }
break; break;
case WindowHeap.Direction.Up: case WindowHeap.Direction.Up:
for (let candidateIndex = 0; candidateIndex < windowsRepeater.count; ++candidateIndex) { for (let candidateIndex = 0; candidateIndex < windowsInstantiator.count; ++candidateIndex) {
const candidateItem = windowsRepeater.itemAt(candidateIndex); const candidateItem = windowsInstantiator.objectAt(candidateIndex);
if (candidateItem.hidden) { if (candidateItem.hidden) {
continue; continue;
} }
@ -241,7 +244,7 @@ FocusScope {
if (nextIndex === -1) { if (nextIndex === -1) {
nextIndex = candidateIndex; nextIndex = candidateIndex;
} else { } else {
const nextItem = windowsRepeater.itemAt(nextIndex); const nextItem = windowsInstantiator.objectAt(nextIndex);
if (nextItem.y + nextItem.height < candidateItem.y + candidateItem.height) { if (nextItem.y + nextItem.height < candidateItem.y + candidateItem.height) {
nextIndex = candidateIndex; nextIndex = candidateIndex;
} }
@ -250,8 +253,8 @@ FocusScope {
} }
break; break;
case WindowHeap.Direction.Down: case WindowHeap.Direction.Down:
for (let candidateIndex = 0; candidateIndex < windowsRepeater.count; ++candidateIndex) { for (let candidateIndex = 0; candidateIndex < windowsInstantiator.count; ++candidateIndex) {
const candidateItem = windowsRepeater.itemAt(candidateIndex); const candidateItem = windowsInstantiator.objectAt(candidateIndex);
if (candidateItem.hidden) { if (candidateItem.hidden) {
continue; continue;
} }
@ -266,7 +269,7 @@ FocusScope {
if (nextIndex === -1) { if (nextIndex === -1) {
nextIndex = candidateIndex; nextIndex = candidateIndex;
} else { } else {
const nextItem = windowsRepeater.itemAt(nextIndex); const nextItem = windowsInstantiator.objectAt(nextIndex);
if (candidateItem.y < nextItem.y) { if (candidateItem.y < nextItem.y) {
nextIndex = candidateIndex; nextIndex = candidateIndex;
} }
@ -353,11 +356,11 @@ FocusScope {
handled = false; handled = false;
let selectedItem = null; let selectedItem = null;
if (selectedIndex !== -1) { if (selectedIndex !== -1) {
selectedItem = windowsRepeater.itemAt(selectedIndex); selectedItem = windowsInstantiator.objectAt(selectedIndex);
} else { } else {
// If the window heap has only one visible window, activate it. // If the window heap has only one visible window, activate it.
for (let i = 0; i < windowsRepeater.count; ++i) { for (let i = 0; i < windowsInstantiator.count; ++i) {
const candidateItem = windowsRepeater.itemAt(i); const candidateItem = windowsInstantiator.objectAt(i);
if (candidateItem.hidden) { if (candidateItem.hidden) {
continue; continue;
} else if (selectedItem) { } else if (selectedItem) {

View file

@ -212,7 +212,9 @@ Item {
} }
} }
Repeater { Instantiator {
asynchronous: true
model: KWinComponents.ClientFilterModel { model: KWinComponents.ClientFilterModel {
desktop: KWinComponents.Workspace.currentVirtualDesktop desktop: KWinComponents.Workspace.currentVirtualDesktop
screenName: targetScreen.name screenName: targetScreen.name
@ -233,6 +235,10 @@ Item {
NumberAnimation { duration: container.effect.animationDuration; easing.type: Easing.OutCubic } NumberAnimation { duration: container.effect.animationDuration; easing.type: Easing.OutCubic }
} }
} }
onObjectAdded: (index, object) => {
object.parent = container
}
} }
KWinComponents.ClientModel { KWinComponents.ClientModel {