Files
gKeyMapper/daemon/action.cpp
2026-10-17 03:53:51 +02:00

69 lines
2.1 KiB
C++

// gKeyMapper daemon - executes the mapping configured for a G key.
#include "action.h"
#include <cstdio>
#include <vector>
#include <unistd.h>
namespace gkeymapper::daemon {
bool ActionRunner::init() {
keymap_.init();
if (!keyboard_.open()) {
std::fprintf(stderr,
"gkeymapper-daemon: no virtual keyboard, 'key' mappings disabled\n");
return false;
}
return true;
}
void ActionRunner::run(const gkeymapper::Mapping& mapping) {
switch (mapping.type) {
case gkeymapper::ActionType::Key: {
std::vector<gkeymapper::ShortcutStep> steps;
// Resolve key names through the active keyboard layout.
gkeymapper::KeyResolver resolve = [this](const std::string& name) {
return keymap_.key_code(name);
};
if (!gkeymapper::parse_shortcut(mapping.target, steps, resolve)) {
std::fprintf(stderr, "gkeymapper-daemon: invalid shortcut '%s'\n",
mapping.target.c_str());
return;
}
keyboard_.play(steps);
break;
}
case gkeymapper::ActionType::Command:
run_command(mapping.target);
break;
case gkeymapper::ActionType::Disabled:
default:
break;
}
}
void ActionRunner::run_command(const std::string& command) {
if (command.empty()) {
return;
}
pid_t pid = fork();
if (pid < 0) {
std::fprintf(stderr, "gkeymapper-daemon: fork failed\n");
return;
}
if (pid == 0) {
// The field may be a bare program path (which may contain spaces) or a
// command line with arguments. Try the path directly first, then fall
// back to a shell so arguments and quoting also work.
execlp(command.c_str(), command.c_str(), static_cast<char*>(nullptr));
execl("/bin/sh", "sh", "-c", command.c_str(), static_cast<char*>(nullptr));
_exit(127);
}
// Parent: children are reaped by the SIGCHLD handler.
}
} // namespace gkeymapper::daemon