msgProc: Gestures
Mouse gestures let users trigger actions by drawing shapes with the right mouse button. Drag left to go back, drag right to go forward. When recognized, msgProc receives MSG_GESTURE events with pattern details for building browser-style navigation shortcuts.
How Gestures Work
The gesture system tracks right-button drag motions and converts them into directional patterns:
- User presses and holds the right mouse button
- User drags in a pattern (left, right, L-shape, etc.)
- User releases the right mouse button
- System analyzes the path and matches it against registered patterns
- If matched,
MSG_GESTUREis sent to msgProc
false from msgProc when handling MSG_GESTURE to prevent the event from continuing to standard bindings. See the Gesture and Context Menu Interaction section below for implementation patterns.
Mouse Gesture (MSG_GESTURE)
MSG_GESTURE fires when a registered gesture pattern is recognized after the user completes a right-button drag motion. The event contains detailed information about the gesture including the pattern name, direction sequence, timing, and bounding box. Use this to implement browser-style navigation shortcuts, custom actions, or context-sensitive commands.
Message Parameters
| Parameter | Type | Description |
|---|---|---|
wParam |
number | Reserved (always 0) |
lParam |
number | Reserved (always 0) |
Detail Properties
| Property | Type | Description |
|---|---|---|
pattern |
string | Pattern name (e.g., 'left', 'L', 'custom-name') |
directions |
string[] | Array of direction codes (e.g., ['L', 'U']). Directions: 'L'=left, 'R'=right, 'U'=up, 'D'=down |
startTime |
number | When gesture started (milliseconds timestamp) |
endTime |
number | When gesture completed (milliseconds timestamp) |
duration |
number | Total gesture duration in milliseconds (endTime - startTime) |
points |
Array | Array of {x, y, time} points tracked during gesture |
left |
number | Left edge coordinate (minimum x) |
top |
number | Top edge coordinate (minimum y) |
right |
number | Right edge coordinate (maximum x) |
bottom |
number | Bottom edge coordinate (maximum y) |
width |
number | Gesture width in pixels (right - left) |
height |
number | Gesture height in pixels (bottom - top) |
target |
HTMLElement | Element where gesture started |
originalEvent |
Event | Original browser mouseup event |
Example: Simple Navigation
msgProc(event) {
if (event.message === wakaPAC.MSG_GESTURE) {
switch(event.detail.pattern) {
case 'left':
this.navigateBack();
return false;
case 'right':
this.navigateForward();
return false;
case 'up':
this.scrollToTop();
return false;
case 'down':
this.scrollToBottom();
return false;
}
}
}
Built-in Gesture Patterns
WakaPAC includes common single-direction and L-shape patterns:
| Pattern Name | Directions | Description | Common Use |
|---|---|---|---|
'right' |
R | Drag right | Forward navigation, next item |
'left' |
L | Drag left | Back navigation, previous item |
'up' |
U | Drag up | Scroll to top, collapse |
'down' |
D | Drag down | Scroll to bottom, expand |
'L' |
D, R | Down then right (L-shape) | New tab, new item |
'inverted-L' |
D, L | Down then left (inverted L) | Close tab, delete item |
Custom Gesture Registration
Register your own gesture patterns using direction codes. Custom gestures must be registered before initializing WakaPAC.
Direction Codes
| Code | Direction | Description |
|---|---|---|
'R' |
Right | Horizontal movement to the right |
'L' |
Left | Horizontal movement to the left |
'U' |
Up | Vertical movement upward |
'D' |
Down | Vertical movement downward |
Example: Register Custom Patterns
// Register before initializing WakaPAC
wakaPAC.registerGesture('refresh', ['U', 'D']); // Up then down
wakaPAC.registerGesture('undo', ['L', 'R']); // Left then right
wakaPAC.registerGesture('zigzag', ['R', 'L', 'R']); // Right-left-right
wakaPAC('#app', { /* ... */ });
Example: Handle Custom Gestures
msgProc(event) {
if (event.message === wakaPAC.MSG_GESTURE) {
switch(event.detail.pattern) {
case 'refresh':
this.reload();
return false;
case 'undo':
this.cancelOperation();
return false;
case 'zigzag':
this.closePanel();
return false;
}
}
}
Unregister Gestures
wakaPAC.unregisterGesture('refresh');
Gesture Configuration
Gestures have built-in constraints for reliable recognition:
| Parameter | Value | Description |
|---|---|---|
| Minimum segment length | 30 pixels | Prevents accidental jitter from being recognized as direction changes |
| Maximum duration | 2 seconds | Prevents very slow motions from being recognized as gestures |
| Minimum points | 2 points | At least 2 tracked points required to determine a direction |
| Direction threshold | 45° (0.7 cosine) | Determines when motion is cardinal (L/R/U/D) vs diagonal |
Gesture Recognition Details
How Direction Segments Are Detected
- System tracks mouse position at regular intervals during right-drag
- When movement distance exceeds 30 pixels, direction is calculated
- If new direction differs from previous by more than 45°, a new segment begins
- Segments are recorded as 'L', 'R', 'U', or 'D' based on dominant axis
- On mouse release, the sequence is matched against registered patterns
Diagonal Movement
Diagonal movements are resolved to the dominant axis (horizontal or vertical):
- Movement within 45° of horizontal → 'L' or 'R'
- Movement within 45° of vertical → 'U' or 'D'
Pattern Matching
After mouse release, the recorded direction sequence is compared against all registered patterns. The first exact match fires MSG_GESTURE with that pattern name.
MSG_GESTURE events. Only patterns registered via wakaPAC.registerGesture() or the built-in patterns will trigger events. All drag motions (recognized or not) suppress the context menu automatically.
Gesture and Context Menu Interaction
Gestures and right-clicks are separate actions. A stationary right-click fires MSG_RCLICK, which you can use to show a context menu. A right-button drag that matches a registered pattern fires MSG_GESTURE, which you can use for navigation shortcuts. This lets you support both context menus and gesture shortcuts without conflict.
Event Sequence
Stationary right-click:
1. MSG_RBUTTONDOWN → User presses right button
2. MSG_RBUTTONUP → User releases right button
3. MSG_RCLICK → Right-click event fires
Right-button drag (gesture):
1. MSG_RBUTTONDOWN → User presses right button
2. MSG_MOUSEMOVE (multiple) → User drags
3. MSG_RBUTTONUP → User releases right button
4. MSG_GESTURE → Gesture pattern recognized (if registered)
Example: Gestures + Context Menu
msgProc(event) {
// Handle gestures for navigation shortcuts
if (event.message === wakaPAC.MSG_GESTURE) {
switch(event.detail.pattern) {
case 'left':
this.navigateBack();
return false;
case 'right':
this.navigateForward();
return false;
}
}
// Handle stationary right-click for context menu
if (event.message === wakaPAC.MSG_RCLICK) {
const pos = wakaPAC.MAKEPOINTS(event.lParam);
this.showContextMenu(pos.x, pos.y);
return false;
}
}
Best Practices
- Keep patterns simple: One or two segments (L, R, U, D) work best. Complex patterns are hard to remember and draw accurately
- Return false: Always return
falsewhen handling gestures to stop event processing - Use alongside MSG_RCLICK: Gestures handle shortcuts while stationary right-clicks handle context menus — they're separate actions
- Test on different devices: Gestures work great with mouse, less reliable with trackpads
- Provide visual feedback: Consider drawing the gesture path or showing recognized pattern
- Don't rely solely on gestures: Provide alternative ways to trigger actions (buttons, keyboard shortcuts)
- Limit pattern count: 4-6 gestures maximum to avoid overwhelming users
- Use familiar patterns: Borrow from browser conventions (right = forward, left = back)