2020-08-02 22:22:19 +00:00
|
|
|
/*
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
2016-02-01 14:10:00 +00:00
|
|
|
|
2020-08-02 22:22:19 +00:00
|
|
|
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
|
2016-02-01 14:10:00 +00:00
|
|
|
|
2020-08-02 22:22:19 +00:00
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
2016-02-01 14:10:00 +00:00
|
|
|
#include "kwin_wayland_test.h"
|
2016-04-07 07:24:17 +00:00
|
|
|
#include "platform.h"
|
2016-02-01 14:10:00 +00:00
|
|
|
#include "abstract_client.h"
|
2019-01-06 15:34:10 +00:00
|
|
|
#include "composite.h"
|
2016-02-01 14:10:00 +00:00
|
|
|
#include "cursor.h"
|
2019-01-06 15:34:10 +00:00
|
|
|
#include "scene.h"
|
2016-02-02 12:50:13 +00:00
|
|
|
#include "screenedge.h"
|
2016-02-01 14:10:00 +00:00
|
|
|
#include "screens.h"
|
|
|
|
#include "wayland_server.h"
|
|
|
|
#include "workspace.h"
|
2016-02-02 13:41:28 +00:00
|
|
|
#include <kwineffects.h>
|
2016-02-01 14:10:00 +00:00
|
|
|
|
|
|
|
#include <KWayland/Client/connection_thread.h>
|
|
|
|
#include <KWayland/Client/compositor.h>
|
2016-02-08 15:52:22 +00:00
|
|
|
#include <KWayland/Client/keyboard.h>
|
2016-02-01 14:10:00 +00:00
|
|
|
#include <KWayland/Client/registry.h>
|
|
|
|
#include <KWayland/Client/pointer.h>
|
|
|
|
#include <KWayland/Client/seat.h>
|
|
|
|
#include <KWayland/Client/shm_pool.h>
|
|
|
|
#include <KWayland/Client/surface.h>
|
2016-02-10 15:43:06 +00:00
|
|
|
#include <KWayland/Client/touch.h>
|
2020-04-29 15:18:41 +00:00
|
|
|
#include <KWaylandServer/seat_interface.h>
|
2016-02-01 14:10:00 +00:00
|
|
|
|
|
|
|
//screenlocker
|
|
|
|
#include <KScreenLocker/KsldApp>
|
|
|
|
|
2017-01-18 19:24:17 +00:00
|
|
|
#include <KGlobalAccel>
|
|
|
|
|
2016-02-01 14:10:00 +00:00
|
|
|
#include <linux/input.h>
|
|
|
|
|
2016-03-03 15:26:55 +00:00
|
|
|
Q_DECLARE_METATYPE(Qt::Orientation)
|
|
|
|
|
2016-02-01 14:10:00 +00:00
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
|
|
|
static const QString s_socketName = QStringLiteral("wayland_test_kwin_lock_screen-0");
|
|
|
|
|
|
|
|
class LockScreenTest : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
private Q_SLOTS:
|
|
|
|
void initTestCase();
|
|
|
|
void init();
|
|
|
|
void cleanup();
|
2020-05-08 08:26:27 +00:00
|
|
|
void testStackingOrder();
|
2016-02-01 14:10:00 +00:00
|
|
|
void testPointer();
|
2016-02-01 16:57:38 +00:00
|
|
|
void testPointerButton();
|
2016-02-02 12:50:13 +00:00
|
|
|
void testPointerAxis();
|
2016-02-08 15:52:22 +00:00
|
|
|
void testKeyboard();
|
2016-02-02 12:50:13 +00:00
|
|
|
void testScreenEdge();
|
2016-02-02 13:41:28 +00:00
|
|
|
void testEffects();
|
2016-02-08 11:36:39 +00:00
|
|
|
void testEffectsKeyboard();
|
2016-02-19 06:53:20 +00:00
|
|
|
void testEffectsKeyboardAutorepeat();
|
2016-02-03 08:36:12 +00:00
|
|
|
void testMoveWindow();
|
2016-02-04 08:06:15 +00:00
|
|
|
void testPointerShortcut();
|
|
|
|
void testAxisShortcut_data();
|
|
|
|
void testAxisShortcut();
|
2016-02-08 14:23:06 +00:00
|
|
|
void testKeyboardShortcut();
|
2016-02-10 15:43:06 +00:00
|
|
|
void testTouch();
|
2016-02-01 14:10:00 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
void unlock();
|
2016-02-02 15:11:21 +00:00
|
|
|
AbstractClient *showWindow();
|
2016-02-01 14:10:00 +00:00
|
|
|
KWayland::Client::ConnectionThread *m_connection = nullptr;
|
|
|
|
KWayland::Client::Compositor *m_compositor = nullptr;
|
|
|
|
KWayland::Client::Seat *m_seat = nullptr;
|
|
|
|
KWayland::Client::ShmPool *m_shm = nullptr;
|
|
|
|
};
|
|
|
|
|
2016-02-02 13:41:28 +00:00
|
|
|
class HelperEffect : public Effect
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
HelperEffect() {}
|
Run clang-tidy with modernize-use-override check
Summary:
Currently code base of kwin can be viewed as two pieces. One is very
ancient, and the other one is more modern, which uses new C++ features.
The main problem with the ancient code is that it was written before
C++11 era. So, no override or final keywords, lambdas, etc.
Quite recently, KDE compiler settings were changed to show a warning if
a virtual method has missing override keyword. As you might have already
guessed, this fired back at us because of that ancient code. We had
about 500 new compiler warnings.
A "solution" was proposed to that problem - disable -Wno-suggest-override
and the other similar warning for clang. It's hard to call a solution
because those warnings are disabled not only for the old code, but also
for new. This is not what we want!
The main argument for not actually fixing the problem was that git
history will be screwed as well because of human factor. While good git
history is a very important thing, we should not go crazy about it and
block every change that somehow alters git history. git blame allows to
specify starting revision for a reason.
The other argument (human factor) can be easily solved by using tools
such as clang-tidy. clang-tidy is a clang-based linter for C++. It can
be used for various things, e.g. fixing coding style(e.g. add missing
braces to if statements, readability-braces-around-statements check),
or in our case add missing override keywords.
Test Plan: Compiles.
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: davidedmundson, apol, romangg, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D22371
2019-07-22 16:52:26 +00:00
|
|
|
~HelperEffect() override {}
|
2016-02-02 13:41:28 +00:00
|
|
|
|
|
|
|
void windowInputMouseEvent(QEvent*) override {
|
|
|
|
emit inputEvent();
|
|
|
|
}
|
2016-02-08 11:36:39 +00:00
|
|
|
void grabbedKeyboardEvent(QKeyEvent *e) override {
|
|
|
|
emit keyEvent(e->text());
|
|
|
|
}
|
2016-02-02 13:41:28 +00:00
|
|
|
|
|
|
|
Q_SIGNALS:
|
|
|
|
void inputEvent();
|
2016-02-08 11:36:39 +00:00
|
|
|
void keyEvent(const QString&);
|
2016-02-02 13:41:28 +00:00
|
|
|
};
|
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
#define LOCK \
|
|
|
|
QVERIFY(!waylandServer()->isScreenLocked()); \
|
|
|
|
QSignalSpy lockStateChangedSpy(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged); \
|
|
|
|
QVERIFY(lockStateChangedSpy.isValid()); \
|
|
|
|
ScreenLocker::KSldApp::self()->lock(ScreenLocker::EstablishLock::Immediate); \
|
|
|
|
QCOMPARE(lockStateChangedSpy.count(), 1); \
|
|
|
|
QVERIFY(waylandServer()->isScreenLocked());
|
|
|
|
|
|
|
|
#define UNLOCK \
|
2016-02-17 08:41:17 +00:00
|
|
|
int expectedLockCount = 1; \
|
|
|
|
if (ScreenLocker::KSldApp::self()->lockState() == ScreenLocker::KSldApp::Locked) { \
|
|
|
|
expectedLockCount = 2; \
|
|
|
|
} \
|
|
|
|
QCOMPARE(lockStateChangedSpy.count(), expectedLockCount); \
|
2016-02-02 15:11:21 +00:00
|
|
|
unlock(); \
|
2016-02-17 08:41:17 +00:00
|
|
|
if (lockStateChangedSpy.count() < expectedLockCount + 1) { \
|
2016-02-02 15:11:21 +00:00
|
|
|
QVERIFY(lockStateChangedSpy.wait()); \
|
|
|
|
} \
|
2016-02-17 08:41:17 +00:00
|
|
|
QCOMPARE(lockStateChangedSpy.count(), expectedLockCount + 1); \
|
2016-02-02 15:11:21 +00:00
|
|
|
QVERIFY(!waylandServer()->isScreenLocked());
|
|
|
|
|
|
|
|
#define MOTION(target) \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->pointerMotion(target, timestamp++)
|
2016-02-02 15:11:21 +00:00
|
|
|
|
|
|
|
#define PRESS \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->pointerButtonPressed(BTN_LEFT, timestamp++)
|
2016-02-02 15:11:21 +00:00
|
|
|
|
|
|
|
#define RELEASE \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->pointerButtonReleased(BTN_LEFT, timestamp++)
|
2016-02-02 13:41:28 +00:00
|
|
|
|
2016-02-08 11:36:39 +00:00
|
|
|
#define KEYPRESS( key ) \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyPressed(key, timestamp++)
|
2016-02-08 11:36:39 +00:00
|
|
|
|
|
|
|
#define KEYRELEASE( key ) \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyReleased(key, timestamp++)
|
2016-02-08 11:36:39 +00:00
|
|
|
|
2016-02-01 14:10:00 +00:00
|
|
|
void LockScreenTest::unlock()
|
|
|
|
{
|
|
|
|
using namespace ScreenLocker;
|
|
|
|
const auto children = KSldApp::self()->children();
|
|
|
|
for (auto it = children.begin(); it != children.end(); ++it) {
|
|
|
|
if (qstrcmp((*it)->metaObject()->className(), "LogindIntegration") != 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
QMetaObject::invokeMethod(*it, "requestUnlock");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
AbstractClient *LockScreenTest::showWindow()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
#define VERIFY(statement) \
|
|
|
|
if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__))\
|
|
|
|
return nullptr;
|
|
|
|
#define COMPARE(actual, expected) \
|
|
|
|
if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
|
|
|
|
return nullptr;
|
|
|
|
|
2016-06-30 11:32:54 +00:00
|
|
|
Surface *surface = Test::createSurface(m_compositor);
|
2016-02-02 15:11:21 +00:00
|
|
|
VERIFY(surface);
|
2019-08-27 15:01:14 +00:00
|
|
|
XdgShellSurface *shellSurface = Test::createXdgShellStableSurface(surface, surface);
|
2016-02-02 15:11:21 +00:00
|
|
|
VERIFY(shellSurface);
|
|
|
|
// let's render
|
2016-07-01 07:54:44 +00:00
|
|
|
auto c = Test::renderAndWaitForShown(surface, QSize(100, 50), Qt::blue);
|
2016-02-02 15:11:21 +00:00
|
|
|
|
|
|
|
VERIFY(c);
|
2016-07-01 07:54:44 +00:00
|
|
|
COMPARE(workspace()->activeClient(), c);
|
2016-02-02 15:11:21 +00:00
|
|
|
|
|
|
|
#undef VERIFY
|
|
|
|
#undef COMPARE
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2016-02-01 14:10:00 +00:00
|
|
|
void LockScreenTest::initTestCase()
|
|
|
|
{
|
|
|
|
qRegisterMetaType<KWin::AbstractClient*>();
|
2020-07-07 09:32:29 +00:00
|
|
|
QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
|
|
|
|
QVERIFY(applicationStartedSpy.isValid());
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024));
|
2016-07-04 07:09:03 +00:00
|
|
|
QVERIFY(waylandServer()->init(s_socketName.toLocal8Bit()));
|
2019-08-26 21:16:53 +00:00
|
|
|
QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2));
|
2016-02-01 14:10:00 +00:00
|
|
|
|
2018-11-17 08:52:53 +00:00
|
|
|
qputenv("KWIN_COMPOSE", QByteArrayLiteral("O2"));
|
2016-02-01 14:10:00 +00:00
|
|
|
kwinApp()->start();
|
2020-07-07 09:32:29 +00:00
|
|
|
QVERIFY(applicationStartedSpy.wait());
|
2016-02-01 14:10:00 +00:00
|
|
|
QCOMPARE(screens()->count(), 2);
|
|
|
|
QCOMPARE(screens()->geometry(0), QRect(0, 0, 1280, 1024));
|
|
|
|
QCOMPARE(screens()->geometry(1), QRect(1280, 0, 1280, 1024));
|
|
|
|
setenv("QT_QPA_PLATFORM", "wayland", true);
|
|
|
|
waylandServer()->initWorkspace();
|
2019-01-06 15:34:10 +00:00
|
|
|
|
|
|
|
auto scene = KWin::Compositor::self()->scene();
|
|
|
|
QVERIFY(scene);
|
|
|
|
QCOMPARE(scene->compositingType(), KWin::OpenGL2Compositing);
|
2016-02-01 14:10:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void LockScreenTest::init()
|
|
|
|
{
|
2016-12-03 13:31:14 +00:00
|
|
|
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat));
|
2016-06-30 11:32:54 +00:00
|
|
|
QVERIFY(Test::waitForWaylandPointer());
|
|
|
|
m_connection = Test::waylandConnection();
|
|
|
|
m_compositor = Test::waylandCompositor();
|
|
|
|
m_shm = Test::waylandShmPool();
|
|
|
|
m_seat = Test::waylandSeat();
|
2016-02-01 14:10:00 +00:00
|
|
|
|
|
|
|
screens()->setCurrent(0);
|
2020-04-02 16:18:01 +00:00
|
|
|
Cursors::self()->mouse()->setPos(QPoint(640, 512));
|
2016-02-01 14:10:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void LockScreenTest::cleanup()
|
|
|
|
{
|
2016-06-30 11:32:54 +00:00
|
|
|
Test::destroyWaylandConnection();
|
2016-02-01 14:10:00 +00:00
|
|
|
}
|
|
|
|
|
2020-05-08 08:26:27 +00:00
|
|
|
void LockScreenTest::testStackingOrder()
|
|
|
|
{
|
|
|
|
// This test verifies that the lockscreen greeter is placed above other windows.
|
|
|
|
|
2020-07-22 18:35:41 +00:00
|
|
|
QSignalSpy clientAddedSpy(workspace(), &Workspace::clientAdded);
|
2020-05-08 08:26:27 +00:00
|
|
|
QVERIFY(clientAddedSpy.isValid());
|
|
|
|
|
|
|
|
LOCK
|
|
|
|
QVERIFY(clientAddedSpy.wait());
|
|
|
|
|
|
|
|
AbstractClient *client = clientAddedSpy.first().first().value<AbstractClient *>();
|
|
|
|
QVERIFY(client);
|
|
|
|
QVERIFY(client->isLockScreen());
|
|
|
|
QCOMPARE(client->layer(), UnmanagedLayer);
|
|
|
|
|
|
|
|
UNLOCK
|
|
|
|
}
|
|
|
|
|
2016-02-01 14:10:00 +00:00
|
|
|
void LockScreenTest::testPointer()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
|
|
|
|
QScopedPointer<Pointer> pointer(m_seat->createPointer());
|
|
|
|
QVERIFY(!pointer.isNull());
|
|
|
|
QSignalSpy enteredSpy(pointer.data(), &Pointer::entered);
|
|
|
|
QVERIFY(enteredSpy.isValid());
|
|
|
|
QSignalSpy leftSpy(pointer.data(), &Pointer::left);
|
|
|
|
QVERIFY(leftSpy.isValid());
|
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
AbstractClient *c = showWindow();
|
2016-02-01 14:10:00 +00:00
|
|
|
QVERIFY(c);
|
|
|
|
|
|
|
|
// first move cursor into the center of the window
|
|
|
|
quint32 timestamp = 1;
|
2019-09-27 10:01:10 +00:00
|
|
|
MOTION(c->frameGeometry().center());
|
2016-02-01 14:10:00 +00:00
|
|
|
QVERIFY(enteredSpy.wait());
|
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
LOCK
|
2016-02-01 14:10:00 +00:00
|
|
|
|
2016-11-25 06:56:24 +00:00
|
|
|
QVERIFY(leftSpy.wait());
|
2016-02-01 14:10:00 +00:00
|
|
|
QCOMPARE(leftSpy.count(), 1);
|
|
|
|
|
|
|
|
// simulate moving out in and out again
|
2019-09-27 10:01:10 +00:00
|
|
|
MOTION(c->frameGeometry().center());
|
|
|
|
MOTION(c->frameGeometry().bottomRight() + QPoint(100, 100));
|
|
|
|
MOTION(c->frameGeometry().bottomRight() + QPoint(100, 100));
|
2016-11-25 06:56:24 +00:00
|
|
|
QVERIFY(!leftSpy.wait());
|
2016-02-01 14:10:00 +00:00
|
|
|
QCOMPARE(leftSpy.count(), 1);
|
|
|
|
QCOMPARE(enteredSpy.count(), 1);
|
|
|
|
|
|
|
|
// go back on the window
|
2019-09-27 10:01:10 +00:00
|
|
|
MOTION(c->frameGeometry().center());
|
2016-02-01 14:10:00 +00:00
|
|
|
// and unlock
|
2016-02-02 15:11:21 +00:00
|
|
|
UNLOCK
|
2016-02-01 14:10:00 +00:00
|
|
|
|
2016-11-25 06:56:24 +00:00
|
|
|
QVERIFY(enteredSpy.wait());
|
2016-02-01 14:10:00 +00:00
|
|
|
QCOMPARE(enteredSpy.count(), 2);
|
|
|
|
// move on the window
|
2019-09-27 10:01:10 +00:00
|
|
|
MOTION(c->frameGeometry().center() + QPoint(100, 100));
|
2016-02-09 16:18:58 +00:00
|
|
|
QVERIFY(leftSpy.wait());
|
2019-09-27 10:01:10 +00:00
|
|
|
MOTION(c->frameGeometry().center());
|
2016-02-09 16:18:58 +00:00
|
|
|
QVERIFY(enteredSpy.wait());
|
|
|
|
QCOMPARE(enteredSpy.count(), 3);
|
2016-02-01 14:10:00 +00:00
|
|
|
}
|
|
|
|
|
2016-02-01 16:57:38 +00:00
|
|
|
void LockScreenTest::testPointerButton()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
|
|
|
|
QScopedPointer<Pointer> pointer(m_seat->createPointer());
|
|
|
|
QVERIFY(!pointer.isNull());
|
2016-08-08 09:12:22 +00:00
|
|
|
QSignalSpy enteredSpy(pointer.data(), &Pointer::entered);
|
|
|
|
QVERIFY(enteredSpy.isValid());
|
2016-02-01 16:57:38 +00:00
|
|
|
QSignalSpy buttonChangedSpy(pointer.data(), &Pointer::buttonStateChanged);
|
|
|
|
QVERIFY(buttonChangedSpy.isValid());
|
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
AbstractClient *c = showWindow();
|
2016-02-01 16:57:38 +00:00
|
|
|
QVERIFY(c);
|
|
|
|
|
|
|
|
// first move cursor into the center of the window
|
|
|
|
quint32 timestamp = 1;
|
2019-09-27 10:01:10 +00:00
|
|
|
MOTION(c->frameGeometry().center());
|
2016-08-08 09:12:22 +00:00
|
|
|
QVERIFY(enteredSpy.wait());
|
2016-02-01 16:57:38 +00:00
|
|
|
// and simulate a click
|
2016-02-02 15:11:21 +00:00
|
|
|
PRESS;
|
2016-02-01 16:57:38 +00:00
|
|
|
QVERIFY(buttonChangedSpy.wait());
|
2016-02-02 15:11:21 +00:00
|
|
|
RELEASE;
|
2016-02-01 16:57:38 +00:00
|
|
|
QVERIFY(buttonChangedSpy.wait());
|
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
LOCK
|
2016-02-01 16:57:38 +00:00
|
|
|
|
|
|
|
// and simulate a click
|
2016-02-02 15:11:21 +00:00
|
|
|
PRESS;
|
2016-11-25 06:56:24 +00:00
|
|
|
QVERIFY(!buttonChangedSpy.wait());
|
2016-02-02 15:11:21 +00:00
|
|
|
RELEASE;
|
2016-11-25 06:56:24 +00:00
|
|
|
QVERIFY(!buttonChangedSpy.wait());
|
2016-02-01 16:57:38 +00:00
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
UNLOCK
|
2016-08-08 09:12:22 +00:00
|
|
|
QVERIFY(enteredSpy.wait());
|
|
|
|
QCOMPARE(enteredSpy.count(), 2);
|
2016-02-02 09:22:37 +00:00
|
|
|
|
2016-02-01 16:57:38 +00:00
|
|
|
// and click again
|
2016-02-02 15:11:21 +00:00
|
|
|
PRESS;
|
2016-02-01 16:57:38 +00:00
|
|
|
QVERIFY(buttonChangedSpy.wait());
|
2016-02-02 15:11:21 +00:00
|
|
|
RELEASE;
|
2016-02-01 16:57:38 +00:00
|
|
|
QVERIFY(buttonChangedSpy.wait());
|
|
|
|
}
|
|
|
|
|
2016-02-02 12:50:13 +00:00
|
|
|
void LockScreenTest::testPointerAxis()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
|
|
|
|
QScopedPointer<Pointer> pointer(m_seat->createPointer());
|
|
|
|
QVERIFY(!pointer.isNull());
|
|
|
|
QSignalSpy axisChangedSpy(pointer.data(), &Pointer::axisChanged);
|
|
|
|
QVERIFY(axisChangedSpy.isValid());
|
2016-08-08 09:12:22 +00:00
|
|
|
QSignalSpy enteredSpy(pointer.data(), &Pointer::entered);
|
|
|
|
QVERIFY(enteredSpy.isValid());
|
2016-02-02 12:50:13 +00:00
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
AbstractClient *c = showWindow();
|
2016-02-02 12:50:13 +00:00
|
|
|
QVERIFY(c);
|
|
|
|
|
|
|
|
// first move cursor into the center of the window
|
|
|
|
quint32 timestamp = 1;
|
2019-09-27 10:01:10 +00:00
|
|
|
MOTION(c->frameGeometry().center());
|
2016-08-08 09:12:22 +00:00
|
|
|
QVERIFY(enteredSpy.wait());
|
2016-02-02 12:50:13 +00:00
|
|
|
// and simulate axis
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->pointerAxisHorizontal(5.0, timestamp++);
|
2016-02-02 12:50:13 +00:00
|
|
|
QVERIFY(axisChangedSpy.wait());
|
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
LOCK
|
2016-02-02 12:50:13 +00:00
|
|
|
|
|
|
|
// and simulate axis
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->pointerAxisHorizontal(5.0, timestamp++);
|
2016-02-02 12:50:13 +00:00
|
|
|
QVERIFY(!axisChangedSpy.wait(100));
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->pointerAxisVertical(5.0, timestamp++);
|
2016-02-02 12:50:13 +00:00
|
|
|
QVERIFY(!axisChangedSpy.wait(100));
|
|
|
|
|
|
|
|
// and unlock
|
2016-02-02 15:11:21 +00:00
|
|
|
UNLOCK
|
2016-08-08 09:12:22 +00:00
|
|
|
QVERIFY(enteredSpy.wait());
|
|
|
|
QCOMPARE(enteredSpy.count(), 2);
|
2016-02-02 12:50:13 +00:00
|
|
|
|
|
|
|
// and move axis again
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->pointerAxisHorizontal(5.0, timestamp++);
|
2016-02-02 12:50:13 +00:00
|
|
|
QVERIFY(axisChangedSpy.wait());
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->pointerAxisVertical(5.0, timestamp++);
|
2016-02-02 12:50:13 +00:00
|
|
|
QVERIFY(axisChangedSpy.wait());
|
|
|
|
}
|
|
|
|
|
2016-02-08 15:52:22 +00:00
|
|
|
void LockScreenTest::testKeyboard()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
|
|
|
|
QScopedPointer<Keyboard> keyboard(m_seat->createKeyboard());
|
|
|
|
QVERIFY(!keyboard.isNull());
|
|
|
|
QSignalSpy enteredSpy(keyboard.data(), &Keyboard::entered);
|
|
|
|
QVERIFY(enteredSpy.isValid());
|
|
|
|
QSignalSpy leftSpy(keyboard.data(), &Keyboard::left);
|
|
|
|
QVERIFY(leftSpy.isValid());
|
|
|
|
QSignalSpy keyChangedSpy(keyboard.data(), &Keyboard::keyChanged);
|
|
|
|
QVERIFY(keyChangedSpy.isValid());
|
|
|
|
|
|
|
|
AbstractClient *c = showWindow();
|
|
|
|
QVERIFY(c);
|
|
|
|
QVERIFY(enteredSpy.wait());
|
|
|
|
QTRY_COMPARE(enteredSpy.count(), 1);
|
|
|
|
|
|
|
|
quint32 timestamp = 1;
|
|
|
|
KEYPRESS(KEY_A);
|
|
|
|
QVERIFY(keyChangedSpy.wait());
|
|
|
|
QCOMPARE(keyChangedSpy.count(), 1);
|
|
|
|
QCOMPARE(keyChangedSpy.at(0).at(0).value<quint32>(), quint32(KEY_A));
|
|
|
|
QCOMPARE(keyChangedSpy.at(0).at(1).value<Keyboard::KeyState>(), Keyboard::KeyState::Pressed);
|
|
|
|
QCOMPARE(keyChangedSpy.at(0).at(2).value<quint32>(), quint32(1));
|
|
|
|
KEYRELEASE(KEY_A);
|
|
|
|
QVERIFY(keyChangedSpy.wait());
|
|
|
|
QCOMPARE(keyChangedSpy.count(), 2);
|
|
|
|
QCOMPARE(keyChangedSpy.at(1).at(0).value<quint32>(), quint32(KEY_A));
|
|
|
|
QCOMPARE(keyChangedSpy.at(1).at(1).value<Keyboard::KeyState>(), Keyboard::KeyState::Released);
|
|
|
|
QCOMPARE(keyChangedSpy.at(1).at(2).value<quint32>(), quint32(2));
|
|
|
|
|
|
|
|
LOCK
|
2016-02-10 13:40:56 +00:00
|
|
|
QVERIFY(leftSpy.wait());
|
2016-02-08 15:52:22 +00:00
|
|
|
KEYPRESS(KEY_B);
|
|
|
|
KEYRELEASE(KEY_B);
|
|
|
|
QCOMPARE(leftSpy.count(), 1);
|
|
|
|
QCOMPARE(keyChangedSpy.count(), 2);
|
|
|
|
|
|
|
|
UNLOCK
|
2016-02-10 13:40:56 +00:00
|
|
|
QVERIFY(enteredSpy.wait());
|
|
|
|
QCOMPARE(enteredSpy.count(), 2);
|
2016-02-08 15:52:22 +00:00
|
|
|
KEYPRESS(KEY_C);
|
|
|
|
QVERIFY(keyChangedSpy.wait());
|
|
|
|
QCOMPARE(keyChangedSpy.count(), 3);
|
|
|
|
KEYRELEASE(KEY_C);
|
|
|
|
QVERIFY(keyChangedSpy.wait());
|
|
|
|
QCOMPARE(keyChangedSpy.count(), 4);
|
|
|
|
QCOMPARE(enteredSpy.count(), 2);
|
|
|
|
QCOMPARE(keyChangedSpy.at(2).at(0).value<quint32>(), quint32(KEY_C));
|
|
|
|
QCOMPARE(keyChangedSpy.at(3).at(0).value<quint32>(), quint32(KEY_C));
|
|
|
|
QCOMPARE(keyChangedSpy.at(2).at(2).value<quint32>(), quint32(5));
|
|
|
|
QCOMPARE(keyChangedSpy.at(3).at(2).value<quint32>(), quint32(6));
|
|
|
|
QCOMPARE(keyChangedSpy.at(2).at(1).value<Keyboard::KeyState>(), Keyboard::KeyState::Pressed);
|
|
|
|
QCOMPARE(keyChangedSpy.at(3).at(1).value<Keyboard::KeyState>(), Keyboard::KeyState::Released);
|
|
|
|
}
|
|
|
|
|
2016-02-02 12:50:13 +00:00
|
|
|
void LockScreenTest::testScreenEdge()
|
|
|
|
{
|
|
|
|
QSignalSpy screenEdgeSpy(ScreenEdges::self(), &ScreenEdges::approaching);
|
|
|
|
QVERIFY(screenEdgeSpy.isValid());
|
|
|
|
QCOMPARE(screenEdgeSpy.count(), 0);
|
|
|
|
|
|
|
|
quint32 timestamp = 1;
|
2016-02-02 15:11:21 +00:00
|
|
|
MOTION(QPoint(5, 5));
|
2016-02-02 12:50:13 +00:00
|
|
|
QCOMPARE(screenEdgeSpy.count(), 1);
|
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
LOCK
|
2016-02-02 12:50:13 +00:00
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
MOTION(QPoint(4, 4));
|
2016-02-02 12:50:13 +00:00
|
|
|
QCOMPARE(screenEdgeSpy.count(), 1);
|
|
|
|
|
|
|
|
// and unlock
|
2016-02-02 15:11:21 +00:00
|
|
|
UNLOCK
|
2016-02-02 12:50:13 +00:00
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
MOTION(QPoint(5, 5));
|
2016-02-02 12:50:13 +00:00
|
|
|
QCOMPARE(screenEdgeSpy.count(), 2);
|
|
|
|
}
|
|
|
|
|
2016-02-02 13:41:28 +00:00
|
|
|
void LockScreenTest::testEffects()
|
|
|
|
{
|
|
|
|
QScopedPointer<HelperEffect> effect(new HelperEffect);
|
|
|
|
QSignalSpy inputSpy(effect.data(), &HelperEffect::inputEvent);
|
|
|
|
QVERIFY(inputSpy.isValid());
|
|
|
|
effects->startMouseInterception(effect.data(), Qt::ArrowCursor);
|
|
|
|
|
|
|
|
quint32 timestamp = 1;
|
|
|
|
QCOMPARE(inputSpy.count(), 0);
|
2016-02-02 15:11:21 +00:00
|
|
|
MOTION(QPoint(5, 5));
|
2016-02-02 13:41:28 +00:00
|
|
|
QCOMPARE(inputSpy.count(), 1);
|
|
|
|
// simlate click
|
2016-02-02 15:11:21 +00:00
|
|
|
PRESS;
|
2016-02-02 13:41:28 +00:00
|
|
|
QCOMPARE(inputSpy.count(), 2);
|
2016-02-02 15:11:21 +00:00
|
|
|
RELEASE;
|
2016-02-02 13:41:28 +00:00
|
|
|
QCOMPARE(inputSpy.count(), 3);
|
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
LOCK
|
2016-02-02 13:41:28 +00:00
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
MOTION(QPoint(6, 6));
|
2016-02-02 13:41:28 +00:00
|
|
|
QCOMPARE(inputSpy.count(), 3);
|
|
|
|
// simlate click
|
2016-02-02 15:11:21 +00:00
|
|
|
PRESS;
|
2016-02-02 13:41:28 +00:00
|
|
|
QCOMPARE(inputSpy.count(), 3);
|
2016-02-02 15:11:21 +00:00
|
|
|
RELEASE;
|
2016-02-02 13:41:28 +00:00
|
|
|
QCOMPARE(inputSpy.count(), 3);
|
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
UNLOCK
|
2016-02-02 13:41:28 +00:00
|
|
|
|
2016-02-02 15:11:21 +00:00
|
|
|
MOTION(QPoint(5, 5));
|
2016-02-02 13:41:28 +00:00
|
|
|
QCOMPARE(inputSpy.count(), 4);
|
|
|
|
// simlate click
|
2016-02-02 15:11:21 +00:00
|
|
|
PRESS;
|
2016-02-02 13:41:28 +00:00
|
|
|
QCOMPARE(inputSpy.count(), 5);
|
2016-02-02 15:11:21 +00:00
|
|
|
RELEASE;
|
2016-02-02 13:41:28 +00:00
|
|
|
QCOMPARE(inputSpy.count(), 6);
|
|
|
|
|
|
|
|
effects->stopMouseInterception(effect.data());
|
|
|
|
}
|
|
|
|
|
2016-02-08 11:36:39 +00:00
|
|
|
void LockScreenTest::testEffectsKeyboard()
|
|
|
|
{
|
|
|
|
QScopedPointer<HelperEffect> effect(new HelperEffect);
|
|
|
|
QSignalSpy inputSpy(effect.data(), &HelperEffect::keyEvent);
|
|
|
|
QVERIFY(inputSpy.isValid());
|
|
|
|
effects->grabKeyboard(effect.data());
|
|
|
|
|
|
|
|
quint32 timestamp = 1;
|
|
|
|
KEYPRESS(KEY_A);
|
|
|
|
QCOMPARE(inputSpy.count(), 1);
|
|
|
|
QCOMPARE(inputSpy.first().first().toString(), QStringLiteral("a"));
|
|
|
|
KEYRELEASE(KEY_A);
|
|
|
|
QCOMPARE(inputSpy.count(), 2);
|
|
|
|
QCOMPARE(inputSpy.first().first().toString(), QStringLiteral("a"));
|
|
|
|
QCOMPARE(inputSpy.at(1).first().toString(), QStringLiteral("a"));
|
|
|
|
|
|
|
|
LOCK
|
|
|
|
KEYPRESS(KEY_B);
|
|
|
|
QCOMPARE(inputSpy.count(), 2);
|
|
|
|
KEYRELEASE(KEY_B);
|
|
|
|
QCOMPARE(inputSpy.count(), 2);
|
|
|
|
|
|
|
|
UNLOCK
|
|
|
|
KEYPRESS(KEY_C);
|
|
|
|
QCOMPARE(inputSpy.count(), 3);
|
|
|
|
QCOMPARE(inputSpy.first().first().toString(), QStringLiteral("a"));
|
|
|
|
QCOMPARE(inputSpy.at(1).first().toString(), QStringLiteral("a"));
|
|
|
|
QCOMPARE(inputSpy.at(2).first().toString(), QStringLiteral("c"));
|
|
|
|
KEYRELEASE(KEY_C);
|
|
|
|
QCOMPARE(inputSpy.count(), 4);
|
|
|
|
QCOMPARE(inputSpy.first().first().toString(), QStringLiteral("a"));
|
|
|
|
QCOMPARE(inputSpy.at(1).first().toString(), QStringLiteral("a"));
|
|
|
|
QCOMPARE(inputSpy.at(2).first().toString(), QStringLiteral("c"));
|
|
|
|
QCOMPARE(inputSpy.at(3).first().toString(), QStringLiteral("c"));
|
|
|
|
|
|
|
|
effects->ungrabKeyboard();
|
|
|
|
}
|
|
|
|
|
2016-02-19 06:53:20 +00:00
|
|
|
void LockScreenTest::testEffectsKeyboardAutorepeat()
|
|
|
|
{
|
|
|
|
// this test is just like testEffectsKeyboard, but tests auto repeat key events
|
|
|
|
// while the key is pressed the Effect should get auto repeated events
|
|
|
|
// but the lock screen should filter them out
|
|
|
|
QScopedPointer<HelperEffect> effect(new HelperEffect);
|
|
|
|
QSignalSpy inputSpy(effect.data(), &HelperEffect::keyEvent);
|
|
|
|
QVERIFY(inputSpy.isValid());
|
|
|
|
effects->grabKeyboard(effect.data());
|
|
|
|
|
|
|
|
// we need to configure the key repeat first. It is only enabled on libinput
|
2020-11-06 04:46:26 +00:00
|
|
|
waylandServer()->seat()->keyboard()->setRepeatInfo(25, 300);
|
2016-02-19 06:53:20 +00:00
|
|
|
|
|
|
|
quint32 timestamp = 1;
|
|
|
|
KEYPRESS(KEY_A);
|
|
|
|
QCOMPARE(inputSpy.count(), 1);
|
|
|
|
QCOMPARE(inputSpy.first().first().toString(), QStringLiteral("a"));
|
|
|
|
QVERIFY(inputSpy.wait());
|
|
|
|
QVERIFY(inputSpy.count() > 1);
|
|
|
|
// and still more events
|
|
|
|
QVERIFY(inputSpy.wait());
|
|
|
|
QCOMPARE(inputSpy.at(1).first().toString(), QStringLiteral("a"));
|
|
|
|
|
|
|
|
// now release
|
|
|
|
inputSpy.clear();
|
|
|
|
KEYRELEASE(KEY_A);
|
|
|
|
QCOMPARE(inputSpy.count(), 1);
|
|
|
|
|
|
|
|
// while locked key repeat should not pass any events to the Effect
|
|
|
|
LOCK
|
|
|
|
KEYPRESS(KEY_B);
|
|
|
|
QVERIFY(!inputSpy.wait(200));
|
|
|
|
KEYRELEASE(KEY_B);
|
|
|
|
QVERIFY(!inputSpy.wait(200));
|
|
|
|
|
|
|
|
UNLOCK
|
|
|
|
// don't test again, that's covered by testEffectsKeyboard
|
|
|
|
|
|
|
|
effects->ungrabKeyboard();
|
|
|
|
}
|
|
|
|
|
2016-02-03 08:36:12 +00:00
|
|
|
void LockScreenTest::testMoveWindow()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
AbstractClient *c = showWindow();
|
|
|
|
QVERIFY(c);
|
|
|
|
QSignalSpy clientStepUserMovedResizedSpy(c, &AbstractClient::clientStepUserMovedResized);
|
|
|
|
QVERIFY(clientStepUserMovedResizedSpy.isValid());
|
|
|
|
quint32 timestamp = 1;
|
|
|
|
|
|
|
|
workspace()->slotWindowMove();
|
2019-04-18 12:28:11 +00:00
|
|
|
QCOMPARE(workspace()->moveResizeClient(), c);
|
2016-02-03 08:36:12 +00:00
|
|
|
QVERIFY(c->isMove());
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyPressed(KEY_RIGHT, timestamp++);
|
|
|
|
kwinApp()->platform()->keyboardKeyReleased(KEY_RIGHT, timestamp++);
|
2016-02-03 08:36:12 +00:00
|
|
|
QEXPECT_FAIL("", "First event is ignored", Continue);
|
|
|
|
QCOMPARE(clientStepUserMovedResizedSpy.count(), 1);
|
|
|
|
|
|
|
|
// TODO adjust once the expected fail is fixed
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyPressed(KEY_RIGHT, timestamp++);
|
|
|
|
kwinApp()->platform()->keyboardKeyReleased(KEY_RIGHT, timestamp++);
|
2016-02-03 08:36:12 +00:00
|
|
|
QCOMPARE(clientStepUserMovedResizedSpy.count(), 1);
|
|
|
|
|
|
|
|
// while locking our window should continue to be in move resize
|
|
|
|
LOCK
|
2019-04-18 12:28:11 +00:00
|
|
|
QCOMPARE(workspace()->moveResizeClient(), c);
|
2016-02-03 08:36:12 +00:00
|
|
|
QVERIFY(c->isMove());
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyPressed(KEY_RIGHT, timestamp++);
|
|
|
|
kwinApp()->platform()->keyboardKeyReleased(KEY_RIGHT, timestamp++);
|
2016-02-03 08:36:12 +00:00
|
|
|
QCOMPARE(clientStepUserMovedResizedSpy.count(), 1);
|
|
|
|
|
|
|
|
UNLOCK
|
2019-04-18 12:28:11 +00:00
|
|
|
QCOMPARE(workspace()->moveResizeClient(), c);
|
2016-02-03 08:36:12 +00:00
|
|
|
QVERIFY(c->isMove());
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyPressed(KEY_RIGHT, timestamp++);
|
|
|
|
kwinApp()->platform()->keyboardKeyReleased(KEY_RIGHT, timestamp++);
|
2016-02-03 08:36:12 +00:00
|
|
|
QCOMPARE(clientStepUserMovedResizedSpy.count(), 2);
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyPressed(KEY_ESC, timestamp++);
|
|
|
|
kwinApp()->platform()->keyboardKeyReleased(KEY_ESC, timestamp++);
|
2016-02-03 08:36:12 +00:00
|
|
|
QVERIFY(!c->isMove());
|
|
|
|
}
|
|
|
|
|
2016-02-04 08:06:15 +00:00
|
|
|
void LockScreenTest::testPointerShortcut()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
QScopedPointer<QAction> action(new QAction(nullptr));
|
|
|
|
QSignalSpy actionSpy(action.data(), &QAction::triggered);
|
|
|
|
QVERIFY(actionSpy.isValid());
|
|
|
|
input()->registerPointerShortcut(Qt::MetaModifier, Qt::LeftButton, action.data());
|
|
|
|
|
|
|
|
// try to trigger the shortcut
|
|
|
|
quint32 timestamp = 1;
|
|
|
|
#define PERFORM(expectedCount) \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTMETA, timestamp++); \
|
2016-02-04 08:06:15 +00:00
|
|
|
PRESS; \
|
|
|
|
QCoreApplication::instance()->processEvents(); \
|
|
|
|
QCOMPARE(actionSpy.count(), expectedCount); \
|
|
|
|
RELEASE; \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTMETA, timestamp++); \
|
2016-02-04 08:06:15 +00:00
|
|
|
QCoreApplication::instance()->processEvents(); \
|
|
|
|
QCOMPARE(actionSpy.count(), expectedCount);
|
|
|
|
|
|
|
|
PERFORM(1)
|
|
|
|
|
|
|
|
// now the same thing with a locked screen
|
|
|
|
LOCK
|
|
|
|
PERFORM(1)
|
|
|
|
|
|
|
|
// and as unlocked
|
|
|
|
UNLOCK
|
|
|
|
PERFORM(2)
|
|
|
|
#undef PERFORM
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void LockScreenTest::testAxisShortcut_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<Qt::Orientation>("direction");
|
|
|
|
QTest::addColumn<int>("sign");
|
|
|
|
|
|
|
|
QTest::newRow("up") << Qt::Vertical << 1;
|
|
|
|
QTest::newRow("down") << Qt::Vertical << -1;
|
|
|
|
QTest::newRow("left") << Qt::Horizontal << 1;
|
|
|
|
QTest::newRow("right") << Qt::Horizontal << -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LockScreenTest::testAxisShortcut()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
QScopedPointer<QAction> action(new QAction(nullptr));
|
|
|
|
QSignalSpy actionSpy(action.data(), &QAction::triggered);
|
|
|
|
QVERIFY(actionSpy.isValid());
|
|
|
|
QFETCH(Qt::Orientation, direction);
|
|
|
|
QFETCH(int, sign);
|
|
|
|
PointerAxisDirection axisDirection = PointerAxisUp;
|
|
|
|
if (direction == Qt::Vertical) {
|
|
|
|
axisDirection = sign > 0 ? PointerAxisUp : PointerAxisDown;
|
|
|
|
} else {
|
|
|
|
axisDirection = sign > 0 ? PointerAxisLeft : PointerAxisRight;
|
|
|
|
}
|
|
|
|
input()->registerAxisShortcut(Qt::MetaModifier, axisDirection, action.data());
|
|
|
|
|
|
|
|
// try to trigger the shortcut
|
|
|
|
quint32 timestamp = 1;
|
|
|
|
#define PERFORM(expectedCount) \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTMETA, timestamp++); \
|
2016-02-04 08:06:15 +00:00
|
|
|
if (direction == Qt::Vertical) \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->pointerAxisVertical(sign * 5.0, timestamp++); \
|
2016-02-04 08:06:15 +00:00
|
|
|
else \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->pointerAxisHorizontal(sign * 5.0, timestamp++); \
|
2016-02-04 08:06:15 +00:00
|
|
|
QCoreApplication::instance()->processEvents(); \
|
|
|
|
QCOMPARE(actionSpy.count(), expectedCount); \
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTMETA, timestamp++); \
|
2016-02-04 08:06:15 +00:00
|
|
|
QCoreApplication::instance()->processEvents(); \
|
|
|
|
QCOMPARE(actionSpy.count(), expectedCount);
|
|
|
|
|
|
|
|
PERFORM(1)
|
|
|
|
|
|
|
|
// now the same thing with a locked screen
|
|
|
|
LOCK
|
|
|
|
PERFORM(1)
|
|
|
|
|
|
|
|
// and as unlocked
|
|
|
|
UNLOCK
|
|
|
|
PERFORM(2)
|
|
|
|
#undef PERFORM
|
|
|
|
}
|
|
|
|
|
2016-02-08 14:23:06 +00:00
|
|
|
void LockScreenTest::testKeyboardShortcut()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
QScopedPointer<QAction> action(new QAction(nullptr));
|
|
|
|
QSignalSpy actionSpy(action.data(), &QAction::triggered);
|
|
|
|
QVERIFY(actionSpy.isValid());
|
2017-01-18 19:24:17 +00:00
|
|
|
action->setProperty("componentName", QStringLiteral(KWIN_NAME));
|
|
|
|
action->setObjectName("LockScreenTest::testKeyboardShortcut");
|
|
|
|
KGlobalAccel::self()->setDefaultShortcut(action.data(), QList<QKeySequence>{Qt::CTRL + Qt::META + Qt::ALT + Qt::Key_Space});
|
|
|
|
KGlobalAccel::self()->setShortcut(action.data(), QList<QKeySequence>{Qt::CTRL + Qt::META + Qt::ALT + Qt::Key_Space},
|
|
|
|
KGlobalAccel::NoAutoloading);
|
2016-02-08 14:23:06 +00:00
|
|
|
|
|
|
|
// try to trigger the shortcut
|
|
|
|
quint32 timestamp = 1;
|
|
|
|
KEYPRESS(KEY_LEFTCTRL);
|
|
|
|
KEYPRESS(KEY_LEFTMETA);
|
|
|
|
KEYPRESS(KEY_LEFTALT);
|
|
|
|
KEYPRESS(KEY_SPACE);
|
2017-01-18 19:24:17 +00:00
|
|
|
QVERIFY(actionSpy.wait());
|
2016-02-08 14:23:06 +00:00
|
|
|
QCOMPARE(actionSpy.count(), 1);
|
|
|
|
KEYRELEASE(KEY_SPACE);
|
2017-01-18 19:24:17 +00:00
|
|
|
QVERIFY(!actionSpy.wait());
|
2016-02-08 14:23:06 +00:00
|
|
|
QCOMPARE(actionSpy.count(), 1);
|
|
|
|
|
|
|
|
LOCK
|
|
|
|
KEYPRESS(KEY_SPACE);
|
2017-01-18 19:24:17 +00:00
|
|
|
QVERIFY(!actionSpy.wait());
|
2016-02-08 14:23:06 +00:00
|
|
|
QCOMPARE(actionSpy.count(), 1);
|
|
|
|
KEYRELEASE(KEY_SPACE);
|
2017-01-18 19:24:17 +00:00
|
|
|
QVERIFY(!actionSpy.wait());
|
2016-02-08 14:23:06 +00:00
|
|
|
QCOMPARE(actionSpy.count(), 1);
|
|
|
|
|
|
|
|
UNLOCK
|
|
|
|
KEYPRESS(KEY_SPACE);
|
2017-01-18 19:24:17 +00:00
|
|
|
QVERIFY(actionSpy.wait());
|
2016-02-08 14:23:06 +00:00
|
|
|
QCOMPARE(actionSpy.count(), 2);
|
|
|
|
KEYRELEASE(KEY_SPACE);
|
2017-01-18 19:24:17 +00:00
|
|
|
QVERIFY(!actionSpy.wait());
|
2016-02-08 14:23:06 +00:00
|
|
|
QCOMPARE(actionSpy.count(), 2);
|
|
|
|
KEYRELEASE(KEY_LEFTCTRL);
|
|
|
|
KEYRELEASE(KEY_LEFTMETA);
|
|
|
|
KEYRELEASE(KEY_LEFTALT);
|
|
|
|
}
|
|
|
|
|
2016-02-10 15:43:06 +00:00
|
|
|
void LockScreenTest::testTouch()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
auto touch = m_seat->createTouch(m_seat);
|
|
|
|
QVERIFY(touch);
|
|
|
|
QVERIFY(touch->isValid());
|
|
|
|
AbstractClient *c = showWindow();
|
|
|
|
QVERIFY(c);
|
|
|
|
QSignalSpy sequenceStartedSpy(touch, &Touch::sequenceStarted);
|
|
|
|
QVERIFY(sequenceStartedSpy.isValid());
|
|
|
|
QSignalSpy cancelSpy(touch, &Touch::sequenceCanceled);
|
|
|
|
QVERIFY(cancelSpy.isValid());
|
|
|
|
QSignalSpy pointRemovedSpy(touch, &Touch::pointRemoved);
|
|
|
|
QVERIFY(pointRemovedSpy.isValid());
|
|
|
|
|
|
|
|
quint32 timestamp = 1;
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->touchDown(1, QPointF(25, 25), timestamp++);
|
2016-02-10 15:43:06 +00:00
|
|
|
QVERIFY(sequenceStartedSpy.wait());
|
|
|
|
QCOMPARE(sequenceStartedSpy.count(), 1);
|
|
|
|
|
|
|
|
LOCK
|
|
|
|
QVERIFY(cancelSpy.wait());
|
|
|
|
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->touchUp(1, timestamp++);
|
2016-02-10 15:43:06 +00:00
|
|
|
QVERIFY(!pointRemovedSpy.wait(100));
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->touchDown(1, QPointF(25, 25), timestamp++);
|
|
|
|
kwinApp()->platform()->touchMotion(1, QPointF(26, 26), timestamp++);
|
|
|
|
kwinApp()->platform()->touchUp(1, timestamp++);
|
2016-02-10 15:43:06 +00:00
|
|
|
|
|
|
|
UNLOCK
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->touchDown(1, QPointF(25, 25), timestamp++);
|
2016-02-10 15:43:06 +00:00
|
|
|
QVERIFY(sequenceStartedSpy.wait());
|
|
|
|
QCOMPARE(sequenceStartedSpy.count(), 2);
|
2016-04-07 06:28:35 +00:00
|
|
|
kwinApp()->platform()->touchUp(1, timestamp++);
|
2016-02-10 15:43:06 +00:00
|
|
|
QVERIFY(pointRemovedSpy.wait());
|
|
|
|
QCOMPARE(pointRemovedSpy.count(), 1);
|
|
|
|
}
|
|
|
|
|
2016-02-01 14:10:00 +00:00
|
|
|
}
|
|
|
|
|
2016-02-11 08:34:19 +00:00
|
|
|
WAYLANDTEST_MAIN(KWin::LockScreenTest)
|
2016-02-01 14:10:00 +00:00
|
|
|
#include "lockscreen.moc"
|