# MouseAction Data Structure > **Relevant source files** > * [src/io/github/samera2022/mouse_macros/manager/MacroManager.java](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/MacroManager.java) ## 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](Global-Input-Capture). For details on how actions are persisted to disk, see [Macro File Format (.mmc)](Macro-File-Format-(.mmc))). For the orchestration of recording and playback operations, see [MacroManager](MacroManager). **Sources:** [src/io/github/samera2022/mouse_macros/manager/MacroManager.java L1-L256](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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. ```mermaid flowchart TD MouseAction["MouseAction"] CoordinateFields["Coordinate Fields
x, y"] ActionFields["Action Classification
type, button, keyCode, awtKeyCode"] TimingFields["Timing Field
delay"] WheelFields["Wheel Field
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 ``` **Diagram: MouseAction in the Recording and Playback Pipeline** **Sources:** [src/io/github/samera2022/mouse_macros/manager/MacroManager.java L110-L125](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/MacroManager.java#L162-L163), [src/io/github/samera2022/mouse_macros/manager/MacroManager.java L211-L244](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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: ```mermaid flowchart TD MouseAction["MouseAction"] MouseMove["Mouse Move
type=MOUSE_MOVED
Uses: x, y, delay"] MousePress["Mouse Press
type=MOUSE_PRESSED
Uses: x, y, button, delay"] MouseRelease["Mouse Release
type=MOUSE_RELEASED
Uses: x, y, button, delay"] MouseWheel["Mouse Wheel
type=MOUSE_WHEEL
Uses: x, y, wheelAmount, delay"] KeyPress["Key Press
type=KEY_PRESSED
Uses: keyCode, awtKeyCode, delay"] KeyRelease["Key Release
type=KEY_RELEASED
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 ``` **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](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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. ```mermaid 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 ``` **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](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/MacroManager.java#L211-L244) ### Version Evolution ```mermaid flowchart TD V1["Version 1
5 fields
Basic mouse actions"] V2["Version 2
6 fields
+ Mouse wheel support"] V3["Version 3
7 fields
+ JNativeHook key codes"] V4["Version 4
8 fields
+ AWT key codes"] V1 --> V2 V2 --> V3 V3 --> V4 ``` **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](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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 ```mermaid flowchart TD Start["MacroManager.play()"] CheckEmpty["actions.isEmpty()"] StartThread["Start playThread"] RepeatLoop["Repeat Loop
(config.repeatTime)"] ActionLoop["Action Loop
(for each MouseAction)"] CheckAbort["playing == true?"] ApplyDelay["Thread.sleep(action.delay)
(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 ``` **Diagram: Playback Loop with MouseAction Execution** **Sources:** [src/io/github/samera2022/mouse_macros/manager/MacroManager.java L36-L93](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/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](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/MacroManager.java#L1-L256)