Skip to content

wlr/workspace: port to ext-workspace-v1 for labwc support #4016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
235 changes: 97 additions & 138 deletions include/modules/wlr/workspace_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,168 +5,127 @@
#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"
#include "ext-workspace-v1-client-protocol.h"

namespace waybar::modules::wlr {

class WorkspaceManager;
class WorkspaceGroup;
class Workspace;

class Workspace {
class WorkspaceManager final : public AModule {
public:
Workspace(const waybar::Bar &bar, const Json::Value &config, WorkspaceGroup &workspace_group,
zext_workspace_handle_v1 *workspace, uint32_t id, std::string name);
~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); }
auto is_empty() const -> bool { return state_ & static_cast<uint32_t>(State::EMPTY); }
auto is_persistent() const -> bool { return persistent_; }
// 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 make_persistent() -> void;
auto handle_duplicate() -> 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),
EMPTY = (1 << 3),
};
WorkspaceManager(const std::string &id, const waybar::Bar &bar, const Json::Value &config);
void register_manager(wl_registry *registry, uint32_t name, uint32_t version);
void remove_workspace_group(uint32_t id);
void remove_workspace(uint32_t id);

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;
bool persistent_ = false;

Gtk::Button button_;
Gtk::Box content_;
Gtk::Label label_;
};
// wlr events
void handle_workspace_group(ext_workspace_group_handle_v1 *handle);
void handle_workspace(ext_workspace_handle_v1 *handle);
void handle_done();
void handle_finished();

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 persistent_workspaces() -> std::vector<std::string> & { return persistent_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;
auto fill_persistent_workspaces() -> void;
auto create_persistent_workspaces() -> 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;
// wlr requests
void commit() const;

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;
void update() override;
bool has_button(const Gtk::Button *button);

uint32_t id_;
std::vector<std::unique_ptr<Workspace>> workspaces_;
bool need_to_sort = false;
std::vector<std::string> persistent_workspaces_;
bool persistent_created_ = false;
};
static uint32_t group_global_id;
static uint32_t workspace_global_id;

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;
bool sort_by_id_ = false;
bool sort_by_name_ = false;
bool sort_by_coordinates_ = false;
bool active_only_ = false;
bool all_outputs_ = false;

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

// wlr stuff
zext_workspace_manager_v1 *workspace_manager_ = nullptr;
ext_workspace_manager_v1 *ext_manager_ = nullptr;
std::vector<std::unique_ptr<WorkspaceGroup>> groups_;
std::vector<std::unique_ptr<Workspace>> workspaces_;
};

static uint32_t group_global_id;
class WorkspaceGroup {
public:
WorkspaceGroup(WorkspaceManager &manager, ext_workspace_group_handle_v1 *handle, uint32_t id);

u_int32_t id() const { return id_; }
bool has_output(const wl_output *output);
bool has_workspace(const ext_workspace_handle_v1 *workspace);

// wlr events
void handle_capabilities(uint32_t capabilities);
void handle_output_enter(wl_output *output);
void handle_output_leave(wl_output *output);
void handle_workspace_enter(ext_workspace_handle_v1 *handle);
void handle_workspace_leave(ext_workspace_handle_v1 *handle);
void handle_removed();

private:
WorkspaceManager &workspaces_manager_;
ext_workspace_group_handle_v1 *ext_handle_;
uint32_t id_;
std::vector<wl_output *> outputs_;
std::vector<ext_workspace_handle_v1 *> workspaces_;
};

bool sort_by_name_ = true;
bool sort_by_coordinates_ = true;
bool sort_by_number_ = false;
bool all_outputs_ = false;
bool active_only_ = false;
bool creation_delayed_ = false;
class Workspace {
public:
Workspace(const Json::Value &config, WorkspaceManager &manager, ext_workspace_handle_v1 *handle, uint32_t id);

ext_workspace_handle_v1 * handle() const { return ext_handle_; }
u_int32_t id() const { return id_; }
std::string & workspace_id() { return workspace_id_; }
std::string & name() { return name_; }
std::vector<u_int32_t> & coordinates() { return coordinates_; }
Gtk::Button & button() { return button_; }
bool is_active() const;
void update();

// wlr events
void handle_id(const std::string &id);
void handle_name(const std::string &name);
void handle_coordinates(const std::vector<uint32_t> &coordinates);
void handle_state(uint32_t state);
void handle_capabilities(uint32_t capabilities);
void handle_removed();

// gdk events
bool handle_clicked(const GdkEventButton *button) const;

private:
std::string icon();

WorkspaceManager &workspace_manager_;
ext_workspace_handle_v1 *ext_handle_ = nullptr;
uint32_t id_;
uint32_t state_ = 0;
std::string workspace_id_;
std::string name_;
std::vector<uint32_t> coordinates_;

std::string format_;
bool with_icon_ = false;
static std::map<std::string, std::string> icon_map_;
std::string on_click_action_;
std::string on_click_middle_action_;
std::string on_click_right_action_;

bool dirty_ = false;

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

} // namespace waybar::modules::wlr
8 changes: 4 additions & 4 deletions include/modules/wlr/workspace_manager_binding.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "ext-workspace-unstable-v1-client-protocol.h"
#include "ext-workspace-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 add_workspace_listener(ext_workspace_handle_v1 *workspace_handle, void *data);
void add_workspace_group_listener(ext_workspace_group_handle_v1 *workspace_group_handle,
void *data);
zext_workspace_manager_v1 *workspace_manager_bind(wl_registry *registry, uint32_t name,
ext_workspace_manager_v1 *workspace_manager_bind(wl_registry *registry, uint32_t name,
uint32_t version, void *data);
} // namespace waybar::modules::wlr
11 changes: 7 additions & 4 deletions man/waybar-wlr-workspaces.5.scd
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ Addressed by *wlr/workspaces*

*sort-by-coordinates*: ++
typeof: bool ++
default: true ++
default: false ++
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.

*sort-by-number*: ++
*sort-by-id*: ++
typeof: bool ++
default: false ++
If set to true, workspace names will be sorted numerically. Takes precedence over any other sort-by option.
Expand All @@ -49,7 +49,9 @@ Addressed by *wlr/workspaces*

# FORMAT REPLACEMENTS

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

*{id}*: ID of workspace assigned by compositor.

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

Expand All @@ -71,6 +73,7 @@ In addition to workspace name matching, the following *format-icons* can be set.
```
"wlr/workspaces": {
"format": "{name}: {icon}",
"on-click": "activate",
"format-icons": {
"1": "",
"2": "",
Expand All @@ -80,7 +83,7 @@ In addition to workspace name matching, the following *format-icons* can be set.
"active": "",
"default": ""
},
"sort-by-number": true
"sort-by-id": true
}
```

Expand Down
22 changes: 11 additions & 11 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,17 @@ if true
man_files += files('man/waybar-wlr-taskbar.5.scd')
endif

if dependency('wayland-protocols', version : ['>=1.39']).found()
add_project_arguments('-DHAVE_WLR_WORKSPACES', language: 'cpp')
src_files += files(
'src/modules/wlr/workspace_manager.cpp',
'src/modules/wlr/workspace_manager_binding.cpp',
)
man_files += files(
'man/waybar-wlr-workspaces.5.scd',
)
endif

if true
add_project_arguments('-DHAVE_RIVER', language: 'cpp')
src_files += files(
Expand Down Expand Up @@ -474,17 +485,6 @@ else
man_files += files('man/waybar-clock.5.scd')
endif

if get_option('experimental')
add_project_arguments('-DHAVE_WLR_WORKSPACES', language: 'cpp')
src_files += files(
'src/modules/wlr/workspace_manager.cpp',
'src/modules/wlr/workspace_manager_binding.cpp',
)
man_files += files(
'man/waybar-wlr-workspaces.5.scd',
)
endif

cava = dependency('cava',
version : '>=0.10.3',
required: get_option('cava'),
Expand Down
Loading