Plug-In API Proposal: Tabbing Integration
Deneb Meketa
Michelle Sintov
Peter Grandmaison
Macromedia
Aaron Leventhal
IBM
Requirements for Keyboard Accessibility
1. Tabbing into and out of plugins.
It is desirable to allow users to tab through HTML content, into plugins that
contain focusable elements, and out the other side of such plugins back into
either the surrounding HTML content, or to the browser's UI if there are no
additional focusable items in the surrounding HTML, or if the plugin is alone
in the browser window. In the current broken model, once a plugin has focus, a
keyboard-only user is stuck there.
2. Sharing of accelerator keys
When a plugin is active, it should have the first shot at most keystrokes.
However, if the plugin sees a keystroke it does not need, it should be able to
pass on the keystroke, so that it can bubble back up to the user agent. For
example, if the plugin does not use Alt+Left and Alt+Right these should find
their way up to the browser for back/forward navigation. Or, perhaps the user
has typed Alt by itself. On Windows and Linux, this should be forwarded to the
user agent so it can focus the menu bar, if the plugin doesn't already have its
own menu bar. In the current broken model, when a plugin has focus it swallows
all keystrokes.
Two Different Keyboard Models for Plugins Today
There are two different keyboard-handling modes for plugins.
1. Focused mode, applicable on Windows, with a non-windowless plugin: the plugin has its own HWND, and becomes focused when users click in it or tab into it, and from then on receives keyboard events directly.
2. Non-focused mode, applicable for windowless plugins, and all plugins on the Mac: the plugin draws into a window maintained by the browser, and never has focus from an OS point of view, and thus depends on the browser for keyboard input.
I don't know what Unixen do, but I assume all cases on all OSes fall into one of the two modes described above. I also assume that plugins and browsers will always be able to determine which of these two modes they are in, based only on platform and windowlessness.
Proposed API Change - new keyPressEvent
We propose to handle tabbing using the existing NPP_HandleEvent and NPN_HandleEvent mechanisms, via the following new event: keyPressEvent
The keyPressEvent will contain boolean event parameters indicating whether
alt, ctrl, shift or meta modifier keys were used, along with an unsigned 32 bit
integer representing key's
DOM_VK key code, via event parameters
For modifier keys (alt, ctrl, shift, meta) alone, the event will be fired on
key up. For keys that involve a non-modifier key the event will be fired on key
down, to attain the appropriate leven of UI responsiveness.
How this helps with
tabbing
into a plugin:
When the browser wants to give the plugin focus and/or advance the focus within the plugin, because a user is currently tabbing, it would forward a keyPressEvent event to the plugin for tab or shift+tab.
If the plugin accepts the tab press, but does not already have the real OS
focus, it needs to give itself OS focus.
How this helps with tabbing out of a plugin:
When the plugin receives key down and up events for tab or shift+tab, either via the new plugin events or from the OS, and it is already at the end of it's tab order, it will send a keyPressEvent up to the browser.
How this helps pass unused keystrokes:
When the plugin receives a key press event, either from the browser firing keyPressEvent in non-focused mode, or from the operating system, it will analyze to see if it needs the keystroke. If it does not need the key, it must send the key back to the browser via keyPressEvent.
Return codes for keyPressEvent:
0: browser or plugin does not understand keyPressEvent
1: keyPressEvent not used. The browse should never return this when it receives a Tab or Shift+Tab, because it should always have a way of accepting focus.
2: keyPressEvent accepted and used
The plugin and browser still need to handle getFocusEvent and loseFocusEvent
as they do now.whenever it received a tab key event that caused focus to pass
beyond the end of its list of focusable items.