From 70a11edea4a28885febe3aa17ec4519c4c0f07fd Mon Sep 17 00:00:00 2001 From: Mahesh Asolkar Date: Sun, 18 Feb 2024 11:26:41 -0800 Subject: [PATCH] Support for DWL IPC v2 * More customizations for indicators --- protocols/dwl-ipc-unstable-v2.xml | 181 ++++++++++++++++++++++++++++++ protocols/meson.build | 2 +- src/bar.cpp | 5 +- src/common.hpp | 10 +- src/main.cpp | 78 ++++++++----- 5 files changed, 239 insertions(+), 37 deletions(-) create mode 100644 protocols/dwl-ipc-unstable-v2.xml diff --git a/protocols/dwl-ipc-unstable-v2.xml b/protocols/dwl-ipc-unstable-v2.xml new file mode 100644 index 0000000..0a6e7e5 --- /dev/null +++ b/protocols/dwl-ipc-unstable-v2.xml @@ -0,0 +1,181 @@ + + + + + This protocol allows clients to update and get updates from dwl. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible + changes may be added together with the corresponding interface + version bump. + Backward incompatible changes are done by bumping the version + number in the protocol and interface names and resetting the + interface version. Once the protocol is to be declared stable, + the 'z' prefix and the version number in the protocol and + interface names are removed and the interface version number is + reset. + + + + + This interface is exposed as a global in wl_registry. + + Clients can use this interface to get a dwl_ipc_output. + After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events. + The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client. + + + + + Indicates that the client will not the dwl_ipc_manager object anymore. + Objects created through this instance are not affected. + + + + + + Get a dwl_ipc_outout for the specified wl_output. + + + + + + + + This event is sent after binding. + A roundtrip after binding guarantees the client recieved all tags. + + + + + + + This event is sent after binding. + A roundtrip after binding guarantees the client recieved all layouts. + + + + + + + + Observe and control a dwl output. + + Events are double-buffered: + Clients should cache events and redraw when a dwl_ipc_output.frame event is sent. + + Request are not double-buffered: + The compositor will update immediately upon request. + + + + + + + + + + + Indicates to that the client no longer needs this dwl_ipc_output. + + + + + + Indicates the client should hide or show themselves. + If the client is visible then hide, if hidden then show. + + + + + + Indicates if the output is active. Zero is invalid, nonzero is valid. + + + + + + + Indicates that a tag has been updated. + + + + + + + + + + Indicates a new layout is selected. + + + + + + + Indicates the title has changed. + + + + + + + Indicates the appid has changed. + + + + + + + Indicates the layout has changed. Since layout symbols are dynamic. + As opposed to the zdwl_ipc_manager.layout event, this should take precendence when displaying. + You can ignore the zdwl_ipc_output.layout event. + + + + + + + Indicates that a sequence of status updates have finished and the client should redraw. + + + + + + + + + + + + The tags are updated as follows: + new_tags = (current_tags AND and_tags) XOR xor_tags + + + + + + + + + + + + + + Indicates if the selected client on this output is fullscreen. + + + + + + + Indicates if the selected client on this output is floating. + + + + + diff --git a/protocols/meson.build b/protocols/meson.build index 5752608..0f6f808 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -15,7 +15,7 @@ wayland_xmls = [ wl_protocol_dir + '/stable/xdg-shell/xdg-shell.xml', wl_protocol_dir + '/unstable/xdg-output/xdg-output-unstable-v1.xml', 'wlr-layer-shell-unstable-v1.xml', - 'net-tapesoftware-dwl-wm-unstable-v1.xml', + 'dwl-ipc-unstable-v2.xml', ] wayland_sources = [ wayland_scanner_code.process(wayland_xmls), diff --git a/src/bar.cpp b/src/bar.cpp index a48f06e..b731220 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -87,8 +87,9 @@ Bar::Bar() if (!_pangoContext) { die("pango_font_map_create_context"); } - for (const auto& tagName : tagNames) { - _tags.push_back({ TagState::None, 0, 0, createComponent(tagName) }); + //for (const auto& tagName : tagNames) { + for (int ti = 1; ti < 10; ti++ ) { + _tags.push_back({ TagState::None, 0, 0, createComponent(std::to_string(ti)) }); } _layoutCmp = createComponent(); _titleCmp = createComponent(); diff --git a/src/common.hpp b/src/common.hpp index a27ca74..28e9faf 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -5,12 +5,14 @@ #include #include #include +#include +#include #include #include #include #include #include "wlr-layer-shell-unstable-v1-client-protocol.h" -#include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h" +#include "dwl-ipc-unstable-v2-client-protocol.h" struct Color { Color() {} @@ -39,8 +41,8 @@ extern wl_display* display; extern wl_compositor* compositor; extern wl_shm* shm; extern zwlr_layer_shell_v1* wlrLayerShell; -extern std::vector tagNames; -extern std::vector layoutNames; +static std::vector tagNames; +static std::vector layoutNames; void view(Monitor& m, const Arg& arg); void toggleview(Monitor& m, const Arg& arg); @@ -74,7 +76,7 @@ WL_DELETER(wl_output, wl_output_release_checked); WL_DELETER(wl_pointer, wl_pointer_release); WL_DELETER(wl_seat, wl_seat_release); WL_DELETER(wl_surface, wl_surface_destroy); -WL_DELETER(znet_tapesoftware_dwl_wm_monitor_v1, znet_tapesoftware_dwl_wm_monitor_v1_release); +WL_DELETER(zdwl_ipc_output_v2, zdwl_ipc_output_v2_destroy); WL_DELETER(zwlr_layer_surface_v1, zwlr_layer_surface_v1_destroy); WL_DELETER(cairo_t, cairo_destroy); diff --git a/src/main.cpp b/src/main.cpp index 1e1eef0..937fd8e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,7 @@ #include "wlr-layer-shell-unstable-v1-client-protocol.h" #include "xdg-output-unstable-v1-client-protocol.h" #include "xdg-shell-client-protocol.h" -#include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h" +#include "dwl-ipc-unstable-v2-client-protocol.h" #include "common.hpp" #include "config.hpp" #include "bar.hpp" @@ -35,7 +35,7 @@ struct Monitor { bool desiredVisibility {true}; bool hasData; uint32_t tags; - wl_unique_ptr dwlMonitor; + wl_unique_ptr dwlMonitor; }; struct SeatPointer { @@ -69,9 +69,8 @@ wl_display* display; wl_compositor* compositor; wl_shm* shm; zwlr_layer_shell_v1* wlrLayerShell; -znet_tapesoftware_dwl_wm_v1* dwlWm; -std::vector tagNames; -std::vector layoutNames; +zdwl_ipc_manager_v2* dwlWm; +char* log_txt; static xdg_wm_base* xdgWmBase; static zxdg_output_manager_v1* xdgOutputManager; static wl_surface* cursorSurface; @@ -92,23 +91,23 @@ static bool quitting {false}; void view(Monitor& m, const Arg& arg) { - znet_tapesoftware_dwl_wm_monitor_v1_set_tags(m.dwlMonitor.get(), arg.ui, 1); + zdwl_ipc_output_v2_set_tags(m.dwlMonitor.get(), arg.ui, 1); } void toggleview(Monitor& m, const Arg& arg) { - znet_tapesoftware_dwl_wm_monitor_v1_set_tags(m.dwlMonitor.get(), m.tags ^ arg.ui, 0); + zdwl_ipc_output_v2_set_tags(m.dwlMonitor.get(), m.tags ^ arg.ui, 0); } void setlayout(Monitor& m, const Arg& arg) { - znet_tapesoftware_dwl_wm_monitor_v1_set_layout(m.dwlMonitor.get(), arg.ui); + zdwl_ipc_output_v2_set_layout(m.dwlMonitor.get(), arg.ui); } void tag(Monitor& m, const Arg& arg) { - znet_tapesoftware_dwl_wm_monitor_v1_set_client_tags(m.dwlMonitor.get(), 0, arg.ui); + zdwl_ipc_output_v2_set_client_tags(m.dwlMonitor.get(), 0, arg.ui); } void toggletag(Monitor& m, const Arg& arg) { - znet_tapesoftware_dwl_wm_monitor_v1_set_client_tags(m.dwlMonitor.get(), ~0, arg.ui); + zdwl_ipc_output_v2_set_client_tags(m.dwlMonitor.get(), ~0, arg.ui); } void spawn(Monitor&, const Arg& arg) { @@ -214,31 +213,35 @@ static const struct wl_seat_listener seatListener = { .name = [](void*, wl_seat*, const char* name) { } }; -static const struct znet_tapesoftware_dwl_wm_v1_listener dwlWmListener = { - .tag = [](void*, znet_tapesoftware_dwl_wm_v1*, const char* name) { - tagNames.push_back(name); +static const struct zdwl_ipc_manager_v2_listener dwlWmListener = { + .tags = [](void*, zdwl_ipc_manager_v2*, uint32_t tag_cnt) { + for (uint32_t ti=0; ti<=tag_cnt; ti++) { + tagNames.push_back(std::to_string(ti)); + } }, - .layout = [](void*, znet_tapesoftware_dwl_wm_v1*, const char* name) { + .layout = [](void*, zdwl_ipc_manager_v2*, const char* name) { layoutNames.push_back(name); }, }; -static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorListener { - .selected = [](void* mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t selected) { +static const struct zdwl_ipc_output_v2_listener dwlWmMonitorListener { + .toggle_visibility = [](void* mv, zdwl_ipc_output_v2*) { + }, + .active = [](void* mv, zdwl_ipc_output_v2*, uint32_t active) { auto mon = static_cast(mv); - if (selected) { + if (active) { selmon = mon; } else if (selmon == mon) { selmon = nullptr; } - mon->bar.setSelected(selected); + mon->bar.setSelected(active); }, - .tag = [](void* mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t tag, uint32_t state, uint32_t numClients, int32_t focusedClient) { + .tag = [](void* mv, zdwl_ipc_output_v2*, uint32_t tag, uint32_t state, uint32_t numClients, uint32_t focusedClient) { auto mon = static_cast(mv); int tagState = TagState::None; - if (state & ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_ACTIVE) + if (state & ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE) tagState |= TagState::Active; - if (state & ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_URGENT) + if (state & ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT) tagState |= TagState::Urgent; mon->bar.setTag(tag, tagState, numClients, focusedClient); uint32_t mask = 1 << tag; @@ -248,7 +251,7 @@ static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorLis mon->tags &= ~mask; } }, - .layout = [](void* mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t layout) { + .layout = [](void* mv, zdwl_ipc_output_v2*, uint32_t layout) { auto mon = static_cast(mv); if (layout == 2) { char lout[4] = "[M]"; @@ -261,14 +264,27 @@ static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorLis mon->bar.setLayout(layoutNames[layout]); } }, - .title = [](void* mv, znet_tapesoftware_dwl_wm_monitor_v1*, const char* title) { + .title = [](void* mv, zdwl_ipc_output_v2*, const char* title) { auto mon = static_cast(mv); mon->bar.setTitle(title); }, - .frame = [](void* mv, znet_tapesoftware_dwl_wm_monitor_v1*) { + .appid = [](void* mv, zdwl_ipc_output_v2*, const char* appid) { + //auto mon = static_cast(mv); + }, + .layout_symbol = [](void* mv, zdwl_ipc_output_v2*, const char* layout) { + auto mon = static_cast(mv); + mon->bar.setLayout(layout); + }, + .frame = [](void* mv, zdwl_ipc_output_v2*) { auto mon = static_cast(mv); mon->hasData = true; updatemon(*mon); + }, + .fullscreen = [](void* mv, zdwl_ipc_output_v2*, uint32_t is_fullscreen) { + // auto mon = static_cast(mv); + }, + .floating = [](void* mv, zdwl_ipc_output_v2*, uint32_t is_floating) { + //auto mon = static_cast(mv); } }; @@ -277,8 +293,8 @@ void setupMonitor(uint32_t name, wl_output* output) { monitor.bar.setStatus(lastStatus); auto xdgOutput = zxdg_output_manager_v1_get_xdg_output(xdgOutputManager, monitor.wlOutput.get()); zxdg_output_v1_add_listener(xdgOutput, &xdgOutputListener, &monitor); - monitor.dwlMonitor.reset(znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, monitor.wlOutput.get())); - znet_tapesoftware_dwl_wm_monitor_v1_add_listener(monitor.dwlMonitor.get(), &dwlWmMonitorListener, &monitor); + monitor.dwlMonitor.reset(zdwl_ipc_manager_v2_get_output(dwlWm, monitor.wlOutput.get())); + zdwl_ipc_output_v2_add_listener(monitor.dwlMonitor.get(), &dwlWmMonitorListener, &monitor); } void updatemon(Monitor& mon) @@ -304,7 +320,7 @@ void onReady() requireGlobal(shm, "wl_shm"); requireGlobal(wlrLayerShell, "zwlr_layer_shell_v1"); requireGlobal(xdgOutputManager, "zxdg_output_manager_v1"); - requireGlobal(dwlWm, "znet_tapesoftware_dwl_wm_v1"); + requireGlobal(dwlWm, "zdwl_ipc_manager_v2_interface"); setupStatusFifo(); wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc. @@ -318,6 +334,7 @@ void onReady() bool createFifo(std::string path) { auto result = mkfifo(path.c_str(), 0666); + // if (result == 0) { if ((result == 0) || (errno == EEXIST)) { auto fd = open(path.c_str(), O_CLOEXEC | O_NONBLOCK | O_RDONLY); if (fd < 0) { @@ -362,6 +379,7 @@ void setupStatusFifo() static LineBuffer<512> stdinBuffer; static void onStdin() { + return; auto res = stdinBuffer.readLines( [](void* p, size_t size) { return read(0, p, size); }, [](char* p, size_t size) { handleStdin({p, size}); }); @@ -495,8 +513,8 @@ void onGlobalAdd(void*, wl_registry* registry, uint32_t name, const char* interf xdg_wm_base_add_listener(xdgWmBase, &xdgWmBaseListener, nullptr); return; } - if (reg.handle(dwlWm, znet_tapesoftware_dwl_wm_v1_interface, 1)) { - znet_tapesoftware_dwl_wm_v1_add_listener(dwlWm, &dwlWmListener, nullptr); + if (reg.handle(dwlWm, zdwl_ipc_manager_v2_interface, 1)) { + zdwl_ipc_manager_v2_add_listener(dwlWm, &dwlWmListener, nullptr); return; } if (wl_seat* wlSeat; reg.handle(wlSeat, wl_seat_interface, 7)) { @@ -526,6 +544,7 @@ static const struct wl_registry_listener registry_listener = { int main(int argc, char* argv[]) { int opt; + while ((opt = getopt(argc, argv, "chvs:")) != -1) { switch (opt) { case 's': @@ -701,4 +720,3 @@ void diesys(const char* why) { cleanup(); exit(1); } -