How to fix disappearing Flash component

While working on the video player for the Minoto Video Platform, I ran into a serious issue with Flash player and the ComboBox component that comes with Flash CS4. I thought I’d share the story and solution to help others that are in a similar hair-pulling situation.

The hunt

For the video player we wanted to replace the existing quality toggle button (similar to YouTube’s "HD" button) with a ComboBox, because the platform will support more than 2 qualities in the near future. The ComboBox component that comes with Flash seemed like a good choice, so I put it in, changed the color scheme so it fits with the rest of the player, and added the underlying code to make it work. I was done after two days, and tested it both in the standalone Flash player, and the Flash-generated HTML embed. All seemed to work just fine, so I put it on our test environment. Surprise! The ComboBox wasn’t there.

Of course I immediately suspected that it was a Z-index put too low, or a visibility property that got flipped to false somehow. I also blamed the animation that hides the control bar if you move the mouse out of the video or hold it still for three seconds. I checked and tested all that, but it kept working in my tests, but it would disappear again as soon as I put it in the test environment. Eventually I noticed that the control bar would appear when the player was switched to full-screen, and it would stay functional after I switched back from full-screen. That’s when I started to suspect that the bug was in either the component or the Flash player, instead of in my coding.

When I Googled for "flash invisible combobox" and similar terms, all I found was one person with the same problem, but no solution. A question I posted on Stack Overflow got no response, and earned me the Tumbleweed badge.

The culprit

Eventually it dawned on me (thanks Nicolas, for putting me on the right track) that the difference between my tests and the test environment was in the embed code, so I started comparing those. As it turns out, there was an attribute in the <embed> tag that made the bug appear: wmode="transparent". Now that I found the culprit, it was a lot easier to Google for a solution.

First let me explain what the wmode attribute does (described in Adobe’s embed tag documentation). It determines how the movie interacts with other elements on the HTML page. If it is set to opaque or window, it floats above all other things on the page. This is not an option for us, since a lot of our publishers use DHTML (i.e. JavaScript) menus for their navigation, and they would no longer work.

The fix

Eventually, I found this blog post explaining the problem, and a possible workaround in the comments. The problem is that for some reason the Flash player decides not to dispatch RENDER events anymore. The solution is to dispatch that event manually on key moments, to allow the component to re-render itself. My code ended up looking like this:

private function renderStage(e:Event=null){
 stage.dispatchEvent(new Event(Event.RENDER));
}

myComboBox.addEventListener(ListEvent.ITEM_CLICK, renderStage);
myComboBox.addEventListener(ListEvent.ITEM_DOUBLE_CLICK, renderStage);
myComboBox.addEventListener(ListEvent.ITEM_ROLL_OUT, renderStage);
myComboBox.addEventListener(ListEvent.ITEM_ROLL_OVER, renderStage);
myComboBox.addEventListener(Event.CHANGE, renderStage);

Conclusion

It is just insane that I have to jump through these hoops to avoid a critial bug (or maybe design flaw) in something as omnipresent as Flash player, even though I’m using out-of-the-box component that Adobe itself ships with the official authoring tool for its own player. There’s this glaring bug in the Flash player, one that even Adobe runs into, and yet they fail to fix or even document the behavior. I’ve lost a lot of time on this (a full week, I estimate), and by the end I was extremely frustrated because I couldn’t find anything wrong with what I was doing. I’m really glad I found that useful blog post, and I’ve added the answer to my Stack Overflow question, and wrote this article so others may find a solution easier and faster.