File indexing completed on 2024-02-18 16:20:29

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2013, 2016, 2017 Martin Gräßlin <mgraesslin@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #pragma once
0010 #include "input.h"
0011 #include <xkbcommon/xkbcommon.h>
0012 
0013 #include <kwin_export.h>
0014 
0015 #include <KConfigGroup>
0016 
0017 #include <QLoggingCategory>
0018 
0019 #include <optional>
0020 
0021 Q_DECLARE_LOGGING_CATEGORY(KWIN_XKB)
0022 
0023 struct xkb_context;
0024 struct xkb_keymap;
0025 struct xkb_state;
0026 struct xkb_compose_table;
0027 struct xkb_compose_state;
0028 typedef uint32_t xkb_mod_index_t;
0029 typedef uint32_t xkb_led_index_t;
0030 typedef uint32_t xkb_keysym_t;
0031 typedef uint32_t xkb_layout_index_t;
0032 
0033 namespace KWaylandServer
0034 {
0035 class SeatInterface;
0036 }
0037 
0038 namespace KWin
0039 {
0040 
0041 class KWIN_EXPORT Xkb : public QObject
0042 {
0043     Q_OBJECT
0044 public:
0045     Xkb(bool followLocale1 = false);
0046     ~Xkb() override;
0047     void setConfig(const KSharedConfigPtr &config);
0048     void setNumLockConfig(const KSharedConfigPtr &config);
0049 
0050     void updateModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group);
0051     void updateKey(uint32_t key, InputRedirection::KeyboardKeyState state);
0052     xkb_keysym_t toKeysym(uint32_t key);
0053     xkb_keysym_t currentKeysym() const
0054     {
0055         return m_keysym;
0056     }
0057     QString toString(xkb_keysym_t keysym);
0058     Qt::Key toQtKey(xkb_keysym_t keysym,
0059                     uint32_t scanCode = 0,
0060                     Qt::KeyboardModifiers modifiers = Qt::KeyboardModifiers(),
0061                     bool superAsMeta = false) const;
0062     Qt::KeyboardModifiers modifiers() const;
0063     Qt::KeyboardModifiers modifiersRelevantForGlobalShortcuts(uint32_t scanCode = 0) const;
0064     Qt::KeyboardModifiers modifiersRelevantForTabBox() const;
0065     bool shouldKeyRepeat(quint32 key) const;
0066 
0067     void switchToNextLayout();
0068     void switchToPreviousLayout();
0069     bool switchToLayout(xkb_layout_index_t layout);
0070 
0071     LEDs leds() const
0072     {
0073         return m_leds;
0074     }
0075 
0076     xkb_keymap *keymap() const
0077     {
0078         return m_keymap;
0079     }
0080 
0081     xkb_state *state() const
0082     {
0083         return m_state;
0084     }
0085 
0086     quint32 currentLayout() const
0087     {
0088         return m_currentLayout;
0089     }
0090 
0091     const auto &modifierState() const
0092     {
0093         return m_modifierState;
0094     }
0095     QString layoutName(xkb_layout_index_t index) const;
0096     QString layoutName() const;
0097     QString layoutShortName(int index) const;
0098     quint32 numberOfLayouts() const;
0099 
0100     /**
0101      * Forwards the current modifier state to the Wayland seat
0102      */
0103     void forwardModifiers();
0104 
0105     void setSeat(KWaylandServer::SeatInterface *seat);
0106     QByteArray keymapContents() const;
0107 
0108     std::optional<int> keycodeFromKeysym(xkb_keysym_t keysym);
0109 
0110     void setFollowLocale1(bool follow);
0111 
0112 public Q_SLOTS:
0113     void reconfigure();
0114 
0115 Q_SIGNALS:
0116     void ledsChanged(const LEDs &leds);
0117     void modifierStateChanged();
0118 
0119 private:
0120     void applyEnvironmentRules(xkb_rule_names &);
0121     xkb_keymap *loadKeymapFromConfig();
0122     xkb_keymap *loadDefaultKeymap();
0123     xkb_keymap *loadKeymapFromLocale1();
0124     void updateKeymap(xkb_keymap *keymap);
0125     void createKeymapFile();
0126     void updateModifiers();
0127     void updateConsumedModifiers(uint32_t key);
0128     xkb_context *m_context;
0129     xkb_keymap *m_keymap;
0130     QStringList m_layoutList;
0131     xkb_state *m_state;
0132     xkb_mod_index_t m_shiftModifier;
0133     xkb_mod_index_t m_capsModifier;
0134     xkb_mod_index_t m_controlModifier;
0135     xkb_mod_index_t m_altModifier;
0136     xkb_mod_index_t m_metaModifier;
0137     xkb_mod_index_t m_numModifier;
0138     xkb_led_index_t m_numLock;
0139     xkb_led_index_t m_capsLock;
0140     xkb_led_index_t m_scrollLock;
0141     Qt::KeyboardModifiers m_modifiers;
0142     Qt::KeyboardModifiers m_consumedModifiers;
0143     xkb_keysym_t m_keysym;
0144     quint32 m_currentLayout = 0;
0145 
0146     struct
0147     {
0148         xkb_compose_table *table = nullptr;
0149         xkb_compose_state *state = nullptr;
0150     } m_compose;
0151     LEDs m_leds;
0152     KConfigGroup m_configGroup;
0153     KSharedConfigPtr m_numLockConfig;
0154 
0155     struct
0156     {
0157         xkb_mod_index_t depressed = 0;
0158         xkb_mod_index_t latched = 0;
0159         xkb_mod_index_t locked = 0;
0160     } m_modifierState;
0161 
0162     QPointer<KWaylandServer::SeatInterface> m_seat;
0163     const bool m_followLocale1;
0164 };
0165 
0166 inline Qt::KeyboardModifiers Xkb::modifiers() const
0167 {
0168     return m_modifiers;
0169 }
0170 
0171 }