dont deadlock while receiving events
This commit is contained in:
		
							parent
							
								
									0b5710da3e
								
							
						
					
					
						commit
						7298730969
					
				| @ -66,6 +66,12 @@ | |||||||
|             <arg name="tag" type="int"/> |             <arg name="tag" type="int"/> | ||||||
|             <arg name="active" type="int"/> |             <arg name="active" type="int"/> | ||||||
|             <arg name="num_clients" type="int"/> |             <arg name="num_clients" type="int"/> | ||||||
|  |             <arg name="urgent" type="int"/> | ||||||
|  |         </event> | ||||||
|  | 
 | ||||||
|  |         <event name="frame"> | ||||||
|  |             <description summary="sent after all other events have been sent. allows for atomic updates."> | ||||||
|  |             </description> | ||||||
|         </event> |         </event> | ||||||
|     </interface> |     </interface> | ||||||
| </protocol> | </protocol> | ||||||
|  | |||||||
							
								
								
									
										46
									
								
								src/bar.cpp
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								src/bar.cpp
									
									
									
									
									
								
							| @ -27,25 +27,25 @@ static QFont getFont() | |||||||
|     font.setBold(fontBold); |     font.setBold(fontBold); | ||||||
|     return font; |     return font; | ||||||
| } | } | ||||||
|  | static QFont font = getFont(); | ||||||
|  | static QFontMetrics fontMetrics = QFontMetrics {font}; | ||||||
| 
 | 
 | ||||||
| Bar::Bar(const wl_output *output) | Bar::Bar(const wl_output *output) | ||||||
|     : _font {getFont()} |  | ||||||
|     , _fontMetrics {_font} |  | ||||||
| { | { | ||||||
|     _surface = wl_compositor_create_surface(compositor); |     _surface.reset(wl_compositor_create_surface(compositor)); | ||||||
|     _layerSurface = zwlr_layer_shell_v1_get_layer_surface(wlrLayerShell, |     _layerSurface.reset(zwlr_layer_shell_v1_get_layer_surface(wlrLayerShell, | ||||||
|         _surface, nullptr, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "net.tapesoftware.Somebar"); |         _surface.get(), nullptr, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "net.tapesoftware.Somebar")); | ||||||
|     zwlr_layer_surface_v1_add_listener(_layerSurface, &_layerSurfaceListener, this); |     zwlr_layer_surface_v1_add_listener(_layerSurface.get(), &_layerSurfaceListener, this); | ||||||
|     auto anchor = topbar ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; |     auto anchor = topbar ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; | ||||||
|     zwlr_layer_surface_v1_set_anchor(_layerSurface, |     zwlr_layer_surface_v1_set_anchor(_layerSurface.get(), | ||||||
|         anchor | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); |         anchor | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); | ||||||
| 
 | 
 | ||||||
|     auto barSize = _fontMetrics.ascent() + _fontMetrics.descent() + paddingY * 2; |     auto barSize = fontMetrics.ascent() + fontMetrics.descent() + paddingY * 2; | ||||||
|     _textY = _fontMetrics.ascent() + paddingY; |     _textY = fontMetrics.ascent() + paddingY; | ||||||
| 
 | 
 | ||||||
|     zwlr_layer_surface_v1_set_size(_layerSurface, 0, barSize); |     zwlr_layer_surface_v1_set_size(_layerSurface.get(), 0, barSize); | ||||||
|     zwlr_layer_surface_v1_set_exclusive_zone(_layerSurface, barSize); |     zwlr_layer_surface_v1_set_exclusive_zone(_layerSurface.get(), barSize); | ||||||
|     wl_surface_commit(_surface); |     wl_surface_commit(_surface.get()); | ||||||
| 
 | 
 | ||||||
|     for (auto tag : tagNames) { |     for (auto tag : tagNames) { | ||||||
|         _tags.push_back({ tag, false }); |         _tags.push_back({ tag, false }); | ||||||
| @ -54,11 +54,7 @@ Bar::Bar(const wl_output *output) | |||||||
|     _status = "Status"; |     _status = "Status"; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Bar::~Bar() | const wl_surface* Bar::surface() const { return _surface.get(); } | ||||||
| { |  | ||||||
|     wl_surface_destroy(_surface); |  | ||||||
|     zwlr_layer_surface_v1_destroy(_layerSurface); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void Bar::click(int x, int) | void Bar::click(int x, int) | ||||||
| { | { | ||||||
| @ -75,9 +71,9 @@ void Bar::invalidate() | |||||||
| { | { | ||||||
|     if (_invalid) return; |     if (_invalid) return; | ||||||
|     _invalid = true; |     _invalid = true; | ||||||
|     auto frame = wl_surface_frame(_surface); |     auto frame = wl_surface_frame(_surface.get()); | ||||||
|     wl_callback_add_listener(frame, &_frameListener, this); |     wl_callback_add_listener(frame, &_frameListener, this); | ||||||
|     wl_surface_commit(_surface); |     wl_surface_commit(_surface.get()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Bar::setStatus(const QString &status) | void Bar::setStatus(const QString &status) | ||||||
| @ -88,7 +84,7 @@ void Bar::setStatus(const QString &status) | |||||||
| 
 | 
 | ||||||
| void Bar::layerSurfaceConfigure(uint32_t serial, uint32_t width, uint32_t height) | void Bar::layerSurfaceConfigure(uint32_t serial, uint32_t width, uint32_t height) | ||||||
| { | { | ||||||
|     zwlr_layer_surface_v1_ack_configure(_layerSurface, serial); |     zwlr_layer_surface_v1_ack_configure(_layerSurface.get(), serial); | ||||||
|     _bufs.emplace(width, height, WL_SHM_FORMAT_XRGB8888); |     _bufs.emplace(width, height, WL_SHM_FORMAT_XRGB8888); | ||||||
|     render(); |     render(); | ||||||
| } | } | ||||||
| @ -105,7 +101,7 @@ void Bar::render() | |||||||
|     auto painter = QPainter {&img}; |     auto painter = QPainter {&img}; | ||||||
|     _painter = &painter; |     _painter = &painter; | ||||||
|     _x = 0; |     _x = 0; | ||||||
|     painter.setFont(_font); |     painter.setFont(font); | ||||||
| 
 | 
 | ||||||
|     setColorScheme(colorActive); |     setColorScheme(colorActive); | ||||||
|     painter.fillRect(0, 0, img.width(), img.height(), painter.brush()); |     painter.fillRect(0, 0, img.width(), img.height(), painter.brush()); | ||||||
| @ -115,9 +111,9 @@ void Bar::render() | |||||||
|     renderStatus(); |     renderStatus(); | ||||||
|      |      | ||||||
|     _painter = nullptr; |     _painter = nullptr; | ||||||
|     wl_surface_attach(_surface, _bufs->buffer(), 0, 0); |     wl_surface_attach(_surface.get(), _bufs->buffer(), 0, 0); | ||||||
|     wl_surface_damage(_surface, 0, 0, INT_MAX, INT_MAX); |     wl_surface_damage(_surface.get(), 0, 0, INT_MAX, INT_MAX); | ||||||
|     wl_surface_commit(_surface); |     wl_surface_commit(_surface.get()); | ||||||
|     _bufs->flip(); |     _bufs->flip(); | ||||||
|     _invalid = false; |     _invalid = false; | ||||||
| } | } | ||||||
| @ -156,5 +152,5 @@ void Bar::renderStatus() | |||||||
| 
 | 
 | ||||||
| int Bar::textWidth(const QString &text) | int Bar::textWidth(const QString &text) | ||||||
| { | { | ||||||
|     return _fontMetrics.size(Qt::TextSingleLine, text).width(); |     return fontMetrics.size(Qt::TextSingleLine, text).width(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -22,11 +22,9 @@ class Bar { | |||||||
|     static const zwlr_layer_surface_v1_listener _layerSurfaceListener; |     static const zwlr_layer_surface_v1_listener _layerSurfaceListener; | ||||||
|     static const wl_callback_listener _frameListener; |     static const wl_callback_listener _frameListener; | ||||||
| 
 | 
 | ||||||
|     wl_surface *_surface {nullptr}; |     wl_unique_ptr<wl_surface> _surface; | ||||||
|     zwlr_layer_surface_v1 *_layerSurface {nullptr}; |     wl_unique_ptr<zwlr_layer_surface_v1> _layerSurface; | ||||||
|     QPainter *_painter {nullptr}; |     QPainter *_painter {nullptr}; | ||||||
|     QFont _font; |  | ||||||
|     QFontMetrics _fontMetrics; |  | ||||||
|     std::optional<ShmBuffer> _bufs; |     std::optional<ShmBuffer> _bufs; | ||||||
|     int _textY, _x; |     int _textY, _x; | ||||||
|     bool _invalid {false}; |     bool _invalid {false}; | ||||||
| @ -45,7 +43,7 @@ class Bar { | |||||||
|     void invalidate(); |     void invalidate(); | ||||||
| public: | public: | ||||||
|     explicit Bar(const wl_output *output); |     explicit Bar(const wl_output *output); | ||||||
|  |     const wl_surface* surface() const; | ||||||
|     void setStatus(const QString &status); |     void setStatus(const QString &status); | ||||||
|     void click(int x, int y); |     void click(int x, int y); | ||||||
|     ~Bar(); |  | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ | |||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include <wayland-client.h> | #include <wayland-client.h> | ||||||
|  | #include <memory> | ||||||
| #include <vector> | #include <vector> | ||||||
| #include <QColor> | #include <QColor> | ||||||
| #include <QString> | #include <QString> | ||||||
| #include "wlr-layer-shell-unstable-v1-client-protocol.h" | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | ||||||
|  | #include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h" | ||||||
| 
 | 
 | ||||||
| extern wl_display *display; | extern wl_display *display; | ||||||
| extern wl_compositor *compositor; | extern wl_compositor *compositor; | ||||||
| @ -17,3 +19,17 @@ extern std::vector<QString> tagNames; | |||||||
| struct ColorScheme { | struct ColorScheme { | ||||||
|     QColor fg, bg; |     QColor fg, bg; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | // wayland smart pointers
 | ||||||
|  | template<typename T> | ||||||
|  | struct wl_deleter; | ||||||
|  | #define WL_DELETER(type, fn) template<> struct wl_deleter<type> { void operator()(type *v) { if(v) fn(v); } } | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | using wl_unique_ptr = std::unique_ptr<T, wl_deleter<T>>; | ||||||
|  | 
 | ||||||
|  | WL_DELETER(wl_surface, wl_surface_destroy); | ||||||
|  | WL_DELETER(zwlr_layer_surface_v1, zwlr_layer_surface_v1_destroy); | ||||||
|  | WL_DELETER(wl_buffer, wl_buffer_destroy); | ||||||
|  | WL_DELETER(wl_output, wl_output_release); | ||||||
|  | WL_DELETER(znet_tapesoftware_dwl_wm_monitor_v1, znet_tapesoftware_dwl_wm_monitor_v1_release); | ||||||
|  | |||||||
							
								
								
									
										114
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								src/main.cpp
									
									
									
									
									
								
							| @ -24,8 +24,8 @@ | |||||||
| 
 | 
 | ||||||
| struct Monitor { | struct Monitor { | ||||||
|     uint32_t name; |     uint32_t name; | ||||||
|     wl_output *wlOutput; |     wl_unique_ptr<wl_output> wlOutput; | ||||||
|     znet_tapesoftware_dwl_wm_monitor_v1 *dwlMonitor; |     wl_unique_ptr<znet_tapesoftware_dwl_wm_monitor_v1> dwlMonitor; | ||||||
|     std::optional<Bar> bar; |     std::optional<Bar> bar; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -42,8 +42,8 @@ wl_shm *shm; | |||||||
| zwlr_layer_shell_v1 *wlrLayerShell; | zwlr_layer_shell_v1 *wlrLayerShell; | ||||||
| znet_tapesoftware_dwl_wm_v1 *dwlWm; | znet_tapesoftware_dwl_wm_v1 *dwlWm; | ||||||
| std::vector<QString> tagNames; | std::vector<QString> tagNames; | ||||||
|  | static bool ready; | ||||||
| static std::vector<Monitor> monitors; | static std::vector<Monitor> monitors; | ||||||
| static std::optional<Bar> bar; |  | ||||||
| static std::string statusFifoName; | static std::string statusFifoName; | ||||||
| static int statusFifoFd {-1}; | static int statusFifoFd {-1}; | ||||||
| static int statusFifoWriter {-1}; | static int statusFifoWriter {-1}; | ||||||
| @ -57,7 +57,7 @@ static const struct xdg_wm_base_listener xdgWmBaseListener = { | |||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct PointerState { | struct SeatState { | ||||||
|     wl_pointer *pointer; |     wl_pointer *pointer; | ||||||
|     wl_surface *cursorSurface; |     wl_surface *cursorSurface; | ||||||
|     wl_cursor_image *cursorImage; |     wl_cursor_image *cursorImage; | ||||||
| @ -65,33 +65,40 @@ struct PointerState { | |||||||
|     int x, y; |     int x, y; | ||||||
|     bool leftButtonClick; |     bool leftButtonClick; | ||||||
| }; | }; | ||||||
| static PointerState pointerState; | static SeatState seatState; | ||||||
|  | static Bar* barFromSurface(const wl_surface *surface) | ||||||
|  | { | ||||||
|  |     auto fbar = std::find_if(begin(monitors), end(monitors), [surface](const Monitor &mon) { | ||||||
|  |         return mon.bar && mon.bar->surface() == surface; | ||||||
|  |     }); | ||||||
|  |     return fbar != end(monitors) && fbar->bar ? &*fbar->bar : nullptr; | ||||||
|  | } | ||||||
| static const struct wl_pointer_listener pointerListener = { | static const struct wl_pointer_listener pointerListener = { | ||||||
|     .enter = [](void*, wl_pointer *pointer, uint32_t serial, |     .enter = [](void*, wl_pointer *pointer, uint32_t serial, | ||||||
|                 wl_surface*, wl_fixed_t x, wl_fixed_t y) |                 wl_surface *surface, wl_fixed_t x, wl_fixed_t y) | ||||||
|     { |     { | ||||||
|         pointerState.focusedBar = &bar.value(); |         seatState.focusedBar = barFromSurface(surface); | ||||||
|         wl_pointer_set_cursor(pointer, serial, pointerState.cursorSurface, |         wl_pointer_set_cursor(pointer, serial, seatState.cursorSurface, | ||||||
|             pointerState.cursorImage->hotspot_x, pointerState.cursorImage->hotspot_y); |             seatState.cursorImage->hotspot_x, seatState.cursorImage->hotspot_y); | ||||||
|     }, |     }, | ||||||
|     .leave = [](void*, wl_pointer*, uint32_t serial, wl_surface*) { |     .leave = [](void*, wl_pointer*, uint32_t serial, wl_surface*) { | ||||||
|         pointerState.focusedBar = nullptr; |         seatState.focusedBar = nullptr; | ||||||
|     }, |     }, | ||||||
|     .motion = [](void*, wl_pointer*, uint32_t, wl_fixed_t x, wl_fixed_t y) { |     .motion = [](void*, wl_pointer*, uint32_t, wl_fixed_t x, wl_fixed_t y) { | ||||||
|         pointerState.x = wl_fixed_to_int(x); |         seatState.x = wl_fixed_to_int(x); | ||||||
|         pointerState.y = wl_fixed_to_int(y); |         seatState.y = wl_fixed_to_int(y); | ||||||
|     }, |     }, | ||||||
|     .button = [](void*, wl_pointer*, uint32_t, uint32_t, uint32_t button, uint32_t pressed) { |     .button = [](void*, wl_pointer*, uint32_t, uint32_t, uint32_t button, uint32_t pressed) { | ||||||
|         if (button == BTN_LEFT) { |         if (button == BTN_LEFT) { | ||||||
|             pointerState.leftButtonClick = pressed == WL_POINTER_BUTTON_STATE_PRESSED; |             seatState.leftButtonClick = pressed == WL_POINTER_BUTTON_STATE_PRESSED; | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|     .axis = [](void*, wl_pointer*, uint32_t, uint32_t, wl_fixed_t) { }, |     .axis = [](void*, wl_pointer*, uint32_t, uint32_t, wl_fixed_t) { }, | ||||||
|     .frame = [](void*, wl_pointer*) { |     .frame = [](void*, wl_pointer*) { | ||||||
|         if (!pointerState.focusedBar) return; |         if (!seatState.focusedBar) return; | ||||||
|         if (pointerState.leftButtonClick) { |         if (seatState.leftButtonClick) { | ||||||
|             pointerState.leftButtonClick = false; |             seatState.leftButtonClick = false; | ||||||
|             pointerState.focusedBar->click(pointerState.x, pointerState.y); |             seatState.focusedBar->click(seatState.x, seatState.y); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|     .axis_source = [](void*, wl_pointer*, uint32_t) { }, |     .axis_source = [](void*, wl_pointer*, uint32_t) { }, | ||||||
| @ -103,16 +110,16 @@ static wl_seat *seat; | |||||||
| static const struct wl_seat_listener seatListener = { | static const struct wl_seat_listener seatListener = { | ||||||
|     [](void*, wl_seat*, uint32_t cap) |     [](void*, wl_seat*, uint32_t cap) | ||||||
|     { |     { | ||||||
|         if (!pointerState.pointer && WL_SEAT_CAPABILITY_POINTER) { |         if (!seatState.pointer && WL_SEAT_CAPABILITY_POINTER) { | ||||||
|             auto cursorTheme = wl_cursor_theme_load(NULL, 24, shm); |             auto cursorTheme = wl_cursor_theme_load(NULL, 24, shm); | ||||||
|             auto cursorImage = wl_cursor_theme_get_cursor(cursorTheme, "left_ptr")->images[0]; |             auto cursorImage = wl_cursor_theme_get_cursor(cursorTheme, "left_ptr")->images[0]; | ||||||
|             pointerState.cursorImage = cursorImage; |             seatState.cursorImage = cursorImage; | ||||||
|             pointerState.cursorSurface = wl_compositor_create_surface(compositor); |             seatState.cursorSurface = wl_compositor_create_surface(compositor); | ||||||
|             wl_surface_attach(pointerState.cursorSurface, |             wl_surface_attach(seatState.cursorSurface, | ||||||
|                 wl_cursor_image_get_buffer(cursorImage), 0, 0); |                 wl_cursor_image_get_buffer(cursorImage), 0, 0); | ||||||
|             wl_surface_commit(pointerState.cursorSurface); |             wl_surface_commit(seatState.cursorSurface); | ||||||
|             pointerState.pointer = wl_seat_get_pointer(seat); |             seatState.pointer = wl_seat_get_pointer(seat); | ||||||
|             wl_pointer_add_listener(pointerState.pointer, &pointerListener, nullptr); |             wl_pointer_add_listener(seatState.pointer, &pointerListener, nullptr); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|     [](void*, wl_seat*, const char *name) { } |     [](void*, wl_seat*, const char *name) { } | ||||||
| @ -125,21 +132,26 @@ static const struct znet_tapesoftware_dwl_wm_v1_listener dwlWmListener = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorListener { | static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorListener { | ||||||
|     .tag = [](void*, znet_tapesoftware_dwl_wm_monitor_v1*, int tag, int active, int numClients) { |     .tag = [](void*, znet_tapesoftware_dwl_wm_monitor_v1*, int tag, int active, int numClients, int urgent) { | ||||||
|         printf("tag %s: active=%d, num_clients=%d\n", qPrintable(tagNames[tag]), active, numClients); |         printf("tag %s: active=%d, num_clients=%d, urgent=%d\n", qPrintable(tagNames[tag]), active, numClients, urgent); | ||||||
|  |     }, | ||||||
|  |     .frame = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*) { | ||||||
|  |         auto mon = static_cast<Monitor*>(mv); | ||||||
|  |         if (!mon->bar) { | ||||||
|  |             mon->bar.emplace(mon->wlOutput.get()); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static void setupOutput(Monitor &monitor) { | static void setupMonitor(Monitor &monitor) { | ||||||
|     monitor.dwlMonitor = znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, monitor.wlOutput); |     monitor.dwlMonitor.reset(znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, monitor.wlOutput.get())); | ||||||
|     znet_tapesoftware_dwl_wm_monitor_v1_add_listener(monitor.dwlMonitor, &dwlWmMonitorListener, &monitor); |     znet_tapesoftware_dwl_wm_monitor_v1_add_listener(monitor.dwlMonitor.get(), &dwlWmMonitorListener, &monitor); | ||||||
|     monitor.bar.emplace(monitor.wlOutput); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void onOutput(int name, wl_output *output) { | static void onOutput(uint32_t name, wl_output *output) { | ||||||
|     auto& monitor = monitors.emplace_back(name, output); |     auto& m = monitors.emplace_back(Monitor {name, wl_unique_ptr<wl_output> {output}}); | ||||||
|     if (dwlWm) { |     if (ready) { | ||||||
|         setupOutput(monitor); |         setupMonitor(m); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -153,10 +165,9 @@ static void onReady() | |||||||
|     requireGlobal(dwlWm, "znet_tapesoftware_dwl_wm_v1"); |     requireGlobal(dwlWm, "znet_tapesoftware_dwl_wm_v1"); | ||||||
|     setupStatusFifo(); |     setupStatusFifo(); | ||||||
|     wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc.
 |     wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc.
 | ||||||
|  |     ready = true; | ||||||
|     for (auto& monitor : monitors) { |     for (auto& monitor : monitors) { | ||||||
|         auto monitor = znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, output); |         setupMonitor(monitor); | ||||||
|         printf("created monitor %p for output %p\n", monitor, output); |  | ||||||
|         bar.emplace(output); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -198,8 +209,10 @@ static void onStatus() | |||||||
|     char buffer[512]; |     char buffer[512]; | ||||||
|     auto n = read(statusFifoFd, buffer, sizeof(buffer)); |     auto n = read(statusFifoFd, buffer, sizeof(buffer)); | ||||||
|     auto str = QString::fromUtf8(buffer, n); |     auto str = QString::fromUtf8(buffer, n); | ||||||
|     if (bar) { |     for (auto &monitor : monitors) { | ||||||
|         bar->setStatus(str); |         if (monitor.bar) { | ||||||
|  |             monitor.bar->setStatus(str); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -230,13 +243,23 @@ static void registryHandleGlobal(void*, wl_registry *registry, uint32_t name, co | |||||||
|         wl_seat_add_listener(seat, &seatListener, nullptr); |         wl_seat_add_listener(seat, &seatListener, nullptr); | ||||||
|     } |     } | ||||||
|     if (wl_output *output; reg.handle(output, wl_output_interface, 1)) { |     if (wl_output *output; reg.handle(output, wl_output_interface, 1)) { | ||||||
|         outputs.push_back(output); |         onOutput(name, output); | ||||||
|     } |     } | ||||||
|     if (reg.handle(dwlWm, znet_tapesoftware_dwl_wm_v1_interface, 1)) { |     if (reg.handle(dwlWm, znet_tapesoftware_dwl_wm_v1_interface, 1)) { | ||||||
|         znet_tapesoftware_dwl_wm_v1_add_listener(dwlWm, &dwlWmListener, nullptr); |         znet_tapesoftware_dwl_wm_v1_add_listener(dwlWm, &dwlWmListener, nullptr); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| static const struct wl_registry_listener registry_listener = { registryHandleGlobal, nullptr }; | static void registryHandleRemove(void*, wl_registry *registry, uint32_t name) | ||||||
|  | { | ||||||
|  |     auto it = std::find_if(begin(monitors), end(monitors), [name](const Monitor &m) { return m.name == name; }); | ||||||
|  |     if (it != end(monitors)) { | ||||||
|  |         monitors.erase(it); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | static const struct wl_registry_listener registry_listener = { | ||||||
|  |     .global = registryHandleGlobal, | ||||||
|  |     .global_remove = registryHandleRemove, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||||
| { | { | ||||||
| @ -273,7 +296,14 @@ int main(int argc, char **argv) | |||||||
| 
 | 
 | ||||||
|     QSocketNotifier displayReadNotifier(wl_display_get_fd(display), QSocketNotifier::Read); |     QSocketNotifier displayReadNotifier(wl_display_get_fd(display), QSocketNotifier::Read); | ||||||
|     displayReadNotifier.setEnabled(true); |     displayReadNotifier.setEnabled(true); | ||||||
|     QObject::connect(&displayReadNotifier, &QSocketNotifier::activated, [=]() { wl_display_dispatch(display); }); |     QObject::connect(&displayReadNotifier, &QSocketNotifier::activated, [=]() { | ||||||
|  |         auto res = wl_display_dispatch(display); | ||||||
|  |         if (res < 0) { | ||||||
|  |             perror("wl_display_dispatch"); | ||||||
|  |             cleanup(); | ||||||
|  |             exit(1); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|     displayWriteNotifier = new QSocketNotifier(wl_display_get_fd(display), QSocketNotifier::Write); |     displayWriteNotifier = new QSocketNotifier(wl_display_get_fd(display), QSocketNotifier::Write); | ||||||
|     displayWriteNotifier->setEnabled(false); |     displayWriteNotifier->setEnabled(false); | ||||||
|     QObject::connect(displayWriteNotifier, &QSocketNotifier::activated, waylandWriteReady); |     QObject::connect(displayWriteNotifier, &QSocketNotifier::activated, waylandWriteReady); | ||||||
|  | |||||||
| @ -22,20 +22,21 @@ ShmBuffer::ShmBuffer(int w, int h, wl_shm_format format) | |||||||
|     close(fd); |     close(fd); | ||||||
|     for (auto i=0; i<n; i++) { |     for (auto i=0; i<n; i++) { | ||||||
|         auto offset = oneSize*i; |         auto offset = oneSize*i; | ||||||
|         auto buffer = wl_shm_pool_create_buffer(pool, offset, width, height, stride, format); |         _buffers[i] = { | ||||||
|         _buffers[i] = { ptr+offset, buffer }; |             ptr+offset, | ||||||
|  |             wl_unique_ptr<wl_buffer> { wl_shm_pool_create_buffer(pool, offset, width, height, stride, format) }, | ||||||
|  |         }; | ||||||
|     } |     } | ||||||
|     wl_shm_pool_destroy(pool); |     wl_shm_pool_destroy(pool); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ShmBuffer::~ShmBuffer() | ShmBuffer::~ShmBuffer() | ||||||
| { | { | ||||||
|  |     if (_buffers[0].data) { | ||||||
|         munmap(_buffers[0].data, _totalSize); |         munmap(_buffers[0].data, _totalSize); | ||||||
|     for (auto i=0; i<n; i++) { |  | ||||||
|         wl_buffer_destroy(_buffers[i].buffer); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint8_t* ShmBuffer::data() const { return _buffers[_current].data; } | uint8_t* ShmBuffer::data() const { return _buffers[_current].data; } | ||||||
| wl_buffer* ShmBuffer::buffer() const { return _buffers[_current].buffer; } | wl_buffer* ShmBuffer::buffer() const { return _buffers[_current].buffer.get(); } | ||||||
| void ShmBuffer::flip() { _current = 1-_current; } | void ShmBuffer::flip() { _current = 1-_current; } | ||||||
|  | |||||||
| @ -4,22 +4,29 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include <array> | #include <array> | ||||||
| #include <wayland-client.h> | #include <wayland-client.h> | ||||||
|  | #include "common.hpp" | ||||||
| 
 | 
 | ||||||
| // double buffered shm
 | // double buffered shm
 | ||||||
| // format is must be 32-bit
 | // format is must be 32-bit
 | ||||||
| class ShmBuffer { | class ShmBuffer { | ||||||
|     struct Buf { |     struct Buf { | ||||||
|         uint8_t *data {nullptr}; |         uint8_t *data {nullptr}; | ||||||
|         wl_buffer *buffer {nullptr}; |         wl_unique_ptr<wl_buffer> buffer; | ||||||
|     }; |     }; | ||||||
|     std::array<Buf, 2> _buffers; |     std::array<Buf, 2> _buffers; | ||||||
|     int _current {0}; |     int _current {0}; | ||||||
|     size_t _totalSize {0}; |     size_t _totalSize {0}; | ||||||
| public: | public: | ||||||
|     int width, height, stride; |     int width, height, stride; | ||||||
|  | 
 | ||||||
|     explicit ShmBuffer(int width, int height, wl_shm_format format); |     explicit ShmBuffer(int width, int height, wl_shm_format format); | ||||||
|  |     ShmBuffer(const ShmBuffer&) = delete; | ||||||
|  |     ShmBuffer(ShmBuffer&&) = default; | ||||||
|  |     ShmBuffer& operator=(const ShmBuffer&) = delete; | ||||||
|  |     ShmBuffer& operator=(ShmBuffer&&) = default; | ||||||
|  |     ~ShmBuffer(); | ||||||
|  | 
 | ||||||
|     uint8_t* data() const; |     uint8_t* data() const; | ||||||
|     wl_buffer* buffer() const; |     wl_buffer* buffer() const; | ||||||
|     void flip(); |     void flip(); | ||||||
|     ~ShmBuffer(); |  | ||||||
| }; | }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user