File indexing completed on 2024-04-28 16:48:51

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #pragma once
0010 
0011 #include "wayland/textinput_v2_interface.h"
0012 
0013 #include <utility>
0014 #include <vector>
0015 
0016 #include <QObject>
0017 
0018 #include <kwin_export.h>
0019 #include <kwinglobals.h>
0020 
0021 #include <QPointer>
0022 #include <QTimer>
0023 
0024 class QProcess;
0025 
0026 namespace KWaylandServer
0027 {
0028 class InputMethodGrabV1;
0029 }
0030 
0031 namespace KWin
0032 {
0033 
0034 class Window;
0035 class InputPanelV1Window;
0036 
0037 /**
0038  * This class implements the zwp_input_method_unstable_v1, which is currently used to provide
0039  * the Virtual Keyboard using supported input method client (maliit-keyboard e.g.)
0040  **/
0041 class KWIN_EXPORT InputMethod : public QObject
0042 {
0043     Q_OBJECT
0044 public:
0045     enum ForwardModifiersForce {
0046         NoForce = 0,
0047         Force = 1,
0048     };
0049 
0050     InputMethod();
0051     ~InputMethod() override;
0052 
0053     void init();
0054     void setEnabled(bool enable);
0055     bool isEnabled() const
0056     {
0057         return m_enabled;
0058     }
0059     bool isActive() const;
0060     void setActive(bool active);
0061     void hide();
0062     void show();
0063     bool isVisible() const;
0064     bool isAvailable() const;
0065 
0066     InputPanelV1Window *panel() const;
0067     void setPanel(InputPanelV1Window *panel);
0068     void setInputMethodCommand(const QString &path);
0069 
0070     KWaylandServer::InputMethodGrabV1 *keyboardGrab();
0071     bool shouldShowOnActive() const;
0072 
0073     void forwardModifiers(ForwardModifiersForce force);
0074     bool activeClientSupportsTextInput() const;
0075     void forceActivate();
0076 
0077 Q_SIGNALS:
0078     void panelChanged();
0079     void activeChanged(bool active);
0080     void enabledChanged(bool enabled);
0081     void visibleChanged();
0082     void availableChanged();
0083     void activeClientSupportsTextInputChanged();
0084 
0085 private Q_SLOTS:
0086     // textinput interface slots
0087     void handleFocusedSurfaceChanged();
0088     void surroundingTextChanged();
0089     void contentTypeChanged();
0090     void textInputInterfaceV1EnabledChanged();
0091     void textInputInterfaceV2EnabledChanged();
0092     void textInputInterfaceV3EnabledChanged();
0093     void stateCommitted(uint32_t serial);
0094     void textInputInterfaceV1StateUpdated(quint32 serial);
0095     void textInputInterfaceV1Reset();
0096     void invokeAction(quint32 button, quint32 index);
0097     void textInputInterfaceV2StateUpdated(quint32 serial, KWaylandServer::TextInputV2Interface::UpdateReason reason);
0098     void textInputInterfaceV3EnableRequested();
0099 
0100     // inputcontext slots
0101     void setPreeditString(uint32_t serial, const QString &text, const QString &commit);
0102     void setPreeditStyling(quint32 index, quint32 length, quint32 style);
0103     void setPreeditCursor(qint32 index);
0104     void key(quint32 serial, quint32 time, quint32 key, bool pressed);
0105     void modifiers(quint32 serial, quint32 mods_depressed, quint32 mods_latched, quint32 mods_locked, quint32 group);
0106 
0107 private:
0108     void updateInputPanelState();
0109     void adoptInputMethodContext();
0110     void commitString(qint32 serial, const QString &text);
0111     void keysymReceived(quint32 serial, quint32 time, quint32 sym, bool pressed, quint32 modifiers);
0112     void deleteSurroundingText(int32_t index, uint32_t length);
0113     void setCursorPosition(qint32 index, qint32 anchor);
0114     void setLanguage(uint32_t serial, const QString &language);
0115     void setTextDirection(uint32_t serial, Qt::LayoutDirection direction);
0116     void startInputMethod();
0117     void stopInputMethod();
0118     void setTrackedWindow(Window *trackedWindow);
0119     void installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboardGrab);
0120     void updateModifiersMap(const QByteArray &modifiers);
0121 
0122     bool touchEventTriggered() const;
0123     void resetPendingPreedit();
0124     void refreshActive();
0125 
0126     struct
0127     {
0128         QString text = QString();
0129         qint32 cursor = 0;
0130         std::vector<std::pair<quint32, quint32>> highlightRanges;
0131     } preedit;
0132 
0133     bool m_enabled = true;
0134     quint32 m_serial = 0;
0135     QPointer<InputPanelV1Window> m_panel;
0136     QPointer<Window> m_trackedWindow;
0137     QPointer<KWaylandServer::InputMethodGrabV1> m_keyboardGrab;
0138 
0139     QProcess *m_inputMethodProcess = nullptr;
0140     QTimer m_inputMethodCrashTimer;
0141     uint m_inputMethodCrashes = 0;
0142     QString m_inputMethodCommand;
0143 
0144     bool m_hasPendingModifiers = false;
0145     bool m_activeClientSupportsTextInput = false;
0146     bool m_shouldShowPanel = false;
0147 };
0148 
0149 }