Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions include/modules/niri/workspace.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/image.h>
#include <gtkmm/label.h>
#include <json/value.h>

#include <string>

namespace waybar::modules::niri {

class Workspaces;

class Workspace {
public:
Workspace(const Json::Value& workspace_data, Workspaces& manager);
~Workspace() = default;

Workspace(const Workspace&) = delete;
Workspace& operator=(const Workspace&) = delete;

Gtk::Button& button() { return button_; }
uint64_t id() const { return id_; }

void update(const Json::Value& workspace_data, const std::vector<Json::Value>& all_windows);

private:
void rebuildTaskbar(const std::vector<Json::Value>& my_windows);

Glib::RefPtr<Gdk::Pixbuf> loadIcon(const std::string& app_id, int size);

Workspaces& manager_;
uint64_t id_;

// Layout: button_
// └─ box_ (horizontal)
// ├─ label_ workspace label / icon
// └─ taskbar_box_ app icon buttons (shown only when taskbar enabled)
Gtk::Button button_;
Gtk::Box box_;
Gtk::Label label_;
Gtk::Box taskbar_box_;
};

} // namespace waybar::modules::niri
24 changes: 17 additions & 7 deletions include/modules/niri/workspaces.hpp
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
#pragma once

#include <gtkmm/button.h>
#include <gtkmm/box.h>
#include <json/value.h>

#include <memory>
#include <vector>

#include "AModule.hpp"
#include "bar.hpp"
#include "modules/niri/backend.hpp"
#include "modules/niri/workspace.hpp"

namespace waybar::modules::niri {

class Workspaces : public AModule, public EventHandler {
public:
Workspaces(const std::string&, const Bar&, const Json::Value&);
Workspaces(const std::string& id, const Bar& bar, const Json::Value& config);
~Workspaces() override;

void update() override;

const Json::Value& config() const { return config_; }
const Bar& bar() const { return bar_; }

std::string getIcon(const std::string& value, const Json::Value& ws) const;

private:
void onEvent(const Json::Value& ev) override;
void doUpdate();
Gtk::Button& addButton(const Json::Value& ws);
std::string getIcon(const std::string& value, const Json::Value& ws);

void createWorkspace(const Json::Value& workspace_data);

const Bar& bar_;
Gtk::Box box_;
// Map from niri workspace id to button.
std::unordered_map<uint64_t, Gtk::Button> buttons_;

std::vector<std::unique_ptr<Workspace>> workspaces_;
};

} // namespace waybar::modules::niri
} // namespace waybar::modules::niri
26 changes: 26 additions & 0 deletions man/waybar-niri-workspaces.5.scd
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ Addressed by *niri/workspaces*
typeof: bool ++
default: false ++
Enables this module to consume all left over space dynamically.

*workspace-taskbar*: ++
typeof: object ++
Contains settings for the workspace taskbar, which displays app icons within each workspace.

*enable*: ++
typeof: bool ++
default: false ++
Enables the workspace taskbar mode.

*icon-size*: ++
typeof: int ++
default: 18 ++
Size of the icons in the workspace taskbar.

# FORMAT REPLACEMENTS

Expand Down Expand Up @@ -92,6 +106,16 @@ Additional to workspace name matching, the following *format-icons* can be set.
}
```

```
"niri/workspaces": {
"format": "{icon}",
"workspace-taskbar": {
"enable": true,
"icon-size": 18
}
}
```

# Style

- *#workspaces button*
Expand All @@ -103,3 +127,5 @@ Additional to workspace name matching, the following *format-icons* can be set.
the bar that it is displayed on.
- *#workspaces button#niri-workspace-<name>*: Workspaces named this, or index
for unnamed workspaces.
- *#workspaces button.niri-workspace*: The main container for the workspace.
- *#workspaces button .niri-taskbar-btn*: The icon buttons within the taskbar.
3 changes: 3 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ wayland_client = dependency('wayland-client')
wayland_cursor = dependency('wayland-cursor')
wayland_protos = dependency('wayland-protocols')
gtkmm = dependency('gtkmm-3.0', version : ['>=3.22.0'])
giomm = dependency('giomm-2.4', version : ['>=2.4.0'])
dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4', required: get_option('dbusmenu-gtk'))
giounix = dependency('gio-unix-2.0')
jsoncpp = dependency('jsoncpp', version : ['>=1.9.2'], fallback : ['jsoncpp', 'jsoncpp_dep'])
Expand Down Expand Up @@ -340,6 +341,7 @@ if get_option('niri')
'src/modules/niri/language.cpp',
'src/modules/niri/window.cpp',
'src/modules/niri/workspaces.cpp',
'src/modules/niri/workspace.cpp',
)
man_files += files(
'man/waybar-niri-language.5.scd',
Expand Down Expand Up @@ -542,6 +544,7 @@ executable(
jsoncpp,
wayland_cursor,
gtkmm,
giomm,
dbusmenu_gtk,
giounix,
libinput,
Expand Down
12 changes: 12 additions & 0 deletions src/modules/niri/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,18 @@ void IPC::parseIPC(const std::string& line) {
for (auto& win : windows_) {
win["is_focused"] = focused && win["id"].asUInt64() == id;
}
} else if (const auto& payload = ev["WindowLayoutsChanged"]) {
const auto& changes = payload["changes"];
for (const auto& change : changes) {
const auto id = change[0].asUInt64();
auto it = std::find_if(windows_.begin(), windows_.end(),
[id](const auto& win) { return win["id"].asUInt64() == id; });
if (it != windows_.end()) {
(*it)["layout"] = change[1];
} else {
spdlog::warn("WindowLayoutsChanged: unknown window id {}", id);
}
}
}
}

Expand Down
Loading