NPAPI:AdvancedKeyHandling

(Redirected from Plugins:AdvancedKeyHandling)

Contents

Status

Accepted, ready for implementation. Assigned NPAPI version 25.

Contributors

  • Last modified: March 20, 2009
  • Author: Josh Aas, Mozilla Corporation
  • Contributors: Johnny Stenback (Mozilla), Aaron Leventhal (IBM), Oliver Yeoh (Sun), Danielle Pham (Sun), Deneb Meketa (Adobe), Anders Carlsson (Apple), Michelle Sintov (Adobe), Karl Tomlinson (Mozilla)

Overview

This specification aims to solve these major problems with NPAPI:

  • Plugins eat all key events when focused, the browser does not get a chance to process anything. For Gecko, this is Mozilla bug 78414.
  • There is no way to get focus from a plugin using the keyboard. This is Mozilla bug 93149.

This specification adds the following capabilities to NPAPI:

  • Plugins should be able to participate in tab navigation just like any other tab-navigable elements.
  • This API will allow for focus direction to be recalled and followed - plugins should know what direction focus is coming from when being focused, and the browser should know which direction focus is going when unfocusing the plugin.
  • Plugins should be able to hand events to the browser when they want to, regardless of the source. This would allow the browser to handle events the plugin does not want to handle.

Negotiating Advanced Key Handling

In order for behavior to change, the browser must return a boolean value of "true" for "NPNVsupportsAdvancedKeyHandling" and the plugin must return a boolean value of "true" for "NPPVsupportsAdvancedKeyHandling". There is no active negotiation of modes and supported status cannot change at any time for either the browser or the plugin.

  • NPPVsupportsAdvancedKeyHandling (NPPVariable = 21)
  • NPNVsupportsAdvancedKeyHandling (NPNVariable = 21)

Specification

For windowed plugins, events that the browser should attempt to handle can be forwarded to the browser via a new function.

// Called by windowed plugins to pass an event on to the browser.
// Instance argument indicates the instance sending the event.
// Event argument is the event being forwarded.
// Handled argument indicates whether or not the plugin already handled the event.
//   This encourages the forwarding of all events even if the plugin already handled them.
//   The browser is then able to take further action if that is necessary for some reason.
//   Mouse move and null events should not be forwarded for performance reasons.
// Return value indicates whether or not the browser handled the event.
NPBool NPN_HandleEvent(NPP instance, void *event, NPBool handled);

For windowless plugins, returning 0 from NPP_HandleEvent will allow the browser to handle the event. The browser will consider a return value of 1 to mean that the event has been handled by the plugin.

For both windowed and windowless plugins, there will be 3 function and a set of enum values controlling focus.

enum  {
  NPFocusNext = 0,
  NPFocusPrevious = 1
} NPFocusDirection;

// Called by the plugin when the plugin intends to give up focus.
// Instance argument indicates the instance wishing to give up focus.
// Direction argument indicates whether the next or the previous element should take focus.
// Return value indicates whether or not the browser will take focus.
NPBool NPN_UnfocusInstance(NPP instance, NPFocusDirection direction);

// Called by the browser when the browser intends to focus an instance.
// Instance argument indicates the instance getting focus.
// Direction argument indicates the direction in which focus advanced to the instance.
// Return value indicates whether or not the plugin accepts focus.
NPBool NPP_GotFocus(NPP instance, NPFocusDirection direction);

// Called by the browser when the browser intends to take focus.
// Instance argument indicates the instances losing focus.
// There is no return value, plugins will lose focus when this is called.
void NPP_LostFocus(NPP instance);

When a plugin takes focus, it will receive an NPP_GotFocus call before receiving any events that might have given it focus, such as a mouse click. The plugin may not receive the event that gave it focus if the browser considers itself to have handled the event by giving focus to the plugin. For example, the browser may handle a tab key press by giving focus to the plugin and having handled the event, not send the tab key to the plugin.

If a plugin receives an event that causes it to attempt to give up focus, the plugin should simply call NPN_UnfocusInstance and not pass on the event since attempting to give up focus is essentially handling the event.

Focus events will not be passed to plugins via NPP_HandleEvent when AKH is enabled. Per platform, this means:

  • Mac OS X (windowless): NPEventType_GetFocusEvent and NPEventType_LoseFocusEvent will not be sent.
  • Windows (windowless): WM_SETFOCUS and WM_KILLFOCUS will not be sent.
  • GTK (non-xembed windowless): FocusIn and FocusOut will not be sent.

Comments

  • Situations to consider:
    • Plugin is the only object in the tab chain for the window, last element inside plugin is focused and user hits tab.
      • Plugin should call NPN_GiveUpFocus in response to the tab event, browser should return true and then call NPP_GotFocus with NPFocusNext for the direction argument to return focus to the first element in the plugin. If the browser does not want focus to wrap around then it can return false for the NPN_GiveUpFocus call. Plugin does not pass the tab event to the browser either way.

Specification History

Click here to see information on past specification attempts.