diff --git a/src/inputmethod.cpp b/src/inputmethod.cpp index 5e2e62c1d2..d05349c133 100644 --- a/src/inputmethod.cpp +++ b/src/inputmethod.cpp @@ -86,7 +86,6 @@ void InputMethod::init() new TextInputManagerV2Interface(waylandServer()->display()); new TextInputManagerV3Interface(waylandServer()->display()); - connect(workspace(), &Workspace::clientAdded, this, &InputMethod::clientAdded); connect(waylandServer()->seat(), &SeatInterface::focusedTextInputSurfaceChanged, this, &InputMethod::handleFocusedSurfaceChanged); TextInputV2Interface *textInputV2 = waylandServer()->seat()->textInputV2(); @@ -118,11 +117,15 @@ void InputMethod::hide() setActive(false); } -void InputMethod::setActive(bool active) +bool InputMethod::touchEventTriggered() const { - active &= input()->touch() + return input()->touch() && input()->touch()->lastEventTime() > input()->keyboard()->lastEventTime() && input()->touch()->lastEventTime() > input()->pointer()->lastEventTime(); +} + +void InputMethod::setActive(bool active) +{ const bool wasActive = waylandServer()->inputMethod()->context(); if (wasActive && !active) { waylandServer()->inputMethod()->sendDeactivate(); @@ -148,18 +151,14 @@ void InputMethod::setActive(bool active) } } -void InputMethod::clientAdded(AbstractClient *_client) +void InputMethod::setPanel(InputPanelV1Client *client) { - if (!_client->isInputMethod()) { - return; - } - + Q_ASSERT(client->isInputMethod()); if (m_inputClient) { - qCWarning(KWIN_VIRTUALKEYBOARD) << "Replacing input client" << m_inputClient << "with" << _client; + qCWarning(KWIN_VIRTUALKEYBOARD) << "Replacing input client" << m_inputClient << "with" << client; disconnect(m_inputClient, nullptr, this, nullptr); } - const auto client = dynamic_cast(_client); m_inputClient = client; connect(client->surface(), &SurfaceInterface::inputChanged, this, &InputMethod::updateInputPanelState); connect(client, &QObject::destroyed, this, [this] { @@ -253,6 +252,9 @@ void InputMethod::textInputInterfaceV2StateUpdated(quint32 serial, KWaylandServe if (!t2 || !t2->isEnabled()) { return; } + if (m_inputClient && touchEventTriggered()) { + m_inputClient->allow(); + } switch (reason) { case KWaylandServer::TextInputV2Interface::UpdateReason::StateChange: break; @@ -526,6 +528,10 @@ void InputMethod::updateInputPanelState() return; } + if (m_inputClient && touchEventTriggered()) { + m_inputClient->allow(); + } + QRect overlap = QRect(0, 0, 0, 0); if (m_trackedClient) { const bool bottomKeyboard = m_inputClient && m_inputClient->mode() != InputPanelV1Client::Overlay && m_inputClient->isShown(false); diff --git a/src/inputmethod.h b/src/inputmethod.h index 79e667670c..77fcfae908 100644 --- a/src/inputmethod.h +++ b/src/inputmethod.h @@ -54,6 +54,7 @@ public: bool isVisible() const; bool isAvailable() const; + void setPanel(InputPanelV1Client* client); void setInputMethodCommand(const QString &path); Q_SIGNALS: @@ -63,8 +64,6 @@ Q_SIGNALS: void availableChanged(); private Q_SLOTS: - void clientAdded(AbstractClient* client); - // textinput interface slots void handleFocusedSurfaceChanged(); void surroundingTextChanged(); @@ -94,6 +93,8 @@ private: void setTrackedClient(AbstractClient *trackedClient); void installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboardGrab); + bool touchEventTriggered() const; + struct { QString text = QString(); quint32 begin = 0; diff --git a/src/inputpanelv1client.cpp b/src/inputpanelv1client.cpp index a31f76bfa9..7883df1fe0 100644 --- a/src/inputpanelv1client.cpp +++ b/src/inputpanelv1client.cpp @@ -13,6 +13,7 @@ #include "workspace.h" #include "abstract_wayland_output.h" #include "platform.h" +#include "inputmethod.h" #include #include #include @@ -38,6 +39,8 @@ InputPanelV1Client::InputPanelV1Client(InputPanelSurfaceV1Interface *panelSurfac connect(panelSurface, &InputPanelSurfaceV1Interface::topLevel, this, &InputPanelV1Client::showTopLevel); connect(panelSurface, &InputPanelSurfaceV1Interface::overlayPanel, this, &InputPanelV1Client::showOverlayPanel); connect(panelSurface, &InputPanelSurfaceV1Interface::destroyed, this, &InputPanelV1Client::destroyClient); + + InputMethod::self()->setPanel(this); } void InputPanelV1Client::showOverlayPanel() @@ -53,12 +56,20 @@ void InputPanelV1Client::showTopLevel(OutputInterface *output, InputPanelSurface Q_UNUSED(position); m_mode = Toplevel; setOutput(output); - reposition(); +} + +void InputPanelV1Client::allow() +{ setReadyForPainting(); + reposition(); } void KWin::InputPanelV1Client::reposition() { + if (!readyForPainting()) { + return; + } + switch (m_mode) { case Toplevel: { if (m_output) { @@ -109,7 +120,7 @@ NET::WindowType InputPanelV1Client::windowType(bool, int) const QRect InputPanelV1Client::inputGeometry() const { - return surface()->input().boundingRect().translated(pos()); + return readyForPainting() ? surface()->input().boundingRect().translated(pos()) : QRect(); } void InputPanelV1Client::setOutput(OutputInterface *outputIface) diff --git a/src/inputpanelv1client.h b/src/inputpanelv1client.h index 7748e033d9..66ae8a1234 100644 --- a/src/inputpanelv1client.h +++ b/src/inputpanelv1client.h @@ -47,6 +47,7 @@ public: { return m_mode; } + void allow(); protected: void moveResizeInternal(const QRect &rect, MoveResizeMode mode) override;