diff --git a/inputpanelv1client.cpp b/inputpanelv1client.cpp index c77d80248b..98840e3c4c 100644 --- a/inputpanelv1client.cpp +++ b/inputpanelv1client.cpp @@ -124,6 +124,11 @@ NET::WindowType InputPanelV1Client::windowType(bool, int) const return NET::Utility; } +QRect InputPanelV1Client::inputGeometry() const +{ + return surface()->input().boundingRect().translated(pos()); +} + void InputPanelV1Client::hideClient(bool hide) { m_visible = !hide; @@ -135,6 +140,7 @@ void InputPanelV1Client::hideClient(bool hide) reposition(); addRepaintFull(); Q_EMIT windowShown(this); + autoRaise(); } } diff --git a/inputpanelv1client.h b/inputpanelv1client.h index 247dac6812..3fdd3529f5 100644 --- a/inputpanelv1client.h +++ b/inputpanelv1client.h @@ -55,6 +55,7 @@ public: void setNoBorder(bool /*set*/) override {} NET::WindowType windowType(bool /*direct*/, int /*supported_types*/) const override; void debug(QDebug & stream) const override; + QRect inputGeometry() const override; private: void showTopLevel(KWaylandServer::OutputInterface *output, KWaylandServer::InputPanelSurfaceV1Interface::Position position); diff --git a/internal_client.cpp b/internal_client.cpp index 3d329e09a5..da9b301b29 100644 --- a/internal_client.cpp +++ b/internal_client.cpp @@ -246,9 +246,6 @@ bool InternalClient::isLockScreen() const bool InternalClient::isInputMethod() const { - if (m_internalWindow) { - return m_internalWindow->property("__kwin_input_method").toBool(); - } return false; } diff --git a/plugins/qpa/integration.cpp b/plugins/qpa/integration.cpp index ebce5165ac..b7424e6459 100644 --- a/plugins/qpa/integration.cpp +++ b/plugins/qpa/integration.cpp @@ -99,15 +99,6 @@ void Integration::initialize() } } ); - connect(qApp->inputMethod(), &QInputMethod::visibleChanged, this, - [] { - if (qApp->inputMethod()->isVisible()) { - if (QWindow *w = VirtualKeyboard::self()->inputPanel()) { - QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason); - } - } - } - ); } } diff --git a/qml/CMakeLists.txt b/qml/CMakeLists.txt index 9be5dd3aa3..1a316c2525 100644 --- a/qml/CMakeLists.txt +++ b/qml/CMakeLists.txt @@ -1,3 +1,3 @@ install(DIRECTORY outline/plasma DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/outline) install(DIRECTORY onscreennotification/plasma DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/onscreennotification) -install(DIRECTORY virtualkeyboard DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}) + diff --git a/qml/virtualkeyboard/main.qml b/qml/virtualkeyboard/main.qml deleted file mode 100644 index e6cf136a82..0000000000 --- a/qml/virtualkeyboard/main.qml +++ /dev/null @@ -1,61 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2016 Martin Gräßlin - - SPDX-License-Identifier: GPL-2.0-or-later -*/ -import QtQuick 2.0 -import QtQuick.Controls 2.3 -import QtQuick.VirtualKeyboard 2.1 -import org.kde.kirigami 2.5 as Kirigami - -Item { - id: window - property real adjustment: 0 - property real adjustmentFactor: 0.0 - InputPanel { - id: inputPanel - objectName: "inputPanel" - width: parent.width - parent.width * parent.adjustmentFactor - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.bottom - } - //NOTE: ToolButton for some reasons breaks the virtual keyboard loading on Plasma Mobile - Button { - id: resizeButton - visible: !Kirigami.Settings.isMobile //don't show on handheld devices - flat: true - display: AbstractButton.IconOnly - icon.name: "transform-scale" - icon.color: "white" - down: mouseArea.pressed - - anchors { - right: inputPanel.right - top: inputPanel.top - } - - MouseArea { - id: mouseArea - property real startPoint: 0 - anchors.fill: parent - onPressed: { - startPoint = mouse.x; - } - onPositionChanged: { - window.adjustment -= (mouse.x - startPoint); - window.adjustmentFactor = Math.min(Math.max(window.adjustment / window.width, 0.0), 0.66); - startPoint = mouse.x; - } - } - } - // this property assignment is done here to not break 5.14.x qtvirtualkeyboard - // TODO: Move it to InputPanel when we depend on 5.15 - Component.onCompleted: { - if (inputPanel.hasOwnProperty("desktopPanel")) { - inputPanel.desktopPanel = true; - } - } -} diff --git a/virtualkeyboard.cpp b/virtualkeyboard.cpp index 298cac3810..d984622933 100644 --- a/virtualkeyboard.cpp +++ b/virtualkeyboard.cpp @@ -63,20 +63,6 @@ VirtualKeyboard::~VirtualKeyboard() = default; void VirtualKeyboard::init() { - // TODO: need a shared Qml engine - qCDebug(KWIN_VIRTUALKEYBOARD) << "Initializing window"; - m_inputWindow.reset(new QQuickView(nullptr)); - m_inputWindow->setFlags(Qt::FramelessWindowHint); - m_inputWindow->setGeometry(screens()->geometry(screens()->current())); - m_inputWindow->setResizeMode(QQuickView::SizeRootObjectToView); - m_inputWindow->setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral(KWIN_NAME "/virtualkeyboard/main.qml")))); - if (m_inputWindow->status() != QQuickView::Status::Ready) { - qCWarning(KWIN_VIRTUALKEYBOARD) << "window not ready yet"; - m_inputWindow.reset(); - return; - } - m_inputWindow->setProperty("__kwin_input_method", true); - connect(ScreenLockerWatcher::self(), &ScreenLockerWatcher::aboutToLock, this, &VirtualKeyboard::hide); if (waylandServer()) { @@ -118,28 +104,22 @@ void VirtualKeyboard::init() t2->create(); auto inputPanel = waylandServer()->display()->createInputPanelInterface(this); - connect(inputPanel, &InputPanelV1Interface::inputPanelSurfaceAdded, this, [this, inputPanel] (InputPanelSurfaceV1Interface *surface) { + connect(inputPanel, &InputPanelV1Interface::inputPanelSurfaceAdded, this, [this] (InputPanelSurfaceV1Interface *surface) { m_inputClient = waylandServer()->createInputPanelClient(surface); auto refreshFrame = [this] { - const QRect inputGeometry = m_inputClient->surface()->input().boundingRect(); - if (!m_trackedClient || inputGeometry.isEmpty()) { + if (!m_trackedClient) { return; } - m_trackedClient->setVirtualKeyboardGeometry(inputGeometry); + + m_trackedClient->setVirtualKeyboardGeometry(m_inputClient ? m_inputClient->inputGeometry() : QRect()); }; connect(surface->surface(), &SurfaceInterface::inputChanged, this, refreshFrame); - - connect(surface->surface(), &SurfaceInterface::inputChanged, this, refreshFrame); - connect(this, &VirtualKeyboard::hide, m_inputClient, [this] { - m_inputClient->hideClient(true); - }); - connect(this, &VirtualKeyboard::show, m_inputClient, [this] { - m_inputClient->hideClient(false); - }); - connect(surface->surface(), &SurfaceInterface::unmapped, this, [this, inputPanel, surface] { - m_inputClient->destroyClient(); - inputPanel->inputPanelSurfaceAdded(surface); + connect(surface->surface(), &QObject::destroyed, this, [this] { + if (m_trackedClient) { + m_trackedClient->setVirtualKeyboardGeometry({}); + } }); + updateInputPanelState(); refreshFrame(); }); @@ -182,7 +162,7 @@ void VirtualKeyboard::init() adoptInputMethodContext(); } else { waylandServer()->inputMethod()->sendDeactivate(); - Q_EMIT hide(); + hide(); } qApp->inputMethod()->update(Qt::ImQueryAll); }); @@ -197,7 +177,6 @@ void VirtualKeyboard::init() m_trackedClient = newClient; } - updateInputPanelState(); } else { m_waylandShowConnection = QMetaObject::Connection(); @@ -211,26 +190,21 @@ void VirtualKeyboard::init() } ); } - m_inputWindow->installEventFilter(this); - connect(Workspace::self(), &Workspace::destroyed, this, - [this] { - m_inputWindow.reset(); - } - ); - m_inputWindow->setColor(Qt::transparent); - m_inputWindow->setMask(m_inputWindow->rootObject()->childrenRect().toRect()); - connect(m_inputWindow->rootObject(), &QQuickItem::childrenRectChanged, m_inputWindow.data(), - [this] { - if (!m_inputWindow) { - return; - } - m_inputWindow->setMask(m_inputWindow->rootObject()->childrenRect().toRect()); - } - ); - connect(qApp->inputMethod(), &QInputMethod::visibleChanged, this, &VirtualKeyboard::updateInputPanelState); +} - connect(m_inputWindow->rootObject(), &QQuickItem::childrenRectChanged, this, &VirtualKeyboard::updateInputPanelState); +void VirtualKeyboard::show() +{ + auto t = waylandServer()->seat()->focusedTextInput(); + if (t) { + Q_EMIT t->enabledChanged(); + } +} + +void VirtualKeyboard::hide() +{ + waylandServer()->inputMethod()->sendDeactivate(); + updateInputPanelState(); } void VirtualKeyboard::setEnabled(bool enabled) @@ -373,57 +347,8 @@ void VirtualKeyboard::updateInputPanelState() return; } - if (m_inputWindow) { - const bool inputPanelHasBeenClosed = m_inputWindow->isVisible() && !qApp->inputMethod()->isVisible(); - if (inputPanelHasBeenClosed && m_floodTimer->isActive()) { - return; - } - m_floodTimer->start(); - - m_inputWindow->setVisible(qApp->inputMethod()->isVisible()); - - if (qApp->inputMethod()->isVisible()) { - m_inputWindow->setMask(m_inputWindow->rootObject()->childrenRect().toRect()); - } - - if (m_inputWindow->isVisible() && m_trackedClient && m_inputWindow->rootObject()) { - const QRect inputPanelGeom = m_inputWindow->rootObject()->childrenRect().toRect().translated(m_inputWindow->geometry().topLeft()); - - m_trackedClient->setVirtualKeyboardGeometry(inputPanelGeom); - - t->setInputPanelState(true, QRect(0, 0, 0, 0)); - - } else { - if (inputPanelHasBeenClosed && m_trackedClient) { - m_trackedClient->setVirtualKeyboardGeometry(QRect()); - } - - t->setInputPanelState(false, QRect(0, 0, 0, 0)); - } - } - - if (m_inputClient) { - m_trackedClient->setVirtualKeyboardGeometry(m_inputClient->frameGeometry()); - t->setInputPanelState(true, QRect(0, 0, 0, 0)); - } -} - -void VirtualKeyboard::show() -{ - if (m_inputWindow.isNull() || !m_enabled) { - return; - } - m_inputWindow->setGeometry(screens()->geometry(screens()->current())); - qApp->inputMethod()->show(); -} - -void VirtualKeyboard::hide() -{ - if (m_inputWindow.isNull()) { - return; - } - m_inputWindow->hide(); - qApp->inputMethod()->hide(); + m_trackedClient->setVirtualKeyboardGeometry(m_inputClient ? m_inputClient->inputGeometry() : QRect()); + t->setInputPanelState(m_inputClient && m_inputClient->isShown(false), QRect(0, 0, 0, 0)); } bool VirtualKeyboard::event(QEvent *e) @@ -596,37 +521,4 @@ bool VirtualKeyboard::event(QEvent *e) return QObject::event(e); } -bool VirtualKeyboard::eventFilter(QObject *o, QEvent *e) -{ - if (o != m_inputWindow.data() || !m_inputWindow->isVisible()) { - return false; - } - if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) { - QKeyEvent *event = static_cast(e); - if (event->nativeScanCode() == 0) { - // this is a key composed by the virtual keyboard - we need to send it to the client - const auto sym = input()->keyboard()->xkb()->fromKeyEvent(event); - if (sym != 0) { - if (waylandServer()) { - auto t = waylandServer()->seat()->focusedTextInput(); - if (t && t->isEnabled()) { - if (e->type() == QEvent::KeyPress) { - t->keysymPressed(sym); - } else if (e->type() == QEvent::KeyRelease) { - t->keysymReleased(sym); - } - } - } - } - return true; - } - } - return false; -} - -QWindow *VirtualKeyboard::inputPanel() const -{ - return m_inputWindow.data(); -} - } diff --git a/virtualkeyboard.h b/virtualkeyboard.h index 020d6ad6bb..565573608a 100644 --- a/virtualkeyboard.h +++ b/virtualkeyboard.h @@ -33,16 +33,13 @@ public: void init(); bool event(QEvent *e) override; - bool eventFilter(QObject *o, QEvent *event) override; - - QWindow *inputPanel() const; + void hide(); + void show(); Q_SIGNALS: void enabledChanged(bool enabled); private: - void show(); - void hide(); void setEnabled(bool enable); void updateSni(); void updateInputPanelState(); @@ -50,7 +47,6 @@ private: bool m_enabled = false; KStatusNotifierItem *m_sni = nullptr; - QScopedPointer m_inputWindow; QPointer m_inputClient; QPointer m_trackedClient; // If a surface loses focus immediately after being resized by the keyboard, don't react to it to avoid resize loops