This commit is contained in:
Christoph Cullmann 2025-03-18 22:27:19 +01:00
parent 4dc5811f00
commit ee0a3c3be0
No known key found for this signature in database
61 changed files with 5743 additions and 0 deletions

View file

@ -0,0 +1,37 @@
# Mouse Turbo Click
<table>
<tr><td><b>Module</b></td><td><tt>getreuer/mouse_turbo_click</tt></td></tr>
<tr><td><b>Version</b></td><td>2025-03-07</td></tr>
<tr><td><b>Maintainer</b></td><td>Pascal Getreuer (@getreuer)</td></tr>
<tr><td><b>License</b></td><td><a href="../LICENSE.txt">Apache 2.0</a></td></tr>
<tr><td><b>Documentation</b></td><td>
<a href="https://getreuer.info/posts/keyboards/mouse-turbo-click">https://getreuer.info/posts/keyboards/mouse-turbo-click</a>
</td></tr>
</table>
This is a community module adaptation of [Mouse Turbo
Click](https://getreuer.info/posts/keyboards/mouse-turbo-click) to click the
mouse rapidly.
Add the following to your `keymap.json`:
```json
{
"modules": ["getreuer/mouse_turbo_click"]
}
```
Then use the keycode `TURBO` somewhere in your layout. This key clicks the mouse
rapidly, implemented using mouse keys and a periodic callback function:
* Pressing and holding the Turbo Click button sends rapid mouse clicks,
about 12 clicks per second.
* Quickly double tapping the Turbo Click button "locks" it. Rapid mouse
clicks are sent until the Turbo Click button is tapped again.
Optionally, the click rate and keycode can be customized. See the [Mouse Turbo
Click documentation](https://getreuer.info/posts/keyboards/mouse-turbo-click)
for details.

View file

@ -0,0 +1,121 @@
// Copyright 2022-2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @file mouse_turbo_click.c
* @brief Mouse Turbo Click community module: click the mouse rapidly
*
* This module implements a "Turbo Click" button that clicks the mouse rapidly,
* implemented using mouse keys and a periodic callback function:
*
* * Pressing and holding the Turbo Click button sends rapid mouse clicks,
* about 12 clicks per second.
*
* * Quickly double tapping the Turbo Click button "locks" it. Rapid mouse
* clicks are sent until the Turbo Click button is tapped again.
*
* For full documentation, see
* <https://getreuer.info/posts/keyboards/mouse-turbo-click>
*/
#include "quantum.h"
ASSERT_COMMUNITY_MODULES_MIN_API_VERSION(1, 0, 0);
// The keycode to be repeatedly clicked, `MS_BTN1` mouse button 1 by default.
#ifndef MOUSE_TURBO_CLICK_KEY
#define MOUSE_TURBO_CLICK_KEY MS_BTN1
#endif // MOUSE_TURBO_CLICK_KEY
// The click period in milliseconds. For instance a period of 200 ms would be 5
// clicks per second. Smaller period implies faster clicking.
//
// WARNING: The keyboard might become unresponsive if the period is too small.
// I suggest setting this no smaller than 10.
#ifndef MOUSE_TURBO_CLICK_PERIOD
#define MOUSE_TURBO_CLICK_PERIOD 80
#endif // MOUSE_TURBO_CLICK_PERIOD
static deferred_token click_token = INVALID_DEFERRED_TOKEN;
static bool click_registered = false;
// Callback used with deferred execution. It alternates between registering and
// unregistering (pressing and releasing) `MOUSE_TURBO_CLICK_KEY`.
static uint32_t turbo_click_callback(uint32_t trigger_time, void* cb_arg) {
if (click_registered) {
unregister_code16(MOUSE_TURBO_CLICK_KEY);
click_registered = false;
} else {
click_registered = true;
register_code16(MOUSE_TURBO_CLICK_KEY);
}
return MOUSE_TURBO_CLICK_PERIOD / 2; // Execute again in half a period.
}
// Starts Turbo Click, begins the `turbo_click_callback()` callback.
static void turbo_click_start(void) {
if (click_token == INVALID_DEFERRED_TOKEN) {
uint32_t next_delay_ms = turbo_click_callback(0, NULL);
click_token = defer_exec(next_delay_ms, turbo_click_callback, NULL);
}
}
// Stops Turbo Click, cancels the callback.
static void turbo_click_stop(void) {
if (click_token != INVALID_DEFERRED_TOKEN) {
cancel_deferred_exec(click_token);
click_token = INVALID_DEFERRED_TOKEN;
if (click_registered) {
// If `MOUSE_TURBO_CLICK_KEY` is currently registered, release it.
unregister_code16(MOUSE_TURBO_CLICK_KEY);
click_registered = false;
}
}
}
bool process_record_mouse_turbo_click(uint16_t keycode, keyrecord_t* record) {
static bool locked = false;
static bool tapped = false;
static uint16_t tap_timer = 0;
if (keycode == MOUSE_TURBO_CLICK) {
if (record->event.pressed) { // Turbo Click key was pressed.
if (tapped && !timer_expired(record->event.time, tap_timer)) {
// If the key was recently tapped, lock turbo click.
locked = true;
} else if (locked) {
// Otherwise if currently locked, unlock and stop.
locked = false;
tapped = false;
turbo_click_stop();
return false;
}
// Set that the first tap occurred in a potential double tap.
tapped = true;
tap_timer = record->event.time + TAPPING_TERM;
turbo_click_start();
} else if (!locked) {
// If not currently locked, stop on key release.
turbo_click_stop();
}
return false;
} else {
// On an event with any other key, reset the double tap state.
tapped = false;
return true;
}
}

View file

@ -0,0 +1,14 @@
{
"module_name": "Mouse Turbo Click",
"maintainer": "getreuer",
"features": {
"deferred_exec": true,
"mousekeys": true
},
"keycodes": [
{
"key": "MOUSE_TURBO_CLICK",
"aliases": ["TURBO"]
}
]
}