From 9337f145d5c1b74bafd1a7a379e17235c45052a5 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Wed, 20 Jul 2022 12:14:27 +0200 Subject: [PATCH] move InputMethod singleton to Application --- autotests/integration/inputmethod_test.cpp | 68 +++++++++---------- autotests/integration/kwin_wayland_test.cpp | 6 +- .../integration/test_virtualkeyboard_dbus.cpp | 6 +- src/effects.cpp | 10 +-- src/input.cpp | 10 ++- src/inputmethod.cpp | 6 +- src/inputmethod.h | 3 +- src/inputpanelv1window.cpp | 2 +- src/keyboard_input.cpp | 2 +- src/main.cpp | 9 ++- src/main.h | 3 + src/main_wayland.cpp | 4 +- 12 files changed, 65 insertions(+), 64 deletions(-) diff --git a/autotests/integration/inputmethod_test.cpp b/autotests/integration/inputmethod_test.cpp index d74eb199d8..f717acaeb5 100644 --- a/autotests/integration/inputmethod_test.cpp +++ b/autotests/integration/inputmethod_test.cpp @@ -104,7 +104,7 @@ void InputMethodTest::init() workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); - InputMethod::self()->setEnabled(true); + kwinApp()->inputMethod()->setEnabled(true); } void InputMethodTest::cleanup() @@ -181,29 +181,29 @@ void InputMethodTest::testEnableDisableV3() textInputV3->init(Test::waylandTextInputManagerV3()->get_text_input(*(Test::waylandSeat()))); textInputV3->enable(); - QSignalSpy inputMethodActiveSpy(InputMethod::self(), &InputMethod::activeChanged); + QSignalSpy inputMethodActiveSpy(kwinApp()->inputMethod(), &InputMethod::activeChanged); // just enabling the text-input should not show it but rather on commit - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); textInputV3->commit(); QVERIFY(inputMethodActiveSpy.count() || inputMethodActiveSpy.wait()); - QVERIFY(InputMethod::self()->isActive()); + QVERIFY(kwinApp()->inputMethod()->isActive()); // disable text input and ensure that it is not hiding input panel without commit inputMethodActiveSpy.clear(); - QVERIFY(InputMethod::self()->isActive()); + QVERIFY(kwinApp()->inputMethod()->isActive()); textInputV3->disable(); textInputV3->commit(); QVERIFY(inputMethodActiveSpy.count() || inputMethodActiveSpy.wait()); - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); } void InputMethodTest::testEnableActive() { - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); QSignalSpy windowRemovedSpy(workspace(), &Workspace::windowRemoved); - QSignalSpy activateSpy(InputMethod::self(), &InputMethod::activeChanged); + QSignalSpy activateSpy(kwinApp()->inputMethod(), &InputMethod::activeChanged); // Create an xdg_toplevel surface and wait for the compositor to catch up. QScopedPointer surface(Test::createSurface()); @@ -235,12 +235,12 @@ void InputMethodTest::testEnableActive() textInput->showInputPanel(); activateSpy.wait(200); QVERIFY(activateSpy.isEmpty()); - QVERIFY(InputMethod::self()->isActive()); + QVERIFY(kwinApp()->inputMethod()->isActive()); auto keyboardWindow = Test::inputPanelWindow(); QVERIFY(keyboardWindow); textInput->enable(surface.get()); - QVERIFY(InputMethod::self()->isActive()); + QVERIFY(kwinApp()->inputMethod()->isActive()); // Destroy the test window. shellSurface.reset(); @@ -249,14 +249,14 @@ void InputMethodTest::testEnableActive() void InputMethodTest::testHidePanel() { - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); touchNow(); QSignalSpy windowAddedSpy(workspace(), &Workspace::windowAdded); QSignalSpy windowRemovedSpy(workspace(), &Workspace::windowRemoved); QVERIFY(windowAddedSpy.isValid()); - QSignalSpy activateSpy(InputMethod::self(), &InputMethod::activeChanged); + QSignalSpy activateSpy(kwinApp()->inputMethod(), &InputMethod::activeChanged); QScopedPointer textInput(Test::waylandTextInputManager()->createTextInput(Test::waylandSeat())); // Create an xdg_toplevel surface and wait for the compositor to catch up. @@ -273,16 +273,16 @@ void InputMethodTest::testHidePanel() QCOMPARE(windowAddedSpy.count(), 2); QVERIFY(activateSpy.count() || activateSpy.wait()); - QVERIFY(InputMethod::self()->isActive()); + QVERIFY(kwinApp()->inputMethod()->isActive()); auto keyboardWindow = Test::inputPanelWindow(); auto ipsurface = Test::inputPanelSurface(); QVERIFY(keyboardWindow); windowRemovedSpy.clear(); delete ipsurface; - QVERIFY(InputMethod::self()->isVisible()); + QVERIFY(kwinApp()->inputMethod()->isVisible()); QVERIFY(windowRemovedSpy.count() || windowRemovedSpy.wait()); - QVERIFY(!InputMethod::self()->isVisible()); + QVERIFY(!kwinApp()->inputMethod()->isVisible()); // Destroy the test window. shellSurface.reset(); @@ -292,13 +292,13 @@ void InputMethodTest::testHidePanel() void InputMethodTest::testSwitchFocusedSurfaces() { touchNow(); - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); QSignalSpy windowAddedSpy(workspace(), &Workspace::windowAdded); QSignalSpy windowRemovedSpy(workspace(), &Workspace::windowRemoved); QVERIFY(windowAddedSpy.isValid()); - QSignalSpy activateSpy(InputMethod::self(), &InputMethod::activeChanged); + QSignalSpy activateSpy(kwinApp()->inputMethod(), &InputMethod::activeChanged); QScopedPointer textInput(Test::waylandTextInputManager()->createTextInput(Test::waylandSeat())); QVector windows; @@ -316,20 +316,20 @@ void InputMethodTest::testSwitchFocusedSurfaces() QCOMPARE(windowAddedSpy.count(), 3); waylandServer()->seat()->setFocusedTextInputSurface(windows.constFirst()->surface()); - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); textInput->enable(surfaces.last()); - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); waylandServer()->seat()->setFocusedTextInputSurface(windows.first()->surface()); - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); activateSpy.clear(); waylandServer()->seat()->setFocusedTextInputSurface(windows.last()->surface()); QVERIFY(activateSpy.count() || activateSpy.wait()); - QVERIFY(InputMethod::self()->isActive()); + QVERIFY(kwinApp()->inputMethod()->isActive()); activateSpy.clear(); waylandServer()->seat()->setFocusedTextInputSurface(windows.first()->surface()); QVERIFY(activateSpy.count() || activateSpy.wait()); - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); // Destroy the test window. for (int i = 0; i < windows.count(); ++i) { @@ -352,13 +352,13 @@ void InputMethodTest::testV3Styling() textInputV3->init(Test::waylandTextInputManagerV3()->get_text_input(*(Test::waylandSeat()))); textInputV3->enable(); - QSignalSpy inputMethodActiveSpy(InputMethod::self(), &InputMethod::activeChanged); + QSignalSpy inputMethodActiveSpy(kwinApp()->inputMethod(), &InputMethod::activeChanged); QSignalSpy inputMethodActivateSpy(Test::inputMethod(), &Test::MockInputMethod::activate); // just enabling the text-input should not show it but rather on commit - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); textInputV3->commit(); QVERIFY(inputMethodActiveSpy.count() || inputMethodActiveSpy.wait()); - QVERIFY(InputMethod::self()->isActive()); + QVERIFY(kwinApp()->inputMethod()->isActive()); QVERIFY(inputMethodActivateSpy.wait()); auto context = Test::inputMethod()->context(); QSignalSpy textInputPreeditSpy(textInputV3, &Test::TextInputV3::preeditString); @@ -440,24 +440,24 @@ void InputMethodTest::testDisableShowInputPanel() QScopedPointer textInputV2(Test::waylandTextInputManager()->createTextInput(Test::waylandSeat())); - QSignalSpy inputMethodActiveSpy(InputMethod::self(), &InputMethod::activeChanged); + QSignalSpy inputMethodActiveSpy(kwinApp()->inputMethod(), &InputMethod::activeChanged); // just enabling the text-input should not show it but rather on commit - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); textInputV2->enable(surface.get()); QVERIFY(inputMethodActiveSpy.count() || inputMethodActiveSpy.wait()); - QVERIFY(InputMethod::self()->isActive()); + QVERIFY(kwinApp()->inputMethod()->isActive()); // disable text input and ensure that it is not hiding input panel without commit inputMethodActiveSpy.clear(); - QVERIFY(InputMethod::self()->isActive()); + QVERIFY(kwinApp()->inputMethod()->isActive()); textInputV2->disable(surface.get()); QVERIFY(inputMethodActiveSpy.count() || inputMethodActiveSpy.wait()); - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); QSignalSpy requestShowInputPanelSpy(waylandServer()->seat()->textInputV2(), &KWaylandServer::TextInputV2Interface::requestShowInputPanel); textInputV2->showInputPanel(); QVERIFY(requestShowInputPanelSpy.count() || requestShowInputPanelSpy.wait()); - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); } void InputMethodTest::testModifierForwarding() @@ -474,13 +474,13 @@ void InputMethodTest::testModifierForwarding() textInputV3->init(Test::waylandTextInputManagerV3()->get_text_input(*(Test::waylandSeat()))); textInputV3->enable(); - QSignalSpy inputMethodActiveSpy(InputMethod::self(), &InputMethod::activeChanged); + QSignalSpy inputMethodActiveSpy(kwinApp()->inputMethod(), &InputMethod::activeChanged); QSignalSpy inputMethodActivateSpy(Test::inputMethod(), &Test::MockInputMethod::activate); // just enabling the text-input should not show it but rather on commit - QVERIFY(!InputMethod::self()->isActive()); + QVERIFY(!kwinApp()->inputMethod()->isActive()); textInputV3->commit(); QVERIFY(inputMethodActiveSpy.count() || inputMethodActiveSpy.wait()); - QVERIFY(InputMethod::self()->isActive()); + QVERIFY(kwinApp()->inputMethod()->isActive()); QVERIFY(inputMethodActivateSpy.wait()); auto context = Test::inputMethod()->context(); QScopedPointer keyboardGrab(new KWayland::Client::Keyboard); diff --git a/autotests/integration/kwin_wayland_test.cpp b/autotests/integration/kwin_wayland_test.cpp index f83d06c141..dbc0900675 100644 --- a/autotests/integration/kwin_wayland_test.cpp +++ b/autotests/integration/kwin_wayland_test.cpp @@ -123,10 +123,10 @@ void WaylandTestApplication::destroyVirtualInputDevices() void WaylandTestApplication::performStartup() { if (!m_inputMethodServerToStart.isEmpty()) { - InputMethod::create(); + createInputMethod(); if (m_inputMethodServerToStart != QStringLiteral("internal")) { - InputMethod::self()->setInputMethodCommand(m_inputMethodServerToStart); - InputMethod::self()->setEnabled(true); + inputMethod()->setInputMethodCommand(m_inputMethodServerToStart); + inputMethod()->setEnabled(true); } } diff --git a/autotests/integration/test_virtualkeyboard_dbus.cpp b/autotests/integration/test_virtualkeyboard_dbus.cpp index 3198d2a59e..1a4bc6cee0 100644 --- a/autotests/integration/test_virtualkeyboard_dbus.cpp +++ b/autotests/integration/test_virtualkeyboard_dbus.cpp @@ -59,7 +59,7 @@ void VirtualKeyboardDBusTest::initTestCase() void VirtualKeyboardDBusTest::init() { - InputMethod::self()->setEnabled(false); + kwinApp()->inputMethod()->setEnabled(false); } void VirtualKeyboardDBusTest::cleanup() @@ -69,7 +69,7 @@ void VirtualKeyboardDBusTest::cleanup() void VirtualKeyboardDBusTest::testEnabled() { - VirtualKeyboardDBus dbus(KWin::InputMethod::self()); + VirtualKeyboardDBus dbus(KWin::kwinApp()->inputMethod()); OrgKdeKwinVirtualKeyboardInterface iface(QStringLiteral("org.kde.kwin.testvirtualkeyboard"), QStringLiteral("/VirtualKeyboard"), QDBusConnection::sessionBus()); QSignalSpy helperChangedSpy(&iface, &OrgKdeKwinVirtualKeyboardInterface::enabledChanged); QVERIFY(helperChangedSpy.isValid()); @@ -118,7 +118,7 @@ void VirtualKeyboardDBusTest::testRequestEnabled() QFETCH(QString, method); QFETCH(bool, expectedResult); - VirtualKeyboardDBus dbus(KWin::InputMethod::self()); + VirtualKeyboardDBus dbus(KWin::kwinApp()->inputMethod()); OrgKdeKwinVirtualKeyboardInterface iface(QStringLiteral("org.kde.kwin.testvirtualkeyboard"), QStringLiteral("/VirtualKeyboard"), QDBusConnection::sessionBus()); iface.setEnabled(expectedResult); diff --git a/src/effects.cpp b/src/effects.cpp index 9e0af0f75b..1cb18c3163 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -263,7 +263,7 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene) slotOutputAdded(output); } - connect(InputMethod::self(), &InputMethod::panelChanged, this, &EffectsHandlerImpl::inputPanelChanged); + connect(kwinApp()->inputMethod(), &InputMethod::panelChanged, this, &EffectsHandlerImpl::inputPanelChanged); reconfigure(); } @@ -1821,11 +1821,11 @@ qreal EffectsHandlerImpl::renderTargetScale() const KWin::EffectWindow *EffectsHandlerImpl::inputPanel() const { - if (!InputMethod::self() || !InputMethod::self()->isEnabled()) { + if (!kwinApp()->inputMethod() || !kwinApp()->inputMethod()->isEnabled()) { return nullptr; } - auto panel = InputMethod::self()->panel(); + auto panel = kwinApp()->inputMethod()->panel(); if (panel) { return panel->effectWindow(); } @@ -1834,11 +1834,11 @@ KWin::EffectWindow *EffectsHandlerImpl::inputPanel() const bool EffectsHandlerImpl::isInputPanelOverlay() const { - if (!InputMethod::self() || !InputMethod::self()->isEnabled()) { + if (!kwinApp()->inputMethod() || !kwinApp()->inputMethod()->isEnabled()) { return true; } - auto panel = InputMethod::self()->panel(); + auto panel = kwinApp()->inputMethod()->panel(); if (panel) { return panel->mode() == InputPanelV1Window::Overlay; } diff --git a/src/input.cpp b/src/input.cpp index 21fcbd17e7..925ee08d24 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -292,21 +292,19 @@ void InputEventFilter::passToWaylandServer(QKeyEvent *event) bool InputEventFilter::passToInputMethod(QKeyEvent *event) { - auto *inputmethod = InputMethod::self(); - - if (!inputmethod) { + if (!kwinApp()->inputMethod()) { return false; } - - if (auto keyboardGrab = inputmethod->keyboardGrab()) { + if (auto keyboardGrab = kwinApp()->inputMethod()->keyboardGrab()) { if (event->isAutoRepeat()) { return true; } auto newState = event->type() == QEvent::KeyPress ? KWaylandServer::KeyboardKeyState::Pressed : KWaylandServer::KeyboardKeyState::Released; keyboardGrab->sendKey(waylandServer()->display()->nextSerial(), event->timestamp(), event->nativeScanCode(), newState); return true; + } else { + return false; } - return false; } class VirtualTerminalFilter : public InputEventFilter diff --git a/src/inputmethod.cpp b/src/inputmethod.cpp index 2668732668..8f55dec951 100644 --- a/src/inputmethod.cpp +++ b/src/inputmethod.cpp @@ -49,10 +49,7 @@ using namespace KWaylandServer; namespace KWin { -KWIN_SINGLETON_FACTORY(InputMethod) - -InputMethod::InputMethod(QObject *parent) - : QObject(parent) +InputMethod::InputMethod() { m_enabled = kwinApp()->config()->group("Wayland").readEntry("VirtualKeyboardEnabled", true); // this is actually too late. Other processes are started before init, @@ -68,7 +65,6 @@ InputMethod::InputMethod(QObject *parent) InputMethod::~InputMethod() { stopInputMethod(); - s_self = nullptr; } void InputMethod::init() diff --git a/src/inputmethod.h b/src/inputmethod.h index e31bfd4bc8..d5a1c137fc 100644 --- a/src/inputmethod.h +++ b/src/inputmethod.h @@ -48,6 +48,7 @@ public: Force = 1, }; + InputMethod(); ~InputMethod() override; void init(); @@ -133,8 +134,6 @@ private: QString m_inputMethodCommand; bool m_hasPendingModifiers = false; - - KWIN_SINGLETON(InputMethod) }; } diff --git a/src/inputpanelv1window.cpp b/src/inputpanelv1window.cpp index 91ae2c34a5..f581a1bf1d 100644 --- a/src/inputpanelv1window.cpp +++ b/src/inputpanelv1window.cpp @@ -41,7 +41,7 @@ InputPanelV1Window::InputPanelV1Window(InputPanelSurfaceV1Interface *panelSurfac connect(panelSurface, &InputPanelSurfaceV1Interface::overlayPanel, this, &InputPanelV1Window::showOverlayPanel); connect(panelSurface, &InputPanelSurfaceV1Interface::destroyed, this, &InputPanelV1Window::destroyWindow); - InputMethod::self()->setPanel(this); + kwinApp()->inputMethod()->setPanel(this); } void InputPanelV1Window::showOverlayPanel() diff --git a/src/keyboard_input.cpp b/src/keyboard_input.cpp index d234e85095..30934653ee 100644 --- a/src/keyboard_input.cpp +++ b/src/keyboard_input.cpp @@ -254,7 +254,7 @@ void KeyboardInputRedirection::processKey(uint32_t key, InputRedirection::Keyboa m_input->processFilters(std::bind(&InputEventFilter::keyEvent, std::placeholders::_1, &event)); m_xkb->forwardModifiers(); - if (auto *inputmethod = InputMethod::self()) { + if (auto *inputmethod = kwinApp()->inputMethod()) { inputmethod->forwardModifiers(InputMethod::NoForce); } diff --git a/src/main.cpp b/src/main.cpp index cfeda13a8c..31ec9c9fd7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -276,7 +276,7 @@ void Application::createColorManager() void Application::createInputMethod() { - InputMethod::create(this); + m_inputMethod = std::make_unique(); } void Application::installNativeX11EventFilter() @@ -316,7 +316,7 @@ void Application::destroyColorManager() void Application::destroyInputMethod() { - delete InputMethod::self(); + m_inputMethod.reset(); } void Application::registerEventFilter(X11EventFilter *filter) @@ -567,4 +567,9 @@ PluginManager *Application::pluginManager() const return m_pluginManager.get(); } +InputMethod *Application::inputMethod() const +{ + return m_inputMethod.get(); +} + } // namespace diff --git a/src/main.h b/src/main.h index c68246f2e6..46cc36d5a1 100644 --- a/src/main.h +++ b/src/main.h @@ -30,6 +30,7 @@ namespace KWin class Platform; class X11EventFilter; class PluginManager; +class InputMethod; class XcbEventFilter : public QAbstractNativeEventFilter { @@ -241,6 +242,7 @@ public: static void setupLocalizedString(); PluginManager *pluginManager() const; + InputMethod *inputMethod() const; Q_SIGNALS: void x11ConnectionChanged(); @@ -298,6 +300,7 @@ private: qreal m_xwaylandScale = 1; QProcessEnvironment m_processEnvironment; std::unique_ptr m_pluginManager; + std::unique_ptr m_inputMethod; }; inline static Application *kwinApp() diff --git a/src/main_wayland.cpp b/src/main_wayland.cpp index 17e9ab6191..f10c212485 100644 --- a/src/main_wayland.cpp +++ b/src/main_wayland.cpp @@ -193,7 +193,7 @@ void ApplicationWayland::refreshSettings(const KConfigGroup &group, const QByteA { if (group.name() == "Wayland" && names.contains("InputMethod")) { KDesktopFile file(group.readPathEntry("InputMethod", QString())); - InputMethod::self()->setInputMethodCommand(file.desktopGroup().readEntry("Exec", QString())); + kwinApp()->inputMethod()->setInputMethodCommand(file.desktopGroup().readEntry("Exec", QString())); } if (m_startXWayland && group.name() == "Xwayland" && names.contains("Scale")) { @@ -212,7 +212,7 @@ void ApplicationWayland::startSession() connect(m_settingsWatcher.data(), &KConfigWatcher::configChanged, this, &ApplicationWayland::refreshSettings); if (!m_inputMethodServerToStart.isEmpty()) { - InputMethod::self()->setInputMethodCommand(m_inputMethodServerToStart); + kwinApp()->inputMethod()->setInputMethodCommand(m_inputMethodServerToStart); } else { refreshSettings(kwinSettings->group("Wayland"), {"InputMethod"}); }