Skip to content

Instantly share code, notes, and snippets.

@Moon-0xff
Created February 28, 2023 08:51
Show Gist options
  • Save Moon-0xff/e7fd402033b66ffebaa4edb4c2d16a88 to your computer and use it in GitHub Desktop.
Save Moon-0xff/e7fd402033b66ffebaa4edb4c2d16a88 to your computer and use it in GitHub Desktop.
apply with $ patch < diff.diff
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0e64314..ff7d8ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,3 +29,4 @@ Aditionally:
- Improves filtering
- Increases the chance of finding the application icon
- Adds bindable mouse controls
+- Improves performance (refresh time down from 6-7ms to >1ms)
diff --git a/extension.js b/extension.js
index 432b243..ebabf88 100644
--- a/extension.js
+++ b/extension.js
@@ -158,6 +158,7 @@ class MprisLabel extends PanelMenu.Button {
break;
case 'next-player':
this.player = this.players.next();
+ this._refresh();
break;
}
}
diff --git a/players.js b/players.js
index 0093d5a..01eb6c2 100644
--- a/players.js
+++ b/players.js
@@ -15,6 +15,7 @@ const mprisInterface = `
<property name="Metadata" type="a{sv}" access="read"/>
<property name="PlaybackStatus" type="s" access="read"/>
</interface>
+
</node>`
const entryInterface = `
@@ -31,6 +32,11 @@ const dBusInterface = `
<method name="ListNames">
<arg direction="out" type="as"/>
</method>
+ <signal name="NameOwnerChanged">
+ <arg direction="out" type="s"/>
+ <arg direction="out" type="s"/>
+ <arg direction="out" type="s"/>
+ </signal>
</interface>
</node>`
@@ -38,15 +44,13 @@ var Players = class Players {
constructor(){
this.list = [];
const dBusProxyWrapper = Gio.DBusProxy.makeProxyWrapper(dBusInterface);
- this.dBusProxy = dBusProxyWrapper(Gio.DBus.session,"org.freedesktop.DBus","/org/freedesktop/DBus");
+ this.dBusProxy = dBusProxyWrapper(Gio.DBus.session,"org.freedesktop.DBus","/org/freedesktop/DBus",this._initList.bind(this));
this.settings = ExtensionUtils.getSettings('org.gnome.shell.extensions.mpris-label');
}
pick(){
const REMOVE_TEXT_WHEN_PAUSED = this.settings.get_boolean('remove-text-when-paused');
const AUTO_SWITCH_TO_MOST_RECENT = this.settings.get_boolean('auto-switch-to-most-recent');
- this._updateList();
-
if(this.list.length == 0){
this.selected = null;
return this.selected
@@ -81,8 +85,6 @@ var Players = class Players {
next(){
const AUTO_SWITCH_TO_MOST_RECENT = this.settings.get_boolean('auto-switch-to-most-recent');
- this._updateList();
-
let list = this.list;
if(AUTO_SWITCH_TO_MOST_RECENT)
@@ -104,59 +106,89 @@ var Players = class Players {
return this.selected
}
- _updateList(){
+ _initList(){
+ log("initList");
let dBusList = this.dBusProxy.ListNamesSync()[0];
dBusList = dBusList.filter(element => element.startsWith("org.mpris.MediaPlayer2"));
- const SOURCES_BLACKLIST = this.settings.get_string('mpris-sources-blacklist');
- const SOURCES_WHITELIST = this.settings.get_string('mpris-sources-whitelist');
-
- if(SOURCES_BLACKLIST || SOURCES_WHITELIST){
- let USE_WHITELIST = this.settings.get_boolean('use-whitelisted-sources-only');
- if(SOURCES_BLACKLIST && USE_WHITELIST && !SOURCES_WHITELIST)
- USE_WHITELIST = false;
+ this.unfilteredList = [];
+ dBusList.forEach(address => this.unfilteredList.push(new Player(address)));
- const blacklist = SOURCES_BLACKLIST.toLowerCase().replaceAll(' ','').split(',');
- const whitelist = SOURCES_WHITELIST.toLowerCase().replaceAll(' ','').split(',');
+ this.unfilteredList.forEach(player => {
+ player.connect('closed',() => {
+ this.unfilteredList.delete(player);
+ });
+ player.connect('notify::playbackStatus'() => {
+ this.activePlayers = this.list.filter(player => player.playbackStatus == "Playing");
+ });
+ });
- let entryWrapper = Gio.DBusProxy.makeProxyWrapper(entryInterface);
- dBusList = dBusList.filter(function(element){
- let entryProxy = entryWrapper(Gio.DBus.session,element,"/org/mpris/MediaPlayer2");
- let identity = entryProxy.Identity.replace(' ','').toLowerCase();
- if (blacklist.includes(identity) || (!whitelist.includes(identity) && USE_WHITELIST))
- return false
+ this.dBusProxy.connectSignal('NameOwnerChanged',this._addPlayer.bind(this));
- return true
+ this._updateList();
+ }
+ _addPlayer(proxy, sender, [name,oldOwner,newOwner]){
+ if(name.startsWith("org.mpris.MediaPlayer2") && (newOwner && !oldOwner)){
+ log(name);
+ let player = new Player(name);
+ player.connect('closed',() => {
+ this.unfilteredList.delete(player);
});
+ player.connect('notify::playbackStatus'() => {
+ this.activePlayers = this.list.filter(player => player.playbackStatus == "Playing");
+ });
+ this.unfilteredList.push(player);
+ log("added player:" + name);
+
+ this._updateList();
}
+ }
+ _updateList(){
+ log("updateList");
+ const SOURCES_BLACKLIST = this.settings.get_string('mpris-sources-blacklist');
+ const SOURCES_WHITELIST = this.settings.get_string('mpris-sources-whitelist');
+ let USE_WHITELIST = this.settings.get_boolean('use-whitelisted-sources-only');
- this.list = this.list.filter(element => dBusList.includes(element.address));
+ if(!SOURCES_BLACKLIST || !SOURCES_WHITELIST)
+ this.list = this.unfilteredList;
- let addresses = [];
- this.list.forEach(element => {
- addresses.push(element.address);
- });
+ const blacklist = SOURCES_BLACKLIST.toLowerCase().replaceAll(' ','').split(',');
+ const whitelist = SOURCES_WHITELIST.toLowerCase().replaceAll(' ','').split(',');
- let newPlayers = dBusList.filter(element => !addresses.includes(element));
- newPlayers.forEach(element => this.list.push(new Player(element)));
+ if(USE_WHITELIST && SOURCES_WHITELIST)
+ this.list = this.unfilteredList.filter(element => whitelist.includes(element));
- this.activePlayers = this.list.filter(element => element.playbackStatus == "Playing")
+ if(!USE_WHITELIST && SOURCES_BLACKLIST)
+ this.list = this.unfilteredList.filter(element => !blacklist.includes(element));
+
+ log(this.list);
+
+
+ log(this.activePlayers);
}
}
-class Player {
- constructor(address){
+let Player = GObject.registerClass(
+ { GTypeName: 'MprisLabel_Player', Signals: { 'closed': {} } },
+class Player extends GObject.Object {
+ _init(address){
this.address = address;
this.statusTimestamp = new Date().getTime();
const proxyWrapper = Gio.DBusProxy.makeProxyWrapper(mprisInterface);
this.proxy = proxyWrapper(Gio.DBus.session,this.address, "/org/mpris/MediaPlayer2",this.update.bind(this));
this.proxy.connect('g-properties-changed', this.update.bind(this));
+ this.proxy.connect('notify::g-name-owner', () => {
+ this.emit('closed');
+ });
- let entryWrapper = Gio.DBusProxy.makeProxyWrapper(entryInterface);
- let entryProxy = entryWrapper(Gio.DBus.session,this.address,"/org/mpris/MediaPlayer2");
- this.identity = entryProxy.Identity;
- this.desktopEntry = entryProxy.DesktopEntry;
+ const entryWrapper = Gio.DBusProxy.makeProxyWrapper(entryInterface);
+ this.entryProxy = entryWrapper(Gio.DBus.session,this.address, "/org/mpris/MediaPlayer2",this._getIdentity.bind(this));
+
+ }
+ _getIdentity(){
+ this.identity = this.entryProxy.Identity;
+ this.desktopEntry = this.entryProxy.DesktopEntry;
this.desktopApp = null;
let matchedEntries = [];
@@ -164,10 +196,10 @@ class Player {
matchedEntries = Gio.DesktopAppInfo.search(this.identity);
if ( matchedEntries.length === 0 && !(this.desktopEntry == null | undefined) )//backup method using DesktopEntry info
- matchedEntries = Gio.DesktopAppInfo.search(this.desktopEntry)
+ matchedEntries = Gio.DesktopAppInfo.search(this.desktopEntry);
if ( matchedEntries.length > 0 )
- this.desktopApp = matchedEntries[0][0]
+ this.desktopApp = matchedEntries[0][0];
this.icon = this.getIcon(this.desktopApp);
}
@@ -221,5 +253,5 @@ class Player {
if (this.proxy.CanGoPrevious)
this.proxy.PreviousRemote()
}
-}
+});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment