summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.co.uk>2017-03-24 16:21:06 +0200
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2017-10-04 16:18:06 +0300
commit01e0068868a2424aa53c5df9849f0aaa43b5bf37 (patch)
treece10eb8239d6220079911e2643ed097ecd2b818d
parenta0bfedc1cf01e6ed60e303e33efe977f9a70b4d8 (diff)
libweston: send more wl_surface.enter/leave events
A client may have bound the same wl_output multiple times, for who knows what reason. As the server cannot know which wl_output resource to use for which wl_surface, send enter/leave events for all of them. This is a protocol correctness fix. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Ian Ray <ian.ray@ge.com> Acked-by Daniel Stone <daniels@collabora.com>
-rw-r--r--libweston/compositor.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 165ff013..e647d30f 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -918,6 +918,39 @@ weston_view_damage_below(struct weston_view *view)
weston_view_schedule_repaint(view);
}
+/** Send wl_surface.enter/leave events
+ *
+ * \param surface The surface.
+ * \param output The entered/left output.
+ * \param enter True if entered.
+ * \param left True if left.
+ *
+ * Send the enter/leave events for all protocol objects bound to the given
+ * output by the client owning the surface.
+ */
+static void
+weston_surface_send_enter_leave(struct weston_surface *surface,
+ struct weston_output *output,
+ bool enter,
+ bool leave)
+{
+ struct wl_resource *wloutput;
+ struct wl_client *client;
+
+ assert(enter != leave);
+
+ client = wl_resource_get_client(surface->resource);
+ wl_resource_for_each(wloutput, &output->resource_list) {
+ if (wl_resource_get_client(wloutput) != client)
+ continue;
+
+ if (enter)
+ wl_surface_send_enter(surface->resource, wloutput);
+ if (leave)
+ wl_surface_send_leave(surface->resource, wloutput);
+ }
+}
+
/**
* \param es The surface
* \param mask The new set of outputs for the surface
@@ -933,9 +966,8 @@ weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
uint32_t different = es->output_mask ^ mask;
uint32_t entered = mask & different;
uint32_t left = es->output_mask & different;
+ uint32_t output_bit;
struct weston_output *output;
- struct wl_resource *resource = NULL;
- struct wl_client *client;
es->output_mask = mask;
if (es->resource == NULL)
@@ -943,19 +975,14 @@ weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
if (different == 0)
return;
- client = wl_resource_get_client(es->resource);
-
wl_list_for_each(output, &es->compositor->output_list, link) {
- if (1u << output->id & different)
- resource =
- wl_resource_find_for_client(&output->resource_list,
- client);
- if (resource == NULL)
+ output_bit = 1u << output->id;
+ if (!(output_bit & different))
continue;
- if (1u << output->id & entered)
- wl_surface_send_enter(es->resource, resource);
- if (1u << output->id & left)
- wl_surface_send_leave(es->resource, resource);
+
+ weston_surface_send_enter_leave(es, output,
+ output_bit & entered,
+ output_bit & left);
}
}