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:

  1. User presses and holds the right mouse button
  2. User drags in a pattern (left, right, L-shape, etc.)
  3. User releases the right mouse button
  4. System analyzes the path and matches it against registered patterns
  5. If matched, MSG_GESTURE is sent to msgProc
Gesture vs. Right-Click: A stationary right-click fires MSG_RCLICK for context menus. Any right-button drag suppresses both MSG_RCLICK and the browser context menu. If the drag matches a registered gesture pattern, MSG_GESTURE fires. Return 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
Configuration: These values are optimized for typical usage and cannot currently be changed without modifying the framework.

Gesture Recognition Details

How Direction Segments Are Detected

  1. System tracks mouse position at regular intervals during right-drag
  2. When movement distance exceeds 30 pixels, direction is calculated
  3. If new direction differs from previous by more than 45°, a new segment begins
  4. Segments are recorded as 'L', 'R', 'U', or 'D' based on dominant axis
  5. 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.

Important: Unrecognized gesture patterns do not fire 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 Practice: Use MSG_GESTURE for quick shortcuts and MSG_RCLICK for context menus. Users can drag for gestures or click-release for menus — the two actions don't interfere with each other.

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 false when 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)