qmk_firmware/feature_pointing_device.html

259 lines
241 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Pointing Device | QMK Firmware</title>
<meta name="description" content="Documentation for QMK Firmware">
<meta name="generator" content="VitePress v1.1.3">
<link rel="preload stylesheet" href="/assets/style.No8zk9aC.css" as="style">
<script type="module" src="/assets/app.C665oY-b.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/framework.DyMmIvSC.js">
<link rel="modulepreload" href="/assets/chunks/theme.DDP8I4Kh.js">
<link rel="modulepreload" href="/assets/feature_pointing_device.md.D8bKydDH.lean.js">
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-5d98c3a5><!--[--><!--]--><!--[--><span tabindex="-1" data-v-0f60ec36></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-0f60ec36> Skip to content </a><!--]--><!----><header class="VPNav" data-v-5d98c3a5 data-v-ae24b3ad><div class="VPNavBar has-sidebar top" data-v-ae24b3ad data-v-ccf7ddec><div class="wrapper" data-v-ccf7ddec><div class="container" data-v-ccf7ddec><div class="title" data-v-ccf7ddec><div class="VPNavBarTitle has-sidebar" data-v-ccf7ddec data-v-ab179fa1><a class="title" href="/" data-v-ab179fa1><!--[--><!--]--><!--[--><!--[--><!--[--><img class="VPImage dark logo" src="/qmk-logo-dark.svg" alt data-v-8426fc1a><!--]--><!--[--><img class="VPImage light logo" src="/qmk-logo-light.svg" alt data-v-8426fc1a><!--]--><!--]--><!--]--><span data-v-ab179fa1>QMK Firmware</span><!--[--><!--]--></a></div></div><div class="content" data-v-ccf7ddec><div class="content-body" data-v-ccf7ddec><!--[--><!--]--><div class="VPNavBarSearch search" data-v-ccf7ddec><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-ccf7ddec data-v-7f418b0f><span id="main-nav-aria-label" class="visually-hidden" data-v-7f418b0f>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="./" tabindex="0" data-v-7f418b0f data-v-9c663999><!--[--><span data-v-9c663999>Home</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-ccf7ddec data-v-e6aabb21><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="Switch to dark theme" aria-checked="false" data-v-e6aabb21 data-v-d1f28634 data-v-1d5665e3><span class="check" data-v-1d5665e3><span class="icon" data-v-1d5665e3><!--[--><span class="vpi-sun sun" data-v-d1f28634></span><span class="vpi-moon moon" data-v-d1f28634></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-ccf7ddec data-v-0394ad82 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://reddit.com/r/olkb" aria-label target="_blank" rel="noopener" data-v-7bc22406 data-v-eee4e7cb><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50px" height="50px"><path d="M 29 3 C 28.0625 3 27.164063 3.382813 26.5 4 C 25.835938 4.617188 25.363281 5.433594 25 6.40625 C 24.355469 8.140625 24.085938 10.394531 24.03125 13.03125 C 19.234375 13.179688 14.820313 14.421875 11.28125 16.46875 C 10.214844 15.46875 8.855469 14.96875 7.5 14.96875 C 6.089844 14.96875 4.675781 15.511719 3.59375 16.59375 C 1.425781 18.761719 1.425781 22.238281 3.59375 24.40625 L 3.84375 24.65625 C 3.3125 26.035156 3 27.488281 3 29 C 3 33.527344 5.566406 37.585938 9.5625 40.4375 C 13.558594 43.289063 19.007813 45 25 45 C 30.992188 45 36.441406 43.289063 40.4375 40.4375 C 44.433594 37.585938 47 33.527344 47 29 C 47 27.488281 46.6875 26.035156 46.15625 24.65625 L 46.40625 24.40625 C 48.574219 22.238281 48.574219 18.761719 46.40625 16.59375 C 45.324219 15.511719 43.910156 14.96875 42.5 14.96875 C 41.144531 14.96875 39.785156 15.46875 38.71875 16.46875 C 35.195313 14.433594 30.800781 13.191406 26.03125 13.03125 C 26.09375 10.546875 26.363281 8.46875 26.875 7.09375 C 27.164063 6.316406 27.527344 5.757813 27.875 5.4375 C 28.222656 5.117188 28.539063 5 29 5 C 29.460938 5 29.683594 5.125 30.03125 5.40625 C 30.378906 5.6875 30.785156 6.148438 31.3125 6.6875 C 32.253906 7.652344 33.695313 8.714844 36.09375 8.9375 C 36.539063 11.238281 38.574219 13 41 13 C 43.75 13 46 10.75 46 8 C 46 5.25 43.75 3 41 3 C 38.605469 3 36.574219 4.710938 36.09375 6.96875 C 34.3125 6.796875 33.527344 6.109375 32.75 5.3125 C 32.300781 4.851563 31.886719
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> PMW33XX_CS_PINS</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { B5, B6 }</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// in keyboard.c:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#ifdef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> POINTING_DEVICE_ENABLE</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_init_kb</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pmw33xx_init</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // index 1 is the second device.</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pmw33xx_set_cpi</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">800</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // applies to first sensor</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pmw33xx_set_cpi</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">800</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // applies to second sensor</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_init_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Contains report from sensor #0 already, need to merge in from sensor #1</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_task_kb</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> mouse_report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> pmw33xx_report_t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> report </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pmw33xx_read_burst</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">report.motion.b.is_lifted </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&amp;&amp;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> report.motion.b.is_motion) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// From quantum/pointing_device_drivers.c</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> constrain_hid</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">amt</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) ((amt) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> -</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">127</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ?</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> -</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">127</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> :</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ((amt) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 127</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ?</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 127</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> :</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (amt)))</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.x </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> constrain_hid</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(mouse_report.x </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">+</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> report.delta_x);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.y </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> constrain_hid</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(mouse_report.y </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">+</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> report.delta_y);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_task_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(mouse_report);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#endif</span></span></code></pre></div><h3 id="custom-driver" tabindex="-1">Custom Driver <a class="header-anchor" href="#custom-driver" aria-label="Permalink to &quot;Custom Driver&quot;"></a></h3><p>If you have a sensor type that isn&#39;t supported above, a custom option is available by adding the following to your <code>rules.mk</code></p><div class="language-make vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">make</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--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><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_driver_init</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {}</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_driver_get_report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> mouse_report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report; }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint16_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_driver_get_cpi</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_driver_set_cpi</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint16_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> cpi</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {}</span></span></code></pre></div><div class="warning custom-block"><p class="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&#39;s very specific to the hardware. So these functions are provided, just in case.</p></div><h2 id="common-configuration" tabindex="-1">Common Configuration <a class="header-anchor" href="#common-configuration" aria-label="Permalink to &quot;Common Configuration&quot;"></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><div class="warning custom-block"><p class="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
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> report_mouse_t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> currentReport </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_get_report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (record</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">event.pressed) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> currentReport.v </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 127</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> currentReport.h </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 127</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> currentReport.buttons </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">|=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> MOUSE_BTN1;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // this is defined in report.h</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">else</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> currentReport.v </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> -</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">127</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> currentReport.h </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> -</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">127</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> currentReport.buttons </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&amp;=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ~</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">MOUSE_BTN1;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_set_report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(currentReport);</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_send</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> break</span><span style="--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><h3 id="drag-scroll-or-mouse-scroll" tabindex="-1">Drag Scroll or Mouse Scroll <a class="header-anchor" href="#drag-scroll-or-mouse-scroll" aria-label="Permalink to &quot;Drag Scroll or Mouse Scroll&quot;"></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&#39;s sent to the host system.</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">enum</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> custom_keycodes {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> DRAG_SCROLL </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SAFE_RANGE,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">};</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">bool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> set_scrolling </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_task_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> mouse_report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (set_scrolling) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.h </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.x;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.v </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.y;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.x </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.y </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">bool</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> process_record_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint16_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> keycode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">keyrecord_t</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">record</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (keycode </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">==</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> DRAG_SCROLL </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&amp;&amp;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> record-&gt;event.pressed) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> set_scrolling </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> !</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">set_scrolling;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--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><h3 id="advanced-drag-scroll" tabindex="-1">Advanced Drag Scroll <a class="header-anchor" href="#advanced-drag-scroll" aria-label="Permalink to &quot;Advanced Drag Scroll&quot;"></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-&gt;event.pressed. This way, the drag scrolling will only be active while the DRAG_SCROLL button is held down.</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">enum</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> custom_keycodes {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> DRAG_SCROLL </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SAFE_RANGE,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">};</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">bool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> set_scrolling </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Modify these values to adjust the scrolling speed</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SCROLL_DIVISOR_H</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 8.0</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SCROLL_DIVISOR_V</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 8.0</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Variables to store accumulated scroll values</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">float</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> scroll_accumulated_h </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">float</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> scroll_accumulated_v </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Function to handle mouse reports and perform drag scrolling</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_task_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> mouse_report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Check if drag scrolling is active</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (set_scrolling) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Calculate and accumulate scroll values based on mouse movement and divisors</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> scroll_accumulated_h </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">+=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">float</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)mouse_report.x </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SCROLL_DIVISOR_H;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> scroll_accumulated_v </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">+=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">float</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)mouse_report.y </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SCROLL_DIVISOR_V;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Assign integer parts of accumulated scroll values to the mouse report</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.h </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int8_t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)scroll_accumulated_h;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.v </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int8_t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)scroll_accumulated_v;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Update accumulated scroll values by subtracting the integer parts</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> scroll_accumulated_h </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int8_t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)scroll_accumulated_h;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> scroll_accumulated_v </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int8_t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)scroll_accumulated_v;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Clear the X and Y values of the mouse report</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.x </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.y </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Function to handle key events and enable/disable drag scrolling</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">bool</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> process_record_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint16_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> keycode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">keyrecord_t</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">record</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> switch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (keycode) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> case</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> DRAG_SCROLL:</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Toggle set_scrolling when DRAG_SCROLL key is pressed or released</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> set_scrolling </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> record-&gt;event.pressed;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> break</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> break</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Function to handle layer changes and disable drag scrolling when not in AUTO_MOUSE_DEFAULT_LAYER</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">layer_state_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> layer_state_set_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">layer_state_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> state</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Disable set_scrolling if the current layer is not the AUTO_MOUSE_DEFAULT_LAYER</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get_highest_layer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(state) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> AUTO_MOUSE_DEFAULT_LAYER) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> set_scrolling </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> state;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h2 id="split-examples" tabindex="-1">Split Examples <a class="header-anchor" href="#split-examples" aria-label="Permalink to &quot;Split Examples&quot;"></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><h3 id="single-pointing-device" tabindex="-1">Single Pointing Device <a class="header-anchor" href="#single-pointing-device" aria-label="Permalink to &quot;Single Pointing Device&quot;"></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><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">static</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> bool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> scrolling_mode </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">layer_state_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> layer_state_set_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">layer_state_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> state</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> switch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get_highest_layer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(state)) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> case</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _RAISE:</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // If we&#39;re on the _RAISE layer enable scrolling mode</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> scrolling_mode </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_set_cpi</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">2000</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> break</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (scrolling_mode) {</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // check if we were scrolling before and set disable if so</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> scrolling_mode </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_set_cpi</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">8000</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> break</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> state;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_task_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> mouse_report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (scrolling_mode) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.h </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.x;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.v </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.y;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.x </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report.y </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mouse_report;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h3 id="combined-pointing-devices" tabindex="-1">Combined Pointing Devices <a class="header-anchor" href="#combined-pointing-devices" aria-label="Permalink to &quot;Combined Pointing Devices&quot;"></a></h3><p>The following example requires <code>POINTING_DEVICE_COMBINED</code> and sets the left side pointing device to scroll only.</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> keyboard_post_init_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_set_cpi_on_side</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1000</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //Set cpi on left side to a low value for slower scrolling.</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_set_cpi_on_side</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">8000</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //Set cpi on right side to a reasonable value for mousing.</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_task_combined_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> left_report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">report_mouse_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> right_report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> left_report.h </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> left_report.x;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> left_report.v </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> left_report.y;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> left_report.x </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> left_report.y </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_combine_reports</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(left_report, right_report);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h1 id="troubleshooting" tabindex="-1">Troubleshooting <a class="header-anchor" href="#troubleshooting" aria-label="Permalink to &quot;Troubleshooting&quot;"></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><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> POINTING_DEVICE_DEBUG</span></span></code></pre></div><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>The messages will be printed out to the <code>CONSOLE</code> output. For additional information, refer to <a href="./faq_debug">Debugging/Troubleshooting QMK</a>.</p></div><hr><h1 id="pointing-device-auto-mouse" tabindex="-1">Automatic Mouse Layer <a class="header-anchor" href="#pointing-device-auto-mouse" aria-label="Permalink to &quot;Automatic Mouse Layer {#pointing-device-auto-mouse}&quot;"></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&#39;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(&lt;new_target_layer&gt;);</code> function.</p><h3 id="behaviour-of-layer-keys-that-activate-the-target-layer" tabindex="-1">Behaviour of Layer keys that activate the target layer <a class="header-anchor" href="#behaviour-of-layer-keys-that-activate-the-target-layer" aria-label="Permalink to &quot;Behaviour of Layer keys that activate the target layer&quot;"></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(&lt;target_layer&gt;)</code></td><td>Treated as a mouse key holding the layer while pressed</td></tr><tr><td><code>LT(&lt;target_layer&gt;)</code></td><td>When tapped will be treated as non mouse key and mouse key when held</td></tr><tr><td><code>LM(&lt;target_layer&gt;)</code></td><td>Treated as a mouse key</td></tr><tr><td><code>TG(&lt;target_layer&gt;)</code></td><td>Will set flag preventing target layer deactivation or removal until pressed again</td></tr><tr><td><code>TO(&lt;target_layer&gt;)</code></td><td>Same as <code>TG(&lt;target_layer&gt;)</code></td></tr><tr><td><code>TT(&lt;target_layer&gt;)</code></td><td>Treated as a mouse key when <code>tap.count &lt; TAPPING_TOGGLE</code> and as <code>TG</code> when <code>tap.count == TAPPING_TOGGLE</code></td></tr><tr><td><code>DF(&lt;targe
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> POINTING_DEVICE_AUTO_MOUSE_ENABLE</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// only required if not setting mouse layer elsewhere</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AUTO_MOUSE_DEFAULT_LAYER</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> &lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">index of your mouse layer</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// in keymap.c:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_init_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> set_auto_mouse_layer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">mouse_layer</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // only required if AUTO_MOUSE_DEFAULT_LAYER is not set to index of &lt;mouse_layer&gt;</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> set_auto_mouse_enable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // always required before the auto mouse feature will work</span></span>
<span class="line"><span style="--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(&lt;mouse_layer&gt;)</code> can be used.</em></p><h2 id="how-to-customize" tabindex="-1">How to Customize: <a class="header-anchor" href="#how-to-customize" aria-label="Permalink to &quot;How to Customize:&quot;"></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><h3 id="config-h-options" tabindex="-1"><code>config.h</code> Options: <a class="header-anchor" href="#config-h-options" aria-label="Permalink to &quot;`config.h` Options:&quot;"></a></h3><table><thead><tr><th>Define</th><th>Description</th><th style="text-align:center;">Range</th><th style="text-align:center;">Units</th><th style="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><td style="text-align:center;"></td><td style="text-align:center;"><em>None</em></td><td style="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><td style="text-align:center;">0 - <code>LAYER_MAX</code></td><td style="text-align:center;"><em><code>uint8_t</code></em></td><td style="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><td style="text-align:center;"><em>ideally</em> (250-1000)</td><td style="text-align:center;"><em>ms</em></td><td style="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><td style="text-align:center;"><em>ideally</em> (100-1000)</td><td style="text-align:center;"><em>ms</em></td><td style="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><td style="text-align:center;"><em>ideally</em> (10 - 100)</td><td style="text-align:center;"><em>ms</em></td><td style="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><td style="text-align:center;">0 -</td><td style="text-align:center;"><em>units</em></td><td style="text-align:right;"><code>10 units</code></td></tr></tbody></table><h3 id="adding-mouse-keys" tabindex="-1">Adding mouse keys <a class="header-anchor" href="#adding-mouse-keys" aria-label="Permalink to &quot;Adding mouse keys&quot;"></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><h4 id="callbacks-for-setting-up-additional-key-codes-as-mouse-keys" tabindex="-1">Callbacks for setting up additional key codes as mouse keys: <a class="header-anchor" href="#callbacks-for-setting-up-additional-key-codes-as-mouse-keys" aria-label="Permalink to &quot;Callbacks for setting up additional key codes as mouse keys:&quot;"></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><h5 id="
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// in &lt;keyboard&gt;.c:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">bool</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> is_mouse_record_kb</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint16_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> keycode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">keyrecord_t</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> record</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> switch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(keycode) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> case</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> KC_ENT:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> case</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> KC_RIGHT ... KC_UP:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> is_mouse_record_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(keycode, record);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h2 id="advanced-control" tabindex="-1">Advanced control <a class="header-anchor" href="#advanced-control" aria-label="Permalink to &quot;Advanced control&quot;"></a></h2><p>There are several functions that allow for more advanced interaction with the auto mouse feature allowing for greater control.</p><h3 id="functions-to-control-auto-mouse-enable-and-target-layer" tabindex="-1">Functions to control auto mouse enable and target layer: <a class="header-anchor" href="#functions-to-control-auto-mouse-enable-and-target-layer" aria-label="Permalink to &quot;Functions to control auto mouse enable and target layer:&quot;"></a></h3><table><thead><tr><th style="text-align:left;">Function</th><th>Description</th><th>Aliases</th><th style="text-align:right;">Return type</th></tr></thead><tbody><tr><td style="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><td style="text-align:right;"><code>void</code>(None)</td></tr><tr><td style="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><td style="text-align:right;"><code>bool</code></td></tr><tr><td style="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><td style="text-align:right;"><code>void</code>(None)</td></tr><tr><td style="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><td style="text-align:right;"><code>uint8_t</code></td></tr><tr><td style="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><td style="text-align:right;"><code>layer_state_t</code></td></tr><tr><td style="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><td style="text-align:right;"><code>void</code>(None)</td></tr><tr><td style="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><td style="text-align:right;"><code>void</code>(None)</td></tr><tr><td style="text-align:left;"><code>get_auto_mouse_toggle(void)</code></td><td>Return value of toggling state variable</td><td></td><td style="text-align:right;"><code>bool</code></td></tr><tr><td style="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><td style="text-align:right;"><code>void</code>(None)</td></tr><tr><td style="text-align:left;"><code>get_auto_mouse_timeout(void)</code></td><td>Return the current timeout for turing off the layer</td><td></td><td style="text-align:right;"><code>uint16_t</code></td></tr><tr><td style="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><td style="text-align:right;"><code>void</code>(None)</td></tr><tr><td style="text-align:left;"><code>get_auto_mouse_debounce(void)</code></td><td>Return the current debounce for preventing layer activation</td><td></td><td style="text-align:right;"><code>uint8_t</code></td></tr><tr><td style="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><td style="text-align:right;"><code>bool</code></td></tr><tr><td style="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><td style="text-align:right;"><code>int8_t</code>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">layer_state_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> layer_state_set_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">layer_state_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> state</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // checks highest layer other than target layer</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> switch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get_highest_layer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">remove_auto_mouse_layer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(state, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">))) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> case</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _LAYER5 ... _LAYER7:</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // remove_auto_mouse_target must be called to adjust state *before* setting enable</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> state </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> remove_auto_mouse_layer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(state, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> set_auto_mouse_enable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> break</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> set_auto_mouse_enable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> break</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // recommend that any code that makes adjustment based on auto mouse layer state would go here</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> state;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h4 id="set-different-target-layer-when-a-particular-layer-is-active" tabindex="-1">Set different target layer when a particular layer is active: <a class="header-anchor" href="#set-different-target-layer-when-a-particular-layer-is-active" aria-label="Permalink to &quot;Set different target layer when a particular layer is active:&quot;"></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><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// in keymap.c</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">layer_state_t</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> default_layer_state_set_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">layer_state_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> state</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--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>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> switch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get_highest_layer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(state)) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> case</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _DEFAULT_LAYER_2:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ((AUTO_MOUSE_TARGET_LAYER) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">==</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _MOUSE_LAYER_2) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">break</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> auto_mouse_layer_off</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> set_auto_mouse_layer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(_MOUSE_LAYER_2);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> break</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">((AUTO_MOUSE_TARGET_LAYER) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">==</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _MOUSE_LAYER_1) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">break</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> auto_mouse_layer_off</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> set_auto_mouse_layer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(_MOUSE_LAYER_1);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> state;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h3 id="use-custom-keys-to-control-auto-mouse" tabindex="-1">Use custom keys to control auto mouse: <a class="header-anchor" href="#use-custom-keys-to-control-auto-mouse" aria-label="Permalink to &quot;Use custom keys to control auto mouse:&quot;"></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><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// in config.h:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">enum</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> user_custom_keycodes {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> AM_Toggle </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SAFE_RANGE</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">};</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// in keymap.c:</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// set up global bool to adjust other user code</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">bool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> auto_mouse_tg_off </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> !</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">AUTO_MOUSE_ENABLED;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">bool</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> process_record_user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint16_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> keycode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">keyrecord_t</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> record</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> switch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (keycode) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // toggle auto mouse enable key</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> case</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> AM_Toggle:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(record</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">event.pressed) {</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // key down</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> auto_mouse_layer_off</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // disable target layer if needed</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> set_auto_mouse_enabled</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">((AUTO_MOUSE_ENABLED) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">^</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> auto_mouse_tg_off </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> !</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get_auto_mouse_enabled</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // do nothing on key up</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // prevent further processing of keycode</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h2 id="customize-target-layer-activation" tabindex="-1">Customize Target Layer Activation <a class="header-anchor" href="#customize-target-layer-activation" aria-label="Permalink to &quot;Customize Target Layer Activation&quot;"></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><th style="text-align:left;">Function</th><th>Description</th><th style="text-align:right;">Return type</th></tr></thead><tbody><tr><td style="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><td style="text-align:right;"><code>bool</code></td></tr></tbody></table><h2 id="auto-mouse-for-custom-pointing-device-task" tabindex="-1">Auto Mouse for Custom Pointing Device Task <a class="header-anchor" href="#auto-mouse-for-custom-pointing-device-task" aria-label="Permalink to &quot;Auto Mouse for Custom Pointing Device Task&quot;"></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><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">bool</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_task</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //...Custom pointing device task code</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // handle automatic mouse layer (needs report_mouse_t as input)</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_task_auto_mouse</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(local_mouse_report);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //...More custom pointing device task code</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pointing_device_send</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--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><th style="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><td style="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><td style="text-align:right;"><code>process_record</code> stack</td></tr></tbody></table></div></div></main><footer class="VPDocFooter" data-v-39a288b8 data-v-09de1c0f><!--[--><!--]--><!----><nav class="prev-next" data-v-09de1c0f><div class="pager" data-v-09de1c0f><a class="VPLink link pager-link prev" href="/feature_midi" data-v-09de1c0f><!--[--><span class="desc" data-v-09de1c0f>Previous page</span><span class="title" data-v-09de1c0f>MIDI</span><!--]--></a></div><div class="pager" data-v-09de1c0f><a class="VPLink link pager-link next" href="/feature_ps2_mouse" data-v-09de1c0f><!--[--><span class="desc" data-v-09de1c0f>Next page</span><span class="title" data-v-09de1c0f>PS/2 Mouse</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"changelog_20200530.md\":\"Dk-vRpTQ\",\"changelog_20240225.md\":\"CGDoAFQ4\",\"changelog_20200229.md\":\"DNsowwM1\",\"changelog_20231126.md\":\"D2Ok5QAf\",\"capabilities.md\":\"DgKwcj5n\",\"changelog_20190830.md\":\"Drtq3lMy\",\"chibios_upgrade_instructions.md\":\"B5dMtL5R\",\"changelog_20201128.md\":\"7XXL02Bn\",\"changelog_20210227.md\":\"BWOtCaeS\",\"api_development_environment.md\":\"EhJClb9f\",\"breaking_changes.md\":\"BtdqWQlY\",\"breaking_changes_instructions.md\":\"BAjIGeJb\",\"apa102_driver.md\":\"DGTINeKZ\",\"changelog_20220528.md\":\"BdSPPJS6\",\"changelog_20230827.md\":\"CkGh7Wzq\",\"changelog_20210529.md\":\"CR1YNfZX\",\"changelog_20230528.md\":\"BMuuw__T\",\"arm_debugging.md\":\"BH-H2Ukz\",\"changelog_20240526.md\":\"iGLFD0SP\",\"changelog_20220827.md\":\"I6ja7C5w\",\"changelog_20220226.md\":\"Ee8ZP8S1\",\"capabilities_inc.md\":\"Ca9zpMce\",\"coding_conventions_python.md\":\"BV-OK1s5\",\"config_options.md\":\"D0qoSxZG\",\"api_overview.md\":\"0FPaUsMb\",\"breaking_changes_history.md\":\"CkzdD6x8\",\"configurator_step_by_step.md\":\"GvmPtScT\",\"changelog_20210828.md\":\"X99NaKjy\",\"configurator_default_keymaps.md\":\"B3v8dlHd\",\"driver_installation_zadig.md\":\"C1kH3vn8\",\"contributing.md\":\"DLsp4vSA\",\"easy_maker.md\":\"BLadB4D_\",\"custom_matrix.md\":\"DMnRw_5l\",\"changelog_20211127.md\":\"BDzkUAQX\",\"adc_driver.md\":\"DGNSFJQa\",\"changelog_20200829.md\":\"CoqrOffn\",\"audio_driver.md\":\"YKqJ1wkZ\",\"custom_quantum_functions.md\":\"BabGw-ye\",\"api_development_overview.md\":\"Dcey4ntL\",\"compatible_microcontrollers.md\":\"6HA6FJZJ\",\"cli.md\":\"BLzAdA6l\",\"feature_auto_shift.md\":\"0xqmu9IK\",\"changelog_20230226.md\":\"CEQKb2Sw\",\"configurator_architecture.md\":\"DEFTvTlS\",\"documentation_templates.md\":\"Bhkum0wD\",\"cli_configuration.md\":\"CGSB128P\",\"faq_keymap.md\":\"BNm1UZCq\",\"configurator_troubleshooting.md\":\"BxGLPT8G\",\"feature_audio.md\":\"CSdy-B0q\",\"cli_commands.md\":\"DCpejdln\",\"api_docs.md\":\"CRoD6CbL\",\"coding_conventions_c.md\":\"DdrpXBEh\",\"eeprom_driver.md\":\"CJGhJYmK\",\"faq_build.md\":\"Bryo1ywz\",\"cli_development.md\":\"3xFA2OvS\",\"cli_tab_complete.md\":\"ChaxfzYo\",\"changelog_20221126.md\":\"BOpHhXi2\",\"faq_general.md\":\"BC3pFw4U\",\"feature_autocorrect.md\":\"MXySdvB8\",\"feature_converters.md\":\"Bmv29bqN\",\"getting_started_docker.md\":\"mz6HE4Bl\",\"feature_stenography.md\":\"7-PPOa0f\",\"feature_caps_word.md\":\"DFEidvi5\",\"feature_swap_hands.md\":\"DYy3Hkxa\",\"feature_advanced_keycodes.md\":\"jN1BLaPG\",\"faq_misc.md\":\"qGrhOTu4\",\"getting_started_github.md\":\"OYq7IT7B\",\"getting_started_make_guide.md\":\"fsRi0mqX\",\"gpio_control.md\":\"BXAY05Da\",\"feature_grave_esc.md\":\"Dfk03Mwq\",\"feature_bootmagic.md\":\"CHslUBOY\",\"feature_dip_switch.md\":\"BRm_919T\",\"feature_hd44780.md\":\"yQt2vqod\",\"faq_debug.md\":\"uJtFRvCN\",\"reference_configurator_support.md\":\"FaBQzIj6\",\"feature_debounce_type.md\":\"CUrSp0Iy\",\"how_a_matrix_works.md\":\"JINKbCuX\",\"documentation_best_practices.md\":\"D_UwEt1C\",\"feature_ps2_mouse.md\":\"DgKRvSpd\",\"feature_rawhid.md\":\"_qE_L8rS\",\"feature_repeat_key.md\":\"D8sTeKpj\",\"feature_send_string.md\":\"ucKdf_1f\",\"feature_secure.md\":\"DTio1NtX\",\"feature_haptic_feedback.md\":\"CI5hNqfq\",\"feature_sequencer.md\":\"CAso80-u\",\"feature_split_keyboard.md\":\"dSXqGTcC\",\"feature_space_cadet.md\":\"BadigqA6\",\"feature_combo.md\":\"BFcSajDz\",\"feature_command.md\":\"DyD1wEzr\",\"feature_bluetooth.md\":\"bG-tYvch\",\"feature_dynamic_macros.md\":\"CQqgFNCL\",\"platformdev_rp2040.md\":\"Ca0zZxM4\",\"feature_rgb_matrix.md\":\"DjrTztSt\",\"feature_encoders.md\":\"DzEjkR0q\",\"platformdev_proton_c.md\":\"CDRuJBvD\",\"platformdev_selecting_arm_mcu.md\":\"aF4DUsvb\",\"reference_keymap_extras.md\":\"-n_bLm78\",\"reference_info_json.md\":\"DLkUuXVh\",\"spi_driver.md\":\"BUPXWtdm\",\"uart_driver.md\":\"Cby_2B9q\",\"quantum_painter_lvgl.md\":\"DobNbSgA\",\"squeezing_avr.md\":\"BmcLYKOr\",\"support_deprecation_policy.md\":\"CCo4ljiw\",\"ws2812_driver.md\":\"DXixRTS
</body>
</html>