Codebase list gnome-shell-extensions / 2d3307c
window-list: Use InjectionManager instead of custom classes Once the shell is ported to ESM, it will no longer be possible to replace entire classes (even when imported). Prepare for that by overriding methods of the regular WorkspaceBackground class instead. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/268> Florian Müllner 9 months ago
1 changed file(s) with 65 addition(s) and 71 deletion(s). Raw diff Collapse all Expand all
22 import Shell from 'gi://Shell';
33 import St from 'gi://St';
44
5 import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
5 import {Extension, InjectionManager} from 'resource:///org/gnome/shell/extensions/extension.js';
66
77 const Layout = imports.ui.layout;
88 const Main = imports.ui.main;
7676 }
7777 }
7878
79 class MyWorkspace extends Workspace.Workspace {
80 static {
81 GObject.registerClass(this);
82 }
83
84 constructor(...args) {
85 super(...args);
86
87 this._overviewAdjustment.connectObject('notify::value', () => {
88 const {value: progress} = this._overviewAdjustment;
89 const brightness = 1 - (1 - VIGNETTE_BRIGHTNESS) * progress;
90 for (const bg of this._background?._backgroundGroup ?? []) {
91 bg.content.set({
92 vignette: true,
93 brightness,
94 });
95 }
96 }, this);
97 }
98 }
99
100 class MyWorkspaceBackground extends Workspace.WorkspaceBackground {
101 static {
102 GObject.registerClass(this);
103 }
104
105 _updateBorderRadius() {
106 }
107
108 vfunc_allocate(box) {
109 this.set_allocation(box);
110
111 const themeNode = this.get_theme_node();
112 const contentBox = themeNode.get_content_box(box);
113
114 this._bin.allocate(contentBox);
115
116 const [contentWidth, contentHeight] = contentBox.get_size();
117 const monitor = Main.layoutManager.monitors[this._monitorIndex];
118 const xRatio = contentWidth / this._workarea.width;
119 const yRatio = contentHeight / this._workarea.height;
120
121 const right = area => area.x + area.width;
122 const bottom = area => area.y + area.height;
123
124 const offsets = {
125 left: xRatio * (this._workarea.x - monitor.x),
126 right: xRatio * (right(monitor) - right(this._workarea)),
127 top: yRatio * (this._workarea.y - monitor.y),
128 bottom: yRatio * (bottom(monitor) - bottom(this._workarea)),
129 };
130
131 contentBox.set_origin(-offsets.left, -offsets.top);
132 contentBox.set_size(
133 offsets.left + contentWidth + offsets.right,
134 offsets.top + contentHeight + offsets.bottom);
135 this._backgroundGroup.allocate(contentBox);
136 }
137 }
138
13979 export class WindowPicker extends Clutter.Actor {
14080 static [GObject.signals] = {
14181 'open-state-changed': {param_types: [GObject.TYPE_BOOLEAN]},
15595
15696 this._adjustment = new OverviewAdjustment(this);
15797
98 this._injectionManager = new InjectionManager();
15899 this.connect('destroy', this._onDestroy.bind(this));
159100
160101 global.bind_property('screen-width',
182123 }
183124
184125 _injectBackgroundShade() {
185 this._origWorkspace = Workspace.Workspace;
186 this._origWorkspaceBackground = Workspace.WorkspaceBackground;
187
188 Workspace.Workspace = MyWorkspace;
189 Workspace.WorkspaceBackground = MyWorkspaceBackground;
126 const backgroundProto = Workspace.WorkspaceBackground.prototype;
127 this._injectionManager.overrideMethod(backgroundProto, '_updateBorderRadius',
128 () => {
129 return function () {};
130 });
131 this._injectionManager.overrideMethod(backgroundProto, 'vfunc_allocate',
132 () => {
133 /* eslint-disable no-invalid-this */
134 return function (box) {
135 this.set_allocation(box);
136
137 const themeNode = this.get_theme_node();
138 const contentBox = themeNode.get_content_box(box);
139
140 this._bin.allocate(contentBox);
141
142 const [contentWidth, contentHeight] = contentBox.get_size();
143 const monitor = Main.layoutManager.monitors[this._monitorIndex];
144 const xRatio = contentWidth / this._workarea.width;
145 const yRatio = contentHeight / this._workarea.height;
146
147 const right = area => area.x + area.width;
148 const bottom = area => area.y + area.height;
149
150 const offsets = {
151 left: xRatio * (this._workarea.x - monitor.x),
152 right: xRatio * (right(monitor) - right(this._workarea)),
153 top: yRatio * (this._workarea.y - monitor.y),
154 bottom: yRatio * (bottom(monitor) - bottom(this._workarea)),
155 };
156
157 contentBox.set_origin(-offsets.left, -offsets.top);
158 contentBox.set_size(
159 offsets.left + contentWidth + offsets.right,
160 offsets.top + contentHeight + offsets.bottom);
161 this._backgroundGroup.allocate(contentBox);
162 };
163 /* eslint-enable */
164 });
165 this._injectionManager.overrideMethod(backgroundProto, 'vfunc_parent_set',
166 () => {
167 /* eslint-disable no-invalid-this */
168 return function () {
169 setTimeout(() => {
170 const parent = this.get_parent();
171 if (!parent)
172 return;
173
174 parent._overviewAdjustment.connectObject('notify::value', () => {
175 const {value: progress} = parent._overviewAdjustment;
176 const brightness = 1 - (1 - VIGNETTE_BRIGHTNESS) * progress;
177 for (const bg of this._backgroundGroup ?? []) {
178 bg.content.set({
179 vignette: true,
180 brightness,
181 });
182 }
183 }, this);
184 });
185 };
186 /* eslint-enable */
187 });
190188 }
191189
192190 get visible() {
292290 }
293291
294292 _onDestroy() {
295 if (this._origWorkspace)
296 Workspace.Workspace = this._origWorkspace;
297
298 if (this._origWorkspaceBackground)
299 Workspace.WorkspaceBackground = this._origWorkspaceBackground;
293 this._injectionManager.clear();
300294
301295 if (this._stageKeyPressId)
302296 global.stage.disconnect(this._stageKeyPressId);