[RFC 1/2] Introduce wl_probe_visible protocol

Jasper St. Pierre jstpierre at mecheye.net
Thu Oct 8 13:21:09 PDT 2015


Mir seems to be pushing forward with their compositor-based attachment
protocol, and if they've analyzed it and established that it covers
most cases, I'm totally fine with us taking that.

Descriptive, not prescriptive :)

On Thu, Oct 8, 2015 at 1:16 PM, Daniel Stone <daniel at fooishbar.org> wrote:
> 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
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel



-- 
  Jasper


More information about the wayland-devel mailing list