Skip to content
Merged
1 change: 1 addition & 0 deletions include/factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#endif
#ifdef HAVE_WLR
#include "modules/wlr/taskbar.hpp"
#include "modules/wlr/workspace_manager.hpp"
#endif
#ifdef HAVE_RIVER
#include "modules/river/tags.hpp"
Expand Down
160 changes: 160 additions & 0 deletions include/modules/wlr/workspace_manager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#pragma once

#include <fmt/format.h>
#include <gtkmm/button.h>
#include <gtkmm/image.h>
#include <gtkmm/label.h>

#include <functional>
#include <map>
#include <memory>
#include <vector>

#include "AModule.hpp"
#include "bar.hpp"
#include "ext-workspace-unstable-v1-client-protocol.h"

namespace waybar::modules::wlr {

class WorkspaceManager;
class WorkspaceGroup;

class Workspace {
public:
Workspace(const waybar::Bar &bar, const Json::Value &config, WorkspaceGroup &workspace_group,
zext_workspace_handle_v1 *workspace, uint32_t id);
~Workspace();
auto update() -> void;

auto id() const -> uint32_t { return id_; }
auto is_active() const -> bool { return state_ & static_cast<uint32_t>(State::ACTIVE); }
auto is_urgent() const -> bool { return state_ & static_cast<uint32_t>(State::URGENT); }
auto is_hidden() const -> bool { return state_ & static_cast<uint32_t>(State::HIDDEN); }
// wlr stuff
auto handle_name(const std::string &name) -> void;
auto handle_coordinates(const std::vector<uint32_t> &coordinates) -> void;
auto handle_state(const std::vector<uint32_t> &state) -> void;
auto handle_remove() -> void;

auto handle_done() -> void;
auto handle_clicked(GdkEventButton *bt) -> bool;
auto show() -> void;
auto hide() -> void;
auto get_button_ref() -> Gtk::Button & { return button_; }
auto get_name() -> std::string & { return name_; }
auto get_coords() -> std::vector<uint32_t> & { return coordinates_; }

enum class State {
ACTIVE = (1 << 0),
URGENT = (1 << 1),
HIDDEN = (1 << 2),
};

private:
auto get_icon() -> std::string;

const Bar &bar_;
const Json::Value &config_;
WorkspaceGroup &workspace_group_;

// wlr stuff
zext_workspace_handle_v1 *workspace_handle_;
uint32_t state_ = 0;

uint32_t id_;
std::string name_;
std::vector<uint32_t> coordinates_;
static std::map<std::string, std::string> icons_map_;
std::string format_;
bool with_icon_ = false;

Gtk::Button button_;
Gtk::Box content_;
Gtk::Label label_;
};

class WorkspaceGroup {
public:
WorkspaceGroup(const waybar::Bar &bar, Gtk::Box &box, const Json::Value &config,
WorkspaceManager &manager, zext_workspace_group_handle_v1 *workspace_group_handle,
uint32_t id);
~WorkspaceGroup();
auto update() -> void;

auto id() const -> uint32_t { return id_; }
auto is_visible() const -> bool;
auto remove_workspace(uint32_t id_) -> void;
auto active_only() const -> bool;
auto creation_delayed() const -> bool;
auto workspaces() -> std::vector<std::unique_ptr<Workspace>> & { return workspaces_; }

auto sort_workspaces() -> void;
auto set_need_to_sort() -> void { need_to_sort = true; }
auto add_button(Gtk::Button &button) -> void;
auto remove_button(Gtk::Button &button) -> void;

// wlr stuff
auto handle_workspace_create(zext_workspace_handle_v1 *workspace_handle) -> void;
auto handle_remove() -> void;
auto handle_output_enter(wl_output *output) -> void;
auto handle_output_leave() -> void;
auto handle_done() -> void;
auto commit() -> void;

private:
static uint32_t workspace_global_id;
const waybar::Bar &bar_;
Gtk::Box &box_;
const Json::Value &config_;
WorkspaceManager &workspace_manager_;

// wlr stuff
zext_workspace_group_handle_v1 *workspace_group_handle_;
wl_output *output_ = nullptr;

uint32_t id_;
std::vector<std::unique_ptr<Workspace>> workspaces_;
bool need_to_sort = false;
};

class WorkspaceManager : public AModule {
public:
WorkspaceManager(const std::string &id, const waybar::Bar &bar, const Json::Value &config);
~WorkspaceManager() override;
auto update() -> void override;

auto all_outputs() const -> bool { return all_outputs_; }
auto active_only() const -> bool { return active_only_; }
auto workspace_comparator() const
-> std::function<bool(std::unique_ptr<Workspace> &, std::unique_ptr<Workspace> &)>;
auto creation_delayed() const -> bool { return creation_delayed_; }

auto sort_workspaces() -> void;
auto remove_workspace_group(uint32_t id_) -> void;

// wlr stuff
auto register_manager(wl_registry *registry, uint32_t name, uint32_t version) -> void;
auto handle_workspace_group_create(zext_workspace_group_handle_v1 *workspace_group_handle)
-> void;
auto handle_done() -> void;
auto handle_finished() -> void;
auto commit() -> void;

private:
const waybar::Bar &bar_;
Gtk::Box box_;
std::vector<std::unique_ptr<WorkspaceGroup>> groups_;

// wlr stuff
zext_workspace_manager_v1 *workspace_manager_ = nullptr;

static uint32_t group_global_id;

bool sort_by_name_ = true;
bool sort_by_coordinates_ = true;
bool all_outputs_ = false;
bool active_only_ = false;
bool creation_delayed_ = false;
};

} // namespace waybar::modules::wlr
8 changes: 8 additions & 0 deletions include/modules/wlr/workspace_manager_binding.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "ext-workspace-unstable-v1-client-protocol.h"

namespace waybar::modules::wlr {
void add_registry_listener(void *data);
void add_workspace_listener(zext_workspace_handle_v1 *workspace_handle, void *data);
void add_workspace_group_listener(zext_workspace_group_handle_v1 *workspace_group_handle, void *data);
zext_workspace_manager_v1* workspace_manager_bind(wl_registry *registry, uint32_t name, uint32_t version, void *data);
}
87 changes: 87 additions & 0 deletions man/waybar-wlr-workspaces.5.scd
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
waybar-wlr-workspaces(5)

# NAME

waybar - wlr workspaces module

# DESCRIPTION

The *workspaces* module displays the currently used workspaces in wayland compositor.

# CONFIGURATION

Addressed by *wlr/workspaces*

*format*: ++
typeof: string ++
default: {name} ++
The format, how information should be displayed.

*format-icons*: ++
typeof: array ++
Based on the workspace name and state, the corresponding icon gets selected. See *icons*.

*sort-by-name*: ++
typeof: bool ++
default: true ++
Should workspaces be sorted by name.

*sort-by-coordinates*: ++
typeof: bool ++
default: true ++
Should workspaces be sorted by coordinates.
Note that if both *sort-by-name* and *sort-by-coordinates* are true sort by name will be first.
If both are false - sort by id will be performed.

*all-outputs*: ++
typeof: bool ++
default: false ++
If set to false workspaces group will be shown only in assigned output. Otherwise all workspace groups are shown.

*active-only*: ++
typeof: bool ++
default: false ++
If set to true only active or urgent workspaces will be shown.

# FORMAT REPLACEMENTS

*{name}*: Name of workspace assigned by compositor

*{icon}*: Icon, as defined in *format-icons*.

# CLICK ACTIONS

*activate*: Switch to workspace.
*close*: Close the workspace.

# ICONS

Additional to workspace name matching, the following *format-icons* can be set.

- *default*: Will be shown, when no string match is found.
- *focused*: Will be shown, when workspace is focused

# EXAMPLES

```
"wlr/workspaces": {
"format": "{name}: {icon}",
"format-icons": {
"1": "",
"2": "",
"3": "",
"4": "",
"5": "",
"focused": "",
"default": ""
}
}
```

# Style

- *#workspaces*
- *#workspaces button*
- *#workspaces button.active*
- *#workspaces button.urgent*
- *#workspaces button.hidden*
1 change: 1 addition & 0 deletions man/waybar.5.scd.in
Original file line number Diff line number Diff line change
Expand Up @@ -224,5 +224,6 @@ Valid options for the "rotate" property are: 0, 90, 180 and 270.
- *waybar-sway-window(5)*
- *waybar-sway-workspaces(5)*
- *waybar-wlr-taskbar(5)*
- *waybar-wlr-workspaces(5)*
- *waybar-temperature(5)*
- *waybar-tray(5)*
3 changes: 3 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ src_files += [
if true
add_project_arguments('-DHAVE_WLR', language: 'cpp')
src_files += 'src/modules/wlr/taskbar.cpp'
src_files += 'src/modules/wlr/workspace_manager.cpp'
src_files += 'src/modules/wlr/workspace_manager_binding.cpp'
endif

if true
Expand Down Expand Up @@ -334,6 +336,7 @@ if scdoc.found()
'waybar-tray.5.scd',
'waybar-states.5.scd',
'waybar-wlr-taskbar.5.scd',
'waybar-wlr-workspaces.5.scd',
'waybar-bluetooth.5.scd',
'waybar-sndio.5.scd',
]
Expand Down
Loading