inputmethod: Use touch events to decide if the panel is shown not the state
Prefer hiding/showing the panel (i.e. the window) when not a touch event than stopping to make the inputmethod active. This way we remain compatible with non-virtualkeyboard inputmethods.
This commit is contained in:
parent
5b9deafa14
commit
3e77907d21
4 changed files with 33 additions and 14 deletions
|
@ -86,7 +86,6 @@ void InputMethod::init()
|
||||||
new TextInputManagerV2Interface(waylandServer()->display());
|
new TextInputManagerV2Interface(waylandServer()->display());
|
||||||
new TextInputManagerV3Interface(waylandServer()->display());
|
new TextInputManagerV3Interface(waylandServer()->display());
|
||||||
|
|
||||||
connect(workspace(), &Workspace::clientAdded, this, &InputMethod::clientAdded);
|
|
||||||
connect(waylandServer()->seat(), &SeatInterface::focusedTextInputSurfaceChanged, this, &InputMethod::handleFocusedSurfaceChanged);
|
connect(waylandServer()->seat(), &SeatInterface::focusedTextInputSurfaceChanged, this, &InputMethod::handleFocusedSurfaceChanged);
|
||||||
|
|
||||||
TextInputV2Interface *textInputV2 = waylandServer()->seat()->textInputV2();
|
TextInputV2Interface *textInputV2 = waylandServer()->seat()->textInputV2();
|
||||||
|
@ -118,11 +117,15 @@ void InputMethod::hide()
|
||||||
setActive(false);
|
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()->keyboard()->lastEventTime()
|
||||||
&& input()->touch()->lastEventTime() > input()->pointer()->lastEventTime();
|
&& input()->touch()->lastEventTime() > input()->pointer()->lastEventTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputMethod::setActive(bool active)
|
||||||
|
{
|
||||||
const bool wasActive = waylandServer()->inputMethod()->context();
|
const bool wasActive = waylandServer()->inputMethod()->context();
|
||||||
if (wasActive && !active) {
|
if (wasActive && !active) {
|
||||||
waylandServer()->inputMethod()->sendDeactivate();
|
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()) {
|
Q_ASSERT(client->isInputMethod());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_inputClient) {
|
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);
|
disconnect(m_inputClient, nullptr, this, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto client = dynamic_cast<InputPanelV1Client *>(_client);
|
|
||||||
m_inputClient = client;
|
m_inputClient = client;
|
||||||
connect(client->surface(), &SurfaceInterface::inputChanged, this, &InputMethod::updateInputPanelState);
|
connect(client->surface(), &SurfaceInterface::inputChanged, this, &InputMethod::updateInputPanelState);
|
||||||
connect(client, &QObject::destroyed, this, [this] {
|
connect(client, &QObject::destroyed, this, [this] {
|
||||||
|
@ -253,6 +252,9 @@ void InputMethod::textInputInterfaceV2StateUpdated(quint32 serial, KWaylandServe
|
||||||
if (!t2 || !t2->isEnabled()) {
|
if (!t2 || !t2->isEnabled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (m_inputClient && touchEventTriggered()) {
|
||||||
|
m_inputClient->allow();
|
||||||
|
}
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case KWaylandServer::TextInputV2Interface::UpdateReason::StateChange:
|
case KWaylandServer::TextInputV2Interface::UpdateReason::StateChange:
|
||||||
break;
|
break;
|
||||||
|
@ -526,6 +528,10 @@ void InputMethod::updateInputPanelState()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_inputClient && touchEventTriggered()) {
|
||||||
|
m_inputClient->allow();
|
||||||
|
}
|
||||||
|
|
||||||
QRect overlap = QRect(0, 0, 0, 0);
|
QRect overlap = QRect(0, 0, 0, 0);
|
||||||
if (m_trackedClient) {
|
if (m_trackedClient) {
|
||||||
const bool bottomKeyboard = m_inputClient && m_inputClient->mode() != InputPanelV1Client::Overlay && m_inputClient->isShown(false);
|
const bool bottomKeyboard = m_inputClient && m_inputClient->mode() != InputPanelV1Client::Overlay && m_inputClient->isShown(false);
|
||||||
|
|
|
@ -54,6 +54,7 @@ public:
|
||||||
bool isVisible() const;
|
bool isVisible() const;
|
||||||
bool isAvailable() const;
|
bool isAvailable() const;
|
||||||
|
|
||||||
|
void setPanel(InputPanelV1Client* client);
|
||||||
void setInputMethodCommand(const QString &path);
|
void setInputMethodCommand(const QString &path);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
@ -63,8 +64,6 @@ Q_SIGNALS:
|
||||||
void availableChanged();
|
void availableChanged();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void clientAdded(AbstractClient* client);
|
|
||||||
|
|
||||||
// textinput interface slots
|
// textinput interface slots
|
||||||
void handleFocusedSurfaceChanged();
|
void handleFocusedSurfaceChanged();
|
||||||
void surroundingTextChanged();
|
void surroundingTextChanged();
|
||||||
|
@ -94,6 +93,8 @@ private:
|
||||||
void setTrackedClient(AbstractClient *trackedClient);
|
void setTrackedClient(AbstractClient *trackedClient);
|
||||||
void installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboardGrab);
|
void installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboardGrab);
|
||||||
|
|
||||||
|
bool touchEventTriggered() const;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
QString text = QString();
|
QString text = QString();
|
||||||
quint32 begin = 0;
|
quint32 begin = 0;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
#include "abstract_wayland_output.h"
|
#include "abstract_wayland_output.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "inputmethod.h"
|
||||||
#include <KWaylandServer/output_interface.h>
|
#include <KWaylandServer/output_interface.h>
|
||||||
#include <KWaylandServer/seat_interface.h>
|
#include <KWaylandServer/seat_interface.h>
|
||||||
#include <KWaylandServer/surface_interface.h>
|
#include <KWaylandServer/surface_interface.h>
|
||||||
|
@ -38,6 +39,8 @@ InputPanelV1Client::InputPanelV1Client(InputPanelSurfaceV1Interface *panelSurfac
|
||||||
connect(panelSurface, &InputPanelSurfaceV1Interface::topLevel, this, &InputPanelV1Client::showTopLevel);
|
connect(panelSurface, &InputPanelSurfaceV1Interface::topLevel, this, &InputPanelV1Client::showTopLevel);
|
||||||
connect(panelSurface, &InputPanelSurfaceV1Interface::overlayPanel, this, &InputPanelV1Client::showOverlayPanel);
|
connect(panelSurface, &InputPanelSurfaceV1Interface::overlayPanel, this, &InputPanelV1Client::showOverlayPanel);
|
||||||
connect(panelSurface, &InputPanelSurfaceV1Interface::destroyed, this, &InputPanelV1Client::destroyClient);
|
connect(panelSurface, &InputPanelSurfaceV1Interface::destroyed, this, &InputPanelV1Client::destroyClient);
|
||||||
|
|
||||||
|
InputMethod::self()->setPanel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputPanelV1Client::showOverlayPanel()
|
void InputPanelV1Client::showOverlayPanel()
|
||||||
|
@ -53,12 +56,20 @@ void InputPanelV1Client::showTopLevel(OutputInterface *output, InputPanelSurface
|
||||||
Q_UNUSED(position);
|
Q_UNUSED(position);
|
||||||
m_mode = Toplevel;
|
m_mode = Toplevel;
|
||||||
setOutput(output);
|
setOutput(output);
|
||||||
reposition();
|
}
|
||||||
|
|
||||||
|
void InputPanelV1Client::allow()
|
||||||
|
{
|
||||||
setReadyForPainting();
|
setReadyForPainting();
|
||||||
|
reposition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KWin::InputPanelV1Client::reposition()
|
void KWin::InputPanelV1Client::reposition()
|
||||||
{
|
{
|
||||||
|
if (!readyForPainting()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (m_mode) {
|
switch (m_mode) {
|
||||||
case Toplevel: {
|
case Toplevel: {
|
||||||
if (m_output) {
|
if (m_output) {
|
||||||
|
@ -109,7 +120,7 @@ NET::WindowType InputPanelV1Client::windowType(bool, int) const
|
||||||
|
|
||||||
QRect InputPanelV1Client::inputGeometry() const
|
QRect InputPanelV1Client::inputGeometry() const
|
||||||
{
|
{
|
||||||
return surface()->input().boundingRect().translated(pos());
|
return readyForPainting() ? surface()->input().boundingRect().translated(pos()) : QRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputPanelV1Client::setOutput(OutputInterface *outputIface)
|
void InputPanelV1Client::setOutput(OutputInterface *outputIface)
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
{
|
{
|
||||||
return m_mode;
|
return m_mode;
|
||||||
}
|
}
|
||||||
|
void allow();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void moveResizeInternal(const QRect &rect, MoveResizeMode mode) override;
|
void moveResizeInternal(const QRect &rect, MoveResizeMode mode) override;
|
||||||
|
|
Loading…
Reference in a new issue