diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h index c415260c0..604dee81b 100644 --- a/src/compositor/meta-shaped-texture-private.h +++ b/src/compositor/meta-shaped-texture-private.h @@ -69,4 +69,6 @@ int meta_shaped_texture_get_height (MetaShapedTexture *stex); void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, cairo_region_t *clip_region); +void meta_shaped_texture_ensure_size_valid (MetaShapedTexture *stex); + #endif diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index ec1faf9fc..51b15b1fb 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -210,8 +210,8 @@ update_size (MetaShapedTexture *stex) } } -static void -ensure_size_valid (MetaShapedTexture *stex) +void +meta_shaped_texture_ensure_size_valid (MetaShapedTexture *stex) { if (stex->size_invalid) update_size (stex); @@ -545,7 +545,7 @@ do_paint_content (MetaShapedTexture *stex, CoglFramebuffer *framebuffer; int sample_width, sample_height; - ensure_size_valid (stex); + meta_shaped_texture_ensure_size_valid (stex); dst_width = stex->dst_width; dst_height = stex->dst_height; @@ -822,7 +822,7 @@ meta_shaped_texture_get_preferred_size (ClutterContent *content, { MetaShapedTexture *stex = META_SHAPED_TEXTURE (content); - ensure_size_valid (stex); + meta_shaped_texture_ensure_size_valid (stex); if (width) *width = stex->dst_width; @@ -897,6 +897,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, cairo_rectangle_int_t *clip) { MetaMonitorTransform inverted_transform; + int scaled_and_transformed_width; + int scaled_and_transformed_height; if (stex->texture == NULL) return FALSE; @@ -913,12 +915,22 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, META_ROUNDING_STRATEGY_SHRINK, clip); + if (meta_monitor_transform_is_rotated (stex->transform)) + { + scaled_and_transformed_width = stex->tex_height / stex->buffer_scale; + scaled_and_transformed_height = stex->tex_width / stex->buffer_scale; + } + else + { + scaled_and_transformed_width = stex->tex_width / stex->buffer_scale; + scaled_and_transformed_height = stex->tex_height / stex->buffer_scale; + } + inverted_transform = meta_monitor_transform_invert (stex->transform); - ensure_size_valid (stex); meta_rectangle_transform (clip, inverted_transform, - stex->dst_width, - stex->dst_height, + scaled_and_transformed_width, + scaled_and_transformed_height, clip); if (stex->has_viewport_src_rect || stex->has_viewport_dst_size) @@ -939,8 +951,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, viewport = (graphene_rect_t) { .origin.x = 0, .origin.y = 0, - .size.width = stex->tex_width, - .size.height = stex->tex_height, + .size.width = scaled_and_transformed_width, + .size.height = scaled_and_transformed_height, }; } @@ -951,8 +963,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, } else { - dst_width = (float) stex->tex_width; - dst_height = (float) stex->tex_height; + dst_width = (float) viewport.size.width; + dst_height = (float) viewport.size.height; } inverted_viewport = (graphene_rect_t) { @@ -1133,7 +1145,7 @@ meta_shaped_texture_is_opaque (MetaShapedTexture *stex) cairo_region_get_extents (stex->opaque_region, &opaque_rect); - ensure_size_valid (stex); + meta_shaped_texture_ensure_size_valid (stex); return meta_rectangle_equal (&opaque_rect, &(MetaRectangle) { @@ -1160,10 +1172,14 @@ meta_shaped_texture_set_viewport_src_rect (MetaShapedTexture *stex, graphene_rect_t *src_rect) { if (!stex->has_viewport_src_rect || - stex->viewport_src_rect.origin.x != src_rect->origin.x || - stex->viewport_src_rect.origin.y != src_rect->origin.y || - stex->viewport_src_rect.size.width != src_rect->size.width || - stex->viewport_src_rect.size.height != src_rect->size.height) + !G_APPROX_VALUE (stex->viewport_src_rect.origin.x, + src_rect->origin.x, FLT_EPSILON) || + !G_APPROX_VALUE (stex->viewport_src_rect.origin.y, + src_rect->origin.y, FLT_EPSILON) || + !G_APPROX_VALUE (stex->viewport_src_rect.size.width, + src_rect->size.width, FLT_EPSILON) || + !G_APPROX_VALUE (stex->viewport_src_rect.size.height, + src_rect->size.height, FLT_EPSILON)) { stex->has_viewport_src_rect = TRUE; stex->viewport_src_rect = *src_rect; @@ -1360,7 +1376,7 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex, if (texture == NULL) return NULL; - ensure_size_valid (stex); + meta_shaped_texture_ensure_size_valid (stex); if (stex->dst_width == 0 || stex->dst_height == 0) return NULL; @@ -1503,7 +1519,7 @@ meta_shaped_texture_get_width (MetaShapedTexture *stex) { g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 0); - ensure_size_valid (stex); + meta_shaped_texture_ensure_size_valid (stex); return stex->dst_width; } @@ -1513,7 +1529,7 @@ meta_shaped_texture_get_height (MetaShapedTexture *stex) { g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 0); - ensure_size_valid (stex); + meta_shaped_texture_ensure_size_valid (stex); return stex->dst_height; } diff --git a/src/compositor/meta-window-actor-wayland.c b/src/compositor/meta-window-actor-wayland.c index 98f26fc6c..8ebffbe8c 100644 --- a/src/compositor/meta-window-actor-wayland.c +++ b/src/compositor/meta-window-actor-wayland.c @@ -32,37 +32,37 @@ struct _MetaWindowActorWayland G_DEFINE_TYPE (MetaWindowActorWayland, meta_window_actor_wayland, META_TYPE_WINDOW_ACTOR) -static gboolean -remove_surface_actor_from_children (GNode *node, - gpointer data) +typedef struct _SurfaceTreeTraverseData { - MetaWaylandSurface *surface = node->data; - MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); - MetaWindowActor *window_actor = data; - ClutterActor *parent; - - parent = clutter_actor_get_parent (CLUTTER_ACTOR (surface_actor)); - if (!parent) - return FALSE; - - g_return_val_if_fail (parent == CLUTTER_ACTOR (window_actor), FALSE); - - clutter_actor_remove_child (CLUTTER_ACTOR (window_actor), - CLUTTER_ACTOR (surface_actor)); - - return FALSE; -} + MetaWindowActor *window_actor; + int index; +} SurfaceTreeTraverseData; static gboolean -add_surface_actor_to_children (GNode *node, - gpointer data) +set_surface_actor_index (GNode *node, + gpointer data) { MetaWaylandSurface *surface = node->data; MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); - MetaWindowActor *window_actor = data; - clutter_actor_add_child (CLUTTER_ACTOR (window_actor), - CLUTTER_ACTOR (surface_actor)); + SurfaceTreeTraverseData *traverse_data = data; + + if (clutter_actor_contains (CLUTTER_ACTOR (traverse_data->window_actor), + CLUTTER_ACTOR (surface_actor))) + { + clutter_actor_set_child_at_index ( + CLUTTER_ACTOR (traverse_data->window_actor), + CLUTTER_ACTOR (surface_actor), + traverse_data->index); + } + else + { + clutter_actor_insert_child_at_index ( + CLUTTER_ACTOR (traverse_data->window_actor), + CLUTTER_ACTOR (surface_actor), + traverse_data->index); + } + traverse_data->index++; return FALSE; } @@ -75,20 +75,19 @@ meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor) MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface ( META_SURFACE_ACTOR_WAYLAND (surface_actor)); GNode *root_node = surface->subsurface_branch_node; + SurfaceTreeTraverseData traverse_data; - g_node_traverse (root_node, - G_IN_ORDER, - G_TRAVERSE_LEAVES, - -1, - remove_surface_actor_from_children, - actor); + traverse_data = (SurfaceTreeTraverseData) { + .window_actor = actor, + .index = 0, + }; g_node_traverse (root_node, G_IN_ORDER, G_TRAVERSE_LEAVES, -1, - add_surface_actor_to_children, - actor); + set_surface_actor_index, + &traverse_data); } static void diff --git a/src/compositor/region-utils.c b/src/compositor/region-utils.c index 7b396cce2..95dd4f599 100644 --- a/src/compositor/region-utils.c +++ b/src/compositor/region-utils.c @@ -428,8 +428,8 @@ meta_region_crop_and_scale (cairo_region_t *region, { viewport_region = cairo_region_copy (region); - if (G_APPROX_VALUE (src_rect->origin.x, 0, FLT_EPSILON) || - G_APPROX_VALUE (src_rect->origin.y, 0, FLT_EPSILON)) + if (!G_APPROX_VALUE (src_rect->origin.x, 0, FLT_EPSILON) || + !G_APPROX_VALUE (src_rect->origin.y, 0, FLT_EPSILON)) { cairo_region_translate (viewport_region, (int) src_rect->origin.x, diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c index f4b958673..0ce5bbb6c 100644 --- a/src/wayland/meta-wayland-actor-surface.c +++ b/src/wayland/meta-wayland-actor-surface.c @@ -268,6 +268,8 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor meta_surface_actor_reset_viewport_dst_size (surface_actor); } + meta_shaped_texture_ensure_size_valid (stex); + META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface) { MetaWaylandActorSurface *actor_surface; diff --git a/src/wayland/meta-wayland-subsurface.c b/src/wayland/meta-wayland-subsurface.c index 24d5c0a53..d553e72f7 100644 --- a/src/wayland/meta-wayland-subsurface.c +++ b/src/wayland/meta-wayland-subsurface.c @@ -344,11 +344,11 @@ is_valid_sibling (MetaWaylandSurface *surface, } static void -subsurface_handle_pending_surface_destroyed (struct wl_listener *listener, - void *data) +subsurface_handle_pending_subsurface_destroyed (struct wl_listener *listener, + void *data) { MetaWaylandSubsurfacePlacementOp *op = - wl_container_of (listener, op, surface_destroy_listener); + wl_container_of (listener, op, subsurface_destroy_listener); op->surface = NULL; } @@ -367,7 +367,7 @@ void meta_wayland_subsurface_placement_op_free (MetaWaylandSubsurfacePlacementOp *op) { if (op->surface) - wl_list_remove (&op->surface_destroy_listener.link); + wl_list_remove (&op->subsurface_destroy_listener.link); if (op->sibling) wl_list_remove (&op->sibling_destroy_listener.link); g_free (op); @@ -385,12 +385,12 @@ queue_subsurface_placement (MetaWaylandSurface *surface, op->placement = placement; op->surface = surface; op->sibling = sibling; - op->surface_destroy_listener.notify = - subsurface_handle_pending_surface_destroyed; + op->subsurface_destroy_listener.notify = + subsurface_handle_pending_subsurface_destroyed; op->sibling_destroy_listener.notify = subsurface_handle_pending_sibling_destroyed; - wl_resource_add_destroy_listener (surface->resource, - &op->surface_destroy_listener); + wl_resource_add_destroy_listener (surface->wl_subsurface, + &op->subsurface_destroy_listener); wl_resource_add_destroy_listener (sibling->resource, &op->sibling_destroy_listener); diff --git a/src/wayland/meta-wayland-subsurface.h b/src/wayland/meta-wayland-subsurface.h index 7ea6bc5ae..45dbf8626 100644 --- a/src/wayland/meta-wayland-subsurface.h +++ b/src/wayland/meta-wayland-subsurface.h @@ -40,7 +40,7 @@ typedef struct MetaWaylandSubsurfacePlacement placement; MetaWaylandSurface *surface; MetaWaylandSurface *sibling; - struct wl_listener surface_destroy_listener; + struct wl_listener subsurface_destroy_listener; struct wl_listener sibling_destroy_listener; } MetaWaylandSubsurfacePlacementOp;