qt5-quickcontrols2 ,svg,wayland,translations rebuild

This commit is contained in:
Rmys
2022-08-25 11:48:33 +03:00
parent 67378ef76e
commit da9a063b36
7 changed files with 619 additions and 43 deletions
@@ -491,7 +491,7 @@ index 25afff79..96f07bc3 100644
}
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index f10c1f79..86045a35 100644
index f10c1f79..e8613ed8 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -85,10 +85,203 @@
@@ -722,10 +722,15 @@ index f10c1f79..86045a35 100644
if (mSyncCallback)
wl_callback_destroy(mSyncCallback);
@@ -189,6 +381,18 @@ QWaylandDisplay::~QWaylandDisplay(void)
@@ -187,6 +379,21 @@ QWaylandDisplay::~QWaylandDisplay(void)
#endif
if (mDisplay)
wl_display_disconnect(mDisplay);
}
+
+ if (m_frameEventQueue)
+ wl_event_queue_destroy(m_frameEventQueue);
+}
+
+// Steps which is called just after constructor. This separates registry_global() out of the constructor
+// so that factory functions in integration can be overridden.
+void QWaylandDisplay::initialize()
@@ -736,12 +741,10 @@ index f10c1f79..86045a35 100644
+ // Give wl_output.done and zxdg_output_v1.done events a chance to arrive
+ forceRoundTrip();
+ }
+}
+
}
void QWaylandDisplay::ensureScreen()
{
if (!mScreens.empty() || mPlaceholderScreen)
@@ -203,98 +407,37 @@ void QWaylandDisplay::ensureScreen()
@@ -203,98 +410,37 @@ void QWaylandDisplay::ensureScreen()
void QWaylandDisplay::checkError() const
{
@@ -860,7 +863,7 @@ index f10c1f79..86045a35 100644
}
QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const
@@ -345,7 +488,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
@@ -345,7 +491,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
if (interface == QStringLiteral("wl_output")) {
mWaitingScreens << new QWaylandScreen(this, version, id);
} else if (interface == QStringLiteral("wl_compositor")) {
@@ -869,7 +872,7 @@ index f10c1f79..86045a35 100644
mCompositor.init(registry, id, mCompositorVersion);
} else if (interface == QStringLiteral("wl_shm")) {
mShm.reset(new QWaylandShm(this, version, id));
@@ -354,7 +497,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
@@ -354,7 +500,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
mInputDevices.append(inputDevice);
#if QT_CONFIG(wayland_datadevice)
} else if (interface == QStringLiteral("wl_data_device_manager")) {
@@ -878,7 +881,7 @@ index f10c1f79..86045a35 100644
#endif
} else if (interface == QStringLiteral("qt_surface_extension")) {
mWindowExtension.reset(new QtWayland::qt_surface_extension(registry, id, 1));
@@ -452,9 +595,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
@@ -452,9 +598,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
void QWaylandDisplay::removeListener(RegistryListener listener, void *data)
{
@@ -890,7 +893,7 @@ index f10c1f79..86045a35 100644
}
uint32_t QWaylandDisplay::currentTimeMillisec()
@@ -467,50 +611,9 @@ uint32_t QWaylandDisplay::currentTimeMillisec()
@@ -467,50 +614,9 @@ uint32_t QWaylandDisplay::currentTimeMillisec()
return 0;
}
@@ -942,7 +945,7 @@ index f10c1f79..86045a35 100644
}
bool QWaylandDisplay::supportsWindowDecoration() const
@@ -574,14 +677,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
@@ -574,14 +680,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
if (mLastKeyboardFocus == keyboardFocus)
return;
@@ -961,7 +964,7 @@ index f10c1f79..86045a35 100644
mLastKeyboardFocus = keyboardFocus;
}
@@ -600,6 +699,19 @@ void QWaylandDisplay::handleWaylandSync()
@@ -600,6 +702,19 @@ void QWaylandDisplay::handleWaylandSync()
QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window();
if (activeWindow != QGuiApplication::focusWindow())
QWindowSystemInterface::handleWindowActivated(activeWindow);
@@ -981,7 +984,7 @@ index f10c1f79..86045a35 100644
}
const wl_callback_listener QWaylandDisplay::syncCallbackListener = {
@@ -626,6 +738,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
@@ -626,6 +741,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
}
@@ -995,7 +998,7 @@ index f10c1f79..86045a35 100644
#if QT_CONFIG(cursor)
QWaylandCursor *QWaylandDisplay::waylandCursor()
@@ -652,4 +771,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p
@@ -652,4 +774,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p
} // namespace QtWaylandClient
@@ -1402,7 +1405,7 @@ index df1c94f2..050cfdc0 100644
#if QT_CONFIG(cursor)
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index e96d8fe9..ceaa4c73 100644
index e96d8fe9..c90a0ebf 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -76,7 +76,6 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = nullptr;
@@ -1423,7 +1426,15 @@ index e96d8fe9..ceaa4c73 100644
delete mWindowDecoration;
if (mSurface)
@@ -266,6 +262,8 @@ void QWaylandWindow::reset()
@@ -243,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const
void QWaylandWindow::reset()
{
+ closeChildPopups();
delete mShellSurface;
mShellSurface = nullptr;
delete mSubSurfaceWindow;
@@ -266,6 +263,8 @@ void QWaylandWindow::reset()
mMask = QRegion();
mQueuedBuffer = nullptr;
@@ -1432,7 +1443,7 @@ index e96d8fe9..ceaa4c73 100644
}
QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
@@ -374,7 +372,7 @@ void QWaylandWindow::setGeometry(const QRect &rect)
@@ -374,7 +373,7 @@ void QWaylandWindow::setGeometry(const QRect &rect)
mShellSurface->setWindowGeometry(windowContentGeometry());
if (isOpaque() && mMask.isEmpty())
@@ -1441,15 +1452,48 @@ index e96d8fe9..ceaa4c73 100644
}
void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset)
@@ -435,7 +433,6 @@ void QWaylandWindow::setVisible(bool visible)
if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip)
activePopups << this;
@@ -399,21 +398,6 @@ void QWaylandWindow::sendExposeEvent(const QRect &rect)
mLastExposeGeometry = rect;
}
-
-static QVector<QPointer<QWaylandWindow>> activePopups;
-
-void QWaylandWindow::closePopups(QWaylandWindow *parent)
-{
- while (!activePopups.isEmpty()) {
- auto popup = activePopups.takeLast();
- if (popup.isNull())
- continue;
- if (popup.data() == parent)
- return;
- popup->reset();
- }
-}
-
QPlatformScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const
{
if (mSurface) {
@@ -432,10 +416,7 @@ void QWaylandWindow::setVisible(bool visible)
lastVisible = visible;
if (visible) {
- if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip)
- activePopups << this;
initWindow();
- mDisplay->flushRequests();
setGeometry(windowGeometry());
// Don't flush the events here, or else the newly visible window may start drawing, but since
@@ -464,14 +461,15 @@ void QWaylandWindow::lower()
@@ -443,7 +424,6 @@ void QWaylandWindow::setVisible(bool visible)
// QWaylandShmBackingStore::beginPaint().
} else {
sendExposeEvent(QRect());
- closePopups(this);
reset();
}
}
@@ -464,14 +444,15 @@ void QWaylandWindow::lower()
void QWaylandWindow::setMask(const QRegion &mask)
{
@@ -1468,7 +1512,7 @@ index e96d8fe9..ceaa4c73 100644
if (mMask.isEmpty()) {
mSurface->set_input_region(nullptr);
@@ -554,8 +552,8 @@ void QWaylandWindow::sendRecursiveExposeEvent()
@@ -554,8 +535,8 @@ void QWaylandWindow::sendRecursiveExposeEvent()
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
{
@@ -1478,7 +1522,7 @@ index e96d8fe9..ceaa4c73 100644
handleUpdate();
buffer->setBusy();
@@ -573,7 +571,11 @@ void QWaylandWindow::attachOffset(QWaylandBuffer *buffer)
@@ -573,7 +554,11 @@ void QWaylandWindow::attachOffset(QWaylandBuffer *buffer)
void QWaylandWindow::damage(const QRect &rect)
{
@@ -1491,7 +1535,7 @@ index e96d8fe9..ceaa4c73 100644
}
void QWaylandWindow::safeCommit(QWaylandBuffer *buffer, const QRegion &damage)
@@ -607,8 +609,14 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage)
@@ -607,8 +592,14 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage)
return;
attachOffset(buffer);
@@ -1508,7 +1552,7 @@ index e96d8fe9..ceaa4c73 100644
Q_ASSERT(!buffer->committed());
buffer->setCommitted();
mSurface->commit();
@@ -621,42 +629,50 @@ void QWaylandWindow::commit()
@@ -621,42 +612,50 @@ void QWaylandWindow::commit()
const wl_callback_listener QWaylandWindow::callbackListener = {
[](void *data, wl_callback *callback, uint32_t time) {
@@ -1574,7 +1618,7 @@ index e96d8fe9..ceaa4c73 100644
if (mWaitingForFrameCallback) {
qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed";
@@ -805,7 +821,7 @@ bool QWaylandWindow::createDecoration()
@@ -805,7 +804,7 @@ bool QWaylandWindow::createDecoration()
decoration = false;
if (mSubSurfaceWindow)
decoration = false;
@@ -1583,7 +1627,7 @@ index e96d8fe9..ceaa4c73 100644
decoration = false;
bool hadDecoration = mWindowDecoration;
@@ -1078,10 +1094,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
@@ -1078,10 +1077,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
return true;
}
@@ -1603,7 +1647,7 @@ index e96d8fe9..ceaa4c73 100644
mLastReportedWindowStates = states;
}
@@ -1144,8 +1168,11 @@ void QWaylandWindow::requestUpdate()
@@ -1144,8 +1151,11 @@ void QWaylandWindow::requestUpdate()
Q_ASSERT(hasPendingUpdateRequest()); // should be set by QPA
// If we have a frame callback all is good and will be taken care of there
@@ -1617,7 +1661,7 @@ index e96d8fe9..ceaa4c73 100644
// If we've already called deliverUpdateRequest(), but haven't seen any attach+commit/swap yet
// This is a somewhat redundant behavior and might indicate a bug in the calling code, so log
@@ -1158,7 +1185,12 @@ void QWaylandWindow::requestUpdate()
@@ -1158,7 +1168,12 @@ void QWaylandWindow::requestUpdate()
// so use invokeMethod to delay the delivery a bit.
QMetaObject::invokeMethod(this, [this] {
// Things might have changed in the meantime
@@ -1631,7 +1675,7 @@ index e96d8fe9..ceaa4c73 100644
deliverUpdateRequest();
}, Qt::QueuedConnection);
}
@@ -1169,19 +1201,19 @@ void QWaylandWindow::requestUpdate()
@@ -1169,19 +1184,19 @@ void QWaylandWindow::requestUpdate()
void QWaylandWindow::handleUpdate()
{
qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
@@ -1657,7 +1701,7 @@ index e96d8fe9..ceaa4c73 100644
mFrameCallback = wl_surface_frame(wrappedSurface);
wl_proxy_wrapper_destroy(wrappedSurface);
wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this);
@@ -1191,6 +1223,8 @@ void QWaylandWindow::handleUpdate()
@@ -1191,6 +1206,8 @@ void QWaylandWindow::handleUpdate()
// Start a timer for handling the case when the compositor stops sending frame callbacks.
if (mFrameCallbackTimeout > 0) {
QMetaObject::invokeMethod(this, [this] {
@@ -1666,8 +1710,29 @@ index e96d8fe9..ceaa4c73 100644
if (mWaitingForFrameCallback) {
if (mFrameCallbackCheckIntervalTimerId < 0)
mFrameCallbackCheckIntervalTimerId = startTimer(mFrameCallbackTimeout);
@@ -1251,6 +1268,20 @@ void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea)
wl_region_destroy(region);
}
+void QWaylandWindow::addChildPopup(QWaylandWindow *surface) {
+ mChildPopups.append(surface);
+}
+
+void QWaylandWindow::removeChildPopup(QWaylandWindow *surface) {
+ mChildPopups.removeAll(surface);
+}
+
+void QWaylandWindow::closeChildPopups() {
+ while (!mChildPopups.isEmpty()) {
+ auto popup = mChildPopups.takeLast();
+ popup->reset();
+ }
+}
}
QT_END_NAMESPACE
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index 6cc1664b..cb9135f6 100644
index 6cc1664b..d211178a 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -148,6 +148,7 @@ public:
@@ -1678,7 +1743,18 @@ index 6cc1664b..cb9135f6 100644
void raise() override;
void lower() override;
@@ -227,11 +228,11 @@ protected:
@@ -206,6 +207,10 @@ public:
void handleUpdate();
void deliverUpdateRequest() override;
+ void addChildPopup(QWaylandWindow* child);
+ void removeChildPopup(QWaylandWindow* child);
+ void closeChildPopups();
+
public slots:
void applyConfigure();
@@ -227,11 +232,11 @@ protected:
WId mWindowId;
bool mWaitingForFrameCallback = false;
bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
@@ -1692,6 +1768,15 @@ index 6cc1664b..cb9135f6 100644
QWaitCondition mFrameSyncWait;
// True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
@@ -261,6 +266,8 @@ protected:
QWaylandBuffer *mQueuedBuffer = nullptr;
QRegion mQueuedBufferDamage;
+ QList<QPointer<QWaylandWindow>> mChildPopups;
+
private:
void setGeometry_helper(const QRect &rect);
void initWindow();
diff --git a/src/client/shellintegration/qwaylandshellintegration_p.h b/src/client/shellintegration/qwaylandshellintegration_p.h
index ccad0048..4cc9b3b8 100644
--- a/src/client/shellintegration/qwaylandshellintegration_p.h
@@ -1811,6 +1896,80 @@ index 5b1f4d56..0079dfef 100644
};
}
diff --git a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
index 56a710c3..c6a8b6c6 100644
--- a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+++ b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
@@ -41,6 +41,8 @@
#include <QtCore/QTextStream>
#include <QtGui/QOpenGLTexture>
+#include <array>
+
#include <EGL/egl.h>
#include <EGL/eglext.h>
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
index 85d25e3c..60bdd491 100644
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
@@ -47,18 +47,21 @@ QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
-QWaylandXdgPopupV5::QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow *window)
+QWaylandXdgPopupV5::QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow* parent, QWaylandWindow *window)
: QWaylandShellSurface(window)
, QtWayland::xdg_popup_v5(popup)
+ , m_parent(parent)
, m_window(window)
{
if (window->display()->windowExtension())
m_extendedWindow = new QWaylandExtendedSurface(window);
+ m_parent->addChildPopup(m_window);
}
QWaylandXdgPopupV5::~QWaylandXdgPopupV5()
{
xdg_popup_destroy(object());
+ m_parent->removeChildPopup(m_window);
delete m_extendedWindow;
}
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
index 7494f6a6..d85f130b 100644
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
@@ -70,7 +70,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgPopupV5 : public QWaylandShellSurface
{
Q_OBJECT
public:
- QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow *window);
+ QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow* parent, QWaylandWindow *window);
~QWaylandXdgPopupV5() override;
protected:
@@ -78,6 +78,7 @@ protected:
private:
QWaylandExtendedSurface *m_extendedWindow = nullptr;
+ QWaylandWindow *m_parent = nullptr;
QWaylandWindow *m_window = nullptr;
};
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
index 7e242c4a..def8452a 100644
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
@@ -84,7 +84,7 @@ QWaylandXdgPopupV5 *QWaylandXdgShellV5::createXdgPopup(QWaylandWindow *window, Q
int x = position.x() + parentWindow->frameMargins().left();
int y = position.y() + parentWindow->frameMargins().top();
- auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), window);
+ auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), parentWindow, window);
m_popups.append(window);
QObject::connect(popup, &QWaylandXdgPopupV5::destroyed, [this, window](){
m_popups.removeOne(window);
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
index 4e25949f..cfc60939 100644
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
@@ -1841,6 +2000,27 @@ index ce6bdb9e..aed88670 100644
private:
QScopedPointer<QWaylandXdgShellV5> m_xdgShell;
diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
index 8c371661..151c78e3 100644
--- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
+++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
@@ -174,6 +174,7 @@ QWaylandXdgSurfaceV6::Popup::Popup(QWaylandXdgSurfaceV6 *xdgSurface, QWaylandXdg
, m_xdgSurface(xdgSurface)
, m_parent(parent)
{
+ m_parent->window()->addChildPopup(m_xdgSurface->window());
}
QWaylandXdgSurfaceV6::Popup::~Popup()
@@ -181,6 +182,8 @@ QWaylandXdgSurfaceV6::Popup::~Popup()
if (isInitialized())
destroy();
+ m_parent->window()->removeChildPopup(m_xdgSurface->window());
+
if (m_grabbing) {
auto *shell = m_xdgSurface->m_shell;
Q_ASSERT(shell->m_topmostGrabbingPopup == this);
diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
index 03164316..e8da8ba1 100644
--- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
@@ -1879,7 +2059,7 @@ index 261f8cbb..c1bcd5c6 100644
private:
QScopedPointer<QWaylandXdgShellV6> m_xdgShell;
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
index 3a1569f7..d7d0ddf7 100644
index 3a1569f7..3999a5ee 100644
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
@@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
@@ -1925,7 +2105,44 @@ index 3a1569f7..d7d0ddf7 100644
m_applied = m_pending;
qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states;
}
@@ -257,6 +249,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
@@ -203,12 +195,17 @@ QtWayland::xdg_toplevel::resize_edge QWaylandXdgSurface::Toplevel::convertToResi
| ((edges & Qt::RightEdge) ? resize_edge_right : 0));
}
-QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent,
+QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent,
QtWayland::xdg_positioner *positioner)
- : xdg_popup(xdgSurface->get_popup(parent->object(), positioner->object()))
- , m_xdgSurface(xdgSurface)
+ : m_xdgSurface(xdgSurface)
+ , m_parentXdgSurface(qobject_cast<QWaylandXdgSurface *>(parent->shellSurface()))
, m_parent(parent)
{
+
+ init(xdgSurface->get_popup(m_parentXdgSurface ? m_parentXdgSurface->object() : nullptr, positioner->object()));
+ if (m_parent) {
+ m_parent->addChildPopup(m_xdgSurface->window());
+ }
}
QWaylandXdgSurface::Popup::~Popup()
@@ -216,10 +213,14 @@ QWaylandXdgSurface::Popup::~Popup()
if (isInitialized())
destroy();
+ if (m_parent) {
+ m_parent->removeChildPopup(m_xdgSurface->window());
+ }
+
if (m_grabbing) {
auto *shell = m_xdgSurface->m_shell;
Q_ASSERT(shell->m_topmostGrabbingPopup == this);
- shell->m_topmostGrabbingPopup = m_parent->m_popup;
+ shell->m_topmostGrabbingPopup = m_parentXdgSurface ? m_parentXdgSurface->m_popup : nullptr;
}
}
@@ -257,6 +258,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
}
}
@@ -1933,6 +2150,48 @@ index 3a1569f7..d7d0ddf7 100644
}
QWaylandXdgSurface::~QWaylandXdgSurface()
@@ -399,8 +401,6 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
{
Q_ASSERT(!m_toplevel && !m_popup);
- auto parentXdgSurface = static_cast<QWaylandXdgSurface *>(parent->shellSurface());
-
auto positioner = new QtWayland::xdg_positioner(m_shell->create_positioner());
// set_popup expects a position relative to the parent
QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
@@ -413,8 +413,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left);
positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right);
positioner->set_size(m_window->geometry().width(), m_window->geometry().height());
- m_popup = new Popup(this, parentXdgSurface, positioner);
+ m_popup = new Popup(this, parent, positioner);
positioner->destroy();
+
delete positioner;
}
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
index 0c98be35..28ff76ba 100644
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
@@ -131,14 +131,15 @@ private:
class Popup : public QtWayland::xdg_popup {
public:
- Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent, QtWayland::xdg_positioner *positioner);
+ Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, QtWayland::xdg_positioner *positioner);
~Popup() override;
void grab(QWaylandInputDevice *seat, uint serial);
void xdg_popup_popup_done() override;
QWaylandXdgSurface *m_xdgSurface = nullptr;
- QWaylandXdgSurface *m_parent = nullptr;
+ QWaylandXdgSurface *m_parentXdgSurface = nullptr;
+ QWaylandWindow *m_parent = nullptr;
bool m_grabbing = false;
};
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
index 8769d971..da0dd6a7 100644
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
@@ -2070,6 +2329,18 @@ index 1568b3b9..067410d0 100644
class DataDeviceCompositor : public DefaultCompositor {
public:
diff --git a/tests/auto/client/shared/corecompositor.cpp b/tests/auto/client/shared/corecompositor.cpp
index 5c6c83ba..fa9b7662 100644
--- a/tests/auto/client/shared/corecompositor.cpp
+++ b/tests/auto/client/shared/corecompositor.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "corecompositor.h"
+#include <thread>
namespace MockCompositor {
diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h
index a1af137a..296dbf47 100644
--- a/tests/auto/client/shared/coreprotocol.h
@@ -2131,7 +2402,7 @@ index 949dc23d..d176837e 100644
uint32_t callback) override;
void surface_commit(Resource *resource) override;
diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp
index 2277bbb8..73d1eb9c 100644
index 2277bbb8..747875b4 100644
--- a/tests/auto/client/xdgshell/tst_xdgshell.cpp
+++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp
@@ -31,6 +31,7 @@
@@ -2142,7 +2413,15 @@ index 2277bbb8..73d1eb9c 100644
using namespace MockCompositor;
@@ -138,6 +139,7 @@ void tst_xdgshell::configureSize()
@@ -45,6 +46,7 @@ private slots:
void configureStates();
void popup();
void tooltipOnPopup();
+ void tooltipAndSiblingPopup();
void switchPopups();
void hidePopupParent();
void pongs();
@@ -138,6 +140,7 @@ void tst_xdgshell::configureSize()
void tst_xdgshell::configureStates()
{
@@ -2150,7 +2429,7 @@ index 2277bbb8..73d1eb9c 100644
QRasterWindow window;
window.resize(64, 48);
window.show();
@@ -154,9 +156,12 @@ void tst_xdgshell::configureStates()
@@ -154,9 +157,12 @@ void tst_xdgshell::configureStates()
// Toplevel windows don't know their position on xdg-shell
// QCOMPARE(window.frameGeometry().topLeft(), QPoint()); // TODO: this doesn't currently work when window decorations are enabled
@@ -2166,7 +2445,7 @@ index 2277bbb8..73d1eb9c 100644
const QSize screenSize(640, 480);
const uint maximizedSerial = exec([=] {
@@ -186,6 +191,7 @@ void tst_xdgshell::configureStates()
@@ -186,6 +192,7 @@ void tst_xdgshell::configureStates()
QCOMPARE(window.windowStates(), Qt::WindowNoState);
QCOMPARE(window.frameGeometry().size(), windowedSize);
// QCOMPARE(window.frameGeometry().topLeft(), QPoint()); // TODO: this doesn't currently work when window decorations are enabled
@@ -2174,7 +2453,100 @@ index 2277bbb8..73d1eb9c 100644
}
void tst_xdgshell::popup()
@@ -505,7 +511,7 @@ void tst_xdgshell::minMaxSize()
@@ -340,6 +347,92 @@ void tst_xdgshell::tooltipOnPopup()
QCOMPOSITOR_TRY_COMPARE(xdgPopup(0), nullptr);
}
+void tst_xdgshell::tooltipAndSiblingPopup()
+{
+ class ToolTip : public QRasterWindow {
+ public:
+ explicit ToolTip(QWindow *parent) {
+ setTransientParent(parent);
+ setFlags(Qt::ToolTip);
+ resize(100, 100);
+ show();
+ }
+ void mousePressEvent(QMouseEvent *event) override {
+ QRasterWindow::mousePressEvent(event);
+ m_popup = new QRasterWindow;
+ m_popup->setTransientParent(transientParent());
+ m_popup->setFlags(Qt::Popup);
+ m_popup->resize(100, 100);
+ m_popup->show();
+ }
+
+ QRasterWindow *m_popup = nullptr;
+ };
+
+ class Window : public QRasterWindow {
+ public:
+ void mousePressEvent(QMouseEvent *event) override {
+ QRasterWindow::mousePressEvent(event);
+ m_tooltip = new ToolTip(this);
+ }
+ ToolTip *m_tooltip = nullptr;
+ };
+
+ Window window;
+ window.resize(200, 200);
+ window.show();
+
+ QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
+ exec([=] { xdgToplevel()->sendCompleteConfigure(); });
+ QCOMPOSITOR_TRY_VERIFY(xdgToplevel()->m_xdgSurface->m_committedConfigureSerial);
+
+ exec([=] {
+ auto *surface = xdgToplevel()->surface();
+ auto *p = pointer();
+ auto *c = client();
+ p->sendEnter(surface, {100, 100});
+ p->sendFrame(c);
+ p->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed);
+ p->sendButton(client(), BTN_LEFT, Pointer::button_state_released);
+ p->sendFrame(c);
+ p->sendLeave(surface);
+ p->sendFrame(c);
+ });
+
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup());
+ exec([=] { xdgPopup()->sendCompleteConfigure(QRect(100, 100, 100, 100)); });
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup()->m_xdgSurface->m_committedConfigureSerial);
+ QCOMPOSITOR_TRY_VERIFY(!xdgPopup()->m_grabbed);
+
+ exec([=] {
+ auto *surface = xdgPopup()->surface();
+ auto *p = pointer();
+ auto *c = client();
+ p->sendEnter(surface, {100, 100});
+ p->sendFrame(c);
+ p->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed);
+ p->sendButton(client(), BTN_LEFT, Pointer::button_state_released);
+ p->sendFrame(c);
+ });
+
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup(1));
+ exec([=] { xdgPopup(1)->sendCompleteConfigure(QRect(100, 100, 100, 100)); });
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup(1)->m_xdgSurface->m_committedConfigureSerial);
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup(1)->m_grabbed);
+
+ // Close the middle tooltip (it should not close the sibling popup)
+ window.m_tooltip->close();
+
+ QCOMPOSITOR_TRY_COMPARE(xdgPopup(1), nullptr);
+ // Verify the remaining xdg surface is a grab popup..
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup(0));
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup(0)->m_grabbed);
+
+ window.m_tooltip->m_popup->close();
+ QCOMPOSITOR_TRY_COMPARE(xdgPopup(1), nullptr);
+ QCOMPOSITOR_TRY_COMPARE(xdgPopup(0), nullptr);
+}
+
// QTBUG-65680
void tst_xdgshell::switchPopups()
{
@@ -505,7 +598,7 @@ void tst_xdgshell::minMaxSize()
window.show();
QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
@@ -85,6 +85,13 @@
</Package>
<History>
<Update release="30">
<Date>2022-08-24</Date>
<Version>5.15.5</Version>
<Comment>Rebuild.</Comment>
<Name>Mustafa Cinasal</Name>
<Email>muscnsl@gmail.com</Email>
</Update>
<Update release="29">
<Date>2022-07-05</Date>
<Version>5.15.5</Version>