diff --git a/include/mako.h b/include/mako.h index b1e0525f..0b0df516 100644 --- a/include/mako.h +++ b/include/mako.h @@ -18,6 +18,7 @@ #include "wlr-layer-shell-unstable-v1-client-protocol.h" #include "xdg-output-unstable-v1-client-protocol.h" #include "xdg-activation-v1-client-protocol.h" +#include "surface-invalidation-v1-client-protocol.h" struct mako_state; @@ -58,6 +59,7 @@ struct mako_state { struct zwlr_layer_shell_v1 *layer_shell; struct zxdg_output_manager_v1 *xdg_output_manager; struct xdg_activation_v1 *xdg_activation; + struct wp_surface_invalidation_manager_v1 *surface_invalidation_manager; struct wl_list outputs; // mako_output::link struct wl_list seats; // mako_seat::link diff --git a/protocol/meson.build b/protocol/meson.build index ebb6381c..51e8e93f 100644 --- a/protocol/meson.build +++ b/protocol/meson.build @@ -24,6 +24,7 @@ wayland_scanner_client = generator( client_protocols = [ wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', wl_protocol_dir / 'staging/xdg-activation/xdg-activation-v1.xml', + wl_protocol_dir / 'staging/surface-invalidation/surface-invalidation-v1.xml', wl_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml', 'wlr-layer-shell-unstable-v1.xml', ] diff --git a/wayland.c b/wayland.c index f4290353..18b57802 100644 --- a/wayland.c +++ b/wayland.c @@ -427,7 +427,6 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { .closed = layer_surface_handle_closed, }; - static void handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { struct mako_state *state = data; @@ -457,6 +456,9 @@ static void handle_global(void *data, struct wl_registry *registry, } else if (strcmp(interface, xdg_activation_v1_interface.name) == 0) { state->xdg_activation = wl_registry_bind(registry, name, &xdg_activation_v1_interface, 1); + } else if (strcmp(interface, wp_surface_invalidation_manager_v1_interface.name)) { + state->surface_invalidation_manager = wl_registry_bind(registry, name, + &wp_surface_invalidation_manager_v1_interface, 1); } } @@ -613,8 +615,21 @@ static struct mako_output *get_configured_output(struct mako_surface *surface) { return NULL; } +static void send_frame(struct mako_surface *surface); static void schedule_frame_and_commit(struct mako_surface *surface); +static void surface_invalidation_handle_invalidated(void *data, + struct wp_surface_invalidation_v1 *wp_surface_invalidation_v1, uint32_t serial) { + struct mako_surface *surface = data; + + wp_surface_invalidation_v1_ack(wp_surface_invalidation_v1, serial); + send_frame(surface); +} + +static struct wp_surface_invalidation_v1_listener surface_invalidation_listener = { + .invalidated = surface_invalidation_handle_invalidated, +}; + // Draw and commit a new frame. static void send_frame(struct mako_surface *surface) { struct mako_state *state = surface->state; @@ -676,6 +691,14 @@ static void send_frame(struct mako_surface *surface) { surface->surface = wl_compositor_create_surface(state->compositor); wl_surface_add_listener(surface->surface, &surface_listener, surface); + if (state->surface_invalidation_manager) { + struct wp_surface_invalidation_v1 *surface_invalidation = + wp_surface_invalidation_manager_v1_get_surface_invalidation( + state->surface_invalidation_manager, surface->surface); + wp_surface_invalidation_v1_add_listener(surface_invalidation, + &surface_invalidation_listener, surface); + } + surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface( state->layer_shell, surface->surface, wl_output, surface->layer, "notifications");