388 lines
14 KiB
Diff
388 lines
14 KiB
Diff
From 879b452cc80dccb6581fea70a671a86994fb3a45 Mon Sep 17 00:00:00 2001
|
||
From: yuan_xing <yuanxing@kylinsec.com.cn>
|
||
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 <QInputMethodEvent>
|
||
#include <QPainter>
|
||
#include <QStyleOption>
|
||
+#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<int> 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 <yuanxing@kylinsec.com.cn>
|
||
+ */
|
||
+
|
||
+#include "keycode-helper.h"
|
||
+
|
||
+#include <X11/Xlib.h>
|
||
+
|
||
+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 <yuanxing@kylinsec.com.cn>
|
||
+ */
|
||
+
|
||
+#pragma once
|
||
+
|
||
+#include <QX11Info>
|
||
+#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 <QtXkbCommonSupport/private/qxkbcommon_p.h>
|
||
#include <qt5-log-i.h>
|
||
-#include <QMetaEnum>
|
||
#include <QApplication>
|
||
+#include <QMetaEnum>
|
||
+#include "keycode-helper.h"
|
||
|
||
static QMetaEnum keyMetaEnum = QMetaEnum::fromType<KeycodeTranslator::Key>();
|
||
|
||
@@ -89,23 +91,22 @@ static const QMap<QString, QString> MediaKeyMap = {
|
||
KeycodeTranslator::KeycodeTranslator(QObject *parent)
|
||
: QObject(parent)
|
||
{
|
||
-
|
||
}
|
||
|
||
QString KeycodeTranslator::keycode2ReadableString(const QList<int> &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<int> &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<int> &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<keyList.size();i++)
|
||
+ for (int i = 0; i < keyList.size(); i++)
|
||
{
|
||
- if( SpecialKeyMap.contains(keyList.at(i).toLower()) )
|
||
+ if (SpecialKeyMap.contains(keyList.at(i).toLower()))
|
||
{
|
||
- keyList.replace(i,SpecialKeyMap.value(keyList.at(i).toLower()));
|
||
+ keyList.replace(i, SpecialKeyMap.value(keyList.at(i).toLower()));
|
||
}
|
||
else if (MediaKeyMap.contains(keyList.at(i)))
|
||
{
|
||
@@ -174,7 +182,7 @@ QString KeycodeTranslator::backendKeyString2Readable(const QString &keyString)
|
||
QString KeycodeTranslator::readableKeyString2Backend(const QString &keyString)
|
||
{
|
||
QStringList keystrings = keyString.split('+');
|
||
- for( int i=0;i<keystrings.count();i++ )
|
||
+ for (int i = 0; i < keystrings.count(); i++)
|
||
{
|
||
QString key = keystrings.at(i);
|
||
|
||
diff --git a/plugins/keybinding/utils/keycode-translator.h b/plugins/keybinding/utils/keycode-translator.h
|
||
index 2697b43..40e91f1 100644
|
||
--- a/plugins/keybinding/utils/keycode-translator.h
|
||
+++ b/plugins/keybinding/utils/keycode-translator.h
|
||
@@ -17,7 +17,7 @@
|
||
|
||
#include <QObject>
|
||
|
||
-class KeycodeTranslator : public QObject
|
||
+class KeycodeTranslator : public QObject
|
||
{
|
||
Q_OBJECT
|
||
public:
|
||
@@ -174,9 +174,9 @@ private:
|
||
|
||
public:
|
||
static QString keycode2ReadableString(const QList<int>& 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
|
||
|