-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Relevant source files
MouseMacros is a Java desktop application for recording and replaying mouse and keyboard input events. The application uses JNativeHook for global event capture and java.awt.Robot for input simulation. The codebase is located at https://github.com/Samera2022/MouseMacros.
This wiki documents the application's architecture, component interactions, configuration system, and implementation details. For installation instructions, see Getting Started. For architectural details, see Architecture Overview.
Sources: README.md L1-L6
The application provides four primary operations:
| Operation | Default Hotkey | Implementation |
|---|---|---|
| Record | F2 |
MacroManager.startRecording() captures mouse movements, button clicks (left/right/middle), scroll wheel events, and keyboard inputs via GlobalMouseListener
|
| Stop Recording | F3 |
MacroManager.stopRecording() terminates event capture |
| Save/Load | UI buttons |
MacroManager.saveToFile() and loadFromFile() persist macros as CSV-formatted .mmc files |
| Playback | F4 |
MacroManager.play() executes recorded actions using java.awt.Robot
|
| Abort | F5 |
MacroManager.abort() emergency stop for runaway macros |
System Requirements:
- Java Runtime Environment (JRE) 1.8+
- Configuration storage:
%USERPROFILE%/AppData/MouseMacros/(Windows),~/Library/Application Support/MouseMacros(macOS),~/.local/share/MouseMacros(Linux)
Sources: README.md L25-L48, src/io/github/samera2022/mouse_macros/manager/MacroManager.java L1-L300
| Feature | Description |
|---|---|
| Comprehensive Recording | Captures all mouse buttons (left/right/middle), scroll wheel movements, and keyboard inputs |
| Global Hotkeys | Customizable hotkeys for Start/Stop Recording, Play Macro, and Abort (emergency stop) |
| Multi-Language Support | Built-in localization for English (US) and Simplified Chinese, with extensible architecture |
| Theme Engine | Light and Dark modes with optional automatic synchronization with OS system settings |
| Persistence | Macros saved as .mmc files in human-readable CSV format, allowing manual editing |
| Smart Memory | Caches window sizes, last-used directories, and custom configurations across sessions |
Sources: README.md L23-L34
The MouseMacro class contains the main() method and performs bootstrap operations:
flowchart TD
Main["MouseMacro.main"]
GetConfigDir["ConfigManager.CONFIG_DIR"]
LibsDir["new File(CONFIG_DIR, libs/)"]
CreateDir["libsDir.mkdirs()"]
SetProperty["System.setProperty(jnativehook.lib.path)"]
InvokeLater["SwingUtilities.invokeLater()"]
ShowFrame["MainFrame.MAIN_FRAME.setVisible(true)"]
Main --> GetConfigDir
GetConfigDir --> LibsDir
LibsDir --> CreateDir
CreateDir --> SetProperty
SetProperty --> InvokeLater
InvokeLater --> ShowFrame
Bootstrap Sequence
The initialization sequence:
-
Native Library Path Configuration: Creates
CONFIG_DIR/libs/directory and setsjnativehook.lib.pathsystem property to this location for JNativeHook DLL/SO files -
EDT Thread Initialization: Uses
SwingUtilities.invokeLater()to initializeMainFrame.MAIN_FRAMEon the Event Dispatch Thread
Sources: src/io/github/samera2022/mouse_macros/MouseMacro.java L1-L16
The codebase follows a layered architecture with separation between input capture, business logic, persistence, and UI:
flowchart TD
MouseMacro["MouseMacro.java<br>(main entry)"]
ConfigManager["ConfigManager.java<br>(config.cfg)"]
CacheManager["CacheManager.java<br>(cache.json)"]
MacroManager["MacroManager.java<br>(record/playback)"]
GlobalMouseListener["GlobalMouseListener.java<br>(JNativeHook events)"]
MouseAction["MouseAction.java<br>(event data model)"]
Config["Config.java"]
Cache["Cache.java"]
MainFrame["MainFrame.java"]
SettingsDialog["SettingsDialog.java"]
MacroSettingsDialog["MacroSettingsDialog.java"]
ExitDialog["ExitDialog.java"]
FileUtil["FileUtil.java"]
ComponentUtil["ComponentUtil.java"]
ScreenUtil["ScreenUtil.java"]
Localizer["Localizer.java"]
MouseMacro --> MainFrame
MouseMacro --> ConfigManager
MainFrame --> MacroManager
MainFrame --> GlobalMouseListener
GlobalMouseListener --> MacroManager
MacroManager --> MouseAction
MacroManager --> FileUtil
ConfigManager --> Config
ConfigManager --> FileUtil
CacheManager --> Cache
CacheManager --> FileUtil
MainFrame --> ComponentUtil
MainFrame --> Localizer
subgraph util/ ["util/"]
FileUtil
ComponentUtil
ScreenUtil
Localizer
end
subgraph ui/ ["ui/"]
MainFrame
SettingsDialog
MacroSettingsDialog
ExitDialog
MainFrame --> SettingsDialog
MainFrame --> MacroSettingsDialog
end
subgraph data/ ["data/"]
MouseAction
Config
Cache
end
subgraph listener/ ["listener/"]
GlobalMouseListener
end
subgraph manager/ ["manager/"]
ConfigManager
CacheManager
MacroManager
end
subgraph src/io/github/samera2022/mouse_macros/ ["src/io/github/samera2022/mouse_macros/"]
MouseMacro
end
Package Structure
| Package | Purpose | Key Classes |
|---|---|---|
manager/ |
State and configuration management |
MacroManager, ConfigManager, CacheManager
|
listener/ |
Global input event capture | GlobalMouseListener |
data/ |
Data models |
MouseAction, Config, Cache
|
ui/ |
Swing UI components |
MainFrame, SettingsDialog, MacroSettingsDialog
|
util/ |
Cross-cutting utilities |
FileUtil, ComponentUtil, ScreenUtil, Localizer
|
constants/ |
Static configuration |
ColorConsts, KeyConsts
|
Sources: src/io/github/samera2022/mouse_macros/MouseMacro.java L1-L16, src/io/github/samera2022/mouse_macros/manager/MacroManager.java L1-L50, src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java L1-L50
The recording and playback system uses the following execution flow:
sequenceDiagram
participant User
participant MainFrame
participant GlobalMouseListener
participant JNativeHook
participant MacroManager
participant MouseAction
participant Robot
participant FileSystem
note over User,FileSystem: Recording Phase
User->>MainFrame: Press F2
MainFrame->>MacroManager: startRecording()
MacroManager->>MacroManager: recording = true
User->>JNativeHook: actions.clear()
JNativeHook->>GlobalMouseListener: Mouse/keyboard event
GlobalMouseListener->>MacroManager: nativeMousePressed()
MacroManager->>MouseAction: nativeMouseMoved()
MacroManager->>MacroManager: nativeKeyPressed()
User->>MainFrame: recordAction()
MainFrame->>MacroManager: new MouseAction(x,y,type,button,delay)
MacroManager->>MacroManager: actions.add(mouseAction)
note over User,FileSystem: Save Phase
User->>MainFrame: Press F3
MainFrame->>MacroManager: stopRecording()
MacroManager->>FileSystem: recording = false
note over User,FileSystem: Playback Phase
User->>MainFrame: Click "Save Macro"
MainFrame->>MacroManager: saveToFile()
MacroManager->>FileSystem: Write CSV to .mmc file
FileSystem->>MacroManager: Click "Load Macro"
User->>MainFrame: loadFromFile()
MainFrame->>MacroManager: Read CSV from .mmc file
loop [For each action]
MacroManager->>MouseAction: List<MouseAction>
MouseAction->>Robot: Press F4
MouseAction->>MouseAction: play()
end
Event Flow Mapping
| Phase | User Action | Code Path | Result |
|---|---|---|---|
| Record Start | F2 hotkey |
MainFrame → MacroManager.startRecording()
|
Sets recording = true, clears actions list |
| Event Capture | Mouse/keyboard input |
JNativeHook → GlobalMouseListener.nativeXXX() → MacroManager.recordAction()
|
Creates MouseAction objects, adds to actions list |
| Record Stop | F3 hotkey |
MainFrame → MacroManager.stopRecording()
|
Sets recording = false
|
| Save | Save button |
MainFrame → MacroManager.saveToFile()
|
Writes actions to CSV .mmc file |
| Load | Load button |
MainFrame → MacroManager.loadFromFile()
|
Reads CSV file, populates actions list |
| Playback | F4 hotkey |
MainFrame → MacroManager.play() → MouseAction.execute()
|
Iterates actions, calls Robot methods |
Sources: src/io/github/samera2022/mouse_macros/manager/MacroManager.java L1-L300, src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java L1-L200, src/io/github/samera2022/mouse_macros/data/MouseAction.java L1-L150
The application uses multiple persistence mechanisms:
| File | Manager Class | Purpose | Format | Location |
|---|---|---|---|---|
config.cfg |
ConfigManager |
User preferences (language, theme, hotkeys, storage paths) | JSON | ConfigManager.CONFIG_DIR |
cache.json |
CacheManager |
Session state (window sizes, recent directories, exit behavior) | JSON | ConfigManager.CONFIG_DIR |
*.mmc |
MacroManager |
Recorded macro data | CSV (8 fields) | User-specified |
lang/*.json |
Localizer |
Translation strings | JSON | Classpath resources |
File Location Resolution:
- Windows:
%LOCALAPPDATA%/MouseMacros/ - macOS:
~/Library/Application Support/MouseMacros/ - Linux:
~/.local/share/MouseMacros/
Implemented in FileUtil.getLocalStoragePath().
The Config class (managed by ConfigManager) stores the following fields:
| Field | Type | Default | Description |
|---|---|---|---|
followSystemSettings |
boolean | true | Sync language/theme with OS |
lang |
String | OS locale | Language code (en_us, zh_cn, ja_jp, etc.) |
enableDarkMode |
boolean | false | Dark theme toggle |
enableDefaultStorage |
boolean | false | Use defaultMmcStoragePath for all file operations |
defaultMmcStoragePath |
String | User documents | Default directory for .mmc files |
enableQuickMode |
boolean | false | Ignore delays during playback |
enableCustomMacroSettings |
boolean | false | Enable repeatTime and repeatDelay
|
repeatTime |
int | 1 | Playback iteration count |
repeatDelay |
double | 0.0 | Delay between iterations (seconds) |
allowLongStr |
boolean | false | Tooltip display mode |
readjustFrameMode |
String | "MIXED" | Window resizing strategy (MIXED, STANDARDIZED, MEMORIZED) |
keyMap |
Map<String,String> | F2-F5 | Hotkey bindings (record, stop, play, abort) |
Sources: README.md L62-L90, src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L1-L200, src/io/github/samera2022/mouse_macros/data/Config.java L1-L100
| Component | Technology | Location in Code |
|---|---|---|
| Language | Java 1.8+ | Entire codebase |
| UI Framework | Swing |
ui/ package |
| Global Hooks | JNativeHook | Native library in CONFIG_DIR/libs/, interfaced via GlobalMouseListener
|
| Input Simulation | java.awt.Robot |
MouseAction.execute() |
| Configuration Format | JSON | Parsed in ConfigManager and CacheManager using com.google.gson
|
| Macro Format | CSV | Parsed in MacroManager.loadFromFile()
|
| Localization | JSON | Loaded by Localizer from src/lang/*.json
|
| System Tray | java.awt.SystemTray |
MainFrame system tray integration |
External Dependencies:
-
jnativehook-2.1.0.jar- Global keyboard/mouse event capture -
gson-2.8.x.jar- JSON serialization/deserialization
Sources: README.md L10-L12, src/io/github/samera2022/mouse_macros/MouseMacro.java L1-L16, src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L1-L50
Typical Workflow:
- Launch
MouseMacros.jar(Java 1.8+) orMouseMacros.exe(bundled JRE) - Press F2 →
MainFramecallsMacroManager.startRecording() - Perform mouse/keyboard actions →
GlobalMouseListenercaptures events - Press F3 →
MainFramecallsMacroManager.stopRecording() - Click Save Macro →
MacroManager.saveToFile()writes CSV to.mmcfile - Click Load Macro →
MacroManager.loadFromFile()reads.mmcfile - Press F4 →
MacroManager.play()executes actions viaRobot
For installation details, see Getting Started. For configuration options, see Configuration System.
Sources: README.md L38-L62
| Section | Coverage |
|---|---|
| Getting Started | Installation, JRE requirements, first-time setup |
| Architecture Overview | Component design, data flow, package structure |
| Macro Recording and Playback |
MacroManager, GlobalMouseListener, MouseAction, .mmc format |
| Configuration and Persistence |
ConfigManager, CacheManager, config.cfg, cache.json
|
| Internationalization and Localization |
Localizer, language files, supported locales |
| User Interface Components |
MainFrame, dialogs, theming system, ComponentUtil
|
| Utility Classes |
FileUtil, ScreenUtil, SystemUtil, logging |
| Constants and Resources |
ColorConsts, KeyConsts, static resources |
| Version History |
UpdateInfo enum, release notes, changelog |
Sources: README.md L1-L106
MouseMacros is licensed under the GNU General Public License v3.0 (GPL-3.0). This is a copyleft license that requires derivative works to also be open source under compatible terms. For complete license text, see License and Legal.
Sources: LICENSE L1-L675, README.md L93-L94