Radio Static

Remember when the preset buttons on car radios physically worked like radio buttons — one would be pushed in, and when you pressed a different one the previous one would pop back out? It’s been a long time since I was in a car with a radio like that.

The rest of this post has absolutely nothing to do with that paragraph. Except for talking about radio buttons.

The 0.1.5 release of Rhythmbox Applet added a rating feature. You could rate songs two ways: by clicking on a five-star display in the applet itself, or using the applet’s right-click menu (useful, for example, if you didn’t want the five-star display to appear).

The latter was implemented by six radio menu items, one for each possible rating (0 through 5). Since this is a GNOME panel applet, the applet doesn’t actually manage the menu itself. Instead, it feeds an XML file describing the menu, and the BonoboUI library handles the actual menu. As far as radio menu items are concerned, the applet can be informed when each of their states change, and can change the current selection by altering the states directly.

If you use Rhythmbox Applet, you may have noticed a bug where the currently playing song gets its rating set to 0 stars. It goes something like this:

  1. Start the applet.
  2. Start Rhythmbox.
  3. Start playing something.
  4. Right-click the applet to open the menu.

Regardless of what the song’s rating used to be, it will now be 0 stars! Oops! Yet, this only happens the first time the menu is shown. What’s the deal?

When a song starts playing, Rhythmbox Applet adjusts the five-star display and the menu to show the new song’s rating. For the menu, it sets the state of the corresponding item to “1″. Now, knowing how radio menu items behave, you would think that this would automatically set the state of the previously selected item to “0″, wouldn’t you?

You would, but you’d be wrong; this doesn’t happen if the menu has not yet been displayed! You end up with multiple radio menu items having their state set to “1″ simultaneously! (You can’t see this directly, but you can if you programmatically look at their states.) As soon as you display the menu, BonoboUI realizes something is amiss, and changes the states of all but the first selected radio menu item to “0″. Since the rating displayed when Rhythmbox Applet first starts is 0, this is what you end up with. And since the applet has no way of distinguishing this from the user selecting “rate song 0 starts” from the menu himself, the applet dutifully rates the song 0 stars.

(Actually, BonoboUI’s behavior here is a bit more complicated: upon opening the menu for the first time, it acts as though the user individually selects each of the item whose state is “1″, in order from last to first. So, if items 0, 2, 3, and 5 had been set to “1″, BonoboUI would act like the user selected 5, then selected 3, then selected 2, and finally selected 0. In the process, all but the last one in the sequence gets its state “corrected” to “0″.)

The solution? Rhythmbox Applet has to explicitly set the state of the previously selected radio menu item to “0″. It seems like an unnecessary thing to do — and there’s a nice big comment in the code explaining why that piece is there — but it turns out to in fact be needed.

The moral? Sometimes, radio menu items aren’t.

Comments are closed.