Personal tools

NPAPI:CocoaEventModel

From MozillaWiki

Jump to: navigation, search

Contents

Status

Accepted, ready for implementation. Assigned NPAPI version number 23.

Contributors

  • Last modified: January 18, 2011
  • Authors: Anders Carlsson (Apple)
  • Contributors: Josh Aas (Mozilla Corporation)

Overview

The Cocoa event model is an alternative event model for 32-bit Mac OS X plugins and the default event model for 64-bit Mac OS X plugins.

Note: This specification pre-dates some drawing specifications, so it assumes the CoreGraphics drawing model. Comments related to drawing may not apply to newer drawing models such as Core Animation and invalidating Core Animation.

Event model negotiation

For documentation on negotiating event models, see NPAPI:Models. The event model variables for Cocoa are:

  • NPEventModelCocoa (NPEventModel = 1)
  • NPNVsupportsCocoaBool (NPNVariable = 3001)

The Cocoa event model

If a plug-in sets the event model to NPEventModelCocoa, then the following changes are made, each of which is described in detail further in this document:

  • NPP_HandleEvent now passes an NPCocoaEvent struct.
  • Null events are no longer sent.
  • The window field of NPWindow is null. The CGContextRef to use when drawing is a member of the draw event struct.

All coordinates passed to the plugin via the Cocoa event model are based on the origin being in the top-left (not bottom-left as in standard Cocoa coordinates). This is on account of the fact that the CoreGraphics context given to the plugins is flipped for historical reasons.

The Cocoa event model can not be used with the QuickDraw drawing model.

NPP_HandleEvent

In the Cocoa event model, NPP_HandleEvent now passes a new struct, NPCocoaEvent, which is shown below:

typedef struct _NPCocoaEvent {
    NPCocoaEventType type;
    uint32 version;
    union {
        struct {
            uint32 modifierFlags;
            double pluginX;
            double pluginY;            
            int32 buttonNumber;
            int32 clickCount;
            double deltaX;
            double deltaY;
            double deltaZ;
        } mouse;
        struct {
            uint32 modifierFlags;
            NPNSString *characters;
            NPNSString *charactersIgnoringModifiers;
            NPBool isARepeat;
            uint16 keyCode;
        } key;
        struct {
           CGContextRef context;
           double x;
           double y;
           double width;
           double height;
        } draw;
        struct {
            NPBool hasFocus;
        } focus;
        struct {
            NPNSString *text;
        } text;
    } data;
} NPCocoaEvent;

NPCocoaEventType is one of the following:

typedef enum {
    NPCocoaEventDrawRect = 1,
    NPCocoaEventMouseDown,
    NPCocoaEventMouseUp,
    NPCocoaEventMouseMoved,
    NPCocoaEventMouseEntered,
    NPCocoaEventMouseExited,
    NPCocoaEventMouseDragged,
    NPCocoaEventKeyDown,
    NPCocoaEventKeyUp,
    NPCocoaEventFlagsChanged,
    NPCocoaEventFocusChanged,
    NPCocoaEventWindowFocusChanged,
    NPCocoaEventScrollWheel,
    NPCocoaEventTextInput
} NPCocoaEventType;

version is a per event version number. It is currently 0 for all events.

General event struct members

uint32 modifierFlags;

An integer bit field indicating the modifier keys. It uses the same constants as -[NSEvent modifierFlags].

Mouse events

  • NPCocoaEventMouseDown - Fired when a mouse button is pressed
  • NPCocoaEventMouseUp - Fired when a mouse button is released
  • NPCocoaEventMouseMoved - Fired when the mouse is moved
  • NPCocoaEventMouseEntered - Fired when the mouse enters the plug-in area.
  • NPCocoaEventMouseExited - Fired when the mouse exits the plug-in area.
  • NPCocoaEventMouseDragged - Fired when the mouse is moved with a mouse button pressed. This will fire even if the mouse is moved outside of the plug-in area.
  • NPCocoaEventScrollWheel - Fired when the mouse's scroll wheel has moved.
double pluginX;

The X position of the mouse cursor, in the plug-in's coordinate system.

double pluginY;

The Y position of the mouse cursor, in the plug-in's coordinate system.

int32 buttonNumber;

The button number of the mouse button that generated the mouse event.

int32 clickCount;

The number of mouse clicks associated with the event.

double deltaX;
double deltaY;
double deltaZ;

The X, Y or Z coordinate change for a scroll wheel, mouse-move, or mouse-drag event.

Keyboard events

Keyboard events will only be fired when the plug-in has keyboard focus.

  • NPCocoaEventKeyDown - Fired when a key is pressed
  • NPCocoaEventKeyUp - Fired when a key is released
  • NPCocoaEventFlagsChanged - Fired when a modifier key is pressed or released
NPNSString *characters;

The characters associated with the key-up or key-down event. Will always be null for NPCocoaEventFlagsChanged.

NPNSString *charactersIgnoringModifiers;

The characters generated by the receiving key event as if no modifier key (except for Shift) applies. Will always be null for NPCocoaEventFlagsChanged.

NPBool isARepeat;

TRUE if the key event is a repeat caused by the user holding the key down, FALSE if the key event is new. Will always be FALSE for NPCocoaEventFlagsChanged.

uint16 keyCode;

The virtual key code for the keyboard key associated with the key event.

Focus events

  • NPCocoaEventFocusChanged - Fired when the plug-in gains or loses focus.
  • NPCocoaEventWindowFocusChanged - Fired when the plug-in window gains or loses focus.
NPBool hasFocus;

TRUE if the plug-in or window now has focus, FALSE otherwise.

Draw event

  • NPCocoaEventDrawRect - Fired whenever the plug-in should draw.
CGRect rect;

The dirty rect in plug-in coordinates.

Null events

When the Cocoa drawing model, null events are no longer used. Instead, two new timer functions have been added:

uint32 NPN_ScheduleTimer(NPP npp, uint32 interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32 timerID));
  • npp - The plug-in instance pointer.
  • interval - The timer interval in milliseconds.
  • repeat - Whether the timer should reschedule itself automatically.
  • timerFunc - A pointer to the function that will be run when the timer fires.

This schedules a timer. The return value is 0 on error or a unique timeout ID on success.

void NPN_UnscheduleTimer(NPP npp, uint32 timerID)
  • npp - The plug-in instance pointer.
  • timerID - A timerID returned from NPN_ScheduleTimer.

This unschedules a previously scheduled timer.

Note that the browser may increase the timeout intervals, for example when the browser window containing the plug-in is minimized.

Popup menus

To pop up a context menu, the following function should be used

NPError NPN_PopUpContextMenu(NPP npp, NPNSMenu *menu)

Note that this must be called from the NPP_HandleEvent callback, and will return an error otherwise. The top left corner of the menu will be positioned at the location corresponding to the current event being handled.

The NPNSMenu is a typedef to NSMenu.

Text Input

(Note: Due to an amended specification and inconsistency in original implementations the variable NPNVsupportsUpdatedCocoaTextInputBool (NPNVariable = 3002) will indicate whether a browser supports this updated specification or not. If this is undefined or is false then text input behavior will vary between browsers.)

Plugin-ins can return 2, (kNPEventStartIME) from NPP_HandleEvent for NPCocoaEventKeyDown events when they want the browser to have an input method process the event.

The input method may open an out-of-line input window where complex text can be composed. When the user confirms the text and dismisses the window, an NPCocoaEventTextInput event is sent with the relevant unicode string.

Composition is considered to have started once a plugin returns kNPEventStartIME for a NPCocoaEventKeyDown event. Once a composition is started, plugins will not receive NPCocoaEventKeyDown or NPCocoaEventKeyUp events associated with compositions regardless of whether the composition results in a NPCocoaEventTextInput event or not (it may be canceled or the key press may not result in a meaningful composition).

NPCocoaEventFlagsChanged events will be sent at all times, even during composition.

  • Example 1
    • User presses the "a" key in an en-us context.
    • Plugin gets a NPCocoaEventKeyDown event and returns kNPEventStartIME.
    • Plugin gets NPCocoaEventTextInput event for string "a".
    • Plugin does not get NPCocoaEventKeyUp event for "a" key.
  • Example 2
    • User presses "enter" in an out-of-line composition window to commit a complex text composition that started with the plugin returning kNPEventStartIME for a NPCocoaEventKeyDown event.
    • Plugin does not receive an NPCocoaEventKeyDown event for the "enter" key. It is considered to belong to the composition.
    • Plugin receives NPCocoaEventTextInput event containing composed string.
    • Plugin does not receive a NPCocoaEventKeyUp event for the "enter" key. It is considered to belong to the composition.
  • Example 3
    • User presses "option-e" in an en-us context.
    • Plugin receives a NPCocoaEventKeyDown event for "option-e" and returns kNPEventStartIME.
    • Plugin does not receive a NPCocoaEventKeyUp event for the "option-e" key. It is considered to belong to the composition.
    • User presses "e" to complete a composition of the string "é".
    • Plugin does not receive a NPCocoaEventKeyDown event for the "e" key. It is considered to belong to the composition.
    • Plugin receives NPCocoaEventTextInput event containing composed string "é".
    • Plugin does not receive a NPCocoaEventKeyUp event for the "e" key. It is considered to belong to the composition.
  • Example 4
    • User presses "F3" key in an en-us context.
    • Plugin receives a NPCocoaEventKeyDown event for the "F3" key and returns kNPEventStartIME.
    • Plugin does not receive a NPCocoaEventTextInput event because F3 is a dead key as far as composition is concerned. Composition is considered to be canceled.
    • Plugin does not receive a NPCocoaEventKeyUp event for the "F3" key. It is considered to belong to the composition which is now canceled.

Notes

  • Josh Aas
    • Do we need events for multi-touch?