56 lines
1.8 KiB
C
56 lines
1.8 KiB
C
|
|
// gKeyMapper daemon - watches the mappings file for changes (inotify).
|
||
|
|
#ifndef GKEYMAPPER_DAEMON_CONFIG_WATCH_H
|
||
|
|
#define GKEYMAPPER_DAEMON_CONFIG_WATCH_H
|
||
|
|
|
||
|
|
#include <string>
|
||
|
|
|
||
|
|
namespace gkeymapper::daemon {
|
||
|
|
|
||
|
|
// Watches mappings.conf so a save in the GUI is picked up without a signal.
|
||
|
|
//
|
||
|
|
// The *directory* is watched, not the file: that also catches an atomic save
|
||
|
|
// (write a temporary file, rename it over the config) and the config appearing
|
||
|
|
// after it was deleted.
|
||
|
|
//
|
||
|
|
// poll_events() collects whatever happened since the last call and take_change()
|
||
|
|
// reports it once. Because the daemon evaluates this once per loop iteration
|
||
|
|
// (at least every read timeout, i.e. 500 ms), all events a single save produces
|
||
|
|
// collapse into one reload, and the file is complete by the time it is read
|
||
|
|
// (that is what the atomic save in shared/mapping.cpp guarantees).
|
||
|
|
//
|
||
|
|
// The daemon still accepts SIGHUP/SIGUSR1 as a fallback when inotify is
|
||
|
|
// unavailable.
|
||
|
|
class ConfigWatcher {
|
||
|
|
public:
|
||
|
|
ConfigWatcher() = default;
|
||
|
|
~ConfigWatcher();
|
||
|
|
|
||
|
|
ConfigWatcher(const ConfigWatcher&) = delete;
|
||
|
|
ConfigWatcher& operator=(const ConfigWatcher&) = delete;
|
||
|
|
|
||
|
|
// Watches the directory holding `path` (creating it if it does not exist
|
||
|
|
// yet). Returns false if inotify cannot be set up; the daemon then relies
|
||
|
|
// on signals only.
|
||
|
|
bool init(const std::string& path);
|
||
|
|
|
||
|
|
bool is_watching() const { return fd_ >= 0; }
|
||
|
|
|
||
|
|
// Consumes queued inotify events. Non-blocking and cheap; call it once per
|
||
|
|
// event-loop iteration.
|
||
|
|
void poll_events();
|
||
|
|
|
||
|
|
// True if the mappings file changed since the last call; clears the mark so
|
||
|
|
// every change is reported exactly once.
|
||
|
|
bool take_change();
|
||
|
|
|
||
|
|
private:
|
||
|
|
int fd_ = -1;
|
||
|
|
std::string directory_;
|
||
|
|
std::string name_;
|
||
|
|
bool pending_ = false;
|
||
|
|
};
|
||
|
|
|
||
|
|
} // namespace gkeymapper::daemon
|
||
|
|
|
||
|
|
#endif // GKEYMAPPER_DAEMON_CONFIG_WATCH_H
|