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 *)
{
static_cast<QWaylandBuffer *>(data)->mBusy = false;
static_cast<QWaylandBuffer *>(data)->mBusy--;
}
const wl_buffer_listener QWaylandBuffer::listener = {

View File

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

View File

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

View File

@ -185,6 +185,7 @@ void QWaylandWlShellSurface::updateTransientParent(QWindow *parent)
|| testShowWithoutActivating(m_window->window()))
flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE;
Q_ASSERT(parent_wayland_window->object());
set_transient(parent_wayland_window->object(),
transientPos.x(),
transientPos.y(),
@ -211,15 +212,16 @@ void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevic
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(),
transientPos.x(), transientPos.y(), 0);
}
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());
else if (transientParent)
else if (transientParent && transientParent->object())
updateTransientParent(transientParent->window());
else
setTopLevel();

View File

@ -143,6 +143,8 @@ private slots:
void touchDrag();
void mouseDrag();
void dontCrashOnMultipleCommits();
void hiddenTransientParent();
void hiddenPopupParent();
private:
MockCompositor *compositor;
@ -360,6 +362,48 @@ void tst_WaylandClient::dontCrashOnMultipleCommits()
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)
{
setenv("XDG_RUNTIME_DIR", ".", 1);