diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index e29d7a608..b234cecdd 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -1777,8 +1777,9 @@ unset_fullscreen(struct shell_surface *shsurf) shsurf->orientation); if (shsurf->saved_rotation_valid) { - wl_list_insert(&shsurf->view->geometry.transformation_list, - &shsurf->rotation.transform.link); + weston_view_add_transform(shsurf->view, + &shsurf->view->geometry.transformation_list, + &shsurf->rotation.transform); shsurf->saved_rotation_valid = false; } } @@ -1803,8 +1804,9 @@ unset_maximized(struct shell_surface *shsurf) shsurf->orientation); if (shsurf->saved_rotation_valid) { - wl_list_insert(&shsurf->view->geometry.transformation_list, - &shsurf->rotation.transform.link); + weston_view_add_transform(shsurf->view, + &shsurf->view->geometry.transformation_list, + &shsurf->rotation.transform); shsurf->saved_rotation_valid = false; } } @@ -3491,8 +3493,6 @@ rotate_grab_motion(struct weston_pointer_grab *grab, dy = pointer->pos.c.y - rotate->center.y; r = sqrtf(dx * dx + dy * dy); - wl_list_remove(&shsurf->rotation.transform.link); - if (r > 20.0f) { struct weston_matrix *matrix = &shsurf->rotation.transform.matrix; @@ -3506,17 +3506,16 @@ rotate_grab_motion(struct weston_pointer_grab *grab, weston_matrix_multiply(matrix, &rotate->rotation); weston_matrix_translate(matrix, cx, cy, 0.0f); - wl_list_insert( - &shsurf->view->geometry.transformation_list, - &shsurf->rotation.transform.link); + weston_view_add_transform(shsurf->view, + &shsurf->view->geometry.transformation_list, + &shsurf->rotation.transform); } else { - wl_list_init(&shsurf->rotation.transform.link); + weston_view_remove_transform(shsurf->view, + &shsurf->rotation.transform); weston_matrix_init(&shsurf->rotation.rotation); weston_matrix_init(&rotate->rotation); } - weston_view_geometry_dirty(shsurf->view); - /* We need to adjust the position of the surface * in case it was resized in a rotated state before */ cposx = shsurf->view->geometry.pos_offset.x + cx; diff --git a/fullscreen-shell/fullscreen-shell.c b/fullscreen-shell/fullscreen-shell.c index bc5724e89..3938ee5a9 100644 --- a/fullscreen-shell/fullscreen-shell.c +++ b/fullscreen-shell/fullscreen-shell.c @@ -378,15 +378,16 @@ fs_output_scale_view(struct fs_output *fsout, float width, float height) pos.c.x -= surf_x; pos.c.y -= surf_y; weston_view_set_position(view, pos); + weston_view_remove_transform(fsout->view, &fsout->transform); } else { matrix = &fsout->transform.matrix; weston_matrix_init(matrix); weston_matrix_scale(matrix, width / surf_width, height / surf_height, 1); - wl_list_remove(&fsout->transform.link); - wl_list_insert(&fsout->view->geometry.transformation_list, - &fsout->transform.link); + weston_view_add_transform(fsout->view, + &fsout->view->geometry.transformation_list, + &fsout->transform); pos.c.x += (output->width - width) / 2 - surf_x; pos.c.y += (output->height - height) / 2 - surf_y; diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index 2e6b8f799..2985a99f9 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -2013,6 +2013,15 @@ weston_view_update_transform(struct weston_view *view); void weston_view_geometry_dirty(struct weston_view *view); +void +weston_view_add_transform(struct weston_view *view, + struct wl_list *pos, + struct weston_transform *transform); + +void +weston_view_remove_transform(struct weston_view *view, + struct weston_transform *transform); + struct weston_coord_global __attribute__ ((warn_unused_result)) weston_coord_surface_to_global(const struct weston_view *view, struct weston_coord_surface coord); diff --git a/libweston/animation.c b/libweston/animation.c index 2d6e471c0..c77c7ff49 100644 --- a/libweston/animation.c +++ b/libweston/animation.c @@ -145,10 +145,9 @@ weston_view_animation_destroy(struct weston_view_animation *animation) { wl_list_remove(&animation->animation.link); wl_list_remove(&animation->listener.link); - wl_list_remove(&animation->transform.link); + weston_view_remove_transform(animation->view, &animation->transform); if (animation->reset) animation->reset(animation); - weston_view_geometry_dirty(animation->view); if (animation->done) animation->done(animation, animation->data); free(animation); @@ -189,8 +188,10 @@ weston_view_animation_frame(struct weston_animation *base, if (animation->frame) animation->frame(animation); - weston_view_geometry_dirty(animation->view); - weston_view_schedule_repaint(animation->view); + weston_view_add_transform(animation->view, + &animation->view->geometry.transformation_list, + &animation->transform); + weston_view_update_transform(animation->view); /* The view's output_mask will be zero if its position is * offscreen. Animations should always run but as they are also @@ -237,8 +238,7 @@ weston_view_animation_create(struct weston_view *view, animation->private = private; weston_matrix_init(&animation->transform.matrix); - wl_list_insert(&view->geometry.transformation_list, - &animation->transform.link); + wl_list_init(&animation->transform.link); animation->animation.frame = weston_view_animation_frame; diff --git a/libweston/compositor.c b/libweston/compositor.c index 98b169837..38cfa98d1 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -1623,6 +1623,44 @@ weston_view_geometry_dirty(struct weston_view *view) view->surface->compositor->view_list_needs_rebuild = true; } +WL_EXPORT void +weston_view_add_transform(struct weston_view *view, + struct wl_list *pos, + struct weston_transform *transform) +{ + if (weston_view_is_mapped(view)) + weston_view_damage_below(view); + + wl_list_remove(&transform->link); + wl_list_insert(pos, &transform->link); + + weston_view_geometry_dirty_internal(view); + weston_view_update_transform(view); + + if (weston_view_is_mapped(view)) + weston_surface_damage(view->surface); +} + +WL_EXPORT void +weston_view_remove_transform(struct weston_view *view, + struct weston_transform *transform) +{ + if (wl_list_empty(&transform->link)) + return; + + if (weston_view_is_mapped(view)) + weston_view_damage_below(view); + + wl_list_remove(&transform->link); + wl_list_init(&transform->link); + + weston_view_geometry_dirty_internal(view); + weston_view_update_transform(view); + + if (weston_view_is_mapped(view)) + weston_surface_damage(view->surface); +} + /** * \param surface The surface to be repainted *