client: Implement dialog-v1 protocol
Allows to mark windows as modal dialogs. Change-Id: Ie4999552933e02fc473e621e7cc5e3f2928c0adb Reviewed-by: Vlad Zahorodnii <vlad.zahorodnii@kde.org> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
298c81ef7d
commit
de0be2b5dc
@ -336,5 +336,22 @@
|
|||||||
"License": "MIT License",
|
"License": "MIT License",
|
||||||
"LicenseFile": "MIT_LICENSE.txt",
|
"LicenseFile": "MIT_LICENSE.txt",
|
||||||
"Copyright": "Copyright © 2022 Kenny Levinsen"
|
"Copyright": "Copyright © 2022 Kenny Levinsen"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Id": "xdg-dialog-v1",
|
||||||
|
"Name": "Wayland Dialog Protocol",
|
||||||
|
"QDocModule": "qtwaylandcompositor",
|
||||||
|
"QtUsage": "Used in the Qt Wayland platform plugin",
|
||||||
|
"Files": "xdg-dialog-v1.xml",
|
||||||
|
|
||||||
|
"Description": "Register toplevel as dialogs",
|
||||||
|
"Homepage": "https://wayland.freedesktop.org",
|
||||||
|
"Version": "1",
|
||||||
|
"DownloadLocation": "",
|
||||||
|
"LicenseId": "MIT",
|
||||||
|
"License": "MIT License",
|
||||||
|
"LicenseFile": "MIT_LICENSE.txt",
|
||||||
|
"Copyright": "Copyright © 2023 Carlos Garnacho"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
110
src/3rdparty/wayland/protocols/xdg-dialog-v1.xml
vendored
Normal file
110
src/3rdparty/wayland/protocols/xdg-dialog-v1.xml
vendored
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="dialog_v1">
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2023 Carlos Garnacho
|
||||||
|
|
||||||
|
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="xdg_wm_dialog_v1" version="1">
|
||||||
|
<description summary="create dialogs related to other toplevels">
|
||||||
|
The xdg_wm_dialog_v1 interface is exposed as a global object allowing
|
||||||
|
to register surfaces with a xdg_toplevel role as "dialogs" relative to
|
||||||
|
another toplevel.
|
||||||
|
|
||||||
|
The compositor may let this relation influence how the surface is
|
||||||
|
placed, displayed or interacted with.
|
||||||
|
|
||||||
|
Warning! The protocol described in this file is currently in the testing
|
||||||
|
phase. Backward compatible changes may be added together with the
|
||||||
|
corresponding interface version bump. Backward incompatible changes can
|
||||||
|
only be done by creating a new major version of the extension.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="already_used" value="0"
|
||||||
|
summary="the xdg_toplevel object has already been used to create a xdg_dialog_v1"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the dialog manager object">
|
||||||
|
Destroys the xdg_wm_dialog_v1 object. This does not affect
|
||||||
|
the xdg_dialog_v1 objects generated through it.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="get_xdg_dialog">
|
||||||
|
<description summary="create a dialog object">
|
||||||
|
Creates a xdg_dialog_v1 object for the given toplevel. See the interface
|
||||||
|
description for more details.
|
||||||
|
|
||||||
|
Compositors must raise an already_used error if clients attempt to
|
||||||
|
create multiple xdg_dialog_v1 objects for the same xdg_toplevel.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="xdg_dialog_v1"/>
|
||||||
|
<arg name="toplevel" type="object" interface="xdg_toplevel"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="xdg_dialog_v1" version="1">
|
||||||
|
<description summary="dialog object">
|
||||||
|
A xdg_dialog_v1 object is an ancillary object tied to a xdg_toplevel. Its
|
||||||
|
purpose is hinting the compositor that the toplevel is a "dialog" (e.g. a
|
||||||
|
temporary window) relative to another toplevel (see
|
||||||
|
xdg_toplevel.set_parent). If the xdg_toplevel is destroyed, the xdg_dialog_v1
|
||||||
|
becomes inert.
|
||||||
|
|
||||||
|
Through this object, the client may provide additional hints about
|
||||||
|
the purpose of the secondary toplevel. This interface has no effect
|
||||||
|
on toplevels that are not attached to a parent toplevel.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the dialog object">
|
||||||
|
Destroys the xdg_dialog_v1 object. If this object is destroyed
|
||||||
|
before the related xdg_toplevel, the compositor should unapply its
|
||||||
|
effects.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_modal">
|
||||||
|
<description summary="mark dialog as modal">
|
||||||
|
Hints that the dialog has "modal" behavior. Modal dialogs typically
|
||||||
|
require to be fully addressed by the user (i.e. closed) before resuming
|
||||||
|
interaction with the parent toplevel, and may require a distinct
|
||||||
|
presentation.
|
||||||
|
|
||||||
|
Clients must implement the logic to filter events in the parent
|
||||||
|
toplevel on their own.
|
||||||
|
|
||||||
|
Compositors may choose any policy in event delivery to the parent
|
||||||
|
toplevel, from delivering all events unfiltered to using them for
|
||||||
|
internal consumption.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="unset_modal">
|
||||||
|
<description summary="mark dialog as not modal">
|
||||||
|
Drops the hint that this dialog has "modal" behavior. See
|
||||||
|
xdg_dialog_v1.set_modal for more details.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
@ -17,6 +17,7 @@ qt_internal_add_plugin(QWaylandXdgShellIntegrationPlugin
|
|||||||
qwaylandxdgshell.cpp qwaylandxdgshell_p.h
|
qwaylandxdgshell.cpp qwaylandxdgshell_p.h
|
||||||
qwaylandxdgshellintegration.cpp qwaylandxdgshellintegration_p.h
|
qwaylandxdgshellintegration.cpp qwaylandxdgshellintegration_p.h
|
||||||
qwaylandxdgexporterv2.cpp qwaylandxdgexporterv2_p.h
|
qwaylandxdgexporterv2.cpp qwaylandxdgexporterv2_p.h
|
||||||
|
qwaylandxdgdialogv1.cpp qwaylandxdgdialogv1_p.h
|
||||||
LIBRARIES
|
LIBRARIES
|
||||||
Qt::Core
|
Qt::Core
|
||||||
Qt::Gui
|
Qt::Gui
|
||||||
@ -31,6 +32,7 @@ qt6_generate_wayland_protocol_client_sources(QWaylandXdgShellIntegrationPlugin
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/protocol/xdg-shell.xml
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/protocol/xdg-shell.xml
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/protocol/xdg-activation-v1.xml
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/protocol/xdg-activation-v1.xml
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/protocol/xdg-foreign-unstable-v2.xml
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/protocol/xdg-foreign-unstable-v2.xml
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/protocol/xdg-dialog-v1.xml
|
||||||
)
|
)
|
||||||
|
|
||||||
#### Keys ignored in scope 1:.:.:xdg-shell.pro:<TRUE>:
|
#### Keys ignored in scope 1:.:.:xdg-shell.pro:<TRUE>:
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (C) 2023 David Reondo <kde@david-redondo.de>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||||
|
|
||||||
|
#include "qwaylandxdgdialogv1_p.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace QtWaylandClient {
|
||||||
|
|
||||||
|
QWaylandXdgDialogV1::QWaylandXdgDialogV1(::xdg_dialog_v1 *object) : xdg_dialog_v1(object) { }
|
||||||
|
|
||||||
|
QWaylandXdgDialogV1::~QWaylandXdgDialogV1()
|
||||||
|
{
|
||||||
|
xdg_dialog_v1_destroy(object());
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandXdgDialogWmV1::QWaylandXdgDialogWmV1(wl_registry *registry, uint32_t id, int version)
|
||||||
|
: xdg_wm_dialog_v1(registry, id, version)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandXdgDialogWmV1::~QWaylandXdgDialogWmV1()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
QWaylandXdgDialogV1 *QWaylandXdgDialogWmV1::getDialog(xdg_toplevel *toplevel)
|
||||||
|
{
|
||||||
|
return new QWaylandXdgDialogV1(get_xdg_dialog(toplevel));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QtWaylandClient
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (C) 2022 David Reondo <kde@david-redondo.de>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||||
|
|
||||||
|
#ifndef QWAYLANDDIALOGV1_P_H
|
||||||
|
#define QWAYLANDDIALOGV1_P_H
|
||||||
|
|
||||||
|
#include <qwayland-xdg-dialog-v1.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace QtWaylandClient {
|
||||||
|
|
||||||
|
class QWaylandXdgDialogV1 : public QtWayland::xdg_dialog_v1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QWaylandXdgDialogV1(::xdg_dialog_v1 *object);
|
||||||
|
~QWaylandXdgDialogV1() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QWaylandXdgDialogWmV1 : public QtWayland::xdg_wm_dialog_v1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QWaylandXdgDialogWmV1(wl_registry *registry, uint32_t id, int version);
|
||||||
|
~QWaylandXdgDialogWmV1() override;
|
||||||
|
QWaylandXdgDialogV1 *getDialog(xdg_toplevel *toplevel);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QtWaylandClient
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif
|
@ -6,6 +6,7 @@
|
|||||||
#include "qwaylandxdgshell_p.h"
|
#include "qwaylandxdgshell_p.h"
|
||||||
|
|
||||||
#include "qwaylandxdgexporterv2_p.h"
|
#include "qwaylandxdgexporterv2_p.h"
|
||||||
|
#include "qwaylandxdgdialogv1_p.h"
|
||||||
|
|
||||||
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
|
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
|
||||||
#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
||||||
@ -32,6 +33,16 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
|
|||||||
}
|
}
|
||||||
requestWindowStates(window->windowStates());
|
requestWindowStates(window->windowStates());
|
||||||
requestWindowFlags(window->flags());
|
requestWindowFlags(window->flags());
|
||||||
|
if (auto transientParent = xdgSurface->window()->transientParent()) {
|
||||||
|
if (auto parentSurface =
|
||||||
|
qobject_cast<QWaylandXdgSurface *>(transientParent->shellSurface())) {
|
||||||
|
set_parent(parentSurface->m_toplevel->object());
|
||||||
|
if (window->modality() != Qt::NonModal && m_xdgSurface->m_shell->m_xdgDialogWm) {
|
||||||
|
m_xdgDialog.reset(m_xdgSurface->m_shell->m_xdgDialogWm->getDialog(object()));
|
||||||
|
m_xdgDialog->set_modal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QWaylandXdgSurface::Toplevel::~Toplevel()
|
QWaylandXdgSurface::Toplevel::~Toplevel()
|
||||||
@ -296,11 +307,6 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
|
|||||||
setGrabPopup(transientParent, display->lastInputDevice(), display->lastInputSerial());
|
setGrabPopup(transientParent, display->lastInputDevice(), display->lastInputSerial());
|
||||||
} else {
|
} else {
|
||||||
setToplevel();
|
setToplevel();
|
||||||
if (transientParent) {
|
|
||||||
auto parentXdgSurface = qobject_cast<QWaylandXdgSurface *>(transientParent->shellSurface());
|
|
||||||
if (parentXdgSurface)
|
|
||||||
m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setSizeHints();
|
setSizeHints();
|
||||||
}
|
}
|
||||||
@ -752,6 +758,10 @@ void QWaylandXdgShell::handleRegistryGlobal(void *data, wl_registry *registry, u
|
|||||||
if (interface == QLatin1String(QWaylandXdgExporterV2::interface()->name)) {
|
if (interface == QLatin1String(QWaylandXdgExporterV2::interface()->name)) {
|
||||||
xdgShell->m_xdgExporter.reset(new QWaylandXdgExporterV2(registry, id, version));
|
xdgShell->m_xdgExporter.reset(new QWaylandXdgExporterV2(registry, id, version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (interface == QLatin1String(QWaylandXdgDialogWmV1::interface()->name)) {
|
||||||
|
xdgShell->m_xdgDialogWm.reset(new QWaylandXdgDialogWmV1(registry, id, version));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ class QWaylandInputDevice;
|
|||||||
class QWaylandXdgShell;
|
class QWaylandXdgShell;
|
||||||
class QWaylandXdgExportedV2;
|
class QWaylandXdgExportedV2;
|
||||||
class QWaylandXdgExporterV2;
|
class QWaylandXdgExporterV2;
|
||||||
|
class QWaylandXdgDialogWmV1;
|
||||||
|
class QWaylandXdgDialogV1;
|
||||||
|
|
||||||
class Q_WAYLANDCLIENT_EXPORT QWaylandXdgSurface : public QWaylandShellSurface, public QtWayland::xdg_surface
|
class Q_WAYLANDCLIENT_EXPORT QWaylandXdgSurface : public QWaylandShellSurface, public QtWayland::xdg_surface
|
||||||
{
|
{
|
||||||
@ -109,6 +111,7 @@ private:
|
|||||||
QWaylandXdgSurface *m_xdgSurface = nullptr;
|
QWaylandXdgSurface *m_xdgSurface = nullptr;
|
||||||
QWaylandXdgToplevelDecorationV1 *m_decoration = nullptr;
|
QWaylandXdgToplevelDecorationV1 *m_decoration = nullptr;
|
||||||
QScopedPointer<QWaylandXdgExportedV2> m_exported;
|
QScopedPointer<QWaylandXdgExportedV2> m_exported;
|
||||||
|
QScopedPointer<QWaylandXdgDialogV1> m_xdgDialog;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Popup : public QtWayland::xdg_popup {
|
class Popup : public QtWayland::xdg_popup {
|
||||||
@ -171,6 +174,7 @@ private:
|
|||||||
QScopedPointer<QWaylandXdgDecorationManagerV1> m_xdgDecorationManager;
|
QScopedPointer<QWaylandXdgDecorationManagerV1> m_xdgDecorationManager;
|
||||||
QScopedPointer<QWaylandXdgActivationV1> m_xdgActivation;
|
QScopedPointer<QWaylandXdgActivationV1> m_xdgActivation;
|
||||||
QScopedPointer<QWaylandXdgExporterV2> m_xdgExporter;
|
QScopedPointer<QWaylandXdgExporterV2> m_xdgExporter;
|
||||||
|
QScopedPointer<QWaylandXdgDialogWmV1> m_xdgDialogWm;
|
||||||
|
|
||||||
friend class QWaylandXdgSurface;
|
friend class QWaylandXdgSurface;
|
||||||
};
|
};
|
||||||
|
@ -16,6 +16,7 @@ qt_manual_moc(moc_files
|
|||||||
textinput.h
|
textinput.h
|
||||||
qttextinput.h
|
qttextinput.h
|
||||||
viewport.h
|
viewport.h
|
||||||
|
xdgdialog.h
|
||||||
xdgoutputv1.h
|
xdgoutputv1.h
|
||||||
xdgshell.h
|
xdgshell.h
|
||||||
)
|
)
|
||||||
@ -33,6 +34,7 @@ add_library(SharedClientTest
|
|||||||
qttextinput.cpp qttextinput.h
|
qttextinput.cpp qttextinput.h
|
||||||
xdgoutputv1.cpp xdgoutputv1.h
|
xdgoutputv1.cpp xdgoutputv1.h
|
||||||
xdgshell.cpp xdgshell.h
|
xdgshell.cpp xdgshell.h
|
||||||
|
xdgdialog.cpp xdgdialog.h
|
||||||
viewport.cpp viewport.h
|
viewport.cpp viewport.h
|
||||||
${moc_files}
|
${moc_files}
|
||||||
)
|
)
|
||||||
@ -50,6 +52,7 @@ qt6_generate_wayland_protocol_server_sources(SharedClientTest
|
|||||||
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/viewporter.xml
|
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/viewporter.xml
|
||||||
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/wayland.xml
|
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/wayland.xml
|
||||||
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/xdg-decoration-unstable-v1.xml
|
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/xdg-decoration-unstable-v1.xml
|
||||||
|
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/xdg-dialog-v1.xml
|
||||||
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/xdg-output-unstable-v1.xml
|
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/xdg-output-unstable-v1.xml
|
||||||
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/xdg-shell.xml
|
${PROJECT_SOURCE_DIR}/src/3rdparty/protocol/xdg-shell.xml
|
||||||
)
|
)
|
||||||
|
@ -23,6 +23,7 @@ DefaultCompositor::DefaultCompositor(CompositorType t, int socketFd)
|
|||||||
add<XdgWmBase>();
|
add<XdgWmBase>();
|
||||||
add<FractionalScaleManager>();
|
add<FractionalScaleManager>();
|
||||||
add<Viewporter>();
|
add<Viewporter>();
|
||||||
|
add<XdgWmDialog>();
|
||||||
|
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case CompositorType::Default:
|
case CompositorType::Default:
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "xdgshell.h"
|
#include "xdgshell.h"
|
||||||
#include "viewport.h"
|
#include "viewport.h"
|
||||||
#include "fractionalscalev1.h"
|
#include "fractionalscalev1.h"
|
||||||
|
#include "xdgdialog.h"
|
||||||
|
|
||||||
#include <QtGui/QGuiApplication>
|
#include <QtGui/QGuiApplication>
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ public:
|
|||||||
IviSurface *iviSurface(int i = 0) { return get<IviApplication>()->m_iviSurfaces.value(i, nullptr); }
|
IviSurface *iviSurface(int i = 0) { return get<IviApplication>()->m_iviSurfaces.value(i, nullptr); }
|
||||||
FractionalScale *fractionalScale(int i = 0) {return get<FractionalScaleManager>()->m_fractionalScales.value(i, nullptr); }
|
FractionalScale *fractionalScale(int i = 0) {return get<FractionalScaleManager>()->m_fractionalScales.value(i, nullptr); }
|
||||||
Viewport *viewport(int i = 0) {return get<Viewporter>()->m_viewports.value(i, nullptr); }
|
Viewport *viewport(int i = 0) {return get<Viewporter>()->m_viewports.value(i, nullptr); }
|
||||||
|
XdgDialog *xdgDialog(int i = 0) { return get<XdgWmDialog>()->m_dialogs.value(i, nullptr); }
|
||||||
|
|
||||||
uint sendXdgShellPing();
|
uint sendXdgShellPing();
|
||||||
void xdgPingAndWaitForPong();
|
void xdgPingAndWaitForPong();
|
||||||
|
59
tests/auto/wayland/shared/xdgdialog.cpp
Normal file
59
tests/auto/wayland/shared/xdgdialog.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (C) 2024 David Redondo <kde@david-redondo.de>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
#include "xdgdialog.h"
|
||||||
|
|
||||||
|
#include "xdgshell.h"
|
||||||
|
|
||||||
|
namespace MockCompositor {
|
||||||
|
|
||||||
|
XdgDialog::XdgDialog(XdgWmDialog *wm, XdgToplevel *toplevel, wl_client *client, int id, int version)
|
||||||
|
: QtWaylandServer::xdg_dialog_v1(client, id, version),
|
||||||
|
toplevel(toplevel),
|
||||||
|
modal(false),
|
||||||
|
m_wm(wm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgDialog::xdg_dialog_v1_set_modal(Resource *resource)
|
||||||
|
{
|
||||||
|
Q_UNUSED(resource)
|
||||||
|
modal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgDialog::xdg_dialog_v1_unset_modal(Resource *resource)
|
||||||
|
{
|
||||||
|
Q_UNUSED(resource)
|
||||||
|
modal = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgDialog::xdg_dialog_v1_destroy(Resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy(resource->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgDialog::xdg_dialog_v1_destroy_resource(Resource *resource)
|
||||||
|
{
|
||||||
|
Q_UNUSED(resource)
|
||||||
|
m_wm->m_dialogs.removeOne(this);
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
XdgWmDialog::XdgWmDialog(CoreCompositor *compositor, int version)
|
||||||
|
: QtWaylandServer::xdg_wm_dialog_v1(compositor->m_display, version)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgWmDialog::xdg_wm_dialog_v1_destroy(Resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy(resource->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgWmDialog::xdg_wm_dialog_v1_get_xdg_dialog(Resource *resource, uint32_t id,
|
||||||
|
struct ::wl_resource *toplevel)
|
||||||
|
{
|
||||||
|
auto *t = fromResource<XdgToplevel>(toplevel);
|
||||||
|
auto *dialog = new XdgDialog(this, t, resource->client(), id, resource->version());
|
||||||
|
m_dialogs.push_back(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace MockCompositor
|
49
tests/auto/wayland/shared/xdgdialog.h
Normal file
49
tests/auto/wayland/shared/xdgdialog.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright (C) 2024 David Redondo <kde@david-redondo.de>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#ifndef MOCKCOMPOSITOR_XDG_DIALOG_H
|
||||||
|
#define MOCKCOMPOSITOR_XDG_DIALOG_H
|
||||||
|
|
||||||
|
#include "corecompositor.h"
|
||||||
|
#include <qwayland-server-xdg-dialog-v1.h>
|
||||||
|
|
||||||
|
namespace MockCompositor {
|
||||||
|
|
||||||
|
class XdgToplevel;
|
||||||
|
class XdgWmDialog;
|
||||||
|
|
||||||
|
class XdgDialog : public QtWaylandServer::xdg_dialog_v1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit XdgDialog(XdgWmDialog *wm, XdgToplevel *toplevel, wl_client *client, int id,
|
||||||
|
int version);
|
||||||
|
XdgToplevel *toplevel;
|
||||||
|
bool modal;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void xdg_dialog_v1_set_modal(Resource *resource) override;
|
||||||
|
void xdg_dialog_v1_unset_modal(Resource *resource) override;
|
||||||
|
void xdg_dialog_v1_destroy(Resource *resource) override;
|
||||||
|
void xdg_dialog_v1_destroy_resource(Resource *resource) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
XdgWmDialog *m_wm;
|
||||||
|
};
|
||||||
|
|
||||||
|
class XdgWmDialog : public Global, public QtWaylandServer::xdg_wm_dialog_v1
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit XdgWmDialog(CoreCompositor *compositor, int version = 1);
|
||||||
|
~XdgWmDialog() = default;
|
||||||
|
QList<XdgDialog *> m_dialogs;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void xdg_wm_dialog_v1_destroy(Resource *resource) override;
|
||||||
|
void xdg_wm_dialog_v1_get_xdg_dialog(Resource *resource, uint32_t id,
|
||||||
|
struct ::wl_resource *toplevel) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace MockCompositor
|
||||||
|
|
||||||
|
#endif
|
@ -34,6 +34,7 @@ private slots:
|
|||||||
void nativeResources();
|
void nativeResources();
|
||||||
void suspended();
|
void suspended();
|
||||||
void initiallySuspended();
|
void initiallySuspended();
|
||||||
|
void modality();
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_xdgshell::init()
|
void tst_xdgshell::init()
|
||||||
@ -769,5 +770,40 @@ void tst_xdgshell::initiallySuspended()
|
|||||||
QVERIFY(!window.isExposed());
|
QVERIFY(!window.isExposed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_xdgshell::modality()
|
||||||
|
{
|
||||||
|
QRasterWindow parent;
|
||||||
|
parent.resize(400, 320);
|
||||||
|
parent.show();
|
||||||
|
|
||||||
|
QRasterWindow child;
|
||||||
|
child.resize(400, 320);
|
||||||
|
child.setTransientParent(&parent);
|
||||||
|
child.show();
|
||||||
|
QCOMPOSITOR_TRY_VERIFY(xdgToplevel(1));
|
||||||
|
QCOMPOSITOR_VERIFY(!xdgDialog());
|
||||||
|
|
||||||
|
child.hide();
|
||||||
|
child.setModality(Qt::WindowModal);
|
||||||
|
child.show();
|
||||||
|
QCOMPOSITOR_TRY_VERIFY(xdgDialog());
|
||||||
|
QCOMPOSITOR_VERIFY(xdgDialog()->modal);
|
||||||
|
|
||||||
|
child.hide();
|
||||||
|
QCOMPOSITOR_TRY_VERIFY(!xdgDialog());
|
||||||
|
|
||||||
|
child.setModality(Qt::ApplicationModal);
|
||||||
|
child.show();
|
||||||
|
QCOMPOSITOR_TRY_VERIFY(xdgDialog());
|
||||||
|
QCOMPOSITOR_VERIFY(xdgDialog()->modal);
|
||||||
|
|
||||||
|
child.hide();
|
||||||
|
QCOMPOSITOR_TRY_VERIFY(!xdgDialog());
|
||||||
|
|
||||||
|
child.show();
|
||||||
|
child.setModality(Qt::NonModal);
|
||||||
|
QCOMPOSITOR_TRY_VERIFY(!xdgDialog());
|
||||||
|
}
|
||||||
|
|
||||||
QCOMPOSITOR_TEST_MAIN(tst_xdgshell)
|
QCOMPOSITOR_TEST_MAIN(tst_xdgshell)
|
||||||
#include "tst_xdgshell.moc"
|
#include "tst_xdgshell.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user