kwin/src/inputmethod.h
Xaver Hugl b4e9443820 inputpanelv1window: fix showing and hiding
Instead of InputMethod directly calling showClient() on the input panel,
call methods that properly show or hide the panel as needed, with readyForPainting
set appropriately. This removes the cases where it's shown without being ready for
painting, which causes crashes.

BUG: 459404
2022-09-24 20:21:48 +00:00

146 lines
4 KiB
C++

/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KWIN_VIRTUAL_KEYBOARD_H
#define KWIN_VIRTUAL_KEYBOARD_H
#include "wayland/textinput_v2_interface.h"
#include <utility>
#include <vector>
#include <QObject>
#include <kwin_export.h>
#include <kwinglobals.h>
#include <QPointer>
#include <QTimer>
class QProcess;
namespace KWaylandServer
{
class InputMethodGrabV1;
}
namespace KWin
{
class Window;
class InputPanelV1Window;
/**
* This class implements the zwp_input_method_unstable_v1, which is currently used to provide
* the Virtual Keyboard using supported input method client (maliit-keyboard e.g.)
**/
class KWIN_EXPORT InputMethod : public QObject
{
Q_OBJECT
public:
enum ForwardModifiersForce {
NoForce = 0,
Force = 1,
};
InputMethod();
~InputMethod() override;
void init();
void setEnabled(bool enable);
bool isEnabled() const
{
return m_enabled;
}
bool isActive() const;
void setActive(bool active);
void hide();
void show();
bool isVisible() const;
bool isAvailable() const;
InputPanelV1Window *panel() const;
void setPanel(InputPanelV1Window *panel);
void setInputMethodCommand(const QString &path);
KWaylandServer::InputMethodGrabV1 *keyboardGrab();
bool shouldShowOnActive() const;
void forwardModifiers(ForwardModifiersForce force);
bool activeClientSupportsTextInput() const;
void forceActivate();
Q_SIGNALS:
void panelChanged();
void activeChanged(bool active);
void enabledChanged(bool enabled);
void visibleChanged();
void availableChanged();
void activeClientSupportsTextInputChanged();
private Q_SLOTS:
// textinput interface slots
void handleFocusedSurfaceChanged();
void surroundingTextChanged();
void contentTypeChanged();
void textInputInterfaceV2EnabledChanged();
void textInputInterfaceV3EnabledChanged();
void stateCommitted(uint32_t serial);
void textInputInterfaceV2StateUpdated(quint32 serial, KWaylandServer::TextInputV2Interface::UpdateReason reason);
// inputcontext slots
void setPreeditString(uint32_t serial, const QString &text, const QString &commit);
void setPreeditStyling(quint32 index, quint32 length, quint32 style);
void setPreeditCursor(qint32 index);
void key(quint32 serial, quint32 time, quint32 key, bool pressed);
void modifiers(quint32 serial, quint32 mods_depressed, quint32 mods_latched, quint32 mods_locked, quint32 group);
private:
void updateInputPanelState();
void adoptInputMethodContext();
void commitString(qint32 serial, const QString &text);
void keysymReceived(quint32 serial, quint32 time, quint32 sym, bool pressed, quint32 modifiers);
void deleteSurroundingText(int32_t index, uint32_t length);
void setCursorPosition(qint32 index, qint32 anchor);
void setLanguage(uint32_t serial, const QString &language);
void setTextDirection(uint32_t serial, Qt::LayoutDirection direction);
void startInputMethod();
void stopInputMethod();
void setTrackedWindow(Window *trackedWindow);
void installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboardGrab);
void updateModifiersMap(const QByteArray &modifiers);
bool touchEventTriggered() const;
void resetPendingPreedit();
struct
{
QString text = QString();
qint32 cursor = 0;
std::vector<std::pair<quint32, quint32>> highlightRanges;
} preedit;
bool m_enabled = true;
quint32 m_serial = 0;
QPointer<InputPanelV1Window> m_panel;
QPointer<Window> m_trackedWindow;
QPointer<KWaylandServer::InputMethodGrabV1> m_keyboardGrab;
QProcess *m_inputMethodProcess = nullptr;
QTimer m_inputMethodCrashTimer;
uint m_inputMethodCrashes = 0;
QString m_inputMethodCommand;
bool m_hasPendingModifiers = false;
bool m_activeClientSupportsTextInput = false;
bool m_shouldShowPanel = false;
};
}
#endif