NPAPI:CocoaEventModel
This Document
This proposal was submitted by Anders Carlsson of Apple Computer, Inc. and posted to the plugin-futures (@mozilla.org) mailing list. It has been edited and formatted here by Josh Aas of Mozilla Corporation.
Overview
We're introducing the concept of the "event model" for Mac plug-ins. This is similar to the already existing concept of drawing models.
Event Model Negotiation
When the plug-in starts, it negotiates the event model with the browser.
A plug-in may call NPN_GetValue() with the following NPNVariables to query the browser for its supported event models:
- ifndef NP_NO_CARBON
, NPNVsupportsCarbonBool = 2003 /* TRUE if the browser supports the Carbon event model */
- endif
, NPNVsupportsCocoaBool = 2004 /* TRUE if the browser supports the Cocoa event model */
Once the plug-in finds a supported event model, it calls NPN_SetValue to tell the browser which event model it has. We're adding a new NPNVariable for this:
NPPVpluginEventModel = 1001,
The value of the NPPVpluginEventModel is an NPEventModel, a new enumeration we're adding:
typedef enum {
- ifndef NP_NO_CARBON
NPEventModelCarbon = 0,
- endif
NPEventModelCocoa = 1,
} NPEventModel;
The Carbon event model
The Carbon event model is the event model used by all plug-ins today. If a plug-in does not negotiate an event model, the Carbon event model is used.
In 64-bit, the Carbon event model does not exist, and the Cocoa event model is used if the plug-in does not negotiate an event model.
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 handle in NP_CGContext and NP_GLContext is now an NSWindow* instead of a WindowRef.
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; 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 {
double x, y, width, height;
} draw; struct { NPBool hasFocus; } focus; } event;
} NPCocoaEvent;
NPCocoaEventType is one of the following:
typedef enum {
NPCocoaEventDrawRect NPCocoaEventMouseDown, NPCocoaEventMouseUp, NPCocoaEventMouseMoved, NPCocoaEventMouseEntered, NPCocoaEventMouseExited, NPCocoaEventMouseDragged, NPCocoaEventScrollWheel, NPCocoaEventKeyDown, NPCocoaEventKeyUp, NPCocoaEventFlagsChanged, NPCocoaEventFocusChanged, NPCocoaEventWindowFocusChanged,
} NPCocoaEventType;
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 NPNSMenu is a typedef to NSMenu.
Your feedback is important!
If you are at all involved in Mac browser or plugin development, these changes will affect you. So make your voice heard! We're open to any questions or comments you might have about these proposed changes. Please post comments on the plugin-futures (@mozilla.org) mailing list.
Notes
- Josh Aas
- We need a solution for IME