[gnome] Update extensions
This commit is contained in:
@ -37,6 +37,7 @@ Gio._promisify(GdkPixbuf.Pixbuf, 'get_file_info_async');
|
||||
Gio._promisify(GdkPixbuf.Pixbuf, 'new_from_stream_at_scale_async',
|
||||
'new_from_stream_finish');
|
||||
Gio._promisify(St.IconInfo.prototype, 'load_symbolic_async');
|
||||
Gio._promisify(Gio.DBusConnection.prototype, 'call');
|
||||
|
||||
const MAX_UPDATE_FREQUENCY = 30; // In ms
|
||||
const FALLBACK_ICON_NAME = 'image-loading-symbolic';
|
||||
@ -199,10 +200,10 @@ class AppIndicatorProxy extends DBusProxy {
|
||||
}));
|
||||
}
|
||||
|
||||
_onSignal(...args) {
|
||||
this._onSignalAsync(...args).catch(e => {
|
||||
_onSignal(sender, signal, ...args) {
|
||||
this._onSignalAsync(sender, signal, ...args).catch(e => {
|
||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
logError(e);
|
||||
logError(e, `Error while processing signal '${signal}'`);
|
||||
});
|
||||
}
|
||||
|
||||
@ -311,7 +312,10 @@ class AppIndicatorProxy extends DBusProxy {
|
||||
} catch (e) {
|
||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
||||
// the property may not even exist, silently ignore it
|
||||
Util.Logger.debug(`While refreshing property ${propertyName}: ${e}`);
|
||||
Util.Logger.debug(`Error when calling 'Get(${propertyName})' ` +
|
||||
`in ${this.gName}, ${this.gObjectPath}, ` +
|
||||
`org.freedesktop.DBus.Properties, ${this.gInterfaceName} ` +
|
||||
`while refreshing property ${propertyName}: ${e}`);
|
||||
this.set_cached_property(propertyName, null);
|
||||
this._cancellables.delete(propertyName);
|
||||
delete this._changedProperties[propertyName];
|
||||
@ -435,6 +439,25 @@ export class AppIndicator extends Signals.EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
// We try to lookup the activate method to see if the app supports it
|
||||
try {
|
||||
const introspectionVariant = await this._proxy.gConnection.call(
|
||||
this._proxy.gNameOwner, this._proxy.gObjectPath,
|
||||
'org.freedesktop.DBus.Introspectable', 'Introspect', null, null,
|
||||
Gio.DBusCallFlags.NONE, -1, cancellable);
|
||||
const [introspectionXml] = introspectionVariant.deep_unpack();
|
||||
const nodeInfo = Gio.DBusNodeInfo.new_for_xml(introspectionXml);
|
||||
const interfaceInfo = nodeInfo.lookup_interface(this._proxy.gInterfaceName);
|
||||
this.supportsActivation = !!interfaceInfo.lookup_method('Activate');
|
||||
this._hasAyatanaSecondaryActivate =
|
||||
!!interfaceInfo.lookup_method('XAyatanaSecondaryActivate');
|
||||
} catch (e) {
|
||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
||||
Util.Logger.debug(
|
||||
`${this.uniqueId}, check for Activation support: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
this._commandLine = await Util.getProcessName(this.busName,
|
||||
cancellable, GLib.PRIORITY_LOW);
|
||||
|
||||
@ -130,6 +130,11 @@ export class DbusMenuItem extends Signals.EventEmitter {
|
||||
this.emit('property-changed', prop, this.propertyGetVariant(prop));
|
||||
}
|
||||
|
||||
resetProperties() {
|
||||
Object.entries(PropertyStore.DefaultValues).forEach(([prop, value]) =>
|
||||
this.propertySet(prop, value));
|
||||
}
|
||||
|
||||
getChildrenIds() {
|
||||
return this._children_ids.concat(); // clone it!
|
||||
}
|
||||
@ -297,6 +302,8 @@ export const DBusClient = GObject.registerClass({
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
item.resetProperties();
|
||||
|
||||
for (const [prop, value] of Object.entries(properties))
|
||||
item.propertySet(prop, value);
|
||||
});
|
||||
@ -495,6 +502,9 @@ export const DBusClient = GObject.registerClass({
|
||||
|
||||
// we don't need to cache and burst-send that since it will not happen that frequently
|
||||
async sendAboutToShow(id) {
|
||||
if (this._hasAboutToShow === false)
|
||||
return;
|
||||
|
||||
/* Some indicators (you, dropbox!) don't use the right signature
|
||||
* and don't return a boolean, so we need to support both cases */
|
||||
try {
|
||||
@ -507,6 +517,13 @@ export const DBusClient = GObject.registerClass({
|
||||
ret.is_of_type(new GLib.VariantType('()')))
|
||||
this._requestLayoutUpdate();
|
||||
} catch (e) {
|
||||
Util.Logger.debug('Error when calling \'AboutToShow()\' in ' +
|
||||
`${this.gName}, ${this.gObjectPath}, ${this.gInterfaceName}`);
|
||||
if (e.matches(Gio.DBusError, Gio.DBusError.UNKNOWN_METHOD) ||
|
||||
e.matches(Gio.DBusError, Gio.DBusError.FAILED)) {
|
||||
this._hasAboutToShow = false;
|
||||
return;
|
||||
}
|
||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
logError(e);
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ import * as TrayIconsManager from './trayIconsManager.js';
|
||||
import * as Util from './util.js';
|
||||
import {SettingsManager} from './settingsManager.js';
|
||||
|
||||
export default class DashToDockExtension extends Extension.Extension {
|
||||
export default class AppIndicatorExtension extends Extension.Extension {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ export class IconCache {
|
||||
}
|
||||
|
||||
const oldIcon = this._cache.get(id);
|
||||
if (!oldIcon || !oldIcon.equals(icon)) {
|
||||
if (!oldIcon || !oldIcon.equal(icon)) {
|
||||
Util.Logger.debug(`IconCache: adding ${id}: ${icon}`);
|
||||
this._cache.set(id, icon);
|
||||
} else {
|
||||
|
||||
@ -276,15 +276,15 @@ class IndicatorStatusIcon extends BaseStatusIcon {
|
||||
yAlign: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
this._label = new St.Label();
|
||||
this._labelBin.add_actor(this._label);
|
||||
this._box.add_actor(this._labelBin);
|
||||
Util.addActor(this._labelBin, this._label);
|
||||
Util.addActor(this._box, this._labelBin);
|
||||
}
|
||||
this._label.set_text(label);
|
||||
if (!this._box.contains(this._labelBin))
|
||||
this._box.add_actor(this._labelBin); // FIXME: why is it suddenly necessary?
|
||||
Util.addActor(this._box, this._labelBin); // FIXME: why is it suddenly necessary?
|
||||
} else if (this._label) {
|
||||
this._labelBin.destroy_all_children();
|
||||
this._box.remove_actor(this._labelBin);
|
||||
Util.removeActor(this._box, this._labelBin);
|
||||
this._labelBin.destroy();
|
||||
delete this._labelBin;
|
||||
delete this._label;
|
||||
@ -420,13 +420,6 @@ class IndicatorStatusIcon extends BaseStatusIcon {
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
vfunc_button_release_event(event) {
|
||||
if (!this._indicator.supportsActivation)
|
||||
return this._maybeHandleDoubleClick(event);
|
||||
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
vfunc_scroll_event(event) {
|
||||
// Since Clutter 1.10, clutter will always send a smooth scrolling event
|
||||
// with explicit deltas, no matter what input device is used
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -5,9 +5,11 @@
|
||||
"name": "AppIndicator and KStatusNotifierItem Support",
|
||||
"settings-schema": "org.gnome.shell.extensions.appindicator",
|
||||
"shell-version": [
|
||||
"45"
|
||||
"45",
|
||||
"46",
|
||||
"47"
|
||||
],
|
||||
"url": "https://github.com/ubuntu/gnome-shell-extension-appindicator",
|
||||
"uuid": "appindicatorsupport@rgcjonas.gmail.com",
|
||||
"version": 57
|
||||
"version": 59
|
||||
}
|
||||
@ -45,6 +45,19 @@ export class TrayIconsManager extends Signals.EventEmitter {
|
||||
this._changedId = SettingsManager.getDefaultGSettings().connect(
|
||||
'changed::legacy-tray-enabled', () => this._toggle());
|
||||
|
||||
// On theme changed, need to update the bg color to match style,
|
||||
// This may not be required anymore on newer shell versions that use
|
||||
// ARGBA visuals.
|
||||
this._styleChangedID = Main.panel.connect('style-changed', () => {
|
||||
const panelBgColor = this._getPanelBgColor();
|
||||
const {bgColor} = this._tray ?? {bgColor: null};
|
||||
if (bgColor === panelBgColor || bgColor?.equal(panelBgColor))
|
||||
return;
|
||||
|
||||
this._disable();
|
||||
this._toggle();
|
||||
});
|
||||
|
||||
this._toggle();
|
||||
}
|
||||
|
||||
@ -55,11 +68,16 @@ export class TrayIconsManager extends Signals.EventEmitter {
|
||||
this._disable();
|
||||
}
|
||||
|
||||
_getPanelBgColor() {
|
||||
return Main.panel?.get_parent()
|
||||
? Main.panel.get_theme_node()?.get_background_color() : null;
|
||||
}
|
||||
|
||||
_enable() {
|
||||
if (this._tray)
|
||||
return;
|
||||
|
||||
this._tray = new Shell.TrayManager();
|
||||
this._tray = new Shell.TrayManager({bgColor: this._getPanelBgColor()});
|
||||
Util.connectSmart(this._tray, 'tray-icon-added', this, this.onTrayIconAdded);
|
||||
Util.connectSmart(this._tray, 'tray-icon-removed', this, this.onTrayIconRemoved);
|
||||
|
||||
@ -71,14 +89,8 @@ export class TrayIconsManager extends Signals.EventEmitter {
|
||||
return;
|
||||
|
||||
IndicatorStatusIcon.getTrayIcons().forEach(i => i.destroy());
|
||||
if (this._tray.unmanage_screen) {
|
||||
this._tray.unmanage_screen();
|
||||
this._tray = null;
|
||||
} else {
|
||||
// FIXME: This is very ugly, but it's needed by old shell versions
|
||||
this._tray = null;
|
||||
imports.system.gc(); // force finalizing tray to unmanage screen
|
||||
}
|
||||
this._tray.unmanage_screen();
|
||||
this._tray = null;
|
||||
}
|
||||
|
||||
onTrayIconAdded(_tray, icon) {
|
||||
@ -98,6 +110,7 @@ export class TrayIconsManager extends Signals.EventEmitter {
|
||||
destroy() {
|
||||
this.emit('destroy');
|
||||
SettingsManager.getDefaultGSettings().disconnect(this._changedId);
|
||||
Main.panel.disconnect(this._styleChangedID);
|
||||
this._disable();
|
||||
trayIconsManager = null;
|
||||
}
|
||||
|
||||
@ -19,8 +19,6 @@ import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import St from 'gi://St';
|
||||
|
||||
const ByteArray = imports.byteArray;
|
||||
|
||||
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
|
||||
import * as Config from 'resource:///org/gnome/shell/misc/config.js';
|
||||
import * as Signals from 'resource:///org/gnome/shell/misc/signals.js';
|
||||
@ -102,7 +100,8 @@ export async function getProcessName(connectionName, cancellable = null,
|
||||
const cmdFile = Gio.File.new_for_path(`/proc/${pid}/cmdline`);
|
||||
const inputStream = await cmdFile.read_async(priority, cancellable);
|
||||
const bytes = await inputStream.read_bytes_async(2048, priority, cancellable);
|
||||
return ByteArray.toString(bytes.toArray().map(v => !v ? 0x20 : v));
|
||||
const textDecoder = new TextDecoder();
|
||||
return textDecoder.decode(bytes.toArray().map(v => !v ? 0x20 : v));
|
||||
}
|
||||
|
||||
export async function* introspectBusObject(bus, name, cancellable,
|
||||
@ -376,6 +375,20 @@ export function tryCleanupOldIndicators() {
|
||||
new Set(indicators).forEach(i => i.destroy());
|
||||
}
|
||||
|
||||
export function addActor(obj, actor) {
|
||||
if (obj.add_actor)
|
||||
obj.add_actor(actor);
|
||||
else
|
||||
obj.add_child(actor);
|
||||
}
|
||||
|
||||
export function removeActor(obj, actor) {
|
||||
if (obj.remove_actor)
|
||||
obj.remove_actor(actor);
|
||||
else
|
||||
obj.remove_child(actor);
|
||||
}
|
||||
|
||||
export const CancellableChild = GObject.registerClass({
|
||||
Properties: {
|
||||
'parent': GObject.ParamSpec.object(
|
||||
|
||||
Reference in New Issue
Block a user