Gamepad / Keyboard / Mouse: adds support to ignore input devices by name prefix

Fixes #1950
This commit is contained in:
李通洲
2025-09-19 11:00:18 +08:00
parent 1180eb55a4
commit 0bb5b4cc9c
7 changed files with 239 additions and 6 deletions
+27
View File
@@ -2636,6 +2636,15 @@
"const": "gamepad",
"description": "List connected gamepads"
},
"ignores": {
"type": "array",
"description": "An array of case-insensitive device name prefixes to ignore",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"percent": {
"$ref": "#/$defs/percent"
},
@@ -2895,6 +2904,15 @@
"const": "keyboard",
"description": "List (connected) keyboards"
},
"ignores": {
"type": "array",
"description": "An array of case-insensitive device name prefixes to ignore",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"key": {
"$ref": "#/$defs/key"
},
@@ -3218,6 +3236,15 @@
"const": "mouse",
"description": "List connected mouses"
},
"ignores": {
"type": "array",
"description": "An array of case-insensitive device name prefixes to ignore",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"key": {
"$ref": "#/$defs/key"
},
+70 -2
View File
@@ -68,10 +68,40 @@ bool ffPrintGamepad(FFGamepadOptions* options)
return false;
}
uint8_t index = 0;
FF_LIST_AUTO_DESTROY filtered = ffListCreate(sizeof(FFGamepadDevice*));
FF_LIST_FOR_EACH(FFGamepadDevice, device, result)
{
bool ignored = false;
FF_LIST_FOR_EACH(FFstrbuf, ignore, options->ignores)
{
if(ffStrbufStartsWithIgnCase(&device->name, ignore))
{
ignored = true;
break;
}
}
if(!ignored)
{
FFGamepadDevice** ptr = ffListAdd(&filtered);
*ptr = device;
}
}
if(!filtered.length)
{
ffPrintError(FF_GAMEPAD_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "All devices are ignored");
return false;
}
uint8_t index = 0;
FF_LIST_FOR_EACH(FFGamepadDevice*, pdevice, filtered)
{
FFGamepadDevice* device = *pdevice;
printDevice(options, device, filtered.length > 1 ? ++index : 0);
}
FF_LIST_FOR_EACH(FFGamepadDevice, device, result)
{
printDevice(options, device, result.length > 1 ? ++index : 0);
ffStrbufDestroy(&device->serial);
ffStrbufDestroy(&device->name);
}
@@ -88,6 +118,21 @@ void ffParseGamepadJsonObject(FFGamepadOptions* options, yyjson_val* module)
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (unsafe_yyjson_equals_str(key, "ignores"))
{
yyjson_val *elem;
size_t eidx, emax;
yyjson_arr_foreach(val, eidx, emax, elem)
{
if (yyjson_is_str(elem))
{
FFstrbuf* strbuf = ffListAdd(&options->ignores);
ffStrbufInitJsonVal(strbuf, elem);
}
}
continue;
}
if (ffPercentParseJsonObject(key, val, &options->percent))
continue;
@@ -99,6 +144,12 @@ void ffGenerateGamepadJsonConfig(FFGamepadOptions* options, yyjson_mut_doc* doc,
{
ffJsonConfigGenerateModuleArgsConfig(doc, module, &options->moduleArgs);
if (options->ignores.length > 0)
{
yyjson_mut_val* ignores = yyjson_mut_obj_add_arr(doc, module, "ignores");
FF_LIST_FOR_EACH(FFstrbuf, strbuf, options->ignores)
yyjson_mut_arr_append(ignores, yyjson_mut_strncpy(doc, strbuf->chars, strbuf->length));
}
ffPercentGenerateJsonConfig(doc, module, options->percent);
}
@@ -120,6 +171,17 @@ bool ffGenerateGamepadJsonResult(FF_MAYBE_UNUSED FFGamepadOptions* options, yyjs
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_strbuf(doc, obj, "serial", &device->serial);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &device->name);
bool ignored = false;
FF_LIST_FOR_EACH(FFstrbuf, ignore, options->ignores)
{
if(ffStrbufStartsWithIgnCase(&device->name, ignore))
{
ignored = true;
break;
}
}
yyjson_mut_obj_add_bool(doc, obj, "ignored", ignored);
}
FF_LIST_FOR_EACH(FFGamepadDevice, device, result)
@@ -134,12 +196,18 @@ bool ffGenerateGamepadJsonResult(FF_MAYBE_UNUSED FFGamepadOptions* options, yyjs
void ffInitGamepadOptions(FFGamepadOptions* options)
{
ffOptionInitModuleArg(&options->moduleArgs, "󰺵");
ffListInit(&options->ignores, sizeof(FFstrbuf));
options->percent = (FFPercentageModuleConfig) { 50, 20, 0 };
}
void ffDestroyGamepadOptions(FFGamepadOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
FF_LIST_FOR_EACH(FFstrbuf, str, options->ignores)
ffStrbufDestroy(str);
ffListDestroy(&options->ignores);
}
FFModuleBaseInfo ffGamepadModuleInfo = {
+2
View File
@@ -1,11 +1,13 @@
#pragma once
#include "common/option.h"
#include "util/FFlist.h"
typedef struct FFGamepadOptions
{
FFModuleArgs moduleArgs;
FFlist ignores; // List of FFstrbuf
FFPercentageModuleConfig percent;
} FFGamepadOptions;
+67 -2
View File
@@ -39,10 +39,36 @@ bool ffPrintKeyboard(FFKeyboardOptions* options)
return false;
}
uint8_t index = 0;
FF_LIST_AUTO_DESTROY filtered = ffListCreate(sizeof(FFKeyboardDevice*));
FF_LIST_FOR_EACH(FFKeyboardDevice, device, result)
{
printDevice(options, device, result.length > 1 ? ++index : 0);
bool ignored = false;
FF_LIST_FOR_EACH(FFstrbuf, ignore, options->ignores)
{
if(ffStrbufStartsWithIgnCase(&device->name, ignore))
{
ignored = true;
break;
}
}
if(!ignored)
{
FFKeyboardDevice** ptr = ffListAdd(&filtered);
*ptr = device;
}
}
if(!filtered.length)
{
ffPrintError(FF_KEYBOARD_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "All devices are ignored");
return false;
}
uint8_t index = 0;
FF_LIST_FOR_EACH(FFKeyboardDevice*, pdevice, filtered)
{
FFKeyboardDevice* device = *pdevice;
printDevice(options, device, filtered.length > 1 ? ++index : 0);
ffStrbufDestroy(&device->serial);
ffStrbufDestroy(&device->name);
}
@@ -59,6 +85,21 @@ void ffParseKeyboardJsonObject(FFKeyboardOptions* options, yyjson_val* module)
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (unsafe_yyjson_equals_str(key, "ignores"))
{
yyjson_val *elem;
size_t eidx, emax;
yyjson_arr_foreach(val, eidx, emax, elem)
{
if (yyjson_is_str(elem))
{
FFstrbuf* strbuf = ffListAdd(&options->ignores);
ffStrbufInitJsonVal(strbuf, elem);
}
}
continue;
}
ffPrintError(FF_KEYBOARD_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", unsafe_yyjson_get_str(key));
}
}
@@ -66,6 +107,13 @@ void ffParseKeyboardJsonObject(FFKeyboardOptions* options, yyjson_val* module)
void ffGenerateKeyboardJsonConfig(FFKeyboardOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
ffJsonConfigGenerateModuleArgsConfig(doc, module, &options->moduleArgs);
if (options->ignores.length > 0)
{
yyjson_mut_val* ignores = yyjson_mut_obj_add_arr(doc, module, "ignores");
FF_LIST_FOR_EACH(FFstrbuf, strbuf, options->ignores)
yyjson_mut_arr_append(ignores, yyjson_mut_strncpy(doc, strbuf->chars, strbuf->length));
}
}
bool ffGenerateKeyboardJsonResult(FF_MAYBE_UNUSED FFKeyboardOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
@@ -86,6 +134,17 @@ bool ffGenerateKeyboardJsonResult(FF_MAYBE_UNUSED FFKeyboardOptions* options, yy
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_strbuf(doc, obj, "serial", &device->serial);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &device->name);
bool ignored = false;
FF_LIST_FOR_EACH(FFstrbuf, ignore, options->ignores)
{
if(ffStrbufStartsWithIgnCase(&device->name, ignore))
{
ignored = true;
break;
}
}
yyjson_mut_obj_add_bool(doc, obj, "ignored", ignored);
}
FF_LIST_FOR_EACH(FFKeyboardDevice, device, result)
@@ -100,11 +159,17 @@ bool ffGenerateKeyboardJsonResult(FF_MAYBE_UNUSED FFKeyboardOptions* options, yy
void ffInitKeyboardOptions(FFKeyboardOptions* options)
{
ffOptionInitModuleArg(&options->moduleArgs, "");
ffListInit(&options->ignores, sizeof(FFstrbuf));
}
void ffDestroyKeyboardOptions(FFKeyboardOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
FF_LIST_FOR_EACH(FFstrbuf, str, options->ignores)
ffStrbufDestroy(str);
ffListDestroy(&options->ignores);
}
FFModuleBaseInfo ffKeyboardModuleInfo = {
+3
View File
@@ -1,10 +1,13 @@
#pragma once
#include "common/option.h"
#include "util/FFlist.h"
typedef struct FFKeyboardOptions
{
FFModuleArgs moduleArgs;
FFlist ignores; // List of FFstrbuf
} FFKeyboardOptions;
static_assert(sizeof(FFKeyboardOptions) <= FF_OPTION_MAX_SIZE, "FFKeyboardOptions size exceeds maximum allowed size");
+67 -2
View File
@@ -39,10 +39,36 @@ bool ffPrintMouse(FFMouseOptions* options)
return false;
}
uint8_t index = 0;
FF_LIST_AUTO_DESTROY filtered = ffListCreate(sizeof(FFMouseDevice*));
FF_LIST_FOR_EACH(FFMouseDevice, device, result)
{
printDevice(options, device, result.length > 1 ? ++index : 0);
bool ignored = false;
FF_LIST_FOR_EACH(FFstrbuf, ignore, options->ignores)
{
if(ffStrbufStartsWithIgnCase(&device->name, ignore))
{
ignored = true;
break;
}
}
if(!ignored)
{
FFMouseDevice** ptr = ffListAdd(&filtered);
*ptr = device;
}
}
if(!filtered.length)
{
ffPrintError(FF_MOUSE_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "All devices are ignored");
return false;
}
uint8_t index = 0;
FF_LIST_FOR_EACH(FFMouseDevice*, pdevice, filtered)
{
FFMouseDevice* device = *pdevice;
printDevice(options, device, filtered.length > 1 ? ++index : 0);
ffStrbufDestroy(&device->serial);
ffStrbufDestroy(&device->name);
}
@@ -59,6 +85,21 @@ void ffParseMouseJsonObject(FFMouseOptions* options, yyjson_val* module)
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (unsafe_yyjson_equals_str(key, "ignores"))
{
yyjson_val *elem;
size_t eidx, emax;
yyjson_arr_foreach(val, eidx, emax, elem)
{
if (yyjson_is_str(elem))
{
FFstrbuf* strbuf = ffListAdd(&options->ignores);
ffStrbufInitJsonVal(strbuf, elem);
}
}
continue;
}
ffPrintError(FF_MOUSE_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", unsafe_yyjson_get_str(key));
}
}
@@ -66,6 +107,13 @@ void ffParseMouseJsonObject(FFMouseOptions* options, yyjson_val* module)
void ffGenerateMouseJsonConfig(FFMouseOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
ffJsonConfigGenerateModuleArgsConfig(doc, module, &options->moduleArgs);
if (options->ignores.length > 0)
{
yyjson_mut_val* ignores = yyjson_mut_obj_add_arr(doc, module, "ignores");
FF_LIST_FOR_EACH(FFstrbuf, strbuf, options->ignores)
yyjson_mut_arr_append(ignores, yyjson_mut_strncpy(doc, strbuf->chars, strbuf->length));
}
}
bool ffGenerateMouseJsonResult(FF_MAYBE_UNUSED FFMouseOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
@@ -86,6 +134,17 @@ bool ffGenerateMouseJsonResult(FF_MAYBE_UNUSED FFMouseOptions* options, yyjson_m
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_strbuf(doc, obj, "serial", &device->serial);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &device->name);
bool ignored = false;
FF_LIST_FOR_EACH(FFstrbuf, ignore, options->ignores)
{
if(ffStrbufStartsWithIgnCase(&device->name, ignore))
{
ignored = true;
break;
}
}
yyjson_mut_obj_add_bool(doc, obj, "ignored", ignored);
}
FF_LIST_FOR_EACH(FFMouseDevice, device, result)
@@ -100,11 +159,17 @@ bool ffGenerateMouseJsonResult(FF_MAYBE_UNUSED FFMouseOptions* options, yyjson_m
void ffInitMouseOptions(FFMouseOptions* options)
{
ffOptionInitModuleArg(&options->moduleArgs, "󰍽");
ffListInit(&options->ignores, sizeof(FFstrbuf));
}
void ffDestroyMouseOptions(FFMouseOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
FF_LIST_FOR_EACH(FFstrbuf, str, options->ignores)
ffStrbufDestroy(str);
ffListDestroy(&options->ignores);
}
FFModuleBaseInfo ffMouseModuleInfo = {
+3
View File
@@ -1,10 +1,13 @@
#pragma once
#include "common/option.h"
#include "util/FFlist.h"
typedef struct FFMouseOptions
{
FFModuleArgs moduleArgs;
FFlist ignores; // List of FFstrbuf
} FFMouseOptions;
static_assert(sizeof(FFMouseOptions) <= FF_OPTION_MAX_SIZE, "FFMouseOptions size exceeds maximum allowed size");