Closed Batwam closed 1 year ago
It's a shame we can't run forEach backwards!
We can by chaining it with reverse()
but i don't think we should do that.
for
loops are unnecessarily verbose and except in rare occasions javascript grants us a more easier to read alternative.
Instead of working around the limitations of forEach
we should use another of those alternatives, this is written in the docs:
There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool.
Early termination may be accomplished with looping statements like for, for...of, and for...in. Array methods like every(), some(), find(), and findIndex() also stops iteration immediately when further iteration is not necessary.
Ok, it looks like .find()
might be the way to go.
See proposed implementation using .find()
.
Note that I have left the matchedEntries[0]
fallback but I'm not convinced it is necessary (or preferable) to show the icon of an app which isn't running as it's quite likely to be an incorrect icon. I would personnally prefer returning undefined
and let the extension return the default icon so we know the app wasn't found.
Maybe it's more likely that _matchRunningApps
fails than matchedEntries[0]
is a wrong icon. I really don't know but we didn't crosscheck with running apps until recently and since #27 the only issues with icons so far has been #33
yeah, _matchRunningApps
is the function we worked on recently in #29 . The objective was to fix the function for Firefox and Rhythmbox which return multiple results and matchedEntries[0][1]
(and not matchedEntries[0][0]
) was actually the correct one. The .desktop
is then used to identify the correct icon and player to activate so we need to make sure this is robust.
Turns out we (I) overlooked the unlikely case where different apps are returned in matchedEntries
and both are open. This PR should solve this and make the function more robust.
If we keep the matchedEntries[0]
, it will most likely return something but if we get to this point of the code, it means that it corresponds to an app which isn't currently running and therefore unlikely to be the correct one. If we delete the fallback, this.desktopApp
will be undefined
. The extension will show the default icon and activatePlayer
won't do anything but that's about it. I don't think that desktopApp
is used anywhere else in the extension.
Anyway, that's more of a general design philosophy decision regarding whether it's best to return something or leave the extension show that something fails (having made sure it doesn't crash). Let me know how you want to proceed. Either way, I believe that the original issue with Spot is now fixed without affecting the Firefox/Rhythmbox fix from #29.
You almost convinced me, it's a pretty interesting design choice, but we can also raise a more explicit signal that something doesn't work with the OSD window manager, and we have been lucky getting correct icons from matchedEntries[0]
It all comes down as how likely is _matchRunningApps
to fail vs how likely is matchedEntries[0]
to deliver the wrong icon, and we don't know the answer of that.
no worries. Regarding the last point, we know from #29 that Firefox and Rhythmobx have 100% chance of returning the wrong .desktop (on my system). I am not aware of any case where _matchRunningApps
would fail, but I also didn't foresee this Spot situation.
I guess worst case scenario would be one where both _matchRunningApps
&& matchedEntries[0]
fail which should be pretty remote as it would be essentially a situation were the Seach returns a completely incorrect app or the identity
field isn't populated correctly by the source (e.g. some Browser identifies as Chrome) but we haven't seen this happen (yet).
With regards to issue #33, upon further inspect, due to the inability of the forEach to exit on match, the icon is set based on the last match.
In the case of Spot, if Spotify is open (unlikely by ok...), we get to a situation where
matchedEntries: dev.alextren.Spot.desktop,com.spotify.Client.desktop
which are both open apps. When we get to_matchRunningApps()
, this the first entry matches a running app but so does the second one which is taken as the correct result.We could use a
for
loop with a return instead. In this commit, I have instead implemented amatchFound
flag so when a match is found, no other match is saved. This successfully fixes the issue and on the basis thatmatchedEntries
are already ordered but Gnome in order of probability, I believe that it is fair to prioritise the first match.I don' t believe that this introduces any regression but do let me know if you have any comment. It's a shame we can't run forEach backwards!