[server] Add support for flags on transient ShellSurfaceInterface

A transient surface can indicate through the flags that it does not
want to accept keyboard focus. This is now exposed through a dedicated
method.

REVIEW: 125552
This commit is contained in:
Martin Gräßlin 2015-10-07 19:02:48 +02:00
parent 65444264a9
commit 8f7893b385
3 changed files with 66 additions and 3 deletions

View file

@ -47,6 +47,7 @@ private Q_SLOTS:
void testFullscreen();
void testMaximize();
void testToplevel();
void testTransient_data();
void testTransient();
void testPing();
void testTitle();
@ -335,6 +336,14 @@ void TestWaylandShell::testToplevel()
QVERIFY(!toplevelSpy.first().first().toBool());
}
void TestWaylandShell::testTransient_data()
{
QTest::addColumn<bool>("keyboardFocus");
QTest::newRow("focus") << true;
QTest::newRow("no focus") << false;
}
void TestWaylandShell::testTransient()
{
using namespace KWayland::Server;
@ -349,11 +358,15 @@ void TestWaylandShell::testTransient()
QVERIFY(serverSurfaceSpy.wait());
ShellSurfaceInterface *serverSurface = serverSurfaceSpy.first().first().value<ShellSurfaceInterface*>();
QVERIFY(serverSurface);
QSignalSpy acceptsKeyboardFocusChangedSpy(serverSurface, &ShellSurfaceInterface::acceptsKeyboardFocusChanged);
QVERIFY(acceptsKeyboardFocusChangedSpy.isValid());
QCOMPARE(serverSurface->isToplevel(), true);
QCOMPARE(serverSurface->isPopup(), false);
QCOMPARE(serverSurface->isTransient(), false);
QCOMPARE(serverSurface->transientFor(), QPointer<SurfaceInterface>());
QCOMPARE(serverSurface->transientOffset(), QPoint());
QVERIFY(serverSurface->acceptsKeyboardFocus());
QVERIFY(acceptsKeyboardFocusChangedSpy.isEmpty());
QSignalSpy transientSpy(serverSurface, &ShellSurfaceInterface::transientChanged);
QVERIFY(transientSpy.isValid());
@ -369,8 +382,10 @@ void TestWaylandShell::testTransient()
ShellSurfaceInterface *serverSurface2 = serverSurfaceSpy.first().first().value<ShellSurfaceInterface*>();
QVERIFY(serverSurface2 != serverSurface);
QVERIFY(serverSurface2);
QVERIFY(serverSurface2->acceptsKeyboardFocus());
surface->setTransient(s2.data(), QPoint(10, 20));
QFETCH(bool, keyboardFocus);
surface->setTransient(s2.data(), QPoint(10, 20), keyboardFocus ? ShellSurface::TransientFlag::Default : ShellSurface::TransientFlag::NoFocus);
QVERIFY(transientSpy.wait());
QCOMPARE(transientSpy.count(), 1);
QCOMPARE(transientSpy.first().first().toBool(), true);
@ -382,12 +397,16 @@ void TestWaylandShell::testTransient()
QCOMPARE(serverSurface->isTransient(), true);
QCOMPARE(serverSurface->transientFor(), QPointer<SurfaceInterface>(serverSurface2->surface()));
QCOMPARE(serverSurface->transientOffset(), QPoint(10, 20));
QCOMPARE(serverSurface->acceptsKeyboardFocus(), keyboardFocus);
QCOMPARE(acceptsKeyboardFocusChangedSpy.isEmpty(), keyboardFocus);
QCOMPARE(acceptsKeyboardFocusChangedSpy.count(), keyboardFocus ? 0 : 1);
QCOMPARE(serverSurface2->isToplevel(), true);
QCOMPARE(serverSurface2->isPopup(), false);
QCOMPARE(serverSurface2->isTransient(), false);
QCOMPARE(serverSurface2->transientFor(), QPointer<SurfaceInterface>());
QCOMPARE(serverSurface2->transientOffset(), QPoint());
QVERIFY(serverSurface2->acceptsKeyboardFocus());
}
void TestWaylandShell::testPing()

View file

@ -84,6 +84,7 @@ public:
WindowMode windowMode = WindowMode::Toplevel;
QPoint transientOffset;
QPointer<SurfaceInterface> transientFor;
bool acceptsKeyboardFocus = true;
void setWindowMode(WindowMode newWindowMode);
private:
@ -106,6 +107,7 @@ private:
void setTitle(const QString &title);
void setWindowClass(const QByteArray &windowClass);
void pong(quint32 serial);
void setAcceptsFocus(quint32 flags);
ShellSurfaceInterface *q_func() {
return reinterpret_cast<ShellSurfaceInterface *>(q);
}
@ -283,9 +285,19 @@ void ShellSurfaceInterface::Private::setTransientCallback(wl_client *client, wl_
s->transientFor = QPointer<SurfaceInterface>(SurfaceInterface::get(parent));
s->transientOffset = QPoint(x, y);
emit s->q_func()->transientChanged(!s->transientFor.isNull());
// TODO: flags
emit s->q_func()->transientOffsetChanged(s->transientOffset);
emit s->q_func()->transientForChanged();
s->setAcceptsFocus(flags);
}
void ShellSurfaceInterface::Private::setAcceptsFocus(quint32 flags)
{
const bool acceptsFocus = !(flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
if (acceptsFocus != acceptsKeyboardFocus) {
acceptsKeyboardFocus = acceptsFocus;
Q_Q(ShellSurfaceInterface);
emit q->acceptsKeyboardFocusChanged();
}
}
void ShellSurfaceInterface::Private::setFullscreenCallback(wl_client *client, wl_resource *resource, uint32_t method,
@ -335,9 +347,9 @@ void ShellSurfaceInterface::Private::setPopupCallback(wl_client *client, wl_reso
s->transientOffset = QPoint(x, y);
s->setWindowMode(WindowMode::Popup);
emit s->q_func()->transientChanged(!s->transientFor.isNull());
// TODO: flags
emit s->q_func()->transientOffsetChanged(s->transientOffset);
emit s->q_func()->transientForChanged();
s->setAcceptsFocus(WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
}
void ShellSurfaceInterface::Private::setMaximizedCallback(wl_client *client, wl_resource *resource, wl_resource *output)
@ -435,6 +447,12 @@ QPoint ShellSurfaceInterface::transientOffset() const
return d->transientOffset;
}
bool ShellSurfaceInterface::acceptsKeyboardFocus() const
{
Q_D();
return d->acceptsKeyboardFocus;
}
QPointer< SurfaceInterface > ShellSurfaceInterface::transientFor() const
{
Q_D();

View file

@ -116,6 +116,15 @@ class KWAYLANDSERVER_EXPORT ShellSurfaceInterface : public Resource
* @since 5.5
**/
Q_PROPERTY(QPoint transientOffset READ transientOffset NOTIFY transientOffsetChanged)
/**
* Whether the ShellSurfaceInterface can accept keyboard focus.
*
* By default ShellSurfaceInterface accepts keyboard focus, only transient surfaces
* might not want keyboard focus.
*
* @since 5.5
**/
Q_PROPERTY(bool acceptsKeyboardFocus READ acceptsKeyboardFocus NOTIFY acceptsKeyboardFocusChanged)
public:
virtual ~ShellSurfaceInterface();
@ -205,6 +214,19 @@ public:
**/
QPointer<SurfaceInterface> transientFor() const;
/**
* Whether the ShellSurfaceInterface can accept keyboard focus.
*
* This is only relevant for transient and popup windows. By default all ShellSurfaces
* accept keyboard focus.
*
* @returns Whether the ShellSurfaceInterface can accept keyboard focus.
* @see isTransient()
* @see acceptsKeyboardFocusChanged
* @since 5.5
**/
bool acceptsKeyboardFocus() const;
Q_SIGNALS:
/**
* Emitted whenever the title changes.
@ -244,6 +266,10 @@ Q_SIGNALS:
* @since 5.5
**/
void transientForChanged();
/**
* @since 5.5
**/
void acceptsKeyboardFocusChanged();
private:
friend class ShellInterface;