[RFC 1/2] Introduce wl_probe_visible protocol
Daniel Stone
daniel at fooishbar.org
Thu Oct 8 13:16:51 PDT 2015
Hi,
On 1 October 2015 at 07:51, Jonas Ådahl <jadahl at gmail.com> wrote:
> The are a few problems with this approach, such as:
>
> 1) It requires an extra roundtrip to create a popup/tooltip (not that
> big of a deal though, I'd say).
> 2) When the parent surface has non-trivial transformations (non-90
> degree rotation etc), a resulting rectangle is ambigous. This could be
> made implementation specific or with some required semantics (such as
> prefer rectangles where more corners are untouched, prefer larger
> rectangle etc).
> 3) It may be abused to get an (incorrect) absolute surface position.
> 4) It is racy - for a moving surface, the visibility will change as it
> moves.
Not to sound too dismissive, but if you're trying to open a pop-up on
a window which is also actively moving at that exact moment, you're
never going to get a good result. So I don't think that makes much
odds, though the rest of your reasoning is good.
> A different approach of solving the same issue is to shift the
> responsibility for positioning popups from the client to the
> compositor. This requires a more complex protocol allowing the client
> describing the expected semantics, as well as a roundtrip then the
> client needs to know how the compositor positioned a given rectangle.
> For the position readback case, this approach has the same racyness as
> the approach in this patch, and adding a new kind of positioning logic
> would need changing the protocol. This approach is what Mir is taking.
>
> Personally, I'm not completely convinced a "wl_probe" way of improving
> the menu positioning is the better option here, and would like to hear
> what other think about this.
Speaking as the guy who suggested reviving it - because it seemed to
be the last vague consensus - I'm totally ambivalent. It does seem
like compositor positioning could be quite helpful in the complex
corner cases, though it does add a little more complication to the
compositor than previously.
I'm fine with whatever you and Carlos think is best; seems like at
this stage what we need is a compositor/toolkit implementation to
prove the concept. If compositor positioning does seem best, then a
quick pass through the Enlightenment/KWin guys to check that it's not
too onerous for them to implement would be great. But overall I trust
your judgement a lot more than I do mine.
Cheers,
Daniel
> Makefile.am | 3 ++
> protocol/probe-visible.xml | 91 +++++++++++++++++++++++++++++++++
> src/compositor.c | 125 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 219 insertions(+)
> create mode 100644 protocol/probe-visible.xml
>
> diff --git a/Makefile.am b/Makefile.am
> index 1900390..00f3ad2 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -125,6 +125,8 @@ nodist_weston_SOURCES = \
> protocol/workspaces-server-protocol.h \
> protocol/presentation_timing-protocol.c \
> protocol/presentation_timing-server-protocol.h \
> + protocol/probe-visible-protocol.c \
> + protocol/probe-visible-server-protocol.h \
> protocol/scaler-protocol.c \
> protocol/scaler-server-protocol.h \
> protocol/linux-dmabuf-protocol.c \
> @@ -1345,6 +1347,7 @@ EXTRA_DIST += \
> protocol/xdg-shell.xml \
> protocol/fullscreen-shell.xml \
> protocol/presentation_timing.xml \
> + protocol/probe-visible.xml \
> protocol/scaler.xml \
> protocol/ivi-application.xml \
> protocol/ivi-hmi-controller.xml \
> diff --git a/protocol/probe-visible.xml b/protocol/probe-visible.xml
> new file mode 100644
> index 0000000..0af9ed7
> --- /dev/null
> +++ b/protocol/probe-visible.xml
> @@ -0,0 +1,91 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<protocol name="probe_visible_area">
> +
> + <copyright>
> + Copyright © 2013 Intel Corporation
> + Copyright © 2015 Red Hat Inc.
> +
> + Permission is hereby granted, free of charge, to any person obtaining a
> + copy of this software and associated documentation files (the "Software"),
> + to deal in the Software without restriction, including without limitation
> + the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + and/or sell copies of the Software, and to permit persons to whom the
> + Software is furnished to do so, subject to the following conditions:
> +
> + The above copyright notice and this permission notice (including the next
> + paragraph) shall be included in all copies or substantial portions of the
> + Software.
> +
> + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + DEALINGS IN THE SOFTWARE.
> + </copyright>
> +
> + <interface name="_wl_probe_visible" version="1">
> + <description summary="probe visible area of a rectangle">
> + Probe visibility of regions relative to surfaces.
> +
> + Warning! The protocol described in this file is experimental. Each version
> + of this protocol should be considered incompatible with any other version,
> + and a client binding to a version different to the one advertised will be
> + terminated. Once the protocol is declared stable, backward compatibility
> + is guaranteed, the '_' prefix will be removed from the name and the
> + version will be reset to 1.
> + </description>
> +
> + <enum name="error">
> + <entry name="version_mismatch" value="0"/>
> + </enum>
> +
> + <request name="destroy" type="destructor"/>
> +
> + <request name="probe_rectangle">
> + <description summary="probe visibilty of rectangle">
> + Asks the compositor what the visible area for a surface would be if it
> + was positioned with the proposed rectangle relative to the provided
> + surface. The visible_rectangle event will be fired with the rectangle
> + that the compositor would show. The client can then use this information
> + to reposition the surface as appropriate for its needs. The intention is
> + for this request to be used by clients looking to find the ideal
> + location for a popup window whilst still respecting the borders of the
> + output.
> +
> + The object returned by this request will be destroyed by the compositor
> + after the rectangle is returned and as such the client must destroy the
> + object and not attempt to use it after that point.
> + </description>
> +
> + <arg name="id" type="new_id" interface="_wl_probe_visible_result"/>
> + <arg name="surface" type="object" interface="wl_surface"/>
> + <arg name="x" type="int"/>
> + <arg name="y" type="int"/>
> + <arg name="width" type="int"/>
> + <arg name="height" type="int"/>
> + </request>
> + </interface>
> +
> + <interface name="_wl_probe_visible_result" version="1">
> + <description summary="probed visibility result">
> + </description>
> +
> + <event name="visible_rectangle">
> + <description summary="visible area">
> + This event is fired in response to the probe_rectangle request on the
> + wl_probe_visible object. It returns the visible rectangle that the
> + surface would occupy when taking into consideration the output's edges.
> + If the width or height is zero this indicates that the window would not
> + be visible at all in that dimension. In that case the x and y values
> + represent the distance to the edge of the viewable area.
> + </description>
> + <arg name="x" type="int"/>
> + <arg name="y" type="int"/>
> + <arg name="width" type="int"/>
> + <arg name="height" type="int"/>
> + </event>
> + </interface>
> +
> +</protocol>
> diff --git a/src/compositor.c b/src/compositor.c
> index 125afd5..ea46b97 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -56,6 +56,7 @@
> #include "compositor.h"
> #include "scaler-server-protocol.h"
> #include "presentation_timing-server-protocol.h"
> +#include "probe-visible-server-protocol.h"
> #include "shared/helpers.h"
> #include "shared/os-compatibility.h"
> #include "shared/timespec-util.h"
> @@ -4397,6 +4398,126 @@ bind_presentation(struct wl_client *client,
> }
>
> static void
> +probe_visible_destroy(struct wl_client *client, struct wl_resource *resource)
> +{
> + wl_resource_destroy(resource);
> +}
> +
> +static void
> +weston_view_constrain_visible_rectangle(struct weston_view *view,
> + int32_t *x, int32_t *y,
> + int32_t *width, int32_t *height)
> +{
> + float xf1 = *x;
> + float yf1 = *y;
> + float xf2 = *x + *width;
> + float yf2 = *y + *height;
> + struct weston_output *output = view->output;
> +
> + weston_view_to_global_float(view, xf1, yf1, &xf1, &yf1);
> + weston_view_to_global_float(view, xf2, yf2, &xf2, &yf2);
> +
> + if (xf1 < output->x)
> + xf1 = output->x;
> + if (yf1 < output->y)
> + yf1 = output->y;
> + if (xf1 > output->x + output->width)
> + xf1 = output->x + output->width;
> + if (yf1 > output->y + output->height)
> + yf1 = output->y + output->height;
> +
> + if (xf2 < output->x)
> + xf2 = output->x;
> + if (yf2 < output->y)
> + yf2 = output->y;
> + if (xf2 > output->x + output->width)
> + xf2 = output->x + output->width;
> + if (yf2 > output->y + output->height)
> + yf2 = output->y + output->height;
> +
> + weston_view_from_global_float(view, xf1, yf1, &xf1, &yf1);
> + weston_view_from_global_float(view, xf2, yf2, &xf2, &yf2);
> +
> + *x = (int32_t) xf1;
> + *y = (int32_t) yf1;
> + *width = (int32_t) (xf2 - xf1);
> + *height = (int32_t) (yf2 - yf1);
> +}
> +
> +static void
> +weston_surface_constrain_visible_rectangle(struct weston_surface *surface,
> + int32_t *x, int32_t *y,
> + int32_t *width, int32_t *height)
> +{
> + struct weston_view *view;
> +
> + wl_list_for_each(view, &surface->views, surface_link) {
> + weston_view_constrain_visible_rectangle(view,
> + x, y,
> + width, height);
> + }
> +}
> +
> +static void
> +probe_visible_probe_rectangle(struct wl_client *client,
> + struct wl_resource *resource,
> + uint32_t id,
> + struct wl_resource *surface_resource,
> + int32_t x, int32_t y,
> + int32_t width, int32_t height)
> +{
> + struct wl_resource *result_resource;
> + struct weston_surface *surface = wl_resource_get_user_data(surface_resource);
> +
> + result_resource = wl_resource_create(client,
> + &_wl_probe_visible_result_interface,
> + 1, id);
> + if (result_resource == NULL) {
> + wl_client_post_no_memory(client);
> + return;
> + }
> +
> + weston_surface_constrain_visible_rectangle(surface,
> + &x, &y,
> + &width, &height);
> +
> + _wl_probe_visible_result_send_visible_rectangle(result_resource,
> + x, y,
> + width, height);
> + wl_resource_destroy(result_resource);
> +}
> +
> +static const struct _wl_probe_visible_interface probe_visible_implementation = {
> + probe_visible_destroy,
> + probe_visible_probe_rectangle,
> +};
> +
> +static void
> +bind_probe_visible(struct wl_client *client,
> + void *data, uint32_t version, uint32_t id)
> +{
> + struct weston_compositor *compositor = data;
> + struct wl_resource *resource;
> +
> + resource = wl_resource_create(client, &_wl_probe_visible_interface,
> + 1, id);
> + if (resource == NULL) {
> + wl_client_post_no_memory(client);
> + return;
> + }
> +
> + if (version != 1) {
> + wl_resource_post_error(resource,
> + _WL_PROBE_VISIBLE_ERROR_VERSION_MISMATCH,
> + "Incompatible version");
> + return;
> + }
> +
> + wl_resource_set_implementation(resource, &probe_visible_implementation,
> + compositor, NULL);
> +}
> +
> +static void
> compositor_bind(struct wl_client *client,
> void *data, uint32_t version, uint32_t id)
> {
> @@ -4506,6 +4627,10 @@ weston_compositor_create(struct wl_display *display, void *user_data)
> ec, bind_presentation))
> goto fail;
>
> + if (!wl_global_create(ec->wl_display, &_wl_probe_visible_interface, 1,
> + ec, bind_probe_visible))
> + goto fail;
> +
> wl_list_init(&ec->view_list);
> wl_list_init(&ec->plane_list);
> wl_list_init(&ec->layer_list);
> --
> 2.4.3
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list