convertablet/fcitx5-hooks/hooks.cpp

77 lines
1.9 KiB
C++

#include <fcitx-utils/handlertable_details.h>
#include <fcitx/addonfactory.h>
#include <fcitx/addoninstance.h>
#include <fcitx/addonmanager.h>
#include <fcitx/instance.h>
#include <filesystem>
#include <stdlib.h>
#include <unistd.h>
namespace fs = std::filesystem;
static fs::path const hooksConfigDir =
fs::path(getenv("XDG_CONFIG_DIR")
? getenv("XDG_CONFIG_DIR")
: (fs::path(getenv("HOME")) / ".config")) /
"fcitx5-hooks";
void runCommand(std::string_view hookName)
{
auto full_path = hooksConfigDir / hookName;
pid_t pid = fork();
if (pid < 0) {
FCITX_ERROR() << "Couldn't fork to run command";
return;
} else if (pid == 0) {
char* argv[] = {strdup(full_path.c_str()), 0};
execve(full_path.c_str(), argv, environ);
exit(-1);
}
return;
}
static void eventHandler(fcitx::Event& event)
{
using ET = fcitx::EventType;
switch (event.type()) {
case ET::InputContextFocusIn:
runCommand("input-context-focus-in-hook");
case ET::InputContextFocusOut:
runCommand("input-context-focus-out-hook");
default:
}
}
class Hooks : public fcitx::AddonInstance
{
public:
Hooks(fcitx::Instance* instance)
{
#define WATCH_EVENT(event_name) \
instance->watchEvent(fcitx::EventType::event_name, \
fcitx::EventWatcherPhase::InputMethod, \
eventHandler)
focusEvent_ = WATCH_EVENT(InputContextFocusIn);
unfocusEvent_ = WATCH_EVENT(InputContextFocusOut);
}
private:
std::unique_ptr<fcitx::HandlerTableEntry<fcitx::EventHandler>> focusEvent_;
std::unique_ptr<fcitx::HandlerTableEntry<fcitx::EventHandler>> unfocusEvent_;
};
class HooksFactory : public fcitx::AddonFactory
{
fcitx::AddonInstance* create(fcitx::AddonManager* manager) override
{
FCITX_UNUSED(manager);
return new Hooks(manager->instance());
}
};
FCITX_ADDON_FACTORY(HooksFactory);