NPAPI:CocoaEventModel
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.
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 returnskNPEventStartIME
. - 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 aNPCocoaEventKeyDown
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.
- User presses "enter" in an out-of-line composition window to commit a complex text composition that started with the plugin returning
- Example 3
- User presses "option-e" in an en-us context.
- Plugin receives a
NPCocoaEventKeyDown
event for "option-e" and returnskNPEventStartIME
. - 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 returnskNPEventStartIME
. - 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?