File indexing completed on 2024-11-10 04:55:58
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #include "kwin_wayland_test.h" 0010 0011 #include "input.h" 0012 #include "internalwindow.h" 0013 #include "keyboard_input.h" 0014 #include "pointer_input.h" 0015 #include "useractions.h" 0016 #include "wayland/keyboard.h" 0017 #include "wayland/seat.h" 0018 #include "wayland_server.h" 0019 #include "workspace.h" 0020 #include "x11window.h" 0021 #include "xkb.h" 0022 0023 #include <KWayland/Client/surface.h> 0024 0025 #include <KGlobalAccel> 0026 0027 #include <QAction> 0028 0029 #include <linux/input.h> 0030 #include <netwm.h> 0031 #include <xcb/xcb_icccm.h> 0032 0033 using namespace KWin; 0034 0035 static const QString s_socketName = QStringLiteral("wayland_test_kwin_globalshortcuts-0"); 0036 0037 class GlobalShortcutsTest : public QObject 0038 { 0039 Q_OBJECT 0040 private Q_SLOTS: 0041 void initTestCase(); 0042 void init(); 0043 void cleanup(); 0044 0045 void testNonLatinLayout_data(); 0046 void testNonLatinLayout(); 0047 void testConsumedShift(); 0048 void testRepeatedTrigger(); 0049 void testUserActionsMenu(); 0050 void testMetaShiftW(); 0051 void testComponseKey(); 0052 void testKeypad(); 0053 void testX11WindowShortcut(); 0054 void testWaylandWindowShortcut(); 0055 void testSetupWindowShortcut(); 0056 }; 0057 0058 void GlobalShortcutsTest::initTestCase() 0059 { 0060 qRegisterMetaType<KWin::Window *>(); 0061 qRegisterMetaType<KWin::InternalWindow *>(); 0062 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started); 0063 QVERIFY(waylandServer()->init(s_socketName)); 0064 Test::setOutputConfig({ 0065 QRect(0, 0, 1280, 1024), 0066 QRect(1280, 0, 1280, 1024), 0067 }); 0068 0069 kwinApp()->setConfig(KSharedConfig::openConfig(QString(), KConfig::SimpleConfig)); 0070 qputenv("KWIN_XKB_DEFAULT_KEYMAP", "1"); 0071 qputenv("XKB_DEFAULT_RULES", "evdev"); 0072 qputenv("XKB_DEFAULT_LAYOUT", "us,ru"); 0073 0074 kwinApp()->start(); 0075 QVERIFY(applicationStartedSpy.wait()); 0076 } 0077 0078 void GlobalShortcutsTest::init() 0079 { 0080 QVERIFY(Test::setupWaylandConnection()); 0081 workspace()->setActiveOutput(QPoint(640, 512)); 0082 KWin::input()->pointer()->warp(QPoint(640, 512)); 0083 0084 auto xkb = input()->keyboard()->xkb(); 0085 xkb->switchToLayout(0); 0086 } 0087 0088 void GlobalShortcutsTest::cleanup() 0089 { 0090 Test::destroyWaylandConnection(); 0091 } 0092 0093 Q_DECLARE_METATYPE(Qt::Modifier) 0094 0095 void GlobalShortcutsTest::testNonLatinLayout_data() 0096 { 0097 QTest::addColumn<int>("modifierKey"); 0098 QTest::addColumn<Qt::Modifier>("qtModifier"); 0099 QTest::addColumn<int>("key"); 0100 QTest::addColumn<Qt::Key>("qtKey"); 0101 0102 // KEY_W is "ц" in the RU layout and "w" in the US layout 0103 // KEY_GRAVE is "ё" in the RU layout and "`" in the US layout 0104 // TAB_KEY is the same both in the US and RU layout 0105 0106 QTest::newRow("Left Ctrl + Tab") << KEY_LEFTCTRL << Qt::CTRL << KEY_TAB << Qt::Key_Tab; 0107 QTest::newRow("Left Ctrl + W") << KEY_LEFTCTRL << Qt::CTRL << KEY_W << Qt::Key_W; 0108 QTest::newRow("Left Ctrl + `") << KEY_LEFTCTRL << Qt::CTRL << KEY_GRAVE << Qt::Key_QuoteLeft; 0109 0110 QTest::newRow("Left Alt + Tab") << KEY_LEFTALT << Qt::ALT << KEY_TAB << Qt::Key_Tab; 0111 QTest::newRow("Left Alt + W") << KEY_LEFTALT << Qt::ALT << KEY_W << Qt::Key_W; 0112 QTest::newRow("Left Alt + `") << KEY_LEFTALT << Qt::ALT << KEY_GRAVE << Qt::Key_QuoteLeft; 0113 0114 QTest::newRow("Left Shift + Tab") << KEY_LEFTSHIFT << Qt::SHIFT << KEY_TAB << Qt::Key_Tab; 0115 0116 QTest::newRow("Left Meta + Tab") << KEY_LEFTMETA << Qt::META << KEY_TAB << Qt::Key_Tab; 0117 QTest::newRow("Left Meta + W") << KEY_LEFTMETA << Qt::META << KEY_W << Qt::Key_W; 0118 QTest::newRow("Left Meta + `") << KEY_LEFTMETA << Qt::META << KEY_GRAVE << Qt::Key_QuoteLeft; 0119 } 0120 0121 void GlobalShortcutsTest::testNonLatinLayout() 0122 { 0123 // Shortcuts on non-Latin layouts should still work, see BUG 375518 0124 auto xkb = input()->keyboard()->xkb(); 0125 xkb->switchToLayout(1); 0126 QCOMPARE(xkb->layoutName(), QStringLiteral("Russian")); 0127 0128 QFETCH(int, modifierKey); 0129 QFETCH(Qt::Modifier, qtModifier); 0130 QFETCH(int, key); 0131 QFETCH(Qt::Key, qtKey); 0132 0133 const QKeySequence seq(qtModifier + qtKey); 0134 0135 std::unique_ptr<QAction> action(new QAction(nullptr)); 0136 action->setProperty("componentName", QStringLiteral("kwin")); 0137 action->setObjectName("globalshortcuts-test-non-latin-layout"); 0138 0139 QSignalSpy triggeredSpy(action.get(), &QAction::triggered); 0140 0141 KGlobalAccel::self()->stealShortcutSystemwide(seq); 0142 KGlobalAccel::self()->setShortcut(action.get(), {seq}, KGlobalAccel::NoAutoloading); 0143 0144 quint32 timestamp = 0; 0145 Test::keyboardKeyPressed(modifierKey, timestamp++); 0146 QCOMPARE(input()->keyboardModifiers(), qtModifier); 0147 Test::keyboardKeyPressed(key, timestamp++); 0148 0149 Test::keyboardKeyReleased(key, timestamp++); 0150 Test::keyboardKeyReleased(modifierKey, timestamp++); 0151 0152 QTRY_COMPARE_WITH_TIMEOUT(triggeredSpy.count(), 1, 100); 0153 } 0154 0155 void GlobalShortcutsTest::testConsumedShift() 0156 { 0157 // this test verifies that a shortcut with a consumed shift modifier triggers 0158 // create the action 0159 std::unique_ptr<QAction> action(new QAction(nullptr)); 0160 action->setProperty("componentName", QStringLiteral("kwin")); 0161 action->setObjectName(QStringLiteral("globalshortcuts-test-consumed-shift")); 0162 QSignalSpy triggeredSpy(action.get(), &QAction::triggered); 0163 KGlobalAccel::self()->setShortcut(action.get(), QList<QKeySequence>{Qt::Key_Percent}, KGlobalAccel::NoAutoloading); 0164 0165 // press shift+5 0166 quint32 timestamp = 0; 0167 Test::keyboardKeyPressed(KEY_LEFTSHIFT, timestamp++); 0168 QCOMPARE(input()->keyboardModifiers(), Qt::ShiftModifier); 0169 Test::keyboardKeyPressed(KEY_5, timestamp++); 0170 QTRY_COMPARE(triggeredSpy.count(), 1); 0171 Test::keyboardKeyReleased(KEY_5, timestamp++); 0172 0173 // release shift 0174 Test::keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++); 0175 } 0176 0177 void GlobalShortcutsTest::testRepeatedTrigger() 0178 { 0179 // this test verifies that holding a key, triggers repeated global shortcut 0180 // in addition pressing another key should stop triggering the shortcut 0181 0182 std::unique_ptr<QAction> action(new QAction(nullptr)); 0183 action->setProperty("componentName", QStringLiteral("kwin")); 0184 action->setObjectName(QStringLiteral("globalshortcuts-test-consumed-shift")); 0185 QSignalSpy triggeredSpy(action.get(), &QAction::triggered); 0186 KGlobalAccel::self()->setShortcut(action.get(), QList<QKeySequence>{Qt::Key_Percent}, KGlobalAccel::NoAutoloading); 0187 0188 // we need to configure the key repeat first. It is only enabled on libinput 0189 waylandServer()->seat()->keyboard()->setRepeatInfo(25, 300); 0190 0191 // press shift+5 0192 quint32 timestamp = 0; 0193 Test::keyboardKeyPressed(KEY_WAKEUP, timestamp++); 0194 Test::keyboardKeyPressed(KEY_LEFTSHIFT, timestamp++); 0195 QCOMPARE(input()->keyboardModifiers(), Qt::ShiftModifier); 0196 Test::keyboardKeyPressed(KEY_5, timestamp++); 0197 QTRY_COMPARE(triggeredSpy.count(), 1); 0198 // and should repeat 0199 QVERIFY(triggeredSpy.wait()); 0200 QVERIFY(triggeredSpy.wait()); 0201 // now release the key 0202 Test::keyboardKeyReleased(KEY_5, timestamp++); 0203 QVERIFY(!triggeredSpy.wait(50)); 0204 0205 Test::keyboardKeyReleased(KEY_WAKEUP, timestamp++); 0206 QVERIFY(!triggeredSpy.wait(50)); 0207 0208 // release shift 0209 Test::keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++); 0210 } 0211 0212 void GlobalShortcutsTest::testUserActionsMenu() 0213 { 0214 // this test tries to trigger the user actions menu with Alt+F3 0215 // the problem here is that pressing F3 consumes modifiers as it's part of the 0216 // Ctrl+alt+F3 keysym for vt switching. xkbcommon considers all modifiers as consumed 0217 // which a transformation to any keysym would cause 0218 // for more information see: 0219 // https://bugs.freedesktop.org/show_bug.cgi?id=92818 0220 // https://github.com/xkbcommon/libxkbcommon/issues/17 0221 0222 // first create a window 0223 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0224 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0225 auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue); 0226 QVERIFY(window); 0227 QVERIFY(window->isActive()); 0228 0229 quint32 timestamp = 0; 0230 QVERIFY(!workspace()->userActionsMenu()->isShown()); 0231 Test::keyboardKeyPressed(KEY_LEFTALT, timestamp++); 0232 Test::keyboardKeyPressed(KEY_F3, timestamp++); 0233 Test::keyboardKeyReleased(KEY_F3, timestamp++); 0234 QTRY_VERIFY(workspace()->userActionsMenu()->isShown()); 0235 Test::keyboardKeyReleased(KEY_LEFTALT, timestamp++); 0236 } 0237 0238 void GlobalShortcutsTest::testMetaShiftW() 0239 { 0240 // BUG 370341 0241 std::unique_ptr<QAction> action(new QAction(nullptr)); 0242 action->setProperty("componentName", QStringLiteral("kwin")); 0243 action->setObjectName(QStringLiteral("globalshortcuts-test-meta-shift-w")); 0244 QSignalSpy triggeredSpy(action.get(), &QAction::triggered); 0245 KGlobalAccel::self()->setShortcut(action.get(), QList<QKeySequence>{Qt::META | Qt::SHIFT | Qt::Key_W}, KGlobalAccel::NoAutoloading); 0246 0247 // press meta+shift+w 0248 quint32 timestamp = 0; 0249 Test::keyboardKeyPressed(KEY_LEFTMETA, timestamp++); 0250 QCOMPARE(input()->keyboardModifiers(), Qt::MetaModifier); 0251 Test::keyboardKeyPressed(KEY_LEFTSHIFT, timestamp++); 0252 QCOMPARE(input()->keyboardModifiers(), Qt::ShiftModifier | Qt::MetaModifier); 0253 Test::keyboardKeyPressed(KEY_W, timestamp++); 0254 QTRY_COMPARE(triggeredSpy.count(), 1); 0255 Test::keyboardKeyReleased(KEY_W, timestamp++); 0256 0257 // release meta+shift 0258 Test::keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++); 0259 Test::keyboardKeyReleased(KEY_LEFTMETA, timestamp++); 0260 } 0261 0262 void GlobalShortcutsTest::testComponseKey() 0263 { 0264 // BUG 390110 0265 std::unique_ptr<QAction> action(new QAction(nullptr)); 0266 action->setProperty("componentName", QStringLiteral("kwin")); 0267 action->setObjectName(QStringLiteral("globalshortcuts-accent")); 0268 QSignalSpy triggeredSpy(action.get(), &QAction::triggered); 0269 KGlobalAccel::self()->setShortcut(action.get(), QList<QKeySequence>{Qt::NoModifier}, KGlobalAccel::NoAutoloading); 0270 0271 // press & release ` 0272 quint32 timestamp = 0; 0273 Test::keyboardKeyPressed(KEY_RESERVED, timestamp++); 0274 Test::keyboardKeyReleased(KEY_RESERVED, timestamp++); 0275 0276 QTRY_COMPARE(triggeredSpy.count(), 0); 0277 } 0278 0279 void GlobalShortcutsTest::testKeypad() 0280 { 0281 auto zeroAction = std::make_unique<QAction>(); 0282 zeroAction->setProperty("componentName", QStringLiteral("kwin")); 0283 zeroAction->setObjectName(QStringLiteral("globalshortcuts-test-keypad-0")); 0284 QSignalSpy zeroActionTriggeredSpy(zeroAction.get(), &QAction::triggered); 0285 KGlobalAccel::self()->setShortcut(zeroAction.get(), QList<QKeySequence>{Qt::MetaModifier | Qt::KeypadModifier | Qt::Key_0}, KGlobalAccel::NoAutoloading); 0286 0287 auto insertAction = std::make_unique<QAction>(); 0288 insertAction->setProperty("componentName", QStringLiteral("kwin")); 0289 insertAction->setObjectName(QStringLiteral("globalshortcuts-test-keypad-ins")); 0290 QSignalSpy insertActionTriggeredSpy(insertAction.get(), &QAction::triggered); 0291 KGlobalAccel::self()->setShortcut(insertAction.get(), QList<QKeySequence>{Qt::MetaModifier | Qt::KeypadModifier | Qt::Key_Insert}, KGlobalAccel::NoAutoloading); 0292 0293 // Turn on numlock 0294 quint32 timestamp = 0; 0295 Test::keyboardKeyPressed(KEY_NUMLOCK, timestamp++); 0296 Test::keyboardKeyReleased(KEY_NUMLOCK, timestamp++); 0297 0298 Test::keyboardKeyPressed(KEY_LEFTMETA, timestamp++); 0299 Test::keyboardKeyPressed(KEY_KP0, timestamp++); 0300 Test::keyboardKeyReleased(KEY_KP0, timestamp++); 0301 Test::keyboardKeyReleased(KEY_LEFTMETA, timestamp++); 0302 QTRY_COMPARE(zeroActionTriggeredSpy.count(), 1); 0303 QCOMPARE(insertActionTriggeredSpy.count(), 0); 0304 0305 // Turn off numlock 0306 Test::keyboardKeyPressed(KEY_NUMLOCK, timestamp++); 0307 Test::keyboardKeyReleased(KEY_NUMLOCK, timestamp++); 0308 0309 Test::keyboardKeyPressed(KEY_LEFTMETA, timestamp++); 0310 Test::keyboardKeyPressed(KEY_KP0, timestamp++); 0311 Test::keyboardKeyReleased(KEY_KP0, timestamp++); 0312 Test::keyboardKeyReleased(KEY_LEFTMETA, timestamp++); 0313 QTRY_COMPARE(insertActionTriggeredSpy.count(), 1); 0314 QCOMPARE(zeroActionTriggeredSpy.count(), 1); 0315 } 0316 0317 void GlobalShortcutsTest::testX11WindowShortcut() 0318 { 0319 // create an X11 window 0320 Test::XcbConnectionPtr c = Test::createX11Connection(); 0321 QVERIFY(!xcb_connection_has_error(c.get())); 0322 xcb_window_t windowId = xcb_generate_id(c.get()); 0323 const QRect windowGeometry = QRect(0, 0, 10, 20); 0324 const uint32_t values[] = { 0325 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW}; 0326 xcb_create_window(c.get(), XCB_COPY_FROM_PARENT, windowId, rootWindow(), 0327 windowGeometry.x(), 0328 windowGeometry.y(), 0329 windowGeometry.width(), 0330 windowGeometry.height(), 0331 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, XCB_CW_EVENT_MASK, values); 0332 xcb_size_hints_t hints; 0333 memset(&hints, 0, sizeof(hints)); 0334 xcb_icccm_size_hints_set_position(&hints, 1, windowGeometry.x(), windowGeometry.y()); 0335 xcb_icccm_size_hints_set_size(&hints, 1, windowGeometry.width(), windowGeometry.height()); 0336 xcb_icccm_set_wm_normal_hints(c.get(), windowId, &hints); 0337 NETWinInfo info(c.get(), windowId, rootWindow(), NET::WMAllProperties, NET::WM2AllProperties); 0338 info.setWindowType(NET::Normal); 0339 xcb_map_window(c.get(), windowId); 0340 xcb_flush(c.get()); 0341 0342 QSignalSpy windowCreatedSpy(workspace(), &Workspace::windowAdded); 0343 QVERIFY(windowCreatedSpy.wait()); 0344 X11Window *window = windowCreatedSpy.last().first().value<X11Window *>(); 0345 QVERIFY(window); 0346 0347 QCOMPARE(workspace()->activeWindow(), window); 0348 QVERIFY(window->isActive()); 0349 QCOMPARE(window->shortcut(), QKeySequence()); 0350 const QKeySequence seq(Qt::META | Qt::SHIFT | Qt::Key_Y); 0351 QVERIFY(workspace()->shortcutAvailable(seq)); 0352 window->setShortcut(seq.toString()); 0353 QCOMPARE(window->shortcut(), seq); 0354 QVERIFY(!workspace()->shortcutAvailable(seq)); 0355 QCOMPARE(window->caption(), QStringLiteral(" {Meta+Shift+Y}")); 0356 0357 // it's delayed 0358 QCoreApplication::processEvents(); 0359 0360 workspace()->activateWindow(nullptr); 0361 QVERIFY(!workspace()->activeWindow()); 0362 QVERIFY(!window->isActive()); 0363 0364 // now let's trigger the shortcut 0365 quint32 timestamp = 0; 0366 Test::keyboardKeyPressed(KEY_LEFTMETA, timestamp++); 0367 Test::keyboardKeyPressed(KEY_LEFTSHIFT, timestamp++); 0368 Test::keyboardKeyPressed(KEY_Y, timestamp++); 0369 QTRY_COMPARE(workspace()->activeWindow(), window); 0370 Test::keyboardKeyReleased(KEY_Y, timestamp++); 0371 Test::keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++); 0372 Test::keyboardKeyReleased(KEY_LEFTMETA, timestamp++); 0373 0374 // destroy window again 0375 QSignalSpy windowClosedSpy(window, &X11Window::closed); 0376 xcb_unmap_window(c.get(), windowId); 0377 xcb_destroy_window(c.get(), windowId); 0378 xcb_flush(c.get()); 0379 QVERIFY(windowClosedSpy.wait()); 0380 } 0381 0382 void GlobalShortcutsTest::testWaylandWindowShortcut() 0383 { 0384 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0385 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0386 auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue); 0387 0388 QCOMPARE(workspace()->activeWindow(), window); 0389 QVERIFY(window->isActive()); 0390 QCOMPARE(window->shortcut(), QKeySequence()); 0391 const QKeySequence seq(Qt::META | Qt::SHIFT | Qt::Key_Y); 0392 QVERIFY(workspace()->shortcutAvailable(seq)); 0393 window->setShortcut(seq.toString()); 0394 QCOMPARE(window->shortcut(), seq); 0395 QVERIFY(!workspace()->shortcutAvailable(seq)); 0396 QCOMPARE(window->caption(), QStringLiteral(" {Meta+Shift+Y}")); 0397 0398 workspace()->activateWindow(nullptr); 0399 QVERIFY(!workspace()->activeWindow()); 0400 QVERIFY(!window->isActive()); 0401 0402 // now let's trigger the shortcut 0403 quint32 timestamp = 0; 0404 Test::keyboardKeyPressed(KEY_LEFTMETA, timestamp++); 0405 Test::keyboardKeyPressed(KEY_LEFTSHIFT, timestamp++); 0406 Test::keyboardKeyPressed(KEY_Y, timestamp++); 0407 QTRY_COMPARE(workspace()->activeWindow(), window); 0408 Test::keyboardKeyReleased(KEY_Y, timestamp++); 0409 Test::keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++); 0410 Test::keyboardKeyReleased(KEY_LEFTMETA, timestamp++); 0411 0412 shellSurface.reset(); 0413 surface.reset(); 0414 QVERIFY(Test::waitForWindowClosed(window)); 0415 QTRY_VERIFY_WITH_TIMEOUT(workspace()->shortcutAvailable(seq), 500); // we need the try since KGlobalAccelPrivate::unregister is async 0416 } 0417 0418 void GlobalShortcutsTest::testSetupWindowShortcut() 0419 { 0420 // QTBUG-62102 0421 0422 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0423 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0424 auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue); 0425 0426 QCOMPARE(workspace()->activeWindow(), window); 0427 QVERIFY(window->isActive()); 0428 QCOMPARE(window->shortcut(), QKeySequence()); 0429 0430 QSignalSpy shortcutDialogAddedSpy(workspace(), &Workspace::windowAdded); 0431 workspace()->slotSetupWindowShortcut(); 0432 QTRY_COMPARE(shortcutDialogAddedSpy.count(), 1); 0433 auto dialog = shortcutDialogAddedSpy.first().first().value<InternalWindow *>(); 0434 QVERIFY(dialog); 0435 QVERIFY(dialog->isInternal()); 0436 auto sequenceEdit = workspace()->shortcutDialog()->findChild<QKeySequenceEdit *>(); 0437 QVERIFY(sequenceEdit); 0438 QTRY_VERIFY(sequenceEdit->hasFocus()); 0439 0440 quint32 timestamp = 0; 0441 Test::keyboardKeyPressed(KEY_LEFTMETA, timestamp++); 0442 Test::keyboardKeyPressed(KEY_LEFTSHIFT, timestamp++); 0443 Test::keyboardKeyPressed(KEY_Y, timestamp++); 0444 Test::keyboardKeyReleased(KEY_Y, timestamp++); 0445 Test::keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++); 0446 Test::keyboardKeyReleased(KEY_LEFTMETA, timestamp++); 0447 0448 // the sequence gets accepted after one second, so wait a bit longer 0449 QTest::qWait(2000); 0450 // now send in enter 0451 Test::keyboardKeyPressed(KEY_ENTER, timestamp++); 0452 Test::keyboardKeyReleased(KEY_ENTER, timestamp++); 0453 QTRY_COMPARE(window->shortcut(), QKeySequence(Qt::META | Qt::SHIFT | Qt::Key_Y)); 0454 } 0455 0456 WAYLANDTEST_MAIN(GlobalShortcutsTest) 0457 #include "globalshortcuts_test.moc"