aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Orzechowski <orzechowski.alexander@gmail.com>2022-06-02 10:33:04 -0400
committerAlexander Orzechowski <orzechowski.alexander@gmail.com>2022-06-02 10:33:04 -0400
commit4772eec93dc683b376283222243e852e0332c8a8 (patch)
treec826fb3b1fbbae4e8f816130c5f64db61bf28d4c
parent6936e163b514fd4f43a9319f53090527fc411156 (diff)
wlr_scene_buffer: Call output enter/leave after primary_output calculation
-rw-r--r--types/scene/wlr_scene.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c
index 8f9d0369..791462dd 100644
--- a/types/scene/wlr_scene.c
+++ b/types/scene/wlr_scene.c
@@ -205,6 +205,14 @@ static void scene_buffer_update_outputs(
int largest_overlap = 0;
scene_buffer->primary_output = NULL;
+ uint64_t active_outputs = 0;
+
+ // let's update the outputs in two steps:
+ // - the primary outputs
+ // - the enter/leave signals
+ // This ensures that the enter/leave signals can rely on the primary output
+ // to have a reasonable value. Otherwise, they may get a value that's in
+ // the middle of a calculation.
struct wlr_scene_output *scene_output;
wl_list_for_each(scene_output, &scene->outputs, link) {
struct wlr_box output_box = {
@@ -216,7 +224,6 @@ static void scene_buffer_update_outputs(
struct wlr_box intersection;
bool intersects = wlr_box_intersection(&intersection, &buffer_box, &output_box);
- bool intersects_before = scene_buffer->active_outputs & (1ull << scene_output->index);
if (intersects) {
int overlap = intersection.width * intersection.height;
@@ -224,13 +231,22 @@ static void scene_buffer_update_outputs(
largest_overlap = overlap;
scene_buffer->primary_output = scene_output;
}
+
+ active_outputs |= 1ull << scene_output->index;
}
+ }
+
+ uint64_t old_active = scene_buffer->active_outputs;
+ scene_buffer->active_outputs = active_outputs;
+
+ wl_list_for_each(scene_output, &scene->outputs, link) {
+ uint64_t mask = 1ull << scene_output->index;
+ bool intersects = active_outputs & mask;
+ bool intersects_before = old_active & mask;
if (intersects && !intersects_before) {
- scene_buffer->active_outputs |= 1ull << scene_output->index;
wlr_signal_emit_safe(&scene_buffer->events.output_enter, scene_output);
} else if (!intersects && intersects_before) {
- scene_buffer->active_outputs &= ~(1ull << scene_output->index);
wlr_signal_emit_safe(&scene_buffer->events.output_leave, scene_output);
}
}