client: support Xdg Shell not_shown state
This state is to indicate that a toplevel is not visible, either minimised on another desktop. This maps to QWindow::isExposed. In addition to XdgShell changes. QWaylandWindow is adjusted to check exposure state before sendingExposureEvents. Subsurfaces are un-exposed and re-exposed when the toplevel changes. Change-Id: I76932c2c58681f832c1c2efde3cfde1c32cd3e05 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
parent
1110b2c3e4
commit
0b82d95632
196
src/3rdparty/wayland/protocols/xdg-shell.xml
vendored
196
src/3rdparty/wayland/protocols/xdg-shell.xml
vendored
@ -29,7 +29,7 @@
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="xdg_wm_base" version="4">
|
||||
<interface name="xdg_wm_base" version="6">
|
||||
<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
|
||||
@ -50,6 +50,8 @@
|
||||
summary="the client provided an invalid surface state"/>
|
||||
<entry name="invalid_positioner" value="5"
|
||||
summary="the client provided an invalid positioner"/>
|
||||
<entry name="unresponsive" value="6"
|
||||
summary="the client didn’t respond to a ping event in time"/>
|
||||
</enum>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
@ -58,7 +60,7 @@
|
||||
|
||||
Destroying a bound xdg_wm_base object while there are surfaces
|
||||
still alive created by this xdg_wm_base object instance is illegal
|
||||
and will result in a protocol error.
|
||||
and will result in a defunct_surfaces error.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
@ -77,7 +79,7 @@
|
||||
itself is not a role, the corresponding surface may only be assigned
|
||||
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.
|
||||
assigned role and this will result in a role 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
|
||||
@ -94,7 +96,8 @@
|
||||
<request name="pong">
|
||||
<description summary="respond to a ping event">
|
||||
A client must respond to a ping event with a pong request or
|
||||
the client may be deemed unresponsive. See xdg_wm_base.ping.
|
||||
the client may be deemed unresponsive. See xdg_wm_base.ping
|
||||
and xdg_wm_base.error.unresponsive.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="serial of the ping event"/>
|
||||
</request>
|
||||
@ -108,7 +111,9 @@
|
||||
Compositors can use this to determine if the client is still
|
||||
alive. It's unspecified what will happen if the client doesn't
|
||||
respond to the ping request, or in what timeframe. Clients should
|
||||
try to respond in a reasonable amount of time.
|
||||
try to respond in a reasonable amount of time. The “unresponsive”
|
||||
error is provided for compositors that wish to disconnect unresponsive
|
||||
clients.
|
||||
|
||||
A compositor is free to ping in any way it wants, but a client must
|
||||
always respond to any xdg_wm_base object it created.
|
||||
@ -117,7 +122,7 @@
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_positioner" version="4">
|
||||
<interface name="xdg_positioner" version="6">
|
||||
<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
|
||||
@ -137,7 +142,7 @@
|
||||
For an xdg_positioner object to be considered complete, it must have a
|
||||
non-zero size set by set_size, and a non-zero anchor rectangle set by
|
||||
set_anchor_rect. Passing an incomplete xdg_positioner object when
|
||||
positioning a surface raises an error.
|
||||
positioning a surface raises an invalid_positioner error.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
@ -225,7 +230,8 @@
|
||||
specified (e.g. 'bottom_right' or 'top_left'), then the child surface
|
||||
will be placed towards the specified gravity; otherwise, the child
|
||||
surface will be centered over the anchor point on any axis that had no
|
||||
gravity specified.
|
||||
gravity specified. If the gravity is not in the ‘gravity’ enum, an
|
||||
invalid_input error is raised.
|
||||
</description>
|
||||
<arg name="gravity" type="uint" enum="gravity"
|
||||
summary="gravity direction"/>
|
||||
@ -401,7 +407,7 @@
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_surface" version="4">
|
||||
<interface name="xdg_surface" version="6">
|
||||
<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.
|
||||
@ -430,8 +436,10 @@
|
||||
|
||||
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.
|
||||
will reply with initial wl_surface state such as
|
||||
wl_surface.preferred_buffer_scale followed by 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
|
||||
@ -451,15 +459,25 @@
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="not_constructed" value="1"/>
|
||||
<entry name="already_constructed" value="2"/>
|
||||
<entry name="unconfigured_buffer" value="3"/>
|
||||
<entry name="not_constructed" value="1"
|
||||
summary="Surface was not fully constructed"/>
|
||||
<entry name="already_constructed" value="2"
|
||||
summary="Surface was already constructed"/>
|
||||
<entry name="unconfigured_buffer" value="3"
|
||||
summary="Attaching a buffer to an unconfigured surface"/>
|
||||
<entry name="invalid_serial" value="4"
|
||||
summary="Invalid serial number when acking a configure event"/>
|
||||
<entry name="invalid_size" value="5"
|
||||
summary="Width or height was zero or negative"/>
|
||||
<entry name="defunct_role_object" value="6"
|
||||
summary="Surface was destroyed before its role object"/>
|
||||
</enum>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the xdg_surface">
|
||||
Destroy the xdg_surface object. An xdg_surface must only be destroyed
|
||||
after its role object has been destroyed.
|
||||
after its role object has been destroyed, otherwise
|
||||
a defunct_role_object error is raised.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
@ -514,13 +532,22 @@
|
||||
commit. This unset is meant for extremely simple clients.
|
||||
|
||||
The arguments are given in the surface-local coordinate space of
|
||||
the wl_surface associated with this xdg_surface.
|
||||
the wl_surface associated with this xdg_surface, and may extend outside
|
||||
of the wl_surface itself to mark parts of the subsurface tree as part of
|
||||
the window geometry.
|
||||
|
||||
The width and height must be greater than zero. Setting an invalid size
|
||||
will raise an error. When applied, the effective window geometry will be
|
||||
the set window geometry clamped to the bounding rectangle of the
|
||||
combined geometry of the surface of the xdg_surface and the associated
|
||||
When applied, the effective window geometry will be the set window
|
||||
geometry clamped to the bounding rectangle of the combined
|
||||
geometry of the surface of the xdg_surface and the associated
|
||||
subsurfaces.
|
||||
|
||||
The effective geometry will not be recalculated unless a new call to
|
||||
set_window_geometry is done and the new pending surface state is
|
||||
subsequently applied.
|
||||
|
||||
The width and height of the effective window geometry must be
|
||||
greater than zero. Setting an invalid size will raise an
|
||||
invalid_size error.
|
||||
</description>
|
||||
<arg name="x" type="int"/>
|
||||
<arg name="y" type="int"/>
|
||||
@ -541,6 +568,8 @@
|
||||
|
||||
If the client receives multiple configure events before it
|
||||
can respond to one, it only has to ack the last configure event.
|
||||
Acking a configure event that was never sent raises an invalid_serial
|
||||
error.
|
||||
|
||||
A client is not required to commit immediately after sending
|
||||
an ack_configure request - it may even ack_configure several times
|
||||
@ -549,6 +578,17 @@
|
||||
A client may send multiple ack_configure requests before committing, but
|
||||
only the last request sent before a commit indicates which configure
|
||||
event the client really is responding to.
|
||||
|
||||
Sending an ack_configure request consumes the serial number sent with
|
||||
the request, as well as serial numbers sent by all configure events
|
||||
sent on this xdg_surface prior to the configure event referenced by
|
||||
the committed serial.
|
||||
|
||||
It is an error to issue multiple ack_configure requests referencing a
|
||||
serial from the same configure event, or to issue an ack_configure
|
||||
request referencing a serial from a configure event issued before the
|
||||
event identified by the last ack_configure request for the same
|
||||
xdg_surface. Doing so will raise an invalid_serial error.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="the serial from the configure event"/>
|
||||
</request>
|
||||
@ -577,7 +617,7 @@
|
||||
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_toplevel" version="4">
|
||||
<interface name="xdg_toplevel" version="6">
|
||||
<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,
|
||||
@ -605,24 +645,37 @@
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_resize_edge" value="0" summary="provided value is
|
||||
not a valid variant of the resize_edge enum"/>
|
||||
<entry name="invalid_parent" value="1"
|
||||
summary="invalid parent toplevel"/>
|
||||
<entry name="invalid_size" value="2"
|
||||
summary="client provided an invalid min or max size"/>
|
||||
</enum>
|
||||
|
||||
<request name="set_parent">
|
||||
<description summary="set the parent of this surface">
|
||||
Set the "parent" of this surface. This surface should be stacked
|
||||
above the parent surface and all other ancestor surfaces.
|
||||
|
||||
Parent windows should be set on dialogs, toolboxes, or other
|
||||
Parent surfaces should be set on dialogs, toolboxes, or other
|
||||
"auxiliary" surfaces, so that the parent is raised when the dialog
|
||||
is raised.
|
||||
|
||||
Setting a null parent for a child window removes any parent-child
|
||||
relationship for the child. Setting a null parent for a window which
|
||||
currently has no parent is a no-op.
|
||||
Setting a null parent for a child surface unsets its parent. Setting
|
||||
a null parent for a surface which currently has no parent is a no-op.
|
||||
|
||||
If the parent is unmapped then its children are managed as
|
||||
though the parent of the now-unmapped parent has become the
|
||||
parent of this surface. If no parent exists for the now-unmapped
|
||||
parent then the children are managed as though they have no
|
||||
parent surface.
|
||||
Only mapped surfaces can have child surfaces. Setting a parent which
|
||||
is not mapped is equivalent to setting a null parent. If a surface
|
||||
becomes unmapped, its children's parent is set to the parent of
|
||||
the now-unmapped surface. If the now-unmapped surface has no parent,
|
||||
its children's parent is unset. If the now-unmapped surface becomes
|
||||
mapped again, its parent-child relationship is not restored.
|
||||
|
||||
The parent toplevel must not be one of the child toplevel's
|
||||
descendants, and the parent must be different from the child toplevel,
|
||||
otherwise the invalid_parent protocol error is raised.
|
||||
</description>
|
||||
<arg name="parent" type="object" interface="xdg_toplevel" allow-null="true"/>
|
||||
</request>
|
||||
@ -664,7 +717,7 @@
|
||||
application identifiers and how they relate to well-known D-Bus
|
||||
names and .desktop files.
|
||||
|
||||
[0] http://standards.freedesktop.org/desktop-entry-spec/
|
||||
[0] https://standards.freedesktop.org/desktop-entry-spec/
|
||||
</description>
|
||||
<arg name="app_id" type="string"/>
|
||||
</request>
|
||||
@ -678,7 +731,8 @@
|
||||
This request asks the compositor to pop up such a window menu at
|
||||
the given position, relative to the local surface coordinates of
|
||||
the parent surface. There are no guarantees as to what menu items
|
||||
the window menu contains.
|
||||
the window menu contains, or even if a window menu will be drawn
|
||||
at all.
|
||||
|
||||
This request must be used in response to some sort of user action
|
||||
like a button press, key press, or touch down event.
|
||||
@ -754,12 +808,13 @@
|
||||
guarantee that the device focus will return when the resize is
|
||||
completed.
|
||||
|
||||
The edges parameter specifies how the surface should be resized,
|
||||
and is one of the values of the resize_edge enum. The compositor
|
||||
may use this information to update the surface position for
|
||||
example when dragging the top left corner. The compositor may also
|
||||
use this information to adapt its behavior, e.g. choose an
|
||||
appropriate cursor image.
|
||||
The edges parameter specifies how the surface should be resized, and
|
||||
is one of the values of the resize_edge enum. Values not matching
|
||||
a variant of the enum will cause the invalid_resize_edge protocol error.
|
||||
The compositor may use this information to update the surface position
|
||||
for example when dragging the top left corner. The compositor may also
|
||||
use this information to adapt its behavior, e.g. choose an appropriate
|
||||
cursor image.
|
||||
</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"/>
|
||||
@ -779,7 +834,8 @@
|
||||
<entry name="maximized" value="1" summary="the surface is maximized">
|
||||
<description summary="the surface is maximized">
|
||||
The surface is maximized. The window geometry specified in the configure
|
||||
event must be obeyed by the client.
|
||||
event must be obeyed by the client, or the xdg_wm_base.invalid_surface_state
|
||||
error is raised.
|
||||
|
||||
The client should draw without shadow or other
|
||||
decoration outside of the window geometry.
|
||||
@ -833,6 +889,13 @@
|
||||
considered to be adjacent to another part of the tiling grid.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="suspended" value="9" since="6">
|
||||
<description summary="surface repaint is suspended">
|
||||
The surface is currently not ordinarily being repainted; for
|
||||
example because its content is occluded by another window, or its
|
||||
outputs are switched off due to screen locking.
|
||||
</description>
|
||||
</entry>
|
||||
</enum>
|
||||
|
||||
<request name="set_max_size">
|
||||
@ -866,11 +929,11 @@
|
||||
request.
|
||||
|
||||
Requesting a maximum size to be smaller than the minimum size of
|
||||
a surface is illegal and will result in a protocol error.
|
||||
a surface is illegal and will result in an invalid_size error.
|
||||
|
||||
The width and height must be greater than or equal to zero. Using
|
||||
strictly negative values for width and height will result in a
|
||||
protocol error.
|
||||
strictly negative values for width or height will result in a
|
||||
invalid_size error.
|
||||
</description>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
@ -907,11 +970,11 @@
|
||||
request.
|
||||
|
||||
Requesting a minimum size to be larger than the maximum size of
|
||||
a surface is illegal and will result in a protocol error.
|
||||
a surface is illegal and will result in an invalid_size error.
|
||||
|
||||
The width and height must be greater than or equal to zero. Using
|
||||
strictly negative values for width and height will result in a
|
||||
protocol error.
|
||||
invalid_size error.
|
||||
</description>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
@ -1094,9 +1157,44 @@
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
</event>
|
||||
|
||||
<!-- Version 5 additions -->
|
||||
|
||||
<enum name="wm_capabilities" since="5">
|
||||
<entry name="window_menu" value="1" summary="show_window_menu is available"/>
|
||||
<entry name="maximize" value="2" summary="set_maximized and unset_maximized are available"/>
|
||||
<entry name="fullscreen" value="3" summary="set_fullscreen and unset_fullscreen are available"/>
|
||||
<entry name="minimize" value="4" summary="set_minimized is available"/>
|
||||
</enum>
|
||||
|
||||
<event name="wm_capabilities" since="5">
|
||||
<description summary="compositor capabilities">
|
||||
This event advertises the capabilities supported by the compositor. If
|
||||
a capability isn't supported, clients should hide or disable the UI
|
||||
elements that expose this functionality. For instance, if the
|
||||
compositor doesn't advertise support for minimized toplevels, a button
|
||||
triggering the set_minimized request should not be displayed.
|
||||
|
||||
The compositor will ignore requests it doesn't support. For instance,
|
||||
a compositor which doesn't advertise support for minimized will ignore
|
||||
set_minimized requests.
|
||||
|
||||
Compositors must send this event once before the first
|
||||
xdg_surface.configure event. When the capabilities change, compositors
|
||||
must send this event again and then send an xdg_surface.configure
|
||||
event.
|
||||
|
||||
The configured state should not be applied immediately. See
|
||||
xdg_surface.configure for details.
|
||||
|
||||
The capabilities are sent as an array of 32-bit unsigned integers in
|
||||
native endianness.
|
||||
</description>
|
||||
<arg name="capabilities" type="array" summary="array of 32-bit capabilities"/>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_popup" version="4">
|
||||
<interface name="xdg_popup" version="6">
|
||||
<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
|
||||
@ -1134,8 +1232,8 @@
|
||||
This destroys the popup. Explicitly destroying the xdg_popup
|
||||
object will also dismiss the popup, and unmap the surface.
|
||||
|
||||
If this xdg_popup is not the "topmost" popup, a protocol error
|
||||
will be sent.
|
||||
If this xdg_popup is not the "topmost" popup, the
|
||||
xdg_wm_base.not_the_topmost_popup protocol error will be sent.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
@ -1167,10 +1265,6 @@
|
||||
nested grabbing popup as well. When a compositor dismisses popups, it
|
||||
will follow the same dismissing order as required from the client.
|
||||
|
||||
The parent of a grabbing popup must either be another xdg_popup with an
|
||||
active explicit grab, or an xdg_popup or xdg_toplevel, if there are no
|
||||
explicit grabs already taken.
|
||||
|
||||
If the topmost grabbing popup is destroyed, the grab will be returned to
|
||||
the parent of the popup, if that parent previously had an explicit grab.
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2017 Eurogiciel, author: <philippe.coval@eurogiciel.fr>
|
||||
// Copyright (C) 2023 David Edmundson <davidedmundson@kde.org>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#include "qwaylandxdgshell_p.h"
|
||||
@ -87,10 +88,11 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
|
||||
}
|
||||
}
|
||||
|
||||
m_applied = m_pending;
|
||||
|
||||
if (!surfaceSize.isEmpty())
|
||||
m_xdgSurface->m_window->resizeFromApplyConfigure(surfaceSize.grownBy(m_xdgSurface->m_window->windowContentMargins()));
|
||||
|
||||
m_applied = m_pending;
|
||||
qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states;
|
||||
}
|
||||
|
||||
@ -115,6 +117,7 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t
|
||||
auto *xdgStates = static_cast<uint32_t *>(states->data);
|
||||
size_t numStates = states->size / sizeof(uint32_t);
|
||||
|
||||
m_pending.suspended = false;
|
||||
m_pending.states = Qt::WindowNoState;
|
||||
m_toplevelStates = QWaylandWindow::WindowNoState;
|
||||
|
||||
@ -141,6 +144,9 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t
|
||||
case XDG_TOPLEVEL_STATE_TILED_BOTTOM:
|
||||
m_toplevelStates |= QWaylandWindow::WindowTiledBottom;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_SUSPENDED:
|
||||
m_pending.suspended = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -359,6 +365,9 @@ void QWaylandXdgSurface::setWindowFlags(Qt::WindowFlags flags)
|
||||
|
||||
bool QWaylandXdgSurface::isExposed() const
|
||||
{
|
||||
if (m_toplevel && m_toplevel->m_applied.suspended)
|
||||
return false;
|
||||
|
||||
return m_configured || m_pendingConfigureSerial;
|
||||
}
|
||||
|
||||
@ -606,8 +615,8 @@ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
|
||||
if (!m_configured) {
|
||||
// We have to do the initial applyConfigure() immediately, since that is the expose.
|
||||
applyConfigure();
|
||||
QRegion exposeRegion = QRegion(QRect(QPoint(), m_window->geometry().size()));
|
||||
m_window->handleExpose(exposeRegion);
|
||||
if (isExposed())
|
||||
m_window->handleExpose(QRect(QPoint(), m_window->geometry().size()));
|
||||
} else {
|
||||
// Later configures are probably resizes, so we have to queue them up for a time when we
|
||||
// are not painting to the window.
|
||||
|
@ -101,6 +101,7 @@ private:
|
||||
QSize bounds = {0, 0};
|
||||
QSize size = {0, 0};
|
||||
Qt::WindowStates states = Qt::WindowNoState;
|
||||
bool suspended = false;
|
||||
} m_pending, m_applied;
|
||||
QWaylandWindow::ToplevelWindowTilingStates m_toplevelStates = QWaylandWindow::WindowNoState;
|
||||
QSize m_normalSize;
|
||||
|
@ -12,7 +12,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
QWaylandXdgShellIntegration::QWaylandXdgShellIntegration() : QWaylandShellIntegrationTemplate(4)
|
||||
QWaylandXdgShellIntegration::QWaylandXdgShellIntegration() : QWaylandShellIntegrationTemplate(6)
|
||||
{
|
||||
connect(this, &QWaylandShellIntegrationTemplate::activeChanged, this, [this] {
|
||||
if (isActive()) {
|
||||
|
@ -636,7 +636,7 @@ void QWaylandWindow::doApplyConfigureFromOtherThread()
|
||||
if (!mCanResize || !mWaitingToApplyConfigure)
|
||||
return;
|
||||
doApplyConfigure();
|
||||
sendExposeEvent(QRect(QPoint(), geometry().size()));
|
||||
sendRecursiveExposeEvent();
|
||||
}
|
||||
|
||||
void QWaylandWindow::setCanResize(bool canResize)
|
||||
@ -652,7 +652,7 @@ void QWaylandWindow::setCanResize(bool canResize)
|
||||
bool inGuiThread = QThread::currentThreadId() == QThreadData::get2(thread())->threadId.loadRelaxed();
|
||||
if (inGuiThread) {
|
||||
doApplyConfigure();
|
||||
sendExposeEvent(QRect(QPoint(), geometry().size()));
|
||||
sendRecursiveExposeEvent();
|
||||
} else {
|
||||
QMetaObject::invokeMethod(this, &QWaylandWindow::doApplyConfigureFromOtherThread, Qt::QueuedConnection);
|
||||
}
|
||||
@ -677,9 +677,10 @@ void QWaylandWindow::applyConfigure()
|
||||
|
||||
void QWaylandWindow::sendRecursiveExposeEvent()
|
||||
{
|
||||
if (!window()->isVisible())
|
||||
return;
|
||||
sendExposeEvent(QRect(QPoint(), geometry().size()));
|
||||
if (!isExposed())
|
||||
sendExposeEvent(QRect());
|
||||
else
|
||||
sendExposeEvent(QRect(QPoint(), geometry().size()));
|
||||
|
||||
for (QWaylandSubSurface *subSurface : std::as_const(mChildren)) {
|
||||
auto subWindow = subSurface->window();
|
||||
@ -745,7 +746,7 @@ void QWaylandWindow::safeCommit(QWaylandBuffer *buffer, const QRegion &damage)
|
||||
void QWaylandWindow::handleExpose(const QRegion ®ion)
|
||||
{
|
||||
QWindowSystemInterface::handleExposeEvent(window(), region);
|
||||
if (mQueuedBuffer) {
|
||||
if (mQueuedBuffer && !region.isEmpty()) {
|
||||
commit(mQueuedBuffer, mQueuedBufferDamage);
|
||||
mQueuedBuffer = nullptr;
|
||||
mQueuedBufferDamage = QRegion();
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright (C) 2018 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 David Edmundson <davidedmundson@kde.org>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "mockcompositor.h"
|
||||
@ -30,6 +31,8 @@ private slots:
|
||||
void windowGeometry();
|
||||
void foreignSurface();
|
||||
void nativeResources();
|
||||
void suspended();
|
||||
void initiallySuspended();
|
||||
};
|
||||
|
||||
void tst_xdgshell::init()
|
||||
@ -695,5 +698,35 @@ void tst_xdgshell::nativeResources()
|
||||
QCOMPARE(xdg_popup_proxy, nullptr);
|
||||
}
|
||||
|
||||
void tst_xdgshell::suspended()
|
||||
{
|
||||
QRasterWindow window;
|
||||
window.resize(400, 320);
|
||||
window.show();
|
||||
QVERIFY(!window.isExposed()); // not exposed until we're configured
|
||||
QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
|
||||
|
||||
exec([=] { xdgToplevel()->sendCompleteConfigure(); });
|
||||
QCOMPOSITOR_TRY_VERIFY(xdgToplevel()->m_xdgSurface->m_committedConfigureSerial);
|
||||
QTRY_VERIFY(window.isExposed());
|
||||
|
||||
exec([=] { xdgToplevel()->sendCompleteConfigure(QSize(), {XdgToplevel::state_suspended}); });
|
||||
QTRY_VERIFY(!window.isExposed());
|
||||
|
||||
exec([=] { xdgToplevel()->sendCompleteConfigure(QSize(), {}); });
|
||||
QTRY_VERIFY(window.isExposed());
|
||||
}
|
||||
|
||||
void tst_xdgshell::initiallySuspended()
|
||||
{
|
||||
QRasterWindow window;
|
||||
window.resize(400, 320);
|
||||
window.show();
|
||||
QVERIFY(!window.isExposed());
|
||||
QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
|
||||
exec([=] { xdgToplevel()->sendCompleteConfigure(QSize(), {XdgToplevel::state_suspended}); });
|
||||
QVERIFY(!window.isExposed());
|
||||
}
|
||||
|
||||
QCOMPOSITOR_TEST_MAIN(tst_xdgshell)
|
||||
#include "tst_xdgshell.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user