diff --git a/src/main.cpp b/src/main.cpp index cdb35c3b25..2d27669ad0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,11 @@ #include +#include +#include +#include #include +#include #include #include #include @@ -71,6 +75,7 @@ const struct option *gamescope_options = (struct option[]){ { "mouse-sensitivity", required_argument, nullptr, 's' }, { "mangoapp", no_argument, nullptr, 0 }, { "adaptive-sync", no_argument, nullptr, 0 }, + { "keyboard-filter", required_argument, nullptr, 0 }, { "backend", required_argument, nullptr, 0 }, @@ -209,6 +214,8 @@ const char usage[] = " --framerate-limit Set a simple framerate limit. Used as a divisor of the refresh rate, rounds down eg 60 / 59 -> 60fps, 60 / 25 -> 30fps. Default: 0, disabled.\n" " --mangoapp Launch with the mangoapp (mangohud) performance overlay enabled. You should use this instead of using mangohud on the game or gamescope.\n" " --adaptive-sync Enable adaptive sync if available (variable rate refresh)\n" + " --keyboard-filter Filter keyboard inputs to only process data included (xkb keycodes in int)\n" + " Ex: 17,30-32,57 -- Pass w,a-s-d,space\n" "\n" "Nested mode options:\n" " -o, --nested-unfocused-refresh game refresh rate when unfocused\n" @@ -278,6 +285,8 @@ const char usage[] = std::atomic< bool > g_bRun{true}; +std::vector< filter_range > g_keyboardFilterRange; + int g_nNestedWidth = 0; int g_nNestedHeight = 0; int g_nNestedRefresh = 0; @@ -446,6 +455,20 @@ static int parse_integer(const char *str, const char *optionName) } } +static unsigned int parse_unsigned_integer(const char *str, const char *optionName) +{ + auto result = gamescope::Parse(str); + if ( result.has_value() ) + { + return result.value(); + } + else + { + fprintf( stderr, "gamescope: invalid value for --%s, \"%s\" is either not an positive integer or is far too large\n", optionName, str ); + exit(1); + } +} + static float parse_float(const char *str, const char *optionName) { auto result = gamescope::Parse(str); @@ -821,6 +844,25 @@ int main(int argc, char **argv) } } + } else if (strcmp(opt_name, "keyboard-filter") == 0) { + std::string item; + std::istringstream ss (optarg); + while (std::getline(ss, item, ',')) { + size_t dashOffset = item.find("-"); + if (dashOffset == std::string::npos) { + g_keyboardFilterRange.push_back(filter_range { + .start = parse_unsigned_integer(item.c_str(),opt_name), + .end = parse_unsigned_integer(item.c_str(),opt_name) + }); + } else { + uint32_t first_value = parse_unsigned_integer(item.substr(0,dashOffset).c_str(),opt_name); + uint32_t second_value = parse_unsigned_integer(item.substr(dashOffset+1).c_str(),opt_name); + g_keyboardFilterRange.push_back(filter_range { + .start = std::min(first_value,second_value), + .end = std::max(first_value,second_value) + }); + } + } } break; case '?': diff --git a/src/main.hpp b/src/main.hpp index 2e6fb833af..f600d90698 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -3,12 +3,20 @@ #include #include +#include extern const char *gamescope_optstring; extern const struct option *gamescope_options; extern std::atomic< bool > g_bRun; +typedef struct { + uint32_t start; + uint32_t end; +} filter_range; + +extern std::vector< filter_range > g_keyboardFilterRange; + extern int g_nNestedWidth; extern int g_nNestedHeight; extern int g_nNestedRefresh; // mHz diff --git a/src/wlserver.cpp b/src/wlserver.cpp index 721f6f24be..2eb24bfc0f 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp @@ -2247,6 +2247,16 @@ bool wlserver_process_hotkeys( wlr_keyboard *keyboard, uint32_t key, bool press void wlserver_key( uint32_t key, bool press, uint32_t time ) { + if (g_keyboardFilterRange.size() != 0) { + bool should_continue = false; + for (auto filter: g_keyboardFilterRange) { + if (key >= filter.start && key <= filter.end) { + should_continue = true; + } + } + if (!should_continue) return; + } + assert( wlserver_is_lock_held() ); wlr_keyboard *keyboard = wlserver.wlr.virtual_keyboard_device;