This project is an application switcher in a similar vein to cmd+tab. I may write a more detailed post later on.
Demo video (youtube): http://youtu.be/VHy3NXrRiLk
Following from in-game item/weapon/power-up switchers I decided to give this a shot, and I’m fairly happy with the result. There are a lot of bits and pieces where, if I had the time, I would be swift to remove; for example the custom window and custom view are not needed.
Initially I was fond of using it, but after a while I felt the ‘excitement’ of it dropped quite a lot and I preferred just using cmd+tab. On the positive side it has customisation potential with ring ‘themes’ where every graphic could be customised; given time I would have loved to do something similar to Bowtie. Also, if I am working with the same few apps for a while it is easy to memorise the app position about the ring and instantly switch to the app.
A long while ago I needed a small outlet to keep me programming, and since there is nothing I felt I needed I tried to just make something slightly different. This is the result.
Stumbling on a geektool script a while ago encouraged me to tinker with Spotify’s applescript interface - where I thought I might find some options that would have been useful to push Spotify Menubar further (for times when I might want to change it). Here is what Spotify’s applescript suite offers:
image data n : Image data in TIFF format.
sound volume (integer) : The sound output volume (0 = min, 100 = max).
player state (stopped/playing/paused, r/o) : Is Spotify stopped, paused, or playing?
player position (real) : The Player’s position within the currently playing track in seconds.
next track : Skip to the next track.
previous track : Skip to the previous track.
playpause : Toggle play/pause.
pause : Pause playback.
play : Resume playback.
current track (track, r/o) : The currently playing track.
Properties of the current track
artist (text, r/o) : The artist of the track.
album (text, r/o) : The album of the track.
disc number (integer, r/o) : The length of the track in seconds.
duration (integer, r/o) : The length of the track in seconds.
played count (integer, r/o) : The number of times this track has been played.
track number (integer, r/o) : The index of the track in its album.
starred (boolean, r/o) : Is the track starred?
popularity (integer, r/o) : How popular is this track? 0-100
id (text, r/o) : The ID of the item.
name (text, r/o) : The name of the track.
artwork (image data, r/o) : The track’s album cover.
album artist (text, r/o) : The album artist of the track.
spotify url (text) : The URL of the track.
Most, if not all, of the info here is useful, though I would like to see the ability to write the starred status of a track (r/o means read only, afaik).
With NSApplescript it is easy to take advantage of the applescript properties and use them in a cocoa-based app. Though what is offered is mostly read only, except player position and volume. A simple implementation to illustrate this (by getting the currently playing track name):
NSString *scriptString = @”tell application “Spotify”\n set output to name of current track\n end tell”;
NSAppleScript *script = [[NSAppleScript alloc] initWithSource: scriptString];
NSAppleEventDescriptor *returnData = [script executeAndReturnError:nil];
NSLog([output stringValue]);
Though in hindsight I would have enjoyed playing with this, I only needed the global hotkeys and not the information. After playing about there’s nothing I would really change in Spotify Menubar. Considering Bowtie, Airfoil and Take Five will be working with Spotify, I will probably be using them if I use Spotify.
Update:
I was asked how to write the image data to a file. This is how I might go about it:
NSString *scriptString = @”tell application "Spotify"\n set image_data to artwork of current track\n end tell\n image_data”;
NSAppleScript *script = [[NSAppleScript alloc] initWithSource: scriptString];
NSAppleEventDescriptor *returnData = [script executeAndReturnError: nil];
[[returnData data] writeToFile:@”/Users/<Your Username>/Desktop/artwork.tiff” atomically:NO];
Replacing <Your Username> with your actual username.
(Revised)
Unfortunately I couldn’t find the time to fix Xbox Live Friends (XLF) for the latest website changes. Given time this is the direction I imaged it going:
- Split the core into a front- and back-end.
- Touch up the GUI to take advantage of Lion.
The front-end would handle the delivery of all the content. While the back-end would handle the communication with the Xbox Live website (signing in/out, fetching/sending content, etc.). Only the back-end would need to be updated to cope with changes to the website.
I underestimated the time I needed and, having not used Xbox Live in a long time, I have lost some passion for the content. Though I left it slightly messy, if someone wants to continue my fork is there. The original source is still available too.
This post covers the final commit (or final planned commit) to Spotify Menubar.
Added
- Play/Pause and skip buttons embedded in the menubar.
- SIMBL plugin for seamless global shortcuts.
Removed
- Opening Spotify on launch.
- Opening Spotify on keybind trigger.
- Opening Spotify Menubar at login.
- Updating
Changed
- Preferences are now inline with the rest of the apps out there (using a toolbar).
- It should not be possible to have the menubar icon and the dock icon hidden at the same time.
The preferences were somewhat hideous and for such a simple app there was too much going on in one preference window, switching to the toolbar look just looks better. With the addition of the mini controls in the menubar I can’t see why the process would be running without either the regular menubar icon, the mini controls or the dock icon visible. Right-clicking any of the mini controls should bring up the regular menubar menu.
I initially used small version of Spotify’s play/pause and skip buttons, but they looked wrong in the menubar. I have borrowed the menubar icons from the Menubar Icon Pack by iAndrew which look pretty sleek!
Regarding the requests to remove the app from both the menubar and the dock, I’ve created a simple SIMBL plugin that reads the shortcuts from SM’s preferences to create global shortcuts. It actually works really well and if SM hasn’t been launched before then I just assign the default global keys I use in SM anyway (alt+shift+<key>).
To quickly explain the features removed:
- Opening Spotify on launch doesn’t seem necessary at all. Spotify is likely either already open or could be opened itself instead of launching SM.
- Opening Spotify on keybind trigger is pretty much the same idea. Again, Spotify is likely already open, or could be opened manually. There are many apps that let you efficiently open Spotify if productivity is your thing (Alfred, Quicksilver, etc).
- Realistically, I don’t want SM to open at login for me. If I have the SIMBL plugin installed then I will not be opening SM much at all (unless for the menubar controls).
- Since I did not need to actively update the app and will not be doing so in the future the feature for updating pretty much didn’t get used. I’ve left the code and framework to do so, but it is just another button that is not used.
All of these were really just inconvenient conveniences, where really there are better options for all of these (except updating).
I felt the need not to include some form of hovering controls like the space switcher in Hyperspaces that shows/hides the switcher at the mouse position just because it seemed to contrast the need for global shortcuts. Though it would be a sweet feature, it really comes down to the time I’m willing to spend on SM (which is not a lot anymore).
With all of this: the menubar controls, SIMBL plugin and simplified preferences I feel I’m leaving SM in a fairly fine state. If I was starting the project now, the code would be much tidier: pretty much all the code in one file is a disaster, haha. It still serves the one purpose I had intended for it, global shortcuts, and it does so with minimal intrusion to the user. The menubar controls are simple, the SIMBL plugin is easy to use and it has been an interesting wee project to develop.