<spanclass="line"><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pmw33xx_init</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // index 1 is the second device.</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pmw33xx_set_cpi</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">800</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // applies to first sensor</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pmw33xx_set_cpi</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">800</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // applies to second sensor</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Contains report from sensor #0 already, need to merge in from sensor #1</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#endif</span></span></code></pre></div><h3id="custom-driver"tabindex="-1">Custom Driver <aclass="header-anchor"href="#custom-driver"aria-label="Permalink to "Custom Driver""></a></h3><p>If you have a sensor type that isn't supported above, a custom option is available by adding the following to your <code>rules.mk</code></p><divclass="language-make vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">make</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">POINTING_DEVICE_DRIVER = custom</span></span></code></pre></div><p>Using the custom driver will require implementing the following functions:</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_driver_init</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {}</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_driver_set_cpi</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint16_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> cpi</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {}</span></span></code></pre></div><divclass="warning custom-block"><pclass="custom-block-title">WARNING</p><p>Ideally, new sensor hardware should be added to <code>drivers/sensors/</code> and <code>quantum/pointing_device_drivers.c</code>, but there may be cases where it's very specific to the hardware. So these functions are provided, just in case.</p></div><h2id="common-configuration"tabindex="-1">Common Configuration <aclass="header-anchor"href="#common-configuration"aria-label="Permalink to "Common Configuration""></a></h2><table><thead><tr><th>Setting</th><th>Description</th><th>Default</th></tr></thead><tbody><tr><td><code>MOUSE_EXTENDED_REPORT</code></td><td>(Optional) Enables support for extended mouse reports. (-32767 to 32767, instead of just -127 to 127).</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_ROTATION_90</code></td><td>(Optional) Rotates the X and Y data by 90 degrees.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_ROTATION_180</code></td><td>(Optional) Rotates the X and Y data by 180 degrees.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_ROTATION_270</code></td><td>(Optional) Rotates the X and Y data by 270 degrees.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_INVERT_X</code></td><td>(Optional) Inverts the X axis report.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_INVERT_Y</code></td><td>(Optional) Inverts the Y axis report.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_MOTION_PIN</code></td><td>(Optional) If supported, will only read from sensor if pin is active.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW</code></td><td>(Optional) If defined then the motion pin is active-low.</td><td><em>varies</em></td></tr><tr><td><code>POINTING_DEVICE_TASK_THROTTLE_MS</code></td><td>(Optional) Limits the frequency that the sensor is polled for motion.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE</code></td><td>(Optional) Enable inertial cursor. Cursor continues moving after a flick gesture and slows down by kinetic friction.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_GESTURES_SCROLL_ENABLE</code></td><td>(Optional) Enable scroll gesture. The gesture that activates the scroll is device dependent.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_CS_PIN</code></td><td>(Optional) Provides a default CS pin, useful for supporting multiple sensor configs.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_SDIO_PIN</code></td><td>(Optional) Provides a default SDIO pin, useful for supporting multiple sensor configs.</td><td><em>not defined</em></td></tr><tr><td><code>POINTING_DEVICE_SCLK_PIN</code></td><td>(Optional) Provides a default SCLK pin, useful for supporting multiple sensor configs.</td><td><em>not defined</em></td></tr></tbody></table><divclass="warning custom-block"><pclass="custom-block-title">WARNING</p><p>When using <code>SPLIT_POINTING_ENABLE</code> the <code>POINTING_DEVICE_MOTION_PIN</code> functionality is not supported and <code>POINTING_DEVICE_TASK_THROTTLE_MS</code> will default to <code>1</code>. Increasing this value will increase transport performance at the cost of possible mouse responsiveness.</p></div><p>The <code>POINTING_DEVICE_CS_PIN</code>, <code>POINTING_DEVICE_SDIO_PIN</code>, and <code>POINTING_DEVICE_SCLK_PIN</code> provide a convenient way to define a single pin that can be used for an interchangeable sensor config. T
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> currentReport.buttons </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">|=</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> MOUSE_BTN1;</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // this is defined in report.h</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> break</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span></code></pre></div><p>Recall that the mouse report is set to zero (except the buttons) whenever it is sent, so the scrolling would only occur once in each case.</p><h3id="drag-scroll-or-mouse-scroll"tabindex="-1">Drag Scroll or Mouse Scroll <aclass="header-anchor"href="#drag-scroll-or-mouse-scroll"aria-label="Permalink to "Drag Scroll or Mouse Scroll""></a></h3><p>A very common implementation is to use the mouse movement to scroll instead of moving the cursor on the system. This uses the <code>pointing_device_task_user</code> callback to intercept and modify the mouse report before it's sent to the host system.</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">enum</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> custom_keycodes {</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>This allows you to toggle between scrolling and cursor movement by pressing the DRAG_SCROLL key.</p><h3id="advanced-drag-scroll"tabindex="-1">Advanced Drag Scroll <aclass="header-anchor"href="#advanced-drag-scroll"aria-label="Permalink to "Advanced Drag Scroll""></a></h3><p>Sometimes, like with the Cirque trackpad, you will run into issues where the scrolling may be too fast.</p><p>Here is a slightly more advanced example of drag scrolling. You will be able to change the scroll speed based on the values in set in <code>SCROLL_DIVISOR_H</code> and <code>SCROLL_DIVISOR_V</code>. This bit of code is also set up so that instead of toggling the scrolling state with set_scrolling = !set_scrolling, the set_scrolling variable is set directly to record->event.pressed. This way, the drag scrolling will only be active while the DRAG_SCROLL button is held down.</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">enum</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> custom_keycodes {</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Function to handle mouse reports and perform drag scrolling</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Calculate and accumulate scroll values based on mouse movement and divisors</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Assign integer parts of accumulated scroll values to the mouse report</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Function to handle key events and enable/disable drag scrolling</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Toggle set_scrolling when DRAG_SCROLL key is pressed or released</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Function to handle layer changes and disable drag scrolling when not in AUTO_MOUSE_DEFAULT_LAYER</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Disable set_scrolling if the current layer is not the AUTO_MOUSE_DEFAULT_LAYER</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h2id="split-examples"tabindex="-1">Split Examples <aclass="header-anchor"href="#split-examples"aria-label="Permalink to "Split Examples""></a></h2><p>The following examples make use the <code>SPLIT_POINTING_ENABLE</code> functionality and show how to manipulate the mouse report for a scrolling mode.</p><h3id="single-pointing-device"tabindex="-1">Single Pointing Device <aclass="header-anchor"href="#single-pointing-device"aria-label="Permalink to "Single Pointing Device""></a></h3><p>The following example will work with either <code>POINTING_DEVICE_LEFT</code> or <code>POINTING_DEVICE_RIGHT</code> and enables scrolling mode while on a particular layer.</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> case</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _RAISE:</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // If we're on the _RAISE layer enable scrolling mode</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (scrolling_mode) {</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // check if we were scrolling before and set disable if so</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h3id="combined-pointing-devices"tabindex="-1">Combined Pointing Devices <aclass="header-anchor"href="#combined-pointing-devices"aria-label="Permalink to "Combined Pointing Devices""></a></h3><p>The following example requires <code>POINTING_DEVICE_COMBINED</code> and sets the left side pointing device to scroll only.</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> keyboard_post_init_user</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_set_cpi_on_side</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1000</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //Set cpi on left side to a low value for slower scrolling.</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_set_cpi_on_side</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">8000</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //Set cpi on right side to a reasonable value for mousing.</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h1id="troubleshooting"tabindex="-1">Troubleshooting <aclass="header-anchor"href="#troubleshooting"aria-label="Permalink to "Troubleshooting""></a></h1><p>If you are having issues with pointing device drivers debug messages can be enabled that will give you insights in the inner workings. To enable these add to your keyboards <code>config.h</code> file:</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> POINTING_DEVICE_DEBUG</span></span></code></pre></div><divclass="tip custom-block"><pclass="custom-block-title">TIP</p><p>The messages will be printed out to the <code>CONSOLE</code> output. For additional information, refer to <ahref="./../faq_debug">Debugging/Troubleshooting QMK</a>.</p></div><hr><h1id="pointing-device-auto-mouse"tabindex="-1">Automatic Mouse Layer <aclass="header-anchor"href="#pointing-device-auto-mouse"aria-label="Permalink to "Automatic Mouse Layer {#pointing-device-auto-mouse}""></a></h1><p>When using a pointing device combined with a keyboard the mouse buttons are often kept on a separate layer from the default keyboard layer, which requires pressing or holding a key to change layers before using the mouse. To make this easier and more efficient an additional pointing device feature may be enabled that will automatically activate a target layer as soon as the pointing device is active <em>(in motion, mouse button pressed etc.)</em> and deactivate the target layer after a set time.</p><p>Additionally if any key that is defined as a mouse key is pressed then the layer will be held as long as the key is pressed and the timer will be reset on key release. When a non-mouse key is pressed then the layer is deactivated early <em>(with some exceptions see below)</em>. Mod, mod tap, and one shot mod keys are ignored <em>(i.e. don't hold or activate layer but do not deactivate the layer either)</em> when sending a modifier keycode <em>(e.g. hold for mod tap)</em> allowing for mod keys to be used with the mouse without activating the target layer when typing.</p><p>All of the standard layer keys (tap toggling, toggle, toggle on, one_shot, layer tap, layer mod) that activate the current target layer are uniquely handled to ensure they behave as expected <em>(see layer key table below)</em>. The target layer that can be changed at any point during by calling the <code>set_auto_mouse_layer(<new_target_layer>);</code> function.</p><h3id="behaviour-of-layer-keys-that-activate-the-target-layer"tabindex="-1">Behaviour of Layer keys that activate the target layer <aclass="header-anchor"href="#behaviour-of-layer-keys-that-activate-the-target-layer"aria-label="Permalink to "Behaviour of Layer keys that activate the target layer""></a></h3><table><thead><tr><th>Layer key as in <code>keymap.c</code></th><th>Auto Mouse specific behaviour</th></tr></thead><tbody><tr><td><code>MO(<target_layer>)</code></td><td>Treated as a mouse key holding the layer while pressed</td></tr><tr><td><code>LT(<target_layer>)</code></td><td>When tapped will be treated as non mouse key and mouse key when held</td></tr><tr><td><code>LM(<target_layer>)</code></td><td>Treated as a mouse key</td></tr><tr><td><code>TG(<target_layer>)</code></td><td>Will set flag preventing target layer deactivation or removal until pressed again</td></tr><tr><td><code>TO(<target_layer>)</code></td><td>Same as <code>TG(<target_layer>)</code></td></tr><tr><td><code>TT(<target_layer>)</code></td><td>Treated as a mouse key when <code>tap.count < TAPPING_TOGGLE</code> and as <code>TG</code> when <code>tap.count == TAPPING_TOGGLE</code></td></tr><tr><td><code>DF(<ta
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// only required if not setting mouse layer elsewhere</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AUTO_MOUSE_DEFAULT_LAYER</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"><</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">index of your mouse layer</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span></span>
<spanclass="line"></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// in keymap.c:</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> set_auto_mouse_layer</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"><</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">mouse_layer</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // only required if AUTO_MOUSE_DEFAULT_LAYER is not set to index of <mouse_layer></span></span>
<spanclass="line"><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> set_auto_mouse_enable</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // always required before the auto mouse feature will work</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>Because the auto mouse feature can be disabled/enabled during runtime and starts as disabled by default it must be enabled by calling <code>set_auto_mouse_enable(true);</code> somewhere in firmware before the feature will work.<br><em>Note: for setting the target layer during initialization either setting <code>AUTO_MOUSE_DEFAULT_LAYER</code> in <code>config.h</code> or calling <code>set_auto_mouse_layer(<mouse_layer>)</code> can be used.</em></p><h2id="how-to-customize"tabindex="-1">How to Customize: <aclass="header-anchor"href="#how-to-customize"aria-label="Permalink to "How to Customize:""></a></h2><p>There are a few ways to control the auto mouse feature with both <code>config.h</code> options and functions for controlling it during runtime.</p><h3id="config-h-options"tabindex="-1"><code>config.h</code> Options: <aclass="header-anchor"href="#config-h-options"aria-label="Permalink to "`config.h` Options:""></a></h3><table><thead><tr><th>Define</th><th>Description</th><thstyle="text-align:center;">Range</th><thstyle="text-align:center;">Units</th><thstyle="text-align:right;">Default</th></tr></thead><tbody><tr><td><code>POINTING_DEVICE_AUTO_MOUSE_ENABLE</code></td><td>(Required) Enables auto mouse layer feature</td><tdstyle="text-align:center;"></td><tdstyle="text-align:center;"><em>None</em></td><tdstyle="text-align:right;"><em>Not defined</em></td></tr><tr><td><code>AUTO_MOUSE_DEFAULT_LAYER</code></td><td>(Optional) Index of layer to use as default target layer</td><tdstyle="text-align:center;">0 - <code>LAYER_MAX</code></td><tdstyle="text-align:center;"><em><code>uint8_t</code></em></td><tdstyle="text-align:right;"><code>1</code></td></tr><tr><td><code>AUTO_MOUSE_TIME</code></td><td>(Optional) Time layer remains active after activation</td><tdstyle="text-align:center;"><em>ideally</em> (250-1000)</td><tdstyle="text-align:center;"><em>ms</em></td><tdstyle="text-align:right;"><code>650 ms</code></td></tr><tr><td><code>AUTO_MOUSE_DELAY</code></td><td>(Optional) Lockout time after non-mouse key is pressed</td><tdstyle="text-align:center;"><em>ideally</em> (100-1000)</td><tdstyle="text-align:center;"><em>ms</em></td><tdstyle="text-align:right;"><code>TAPPING_TERM</code> or <code>200 ms</code></td></tr><tr><td><code>AUTO_MOUSE_DEBOUNCE</code></td><td>(Optional) Time delay from last activation to next update</td><tdstyle="text-align:center;"><em>ideally</em> (10 - 100)</td><tdstyle="text-align:center;"><em>ms</em></td><tdstyle="text-align:right;"><code>25 ms</code></td></tr><tr><td><code>AUTO_MOUSE_THRESHOLD</code></td><td>(Optional) Amount of mouse movement required to switch layers</td><tdstyle="text-align:center;">0 -</td><tdstyle="text-align:center;"><em>units</em></td><tdstyle="text-align:right;"><code>10 units</code></td></tr></tbody></table><h3id="adding-mouse-keys"tabindex="-1">Adding mouse keys <aclass="header-anchor"href="#adding-mouse-keys"aria-label="Permalink to "Adding mouse keys""></a></h3><p>While all default mouse keys and layer keys(for current mouse layer) are treated as mouse keys, additional Keyrecords can be added to mouse keys by adding them to the is_mouse_record_* stack.</p><h4id="callbacks-for-setting-up-additional-key-codes-as-mouse-keys"tabindex="-1">Callbacks for setting up additional key codes as mouse keys: <aclass="header-anchor"href="#callbacks-for-setting-up-additional-key-codes-as-mouse-keys"aria-label="Permalink to "Callbacks for setting up additional key codes as mouse keys:""></a></h4><table><thead><tr><th>Callback</th><th>Description</th></tr></thead><tbody><tr><td><code>bool is_mouse_record_kb(uint16_t keycode, keyrecord_t* record)</code></td><td>keyboard level callback for adding mouse keys</td></tr><tr><td><code>bool is_mouse_record_user(uint16_t keycode, keyrecord_t* record)</code></td><td>user/keymap level callback for adding mouse keys</td></tr></tbody></table><h5id="
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// in <keyboard>.c:</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h2id="advanced-control"tabindex="-1">Advanced control <aclass="header-anchor"href="#advanced-control"aria-label="Permalink to "Advanced control""></a></h2><p>There are several functions that allow for more advanced interaction with the auto mouse feature allowing for greater control.</p><h3id="functions-to-control-auto-mouse-enable-and-target-layer"tabindex="-1">Functions to control auto mouse enable and target layer: <aclass="header-anchor"href="#functions-to-control-auto-mouse-enable-and-target-layer"aria-label="Permalink to "Functions to control auto mouse enable and target layer:""></a></h3><table><thead><tr><thstyle="text-align:left;">Function</th><th>Description</th><th>Aliases</th><thstyle="text-align:right;">Return type</th></tr></thead><tbody><tr><tdstyle="text-align:left;"><code>set_auto_mouse_enable(bool enable)</code></td><td>Enable or disable auto mouse (true:enable, false:disable)</td><td></td><tdstyle="text-align:right;"><code>void</code>(None)</td></tr><tr><tdstyle="text-align:left;"><code>get_auto_mouse_enable(void)</code></td><td>Return auto mouse enable state (true:enabled, false:disabled)</td><td><code>AUTO_MOUSE_ENABLED</code></td><tdstyle="text-align:right;"><code>bool</code></td></tr><tr><tdstyle="text-align:left;"><code>set_auto_mouse_layer(uint8_t LAYER)</code></td><td>Change/set the target layer for auto mouse</td><td></td><tdstyle="text-align:right;"><code>void</code>(None)</td></tr><tr><tdstyle="text-align:left;"><code>get_auto_mouse_layer(void)</code></td><td>Return auto mouse target layer index</td><td><code>AUTO_MOUSE_TARGET_LAYER</code></td><tdstyle="text-align:right;"><code>uint8_t</code></td></tr><tr><tdstyle="text-align:left;"><code>remove_auto_mouse_layer(layer_state_t state, bool force)</code></td><td>Return <code>state</code> with target layer removed if appropriate (ignore criteria if <code>force</code>)</td><td></td><tdstyle="text-align:right;"><code>layer_state_t</code></td></tr><tr><tdstyle="text-align:left;"><code>auto_mouse_layer_off(void)</code></td><td>Disable target layer if appropriate will call (makes call to <code>layer_state_set</code>)</td><td></td><tdstyle="text-align:right;"><code>void</code>(None)</td></tr><tr><tdstyle="text-align:left;"><code>auto_mouse_toggle(void)</code></td><td>Toggle on/off target toggle state (disables layer deactivation when true)</td><td></td><tdstyle="text-align:right;"><code>void</code>(None)</td></tr><tr><tdstyle="text-align:left;"><code>get_auto_mouse_toggle(void)</code></td><td>Return value of toggling state variable</td><td></td><tdstyle="text-align:right;"><code>bool</code></td></tr><tr><tdstyle="text-align:left;"><code>set_auto_mouse_timeout(uint16_t timeout)</code></td><td>Change/set the timeout for turing off the layer</td><td></td><tdstyle="text-align:right;"><code>void</code>(None)</td></tr><tr><tdstyle="text-align:left;"><code>get_auto_mouse_timeout(void)</code></td><td>Return the current timeout for turing off the layer</td><td></td><tdstyle="text-align:right;"><code>uint16_t</code></td></tr><tr><tdstyle="text-align:left;"><code>set_auto_mouse_debounce(uint16_t timeout)</code></td><td>Change/set the debounce for preventing layer activation</td><td></td><tdstyle="text-align:right;"><code>void</code>(None)</td></tr><tr><tdstyle="text-align:left;"><code>get_auto_mouse_debounce(void)</code></td><td>Return the current debounce for preventing layer activation</td><td></td><tdstyle="text-align:right;"><code>uint8_t</code></td></tr><tr><tdstyle="text-align:left;"><code>is_auto_mouse_active(void)</code></td><td>Returns the active state of the auto mouse layer (eg if the layer has been triggered)</td><td></td><tdstyle="text-align:right;"><code>bool</code></td></tr><tr><tdstyle="text-align:left;"><code>get_auto_mouse_key_tracker(void)</code></td><td>Gets the current count for the auto mouse key tracker.</td><td></td><tdstyle="text-align:right;"><code>int8_t</code>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // remove_auto_mouse_target must be called to adjust state *before* setting enable</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> state </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> remove_auto_mouse_layer</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(state, </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // recommend that any code that makes adjustment based on auto mouse layer state would go here</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h4id="set-different-target-layer-when-a-particular-layer-is-active"tabindex="-1">Set different target layer when a particular layer is active: <aclass="header-anchor"href="#set-different-target-layer-when-a-particular-layer-is-active"aria-label="Permalink to "Set different target layer when a particular layer is active:""></a></h4><p>The below code will change the auto mouse layer target to <code>_MOUSE_LAYER_2</code> when <code>_DEFAULT_LAYER_2</code> is highest default layer state.</p><p><em>NOTE: that <code>auto_mouse_layer_off</code> is used here instead of <code>remove_auto_mouse_layer</code> as <code>default_layer_state_set_*</code> stack is separate from the <code>layer_state_set_*</code> stack</em>, if something similar was to be done in <code>layer_state_set_user</code>, <code>state = remove_auto_mouse_layer(state, false)</code> should be used instead.</p><p><em>ADDITIONAL NOTE: <code>AUTO_MOUSE_TARGET_LAYER</code> is checked if already set to avoid deactivating the target layer unless needed</em>.</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// in keymap.c</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // switch on change in default layer need to check if target layer already set to avoid turning off layer needlessly</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h3id="use-custom-keys-to-control-auto-mouse"tabindex="-1">Use custom keys to control auto mouse: <aclass="header-anchor"href="#use-custom-keys-to-control-auto-mouse"aria-label="Permalink to "Use custom keys to control auto mouse:""></a></h3><p>Custom key records could also be created that control the auto mouse feature.<br> The code example below would create a custom key that would toggle the auto mouse feature on and off when pressed while also setting a bool that could be used to disable other code that may turn it on such as the layer code above.</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// in config.h:</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // do nothing on key up</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> false</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // prevent further processing of keycode</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h2id="customize-target-layer-activation"tabindex="-1">Customize Target Layer Activation <aclass="header-anchor"href="#customize-target-layer-activation"aria-label="Permalink to "Customize Target Layer Activation""></a></h2><p>Layer activation can be customized by overwriting the <code>auto_mouse_activation</code> function. This function is checked every time <code>pointing_device_task</code> is called when inactive and every <code>AUTO_MOUSE_DEBOUNCE</code> ms when active, and will evaluate pointing device level conditions that trigger target layer activation. When it returns true, the target layer will be activated barring the usual exceptions <em>(e.g. delay time has not expired)</em>.</p><p>By default it will return true if any of the <code>mouse_report</code> axes <code>x</code>,<code>y</code>,<code>h</code>,<code>v</code> are non zero, or if there is any mouse buttons active in <code>mouse_report</code>. <em>Note: The Cirque pinnacle track pad already implements a custom activation function that will activate on touchdown as well as movement all of the default conditions, currently this only works for the master side of split keyboards.</em></p><table><thead><tr><thstyle="text-align:left;">Function</th><th>Description</th><thstyle="text-align:right;">Return type</th></tr></thead><tbody><tr><tdstyle="text-align:left;"><code>auto_mouse_activation(report_mouse_t mouse_report)</code></td><td>Overwritable function that controls target layer activation (when true)</td><tdstyle="text-align:right;"><code>bool</code></td></tr></tbody></table><h2id="auto-mouse-for-custom-pointing-device-task"tabindex="-1">Auto Mouse for Custom Pointing Device Task <aclass="header-anchor"href="#auto-mouse-for-custom-pointing-device-task"aria-label="Permalink to "Auto Mouse for Custom Pointing Device Task""></a></h2><p>When using a custom pointing device (overwriting <code>pointing_device_task</code>) the following code should be somewhere in the <code>pointing_device_task_*</code> stack:</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">bool</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_task</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>In general the following two functions must be implemented in appropriate locations for auto mouse to function:</p><table><thead><tr><th>Function</th><th>Description</th><thstyle="text-align:right;">Suggested location</th></tr></thead><tbody><tr><td><code>pointing_device_task_auto_mouse(report_mouse_t mouse_report)</code></td><td>handles target layer activation and is_active status updates</td><tdstyle="text-align:right;"><code>pointing_device_task</code> stack</td></tr><tr><td><code>process_auto_mouse(uint16_t keycode, keyrecord_t* record)</code></td><td>Keycode processing for auto mouse</td><tdstyle="text-align:right;"><code>process_record</code> stack</td></tr></tbody></table></div></div></main><footerclass="VPDocFooter"data-v-39a288b8data-v-09de1c0f><!--[--><!--]--><!----><navclass="prev-next"data-v-09de1c0f><divclass="pager"data-v-09de1c0f><aclass="VPLink link pager-link prev"href="/features/midi"data-v-09de1c0f><!--[--><spanclass="desc"data-v-09de1c0f>Previous page</span><spanclass="title"data-v-09de1c0f>MIDI</span><!--]--></a></div><divclass="pager"data-v-09de1c0f><aclass="VPLink link pager-link next"href="/features/ps2_mouse"data-v-09de1c0f><!--[--><spanclass="desc"data-v-09de1c0f>Next page</span><spanclass="title"data-v-09de1c0f>PS/2 Mouse</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>