summaryrefslogtreecommitdiff
path: root/src/config/ConfigManager.cpp
diff options
context:
space:
mode:
authorArchSav <96357545+ArchSav@users.noreply.github.com>2026-03-14 00:48:01 +1100
committerGitHub <noreply@github.com>2026-03-13 08:48:01 -0500
commit24a95621e5118e39e1a6e05b17ef89f4ec2c8c01 (patch)
treea37133cd549fb7107ebbaa5bf60fafd52a5bdd77 /src/config/ConfigManager.cpp
parente8684034525829d58054c32da914d1713398fbb8 (diff)
input: add device specific binds (#13073)
Adds support for device-specific binds
Diffstat (limited to 'src/config/ConfigManager.cpp')
-rw-r--r--src/config/ConfigManager.cpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index 3e0a9957..e4632bb9 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -2542,6 +2542,7 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
bool click = false;
bool drag = false;
bool submapUniversal = false;
+ bool isPerDevice = false;
const auto BINDARGS = command.substr(4);
for (auto const& arg : BINDARGS) {
@@ -2566,6 +2567,7 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
release = true;
break;
case 'u': submapUniversal = true; break;
+ case 'k': isPerDevice = true; break;
default: return "bind: invalid flag";
}
}
@@ -2579,13 +2581,14 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
if (click && drag)
return "flags c and g are mutually exclusive";
- const int numbArgs = hasDescription ? 5 : 4;
+ const int numbArgs = (hasDescription ? 5 : 4) + sc<int>(isPerDevice);
const auto ARGS = CVarList(value, numbArgs);
- const int DESCR_OFFSET = hasDescription ? 1 : 0;
+ const int DESCR_OFFSET = hasDescription ? 1 : 0;
+ const int DEVICE_OFFSET = sc<int>(isPerDevice);
if ((ARGS.size() < 3 && !mouse) || (ARGS.size() < 3 && mouse))
return "bind: too few args";
- else if ((ARGS.size() > sc<size_t>(4) + DESCR_OFFSET && !mouse) || (ARGS.size() > sc<size_t>(3) + DESCR_OFFSET && mouse))
+ else if ((ARGS.size() > sc<size_t>(4) + DESCR_OFFSET + DEVICE_OFFSET && !mouse) || (ARGS.size() > sc<size_t>(3) + DESCR_OFFSET + DEVICE_OFFSET && mouse))
return "bind: too many args";
std::set<xkb_keysym_t> KEYSYMS;
@@ -2604,11 +2607,13 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
const auto KEY = multiKey ? "" : ARGS[1];
- const auto DESCRIPTION = hasDescription ? ARGS[2] : "";
+ const auto DEVICEARGS = isPerDevice ? ARGS[2] : "";
- auto HANDLER = ARGS[2 + DESCR_OFFSET];
+ const auto DESCRIPTION = hasDescription ? ARGS[2 + DEVICE_OFFSET] : "";
- const auto COMMAND = mouse ? HANDLER : ARGS[3 + DESCR_OFFSET];
+ auto HANDLER = ARGS[2 + DESCR_OFFSET + DEVICE_OFFSET];
+
+ const auto COMMAND = mouse ? HANDLER : ARGS[3 + DESCR_OFFSET + DEVICE_OFFSET];
if (mouse)
HANDLER = "mouse";
@@ -2628,6 +2633,16 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
return "Invalid mod, requested mod \"" + MODSTR + "\" is not a valid mod.";
}
+ //[!]keyboard1 keyboard2 ...
+ bool deviceInclusive = false;
+ std::unordered_set<std::string> devices = {};
+ if (!DEVICEARGS.empty()) {
+ deviceInclusive = DEVICEARGS[0] != '!';
+ for (const auto deviceString : std::ranges::views::split(DEVICEARGS.substr(deviceInclusive ? 0 : 1), ' ')) {
+ devices.emplace(std::string_view(deviceString));
+ }
+ }
+
if ((!KEY.empty()) || multiKey) {
SParsedKey parsedKey = parseKey(KEY);
@@ -2639,7 +2654,7 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
g_pKeybindManager->addKeybind(SKeybind{parsedKey.key, KEYSYMS, parsedKey.keycode, parsedKey.catchAll, MOD, MODS, HANDLER,
COMMAND, locked, m_currentSubmap, DESCRIPTION, release, repeat, longPress,
mouse, nonConsuming, transparent, ignoreMods, multiKey, hasDescription, dontInhibit,
- click, drag, submapUniversal});
+ click, drag, submapUniversal, deviceInclusive, devices});
}
return {};