[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