diff --git a/include/modules/hyprland/window.hpp b/include/modules/hyprland/window.hpp index 950be05f..54e7e2b7 100644 --- a/include/modules/hyprland/window.hpp +++ b/include/modules/hyprland/window.hpp @@ -40,6 +40,7 @@ class Window : public waybar::ALabel, public EventHandler { std::string last_solo_class_; bool solo_; bool all_floating_; + bool hidden_; bool fullscreen_; }; diff --git a/man/waybar-hyprland-window.5.scd b/man/waybar-hyprland-window.5.scd index 0135d7c9..58227092 100644 --- a/man/waybar-hyprland-window.5.scd +++ b/man/waybar-hyprland-window.5.scd @@ -21,6 +21,10 @@ Addressed by *hyprland/window* typeof: object ++ Rules to rewrite window title. See *rewrite rules*. +*separate-outputs*: ++ + typeof: bool ++ + Show the active window of the monitor the bar belongs to, instead of the focused window. + # REWRITE RULES *rewrite* is an object where keys are regular expressions and values are @@ -48,3 +52,18 @@ Invalid expressions (e.g., mismatched parentheses) are skipped. # STYLE - *#window* +- *#window.empty* When no windows are in the workspace + +The following classes are applied to the entire Waybar rather than just the +window widget: + +- *window#waybar.empty* When no windows are in the workspace +- *window#waybar.solo* When one tiled window is visible in the workspace + (floating windows may be present) +- *window#waybar.* Where ** is the *class* (e.g. *chromium*) of + the solo tiled window in the workspace (use *hyprctl clients* to see classes) +- *window#waybar.floating* When there are only floating windows in the workspace +- *window#waybar.fullscreen* When there is a fullscreen window in the workspace; + useful with Hyprland's *fullscreen, 1* mode +- *window#waybar.hidden* When there are hidden windows in the workspace; usually + occurs due to window swallowing diff --git a/man/waybar-sway-window.5.scd b/man/waybar-sway-window.5.scd index 0dd16295..8091e249 100644 --- a/man/waybar-sway-window.5.scd +++ b/man/waybar-sway-window.5.scd @@ -84,7 +84,7 @@ Addressed by *sway/window* typeof: bool ++ default: false ++ If the workspace itself is focused and the workspace contains nodes or floating_nodes, show the workspace name. If not set, text remains empty but styles according to nodes in the workspace are still applied. - + *rewrite*: ++ typeof: object ++ Rules to rewrite the module format output. See *rewrite rules*. @@ -136,6 +136,10 @@ Invalid expressions (e.g., mismatched parentheses) are skipped. # STYLE - *#window* + +The following classes are applied to the entire Waybar rather than just the +window widget: + - *window#waybar.empty* When no windows are in the workspace, or screen is not focused and offscreen-css option is not set - *window#waybar.solo* When one tiled window is in the workspace - *window#waybar.floating* When there are only floating windows in the workspace diff --git a/src/modules/hyprland/window.cpp b/src/modules/hyprland/window.cpp index cb820bcd..f429b8db 100644 --- a/src/modules/hyprland/window.cpp +++ b/src/modules/hyprland/window.cpp @@ -64,8 +64,9 @@ auto Window::update() -> void { setClass("empty", workspace_.windows == 0); setClass("solo", solo_); - setClass("fullscreen", fullscreen_); setClass("floating", all_floating_); + setClass("hidden", hidden_); + setClass("fullscreen", fullscreen_); if (!last_solo_class_.empty() && solo_class_ != last_solo_class_) { if (bar_.window.get_style_context()->has_class(last_solo_class_)) { @@ -126,36 +127,47 @@ void Window::queryActiveWorkspace() { } if (workspace_.windows > 0) { - const auto clients = gIPC->getSocket1Reply("j/clients"); - Json::Value json = parser_.parse(clients); - assert(json.isArray()); - auto active_window = std::find_if(json.begin(), json.end(), [&](Json::Value window) { + const auto clients = gIPC->getSocket1JsonReply("clients"); + assert(clients.isArray()); + auto active_window = std::find_if(clients.begin(), clients.end(), [&](Json::Value window) { return window["address"] == workspace_.last_window; }); - if (active_window == std::end(json)) { + if (active_window == std::end(clients)) { return; } - if (workspace_.windows == 1 && !(*active_window)["floating"].asBool()) { + std::vector workspace_windows; + std::copy_if(clients.begin(), clients.end(), std::back_inserter(workspace_windows), + [&](Json::Value window) { + return window["workspace"]["id"] == workspace_.id && window["mapped"].asBool(); + }); + hidden_ = std::any_of(workspace_windows.begin(), workspace_windows.end(), + [&](Json::Value window) { return window["hidden"].asBool(); }); + std::vector visible_windows; + std::copy_if(workspace_windows.begin(), workspace_windows.end(), + std::back_inserter(visible_windows), + [&](Json::Value window) { return !window["hidden"].asBool(); }); + solo_ = 1 == std::count_if(visible_windows.begin(), visible_windows.end(), + [&](Json::Value window) { return !window["floating"].asBool(); }); + all_floating_ = std::all_of(visible_windows.begin(), visible_windows.end(), + [&](Json::Value window) { return window["floating"].asBool(); }); + fullscreen_ = (*active_window)["fullscreen"].asBool(); + + if (fullscreen_) { + solo_ = true; + } + + if (solo_) { solo_class_ = (*active_window)["class"].asString(); } else { solo_class_ = ""; } - std::vector workspace_windows; - std::copy_if(json.begin(), json.end(), std::back_inserter(workspace_windows), - [&](Json::Value window) { - return window["workspace"]["id"] == workspace_.id && window["mapped"].asBool(); - }); - solo_ = 1 == std::count_if(workspace_windows.begin(), workspace_windows.end(), - [&](Json::Value window) { return !window["floating"].asBool(); }); - all_floating_ = std::all_of(workspace_windows.begin(), workspace_windows.end(), - [&](Json::Value window) { return window["floating"].asBool(); }); - fullscreen_ = (*active_window)["fullscreen"].asBool(); } else { - solo_class_ = ""; - solo_ = false; all_floating_ = false; + hidden_ = false; fullscreen_ = false; + solo_ = false; + solo_class_ = ""; } }