workspaceAnimation: Use window clones

Instead of reparenting windows, clone them. This will allow to properly
support multi-monitor setups in subsequent commits.

Block window mapping animation while the animation is running to prevent
new windows appearing during the animation from being visible at the same
time as their clones.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/929

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/605
This commit is contained in:
Alexander Mikhaylenko 2019-07-04 23:15:15 +05:00 committed by Florian Müllner
parent f0d498062d
commit 46d5bccfc6

View File

@ -49,15 +49,19 @@ class WorkspaceGroup extends Clutter.Actor {
windows = windows.filter(w => this._shouldShowWindow(w.meta_window)); windows = windows.filter(w => this._shouldShowWindow(w.meta_window));
for (let window of windows) { for (let window of windows) {
let record = { let clone = new Clutter.Clone({
window, source: window,
parent: window.get_parent(), x: window.x,
}; y: window.y,
});
record.parent.remove_child(window); this.add_actor(clone);
this.add_child(window); window.hide();
let record = { window, clone };
record.windowDestroyId = window.connect('destroy', () => { record.windowDestroyId = window.connect('destroy', () => {
clone.destroy();
this._windows.splice(this._windows.indexOf(record), 1); this._windows.splice(this._windows.indexOf(record), 1);
}); });
@ -70,12 +74,11 @@ class WorkspaceGroup extends Clutter.Actor {
let w = this._windows[i]; let w = this._windows[i];
w.window.disconnect(w.windowDestroyId); w.window.disconnect(w.windowDestroyId);
this.remove_child(w.window); w.clone.destroy();
w.parent.add_child(w.window);
if (w.window.get_meta_window().get_workspace() !== if (w.window.get_meta_window().get_workspace() ===
global.workspace_manager.get_active_workspace()) global.workspace_manager.get_active_workspace())
w.window.hide(); w.window.show();
} }
this._windows = []; this._windows = [];