workspace: Only pass MetaWindow to WindowPreviewLayout

Since the WindowPreview class rarely needs to handle the actual actor
painting the window preview, refactor the WindowPreviewLayout a bit to
only pass a MetaWindow to its addWindow() and removeWindow() functions.

Also make the getWindows() function return an array of MetaWindows,
which makes the getMetaWindow() function obsolete, so remove that.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1307
This commit is contained in:
Jonas Dreßler 2020-06-08 09:41:51 +02:00
parent 039431a73f
commit c281e868a0

View File

@ -118,35 +118,63 @@ var WindowPreviewLayout = GObject.registerClass({
} }
} }
addWindow(actor, metaWindow) { /**
if (this._windows.has(actor)) * addWindow:
return; * @param {Meta.Window} window: the MetaWindow instance
*
* Creates a ClutterActor drawing the texture of @window and adds it
* to the container. If @window is already part of the preview, this
* function will do nothing.
*
* @returns {Clutter.Actor} The newly created actor drawing @window
*/
addWindow(window) {
const index = [...this._windows.values()].findIndex(info =>
info.metaWindow === window);
const windowActor = metaWindow.get_compositor_private(); if (index !== -1)
return null;
const windowActor = window.get_compositor_private();
const actor = new Clutter.Clone({ source: windowActor });
this._windows.set(actor, { this._windows.set(actor, {
metaWindow, metaWindow: window,
windowActor, windowActor,
sizeChangedId: metaWindow.connect('size-changed', () => sizeChangedId: window.connect('size-changed', () =>
this._layoutChanged()), this._layoutChanged()),
positionChangedId: metaWindow.connect('position-changed', () => positionChangedId: window.connect('position-changed', () =>
this._layoutChanged()), this._layoutChanged()),
windowActorDestroyId: windowActor.connect('destroy', () => windowActorDestroyId: windowActor.connect('destroy', () =>
actor.destroy()), actor.destroy()),
destroyId: actor.connect('destroy', () => destroyId: actor.connect('destroy', () =>
this.removeWindow(actor)), this.removeWindow(window)),
}); });
this._container.add_child(actor); this._container.add_child(actor);
this._layoutChanged(); this._layoutChanged();
return actor;
} }
removeWindow(actor) { /**
const windowInfo = this._windows.get(actor); * removeWindow:
if (!windowInfo) * @param {Meta.Window} window: the window to remove from the preview
*
* Removes a MetaWindow @window from the preview which has been added
* previously using addWindow(). If @window is not part of preview,
* this function will do nothing.
*/
removeWindow(window) {
const entry = [...this._windows].find(
([, i]) => i.metaWindow === window);
if (!entry)
return; return;
const [actor, windowInfo] = entry;
windowInfo.metaWindow.disconnect(windowInfo.sizeChangedId); windowInfo.metaWindow.disconnect(windowInfo.sizeChangedId);
windowInfo.metaWindow.disconnect(windowInfo.positionChangedId); windowInfo.metaWindow.disconnect(windowInfo.positionChangedId);
windowInfo.windowActor.disconnect(windowInfo.windowActorDestroyId); windowInfo.windowActor.disconnect(windowInfo.windowActorDestroyId);
@ -161,31 +189,13 @@ var WindowPreviewLayout = GObject.registerClass({
/** /**
* getWindows: * getWindows:
* *
* Gets an array of all ClutterActors that were added to the layout * Gets an array of all MetaWindows that were added to the layout
* using addWindow(), ordered by the insertion order. * using addWindow(), ordered by the insertion order.
* *
* @returns {Array} An array including all windows * @returns {Array} An array including all windows
*/ */
getWindows() { getWindows() {
return [...this._windows.keys()]; return [...this._windows.values()].map(i => i.metaWindow);
}
/**
* getMetaWindow:
* @param {Clutter.Actor} window: the window to get the MetaWindow for
*
* Gets the MetaWindow associated to the ClutterActor @window that was
* added to the layout using addWindow(). If @window is not found,
* null is returned.
*
* @returns {Meta.Window} The metaWindow of the window
*/
getMetaWindow(window) {
const windowInfo = this._windows.get(window);
if (!windowInfo)
return null;
return windowInfo.metaWindow;
} }
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
@ -493,8 +503,7 @@ var WindowPreview = GObject.registerClass({
} }
_addWindow(metaWindow) { _addWindow(metaWindow) {
const windowActor = metaWindow.get_compositor_private(); const clone = this._windowContainer.layout_manager.addWindow(metaWindow);
const clone = new Clutter.Clone({ source: windowActor });
// We expect this to be used for all interaction rather than // We expect this to be used for all interaction rather than
// the ClutterClone; as the former is reactive and the latter // the ClutterClone; as the former is reactive and the latter
@ -502,8 +511,6 @@ var WindowPreview = GObject.registerClass({
// actors are picked, so DND operations would operate on the clone. // actors are picked, so DND operations would operate on the clone.
// To avoid this, we hide it from pick. // To avoid this, we hide it from pick.
Shell.util_set_hidden_from_pick(clone, true); Shell.util_set_hidden_from_pick(clone, true);
this._windowContainer.layout_manager.addWindow(clone, metaWindow);
} }
vfunc_has_overlaps() { vfunc_has_overlaps() {
@ -514,12 +521,8 @@ var WindowPreview = GObject.registerClass({
const windows = this._windowContainer.layout_manager.getWindows(); const windows = this._windowContainer.layout_manager.getWindows();
// Delete all windows, starting from the bottom-most (most-modal) one // Delete all windows, starting from the bottom-most (most-modal) one
for (const window of windows.reverse()) { for (const window of windows.reverse())
const metaWindow = window.delete(global.get_current_time());
this._windowContainer.layout_manager.getMetaWindow(window);
metaWindow.delete(global.get_current_time());
}
this._closeRequested = true; this._closeRequested = true;
} }