diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index 04c64a72..07f19b67 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -19,12 +19,6 @@ struct wlr_frame_callback { #define WLR_SURFACE_INVALID_TRANSFORM 32 #define WLR_SURFACE_INVALID_SCALE 64 -struct wlr_subsurface { - struct wl_resource *resource; - struct wlr_surface *surface; - struct wlr_surface *parent; -}; - struct wlr_surface_state { uint32_t invalid; struct wl_resource *buffer; @@ -37,6 +31,25 @@ struct wlr_surface_state { int buffer_width, buffer_height; }; +struct wlr_subsurface { + struct wl_resource *resource; + struct wlr_surface *surface; + struct wlr_surface *parent; + + struct wlr_surface_state cached; + + struct { + int32_t x, y; + } position; + + struct { + int32_t x, y; + bool set; + } pending_position; + + bool synchronized; +}; + struct wlr_surface { struct wl_resource *resource; struct wlr_renderer *renderer; diff --git a/types/wlr_surface.c b/types/wlr_surface.c index d5e0e6a2..3ac6c08e 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -450,6 +450,22 @@ void wlr_subsurface_destroy(struct wlr_subsurface *subsurface) { wlr_log(L_DEBUG, "TODO: wlr subsurface destroy"); } +static bool wlr_subsurface_is_synchronized(struct wlr_subsurface *subsurface) { + while (subsurface) { + if (subsurface->synchronized) { + return true; + } + + if (!subsurface->parent) { + return false; + } + + subsurface = subsurface->parent->subsurface; + } + + return false; +} + static void subsurface_resource_destroy(struct wl_resource *resource) { struct wlr_subsurface *subsurface = wl_resource_get_user_data(resource); @@ -465,7 +481,10 @@ static void subsurface_destroy(struct wl_client *client, static void subsurface_set_position(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y) { - wlr_log(L_DEBUG, "TODO: subsurface set position"); + struct wlr_subsurface *subsurface = wl_resource_get_user_data(resource); + subsurface->pending_position.set = true; + subsurface->pending_position.x = x; + subsurface->pending_position.y = y; } static void subsurface_place_above(struct wl_client *client, @@ -480,12 +499,24 @@ static void subsurface_place_below(struct wl_client *client, static void subsurface_set_sync(struct wl_client *client, struct wl_resource *resource) { - wlr_log(L_DEBUG, "TODO: subsurface set sync"); + struct wlr_subsurface *subsurface = wl_resource_get_user_data(resource); + + if (subsurface) { + subsurface->synchronized = true; + } } static void subsurface_set_desync(struct wl_client *client, struct wl_resource *resource) { - wlr_log(L_DEBUG, "TODO: subsurface set desync"); + struct wlr_subsurface *subsurface = wl_resource_get_user_data(resource); + + if (subsurface && subsurface->synchronized) { + subsurface->synchronized = false; + + if (!wlr_subsurface_is_synchronized(subsurface)) { + // TODO: do a synchronized commit to flush the cache + } + } } static const struct wl_subsurface_interface subsurface_implementation = {