From 879b452cc80dccb6581fea70a671a86994fb3a45 Mon Sep 17 00:00:00 2001 From: yuan_xing Date: Thu, 29 Feb 2024 17:28:42 +0800 Subject: [PATCH 1/1] fix(keybinding):don't convert normal key if use shift modifier in keybinding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 如果在快捷键中使用了shift修饰键,则不转换其普通按键,直接使用普通按键的Qt::Key Relates #30978 --- README.md | 4 +- plugins/keybinding/CMakeLists.txt | 7 ++- plugins/keybinding/utils/custom-line-edit.cpp | 25 +++++++---- plugins/keybinding/utils/keycode-helper.cpp | 42 ++++++++++++++++++ plugins/keybinding/utils/keycode-helper.h | 23 ++++++++++ .../keybinding/utils/keycode-translator.cpp | 44 +++++++++++-------- plugins/keybinding/utils/keycode-translator.h | 6 +-- 7 files changed, 119 insertions(+), 32 deletions(-) create mode 100644 plugins/keybinding/utils/keycode-helper.cpp create mode 100644 plugins/keybinding/utils/keycode-helper.h diff --git a/README.md b/README.md index 83d25b9..ad47094 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ 1. 安装编译依赖 ```bash - $ sudo yum install gcc-c++ qt5-qtbase qt5-qtbase-devel qt5-qtbase-gui qt5-qtx11extras qt5-qtx11extras-devel qt5-qtsvg glibc glibc-devel libX11 libX11-devel kiranwidgets-qt5 kiran-widgets-qt5-devel + $ sudo yum install gcc-c++ qt5-qtbase qt5-qtbase-devel qt5-qtbase-gui qt5-qtx11extras qt5-qtx11extras-devel qt5-qtsvg glibc glibc-devel libX11 libX11-devel kiranwidgets-qt5 kiran-widgets-qt5-devel qt5-qtbase-static qt5-qtbase-private-devel ``` 2. **源码根目录下创建**build**目录`mkdir build` @@ -302,4 +302,4 @@ $ kiran-control-panel ```bash $ kiran-cpanel-launcher --cpanel-plugin 插件安装的desktop文件名 -``` \ No newline at end of file +``` diff --git a/plugins/keybinding/CMakeLists.txt b/plugins/keybinding/CMakeLists.txt index bc94de2..d9dc8d1 100644 --- a/plugins/keybinding/CMakeLists.txt +++ b/plugins/keybinding/CMakeLists.txt @@ -1,5 +1,7 @@ set(TARGET_NAME kiran-cpanel-keybinding) +find_package(Qt5 COMPONENTS XkbCommonSupport) + kiran_qt5_add_dbus_interface_ex(KEYBINDING_PROXY data/com.kylinsec.Kiran.SessionDaemon.Keybinding.xml keybinding_backEnd_proxy @@ -16,6 +18,7 @@ target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/utils + ${Qt5XkbCommonSupport_PRIVATE_INCLUDE_DIRS} ${KLOG_INCLUDE_DIRS} ${KIRAN_WIDGETS_INCLUDE_DIRS} ${KIRAN_CC_DAEMON_INCLUDE_DIRS}) @@ -27,8 +30,10 @@ target_link_libraries(${TARGET_NAME} Qt5::Svg Qt5::Core Qt5::Concurrent + X11 + Qt5::XkbCommonSupport ${KIRANWIDGETS_LIBRARIES} ${KLOG_LIBRARIES}) install(TARGETS ${TARGET_NAME} - DESTINATION ${PLUGIN_LIBS_DIR}/) \ No newline at end of file + DESTINATION ${PLUGIN_LIBS_DIR}/) diff --git a/plugins/keybinding/utils/custom-line-edit.cpp b/plugins/keybinding/utils/custom-line-edit.cpp index 36250da..6defb3b 100644 --- a/plugins/keybinding/utils/custom-line-edit.cpp +++ b/plugins/keybinding/utils/custom-line-edit.cpp @@ -17,6 +17,8 @@ #include #include #include +#include "keycode-translator.h" +#include "logging-category.h" CustomLineEdit::CustomLineEdit(QWidget *parent) : QLineEdit(parent) { @@ -33,18 +35,27 @@ void CustomLineEdit::initUI() setFocusPolicy(Qt::ClickFocus); setReadOnly(true); setObjectName("CustomLineEdit"); -// setStyleSheet("#CustomLineEdit{border:1px solid #393939;border-radius:6px;padding-left:10px;padding-right:10px;}" -// "#CustomLineEdit:focus{border:1px solid #2eb3ff;}"); + // setStyleSheet("#CustomLineEdit{border:1px solid #393939;border-radius:6px;padding-left:10px;padding-right:10px;}" + // "#CustomLineEdit:focus{border:1px solid #2eb3ff;}"); } void CustomLineEdit::keyReleaseEvent(QKeyEvent *event) { QList keycodes; + int qtkey = 0; if (event->key() == Qt::Key_Backspace && event->modifiers() == Qt::NoModifier) { return; } + + //处理shift修饰的快捷键组合,按键不经过shift转化,将原始按键keycode转化为对应的Qt::Key + if (event->key() != 0 && (event->modifiers() & Qt::ShiftModifier)) + { + qtkey = KeycodeTranslator::keycode2QtKey(event->nativeScanCode()); + KLOG_INFO(qLcKeybinding) << "convert KeyCode:" << event->nativeScanCode() << "to Qt::Key:" << qtkey; + } + // no modifier if (event->key() != 0 && event->modifiers() == Qt::NoModifier) { @@ -56,14 +67,12 @@ void CustomLineEdit::keyReleaseEvent(QKeyEvent *event) else if (event->key() != 0 && event->modifiers() == Qt::ShiftModifier) { keycodes.append(Qt::Key_Shift); - keycodes.append(event->key()); - //KLOG_INFO() << "shift :" << event->key() << event->modifiers(); + keycodes.append(qtkey ? qtkey : event->key()); } else if (event->key() != 0 && event->modifiers() == Qt::ControlModifier) { keycodes.append(Qt::Key_Control); keycodes.append(event->key()); - //KLOG_INFO() << "ctrl :" << event->key() << event->text(); } else if (event->key() != 0 && event->modifiers() == Qt::AltModifier) { @@ -76,7 +85,7 @@ void CustomLineEdit::keyReleaseEvent(QKeyEvent *event) { keycodes.append(Qt::Key_Control); keycodes.append(Qt::Key_Shift); - keycodes.append(event->key()); + keycodes.append(qtkey ? qtkey : event->key()); } else if (event->key() != 0 && event->modifiers() == (Qt::ControlModifier | Qt::AltModifier)) { @@ -88,7 +97,7 @@ void CustomLineEdit::keyReleaseEvent(QKeyEvent *event) { keycodes.append(Qt::Key_Shift); keycodes.append(Qt::Key_Alt); - keycodes.append(event->key()); + keycodes.append(qtkey ? qtkey : event->key()); } //three modifier else if (event->key() != 0 && event->modifiers() == (Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier)) @@ -96,7 +105,7 @@ void CustomLineEdit::keyReleaseEvent(QKeyEvent *event) keycodes.append(Qt::Key_Shift); keycodes.append(Qt::Key_Control); keycodes.append(Qt::Key_Alt); - keycodes.append(event->key()); + keycodes.append(qtkey ? qtkey : event->key()); } if (keycodes.size() > 0) { diff --git a/plugins/keybinding/utils/keycode-helper.cpp b/plugins/keybinding/utils/keycode-helper.cpp new file mode 100644 index 0000000..67cb698 --- /dev/null +++ b/plugins/keybinding/utils/keycode-helper.cpp @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: yuanxing + */ + +#include "keycode-helper.h" + +#include + +namespace KeycodeHelper +{ +unsigned long keycode2Keysym(unsigned long keycode) +{ + KeySym keysym = NoSymbol; + Display *display = QX11Info::display(); + if (display == nullptr) + { + KLOG_WARNING(qLcKeybinding) << "can't open display!"; + return keysym; + } + + keysym = XKeycodeToKeysym(display, keycode, 0); + if (keysym != NoSymbol) + { + KLOG_INFO(qLcKeybinding) << "convert KeyCode:" << keycode << "to KeySym:" << keysym; + } + else + { + KLOG_INFO(qLcKeybinding) << "no corresponding" << keycode << "KeySym found."; + } + return keysym; +} +} // namespace KeycodeHelper diff --git a/plugins/keybinding/utils/keycode-helper.h b/plugins/keybinding/utils/keycode-helper.h new file mode 100644 index 0000000..849abe0 --- /dev/null +++ b/plugins/keybinding/utils/keycode-helper.h @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: yuanxing + */ + +#pragma once + +#include +#include "logging-category.h" + +namespace KeycodeHelper +{ +unsigned long keycode2Keysym(unsigned long keycode); +} // namespace KeycodeHelper diff --git a/plugins/keybinding/utils/keycode-translator.cpp b/plugins/keybinding/utils/keycode-translator.cpp index a8dea85..5b7f40c 100644 --- a/plugins/keybinding/utils/keycode-translator.cpp +++ b/plugins/keybinding/utils/keycode-translator.cpp @@ -15,9 +15,11 @@ #include "keycode-translator.h" #include "logging-category.h" +#include #include -#include #include +#include +#include "keycode-helper.h" static QMetaEnum keyMetaEnum = QMetaEnum::fromType(); @@ -89,23 +91,22 @@ static const QMap MediaKeyMap = { KeycodeTranslator::KeycodeTranslator(QObject *parent) : QObject(parent) { - } QString KeycodeTranslator::keycode2ReadableString(const QList &keycodes) { QStringList keyStrings; - for( int key : keycodes ) + for (int key : keycodes) { - if( (key >= Qt::Key_0) && (key <= Qt::Key_9) ) + if ((key >= Qt::Key_0) && (key <= Qt::Key_9)) { - keyStrings.append(QString::number(key-Qt::Key_0)); + keyStrings.append(QString::number(key - Qt::Key_0)); continue; } - const char* keyValue = keyMetaEnum.valueToKey(key); - if( keyValue == nullptr ) + const char *keyValue = keyMetaEnum.valueToKey(key); + if (keyValue == nullptr) { KLOG_WARNING(qLcKeybinding) << "can't convert key:" << key; continue; @@ -113,12 +114,12 @@ QString KeycodeTranslator::keycode2ReadableString(const QList &keycodes) QString keyStr(keyValue); //特殊按键经QMetaEnum翻译之后再经过SpecialKeyMap翻译 - if( SpecialKeyMap.contains(keyStr.toLower()) ) + if (SpecialKeyMap.contains(keyStr.toLower())) { keyStrings.append(SpecialKeyMap.value(keyStr.toLower())); } //特殊按键 "_" 转换成 " " - else if( (key >= Audio_Lower_Volume) && (key <= Audio_Mic_Mute) ) + else if ((key >= Audio_Lower_Volume) && (key <= Audio_Mic_Mute)) { keyStrings.append(keyStr.split("_").join(" ")); } @@ -131,33 +132,40 @@ QString KeycodeTranslator::keycode2ReadableString(const QList &keycodes) return keyStrings.join('+'); } +int KeycodeTranslator::keycode2QtKey(unsigned long keycode) +{ + auto keysym = KeycodeHelper::keycode2Keysym(keycode); + auto qtkey = QXkbCommon::keysymToQtKey(keysym, Qt::KeyboardModifier::NoModifier); + return qtkey; +} + QString KeycodeTranslator::backendKeyString2Readable(const QString &keyString) { QString readableString; - if( keyString.isEmpty() ) + if (keyString.isEmpty()) { readableString = tr("None"); } - else if( keyString.contains("disable",Qt::CaseInsensitive) ) + else if (keyString.contains("disable", Qt::CaseInsensitive)) { readableString = tr("disabled"); } else { QString temp = keyString; - temp = temp.replace("<",""); - temp = temp.replace(">","-"); + temp = temp.replace("<", ""); + temp = temp.replace(">", "-"); #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) QStringList keyList = temp.split("-", QString::SkipEmptyParts); #else - QStringList keyList = temp.split("-",Qt::SkipEmptyParts); + QStringList keyList = temp.split("-", Qt::SkipEmptyParts); #endif - for(int i=0;i -class KeycodeTranslator : public QObject +class KeycodeTranslator : public QObject { Q_OBJECT public: @@ -174,9 +174,9 @@ private: public: static QString keycode2ReadableString(const QList& keycodes); + static int keycode2QtKey(unsigned long keycode); static QString backendKeyString2Readable(const QString& keyString); static QString readableKeyString2Backend(const QString& keyString); }; - -#endif //KIRAN_CONTROL_PANEL_KEYCODE_TRANSLATOR_H +#endif //KIRAN_CONTROL_PANEL_KEYCODE_TRANSLATOR_H -- 2.27.0