Add dwl/window module
parent
32eac3ccb7
commit
17734f0364
|
@ -8,7 +8,7 @@
|
||||||
- Sway (Workspaces, Binding mode, Focused window name)
|
- Sway (Workspaces, Binding mode, Focused window name)
|
||||||
- River (Mapping mode, Tags, Focused window name)
|
- River (Mapping mode, Tags, Focused window name)
|
||||||
- Hyprland (Window Icons, Workspaces, Focused window name)
|
- Hyprland (Window Icons, Workspaces, Focused window name)
|
||||||
- DWL (Tags) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
|
- DWL (Tags, Focused window name) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
|
||||||
- Tray [#21](https://github.com/Alexays/Waybar/issues/21)
|
- Tray [#21](https://github.com/Alexays/Waybar/issues/21)
|
||||||
- Local time
|
- Local time
|
||||||
- Battery
|
- Battery
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "AAppIconLabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "util/json.hpp"
|
||||||
|
#include "dwl-ipc-unstable-v2-client-protocol.h"
|
||||||
|
|
||||||
|
namespace waybar::modules::dwl {
|
||||||
|
|
||||||
|
class Window : public AAppIconLabel, public sigc::trackable {
|
||||||
|
public:
|
||||||
|
Window(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
|
virtual ~Window() = default;
|
||||||
|
|
||||||
|
void handle_layout(const uint32_t layout);
|
||||||
|
void handle_title(const char *title);
|
||||||
|
void handle_appid(const char *ppid);
|
||||||
|
void handle_layout_symbol(const char *layout_symbol);
|
||||||
|
void handle_frame();
|
||||||
|
|
||||||
|
struct zdwl_ipc_manager_v2 *status_manager_;
|
||||||
|
private:
|
||||||
|
const Bar& bar_;
|
||||||
|
|
||||||
|
std::string title_;
|
||||||
|
std::string appid_;
|
||||||
|
std::string layout_symbol_;
|
||||||
|
uint32_t layout_;
|
||||||
|
|
||||||
|
struct zdwl_ipc_output_v2 *output_status_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::dwl
|
|
@ -0,0 +1,118 @@
|
||||||
|
waybar-dwl-window(5)
|
||||||
|
|
||||||
|
# NAME
|
||||||
|
|
||||||
|
waybar - dwl window module
|
||||||
|
|
||||||
|
# DESCRIPTION
|
||||||
|
|
||||||
|
The *window* module displays the title of the currently focused window in DWL
|
||||||
|
|
||||||
|
# CONFIGURATION
|
||||||
|
|
||||||
|
Addressed by *dwl/window*
|
||||||
|
|
||||||
|
*format*: ++
|
||||||
|
typeof: string ++
|
||||||
|
default: {title} ++
|
||||||
|
The format, how information should be displayed.
|
||||||
|
|
||||||
|
*rotate*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
Positive value to rotate the text label.
|
||||||
|
|
||||||
|
*max-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should accept.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
|
*justify*: ++
|
||||||
|
typeof: string ++
|
||||||
|
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||||
|
|
||||||
|
*on-click*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
|
*on-click-right*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when you right-click on the module.
|
||||||
|
|
||||||
|
*on-update*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when the module is updated.
|
||||||
|
|
||||||
|
*on-scroll-up*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when scrolling up on the module.
|
||||||
|
|
||||||
|
*on-scroll-down*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when scrolling down on the module.
|
||||||
|
|
||||||
|
*smooth-scrolling-threshold*: ++
|
||||||
|
typeof: double ++
|
||||||
|
Threshold to be used when scrolling.
|
||||||
|
|
||||||
|
*tooltip*: ++
|
||||||
|
typeof: bool ++
|
||||||
|
default: true ++
|
||||||
|
Option to disable tooltip on hover.
|
||||||
|
|
||||||
|
*rewrite*: ++
|
||||||
|
typeof: object ++
|
||||||
|
Rules to rewrite the module format output. See *rewrite rules*.
|
||||||
|
|
||||||
|
*icon*: ++
|
||||||
|
typeof: bool ++
|
||||||
|
default: false ++
|
||||||
|
Option to hide the application icon.
|
||||||
|
|
||||||
|
*icon-size*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
default: 24 ++
|
||||||
|
Option to change the size of the application icon.
|
||||||
|
|
||||||
|
# FORMAT REPLACEMENTS
|
||||||
|
|
||||||
|
*{title}*: The title of the focused window.
|
||||||
|
|
||||||
|
*{app_id}*: The app_id of the focused window.
|
||||||
|
|
||||||
|
*{layout}*: The layout of the focused window.
|
||||||
|
|
||||||
|
# REWRITE RULES
|
||||||
|
|
||||||
|
*rewrite* is an object where keys are regular expressions and values are
|
||||||
|
rewrite rules if the expression matches. Rules may contain references to
|
||||||
|
captures of the expression.
|
||||||
|
|
||||||
|
Regular expression and replacement follow ECMA-script rules.
|
||||||
|
|
||||||
|
If no expression matches, the format output is left unchanged.
|
||||||
|
|
||||||
|
Invalid expressions (e.g., mismatched parentheses) are skipped.
|
||||||
|
|
||||||
|
# EXAMPLES
|
||||||
|
|
||||||
|
```
|
||||||
|
"dwl/window": {
|
||||||
|
"format": "{}",
|
||||||
|
"max-length": 50,
|
||||||
|
"rewrite": {
|
||||||
|
"(.*) - Mozilla Firefox": "🌎 $1",
|
||||||
|
"(.*) - zsh": "> [$1]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
|
@ -310,6 +310,7 @@ A group may hide all but one element, showing them only on mouse hover. In order
|
||||||
- *waybar-custom(5)*
|
- *waybar-custom(5)*
|
||||||
- *waybar-disk(5)*
|
- *waybar-disk(5)*
|
||||||
- *waybar-dwl-tags(5)*
|
- *waybar-dwl-tags(5)*
|
||||||
|
- *waybar-dwl-window(5)*
|
||||||
- *waybar-gamemode(5)*
|
- *waybar-gamemode(5)*
|
||||||
- *waybar-hyprland-language(5)*
|
- *waybar-hyprland-language(5)*
|
||||||
- *waybar-hyprland-submap(5)*
|
- *waybar-hyprland-submap(5)*
|
||||||
|
|
|
@ -293,7 +293,9 @@ endif
|
||||||
if true
|
if true
|
||||||
add_project_arguments('-DHAVE_DWL', language: 'cpp')
|
add_project_arguments('-DHAVE_DWL', language: 'cpp')
|
||||||
src_files += files('src/modules/dwl/tags.cpp')
|
src_files += files('src/modules/dwl/tags.cpp')
|
||||||
|
src_files += files('src/modules/dwl/window.cpp')
|
||||||
man_files += files('man/waybar-dwl-tags.5.scd')
|
man_files += files('man/waybar-dwl-tags.5.scd')
|
||||||
|
man_files += files('man/waybar-dwl-window.5.scd')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if true
|
if true
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_DWL
|
#ifdef HAVE_DWL
|
||||||
#include "modules/dwl/tags.hpp"
|
#include "modules/dwl/tags.hpp"
|
||||||
|
#include "modules/dwl/window.hpp"
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_HYPRLAND
|
#ifdef HAVE_HYPRLAND
|
||||||
#include "modules/hyprland/language.hpp"
|
#include "modules/hyprland/language.hpp"
|
||||||
|
@ -187,6 +188,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name,
|
||||||
if (ref == "dwl/tags") {
|
if (ref == "dwl/tags") {
|
||||||
return new waybar::modules::dwl::Tags(id, bar_, config_[name]);
|
return new waybar::modules::dwl::Tags(id, bar_, config_[name]);
|
||||||
}
|
}
|
||||||
|
if (ref == "dwl/window") {
|
||||||
|
return new waybar::modules::dwl::Window(id, bar_, config_[name]);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_HYPRLAND
|
#ifdef HAVE_HYPRLAND
|
||||||
if (ref == "hyprland/window") {
|
if (ref == "hyprland/window") {
|
||||||
|
|
|
@ -21,11 +21,11 @@ wl_array tags, layouts;
|
||||||
|
|
||||||
static uint num_tags = 0;
|
static uint num_tags = 0;
|
||||||
|
|
||||||
void toggle_visibility(void *data, zdwl_ipc_output_v2 *zdwl_output_v2) {
|
static void toggle_visibility(void *data, zdwl_ipc_output_v2 *zdwl_output_v2) {
|
||||||
// Intentionally empty
|
// Intentionally empty
|
||||||
}
|
}
|
||||||
|
|
||||||
void active(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, uint32_t active) {
|
static void active(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, uint32_t active) {
|
||||||
// Intentionally empty
|
// Intentionally empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,15 +37,15 @@ static void set_tag(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, uint32_t tag
|
||||||
: num_tags & ~(1 << tag);
|
: num_tags & ~(1 << tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_layout_symbol(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, const char *layout) {
|
static void set_layout_symbol(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, const char *layout) {
|
||||||
// Intentionally empty
|
// Intentionally empty
|
||||||
}
|
}
|
||||||
|
|
||||||
void title(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, const char *title) {
|
static void title(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, const char *title) {
|
||||||
// Intentionally empty
|
// Intentionally empty
|
||||||
}
|
}
|
||||||
|
|
||||||
void dwl_frame(void *data, zdwl_ipc_output_v2 *zdwl_output_v2) {
|
static void dwl_frame(void *data, zdwl_ipc_output_v2 *zdwl_output_v2) {
|
||||||
// Intentionally empty
|
// Intentionally empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ Tags::Tags(const std::string &id, const waybar::Bar &bar, const Json::Value &con
|
||||||
output_status_{nullptr} {
|
output_status_{nullptr} {
|
||||||
struct wl_display *display = Client::inst()->wl_display;
|
struct wl_display *display = Client::inst()->wl_display;
|
||||||
struct wl_registry *registry = wl_display_get_registry(display);
|
struct wl_registry *registry = wl_display_get_registry(display);
|
||||||
|
|
||||||
wl_registry_add_listener(registry, ®istry_listener_impl, this);
|
wl_registry_add_listener(registry, ®istry_listener_impl, this);
|
||||||
wl_display_roundtrip(display);
|
wl_display_roundtrip(display);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
#include "modules/dwl/window.hpp"
|
||||||
|
|
||||||
|
#include <gdkmm/pixbuf.h>
|
||||||
|
#include <glibmm/fileutils.h>
|
||||||
|
#include <glibmm/keyfile.h>
|
||||||
|
#include <glibmm/miscutils.h>
|
||||||
|
#include <gtkmm/enums.h>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include "client.hpp"
|
||||||
|
#include "dwl-ipc-unstable-v2-client-protocol.h"
|
||||||
|
|
||||||
|
#include "util/rewrite_string.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::dwl {
|
||||||
|
|
||||||
|
static void toggle_visibility(void *data, zdwl_ipc_output_v2 *zdwl_output_v2) {
|
||||||
|
// Intentionally empty
|
||||||
|
}
|
||||||
|
|
||||||
|
static void active(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, uint32_t active) {
|
||||||
|
// Intentionally empty
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_tag(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, uint32_t tag, uint32_t state,
|
||||||
|
uint32_t clients, uint32_t focused) {
|
||||||
|
// Intentionally empty
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_layout_symbol(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, const char *layout) {
|
||||||
|
static_cast<Window *>(data)->handle_layout_symbol(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void title(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, const char *title) {
|
||||||
|
static_cast<Window *>(data)->handle_title(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwl_frame(void *data, zdwl_ipc_output_v2 *zdwl_output_v2) {
|
||||||
|
static_cast<Window *>(data)->handle_frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_layout(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, uint32_t layout) {
|
||||||
|
static_cast<Window *>(data)->handle_layout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appid(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, const char *appid){
|
||||||
|
static_cast<Window *>(data)->handle_appid(appid);
|
||||||
|
};
|
||||||
|
|
||||||
|
static const zdwl_ipc_output_v2_listener output_status_listener_impl{
|
||||||
|
.toggle_visibility = toggle_visibility,
|
||||||
|
.active = active,
|
||||||
|
.tag = set_tag,
|
||||||
|
.layout = set_layout,
|
||||||
|
.title = title,
|
||||||
|
.appid = appid,
|
||||||
|
.layout_symbol = set_layout_symbol,
|
||||||
|
.frame = dwl_frame,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void handle_global(void *data, struct wl_registry *registry, uint32_t name,
|
||||||
|
const char *interface, uint32_t version) {
|
||||||
|
if (std::strcmp(interface, zdwl_ipc_manager_v2_interface.name) == 0) {
|
||||||
|
static_cast<Window *>(data)->status_manager_ = static_cast<struct zdwl_ipc_manager_v2 *>(
|
||||||
|
(zdwl_ipc_manager_v2 *)wl_registry_bind(registry, name, &zdwl_ipc_manager_v2_interface, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) {
|
||||||
|
/* Ignore event */
|
||||||
|
}
|
||||||
|
|
||||||
|
static const wl_registry_listener registry_listener_impl = {.global = handle_global,
|
||||||
|
.global_remove = handle_global_remove};
|
||||||
|
|
||||||
|
Window::Window(const std::string& id, const Bar& bar, const Json::Value& config)
|
||||||
|
: AAppIconLabel(config, "window", id, "{}", 0, true), bar_(bar) {
|
||||||
|
struct wl_display *display = Client::inst()->wl_display;
|
||||||
|
struct wl_registry *registry = wl_display_get_registry(display);
|
||||||
|
|
||||||
|
wl_registry_add_listener(registry, ®istry_listener_impl, this);
|
||||||
|
wl_display_roundtrip(display);
|
||||||
|
|
||||||
|
if (!status_manager_) {
|
||||||
|
spdlog::error("dwl_status_manager_v2 not advertised");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_output *output = gdk_wayland_monitor_get_wl_output(bar_.output->monitor->gobj());
|
||||||
|
output_status_ = zdwl_ipc_manager_v2_get_output(status_manager_, output);
|
||||||
|
zdwl_ipc_output_v2_add_listener(output_status_, &output_status_listener_impl, this);
|
||||||
|
zdwl_ipc_manager_v2_destroy(status_manager_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::handle_title(const char *title) {
|
||||||
|
title_ = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::handle_appid(const char *appid) {
|
||||||
|
appid_ = appid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::handle_layout_symbol(const char *layout_symbol) {
|
||||||
|
layout_symbol_ = layout_symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::handle_layout(const uint32_t layout) {
|
||||||
|
layout_ = layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::handle_frame() {
|
||||||
|
label_.set_markup(waybar::util::rewriteString(
|
||||||
|
fmt::format(
|
||||||
|
fmt::runtime(format_),
|
||||||
|
fmt::arg("title", title_),
|
||||||
|
fmt::arg("layout", layout_symbol_),
|
||||||
|
fmt::arg("app_id", appid_)),
|
||||||
|
config_["rewrite"]));
|
||||||
|
updateAppIconName(appid_, "");
|
||||||
|
updateAppIcon();
|
||||||
|
if (tooltipEnabled()) {
|
||||||
|
label_.set_tooltip_text(title_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace waybar::modules::dwl
|
Loading…
Reference in New Issue