aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Orzechowski <orzechowski.alexander@gmail.com>2022-05-19 14:01:03 -0400
committerAlexander Orzechowski <orzechowski.alexander@gmail.com>2022-05-19 14:17:51 -0400
commit933ff0e60c423721403b55295bd3d309b010bd8c (patch)
treee1fc5e5549ca32fee34343e64d286faec0117724
parentc46b53d0b04e52b73cfe041e4bc87656b1d1ce94 (diff)
wlr_scene: Fix missing calls to scene_node_update_outputs
There were a couple places this was missing - on mode change of an output. If the resolution changes for example nodes may fall out of the view. - on commits on an output for scale or transform changes - when the transform of a buffer is changed. If the dest size is not set, the buffer may have been rotated potentially changing its size if the buffer width != height
-rw-r--r--include/wlr/types/wlr_scene.h3
-rw-r--r--types/scene/wlr_scene.c29
2 files changed, 32 insertions, 0 deletions
diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h
index a02a5c89..b48aeff8 100644
--- a/include/wlr/types/wlr_scene.h
+++ b/include/wlr/types/wlr_scene.h
@@ -140,6 +140,9 @@ struct wlr_scene_output {
uint8_t index;
bool prev_scanout;
+
+ struct wl_listener output_commit;
+ struct wl_listener output_mode;
};
/** A layer shell scene helper */
diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c
index 5eb8165d..52d8d00b 100644
--- a/types/scene/wlr_scene.c
+++ b/types/scene/wlr_scene.c
@@ -470,6 +470,8 @@ void wlr_scene_buffer_set_transform(struct wlr_scene_buffer *scene_buffer,
scene_node_damage_whole(&scene_buffer->node);
scene_buffer->transform = transform;
scene_node_damage_whole(&scene_buffer->node);
+
+ scene_node_update_outputs(&scene_buffer->node);
}
static struct wlr_texture *scene_buffer_get_texture(
@@ -996,6 +998,24 @@ static const struct wlr_addon_interface output_addon_impl = {
.destroy = scene_output_handle_destroy,
};
+static void scene_output_handle_commit(struct wl_listener *listener, void *data) {
+ struct wlr_scene_output *scene_output = wl_container_of(listener,
+ scene_output, output_commit);
+ struct wlr_output_event_commit *event = data;
+
+ if (event->committed & (WLR_OUTPUT_STATE_MODE |
+ WLR_OUTPUT_STATE_TRANSFORM |
+ WLR_OUTPUT_STATE_SCALE)) {
+ scene_node_update_outputs(&scene_output->scene->node);
+ }
+}
+
+static void scene_output_handle_mode(struct wl_listener *listener, void *data) {
+ struct wlr_scene_output *scene_output = wl_container_of(listener,
+ scene_output, output_mode);
+ scene_node_update_outputs(&scene_output->scene->node);
+}
+
struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
struct wlr_output *output) {
struct wlr_scene_output *scene_output = calloc(1, sizeof(*scene_output));
@@ -1030,7 +1050,14 @@ struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
assert(scene_output->index < 64);
wl_list_insert(prev_output_link, &scene_output->link);
+ scene_output->output_commit.notify = scene_output_handle_commit;
+ wl_signal_add(&output->events.commit, &scene_output->output_commit);
+
+ scene_output->output_mode.notify = scene_output_handle_mode;
+ wl_signal_add(&output->events.mode, &scene_output->output_mode);
+
wlr_output_damage_add_whole(scene_output->damage);
+ scene_node_update_outputs(&scene->node);
return scene_output;
}
@@ -1062,6 +1089,8 @@ void wlr_scene_output_destroy(struct wlr_scene_output *scene_output) {
wlr_addon_finish(&scene_output->addon);
wl_list_remove(&scene_output->link);
+ wl_list_remove(&scene_output->output_commit.link);
+ wl_list_remove(&scene_output->output_mode.link);
free(scene_output);
}