injectionManager: Support overriding vfuncs

Overriding vfuncs can be useful, in particular when we convert
to ES modules, and exported symbols cannot easily be swapped out.

Adapt overrideMethod() to work correctly in that case as well.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2809>
This commit is contained in:
Florian Müllner
2023-07-22 18:44:08 +02:00
parent f70a75a905
commit a332771562
2 changed files with 57 additions and 2 deletions

View File

@ -1,3 +1,5 @@
const Gi = imports._gi;
import {ExtensionBase, GettextWrapper} from './sharedInternals.js';
const {extensionManager} = imports.ui.main;
@ -48,7 +50,7 @@ export class InjectionManager {
*/
overrideMethod(prototype, methodName, createOverrideFunc) {
const originalMethod = this._saveMethod(prototype, methodName);
prototype[methodName] = createOverrideFunc(originalMethod);
this._installMethod(prototype, methodName, createOverrideFunc(originalMethod));
}
/**
@ -66,7 +68,7 @@ export class InjectionManager {
if (originalMethod === undefined)
delete prototype[methodName];
else
prototype[methodName] = originalMethod;
this._installMethod(prototype, methodName, originalMethod);
savedProtoMethods.delete(methodName);
if (savedProtoMethods.size === 0)
@ -96,4 +98,13 @@ export class InjectionManager {
savedProtoMethods.set(methodName, originalMethod);
return originalMethod;
}
_installMethod(prototype, methodName, method) {
if (methodName.startsWith('vfunc_')) {
const giPrototype = prototype[Gi.gobject_prototype_symbol];
giPrototype[Gi.hook_up_vfunc_symbol](methodName.slice(6), method);
} else {
prototype[methodName] = method;
}
}
}