Merge remote-tracking branch 'qt/5.9' into 5.10

Change-Id: I6c283081669594b3e8c6b30194bb96e389319cb2
This commit is contained in:
Paul Olav Tvete 2017-10-25 14:06:54 +02:00
commit dd6248faff
5 changed files with 70 additions and 17 deletions

View File

@ -66,7 +66,7 @@ void QWaylandBuffer::init(wl_buffer *buf)
void QWaylandBuffer::release(void *data, wl_buffer *) void QWaylandBuffer::release(void *data, wl_buffer *)
{ {
static_cast<QWaylandBuffer *>(data)->mBusy = false; static_cast<QWaylandBuffer *>(data)->mBusy--;
} }
const wl_buffer_listener QWaylandBuffer::listener = { const wl_buffer_listener QWaylandBuffer::listener = {

View File

@ -73,14 +73,14 @@ public:
virtual QSize size() const = 0; virtual QSize size() const = 0;
virtual int scale() const { return 1; } virtual int scale() const { return 1; }
void setBusy() { mBusy = true; } void setBusy() { mBusy++; }
bool busy() const { return mBusy; } bool busy() const { return mBusy > 0; }
protected: protected:
struct wl_buffer *mBuffer; struct wl_buffer *mBuffer;
private: private:
bool mBusy; int mBusy;
static void release(void *data, wl_buffer *); static void release(void *data, wl_buffer *);
static const wl_buffer_listener listener; static const wl_buffer_listener listener;

View File

@ -261,6 +261,8 @@ void QWaylandWindow::reset(bool sendDestroyEvent)
wl_callback_destroy(mFrameCallback); wl_callback_destroy(mFrameCallback);
mFrameCallback = nullptr; mFrameCallback = nullptr;
} }
mMask = QRegion();
} }
QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
@ -790,22 +792,27 @@ QWaylandAbstractDecoration *QWaylandWindow::decoration() const
return mWindowDecoration; return mWindowDecoration;
} }
static QWindow *topLevelWindow(QWindow *window) static QWaylandWindow *closestShellSurfaceWindow(QWindow *window)
{ {
while (QWindow *parent = window->parent()) while (window) {
window = parent; auto w = static_cast<QWaylandWindow *>(window->handle());
return window; if (w->shellSurface())
return w;
window = window->transientParent() ? window->transientParent() : window->parent();
}
return nullptr;
} }
QWaylandWindow *QWaylandWindow::transientParent() const QWaylandWindow *QWaylandWindow::transientParent() const
{ {
// Take the top level window here, since the transient parent may be a QWidgetWindow // Take the closest window with a shell surface, since the transient parent may be a
// or some other window without a shell surface, which is then not able to get mouse // QWidgetWindow or some other window without a shell surface, which is then not able to
// events. // get mouse events.
if (auto transientParent = window()->transientParent()) if (auto transientParent = closestShellSurfaceWindow(window()->transientParent()))
return static_cast<QWaylandWindow *>(topLevelWindow(transientParent)->handle()); return transientParent;
else if (QGuiApplication::focusWindow() && (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup))
return static_cast<QWaylandWindow *>(topLevelWindow(QGuiApplication::focusWindow())->handle()); if (QGuiApplication::focusWindow() && (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup))
return closestShellSurfaceWindow(QGuiApplication::focusWindow());
return nullptr; return nullptr;
} }

View File

@ -185,6 +185,7 @@ void QWaylandWlShellSurface::updateTransientParent(QWindow *parent)
|| testShowWithoutActivating(m_window->window())) || testShowWithoutActivating(m_window->window()))
flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE; flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE;
Q_ASSERT(parent_wayland_window->object());
set_transient(parent_wayland_window->object(), set_transient(parent_wayland_window->object(),
transientPos.x(), transientPos.x(),
transientPos.y(), transientPos.y(),
@ -211,15 +212,16 @@ void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevic
transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
} }
Q_ASSERT(parent_wayland_window->object());
set_popup(device->wl_seat(), serial, parent_wayland_window->object(), set_popup(device->wl_seat(), serial, parent_wayland_window->object(),
transientPos.x(), transientPos.y(), 0); transientPos.x(), transientPos.y(), 0);
} }
void QWaylandWlShellSurface::setType(Qt::WindowType type, QWaylandWindow *transientParent) void QWaylandWlShellSurface::setType(Qt::WindowType type, QWaylandWindow *transientParent)
{ {
if (type == Qt::Popup && transientParent) if (type == Qt::Popup && transientParent && transientParent->object())
setPopup(transientParent, m_window->display()->lastInputDevice(), m_window->display()->lastInputSerial()); setPopup(transientParent, m_window->display()->lastInputDevice(), m_window->display()->lastInputSerial());
else if (transientParent) else if (transientParent && transientParent->object())
updateTransientParent(transientParent->window()); updateTransientParent(transientParent->window());
else else
setTopLevel(); setTopLevel();

View File

@ -143,6 +143,8 @@ private slots:
void touchDrag(); void touchDrag();
void mouseDrag(); void mouseDrag();
void dontCrashOnMultipleCommits(); void dontCrashOnMultipleCommits();
void hiddenTransientParent();
void hiddenPopupParent();
private: private:
MockCompositor *compositor; MockCompositor *compositor;
@ -360,6 +362,48 @@ void tst_WaylandClient::dontCrashOnMultipleCommits()
QTRY_VERIFY(!compositor->surface()); QTRY_VERIFY(!compositor->surface());
} }
void tst_WaylandClient::hiddenTransientParent()
{
QWindow parent;
QWindow transient;
transient.setTransientParent(&parent);
parent.show();
QTRY_VERIFY(compositor->surface());
parent.hide();
QTRY_VERIFY(!compositor->surface());
transient.show();
QTRY_VERIFY(compositor->surface());
}
void tst_WaylandClient::hiddenPopupParent()
{
TestWindow toplevel;
toplevel.show();
// wl_shell relies on a mouse event in order to send a serial and seat
// with the set_popup request.
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
QPoint mousePressPos(16, 16);
QCOMPARE(toplevel.mousePressEventCount, 0);
compositor->sendMousePress(surface, mousePressPos);
QTRY_COMPARE(toplevel.mousePressEventCount, 1);
QWindow popup;
popup.setTransientParent(&toplevel);
popup.setFlag(Qt::Popup, true);
toplevel.hide();
QTRY_VERIFY(!compositor->surface());
popup.show();
QTRY_VERIFY(compositor->surface());
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
setenv("XDG_RUNTIME_DIR", ".", 1); setenv("XDG_RUNTIME_DIR", ".", 1);