mirror of
				https://github.com/rad4day/Waybar.git
				synced 2025-10-31 07:52:42 +01:00 
			
		
		
		
	river/mode: new module
This module shows river's current mapping mode (e.g. normal, locked).
This commit is contained in:
		| @@ -17,6 +17,7 @@ | ||||
| #include "modules/wlr/workspace_manager.hpp" | ||||
| #endif | ||||
| #ifdef HAVE_RIVER | ||||
| #include "modules/river/mode.hpp" | ||||
| #include "modules/river/tags.hpp" | ||||
| #include "modules/river/window.hpp" | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										28
									
								
								include/modules/river/mode.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								include/modules/river/mode.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <wayland-client.h> | ||||
|  | ||||
| #include "ALabel.hpp" | ||||
| #include "bar.hpp" | ||||
| #include "river-status-unstable-v1-client-protocol.h" | ||||
|  | ||||
| namespace waybar::modules::river { | ||||
|  | ||||
| class Mode : public waybar::ALabel { | ||||
|  public: | ||||
|   Mode(const std::string &, const waybar::Bar &, const Json::Value &); | ||||
|   ~Mode(); | ||||
|  | ||||
|   // Handlers for wayland events | ||||
|   void handle_mode(const char *mode); | ||||
|  | ||||
|   struct zriver_status_manager_v1 *status_manager_; | ||||
|   struct wl_seat *seat_; | ||||
|  | ||||
|  private: | ||||
|   const waybar::Bar &bar_; | ||||
|   std::string mode_; | ||||
|   struct zriver_seat_status_v1 *seat_status_; | ||||
| }; | ||||
|  | ||||
| } /* namespace waybar::modules::river */ | ||||
							
								
								
									
										75
									
								
								man/waybar-river-mode.5.scd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								man/waybar-river-mode.5.scd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| waybar-river-mode(5) | ||||
|  | ||||
| # NAME | ||||
|  | ||||
| waybar - river mode module | ||||
|  | ||||
| # DESCRIPTION | ||||
|  | ||||
| The *mode* module displays the current mapping mode of river. | ||||
|  | ||||
| # CONFIGURATION | ||||
|  | ||||
| Addressed by *river/mode* | ||||
|  | ||||
| *format*: ++ | ||||
|     typeof: string  ++ | ||||
|     default: {} ++ | ||||
|     The format, how information should be displayed. On {} data gets inserted. | ||||
|  | ||||
| *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 take up. | ||||
|  | ||||
| *align*: ++ | ||||
|     typeof: float ++ | ||||
|     The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text. | ||||
|  | ||||
| *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 clicked 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. | ||||
|  | ||||
| # EXAMPLES | ||||
|  | ||||
| ``` | ||||
| "river/mode": { | ||||
|     "format": " {}" | ||||
| } | ||||
| ``` | ||||
|  | ||||
| # STYLE | ||||
|  | ||||
| - *#mode* | ||||
| - *#mode.<mode>* | ||||
| @@ -268,7 +268,9 @@ A module group is defined by specifying a module named "group/some-group-name". | ||||
| - *waybar-mpd(5)* | ||||
| - *waybar-network(5)* | ||||
| - *waybar-pulseaudio(5)* | ||||
| - *waybar-river-mode(5)* | ||||
| - *waybar-river-tags(5)* | ||||
| - *waybar-river-window(5)* | ||||
| - *waybar-states(5)* | ||||
| - *waybar-sway-mode(5)* | ||||
| - *waybar-sway-window(5)* | ||||
|   | ||||
| @@ -196,6 +196,7 @@ endif | ||||
|  | ||||
| if true | ||||
|     add_project_arguments('-DHAVE_RIVER', language: 'cpp') | ||||
|     src_files += 'src/modules/river/mode.cpp' | ||||
|     src_files += 'src/modules/river/tags.cpp' | ||||
|     src_files += 'src/modules/river/window.cpp' | ||||
| endif | ||||
| @@ -352,6 +353,7 @@ if scdoc.found() | ||||
|         'waybar-mpd.5.scd', | ||||
|         'waybar-network.5.scd', | ||||
|         'waybar-pulseaudio.5.scd', | ||||
|         'waybar-river-mode.5.scd', | ||||
|         'waybar-river-tags.5.scd', | ||||
|         'waybar-river-window.5.scd', | ||||
|         'waybar-sway-language.5.scd', | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|   </copyright> | ||||
|  | ||||
|   <interface name="zriver_status_manager_v1" version="2"> | ||||
|   <interface name="zriver_status_manager_v1" version="3"> | ||||
|     <description summary="manage river status objects"> | ||||
|       A global factory for objects that receive status information specific | ||||
|       to river. It could be used to implement, for example, a status bar. | ||||
| @@ -85,7 +85,7 @@ | ||||
|     </event> | ||||
|   </interface> | ||||
|  | ||||
|   <interface name="zriver_seat_status_v1" version="1"> | ||||
|   <interface name="zriver_seat_status_v1" version="3"> | ||||
|     <description summary="track seat focus"> | ||||
|       This interface allows clients to receive information about the current | ||||
|       focus of a seat. Note that (un)focused_output events will only be sent | ||||
| @@ -121,5 +121,13 @@ | ||||
|       </description> | ||||
|       <arg name="title" type="string" summary="title of the focused view"/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="mode" since="3"> | ||||
|       <description summary="the active mode changed"> | ||||
|         Sent once on binding the interface and again whenever a new mode | ||||
|         is entered (e.g. with riverctl enter-mode foobar). | ||||
|       </description> | ||||
|       <arg name="name" type="string" summary="name of the mode"/> | ||||
|     </event> | ||||
|   </interface> | ||||
| </protocol> | ||||
|   | ||||
| @@ -47,6 +47,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { | ||||
| #endif | ||||
| #endif | ||||
| #ifdef HAVE_RIVER | ||||
|     if (ref == "river/mode") { | ||||
|       return new waybar::modules::river::Mode(id, bar_, config_[name]); | ||||
|     } | ||||
|     if (ref == "river/tags") { | ||||
|       return new waybar::modules::river::Tags(id, bar_, config_[name]); | ||||
|     } | ||||
|   | ||||
							
								
								
									
										114
									
								
								src/modules/river/mode.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/modules/river/mode.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| #include "modules/river/mode.hpp" | ||||
|  | ||||
| #include <spdlog/spdlog.h> | ||||
| #include <wayland-client.h> | ||||
|  | ||||
| #include "client.hpp" | ||||
|  | ||||
| namespace waybar::modules::river { | ||||
|  | ||||
| static void listen_focused_output(void *data, struct zriver_seat_status_v1 *seat_status, | ||||
|                                   struct wl_output *output) { | ||||
|   // Intentionally empty | ||||
| } | ||||
|  | ||||
| static void listen_unfocused_output(void *data, struct zriver_seat_status_v1 *seat_status, | ||||
|                                     struct wl_output *output) { | ||||
|   // Intentionally empty | ||||
| } | ||||
|  | ||||
| static void listen_focused_view(void *data, struct zriver_seat_status_v1 *seat_status, | ||||
|                                 const char *title) { | ||||
|   // Intentionally empty | ||||
| } | ||||
|  | ||||
| static void listen_mode(void *data, struct zriver_seat_status_v1 *seat_status, const char *mode) { | ||||
|   static_cast<Mode *>(data)->handle_mode(mode); | ||||
| } | ||||
|  | ||||
| static const zriver_seat_status_v1_listener seat_status_listener_impl = { | ||||
|     .focused_output = listen_focused_output, | ||||
|     .unfocused_output = listen_unfocused_output, | ||||
|     .focused_view = listen_focused_view, | ||||
|     .mode = listen_mode, | ||||
| }; | ||||
|  | ||||
| static void handle_global(void *data, struct wl_registry *registry, uint32_t name, | ||||
|                           const char *interface, uint32_t version) { | ||||
|   if (std::strcmp(interface, zriver_status_manager_v1_interface.name) == 0) { | ||||
|     version = std::min<uint32_t>(version, 3); | ||||
|     if (version < ZRIVER_SEAT_STATUS_V1_MODE_SINCE_VERSION) { | ||||
|       spdlog::error( | ||||
|           "river server does not support the \"mode\" event; the module will be disabled"); | ||||
|       return; | ||||
|     } | ||||
|     static_cast<Mode *>(data)->status_manager_ = static_cast<struct zriver_status_manager_v1 *>( | ||||
|         wl_registry_bind(registry, name, &zriver_status_manager_v1_interface, version)); | ||||
|   } else if (std::strcmp(interface, wl_seat_interface.name) == 0) { | ||||
|     version = std::min<uint32_t>(version, 1); | ||||
|     static_cast<Mode *>(data)->seat_ = static_cast<struct wl_seat *>( | ||||
|         wl_registry_bind(registry, name, &wl_seat_interface, version)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| static void handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) { | ||||
|   // Nobody cares | ||||
| } | ||||
|  | ||||
| static const wl_registry_listener registry_listener_impl = {.global = handle_global, | ||||
|                                                             .global_remove = handle_global_remove}; | ||||
|  | ||||
| Mode::Mode(const std::string &id, const waybar::Bar &bar, const Json::Value &config) | ||||
|     : waybar::ALabel(config, "mode", id, "{}"), | ||||
|       status_manager_{nullptr}, | ||||
|       seat_{nullptr}, | ||||
|       bar_(bar), | ||||
|       mode_{""}, | ||||
|       seat_status_{nullptr} { | ||||
|   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("river_status_manager_v1 not advertised"); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if (!seat_) { | ||||
|     spdlog::error("wl_seat not advertised"); | ||||
|   } | ||||
|  | ||||
|   label_.hide(); | ||||
|   ALabel::update(); | ||||
|  | ||||
|   seat_status_ = zriver_status_manager_v1_get_river_seat_status(status_manager_, seat_); | ||||
|   zriver_seat_status_v1_add_listener(seat_status_, &seat_status_listener_impl, this); | ||||
|  | ||||
|   zriver_status_manager_v1_destroy(status_manager_); | ||||
| } | ||||
|  | ||||
| Mode::~Mode() { | ||||
|   if (seat_status_) { | ||||
|     zriver_seat_status_v1_destroy(seat_status_); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void Mode::handle_mode(const char *mode) { | ||||
|   if (format_.empty()) { | ||||
|     label_.hide(); | ||||
|   } else { | ||||
|     if (!mode_.empty()) { | ||||
|       label_.get_style_context()->remove_class(mode_); | ||||
|     } | ||||
|  | ||||
|     label_.get_style_context()->add_class(mode); | ||||
|     label_.set_markup(fmt::format(format_, mode)); | ||||
|     label_.show(); | ||||
|   } | ||||
|  | ||||
|   mode_ = mode; | ||||
|   ALabel::update(); | ||||
| } | ||||
|  | ||||
| } /* namespace waybar::modules::river */ | ||||
| @@ -24,10 +24,16 @@ static void listen_unfocused_output(void *data, struct zriver_seat_status_v1 *zr | ||||
|   static_cast<Window *>(data)->handle_unfocused_output(output); | ||||
| } | ||||
|  | ||||
| static void listen_mode(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, | ||||
|                         const char *mode) { | ||||
|   // This module doesn't care | ||||
| } | ||||
|  | ||||
| static const zriver_seat_status_v1_listener seat_status_listener_impl{ | ||||
|     .focused_output = listen_focused_output, | ||||
|     .unfocused_output = listen_unfocused_output, | ||||
|     .focused_view = listen_focused_view, | ||||
|     .mode = listen_mode, | ||||
| }; | ||||
|  | ||||
| static void handle_global(void *data, struct wl_registry *registry, uint32_t name, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 tiosgz
					tiosgz