mirror of
https://github.com/edu4rdshl/gnome-shell.git
synced 2026-07-18 07:34:54 +00:00
workspace: Use existing code to add windows to workspaces
We already have code to add existing windows, and react to added/removed windows. Hook into this code to add DESKTOP windows to background. This will initialize the overview properly if a desktop window comes into existence or is added while the overview is up. Monitor all windows for change in two properties - skip-taskbar and window_type === Meta.WindowType.DESKTOP. Move from desktop layer in background to overview and vice-versa if the properties change appropriately. This insures if the waylandclient method make_desktop() is called later after the window is created, to move the window correctly into the background, analogous to monitoring the skip-taskbar property. Do not intialize desktoplayer in background if there are no windows of type DESKTOP. This avoids initialization and usage the new backgroundLayoutManager, therefore avoiding expensive context switches with C code in the normal layout manager used.
This commit is contained in:
parent
a37c0fcffe
commit
f6767c5545
1 changed files with 112 additions and 69 deletions
|
|
@ -983,40 +983,14 @@ class WorkspaceBackground extends Shell.WorkspaceBackground {
|
|||
useContentSize: false,
|
||||
});
|
||||
|
||||
const desktopWindows = global.get_window_actors().filter(a =>
|
||||
a.meta_window.get_window_type() === Meta.WindowType.DESKTOP);
|
||||
|
||||
if (desktopWindows.length) {
|
||||
const desktopLayer = new Clutter.Actor({
|
||||
layout_manager: new DesktopBackgroundLayout(),
|
||||
clip_to_allocation: true,
|
||||
});
|
||||
|
||||
for (let windowActor of desktopWindows) {
|
||||
const clone = new Clutter.Clone({
|
||||
source: windowActor,
|
||||
});
|
||||
|
||||
desktopLayer.add_child(clone);
|
||||
|
||||
windowActor.connectObject('destroy', () => {
|
||||
clone.destroy();
|
||||
}, this);
|
||||
}
|
||||
|
||||
const offset = 0;
|
||||
const syncAll = Clutter.BindConstraint.new(this._bgManager.backgroundActor,
|
||||
Clutter.BindCoordinate.ALL, offset);
|
||||
desktopLayer.add_constraint(syncAll);
|
||||
this._backgroundGroup.insert_child_above(desktopLayer,
|
||||
this._bgManager.backgroundActor);
|
||||
}
|
||||
|
||||
this._bgManager.connect('changed', () => {
|
||||
this._updateRoundedClipBounds();
|
||||
this._updateBorderRadius();
|
||||
});
|
||||
|
||||
this._desktopWindows = new Map();
|
||||
this._desktopLayer = null;
|
||||
|
||||
global.display.connectObject('workareas-changed', () => {
|
||||
this._workarea = Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
|
||||
this._updateRoundedClipBounds();
|
||||
|
|
@ -1029,6 +1003,46 @@ class WorkspaceBackground extends Shell.WorkspaceBackground {
|
|||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
addDesktopClone(desktopWindow) {
|
||||
if (this._desktopWindows.has(desktopWindow))
|
||||
return;
|
||||
if (!this._desktopLayer)
|
||||
this._makeDesktopLayer();
|
||||
|
||||
const clone = new Clutter.Clone({
|
||||
source: desktopWindow.get_compositor_private(),
|
||||
});
|
||||
|
||||
this._desktopLayer.add_child(clone);
|
||||
|
||||
clone.connectObject('destroy', () => {
|
||||
clone.destroy();
|
||||
}, this);
|
||||
|
||||
this._desktopWindows.set(desktopWindow, clone);
|
||||
}
|
||||
|
||||
removeDesktopClone(desktopWindow) {
|
||||
if (this._desktopWindows.has(desktopWindow)) {
|
||||
this._desktopWindows.get(desktopWindow)?.destroy();
|
||||
this._desktopWindows.delete(desktopWindow);
|
||||
}
|
||||
}
|
||||
|
||||
_makeDesktopLayer() {
|
||||
this._desktopLayer = new Clutter.Actor({
|
||||
layout_manager: new DesktopBackgroundLayout(),
|
||||
clip_to_allocation: true,
|
||||
});
|
||||
|
||||
const offset = 0;
|
||||
const syncAll = Clutter.BindConstraint.new(this._bgManager.backgroundActor,
|
||||
Clutter.BindCoordinate.ALL, offset);
|
||||
this._desktopLayer.add_constraint(syncAll);
|
||||
this._backgroundGroup.insert_child_above(this._desktopLayer,
|
||||
this._bgManager.backgroundActor);
|
||||
}
|
||||
|
||||
_updateBorderRadius() {
|
||||
const {scaleFactor} = St.ThemeContext.get_for_stage(global.stage);
|
||||
const cornerRadius = scaleFactor * BACKGROUND_CORNER_RADIUS_PIXELS;
|
||||
|
|
@ -1126,6 +1140,14 @@ class Workspace extends St.Widget {
|
|||
this.monitorIndex = monitorIndex;
|
||||
this._monitor = Main.layoutManager.monitors[this.monitorIndex];
|
||||
|
||||
this._skipTaskbarSignals = new Map();
|
||||
this._desktopWindowsSignals = new Map();
|
||||
this._windows = [];
|
||||
this._layoutFrozenId = 0;
|
||||
|
||||
// DND requires this to be set
|
||||
this._delegate = this;
|
||||
|
||||
if (monitorIndex !== Main.layoutManager.primaryIndex)
|
||||
this.add_style_class_name('external-monitor');
|
||||
|
||||
|
|
@ -1147,13 +1169,6 @@ class Workspace extends St.Widget {
|
|||
this.connect('style-changed', this._onStyleChanged.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._skipTaskbarSignals = new Map();
|
||||
this._windows = [];
|
||||
this._layoutFrozenId = 0;
|
||||
|
||||
// DND requires this to be set
|
||||
this._delegate = this;
|
||||
|
||||
// Track window changes, but let the window tracker process them first
|
||||
this.metaWorkspace?.connectObject(
|
||||
'window-added', this._windowAdded.bind(this), GObject.ConnectFlags.AFTER,
|
||||
|
|
@ -1197,6 +1212,31 @@ class Workspace extends St.Widget {
|
|||
this._container.layout_manager.syncStacking(stackIndices);
|
||||
}
|
||||
|
||||
_addDesktopClone(metaWin) {
|
||||
this._background.addDesktopClone(metaWin);
|
||||
}
|
||||
|
||||
_removeDesktopClone(metaWin) {
|
||||
this._background.removeDesktopClone(metaWin);
|
||||
}
|
||||
|
||||
_addPropertyMonitoringSignals(metaWin) {
|
||||
this._skipTaskbarSignals.set(metaWin,
|
||||
metaWin.connect('notify::skip-taskbar', () => {
|
||||
if (metaWin.skip_taskbar)
|
||||
this._doRemoveWindow(metaWin);
|
||||
else
|
||||
this._doAddWindow(metaWin);
|
||||
}));
|
||||
this._desktopWindowsSignals.set(metaWin,
|
||||
metaWin.connect('notify::window_type', () => {
|
||||
if (metaWin.window_type !== Meta.WindowType.DESKTOP)
|
||||
this._removeDesktopClone(metaWin);
|
||||
else
|
||||
this._addDesktopClone(metaWin);
|
||||
}));
|
||||
}
|
||||
|
||||
_doRemoveWindow(metaWin) {
|
||||
let clone = this._removeWindowClone(metaWin);
|
||||
|
||||
|
|
@ -1244,37 +1284,11 @@ class Workspace extends St.Widget {
|
|||
}
|
||||
|
||||
_doAddWindow(metaWin) {
|
||||
let win = metaWin.get_compositor_private();
|
||||
|
||||
if (!win) {
|
||||
// Newly-created windows are added to a workspace before
|
||||
// the compositor finds out about them...
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
if (metaWin.get_compositor_private() &&
|
||||
metaWin.get_workspace() === this.metaWorkspace)
|
||||
this._doAddWindow(metaWin);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] this._doAddWindow');
|
||||
return;
|
||||
}
|
||||
|
||||
// We might have the window in our list already if it was on all workspaces and
|
||||
// now was moved to this workspace
|
||||
if (this.containsMetaWindow(metaWin))
|
||||
return;
|
||||
|
||||
if (!this._isMyWindow(metaWin))
|
||||
return;
|
||||
|
||||
this._skipTaskbarSignals.set(metaWin,
|
||||
metaWin.connect('notify::skip-taskbar', () => {
|
||||
if (metaWin.skip_taskbar)
|
||||
this._doRemoveWindow(metaWin);
|
||||
else
|
||||
this._doAddWindow(metaWin);
|
||||
}));
|
||||
|
||||
if (!this._isOverviewWindow(metaWin)) {
|
||||
if (metaWin.get_transient_for() == null)
|
||||
return;
|
||||
|
|
@ -1314,22 +1328,48 @@ class Workspace extends St.Widget {
|
|||
}
|
||||
|
||||
_windowAdded(metaWorkspace, metaWin) {
|
||||
if (!Main.overview.closing)
|
||||
this._doAddWindow(metaWin);
|
||||
let win = metaWin.get_compositor_private();
|
||||
|
||||
if (!win) {
|
||||
// Newly-created windows are added to a workspace before
|
||||
// the compositor finds out about them...
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
if (metaWin.get_compositor_private() &&
|
||||
metaWin.get_workspace() === this.metaWorkspace)
|
||||
this._windowAdded(metaWin);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] this._windowAdded');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._isMyWindow(metaWin))
|
||||
return;
|
||||
|
||||
if (!Main.overview.closing) {
|
||||
if (metaWin.windowType === Meta.WindowType.DESKTOP)
|
||||
this._addDesktopClone(metaWin);
|
||||
else
|
||||
this._doAddWindow(metaWin);
|
||||
this._addPropertyMonitoringSignals(metaWin);
|
||||
}
|
||||
}
|
||||
|
||||
_windowRemoved(metaWorkspace, metaWin) {
|
||||
this._doRemoveWindow(metaWin);
|
||||
if (this._isOverviewWindow(metaWin))
|
||||
this._doRemoveWindow(metaWin);
|
||||
else if (metaWin.windowType === Meta.WindowType.DESKTOP)
|
||||
this._removeDesktopClone(metaWin);
|
||||
}
|
||||
|
||||
_windowEnteredMonitor(metaDisplay, monitorIndex, metaWin) {
|
||||
if (monitorIndex === this.monitorIndex && !Main.overview.closing)
|
||||
this._doAddWindow(metaWin);
|
||||
this._windowAdded(metaWin);
|
||||
}
|
||||
|
||||
_windowLeftMonitor(metaDisplay, monitorIndex, metaWin) {
|
||||
if (monitorIndex === this.monitorIndex)
|
||||
this._doRemoveWindow(metaWin);
|
||||
this._windowRemoved(metaWin);
|
||||
}
|
||||
|
||||
// check for maximized windows on the workspace
|
||||
|
|
@ -1344,10 +1384,13 @@ class Workspace extends St.Widget {
|
|||
return false;
|
||||
}
|
||||
|
||||
_clearSkipTaskbarSignals() {
|
||||
_clearPropertyMonitoringSignals() {
|
||||
for (const [metaWin, id] of this._skipTaskbarSignals)
|
||||
metaWin.disconnect(id);
|
||||
this._skipTaskbarSignals.clear();
|
||||
for (const [metaWin, id] of this._desktopWindowsSignals)
|
||||
metaWin.disconnect(id);
|
||||
this._desktopWindowsSignals.clear();
|
||||
}
|
||||
|
||||
prepareToLeaveOverview() {
|
||||
|
|
@ -1367,7 +1410,7 @@ class Workspace extends St.Widget {
|
|||
}
|
||||
|
||||
_onDestroy() {
|
||||
this._clearSkipTaskbarSignals();
|
||||
this._clearPropertyMonitoringSignals();
|
||||
|
||||
if (this._layoutFrozenId > 0) {
|
||||
GLib.source_remove(this._layoutFrozenId);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue