77 lines
1.9 KiB
C++
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);
|