diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index 1238653d..6c2928ee 100644 --- a/include/wlr/types/wlr_scene.h +++ b/include/wlr/types/wlr_scene.h @@ -74,6 +74,14 @@ struct wlr_scene_surface { struct wlr_scene_node node; struct wlr_surface *surface; + /** + * The output that the largest area of this surface is displayed on. + * This may be NULL if the surface is not currently displayed on any + * outputs. This is the output that should be used for frame callbacks, + * presentation feedback, etc. + */ + struct wlr_output *primary_output; + // private state int prev_width, prev_height; diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index d2f3f4a7..42697074 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -175,6 +175,9 @@ static void scene_surface_update_outputs( .height = scene_surface->surface->current.height, }; + int largest_overlap = 0; + scene_surface->primary_output = NULL; + struct wlr_scene_output *scene_output; wl_list_for_each(scene_output, &scene->outputs, link) { struct wlr_box output_box = { @@ -184,10 +187,16 @@ static void scene_surface_update_outputs( wlr_output_effective_resolution(scene_output->output, &output_box.width, &output_box.height); - // These enter/leave functions are a noop if the event has already been - // sent for the given output. struct wlr_box intersection; if (wlr_box_intersection(&intersection, &surface_box, &output_box)) { + int overlap = intersection.width * intersection.height; + if (overlap > largest_overlap) { + largest_overlap = overlap; + scene_surface->primary_output = scene_output->output; + } + + // These enter/leave functions are a noop if the event has already been + // sent for the given output. wlr_surface_send_enter(scene_surface->surface, scene_output->output); } else { wlr_surface_send_leave(scene_surface->surface, scene_output->output);