Show bar if a workspace becomes urgent
Add a second reason to show the bar besides visible by modifier. Update the visibility based on changes in the workspace urgency. Check all workspaces for urgency and keep the bar visible if at least one has an urgency hint.pull/1510/head
parent
d87cf8a8f2
commit
e3700b924e
|
@ -30,8 +30,10 @@ class BarIpcClient {
|
|||
private:
|
||||
void onInitialConfig(const struct Ipc::ipc_response& res);
|
||||
void onIpcEvent(const struct Ipc::ipc_response&);
|
||||
void onCmd(const struct Ipc::ipc_response&);
|
||||
void onConfigUpdate(const swaybar_config& config);
|
||||
void onVisibilityUpdate(bool visible_by_modifier);
|
||||
void onUrgencyUpdate(bool visible_by_urgency);
|
||||
void update();
|
||||
|
||||
Bar& bar_;
|
||||
|
@ -40,8 +42,10 @@ class BarIpcClient {
|
|||
|
||||
swaybar_config bar_config_;
|
||||
bool visible_by_modifier_ = false;
|
||||
bool visible_by_urgency_ = false;
|
||||
|
||||
SafeSignal<bool> signal_visible_;
|
||||
SafeSignal<bool> signal_urgency_;
|
||||
SafeSignal<swaybar_config> signal_config_;
|
||||
};
|
||||
|
||||
|
|
|
@ -21,9 +21,11 @@ BarIpcClient::BarIpcClient(waybar::Bar& bar) : bar_{bar} {
|
|||
|
||||
signal_config_.connect(sigc::mem_fun(*this, &BarIpcClient::onConfigUpdate));
|
||||
signal_visible_.connect(sigc::mem_fun(*this, &BarIpcClient::onVisibilityUpdate));
|
||||
signal_urgency_.connect(sigc::mem_fun(*this, &BarIpcClient::onUrgencyUpdate));
|
||||
|
||||
ipc_.subscribe(R"(["bar_state_update", "barconfig_update"])");
|
||||
ipc_.subscribe(R"(["bar_state_update", "barconfig_update", "workspace"])");
|
||||
ipc_.signal_event.connect(sigc::mem_fun(*this, &BarIpcClient::onIpcEvent));
|
||||
ipc_.signal_cmd.connect(sigc::mem_fun(*this, &BarIpcClient::onCmd));
|
||||
// Launch worker
|
||||
ipc_.setWorker([this] {
|
||||
try {
|
||||
|
@ -61,23 +63,66 @@ void BarIpcClient::onInitialConfig(const struct Ipc::ipc_response& res) {
|
|||
void BarIpcClient::onIpcEvent(const struct Ipc::ipc_response& res) {
|
||||
try {
|
||||
auto payload = parser_.parse(res.payload);
|
||||
if (auto id = payload["id"]; id.isString() && id.asString() != bar_.bar_id) {
|
||||
spdlog::trace("swaybar ipc: ignore event for {}", id.asString());
|
||||
return;
|
||||
}
|
||||
if (payload.isMember("visible_by_modifier")) {
|
||||
// visibility change for hidden bar
|
||||
signal_visible_(payload["visible_by_modifier"].asBool());
|
||||
} else {
|
||||
// configuration update
|
||||
auto config = parseConfig(payload);
|
||||
signal_config_(std::move(config));
|
||||
switch (res.type) {
|
||||
case IPC_EVENT_WORKSPACE:
|
||||
if (payload.isMember("change")) {
|
||||
// only check and send signal if the workspace update reason was because of a urgent
|
||||
// change
|
||||
if (payload["change"] == "urgent") {
|
||||
auto urgent = payload["current"]["urgent"];
|
||||
if (urgent.asBool()) {
|
||||
// Event for a new urgency, update the visibly
|
||||
signal_urgency_(true);
|
||||
} else if (!urgent.asBool() && visible_by_urgency_) {
|
||||
// Event clearing an urgency, bar is visible, check if another workspace still has
|
||||
// the urgency hint set
|
||||
ipc_.sendCmd(IPC_GET_WORKSPACES);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IPC_EVENT_BAR_STATE_UPDATE:
|
||||
case IPC_EVENT_BARCONFIG_UPDATE:
|
||||
if (auto id = payload["id"]; id.isString() && id.asString() != bar_.bar_id) {
|
||||
spdlog::trace("swaybar ipc: ignore event for {}", id.asString());
|
||||
return;
|
||||
}
|
||||
if (payload.isMember("visible_by_modifier")) {
|
||||
// visibility change for hidden bar
|
||||
signal_visible_(payload["visible_by_modifier"].asBool());
|
||||
} else {
|
||||
// configuration update
|
||||
auto config = parseConfig(payload);
|
||||
signal_config_(std::move(config));
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
spdlog::error("BarIpcClient::onEvent {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void BarIpcClient::onCmd(const struct Ipc::ipc_response& res) {
|
||||
if (res.type == IPC_GET_WORKSPACES) {
|
||||
try {
|
||||
auto payload = parser_.parse(res.payload);
|
||||
for (auto& ws : payload) {
|
||||
if (ws["urgent"].asBool()) {
|
||||
spdlog::debug("Found workspace {} with urgency set. Stopping search.", ws["name"]);
|
||||
// Found one workspace with urgency set, signal bar visibility
|
||||
signal_urgency_(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Command to get workspaces was sent after a change in workspaces was based on "urgent",
|
||||
// if no workspace has this flag set to true, all flags must be cleared.
|
||||
signal_urgency_(false);
|
||||
} catch (const std::exception& e) {
|
||||
spdlog::error("Bar: {}", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BarIpcClient::onConfigUpdate(const swaybar_config& config) {
|
||||
spdlog::info("config update for {}: id {}, mode {}, hidden_state {}", bar_.bar_id, config.id,
|
||||
config.mode, config.hidden_state);
|
||||
|
@ -86,13 +131,19 @@ void BarIpcClient::onConfigUpdate(const swaybar_config& config) {
|
|||
}
|
||||
|
||||
void BarIpcClient::onVisibilityUpdate(bool visible_by_modifier) {
|
||||
spdlog::debug("visiblity update for {}: {}", bar_.bar_id, visible_by_modifier);
|
||||
spdlog::debug("visibility update for {}: {}", bar_.bar_id, visible_by_modifier);
|
||||
visible_by_modifier_ = visible_by_modifier;
|
||||
update();
|
||||
}
|
||||
|
||||
void BarIpcClient::onUrgencyUpdate(bool visible_by_urgency) {
|
||||
spdlog::debug("urgency update for {}: {}", bar_.bar_id, visible_by_urgency);
|
||||
visible_by_urgency_ = visible_by_urgency;
|
||||
update();
|
||||
}
|
||||
|
||||
void BarIpcClient::update() {
|
||||
bool visible = visible_by_modifier_;
|
||||
bool visible = visible_by_modifier_ || visible_by_urgency_;
|
||||
if (bar_config_.mode == "invisible") {
|
||||
visible = false;
|
||||
} else if (bar_config_.mode != "hide" || bar_config_.hidden_state != "hide") {
|
||||
|
|
Loading…
Reference in New Issue