mirror of
https://github.com/polybar/polybar.git
synced 2024-11-03 04:33:30 -05:00
fix: Ensure reloading when IN_IGNORED fired on config (#371)
This fixes a "bug" where polybar wouldn't reload on a configuration file change on some configurations of vim, which don't actually issue any IN_MODIFY events because they choose to move the file, replace it with a new one, and then delete the file instead. To work around this, we now also listen for IN_IGNORED which fires when the file we are watching is destroyed. When this happens, we re-attach the configuration file watcher to the new file and reload.
This commit is contained in:
parent
b6661825ce
commit
47a2cce03d
3 changed files with 21 additions and 5 deletions
|
@ -26,7 +26,7 @@ class inotify_watch {
|
||||||
void remove(bool force = false);
|
void remove(bool force = false);
|
||||||
bool poll(int wait_ms = 1000) const;
|
bool poll(int wait_ms = 1000) const;
|
||||||
unique_ptr<inotify_event> get_event() const;
|
unique_ptr<inotify_event> get_event() const;
|
||||||
bool await_match() const;
|
unique_ptr<inotify_event> await_match() const;
|
||||||
const string path() const;
|
const string path() const;
|
||||||
int get_file_descriptor() const;
|
int get_file_descriptor() const;
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ void controller::read_events() {
|
||||||
|
|
||||||
if (m_confwatch) {
|
if (m_confwatch) {
|
||||||
m_log.trace("controller: Attach config watch");
|
m_log.trace("controller: Attach config watch");
|
||||||
m_confwatch->attach(IN_MODIFY);
|
m_confwatch->attach(IN_MODIFY | IN_IGNORED);
|
||||||
fds.emplace_back((fd_confwatch = m_confwatch->get_file_descriptor()));
|
fds.emplace_back((fd_confwatch = m_confwatch->get_file_descriptor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +281,22 @@ void controller::read_events() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process event on the config inotify watch fd
|
// Process event on the config inotify watch fd
|
||||||
if (fd_confwatch > -1 && FD_ISSET(fd_confwatch, &readfds) && m_confwatch->await_match()) {
|
unique_ptr<inotify_event> confevent;
|
||||||
|
if (fd_confwatch > -1 && FD_ISSET(fd_confwatch, &readfds) && (confevent = m_confwatch->await_match())) {
|
||||||
|
if (confevent->mask & IN_IGNORED) {
|
||||||
|
// IN_IGNORED: file was deleted or filesystem was unmounted
|
||||||
|
//
|
||||||
|
// This happens in some configurations of vim when a file is saved,
|
||||||
|
// since it is not actually issuing calls to write() but rather
|
||||||
|
// moves a file into the original's place after moving the original
|
||||||
|
// file to a different location (and subsequently deleting it).
|
||||||
|
//
|
||||||
|
// We need to re-attach the watch to the new file in this case.
|
||||||
|
fds.erase(std::remove_if(fds.begin(), fds.end(), [fd_confwatch](int fd) { return fd == fd_confwatch; }), fds.end());
|
||||||
|
m_confwatch = inotify_util::make_watch(m_confwatch->path());
|
||||||
|
m_confwatch->attach(IN_MODIFY | IN_IGNORED);
|
||||||
|
fds.emplace_back((fd_confwatch = m_confwatch->get_file_descriptor()));
|
||||||
|
}
|
||||||
m_log.info("Configuration file changed");
|
m_log.info("Configuration file changed");
|
||||||
g_terminate = 1;
|
g_terminate = 1;
|
||||||
g_reload = 1;
|
g_reload = 1;
|
||||||
|
|
|
@ -98,8 +98,9 @@ unique_ptr<inotify_event> inotify_watch::get_event() const {
|
||||||
/**
|
/**
|
||||||
* Wait for matching event
|
* Wait for matching event
|
||||||
*/
|
*/
|
||||||
bool inotify_watch::await_match() const {
|
unique_ptr<inotify_event> inotify_watch::await_match() const {
|
||||||
return (get_event()->mask & m_mask) == m_mask;
|
auto event = get_event();
|
||||||
|
return event->mask & m_mask ? std::move(event) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue