[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