Skip to content

MouseAction Data Structure

Samera2022 edited this page Jan 30, 2026 · 1 revision

MouseAction Data Structure

Relevant source files

Purpose and Scope

The MouseAction class is the fundamental data structure that represents a single recorded input event in the MouseMacros system. Each instance encapsulates all information necessary to reproduce a mouse movement, button click, keyboard press, or mouse wheel scroll action during playback.

This document covers the structure, fields, and usage of the MouseAction class. For information about how actions are captured from user input, see Global Input Capture. For details on how actions are persisted to disk, see Macro File Format (.mmc)). For the orchestration of recording and playback operations, see MacroManager.

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L1-L256


Class Overview

The MouseAction class resides in the io.github.samera2022.mouse_macros.action package and serves as the atomic unit of macro operations. During recording, each user input event is translated into a MouseAction object by GlobalMouseListener. During playback, MacroManager iterates through a list of MouseAction objects and executes each one via its perform() method.

flowchart TD

MouseAction["MouseAction"]
CoordinateFields["Coordinate Fields<br>x, y"]
ActionFields["Action Classification<br>type, button, keyCode, awtKeyCode"]
TimingFields["Timing Field<br>delay"]
WheelFields["Wheel Field<br>wheelAmount"]
GlobalMouseListener["GlobalMouseListener"]
ScreenUtil["ScreenUtil"]
MacroManager_Record["MacroManager.recordAction()"]
MacroManager_Play["MacroManager.play()"]
Robot["java.awt.Robot"]
ActionPerform["MouseAction.perform()"]

GlobalMouseListener --> MouseAction
ScreenUtil --> MouseAction
MouseAction --> MacroManager_Record
MacroManager_Play --> MouseAction
MouseAction --> ActionPerform

subgraph subGraph2 ["Playback Context"]
    MacroManager_Play
    Robot
    ActionPerform
    ActionPerform --> Robot
end

subgraph subGraph1 ["Recording Context"]
    GlobalMouseListener
    ScreenUtil
    MacroManager_Record
end

subgraph subGraph0 ["MouseAction Structure"]
    MouseAction
    CoordinateFields
    ActionFields
    TimingFields
    WheelFields
    MouseAction --> CoordinateFields
    MouseAction --> ActionFields
    MouseAction --> TimingFields
    MouseAction --> WheelFields
end
Loading

Diagram: MouseAction in the Recording and Playback Pipeline

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L110-L125


Field Definitions

The MouseAction class contains eight fields that fully describe an input event. The field structure has evolved across four format versions to support increasing functionality while maintaining backward compatibility.

Field Type Description Default (Legacy)
x int Normalized X-coordinate of the cursor position N/A (required)
y int Normalized Y-coordinate of the cursor position N/A (required)
type int Action type identifier (see Action Types section) N/A (required)
button int Mouse button code (AWT standard: 1=left, 2=middle, 3=right) N/A (required)
delay long Time delay in milliseconds since the previous action N/A (required)
wheelAmount int Mouse wheel scroll amount (negative=up, positive=down) 0 (version ≤2)
keyCode int JNativeHook key code for keyboard events 0 (version ≤3)
awtKeyCode int AWT key code for keyboard events (java.awt.event.KeyEvent constants) 0 (version ≤4)

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L162-L163, src/io/github/samera2022/mouse_macros/manager/MacroManager.java L211-L244

Coordinate System

The x and y fields store cursor coordinates normalized by ScreenUtil. Normalization converts absolute screen coordinates into relative values that work across different screen resolutions and multi-monitor configurations. This ensures macros recorded on one display setup can be played back on another.

Action Type Encoding

The type field is an integer code that specifies the category of action:

  • Mouse Movement: Cursor position changes
  • Mouse Press: Button down events
  • Mouse Release: Button up events
  • Mouse Wheel: Scroll wheel rotation
  • Key Press: Keyboard key down events
  • Key Release: Keyboard key up events

The specific integer values are determined by the JNativeHook library's event type constants.

Button Code Mapping

The button field uses AWT standard button codes:

  • 1 = Left mouse button (BUTTON1)
  • 2 = Middle mouse button (BUTTON2)
  • 3 = Right mouse button (BUTTON3)

These codes are translated from JNativeHook's non-standard button mapping during event capture by GlobalMouseListener.

Timing Information

The delay field stores the elapsed time in milliseconds between the previous action and the current action. During recording, this is calculated as System.currentTimeMillis() - MacroManager.getLastTime(). During playback, MacroManager respects this timing unless "Quick Mode" is enabled (config.enableQuickMode), which executes actions with zero delay.

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L53-L64


Action Type Categories

The MouseAction class supports six primary action categories, distinguished by the type field value:

flowchart TD

MouseAction["MouseAction"]
MouseMove["Mouse Move<br>type=MOUSE_MOVED<br>Uses: x, y, delay"]
MousePress["Mouse Press<br>type=MOUSE_PRESSED<br>Uses: x, y, button, delay"]
MouseRelease["Mouse Release<br>type=MOUSE_RELEASED<br>Uses: x, y, button, delay"]
MouseWheel["Mouse Wheel<br>type=MOUSE_WHEEL<br>Uses: x, y, wheelAmount, delay"]
KeyPress["Key Press<br>type=KEY_PRESSED<br>Uses: keyCode, awtKeyCode, delay"]
KeyRelease["Key Release<br>type=KEY_RELEASED<br>Uses: keyCode, awtKeyCode, delay"]

MouseAction --> MouseMove
MouseAction --> MousePress
MouseAction --> MouseRelease
MouseAction --> MouseWheel
MouseAction --> KeyPress
MouseAction --> KeyRelease

subgraph subGraph0 ["Action Categories"]
    MouseMove
    MousePress
    MouseRelease
    MouseWheel
    KeyPress
    KeyRelease
end
Loading

Diagram: Action Type Categories and Field Usage

Each action type utilizes a subset of the available fields. For example, mouse wheel events use wheelAmount but not button, while keyboard events use keyCode and awtKeyCode but not coordinates for positioning (though coordinate fields are still populated with the cursor position when the key was pressed).

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L162-L163


Action Execution

The perform() method is responsible for executing the action during macro playback. This method uses java.awt.Robot to generate low-level input events that simulate user actions.

sequenceDiagram
  participant MacroManager
  participant MouseAction
  participant Robot
  participant OS

  MacroManager->>MouseAction: perform()
  loop [Mouse Move]
    MouseAction->>Robot: mouseMove(x, y)
    Robot->>OS: Generate cursor movement
    MouseAction->>Robot: mouseMove(x, y)
    MouseAction->>Robot: mousePress(button) or mouseRelease(button)
    Robot->>OS: Generate button event
    MouseAction->>Robot: mouseWheel(wheelAmount)
    Robot->>OS: Generate scroll event
    MouseAction->>Robot: keyPress(awtKeyCode) or keyRelease(awtKeyCode)
    Robot->>OS: Generate keyboard event
  end
  MouseAction-->>MacroManager: Action complete
Loading

Diagram: Action Execution Flow

The perform() method interprets the type field to determine which Robot methods to invoke. Coordinate normalization is reversed to convert relative coordinates back to absolute screen coordinates appropriate for the current display configuration.

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L49-L66


Constructor Variants and Backward Compatibility

The MouseAction class provides multiple constructor signatures to support loading macro files created by different versions of MouseMacros. The current version (Version 4) uses all eight fields, but the system maintains backward compatibility with three earlier formats.

Constructor Matrix

Version Fields Constructor Signature Missing Fields Default Values
4 (Current) 8 MouseAction(int x, int y, int type, int button, long delay, int wheelAmount, int keyCode, int awtKeyCode) N/A
3 7 MouseAction(int x, int y, int type, int button, long delay, int wheelAmount, int keyCode, 0) awtKeyCode = 0
2 6 MouseAction(int x, int y, int type, int button, long delay, int wheelAmount, 0, 0) keyCode = 0, awtKeyCode = 0
1 5 MouseAction(int x, int y, int type, int button, long delay, 0, 0, 0) wheelAmount = 0, keyCode = 0, awtKeyCode = 0

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L211-L244

Version Evolution

flowchart TD

V1["Version 1<br>5 fields<br>Basic mouse actions"]
V2["Version 2<br>6 fields<br>+ Mouse wheel support"]
V3["Version 3<br>7 fields<br>+ JNativeHook key codes"]
V4["Version 4<br>8 fields<br>+ AWT key codes"]

V1 --> V2
V2 --> V3
V3 --> V4
Loading

Diagram: MouseAction Format Version Evolution

The addition of awtKeyCode in Version 4 provides dual key code support: keyCode preserves the raw JNativeHook event code, while awtKeyCode stores the standard Java AWT key code. This dual representation ensures cross-platform keyboard compatibility, as AWT key codes are more portable than JNativeHook's platform-specific codes.

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L211-L244


Usage in Recording and Playback

Recording Phase

During macro recording, GlobalMouseListener creates MouseAction instances for each captured input event and submits them to MacroManager.recordAction():

  1. Event Capture: GlobalMouseListener receives native input events from JNativeHook
  2. Coordinate Normalization: ScreenUtil converts absolute coordinates to normalized values
  3. Button Code Translation: JNativeHook button codes are mapped to AWT standard codes
  4. Timing Calculation: Delay is computed as System.currentTimeMillis() - MacroManager.getLastTime()
  5. Action Creation: A new MouseAction object is instantiated with all fields populated
  6. Storage: MacroManager.recordAction() adds the action to the internal actions list

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L110-L117

Playback Phase

During macro playback, MacroManager.play() iterates through the recorded actions:

  1. Delay Application: If Quick Mode is disabled, Thread.sleep() waits for the action's delay period
  2. Action Execution: action.perform() is invoked to execute the action via Robot
  3. Interrupt Handling: The playback loop checks for abort signals between actions
  4. Repetition: The entire action sequence repeats based on config.repeatTime
  5. Inter-Repeat Delay: config.repeatDelay seconds elapse between repetitions
flowchart TD

Start["MacroManager.play()"]
CheckEmpty["actions.isEmpty()"]
StartThread["Start playThread"]
RepeatLoop["Repeat Loop<br>(config.repeatTime)"]
ActionLoop["Action Loop<br>(for each MouseAction)"]
CheckAbort["playing == true?"]
ApplyDelay["Thread.sleep(action.delay)<br>(if !enableQuickMode)"]
PerformAction["action.perform()"]
InterRepeatDelay["Thread.sleep(repeatDelay)"]
Complete["Log playback complete"]
End["End"]

Start --> CheckEmpty
CheckEmpty --> End
CheckEmpty --> StartThread
StartThread --> RepeatLoop
RepeatLoop --> ActionLoop
ActionLoop --> CheckAbort
CheckAbort --> Complete
CheckAbort --> ApplyDelay
ApplyDelay --> PerformAction
PerformAction --> ActionLoop
ActionLoop --> InterRepeatDelay
InterRepeatDelay --> RepeatLoop
RepeatLoop --> Complete
Complete --> End
Loading

Diagram: Playback Loop with MouseAction Execution

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L36-L93


File Serialization Format

When macros are saved to .mmc files, each MouseAction is serialized as a single line of comma-separated values in the order: x,y,type,button,delay,wheelAmount,keyCode,awtKeyCode. This CSV format enables human readability and easy debugging of macro files.

Example serialized action:

500,300,501,1,150,0,0,0

This represents:

  • Cursor at normalized coordinates (500, 300)
  • Type 501 (hypothetical mouse press type)
  • Left button (1)
  • 150ms delay since previous action
  • No wheel scroll (0)
  • No keyboard input (keyCode=0, awtKeyCode=0)

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L160-L168

Loading Legacy Formats

When loading macro files, MacroManager automatically detects the format version by counting comma-separated fields in each line. The appropriate constructor variant is invoked based on field count:

  • 8 fields → Version 4 constructor (all fields)
  • 7 fields → Version 3 constructor (defaults awtKeyCode to 0)
  • 6 fields → Version 2 constructor (defaults keyCode and awtKeyCode to 0)
  • 5 fields → Version 1 constructor (defaults wheelAmount, keyCode, and awtKeyCode to 0)

This automatic format detection ensures that macros recorded with older versions of MouseMacros remain functional when loaded in newer versions.

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L207-L245


Summary

The MouseAction class is a comprehensive data structure that encapsulates all information necessary to record and reproduce user input events. Its eight-field design supports mouse movements, button clicks, wheel scrolling, and keyboard input. The class maintains backward compatibility with four format versions through multiple constructor variants, ensuring long-term macro file compatibility. During playback, the perform() method translates the stored data back into OS-level input events, faithfully reproducing the recorded user interactions.

Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L1-L256

Clone this wiki locally