Add support for wl_shell_surface::set_popup and popup_done
Summary: This extends the client side API to support creating popup ShellSurface windows and the server side API to send out the popup_done request. This is needed to properly support popup windows (e.g. context menus) in KWin. Reviewers: #plasma_on_wayland, #frameworks, #kwin Subscribers: plasma-devel Tags: #plasma_on_wayland, #frameworks Differential Revision: https://phabricator.kde.org/D5174
This commit is contained in:
parent
a1c8ea01d7
commit
bccb1f4cba
3 changed files with 90 additions and 0 deletions
|
@ -55,6 +55,7 @@ private Q_SLOTS:
|
||||||
void testToplevel();
|
void testToplevel();
|
||||||
void testTransient_data();
|
void testTransient_data();
|
||||||
void testTransient();
|
void testTransient();
|
||||||
|
void testTransientPopup();
|
||||||
void testPing();
|
void testPing();
|
||||||
void testTitle();
|
void testTitle();
|
||||||
void testWindowClass();
|
void testWindowClass();
|
||||||
|
@ -475,6 +476,72 @@ void TestWaylandShell::testTransient()
|
||||||
QVERIFY(serverSurface2->acceptsKeyboardFocus());
|
QVERIFY(serverSurface2->acceptsKeyboardFocus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestWaylandShell::testTransientPopup()
|
||||||
|
{
|
||||||
|
using namespace KWayland::Server;
|
||||||
|
using namespace KWayland::Client;
|
||||||
|
QScopedPointer<Surface> s(m_compositor->createSurface());
|
||||||
|
QVERIFY(!s.isNull());
|
||||||
|
QVERIFY(s->isValid());
|
||||||
|
ShellSurface *surface = m_shell->createSurface(s.data(), m_shell);
|
||||||
|
|
||||||
|
QSignalSpy serverSurfaceSpy(m_shellInterface, &ShellInterface::surfaceCreated);
|
||||||
|
QVERIFY(serverSurfaceSpy.isValid());
|
||||||
|
QVERIFY(serverSurfaceSpy.wait());
|
||||||
|
ShellSurfaceInterface *serverSurface = serverSurfaceSpy.first().first().value<ShellSurfaceInterface*>();
|
||||||
|
QVERIFY(serverSurface);
|
||||||
|
QCOMPARE(serverSurface->isToplevel(), true);
|
||||||
|
QCOMPARE(serverSurface->isPopup(), false);
|
||||||
|
QCOMPARE(serverSurface->isTransient(), false);
|
||||||
|
QCOMPARE(serverSurface->transientFor(), QPointer<SurfaceInterface>());
|
||||||
|
QCOMPARE(serverSurface->transientOffset(), QPoint());
|
||||||
|
QVERIFY(serverSurface->acceptsKeyboardFocus());
|
||||||
|
|
||||||
|
QSignalSpy transientSpy(serverSurface, &ShellSurfaceInterface::transientChanged);
|
||||||
|
QVERIFY(transientSpy.isValid());
|
||||||
|
QSignalSpy transientOffsetSpy(serverSurface, &ShellSurfaceInterface::transientOffsetChanged);
|
||||||
|
QVERIFY(transientOffsetSpy.isValid());
|
||||||
|
QSignalSpy transientForChangedSpy(serverSurface, &ShellSurfaceInterface::transientForChanged);
|
||||||
|
QVERIFY(transientForChangedSpy.isValid());
|
||||||
|
|
||||||
|
QScopedPointer<Surface> s2(m_compositor->createSurface());
|
||||||
|
m_shell->createSurface(s2.data(), m_shell);
|
||||||
|
serverSurfaceSpy.clear();
|
||||||
|
QVERIFY(serverSurfaceSpy.wait());
|
||||||
|
ShellSurfaceInterface *serverSurface2 = serverSurfaceSpy.first().first().value<ShellSurfaceInterface*>();
|
||||||
|
QVERIFY(serverSurface2 != serverSurface);
|
||||||
|
QVERIFY(serverSurface2);
|
||||||
|
QVERIFY(serverSurface2->acceptsKeyboardFocus());
|
||||||
|
|
||||||
|
// TODO: proper serial checking
|
||||||
|
surface->setTransientPopup(s2.data(), m_seat, 1, QPoint(10, 20));
|
||||||
|
QVERIFY(transientSpy.wait());
|
||||||
|
QCOMPARE(transientSpy.count(), 1);
|
||||||
|
QCOMPARE(transientSpy.first().first().toBool(), true);
|
||||||
|
QCOMPARE(transientOffsetSpy.count(), 1);
|
||||||
|
QCOMPARE(transientOffsetSpy.first().first().toPoint(), QPoint(10, 20));
|
||||||
|
QCOMPARE(transientForChangedSpy.count(), 1);
|
||||||
|
QCOMPARE(serverSurface->isToplevel(), false);
|
||||||
|
QCOMPARE(serverSurface->isPopup(), true);
|
||||||
|
QCOMPARE(serverSurface->isTransient(), true);
|
||||||
|
QCOMPARE(serverSurface->transientFor(), QPointer<SurfaceInterface>(serverSurface2->surface()));
|
||||||
|
QCOMPARE(serverSurface->transientOffset(), QPoint(10, 20));
|
||||||
|
// TODO: honor the flag
|
||||||
|
QCOMPARE(serverSurface->acceptsKeyboardFocus(), false);
|
||||||
|
|
||||||
|
QCOMPARE(serverSurface2->isToplevel(), true);
|
||||||
|
QCOMPARE(serverSurface2->isPopup(), false);
|
||||||
|
QCOMPARE(serverSurface2->isTransient(), false);
|
||||||
|
QCOMPARE(serverSurface2->transientFor(), QPointer<SurfaceInterface>());
|
||||||
|
QCOMPARE(serverSurface2->transientOffset(), QPoint());
|
||||||
|
|
||||||
|
// send popup done
|
||||||
|
QSignalSpy popupDoneSpy(surface, &ShellSurface::popupDone);
|
||||||
|
QVERIFY(popupDoneSpy.isValid());
|
||||||
|
serverSurface->popupDone();
|
||||||
|
QVERIFY(popupDoneSpy.wait());
|
||||||
|
}
|
||||||
|
|
||||||
void TestWaylandShell::testPing()
|
void TestWaylandShell::testPing()
|
||||||
{
|
{
|
||||||
using namespace KWayland::Server;
|
using namespace KWayland::Server;
|
||||||
|
|
|
@ -379,6 +379,9 @@ void ShellSurfaceInterface::Private::setPopupCallback(wl_client *client, wl_reso
|
||||||
emit s->q_func()->transientChanged(!s->transientFor.isNull());
|
emit s->q_func()->transientChanged(!s->transientFor.isNull());
|
||||||
emit s->q_func()->transientOffsetChanged(s->transientOffset);
|
emit s->q_func()->transientOffsetChanged(s->transientOffset);
|
||||||
emit s->q_func()->transientForChanged();
|
emit s->q_func()->transientForChanged();
|
||||||
|
// we ignore the flags as Qt requests keyboard focus for popups
|
||||||
|
// if we would honor the flag this could break compositors
|
||||||
|
// compare QtWayland (5.6), file qwaylandwlshellsurface.cpp:208
|
||||||
s->setAcceptsFocus(WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
|
s->setAcceptsFocus(WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,6 +452,14 @@ bool ShellSurfaceInterface::acceptsKeyboardFocus() const
|
||||||
return d->acceptsKeyboardFocus;
|
return d->acceptsKeyboardFocus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShellSurfaceInterface::popupDone()
|
||||||
|
{
|
||||||
|
Q_D();
|
||||||
|
if (isPopup() && d->resource) {
|
||||||
|
wl_shell_surface_send_popup_done(d->resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QPointer< SurfaceInterface > ShellSurfaceInterface::transientFor() const
|
QPointer< SurfaceInterface > ShellSurfaceInterface::transientFor() const
|
||||||
{
|
{
|
||||||
Q_D();
|
Q_D();
|
||||||
|
|
|
@ -231,6 +231,18 @@ public:
|
||||||
**/
|
**/
|
||||||
bool acceptsKeyboardFocus() const;
|
bool acceptsKeyboardFocus() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a popup done event to the shell surface.
|
||||||
|
* This is only relevant for popup windows. It indicates that the popup grab
|
||||||
|
* got canceled. This happens when e.g. the user clicks outside of any surface
|
||||||
|
* of the same client as this ShellSurfaceInterface. It is the task of the
|
||||||
|
* compositor to send the popupDone event appropriately.
|
||||||
|
*
|
||||||
|
* @see isPopup
|
||||||
|
* @since 5.33
|
||||||
|
**/
|
||||||
|
void popupDone();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* Emitted whenever the title changes.
|
* Emitted whenever the title changes.
|
||||||
|
|
Loading…
Reference in a new issue