Client: Add support for xdg_toplevel.configure_bounds
Currently, QtWayland doesn't know about work area size, which can create a problem where some windows don't fit into the screen area or work area. With the xdg_toplevel.configure_bounds event, the compositor can indicate the client the recommended maximum window geometry size. https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/41 Change-Id: I5214aba9f144d091a2afe639de94b8d717c42fdc Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
parent
165b770fc5
commit
9dd6cc1788
167
src/3rdparty/wayland/protocols/xdg-shell.xml
vendored
167
src/3rdparty/wayland/protocols/xdg-shell.xml
vendored
@ -29,7 +29,7 @@
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="xdg_wm_base" version="2">
|
||||
<interface name="xdg_wm_base" version="4">
|
||||
<description summary="create desktop-style surfaces">
|
||||
The xdg_wm_base interface is exposed as a global object enabling clients
|
||||
to turn their wl_surfaces into windows in a desktop environment. It
|
||||
@ -75,7 +75,9 @@
|
||||
<description summary="create a shell surface from a surface">
|
||||
This creates an xdg_surface for the given surface. While xdg_surface
|
||||
itself is not a role, the corresponding surface may only be assigned
|
||||
a role extending xdg_surface, such as xdg_toplevel or xdg_popup.
|
||||
a role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is
|
||||
illegal to create an xdg_surface for a wl_surface which already has an
|
||||
assigned role and this will result in a protocol error.
|
||||
|
||||
This creates an xdg_surface for the given surface. An xdg_surface is
|
||||
used as basis to define a role to a given surface, such as xdg_toplevel
|
||||
@ -115,7 +117,7 @@
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_positioner" version="2">
|
||||
<interface name="xdg_positioner" version="4">
|
||||
<description summary="child surface positioner">
|
||||
The xdg_positioner provides a collection of rules for the placement of a
|
||||
child surface relative to a parent surface. Rules can be defined to ensure
|
||||
@ -357,9 +359,49 @@
|
||||
<arg name="x" type="int" summary="surface position x offset"/>
|
||||
<arg name="y" type="int" summary="surface position y offset"/>
|
||||
</request>
|
||||
|
||||
<!-- Version 3 additions -->
|
||||
|
||||
<request name="set_reactive" since="3">
|
||||
<description summary="continuously reconstrain the surface">
|
||||
When set reactive, the surface is reconstrained if the conditions used
|
||||
for constraining changed, e.g. the parent window moved.
|
||||
|
||||
If the conditions changed and the popup was reconstrained, an
|
||||
xdg_popup.configure event is sent with updated geometry, followed by an
|
||||
xdg_surface.configure event.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="set_parent_size" since="3">
|
||||
<description summary="">
|
||||
Set the parent window geometry the compositor should use when
|
||||
positioning the popup. The compositor may use this information to
|
||||
determine the future state the popup should be constrained using. If
|
||||
this doesn't match the dimension of the parent the popup is eventually
|
||||
positioned against, the behavior is undefined.
|
||||
|
||||
The arguments are given in the surface-local coordinate space.
|
||||
</description>
|
||||
<arg name="parent_width" type="int"
|
||||
summary="future window geometry width of parent"/>
|
||||
<arg name="parent_height" type="int"
|
||||
summary="future window geometry height of parent"/>
|
||||
</request>
|
||||
|
||||
<request name="set_parent_configure" since="3">
|
||||
<description summary="set parent configure this is a response to">
|
||||
Set the serial of an xdg_surface.configure event this positioner will be
|
||||
used in response to. The compositor may use this information together
|
||||
with set_parent_size to determine what future state the popup should be
|
||||
constrained using.
|
||||
</description>
|
||||
<arg name="serial" type="uint"
|
||||
summary="serial of parent configure event"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_surface" version="2">
|
||||
<interface name="xdg_surface" version="4">
|
||||
<description summary="desktop user interface surface base interface">
|
||||
An interface that may be implemented by a wl_surface, for
|
||||
implementations that provide a desktop-style user interface.
|
||||
@ -386,6 +428,11 @@
|
||||
manipulate a buffer prior to the first xdg_surface.configure call must
|
||||
also be treated as errors.
|
||||
|
||||
After creating a role-specific object and setting it up, the client must
|
||||
perform an initial commit without any buffer attached. The compositor
|
||||
will reply with an xdg_surface.configure event. The client must
|
||||
acknowledge it and is then allowed to attach a buffer to map the surface.
|
||||
|
||||
Mapping an xdg_surface-based role surface is defined as making it
|
||||
possible for the surface to be shown by the compositor. Note that
|
||||
a mapped surface is not guaranteed to be visible once it is mapped.
|
||||
@ -399,7 +446,8 @@
|
||||
|
||||
A newly-unmapped surface is considered to have met condition (1) out
|
||||
of the 3 required conditions for mapping a surface if its role surface
|
||||
has not been destroyed.
|
||||
has not been destroyed, i.e. the client must perform the initial commit
|
||||
again before attaching a buffer.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
@ -526,9 +574,10 @@
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="serial of the configure event"/>
|
||||
</event>
|
||||
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_toplevel" version="2">
|
||||
<interface name="xdg_toplevel" version="4">
|
||||
<description summary="toplevel surface">
|
||||
This interface defines an xdg_surface role which allows a surface to,
|
||||
among other things, set window-like properties such as maximize,
|
||||
@ -540,7 +589,11 @@
|
||||
by the compositor until it is explicitly mapped again.
|
||||
All active operations (e.g., move, resize) are canceled and all
|
||||
attributes (e.g. title, state, stacking, ...) are discarded for
|
||||
an xdg_toplevel surface when it is unmapped.
|
||||
an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
|
||||
the state it had right after xdg_surface.get_toplevel. The client
|
||||
can re-map the toplevel by perfoming a commit without any buffer
|
||||
attached, waiting for a configure event and handling it as usual (see
|
||||
xdg_surface description).
|
||||
|
||||
Attaching a null buffer to a toplevel unmaps the surface.
|
||||
</description>
|
||||
@ -710,7 +763,7 @@
|
||||
</description>
|
||||
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
|
||||
<arg name="serial" type="uint" summary="the serial of the user event"/>
|
||||
<arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
|
||||
<arg name="edges" type="uint" enum="resize_edge" summary="which edge or corner is being dragged"/>
|
||||
</request>
|
||||
|
||||
<enum name="state">
|
||||
@ -757,25 +810,25 @@
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="tiled_left" value="5" since="2">
|
||||
<description summary="the surface is tiled">
|
||||
<description summary="the surface’s left edge is tiled">
|
||||
The window is currently in a tiled layout and the left edge is
|
||||
considered to be adjacent to another part of the tiling grid.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="tiled_right" value="6" since="2">
|
||||
<description summary="the surface is tiled">
|
||||
<description summary="the surface’s right edge is tiled">
|
||||
The window is currently in a tiled layout and the right edge is
|
||||
considered to be adjacent to another part of the tiling grid.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="tiled_top" value="7" since="2">
|
||||
<description summary="the surface is tiled">
|
||||
<description summary="the surface’s top edge is tiled">
|
||||
The window is currently in a tiled layout and the top edge is
|
||||
considered to be adjacent to another part of the tiling grid.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="tiled_bottom" value="8" since="2">
|
||||
<description summary="the surface is tiled">
|
||||
<description summary="the surface’s bottom edge is tiled">
|
||||
The window is currently in a tiled layout and the bottom edge is
|
||||
considered to be adjacent to another part of the tiling grid.
|
||||
</description>
|
||||
@ -1017,9 +1070,33 @@
|
||||
a dialog to ask the user to save their data, etc.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<!-- Version 4 additions -->
|
||||
|
||||
<event name="configure_bounds" since="4">
|
||||
<description summary="recommended window geometry bounds">
|
||||
The configure_bounds event may be sent prior to a xdg_toplevel.configure
|
||||
event to communicate the bounds a window geometry size is recommended
|
||||
to constrain to.
|
||||
|
||||
The passed width and height are in surface coordinate space. If width
|
||||
and height are 0, it means bounds is unknown and equivalent to as if no
|
||||
configure_bounds event was ever sent for this surface.
|
||||
|
||||
The bounds can for example correspond to the size of a monitor excluding
|
||||
any panels or other shell components, so that a surface isn't created in
|
||||
a way that it cannot fit.
|
||||
|
||||
The bounds may change at any point, and in such a case, a new
|
||||
xdg_toplevel.configure_bounds will be sent, followed by
|
||||
xdg_toplevel.configure and xdg_surface.configure.
|
||||
</description>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_popup" version="2">
|
||||
<interface name="xdg_popup" version="4">
|
||||
<description summary="short-lived, popup surfaces for menus">
|
||||
A popup surface is a short-lived, temporary surface. It can be used to
|
||||
implement for example menus, popovers, tooltips and other similar user
|
||||
@ -1043,12 +1120,6 @@
|
||||
The parent of an xdg_popup must be mapped (see the xdg_surface
|
||||
description) before the xdg_popup itself.
|
||||
|
||||
The x and y arguments passed when creating the popup object specify
|
||||
where the top left of the popup should be placed, relative to the
|
||||
local surface coordinates of the parent surface. See
|
||||
xdg_surface.get_popup. An xdg_popup must intersect with or be at least
|
||||
partially adjacent to its parent surface.
|
||||
|
||||
The client must call wl_surface.commit on the corresponding wl_surface
|
||||
for the xdg_popup state to take effect.
|
||||
</description>
|
||||
@ -1126,6 +1197,11 @@
|
||||
The x and y arguments represent the position the popup was placed at
|
||||
given the xdg_positioner rule, relative to the upper left corner of the
|
||||
window geometry of the parent surface.
|
||||
|
||||
For version 2 or older, the configure event for an xdg_popup is only
|
||||
ever sent once for the initial configuration. Starting with version 3,
|
||||
it may be sent again if the popup is setup with an xdg_positioner with
|
||||
set_reactive requested, or in response to xdg_popup.reposition requests.
|
||||
</description>
|
||||
<arg name="x" type="int"
|
||||
summary="x position relative to parent surface window geometry"/>
|
||||
@ -1143,5 +1219,58 @@
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<!-- Version 3 additions -->
|
||||
|
||||
<request name="reposition" since="3">
|
||||
<description summary="recalculate the popup's location">
|
||||
Reposition an already-mapped popup. The popup will be placed given the
|
||||
details in the passed xdg_positioner object, and a
|
||||
xdg_popup.repositioned followed by xdg_popup.configure and
|
||||
xdg_surface.configure will be emitted in response. Any parameters set
|
||||
by the previous positioner will be discarded.
|
||||
|
||||
The passed token will be sent in the corresponding
|
||||
xdg_popup.repositioned event. The new popup position will not take
|
||||
effect until the corresponding configure event is acknowledged by the
|
||||
client. See xdg_popup.repositioned for details. The token itself is
|
||||
opaque, and has no other special meaning.
|
||||
|
||||
If multiple reposition requests are sent, the compositor may skip all
|
||||
but the last one.
|
||||
|
||||
If the popup is repositioned in response to a configure event for its
|
||||
parent, the client should send an xdg_positioner.set_parent_configure
|
||||
and possibly an xdg_positioner.set_parent_size request to allow the
|
||||
compositor to properly constrain the popup.
|
||||
|
||||
If the popup is repositioned together with a parent that is being
|
||||
resized, but not in response to a configure event, the client should
|
||||
send an xdg_positioner.set_parent_size request.
|
||||
</description>
|
||||
<arg name="positioner" type="object" interface="xdg_positioner"/>
|
||||
<arg name="token" type="uint" summary="reposition request token"/>
|
||||
</request>
|
||||
|
||||
<event name="repositioned" since="3">
|
||||
<description summary="signal the completion of a repositioned request">
|
||||
The repositioned event is sent as part of a popup configuration
|
||||
sequence, together with xdg_popup.configure and lastly
|
||||
xdg_surface.configure to notify the completion of a reposition request.
|
||||
|
||||
The repositioned event is to notify about the completion of a
|
||||
xdg_popup.reposition request. The token argument is the token passed
|
||||
in the xdg_popup.reposition request.
|
||||
|
||||
Immediately after this event is emitted, xdg_popup.configure and
|
||||
xdg_surface.configure will be sent with the updated size and position,
|
||||
as well as a new configure serial.
|
||||
|
||||
The client should optionally update the content of the popup, but must
|
||||
acknowledge the new popup configuration for the new position to take
|
||||
effect. See xdg_surface.ack_configure for details.
|
||||
</description>
|
||||
<arg name="token" type="uint" summary="reposition request token"/>
|
||||
</event>
|
||||
|
||||
</interface>
|
||||
</protocol>
|
||||
|
@ -61,8 +61,12 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
|
||||
if (m_pending.size.isEmpty()) {
|
||||
// An empty size in the configure means it's up to the client to choose the size
|
||||
bool normalPending = !(m_pending.states & (Qt::WindowMaximized|Qt::WindowFullScreen));
|
||||
if (normalPending && !m_normalSize.isEmpty())
|
||||
m_xdgSurface->m_window->resizeFromApplyConfigure(m_normalSize);
|
||||
if (normalPending && !m_normalSize.isEmpty()) {
|
||||
QSize size = m_normalSize;
|
||||
if (!m_pending.bounds.isEmpty())
|
||||
size = size.boundedTo(m_pending.bounds);
|
||||
m_xdgSurface->m_window->resizeFromApplyConfigure(size);
|
||||
}
|
||||
} else {
|
||||
m_xdgSurface->m_window->resizeFromApplyConfigure(m_pending.size);
|
||||
}
|
||||
@ -80,6 +84,11 @@ bool QWaylandXdgSurface::Toplevel::wantsDecorations()
|
||||
return !(m_pending.states & Qt::WindowFullScreen);
|
||||
}
|
||||
|
||||
void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure_bounds(int32_t width, int32_t height)
|
||||
{
|
||||
m_pending.bounds = QSize(width, height);
|
||||
}
|
||||
|
||||
void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states)
|
||||
{
|
||||
m_pending.size = QSize(width, height);
|
||||
@ -578,7 +587,7 @@ QString QWaylandXdgSurface::externWindowHandle()
|
||||
}
|
||||
|
||||
QWaylandXdgShell::QWaylandXdgShell(QWaylandDisplay *display, uint32_t id, uint32_t availableVersion)
|
||||
: QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 2u))
|
||||
: QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 4u))
|
||||
, m_display(display)
|
||||
{
|
||||
display->addRegistryListener(&QWaylandXdgShell::handleRegistryGlobal, this);
|
||||
|
@ -88,6 +88,7 @@ private:
|
||||
|
||||
void xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states) override;
|
||||
void xdg_toplevel_close() override;
|
||||
void xdg_toplevel_configure_bounds(int32_t width, int32_t height) override;
|
||||
|
||||
void requestWindowFlags(Qt::WindowFlags flags);
|
||||
void requestWindowStates(Qt::WindowStates states);
|
||||
@ -95,6 +96,7 @@ private:
|
||||
static resize_edge convertToResizeEdges(Qt::Edges edges);
|
||||
|
||||
struct {
|
||||
QSize bounds = {0, 0};
|
||||
QSize size = {0, 0};
|
||||
Qt::WindowStates states = Qt::WindowNoState;
|
||||
} m_pending, m_applied;
|
||||
|
Loading…
x
Reference in New Issue
Block a user