15
15
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
16
16
#include "viewporter-client-protocol.h"
17
17
#include "single-pixel-buffer-v1-client-protocol.h"
18
+ #include "surface-invalidation-v1-client-protocol.h"
18
19
19
20
static uint32_t parse_color (const char * color ) {
20
21
if (color [0 ] == '#' ) {
@@ -41,6 +42,7 @@ struct swaybg_state {
41
42
struct zwlr_layer_shell_v1 * layer_shell ;
42
43
struct wp_viewporter * viewporter ;
43
44
struct wp_single_pixel_buffer_manager_v1 * single_pixel_buffer_manager ;
45
+ struct wp_surface_invalidation_manager_v1 * surface_invalidation_manager ;
44
46
struct wl_list configs ; // struct swaybg_output_config::link
45
47
struct wl_list outputs ; // struct swaybg_output::link
46
48
struct wl_list images ; // struct swaybg_image::link
@@ -81,6 +83,12 @@ struct swaybg_output {
81
83
bool dirty , needs_ack ;
82
84
int32_t committed_width , committed_height , committed_scale ;
83
85
86
+ struct {
87
+ struct wp_surface_invalidation_v1 * object ;
88
+ bool needs_ack ;
89
+ uint32_t serial ;
90
+ } surface_invalidation ;
91
+
84
92
struct wl_list link ;
85
93
};
86
94
@@ -255,10 +263,32 @@ static void output_mode(void *data, struct wl_output *output, uint32_t flags,
255
263
// Who cares
256
264
}
257
265
266
+ static void surface_invalidation_handle_invalidated (void * data ,
267
+ struct wp_surface_invalidation_v1 * wp_surface_invalidation_v1 , uint32_t serial ) {
268
+ struct swaybg_output * output = data ;
269
+ assert (output -> surface_invalidation .object == wp_surface_invalidation_v1 );
270
+
271
+ output -> dirty = true;
272
+ output -> surface_invalidation .needs_ack = true;
273
+ output -> surface_invalidation .serial = serial ;
274
+ }
275
+
276
+ static struct wp_surface_invalidation_v1_listener surface_invalidation_listener = {
277
+ .invalidated = surface_invalidation_handle_invalidated ,
278
+ };
279
+
258
280
static void create_layer_surface (struct swaybg_output * output ) {
259
281
output -> surface = wl_compositor_create_surface (output -> state -> compositor );
260
282
assert (output -> surface );
261
283
284
+ if (output -> state -> surface_invalidation_manager ) {
285
+ output -> surface_invalidation .object =
286
+ wp_surface_invalidation_manager_v1_get_surface_invalidation (
287
+ output -> state -> surface_invalidation_manager , output -> surface );
288
+ wp_surface_invalidation_v1_add_listener (output -> surface_invalidation .object ,
289
+ & surface_invalidation_listener , output );
290
+ }
291
+
262
292
// Empty input region
263
293
struct wl_region * input_region =
264
294
wl_compositor_create_region (output -> state -> compositor );
@@ -385,6 +415,10 @@ static void handle_global(void *data, struct wl_registry *registry,
385
415
wp_single_pixel_buffer_manager_v1_interface .name ) == 0 ) {
386
416
state -> single_pixel_buffer_manager = wl_registry_bind (registry , name ,
387
417
& wp_single_pixel_buffer_manager_v1_interface , 1 );
418
+ } else if (strcmp (interface ,
419
+ wp_surface_invalidation_manager_v1_interface .name ) == 0 ) {
420
+ state -> surface_invalidation_manager = wl_registry_bind (registry , name ,
421
+ & wp_surface_invalidation_manager_v1_interface , 1 );
388
422
}
389
423
}
390
424
@@ -600,6 +634,15 @@ int main(int argc, char **argv) {
600
634
output -> configure_serial );
601
635
}
602
636
637
+ if (output -> surface_invalidation .needs_ack ) {
638
+ output -> surface_invalidation .needs_ack = false;
639
+ wp_surface_invalidation_v1_ack (output -> surface_invalidation .object ,
640
+ output -> surface_invalidation .serial );
641
+ output -> committed_width = 0 ;
642
+ output -> committed_height = 0 ;
643
+ output -> committed_scale = 0 ;
644
+ }
645
+
603
646
int buffer_width = output -> width * output -> scale ,
604
647
buffer_height = output -> height * output -> scale ;
605
648
bool buffer_change =
0 commit comments