-
-
Save Moon-0xff/405e04dd247880452a594c15a38aed32 to your computer and use it in GitHub Desktop.
Some errors still, _buildMenu sometimes stops working but (looks like) almost finished
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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..0303960 100644 | |
--- a/extension.js | |
+++ b/extension.js | |
@@ -50,7 +50,6 @@ class MprisLabel extends PanelMenu.Button { | |
this.players = new Players(); | |
- this._buildMenu(); | |
this.connect('button-press-event',(_a, event) => this._onClick(event)); | |
this.settings.connect('changed::left-padding',this._onPaddingChanged.bind(this)); | |
@@ -158,6 +157,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..6f3dfff 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,22 +32,26 @@ 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>` | |
var Players = class Players { | |
constructor(){ | |
this.list = []; | |
+ this.activePlayers= []; | |
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 +86,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,48 +107,64 @@ var Players = class Players { | |
return this.selected | |
} | |
- _updateList(){ | |
+ _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('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._updateList.bind(this)); | |
+ this.settings.connect('changed::mpris-sources-blacklist',this._filterList.bind(this)); | |
+ this.settings.connect('changed::mpris-sources-whitelist',this._filterList.bind(this)); | |
+ this.settings.connect('changed::use-whitelisted-sources-only',this._filterList.bind(this)); | |
- return true | |
- }); | |
+ this._filterList(); | |
+ } | |
+ _updateList(proxy, sender, [name,oldOwner,newOwner]){ | |
+ if(name.startsWith("org.mpris.MediaPlayer2")){ | |
+ if(newOwner && !oldOwner){ //add player | |
+ let player = new Player(name); | |
+ player.connect('notify::playbackStatus',() => { | |
+ this.activePlayers = this.list.filter(player => player.playbackStatus == "Playing"); | |
+ }); | |
+ this.unfilteredList.push(player); | |
+ } | |
+ else if (!newOwner && oldOwner){ //delete player | |
+ this.unfilteredList = this.unfilteredList.filter(player => player.address != name); | |
+ } | |
+ this._filterList(); | |
} | |
+ } | |
+ _filterList(){ | |
+ 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)); | |
} | |
} | |
-class Player { | |
- constructor(address){ | |
+let Player = GObject.registerClass( | |
+ { GTypeName: 'MprisLabel_Player' }, | |
+class Player extends GObject.Object { | |
+ _init(address){ | |
this.address = address; | |
this.statusTimestamp = new Date().getTime(); | |
@@ -153,10 +172,13 @@ class Player { | |
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)); | |
- 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._onEntryProxyReady.bind(this)); | |
+ | |
+ } | |
+ _onEntryProxyReady(){ | |
+ this.identity = this.entryProxy.Identity; | |
+ this.desktopEntry = this.entryProxy.DesktopEntry; | |
this.desktopApp = null; | |
let matchedEntries = []; | |
@@ -164,10 +186,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 +243,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