fix(niri): keep the initial IPC connect synchronous
#5158 (6672e924) moved connectToSocket() off the constructing thread and
into the detached IPC worker's own try/catch, so a missing NIRI_SOCKET no
longer throws out of IPC::IPC(). That was needed to fix #5117 (the worker
should reconnect instead of dying when an established stream drops), but
it also meant the very first connection attempt can never fail anymore.
Factory::makeModule()/Bar::getModules() rely on that constructor throwing
to disable a module it can't construct. With niri/workspaces and
niri/window always constructing successfully now, they get added to every
bar regardless of which compositor is actually running, showing up as a
permanently-empty widget next to the real workspace modules under
Hyprland/Sway.
Restore the old semantics for the first connection: connectToSocket() runs
synchronously in IPC::IPC() again, so a missing socket still throws and
the module gets disabled as before. Only a drop *after* that succeeds
falls into the retrying reconnect loop, preserving the #5117 fix.
This commit is contained in:
@@ -21,7 +21,13 @@
|
||||
|
||||
namespace waybar::modules::niri {
|
||||
|
||||
IPC::IPC() { startIPC(); }
|
||||
IPC::IPC() {
|
||||
// Connect synchronously so a missing socket (this WM isn't the active
|
||||
// compositor) throws here, same as before the reconnect loop below existed.
|
||||
// That lets the module constructor fail and Factory disable the module,
|
||||
// instead of the module always attaching with a permanently empty widget.
|
||||
startIPC(connectToSocket());
|
||||
}
|
||||
|
||||
IPC::~IPC() { running_ = false; }
|
||||
|
||||
@@ -54,22 +60,30 @@ int IPC::connectToSocket() {
|
||||
return socketfd.release();
|
||||
}
|
||||
|
||||
void IPC::startIPC() {
|
||||
void IPC::startIPC(int initial_socketfd) {
|
||||
// will start IPC and relay events to parseIPC
|
||||
|
||||
std::thread([this]() {
|
||||
std::thread([this, initial_socketfd]() {
|
||||
spdlog::info("Niri IPC starting");
|
||||
|
||||
// Reconnect loop: if the event stream drops we back off briefly and
|
||||
// re-establish the socket instead of leaving the module frozen forever.
|
||||
bool have_initial_fd = true;
|
||||
|
||||
// Reconnect loop: if the event stream drops *after* the initial connect
|
||||
// above succeeded, we back off briefly and re-establish the socket
|
||||
// instead of leaving the module frozen forever.
|
||||
while (running_) {
|
||||
int socketfd;
|
||||
try {
|
||||
socketfd = connectToSocket();
|
||||
} catch (std::exception& e) {
|
||||
spdlog::error("Niri IPC: failed to connect: {}", e.what());
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
continue;
|
||||
if (have_initial_fd) {
|
||||
socketfd = initial_socketfd;
|
||||
have_initial_fd = false;
|
||||
} else {
|
||||
try {
|
||||
socketfd = connectToSocket();
|
||||
} catch (std::exception& e) {
|
||||
spdlog::error("Niri IPC: failed to connect: {}", e.what());
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto unix_istream = Gio::UnixInputStream::create(socketfd, true);
|
||||
|
||||
Reference in New Issue
Block a user