Focus…
December 30th, 2008I mentioned recently that I was working on some significant focus-related changes. I’ve just posted the patch into bug 178324. Test builds are available here. Some tests fail. Help with testing is very appreciated.
The basic idea is that focus can only be in one place at one time. Thus, the currently focused element is only stored in one place, as opposed to the multiple places that the old code did. It addition, all of the code to store and manipulate the focus is all in one place. Thus, focus and blur events only get fired from one place and in a specific way that is far easier to understand. The old way involved a variety of undocumented functions which appeared to adjust the focus or some aspect of it, but it was never clear which of these functions was the right one to call in which situation. Now, all actual focus changes all eventually go through a single function, either directly or via a number of existing APIs (such as by calling an element’s focus method). This eliminates the confusion of multiple code variants, and, more importantly, one cannot change the focus in some other way. The result is that extra focus and blur events do not fire, events do not get lost and you should no longer have the problem of mutliple focus rings appearing or focus rings that just won’t disappear.
The old code was further muddled by having to call into the native operating system at various times (often needlessly doing so repeatedly), which in turn would sometimes fire various focus events back again, causing recursive situations. This was dealt with then by adding focus suppression flags and bailing out when they were set. Unreliable and confusing, of course. In the new world, there’s none of this. Instead, the native platform is only called when necessary. And due to other changes, the calls back again don’t need to be responded to at all anyway. So, they just get ignored.
It’s quite possible that some of these changes break plugins or embedding or some such. However, I think finding a solution to that would be easier with a more logical focus architecture.
The patch includes a test which tests a wide variety of things, including tab navigation (which doesn’t get stuck anymore, see bug 399427), tabindicies, accesskeys, clicking on focusable and non-focusable elements, frame navigation, window switching, as well as some specific tests for elements with particular focus behaviour such as imagemaps, labels and legend elements.
In the following weeks, I’ll be posting more information about all of this. In addition, I plan to provide some documentation for developers, explaining how and when to manipulate focus, as well as specific nuances associated with this.
Finally, I’d like to apologize to all of the Mozilla developers that have spent tireless hours adding hacks on top of hacks in the focus code. Unfortunately I’ve had to remove all of these hacks.


