Skip to content

Commit 7b04583

Browse files
committed
Add niri/workspaces, niri/window, niri/language
1 parent 5d184f7 commit 7b04583

15 files changed

+1133
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Sway (Workspaces, Binding mode, Focused window name)
99
- River (Mapping mode, Tags, Focused window name)
1010
- Hyprland (Window Icons, Workspaces, Focused window name)
11+
- Niri (Workspaces, Focused window name, Language)
1112
- DWL (Tags, Focused window name) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
1213
- Tray [#21](https://github.com/Alexays/Waybar/issues/21)
1314
- Local time

include/modules/niri/backend.hpp

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#pragma once
2+
3+
#include <list>
4+
#include <mutex>
5+
#include <string>
6+
#include <utility>
7+
8+
#include "util/json.hpp"
9+
10+
namespace waybar::modules::niri {
11+
12+
class EventHandler {
13+
public:
14+
virtual void onEvent(const Json::Value& ev) = 0;
15+
virtual ~EventHandler() = default;
16+
};
17+
18+
class IPC {
19+
public:
20+
IPC() { startIPC(); }
21+
22+
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
23+
void unregisterForIPC(EventHandler* handler);
24+
25+
static Json::Value send(const Json::Value& request);
26+
27+
// The data members are only safe to access while dataMutex_ is locked.
28+
std::lock_guard<std::mutex> lockData() { return std::lock_guard(dataMutex_); }
29+
const std::vector<Json::Value> &workspaces() const { return workspaces_; }
30+
const std::vector<Json::Value> &windows() const { return windows_; }
31+
const std::vector<std::string> &keyboardLayoutNames() const { return keyboardLayoutNames_; }
32+
unsigned keyboardLayoutCurrent() const { return keyboardLayoutCurrent_; }
33+
34+
private:
35+
void startIPC();
36+
static int connectToSocket();
37+
void parseIPC(const std::string&);
38+
39+
std::mutex dataMutex_;
40+
std::vector<Json::Value> workspaces_;
41+
std::vector<Json::Value> windows_;
42+
std::vector<std::string> keyboardLayoutNames_;
43+
unsigned keyboardLayoutCurrent_;
44+
45+
util::JsonParser parser_;
46+
std::mutex callbackMutex_;
47+
std::list<std::pair<std::string, EventHandler*>> callbacks_;
48+
};
49+
50+
inline std::unique_ptr<IPC> gIPC;
51+
52+
}; // namespace waybar::modules::niri

include/modules/niri/language.hpp

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include <string>
4+
5+
#include "ALabel.hpp"
6+
#include "bar.hpp"
7+
#include "modules/niri/backend.hpp"
8+
9+
namespace waybar::modules::niri {
10+
11+
class Language : public ALabel, public EventHandler {
12+
public:
13+
Language(const std::string&, const Bar&, const Json::Value&);
14+
~Language() override;
15+
void update() override;
16+
17+
private:
18+
void updateFromIPC();
19+
void onEvent(const Json::Value &ev) override;
20+
void doUpdate();
21+
22+
struct Layout {
23+
std::string full_name;
24+
std::string short_name;
25+
std::string variant;
26+
std::string short_description;
27+
};
28+
29+
static Layout getLayout(const std::string &fullName);
30+
31+
std::mutex mutex_;
32+
const Bar &bar_;
33+
34+
std::vector<Layout> layouts_;
35+
unsigned current_idx_;
36+
};
37+
38+
} // namespace waybar::modules::niri

include/modules/niri/window.hpp

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
3+
#include <gtkmm/button.h>
4+
#include <json/value.h>
5+
6+
#include "AAppIconLabel.hpp"
7+
#include "bar.hpp"
8+
#include "modules/niri/backend.hpp"
9+
10+
namespace waybar::modules::niri {
11+
12+
class Window : public AAppIconLabel, public EventHandler {
13+
public:
14+
Window(const std::string &, const Bar &, const Json::Value &);
15+
~Window() override;
16+
void update() override;
17+
18+
private:
19+
void onEvent(const Json::Value &ev) override;
20+
void doUpdate();
21+
void setClass(const std::string &className, bool enable);
22+
23+
const Bar &bar_;
24+
25+
std::string oldAppId_;
26+
};
27+
28+
} // namespace waybar::modules::niri

include/modules/niri/workspaces.hpp

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
3+
#include <gtkmm/button.h>
4+
#include <json/value.h>
5+
6+
#include "AModule.hpp"
7+
#include "bar.hpp"
8+
#include "modules/niri/backend.hpp"
9+
10+
namespace waybar::modules::niri {
11+
12+
class Workspaces : public AModule, public EventHandler {
13+
public:
14+
Workspaces(const std::string &, const Bar &, const Json::Value &);
15+
~Workspaces() override;
16+
void update() override;
17+
18+
private:
19+
void onEvent(const Json::Value &ev) override;
20+
void doUpdate();
21+
Gtk::Button &addButton(const Json::Value &ws);
22+
std::string getIcon(const std::string &value, const Json::Value &ws);
23+
24+
const Bar &bar_;
25+
Gtk::Box box_;
26+
// Map from niri workspace id to button.
27+
std::unordered_map<uint64_t, Gtk::Button> buttons_;
28+
};
29+
30+
} // namespace waybar::modules::niri

man/waybar-niri-language.5.scd

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
waybar-niri-language(5)
2+
3+
# NAME
4+
5+
waybar - niri language module
6+
7+
# DESCRIPTION
8+
9+
The *language* module displays the currently selected language in niri.
10+
11+
# CONFIGURATION
12+
13+
Addressed by *niri/language*
14+
15+
*format*: ++
16+
typeof: string ++
17+
default: {} ++
18+
The format, how information should be displayed.
19+
20+
*format-<lang>* ++
21+
typeof: string++
22+
Provide an alternative name to display per language where <lang> is the language of your choosing. Can be passed multiple times with multiple languages as shown by the example below.
23+
24+
*menu*: ++
25+
typeof: string ++
26+
Action that popups the menu.
27+
28+
*menu-file*: ++
29+
typeof: string ++
30+
Location of the menu descriptor file. There need to be an element of type GtkMenu with id *menu*
31+
32+
*menu-actions*: ++
33+
typeof: array ++
34+
The actions corresponding to the buttons of the menu.
35+
36+
37+
# FORMAT REPLACEMENTS
38+
39+
*{short}*: Short name of layout (e.g. "us"). Equals to {}.
40+
41+
*{shortDescription}*: Short description of layout (e.g. "en").
42+
43+
*{long}*: Long name of layout (e.g. "English (Dvorak)").
44+
45+
*{variant}*: Variant of layout (e.g. "dvorak").
46+
47+
48+
# EXAMPLES
49+
50+
```
51+
"niri/language": {
52+
"format": "Lang: {long}"
53+
"format-en": "AMERICA, HELL YEAH!"
54+
"format-tr": "As bayrakları"
55+
}
56+
```
57+
58+
# STYLE
59+
60+
- *#language*

man/waybar-niri-window.5.scd

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
waybar-niri-window(5)
2+
3+
# NAME
4+
5+
waybar - niri window module
6+
7+
# DESCRIPTION
8+
9+
The *window* module displays the title of the currently focused window in niri.
10+
11+
# CONFIGURATION
12+
13+
Addressed by *niri/window*
14+
15+
*format*: ++
16+
typeof: string ++
17+
default: {title} ++
18+
The format, how information should be displayed. On {} the current window title is displayed.
19+
20+
*rewrite*: ++
21+
typeof: object ++
22+
Rules to rewrite window title. See *rewrite rules*.
23+
24+
*separate-outputs*: ++
25+
typeof: bool ++
26+
Show the active window of the monitor the bar belongs to, instead of the focused window.
27+
28+
*icon*: ++
29+
typeof: bool ++
30+
default: false ++
31+
Option to hide the application icon.
32+
33+
*icon-size*: ++
34+
typeof: integer ++
35+
default: 24 ++
36+
Option to change the size of the application icon.
37+
38+
# FORMAT REPLACEMENTS
39+
40+
See the output of "niri msg focused-window" for examples
41+
42+
*{title}*: The current title of the focused window.
43+
44+
*{app_id}*: The current app ID of the focused window.
45+
46+
# REWRITE RULES
47+
48+
*rewrite* is an object where keys are regular expressions and values are
49+
rewrite rules if the expression matches. Rules may contain references to
50+
captures of the expression.
51+
52+
Regular expression and replacement follow ECMA-script rules.
53+
54+
If no expression matches, the title is left unchanged.
55+
56+
Invalid expressions (e.g., mismatched parentheses) are skipped.
57+
58+
# EXAMPLES
59+
60+
```
61+
"niri/window": {
62+
"format": "{}",
63+
"rewrite": {
64+
"(.*) - Mozilla Firefox": "🌎 $1",
65+
"(.*) - zsh": "> [$1]"
66+
}
67+
}
68+
```
69+
70+
# STYLE
71+
72+
- *#window*
73+
- *window#waybar.empty #window* When no windows are on the workspace
74+
75+
The following classes are applied to the entire Waybar rather than just the
76+
window widget:
77+
78+
- *window#waybar.empty* When no windows are in the workspace
79+
- *window#waybar.solo* When only one window is on the workspace
80+
- *window#waybar.<app-id>* Where *app-id* is the app ID of the only window on
81+
the workspace

0 commit comments

Comments
 (0)