Add support for transient to ShellSurface(Interface)
On client side a setTransient method is added which wraps the semantic of wl_shell_surface_set_transient. On server side both set_transient and set_popup are implemented, though for popup only the transient part is implemented. In particular the grab is not yet handled and also no popup done is provided. For the transient on server side the flags are ignored. Main reason is that Qt does not use the flag, so testing whether it works is tricky (needs a test application). REVIEW: 125223
This commit is contained in:
parent
265504a088
commit
2bd8a8b98a
3 changed files with 181 additions and 9 deletions
|
@ -47,6 +47,7 @@ private Q_SLOTS:
|
|||
void testFullscreen();
|
||||
void testMaximize();
|
||||
void testToplevel();
|
||||
void testTransient();
|
||||
void testPing();
|
||||
void testTitle();
|
||||
void testWindowClass();
|
||||
|
@ -334,6 +335,61 @@ void TestWaylandShell::testToplevel()
|
|||
QVERIFY(!toplevelSpy.first().first().toBool());
|
||||
}
|
||||
|
||||
void TestWaylandShell::testTransient()
|
||||
{
|
||||
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());
|
||||
|
||||
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);
|
||||
|
||||
surface->setTransient(s2.data(), 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(), false);
|
||||
QCOMPARE(serverSurface->isTransient(), true);
|
||||
QCOMPARE(serverSurface->transientFor(), QPointer<SurfaceInterface>(serverSurface2->surface()));
|
||||
QCOMPARE(serverSurface->transientOffset(), QPoint(10, 20));
|
||||
|
||||
QCOMPARE(serverSurface2->isToplevel(), true);
|
||||
QCOMPARE(serverSurface2->isPopup(), false);
|
||||
QCOMPARE(serverSurface2->isTransient(), false);
|
||||
QCOMPARE(serverSurface2->transientFor(), QPointer<SurfaceInterface>());
|
||||
QCOMPARE(serverSurface2->transientOffset(), QPoint());
|
||||
}
|
||||
|
||||
void TestWaylandShell::testPing()
|
||||
{
|
||||
using namespace KWayland::Server;
|
||||
|
|
|
@ -78,9 +78,13 @@ public:
|
|||
enum class WindowMode {
|
||||
Fullscreen,
|
||||
Toplevel,
|
||||
Maximized
|
||||
Maximized,
|
||||
Transient,
|
||||
Popup
|
||||
};
|
||||
WindowMode windowMode = WindowMode::Toplevel;
|
||||
QPoint transientOffset;
|
||||
QPointer<SurfaceInterface> transientFor;
|
||||
void setWindowMode(WindowMode newWindowMode);
|
||||
|
||||
private:
|
||||
|
@ -274,13 +278,15 @@ void ShellSurfaceInterface::Private::setToplevelCallback(wl_client *client, wl_r
|
|||
void ShellSurfaceInterface::Private::setTransientCallback(wl_client *client, wl_resource *resource, wl_resource *parent,
|
||||
int32_t x, int32_t y, uint32_t flags)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(x)
|
||||
Q_UNUSED(y)
|
||||
Q_UNUSED(flags)
|
||||
auto s = cast<Private>(resource);
|
||||
Q_ASSERT(client == *s->client);
|
||||
// TODO: implement
|
||||
s->transientFor = QPointer<SurfaceInterface>(SurfaceInterface::get(parent));
|
||||
s->transientOffset = QPoint(x, y);
|
||||
s->setWindowMode(WindowMode::Transient);
|
||||
// TODO: flags
|
||||
emit s->q_func()->transientOffsetChanged(s->transientOffset);
|
||||
emit s->q_func()->transientForChanged();
|
||||
}
|
||||
|
||||
void ShellSurfaceInterface::Private::setFullscreenCallback(wl_client *client, wl_resource *resource, uint32_t method,
|
||||
|
@ -312,6 +318,13 @@ void ShellSurfaceInterface::Private::setWindowMode(WindowMode newWindowMode)
|
|||
if (oldWindowMode == WindowMode::Maximized || newWindowMode == WindowMode::Maximized) {
|
||||
emit q->maximizedChanged(windowMode == WindowMode::Maximized);
|
||||
}
|
||||
if (oldWindowMode == WindowMode::Popup || newWindowMode == WindowMode::Popup) {
|
||||
emit q->popupChanged(windowMode == WindowMode::Popup);
|
||||
emit q->transientChanged(windowMode == WindowMode::Popup || windowMode == WindowMode::Transient);
|
||||
}
|
||||
if (oldWindowMode == WindowMode::Transient || newWindowMode == WindowMode::Transient) {
|
||||
emit q->transientChanged(windowMode == WindowMode::Popup || windowMode == WindowMode::Transient);
|
||||
}
|
||||
}
|
||||
|
||||
void ShellSurfaceInterface::Private::setPopupCallback(wl_client *client, wl_resource *resource, wl_resource *seat, uint32_t serial,
|
||||
|
@ -319,13 +332,16 @@ void ShellSurfaceInterface::Private::setPopupCallback(wl_client *client, wl_reso
|
|||
{
|
||||
Q_UNUSED(seat)
|
||||
Q_UNUSED(serial)
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(x)
|
||||
Q_UNUSED(y)
|
||||
Q_UNUSED(flags)
|
||||
auto s = cast<Private>(resource);
|
||||
Q_ASSERT(client == *s->client);
|
||||
// TODO: implement
|
||||
// TODO: what about seat and serial?
|
||||
s->transientFor = QPointer<SurfaceInterface>(SurfaceInterface::get(parent));
|
||||
s->transientOffset = QPoint(x, y);
|
||||
s->setWindowMode(WindowMode::Popup);
|
||||
// TODO: flags
|
||||
emit s->q_func()->transientOffsetChanged(s->transientOffset);
|
||||
emit s->q_func()->transientForChanged();
|
||||
}
|
||||
|
||||
void ShellSurfaceInterface::Private::setMaximizedCallback(wl_client *client, wl_resource *resource, wl_resource *output)
|
||||
|
@ -405,6 +421,30 @@ bool ShellSurfaceInterface::isMaximized() const {
|
|||
return d->windowMode == Private::WindowMode::Maximized;
|
||||
}
|
||||
|
||||
bool ShellSurfaceInterface::isPopup() const
|
||||
{
|
||||
Q_D();
|
||||
return d->windowMode == Private::WindowMode::Popup;
|
||||
}
|
||||
|
||||
bool ShellSurfaceInterface::isTransient() const
|
||||
{
|
||||
Q_D();
|
||||
return isPopup() || d->windowMode == Private::WindowMode::Transient;
|
||||
}
|
||||
|
||||
QPoint ShellSurfaceInterface::transientOffset() const
|
||||
{
|
||||
Q_D();
|
||||
return d->transientOffset;
|
||||
}
|
||||
|
||||
QPointer< SurfaceInterface > ShellSurfaceInterface::transientFor() const
|
||||
{
|
||||
Q_D();
|
||||
return d->transientFor;
|
||||
}
|
||||
|
||||
ShellSurfaceInterface::Private *ShellSurfaceInterface::d_func() const
|
||||
{
|
||||
return reinterpret_cast<ShellSurfaceInterface::Private*>(d.data());
|
||||
|
|
|
@ -97,6 +97,25 @@ class KWAYLANDSERVER_EXPORT ShellSurfaceInterface : public Resource
|
|||
* Whether the window is maximized.
|
||||
**/
|
||||
Q_PROPERTY(bool maximized READ isMaximized NOTIFY maximizedChanged)
|
||||
/**
|
||||
* Whether the ShellSurfaceInterface is a popup for another SurfaceInterface.
|
||||
*
|
||||
* Popup implies transient.
|
||||
* @since 5.5
|
||||
**/
|
||||
Q_PROPERTY(bool popup READ isPopup NOTIFY popupChanged)
|
||||
/**
|
||||
* Whether the ShellSurfaceInterface is a transient for another SurfaceInterface.
|
||||
*
|
||||
* Popup implies transient.
|
||||
* @since 5.5
|
||||
**/
|
||||
Q_PROPERTY(bool transient READ isTransient NOTIFY transientChanged)
|
||||
/**
|
||||
* Offset of the upper left corner in the parent SurfaceInterface's coordinate system.
|
||||
* @since 5.5
|
||||
**/
|
||||
Q_PROPERTY(QPoint transientOffset READ transientOffset NOTIFY transientOffsetChanged)
|
||||
public:
|
||||
virtual ~ShellSurfaceInterface();
|
||||
|
||||
|
@ -144,6 +163,47 @@ public:
|
|||
bool isFullscreen() const;
|
||||
bool isToplevel() const;
|
||||
bool isMaximized() const;
|
||||
/**
|
||||
* @returns @c true if the ShellSurfaceInterface is a popup.
|
||||
* @see isTransient
|
||||
* @see transientOffset
|
||||
* @see transientFor
|
||||
* @since 5.5
|
||||
**/
|
||||
bool isPopup() const;
|
||||
/**
|
||||
* @returns @c true if the ShellSurfaceInterface is a transient or popup for another SurfaceInterface.
|
||||
* @see isPopup
|
||||
* @see transientOffset
|
||||
* @see transientFor
|
||||
* @since 5.5
|
||||
**/
|
||||
bool isTransient() const;
|
||||
/**
|
||||
* In case the ShellSurfaceInterface is a transient this is the offset of the ShellSurfaceInterface
|
||||
* in the coordinate system of the SurfaceInterface this surface is a transient for.
|
||||
*
|
||||
* @returns offset in parent coordinate system.
|
||||
* @see isTransient
|
||||
* @see transientFor
|
||||
* @since 5.5
|
||||
**/
|
||||
QPoint transientOffset() const;
|
||||
/**
|
||||
* The SurfaceInterface for which this ShellSurfaceInterface is a transient.
|
||||
* This is only relevant if the ShellSurfaceInterface is either a transient or a
|
||||
* popup.
|
||||
*
|
||||
* The transientOffset is in the local coordinate system of the SurfaceInterface
|
||||
* returned by this method.
|
||||
*
|
||||
* @returns The SurfaceInterface for which this Surface is a transient
|
||||
* @see isTransient
|
||||
* @see isPopup
|
||||
* @see transientOffset
|
||||
* @since 5.5
|
||||
**/
|
||||
QPointer<SurfaceInterface> transientFor() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
|
@ -168,6 +228,22 @@ Q_SIGNALS:
|
|||
void fullscreenChanged(bool);
|
||||
void toplevelChanged(bool);
|
||||
void maximizedChanged(bool);
|
||||
/**
|
||||
* @since 5.5
|
||||
**/
|
||||
void popupChanged(bool);
|
||||
/**
|
||||
* @since 5.5
|
||||
**/
|
||||
void transientChanged(bool);
|
||||
/**
|
||||
* @since 5.5
|
||||
**/
|
||||
void transientOffsetChanged(const QPoint&);
|
||||
/**
|
||||
* @since 5.5
|
||||
**/
|
||||
void transientForChanged();
|
||||
|
||||
private:
|
||||
friend class ShellInterface;
|
||||
|
|
Loading…
Reference in a new issue