Documentation/Configuration.md
The LinearMouse configuration is stored in ~/.config/linearmouse/linearmouse.json.
If the configuration file does not exist, LinearMouse will create an empty configuration automatically.
Note
It's preferable to use the GUI to alter settings rather than manually updating configuration unless you want to use advanced features.
Note
JSON5 is not supported yet. Writing comments in configuration will raise a parsing error.
Here is a simple example of LinearMouse configuration.
{
"$schema": "https://app.linearmouse.org/schema/0.7.2",
"schemes": [
{
"if": {
"device": {
"category": "mouse"
}
},
"scrolling": {
"reverse": {
"vertical": true
}
}
}
]
}
This configuration reverses the vertical scrolling direction for any mouse connected to your device.
As you can see, $schema defines the JSON schema of the LinearMouse configuration, which enables
autocompletion in editors like VS Code.
SON schemas are published for each LinearMouse version. Backward compatibility is guaranteed for the same major versions.
A scheme is a collection of settings that are activated in specified circumstances.
For example, in get started, we defined a scheme. The if field instructs
LinearMouse to activate this scheme only when the active device is a mouse:
{
"if": {
"device": {
"category": "mouse"
}
}
}
And the scrolling field in this scheme defines the scrolling behaviors, with
"reverse": { "vertical": true } reversing the vertical scrolling direction:
{
"scrolling": {
"reverse": {
"vertical": true
}
}
}
scrolling.smoothed enables a phase-aware scrolling curve that can be tuned separately for
vertical and horizontal scrolling. You can choose a preset such as easeIn, easeOut,
easeInOut, quadratic, cubic, easeOutCubic, easeInOutCubic, quartic,
easeOutQuartic, easeInOutQuartic, smooth, or custom, then fine-tune response,
speed, acceleration, and inertia as needed.
Set enabled to false to explicitly disable an inherited smoothed scrolling configuration for a
direction.
Set bouncing to false to avoid rubber-band overscroll when smoothed scrolling emits synthetic
continuous scroll events. This keeps the smoothed momentum tail, but sends it without scroll
phase/momentum phase markers so apps are less likely to treat it like a trackpad gesture.
For example, to use a smoother scrolling profile for a mouse:
{
"schemes": [
{
"if": {
"device": {
"category": "mouse"
}
},
"scrolling": {
"smoothed": {
"enabled": true,
"preset": "easeInOut",
"response": 0.45,
"speed": 1,
"acceleration": 1.2,
"inertia": 0.65,
"bouncing": false
}
}
}
]
}
If you want different tuning for each direction, provide vertical and horizontal values under
smoothed.
Vendor ID and product ID can be provided to match a specific device.
You may find these values in About This Mac → System Report... → Bluetooth / USB.
For example, to configure pointer speed of my Logitech mouse and Microsoft mouse respectively, I would create two schemes and specify the vendor ID and product ID:
{
"schemes": [
{
"if": {
"device": {
"vendorID": "0x046d",
"productID": "0xc52b"
}
},
"pointer": {
"acceleration": 0,
"speed": 0.36
}
},
{
"if": {
"device": {
"vendorID": "0x045e",
"productID": "0x0827"
}
},
"pointer": {
"acceleration": 0,
"speed": 0.4
}
}
]
}
Then, the pointer speed of my Logitech mouse and Microsoft mouse will be set to 0.36 and 0.4 respectively.
LinearMouse supports a special "unset" value to explicitly restore settings back to their system or device defaults. This differs from omitting a field, which keeps the previously merged value.
Currently, "unset" is supported for pointer acceleration and speed.
{
"schemes": [
{
"if": {
"device": { "category": "mouse" }
},
"pointer": { "acceleration": "unset", "speed": "unset" }
}
]
}
App bundle ID can be provided to match a specific app.
For example, to modify the pointer acceleration in Safari for my Logitech mouse:
{
"schemes": [
{
"if": {
"device": {
"vendorID": "0x046d",
"productID": "0xc52b"
},
"app": "com.apple.Safari"
},
"pointer": {
"acceleration": 0.5
}
}
]
}
Or, to disable reverse scrolling in Safari for all devices:
{
"schemes": [
{
"if": {
"app": "com.apple.Safari"
},
"scrolling": {
"reverse": {
"vertical": false,
"horizontal": false
}
}
}
]
}
By default, LinearMouse checks the app bundle ID of the frontmost process. However, in some
circumstances, a program might not be placed in a specific application bundle. In that case, you
may specify the app bundle ID of the parent process or the process group of the frontmost process
by specify parentApp and groupApp.
For example, to match the Minecraft (a Java process) launched by PolyMC:
{
"schemes": [
{
"if": {
"parentApp": "org.polymc.PolyMC"
}
}
]
}
Or, to match the whole process group:
{
"schemes": [
{
"if": {
"groupApp": "org.polymc.PolyMC"
}
}
]
}
Some programs do not have a stable or any bundle identifier. You can match by the frontmost process's executable instead.
{
"schemes": [
{
"if": {
"processName": "wezterm"
},
"scrolling": { "reverse": false }
}
]
}
{
"schemes": [
{
"if": {
"processPath": "/Applications/WezTerm.app/Contents/MacOS/WezTerm"
},
"pointer": { "acceleration": 0.4 }
}
]
}
Notes
Display name can be provided to match a specific display.
For example, to modify the pointer acceleration on DELL P2415Q:
{
"schemes": [
{
"if": {
"device": {
"vendorID": "0x046d",
"productID": "0xc52b"
},
"display": "DELL P2415Q"
},
"pointer": {
"acceleration": 0.5
}
}
]
}
ifsIf multiple schemes are activated at the same time, they will be merged in the order of their definitions.
Additionally, if multiple ifs are specified, the scheme will be activated as long as any of them
is satisfied.
For example, the configuration above can alternatively be written as:
{
"schemes": [
{
"if": [
{
"device": {
"vendorID": "0x046d",
"productID": "0xc52b"
}
},
{
"device": {
"vendorID": "0x045e",
"productID": "0x0827"
}
}
],
"pointer": {
"acceleration": 0
}
},
{
"if": {
"device": {
"vendorID": "0x046d",
"productID": "0xc52b"
}
},
"pointer": {
"speed": 0.36
}
},
{
"if": {
"device": {
"vendorID": "0x045e",
"productID": "0x0827"
}
},
"pointer": {
"speed": 0.4
}
}
]
}
Or, with fewer lines but more difficult to maintain:
{
"schemes": [
{
"if": [
{
"device": {
"vendorID": "0x046d",
"productID": "0xc52b"
}
},
{
"device": {
"vendorID": "0x045e",
"productID": "0x0827"
}
}
],
"pointer": {
"acceleration": 0,
"speed": 0.36
}
},
{
"if": {
"device": {
"vendorID": "0x045e",
"productID": "0x0827"
}
},
"pointer": {
"speed": 0.4
}
}
]
}
Button mappings is a list that allows you to assign actions to buttons or scroll wheels. For example, to open Launchpad when the wheel button is clicked, or to switch spaces when <kbd>command + back</kbd> or <kbd>command + forward</kbd> is clicked.
{
"schemes": [
{
"if": [
{
"device": {
"category": "mouse"
}
}
],
"buttons": {
"mappings": [
{
"button": 2,
"action": "launchpad"
}
]
}
}
]
}
In this example, the wheel button is bound to open Launchpad.
"button": 2 denotes the auxiliary button, which is usually the wheel button.
The following table lists all the buttons:
| Button | Description |
|---|---|
| 0 | Primary button, usually the left button. |
| 1 | Secondary button, usually the right button. |
| 2 | Auxiliary button, usually the wheel button or the middle button. |
| 3 | The fourth button, typically the back button. |
| 4 | The fifth button, typically the forward button. |
| 5-31 | Other buttons. |
{ "action": { "run": "open -a Launchpad" } } assigns a shell command open -a LaunchPad to
the button. When the button is clicked, the shell command will be executed.
In this example, <kbd>command + forward</kbd> is bound to open Mission Control.
{
"schemes": [
{
"if": [
{
"device": {
"category": "mouse"
}
}
],
"buttons": {
"mappings": [
{
"button": 4,
"command": true,
"action": "missionControl"
}
]
}
}
]
}
"command": true denotes that <kbd>command</kbd> should be pressed.
You can specify shift, option and control as well.
missionControl.spaceLeft and missionControl.spaceRight can be used to move left and right a space.
{
"schemes": [
{
"if": [
{
"device": {
"category": "mouse"
}
}
],
"buttons": {
"mappings": [
{
"button": 3,
"command": true,
"action": "missionControl.spaceLeft"
},
{
"button": 4,
"command": true,
"action": "missionControl.spaceRight"
}
]
}
}
]
}
Note
You will have to grant an additional permission to allow LinearMouse to simulate keys.
With repeat: true, actions will be repeated until the button is up.
In this example, <kbd>option + back</kbd> and <kbd>option + forward</kbd> is bound to volume down and volume up.
If you hold <kbd>option + back</kbd>, the volume will continue to decrease.
Note
If you disabled key repeat in System Settings,repeat: truewill not work. If you change key repeat rate or delay until repeat in System Settings, you have to restart LinearMouse to take effect.
{
"schemes": [
{
"if": [
{
"device": {
"category": "mouse"
}
}
],
"buttons": {
"mappings": [
{
"button": 4,
"repeat": true,
"option": true,
"action": "media.volumeUp"
},
{
"button": 3,
"repeat": true,
"option": true,
"action": "media.volumeDown"
}
]
}
}
]
}
With hold: true, keyboard shortcut actions stay pressed for as long as the mouse button is held.
This is different from repeat: true:
repeat: true keeps sending the shortcut over and over.hold: true sends key down when the mouse button is pressed, then key up when it is released.This is useful for apps that expect a real held key, such as timeline scrubbing or temporary tools.
{
"schemes": [
{
"if": {
"device": {
"category": "mouse"
}
},
"buttons": {
"mappings": [
{
"button": 3,
"hold": true,
"action": {
"keyPress": ["c"]
}
}
]
}
}
]
}
scroll can be specified instead of button to map scroll events to specific actions.
{
"schemes": [
{
"if": [
{
"device": {
"category": "mouse"
}
}
],
"buttons": {
"mappings": [
{
"scroll": "up",
"option": true,
"action": "media.volumeUp"
},
{
"scroll": "down",
"option": true,
"action": "media.volumeDown"
}
]
}
}
]
}
{
"schemes": [
{
"if": [
{
"device": {
"category": "mouse"
}
}
],
"buttons": {
"mappings": [
{
"button": 3,
"action": "mouse.button.forward"
},
{
"button": 4,
"action": "mouse.button.back"
}
]
}
}
]
}
A simple action is an action without any parameters.
{
"action": "<action>"
}
<action> could be one of:
| Action | Description |
|---|---|
auto | Do not modify the button behavior. |
none | Prevent the button events. |
missionControl | Mission Control. |
missionControl.spaceLeft | Mission Control: Move left a space. |
missionControl.spaceRight | Mission Control: Move right a space. |
appExpose | App Exposé. |
launchpad | Launchpad. |
showDesktop | Show desktop. |
showDesktop | Show desktop. |
lookUpAndDataDetectors | Look up & data detectors. |
smartZoom | Smart zoom. |
display.brightnessUp | Display: Brightness up. |
display.brightnessDown | Display: Brightness down. |
media.volumeUp | Media: Volume up. |
media.volumeDown | Media: Volume down. |
media.mute | Media: Toggle mute. |
media.playPause | Media: Play / pause. |
media.next | Media: Next. |
media.previous | Media: Previous. |
media.fastForward | Media: Fast forward. |
media.rewind | Media: Rewind. |
keyboard.brightnessUp | Keyboard: Brightness up. |
keyboard.brightnessDown | Keyboard: Brightness down. |
mouse.wheel.scrollUp | Mouse: Wheel: Scroll up. |
mouse.wheel.scrollDown | Mouse: Wheel: Scroll down. |
mouse.wheel.scrollLeft | Mouse: Wheel: Scroll left. |
mouse.wheel.scrollRight | Mouse: Wheel: Scroll right. |
mouse.button.left | Mouse: Button: Act as left button. |
mouse.button.middle | Mouse: Button: Act as middle button. |
mouse.button.right | Mouse: Button: Act as right button. |
mouse.button.back | Mouse: Button: Act as back button. |
mouse.button.forward | Mouse: Button: Act as forward button. |
{
"action": {
"run": "<command>"
}
}
The <command> will be executed with bash.
{
"action": {
"mouse.wheel.scrollUp": 2
}
}
{
"action": {
"mouse.wheel.scrollLeft": "32px"
}
}
{
"action": {
"keyPress": ["shift", "command", "4"]
}
}
To see the full list of keys, please refer to Configuration.d.ts#L652.
LinearMouse supports all numpad keys for keyboard shortcuts:
numpad0, numpad1, numpad2, numpad3, numpad4, numpad5, numpad6, numpad7, numpad8, numpad9numpadPlus, numpadMinus, numpadMultiply, numpadDivide, numpadEqualsnumpadEnter, numpadDecimal, numpadClearExample usage:
{
"action": {
"keyPress": ["numpad5"]
}
}
The redirectsToScroll property allows you to redirect pointer movements to scroll events. This is useful for scenarios where you want mouse movements to control scrolling instead of cursor positioning.
{
"schemes": [
{
"if": {
"device": {
"category": "mouse"
}
},
"pointer": {
"redirectsToScroll": true
}
}
]
}
When redirectsToScroll is set to true, horizontal mouse movements will generate horizontal scroll events, and vertical mouse movements will generate vertical scroll events.