From 437c17d098de284635642fa27874a91fb9ef4cde Mon Sep 17 00:00:00 2001 From: liuyuanpeng Date: Mon, 17 Apr 2023 15:46:47 +0800 Subject: [PATCH] fix(keyboard): use QCoreApplication::sendEvent when use wayland MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Description:wayland下采用QCoreApplication::sendEvent方式来模拟按键事件 Log:https://gitee.com/openkylin/ukui-screensaver/issues/I5XAG9?from=project-issue --- Common/CMakeLists.txt | 21 +- {src => Common}/plasma-shell-manager.cpp | 77 +++++- {src => Common}/plasma-shell-manager.h | 16 ++ VirtualKeyboard/CMakeLists.txt | 11 +- VirtualKeyboard/src/fakekeyboard.h | 114 +++++++++ VirtualKeyboard/src/letterswidget.cpp | 27 ++- VirtualKeyboard/src/letterswidget.h | 1 + VirtualKeyboard/src/qtkeyboard.cpp | 225 ++++++++++++++++++ VirtualKeyboard/src/qtkeyboard.h | 49 ++++ VirtualKeyboard/src/virtualkeyboardwidget.cpp | 12 +- VirtualKeyboard/src/virtualkeyboardwidget.h | 5 +- VirtualKeyboard/src/x11keyboard.cpp | 9 +- VirtualKeyboard/src/x11keyboard.h | 72 +----- src/CMakeLists.txt | 2 - src/fullbackgroundwidget.cpp | 1 - src/lockwidget.cpp | 30 +-- 16 files changed, 544 insertions(+), 128 deletions(-) rename {src => Common}/plasma-shell-manager.cpp (67%) rename {src => Common}/plasma-shell-manager.h (77%) create mode 100644 VirtualKeyboard/src/fakekeyboard.h create mode 100644 VirtualKeyboard/src/qtkeyboard.cpp create mode 100644 VirtualKeyboard/src/qtkeyboard.h diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt index fc628ff..a53f577 100644 --- a/Common/CMakeLists.txt +++ b/Common/CMakeLists.txt @@ -1,10 +1,21 @@ pkg_check_modules(GLIB REQUIRED glib-2.0) +find_package(X11 REQUIRED) +find_package(KF5WindowSystem) + +include_directories( + ${Qt5Core_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} + ${Qt5DBus_INCLUDE_DIRS} + ${GLIB2_INCLUDE_DIRS} + ${KF5Wayland_LIBRARIES} + ) qt5_wrap_cpp(Common_SRC autoresize.h checkbutton.h commonfunc.h glibinterface.h + plasma-shell-manager.h ) set(Common_SRC @@ -13,14 +24,8 @@ set(Common_SRC checkbutton.cpp commonfunc.cpp glibinterface.cpp - ) - -include_directories( - ${Qt5Core_INCLUDE_DIRS} - ${Qt5Widgets_INCLUDE_DIRS} - ${Qt5DBus_INCLUDE_DIRS} - ${GLIB2_INCLUDE_DIRS} + plasma-shell-manager.cpp ) add_library(Common STATIC ${Common_SRC}) -target_link_libraries(Common Qt5::Core Qt5::DBus Qt5::Widgets ${GIOUNIX2_LIBRARIES}) +target_link_libraries(Common Qt5::Core Qt5::DBus Qt5::Widgets ${GIOUNIX2_LIBRARIES} ${KF5Wayland_LIBRARIES} -lKF5WaylandClient -lKF5WaylandServer KF5::WindowSystem) diff --git a/src/plasma-shell-manager.cpp b/Common/plasma-shell-manager.cpp similarity index 67% rename from src/plasma-shell-manager.cpp rename to Common/plasma-shell-manager.cpp index 98659f0..eeea7e4 100644 --- a/src/plasma-shell-manager.cpp +++ b/Common/plasma-shell-manager.cpp @@ -15,6 +15,7 @@ * along with this program; if not, see . * **/ + #include "plasma-shell-manager.h" #include @@ -129,8 +130,40 @@ bool PlasmaShellManager::supportPlasmaWindowManagement() return m_windowManager && m_appWindow; } +bool PlasmaShellManager::supportFakeInput() +{ + return m_fakeInput; +} + +bool PlasmaShellManager::supportKeyState() +{ + return m_keyState; +} + +KWayland::Client::Keystate::State PlasmaShellManager::getKeyState(KWayland::Client::Keystate::Key key) +{ + if(!supportKeyState()){ + return KWayland::Client::Keystate::Unlocked; + } + + return m_keyStateMap[key]; +} + +void PlasmaShellManager::setKeyPressed(quint32 key) +{ + if(!supportFakeInput()) + return ; + + m_fakeInput->requestKeyboardKeyPress(key); + m_fakeInput->requestKeyboardKeyRelease(key); +} + PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent) { + m_keyStateMap.insert(KWayland::Client::Keystate::Key::CapsLock,KWayland::Client::Keystate::Unlocked); + m_keyStateMap.insert(KWayland::Client::Keystate::Key::NumLock,KWayland::Client::Keystate::Unlocked); + m_keyStateMap.insert(KWayland::Client::Keystate::Key::ScrollLock,KWayland::Client::Keystate::Unlocked); + auto connection = KWayland::Client::ConnectionThread::fromApplication(qApp); auto registry = new KWayland::Client::Registry(this); registry->create(connection->display()); @@ -161,15 +194,15 @@ PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent) m_appWindow = window; connect(m_appWindow, &KWayland::Client::PlasmaWindow::activeChanged, - [this]() { - this->setAppWindowKeepAbove(true); - this->setAppWindowActive(); - }); + [this]() { + this->setAppWindowKeepAbove(true); + this->setAppWindowActive(); + }); connect(m_appWindow, &KWayland::Client::PlasmaWindow::keepAboveChanged, - [this]() { - this->setAppWindowKeepAbove(true); - this->setAppWindowActive(); - }); + [this]() { + this->setAppWindowKeepAbove(true); + this->setAppWindowActive(); + }); } } }); @@ -183,6 +216,34 @@ PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent) } }); + connect(registry, &KWayland::Client::Registry::fakeInputAnnounced, this, [=](){ + qDebug()<<"fakeInputAnnounced"; + const auto interface = registry->interface(KWayland::Client::Registry::Interface::FakeInput); + if (interface.name != 0) { + qDebug()<<"createFakeInput"; + m_fakeInput = registry->createFakeInput(interface.name, interface.version); + m_fakeInput->authenticate("ukui-screensaver-dialog","virual keyboard"); + } + }); + + connect(registry, &KWayland::Client::Registry::keystateAnnounced, this, [=](){ + qDebug()<<"keystateAnnounced"; + const auto interface = registry->interface(KWayland::Client::Registry::Interface::Keystate); + if (interface.name != 0) { + qDebug()<<"createKeyState"; + m_keyState = registry->createKeystate(interface.name, interface.version); + if(m_keyState){ + connect(m_keyState, &KWayland::Client::Keystate::stateChanged, + [this](KWayland::Client::Keystate::Key key,KWayland::Client::Keystate::State state) { + qDebug()<<"key = "<fetchStates(); + } + } + }); + registry->setup(); connection->roundtrip(); } diff --git a/src/plasma-shell-manager.h b/Common/plasma-shell-manager.h similarity index 77% rename from src/plasma-shell-manager.h rename to Common/plasma-shell-manager.h index 35516aa..e5e0230 100644 --- a/src/plasma-shell-manager.h +++ b/Common/plasma-shell-manager.h @@ -15,14 +15,18 @@ * along with this program; if not, see . * **/ + #ifndef PLASMASHELLMANAGER_H #define PLASMASHELLMANAGER_H #include #include +#include #include #include #include +#include +#include class PlasmaShellManager : public QObject { @@ -35,9 +39,16 @@ public: bool setMaximized(QWindow *window); bool setRole(QWindow *window, KWayland::Client::PlasmaShellSurface::Role role); bool setPos(QWindow *window, const QPoint &pos); + void setKeyPressed(quint32 key); + bool supportPlasmaShell(); bool supportShell(); bool supportPlasmaWindowManagement(); + bool supportFakeInput(); + bool supportKeyState(); + KWayland::Client::Keystate::State getKeyState(KWayland::Client::Keystate::Key key); +Q_SIGNALS: + void keyStateChanged(); private: explicit PlasmaShellManager(QObject *parent = nullptr); @@ -46,8 +57,13 @@ private: KWayland::Client::Shell *m_shell = nullptr; KWayland::Client::PlasmaWindowManagement *m_windowManager = nullptr; KWayland::Client::PlasmaWindow *m_appWindow = nullptr; + KWayland::Client::FakeInput *m_fakeInput = nullptr; + KWayland::Client::Keystate *m_keyState = nullptr; bool isFirstCreate = true; + + QMap m_keyStateMap; + }; diff --git a/VirtualKeyboard/CMakeLists.txt b/VirtualKeyboard/CMakeLists.txt index 32bd6ef..aa1ddf2 100644 --- a/VirtualKeyboard/CMakeLists.txt +++ b/VirtualKeyboard/CMakeLists.txt @@ -4,9 +4,15 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) +include_directories(${PROJECT_SOURCE_DIR}/Common) + qt5_add_resources(VirtualKeyboard_SRC src/keyboard.qrc) +qt5_wrap_cpp(VirtualKeyboard_SRC + src/fakekeyboard.h + ) + set(VirtualKeyboard_SRC ${VirtualKeyboard_SRC} src/charsmorewidget.cpp @@ -18,12 +24,13 @@ set(VirtualKeyboard_SRC src/numberswidget.cpp src/virtualkeyboardwidget.cpp src/x11keyboard.cpp + src/qtkeyboard.cpp ) include_directories( ${Qt5Core_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} - ) + ) add_library(VirtualKeyboard STATIC ${VirtualKeyboard_SRC}) -target_link_libraries(VirtualKeyboard Qt5::Core Qt5::Widgets) +target_link_libraries(VirtualKeyboard Qt5::Core Qt5::Widgets Qt5::X11Extras Common) diff --git a/VirtualKeyboard/src/fakekeyboard.h b/VirtualKeyboard/src/fakekeyboard.h new file mode 100644 index 0000000..65a22ce --- /dev/null +++ b/VirtualKeyboard/src/fakekeyboard.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef FAKEKEYBOARD_H +#define FAKEKEYBOARD_H + +#include +#include + +class Modifier : public QObject +{ + Q_OBJECT +public: + Modifier(){} + + enum MOD{ + UNKNOWN = -1, + CTRL, + SHIFT, + ALT, + SUPER + }; + Q_ENUM(MOD) + + static QString getModifierName(int mod) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + const char* modName = metaEnum.valueToKey(mod); + QString result = QString(modName).toLower(); + return result; + } + static MOD getModifier(const QString &modName) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + MOD mod = (MOD)metaEnum.keyToValue(modName.toUpper().toLocal8Bit().data()); + return mod; + } +}; + +class FuncKey : public QObject +{ + Q_OBJECT +public: + FuncKey(){} + + enum FUNCKEY { + UNKNOWN = -1, + SPACE = 0, + BACKSPACE, + ENTER, + HOME, + END, + PGUP, + PGDN, + INSERT, + DELETE, + UP, + DOWN, + LEFT, + RIGHT, + CAPSLOCK + }; + Q_ENUM(FUNCKEY) + static QString getKeyName(int key) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + const char* keyName = metaEnum.valueToKey(key); + QString result = QString(keyName).toLower(); + return result; + } + static FUNCKEY getKey(const QString &keyName) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + FUNCKEY key = (FUNCKEY)metaEnum.keyToValue(keyName.toUpper().toLocal8Bit().data()); + return key; + } +}; + +class FakeKeyboard : public QObject +{ + Q_OBJECT +public: + explicit FakeKeyboard(QObject *parent = nullptr) + : QObject(parent) + { + + } + + virtual void addModifier(Modifier::MOD mod) = 0; + virtual void removeModifier(Modifier::MOD mod) = 0; + virtual bool hasModifier(Modifier::MOD mod) = 0; + virtual QList getAllModifier() = 0; + virtual void clearModifier() = 0; + +public Q_SLOTS: + virtual void onKeyPressed(QChar c) = 0; + virtual void onKeyPressed(FuncKey::FUNCKEY key) = 0; +}; + +#endif // FAKEKEYBOARD_H diff --git a/VirtualKeyboard/src/letterswidget.cpp b/VirtualKeyboard/src/letterswidget.cpp index d02f40a..102d64b 100644 --- a/VirtualKeyboard/src/letterswidget.cpp +++ b/VirtualKeyboard/src/letterswidget.cpp @@ -17,17 +17,29 @@ **/ #include "letterswidget.h" #include "commondef.h" +#include "plasma-shell-manager.h" #include +#include +#include LettersWidget::LettersWidget(QWidget *parent/* = nullptr*/) : QWidget(parent) { this->setAttribute(Qt::WA_TranslucentBackground);//背景透明 initUI(); - settings = new QGSettings("org.ukui.peripherals-keyboard", "", this); - connect(settings, &QGSettings::changed, - this, &LettersWidget::onCapsChanged); - capsState = settings->get("capslock-state").toBool(); + + if(QString(qgetenv("XDG_SESSION_TYPE")) == "wayland") { + isWayland = true; + } + + if(isWayland){ + connect(PlasmaShellManager::getInstance(), &PlasmaShellManager::keyStateChanged, + this, &LettersWidget::onCapsChanged); + }else{ + settings = new QGSettings("org.ukui.peripherals-keyboard", "", this); + connect(settings, &QGSettings::changed, + this, &LettersWidget::onCapsChanged); + } onCapsChanged(); } @@ -319,7 +331,12 @@ void LettersWidget::onBtnClicked(QChar charId) void LettersWidget::onCapsChanged() { - capsState = settings->get("capslock-state").toBool(); + if(isWayland){ + capsState = PlasmaShellManager::getInstance()->getKeyState(KWayland::Client::Keystate::Key::CapsLock); + }else{ + capsState = settings->get("capslock-state").toBool(); + } + isShift = capsState; for (int i = 97; i < 123; i++) { //大小写切换 QString objName = QString("btn_%1").arg(QString::number(i)); diff --git a/VirtualKeyboard/src/letterswidget.h b/VirtualKeyboard/src/letterswidget.h index 593c93a..31ee168 100644 --- a/VirtualKeyboard/src/letterswidget.h +++ b/VirtualKeyboard/src/letterswidget.h @@ -53,6 +53,7 @@ private: QGSettings *settings; bool capsState = false; + bool isWayland = false; }; #endif // LETTERSWIDGET_H diff --git a/VirtualKeyboard/src/qtkeyboard.cpp b/VirtualKeyboard/src/qtkeyboard.cpp new file mode 100644 index 0000000..a87495b --- /dev/null +++ b/VirtualKeyboard/src/qtkeyboard.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "qtkeyboard.h" +#include +#include +#include +#include +#include +#include +#include "plasma-shell-manager.h" + +QMap m_specialSymbolMap = { + {' ', Qt::Key_Space}, + {',', Qt::Key_Comma}, + {'.', Qt::Key_Period}, + {'\'', Qt::Key_QuoteLeft}, + {'@', Qt::Key_At}, + {'#', Qt::Key_NumberSign}, + {'$', Qt::Key_Dollar}, + {'%', Qt::Key_Percent}, + {'&', Qt::Key_Ampersand}, + {'*', Qt::Key_Asterisk}, + {'(', Qt::Key_ParenLeft}, + {')', Qt::Key_ParenRight}, + {'-', Qt::Key_Minus}, + {'+', Qt::Key_Plus}, + {'!', Qt::Key_Exclam}, + {'"', Qt::Key_QuoteDbl}, + {'<', Qt::Key_Less}, + {'>', Qt::Key_Greater}, + {':', Qt::Key_Colon}, + {';', Qt::Key_Semicolon}, + {'/', Qt::Key_Slash}, + {'?', Qt::Key_Question}, + {'=', Qt::Key_Equal}, + {'.', Qt::Key_Period}, /*XK_kana_middledot*/ + {'~', Qt::Key_AsciiTilde}, + {'`', Qt::Key_QuoteLeft}, + {'|', Qt::Key_Bar}, + {'^', Qt::Key_AsciiCircum}, + {'{', Qt::Key_BraceLeft}, + {'}', Qt::Key_BraceRight}, + {'[', Qt::Key_BracketLeft}, + {']', Qt::Key_BracketRight}, + {'_', Qt::Key_Underscore}, + {'\\', Qt::Key_Backslash}, +}; + +QMap m_funckeyMap = { + {FuncKey::SPACE, Qt::Key_Space}, + {FuncKey::BACKSPACE, Qt::Key_Backspace}, + {FuncKey::ENTER, Qt::Key_Enter}, + {FuncKey::HOME, Qt::Key_Home}, + {FuncKey::END, Qt::Key_End}, + {FuncKey::PGUP, Qt::Key_PageUp}, + {FuncKey::PGDN, Qt::Key_PageDown}, + {FuncKey::INSERT, Qt::Key_Insert}, + {FuncKey::DELETE, Qt::Key_Delete}, + {FuncKey::UP, Qt::Key_Up}, + {FuncKey::DOWN, Qt::Key_Down}, + {FuncKey::LEFT, Qt::Key_Left}, + {FuncKey::RIGHT, Qt::Key_Right} +}; + +QMap m_modifierMap = { + {Modifier::CTRL, Qt::ControlModifier}, + {Modifier::ALT, Qt::AltModifier}, + {Modifier::SUPER, Qt::MetaModifier}, + {Modifier::SHIFT, Qt::ShiftModifier} +}; + +QVector m_shiftKeyVec = {'~', '!', '@', '#', '$', '%', '^', '&', '*', + '(', ')', '_', '+', '{', '}', '|', ':', '"', + '>', '?'}; + +#define DRM_DIR "/sys/class/leds/" +#define CAPSLOCK_STATUS "capslock_state" + +/** + * @brief 判断大写键状态 + * @return true: 大写锁定 + */ +bool QtKeyboard::checkCapsLockState() +{ + QDir ledDir(DRM_DIR); + QStringList leds = ledDir.entryList(QDir::Dirs); + QString capsFile; + + for(int i = 0;i QtKeyboard::getAllModifier() +{ + return modList; +} + +void QtKeyboard::clearModifier() +{ + modList.clear(); +} + + +void QtKeyboard::onKeyPressed(QChar c) +{ + /*判断大写锁定打开时,转换字母大小写状态,与x11keyboard类逻辑保持一致*/ + if(checkCapsLockState() && c.isLetter()){ + if(c.isUpper()){ + c = c.toLower(); + } + else if(c.isLower()){ + c = c.toUpper(); + } + } + + if(c>='A' && c<='Z'){ + sendKey(c.toLatin1(),c); + }else if(c>='a' && c<='z'){ + sendKey(c.toLatin1() - 32,c); + }else if(c >= '0' && c<='9'){ + sendKey(c.toLatin1(),c); + }else if(m_specialSymbolMap.contains(c)){ + sendKey(m_specialSymbolMap[c],c); + }else { + sendKey(c.toLatin1(),c); + } +} + +void QtKeyboard::onKeyPressed(FuncKey::FUNCKEY key) +{ + int keysym = m_funckeyMap[key]; + /*这里的text根据实际按键得到的QEvent中的text内容打印*/ + if(key == FuncKey::SPACE){ + sendKey(keysym," "); + }else if(key == FuncKey::BACKSPACE){ + sendKey(keysym,"\b"); + }else if(key == FuncKey::ENTER){ + sendKey(keysym,"\r"); + }else if(key == FuncKey::INSERT){ + sendKey(keysym,"\u007F"); + }else if(key == FuncKey::CAPSLOCK){ + PlasmaShellManager::getInstance()->setKeyPressed(58); + }else{ + sendKey(keysym,""); + } +} + +void QtKeyboard::sendKey(const unsigned int keysym,const QString text) +{ + Qt::KeyboardModifiers modifier = Qt::NoModifier; + for(auto mod : modList){ + modifier = modifier | m_modifierMap[mod]; + } + + QWidget *objfous = QApplication::focusWidget(); + + if(objfous){ + QKeyEvent event1(QEvent::KeyPress, keysym + , modifier, text + , true, 1); + QKeyEvent event2(QEvent::KeyRelease, keysym + , modifier, text + , true, 1); + + QCoreApplication::sendEvent(objfous, &event1); + QCoreApplication::sendEvent(objfous, &event2); + } + +} diff --git a/VirtualKeyboard/src/qtkeyboard.h b/VirtualKeyboard/src/qtkeyboard.h new file mode 100644 index 0000000..a9c9690 --- /dev/null +++ b/VirtualKeyboard/src/qtkeyboard.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef QTKEYBOARD_H +#define QTKEYBOARD_H + +#include +#include +#include "fakekeyboard.h" + +class QtKeyboard : public FakeKeyboard +{ + Q_OBJECT +public: + explicit QtKeyboard(QObject *parent = nullptr); + ~QtKeyboard(); + void addModifier(Modifier::MOD mod); + void removeModifier(Modifier::MOD mod); + bool hasModifier(Modifier::MOD mod); + QList getAllModifier(); + void clearModifier(); + +public Q_SLOTS: + void onKeyPressed(QChar c); + void onKeyPressed(FuncKey::FUNCKEY key); + +private: + void sendKey(const unsigned int keyCode,const QString text); + bool checkCapsLockState(); + +private: + QList modList; +}; + +#endif // QTKEYBOARD_H diff --git a/VirtualKeyboard/src/virtualkeyboardwidget.cpp b/VirtualKeyboard/src/virtualkeyboardwidget.cpp index f7bb4cd..4318702 100644 --- a/VirtualKeyboard/src/virtualkeyboardwidget.cpp +++ b/VirtualKeyboard/src/virtualkeyboardwidget.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include "commondef.h" #include @@ -29,6 +30,8 @@ #include "numberswidget.h" #include "charswidget.h" #include "charsmorewidget.h" +#include "x11keyboard.h" +#include "qtkeyboard.h" VirtualKeyboardWidget::VirtualKeyboardWidget(QWidget *parent) : QWidget(parent) @@ -43,7 +46,12 @@ VirtualKeyboardWidget::VirtualKeyboardWidget(QWidget *parent) Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus); - vKeyboard = new X11Keyboard(this); + if(QX11Info::isPlatformX11()){ + vKeyboard = new X11Keyboard(this); + }else{ + vKeyboard = new QtKeyboard(this); + } + connect(this, SIGNAL(keyPressed(QChar)), vKeyboard, SLOT(onKeyPressed(QChar))); connect(this, SIGNAL(keyPressed(FuncKey::FUNCKEY)), @@ -222,7 +230,7 @@ void VirtualKeyboardWidget::onSpecialBtnClicked(QString keyName) m_lettersWidget->changeFuncKeyStyle(keyName, true); } if (keyName == BTN_CAPSLOCK) { - Q_EMIT keyPressed(FuncKey::UNKNOWN); + Q_EMIT keyPressed(FuncKey::CAPSLOCK); clearModifier(); } } else if(funcKey != FuncKey::UNKNOWN) { diff --git a/VirtualKeyboard/src/virtualkeyboardwidget.h b/VirtualKeyboard/src/virtualkeyboardwidget.h index 46ed923..3238662 100644 --- a/VirtualKeyboard/src/virtualkeyboardwidget.h +++ b/VirtualKeyboard/src/virtualkeyboardwidget.h @@ -22,7 +22,8 @@ #include #include #include -#include "x11keyboard.h" +#include "fakekeyboard.h" +#include "plasma-shell-manager.h" class DragWidget; class KBTitle; @@ -82,7 +83,7 @@ private: bool m_isdragState = false;//是否为悬浮状态 bool isMove;// 是否可移动 QPoint lastPoint;// 拖拽控件时 记录当前控件的位置 - X11Keyboard *vKeyboard; + FakeKeyboard *vKeyboard; }; #endif // VIRTUALKEYBOARDWIDGET_H diff --git a/VirtualKeyboard/src/x11keyboard.cpp b/VirtualKeyboard/src/x11keyboard.cpp index 32d1965..c7cd2c8 100644 --- a/VirtualKeyboard/src/x11keyboard.cpp +++ b/VirtualKeyboard/src/x11keyboard.cpp @@ -21,8 +21,6 @@ #include #include - - struct CharMap { QChar name; KeySym code; @@ -78,7 +76,8 @@ QMap funckeyMap = { {FuncKey::UP, XK_Up}, {FuncKey::DOWN, XK_Down}, {FuncKey::LEFT, XK_Left}, - {FuncKey::RIGHT, XK_Right} + {FuncKey::RIGHT, XK_Right}, + {FuncKey::CAPSLOCK, XK_Caps_Lock} }; QMap modifierMap = { @@ -86,7 +85,6 @@ QMap modifierMap = { {Modifier::ALT, XK_Alt_L}, {Modifier::SUPER, XK_Super_L}, {Modifier::SHIFT, XK_Shift_L}, - {Modifier::CAPSLOCK, XK_Caps_Lock} }; QVector shiftKeyVec = {'~', '!', '@', '#', '$', '%', '^', '&', '*', @@ -123,7 +121,7 @@ unsigned int keyCodeOfChar(QChar c) } X11Keyboard::X11Keyboard(QObject *parent) - : QObject(parent) + : FakeKeyboard(parent) { } @@ -168,6 +166,7 @@ void X11Keyboard::onKeyPressed(QChar c) void X11Keyboard::onKeyPressed(FuncKey::FUNCKEY key) { KeyCode keyCode; + KeySym keysym = funckeyMap[key]; if(keysym != NoSymbol) diff --git a/VirtualKeyboard/src/x11keyboard.h b/VirtualKeyboard/src/x11keyboard.h index c9a8562..9914019 100644 --- a/VirtualKeyboard/src/x11keyboard.h +++ b/VirtualKeyboard/src/x11keyboard.h @@ -20,77 +20,9 @@ #include #include +#include "fakekeyboard.h" -class Modifier : public QObject -{ - Q_OBJECT -public: - Modifier(){} - - enum MOD{ - UNKNOWN = -1, - CTRL, - SHIFT, - ALT, - SUPER, - CAPSLOCK - }; - Q_ENUM(MOD) - - static QString getModifierName(int mod) - { - QMetaEnum metaEnum = QMetaEnum::fromType(); - const char* modName = metaEnum.valueToKey(mod); - QString result = QString(modName).toLower(); - return result; - } - static MOD getModifier(const QString &modName) - { - QMetaEnum metaEnum = QMetaEnum::fromType(); - MOD mod = (MOD)metaEnum.keyToValue(modName.toUpper().toLocal8Bit().data()); - return mod; - } -}; - -class FuncKey : public QObject -{ - Q_OBJECT -public: - FuncKey(){} - - enum FUNCKEY { - UNKNOWN = -1, - SPACE = 0, - BACKSPACE, - ENTER, - HOME, - END, - PGUP, - PGDN, - INSERT, - DELETE, - UP, - DOWN, - LEFT, - RIGHT - }; - Q_ENUM(FUNCKEY) - static QString getKeyName(int key) - { - QMetaEnum metaEnum = QMetaEnum::fromType(); - const char* keyName = metaEnum.valueToKey(key); - QString result = QString(keyName).toLower(); - return result; - } - static FUNCKEY getKey(const QString &keyName) - { - QMetaEnum metaEnum = QMetaEnum::fromType(); - FUNCKEY key = (FUNCKEY)metaEnum.keyToValue(keyName.toUpper().toLocal8Bit().data()); - return key; - } -}; - -class X11Keyboard : public QObject +class X11Keyboard : public FakeKeyboard { Q_OBJECT public: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 86b160f..d22a516 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -112,7 +112,6 @@ qt5_wrap_cpp(dialog_SRC lockchecker.h servicemanager.h mytabwidget.h - plasma-shell-manager.h modebutton.h klabel.h PhysicalDeviceSet/brightnessdeviceset.h @@ -167,7 +166,6 @@ set(dialog_SRC lockchecker.cpp servicemanager.cpp mytabwidget.cpp - plasma-shell-manager.cpp modebutton.cpp klabel.cpp rootWindowBackground.cpp diff --git a/src/fullbackgroundwidget.cpp b/src/fullbackgroundwidget.cpp index e785660..adbcf01 100644 --- a/src/fullbackgroundwidget.cpp +++ b/src/fullbackgroundwidget.cpp @@ -569,7 +569,6 @@ bool FullBackgroundWidget::nativeEventFilter(const QByteArray &eventType, void * //onGlobalKeyPress(xc->detail); } else if (responseType == XCB_KEY_RELEASE) { xcb_key_release_event_t *xc = reinterpret_cast(event); - qDebug()<<"---------------------XCB_KEY_RELEASE:"<detail; onGlobalKeyRelease(xc->detail); } else if(responseType == XCB_GE_GENERIC){ xcb_ge_generic_event_t *xc = reinterpret_cast(event); diff --git a/src/lockwidget.cpp b/src/lockwidget.cpp index 25c420c..5461ace 100644 --- a/src/lockwidget.cpp +++ b/src/lockwidget.cpp @@ -820,27 +820,14 @@ void LockWidget::initUI() this->setCursor(Qt::ArrowCursor); }); - if(QX11Info::isPlatformX11()){ - //虚拟键盘 - ui->btnKeyboard->setIcon(QIcon(":/image/assets/keyboard.svg")); - ui->btnKeyboard->setFixedSize(48, 48); - ui->btnKeyboard->setIconSize(QSize(24, 24)); - ui->btnKeyboard->setFocusPolicy(Qt::NoFocus); - ui->btnKeyboard->installEventFilter(this); + ui->btnKeyboard->setIcon(QIcon(":/image/assets/keyboard.svg")); + ui->btnKeyboard->setFixedSize(48, 48); + ui->btnKeyboard->setIconSize(QSize(24, 24)); + ui->btnKeyboard->setFocusPolicy(Qt::NoFocus); + ui->btnKeyboard->installEventFilter(this); -/* connect(ui->btnKeyboard, &QPushButton::clicked, - this, [&]{ - qDebug() << vKeyboard->isHidden(); - vKeyboard->setVisible(vKeyboard->isHidden()); - }); -*/ - - - connect(ui->btnKeyboard, &QPushButton::clicked, - this, &LockWidget::showVirtualKeyboard); - } else { - ui->btnKeyboard->hide(); - } + connect(ui->btnKeyboard, &QPushButton::clicked, + this, &LockWidget::showVirtualKeyboard); //用户切换 if(displayManager->canSwitch()) @@ -892,9 +879,6 @@ void LockWidget::netInPutStatus() void LockWidget::showVirtualKeyboard() { - if (!QX11Info::isPlatformX11()) { - return ; - } tabAt = LINEEDIT; setBottomBtnSheet(); tabAt = BOTTMBTN;