This commit is contained in:
寂静的羽夏 2022-09-30 14:05:05 +08:00
parent dc16cb71b8
commit 2326e21476
15 changed files with 532 additions and 116 deletions

View File

@ -1,11 +1,11 @@
#include "appmanager.h"
#include <QApplication>
#include <QClipboard>
#include <QKeySequence>
AppManager *AppManager::m_instance = nullptr;
AppManager::AppManager(QObject *parent) : QObject(parent) {
// 初始化选词监控
auto clipboard = qApp->clipboard();
connect(clipboard, &QClipboard::selectionChanged, this, [=] {
@ -24,8 +24,8 @@ AppManager::AppManager(QObject *parent) : QObject(parent) {
CONNECT(mouseMove);
connect(&monitor, &EventMonitor::buttonPress,
[=](EventMonitor::MouseButton btn, int x, int y) {
if (btn == EventMonitor::MouseButton::MiddleButton) {
[=](Qt::MouseButton btn, int x, int y) {
if (this->checkToolShow(btn)) {
toolwin.popup(QCursor::pos());
}
emit this->buttonPress(btn, x, y);
@ -37,7 +37,7 @@ AppManager::AppManager(QObject *parent) : QObject(parent) {
emit this->mouseDrag(x, y);
});
connect(&monitor, &EventMonitor::buttonRelease,
[=](EventMonitor::MouseButton btn, int x, int y) {
[=](Qt::MouseButton btn, int x, int y) {
toolwin.hide();
ignoremsg = true;
emit this->buttonRelease(btn, x, y);
@ -45,8 +45,6 @@ AppManager::AppManager(QObject *parent) : QObject(parent) {
monitor.start();
// 初始化热键存储
// 存单实例
m_instance = this;
}
@ -107,3 +105,7 @@ void AppManager::clearHotkey() {
registeredSeq.clear();
hotkeys.clear();
}
Qt::KeyboardModifier AppManager::getKeyModifier() const {
return monitor.getKeyModifier();
}

View File

@ -4,8 +4,7 @@
#include "class/eventmonitor.h"
#include "class/hotkey.h"
#include "dialog/toolwindow.h"
#undef Bool
#undef Unsorted
#include "utilities.h"
#include <QList>
#include <QObject>
#include <QString>
@ -25,9 +24,11 @@ public:
bool editHotkey(Hotkey *hotkey, QKeySequence &keyseq);
void clearHotkey();
Qt::KeyboardModifier getKeyModifier() const;
signals:
void buttonPress(EventMonitor::MouseButton btn, int x, int y);
void buttonRelease(EventMonitor::MouseButton btn, int x, int y);
void buttonPress(Qt::MouseButton btn, int x, int y);
void buttonRelease(Qt::MouseButton btn, int x, int y);
void clicked(int x, int y);
void doubleClicked(int x, int y);
void mouseWheel(EventMonitor::MouseWheel direction);
@ -39,11 +40,11 @@ signals:
void hotkeyEnableChanged(bool value, const Hotkey *hotkey);
void selectionTextChanged(const QString &selectedText);
bool checkToolShow(Qt::MouseButton btn);
private:
EventMonitor monitor;
QList<Hotkey *> hotkeys;
QStringList execs;
bool ignoremsg = false;

View File

@ -1,6 +1,5 @@
#include "eventmonitor.h"
#include <QApplication>
#include <X11/Xlibint.h>
EventMonitor::EventMonitor(QObject *parent) : QThread(parent) {
isPress = false;
@ -34,7 +33,7 @@ void EventMonitor::run() {
// Receive ButtonPress, ButtonRelease and MotionNotify
// events.
memset(range, 0, sizeof(XRecordRange));
range->device_events.first = ButtonPress;
range->device_events.first = KeyPress;
range->device_events.last = MotionNotify;
// And create the XRECORD context.
@ -66,6 +65,10 @@ void EventMonitor::run() {
isClicked = false;
}
Qt::KeyboardModifier EventMonitor::getKeyModifier() const {
return keyModifier;
}
void EventMonitor::callback(XPointer ptr, XRecordInterceptData *data) {
(reinterpret_cast<EventMonitor *>(ptr))->handleRecordEvent(data);
}
@ -78,10 +81,10 @@ void EventMonitor::handleRecordEvent(XRecordInterceptData *data) {
case ButtonPress:
if (handleWheelEvent(event->u.u.detail)) {
isPress = true;
MouseButton btn = MouseButton::NoneButton;
Qt::MouseButton btn = Qt::MouseButton::NoButton;
switch (event->u.u.detail) {
case Button1: {
btn = MouseButton::LeftButton;
btn = Qt::MouseButton::LeftButton;
auto clicknow = std::chrono::system_clock::now();
double diff_ms =
@ -100,16 +103,16 @@ void EventMonitor::handleRecordEvent(XRecordInterceptData *data) {
} break;
case Button2:
btn = MouseButton::MiddleButton;
btn = Qt::MouseButton::MiddleButton;
break;
case Button3:
btn = MouseButton::RightButton;
btn = Qt::MouseButton::RightButton;
break;
case XButton1:
btn = MouseButton::XButton_1;
case XButton_1:
btn = Qt::MouseButton::XButton1;
break;
case XButton2:
btn = MouseButton::XButton_2;
case XButton_2:
btn = Qt::MouseButton::XButton2;
break;
}
@ -130,28 +133,53 @@ void EventMonitor::handleRecordEvent(XRecordInterceptData *data) {
if (handleWheelEvent(event->u.u.detail)) {
isPress = false;
MouseButton btn = MouseButton::NoneButton;
Qt::MouseButton btn = Qt::MouseButton::NoButton;
switch (event->u.u.detail) {
case Button1:
btn = MouseButton::LeftButton;
btn = Qt::MouseButton::LeftButton;
break;
case Button2:
btn = MouseButton::MiddleButton;
btn = Qt::MouseButton::MiddleButton;
break;
case Button3:
btn = MouseButton::RightButton;
btn = Qt::MouseButton::RightButton;
break;
case XButton1:
btn = MouseButton::XButton_1;
case XButton_1:
btn = Qt::MouseButton::XButton1;
break;
case XButton2:
btn = MouseButton::XButton_2;
case XButton_2:
btn = Qt::MouseButton::XButton2;
break;
}
emit buttonRelease(btn, event->u.keyButtonPointer.rootX,
event->u.keyButtonPointer.rootY);
}
break;
case KeyPress: {
auto code = data->data[1];
switch (code) {
case 50:
case 62:
keyModifier = Qt::ShiftModifier;
break;
case 37:
case 105:
keyModifier = Qt::ControlModifier;
break;
case 64:
case 108:
keyModifier = Qt::AltModifier;
break;
case 133:
keyModifier = Qt::MetaModifier;
break;
default:
break;
}
} break;
case KeyRelease:
keyModifier = Qt::NoModifier;
break;
default:
break;
}

View File

@ -12,9 +12,17 @@
#include <QEvent>
#include <QTextStream>
#include <QThread>
/*== X11 头文件有和 QT 头文件冲突的地方 ==*/
// 所以 undef 使其编译通过
#include <X11/Xlib.h>
#undef None
#include <X11/Xlibint.h>
#include <X11/extensions/record.h>
#undef Unsorted
#undef None
#undef Bool
#undef Data
/*==================================*/
// Virtual button codes that are not defined by X11.
#define Button1 1
@ -24,23 +32,13 @@
#define WheelDown 5
#define WheelLeft 6
#define WheelRight 7
#define XButton1 8
#define XButton2 9
#define XButton_1 8
#define XButton_2 9
class EventMonitor : public QThread {
Q_OBJECT
public:
enum class MouseButton {
NoneButton,
LeftButton,
RightButton,
MiddleButton,
XButton_1,
XButton_2
};
Q_ENUM(MouseButton)
enum class MouseWheel { None, Up, Down, Left, Right };
Q_ENUM(MouseWheel)
@ -48,9 +46,11 @@ public:
EventMonitor(QObject *parent = nullptr);
~EventMonitor() override;
Qt::KeyboardModifier getKeyModifier() const;
signals:
void buttonPress(MouseButton btn, int x, int y); // 当鼠标按键被按下时
void buttonRelease(MouseButton btn, int x, int y); // 当鼠标按键被释放时
void buttonPress(Qt::MouseButton btn, int x, int y); // 当鼠标按键被按下时
void buttonRelease(Qt::MouseButton btn, int x, int y); // 当鼠标按键被释放时
void clicked(int x, int y); // 当鼠标进行单击操作时
void doubleClicked(int x, int y); // 当鼠标进行双击操作时
void mouseWheel(MouseWheel direction); // 当鼠标滚轮滚动时
@ -69,6 +69,8 @@ private:
Display *display_datalink;
std::chrono::system_clock::time_point clickbefore;
Qt::KeyboardModifier keyModifier;
};
#endif

View File

@ -1,11 +1,17 @@
#include "settingmanager.h"
#include "plugin/pluginsystem.h"
#include <QApplication>
#include <QFile>
#include <QStandardPaths>
SettingManager *SettingManager::m_instance = nullptr;
SettingManager::SettingManager(QObject *parent) : QObject(parent) {
SettingManager::SettingManager(QObject *parent)
: QObject(parent), m_toolGridSize(TOOLGRIDSIZE),
m_toolBox(
QKeySequence(Qt::KeyboardModifier::ShiftModifier | Qt::Key_Space)),
m_toolwinMod(Qt::KeyboardModifier::ControlModifier),
m_toolMouse(Qt::MouseButton::MidButton) {
m_instance = this;
}
@ -19,8 +25,132 @@ bool SettingManager::loadSettings() {
.arg(qApp->applicationName());
QFile f(strConfigPath);
QDataStream stream(&f);
if (f.open(QFile::ReadOnly)) {
emit this->loadingFinish();
// 开始读配置文件咯
static char header[] = "WINGTOOL";
char buffer[8];
stream.readRawData(buffer, 8);
if (memcmp(header, buffer, 8)) {
// 如果文件头不对劲,就视为非法配置
return false;
}
auto plgsys = PluginSystem::instance();
// General
stream >> m_toolGridSize >> m_toolBox >> m_toolwinMod >> m_toolMouse;
// 读取结束,提示可以加载基础配置内容了
emit this->loadedGeneral();
// 读取 Hotkey 的相关信息
int len;
stream >> len; // 先读取一下有几个
for (auto i = 0; i < len; i++) {
ToolStructInfo buf;
stream >> buf.enabled >> buf.isPlugin >> buf.seq;
if (buf.isPlugin) {
stream >> buf.serviceID;
QByteArray arr;
stream >> arr;
buf.provider = QString::fromUtf8(arr);
stream >> arr;
buf.params = QString::fromUtf8(arr);
stream >> arr;
auto pi = plgsys->pluginIndexByProvider(buf.provider);
// 找不到了,插件丢失或者不兼容
if (pi < 0)
continue;
// 检查兼容性,不兼容出门左拐
if (!Utilities::isPluginCompatible(plgsys->plugin(pi), arr)) {
continue;
}
// 经历过重重检验,合格入库
emit addHotKeyInfo(buf);
} else {
// 如果是打开文件就没这么多事情了
QByteArray arr;
stream >> arr;
buf.process = QString::fromUtf8(arr);
stream >> arr;
buf.params = QString::fromUtf8(arr);
emit addHotKeyInfo(buf);
}
}
// 下面继续读取 ToolWin 相关信息只有8条
for (auto i = 0; i < 8; i++) {
ToolStructInfo buf{true};
// 对于 ToolWin 来说,这个成员是决定性的
// 只有这个标志位有效,这个工具才有意义
stream >> buf.isPlugin;
if (buf.isPlugin) {
stream >> buf.serviceID;
QByteArray arr;
stream >> arr;
buf.provider = QString::fromUtf8(arr);
stream >> arr;
buf.params = QString::fromUtf8(arr);
auto pi = plgsys->pluginIndexByProvider(buf.provider);
// 找不到了,插件丢失或者不兼容
if (pi < 0)
continue;
// 检查兼容性,不兼容出门左拐
if (!Utilities::isPluginCompatible(plgsys->plugin(pi), arr)) {
continue;
}
// 经历过重重检验,合格入库
emit setToolWinInfo(i, buf);
} else { // 如果是打开文件就没这么多事情了
QByteArray arr;
stream >> arr;
buf.process = QString::fromUtf8(arr);
stream >> arr;
buf.params = QString::fromUtf8(arr);
emit setToolWinInfo(i, buf);
}
}
// 下面读取 WinTool 相关信息
stream >> len; // 先读一下有几个
for (auto i = 0; i < len; i++) {
ToolStructInfo buf;
// 对于 WinTool 来说, enabled 就没用了
// 只存储相关基础信息就可以了
stream >> buf.isPlugin;
if (buf.isPlugin) {
stream >> buf.serviceID;
QByteArray arr;
stream >> arr;
buf.provider = QString::fromUtf8(arr);
stream >> arr;
buf.params = QString::fromUtf8(arr);
auto pi = plgsys->pluginIndexByProvider(buf.provider);
// 找不到了,插件丢失或者不兼容
if (pi < 0)
continue;
// 检查兼容性,不兼容出门左拐
if (!Utilities::isPluginCompatible(plgsys->plugin(pi), arr)) {
continue;
}
// 经历过重重检验,合格入库
emit addWinToolInfo(buf);
} else {
QByteArray arr;
stream >> arr;
buf.process = QString::fromUtf8(arr);
stream >> arr;
buf.params = QString::fromUtf8(arr);
emit addWinToolInfo(buf);
}
}
}
return true;
}
@ -38,24 +168,44 @@ bool SettingManager::exportSettings(QString filename) {
QFile f(filename);
QDataStream stream(&f);
if (f.open(QFile::WriteOnly)) {
// 写文件头
static char header[] = "WINGTOOL";
stream.writeRawData(header, 8);
// General
stream << m_toolGridSize << m_toolBox << m_toolwinMod << m_toolMouse;
// 有些配置直接保存到 CenterWindow 里面了,为了减少内存占用
emit sigSaveConfig(stream);
// 至此,保存完毕
f.close();
return true;
}
return false;
}
int SettingManager::toolGridSize() { return m_toolGridSize; }
int SettingManager::toolGridSize() const { return m_toolGridSize; }
void SettingManager::setToolGridSize(int v) {
void SettingManager::setToolGridSize(const int v) {
if (v > 0) {
m_toolGridSize = v;
emit sigToolGridSizeChanged(v);
}
}
void SettingManager::getHokeysBuffer(QList<Hotkey *> &hotkeysBuf,
QMap<Hotkey *, ToolStructInfo> &buffer) {}
QKeySequence SettingManager::toolBoxHotkey() const { return m_toolBox; }
void SettingManager::getToolLeftBuffer(ToolStructInfo buffer[]) {}
void SettingManager::setToolBoxHotkey(const QKeySequence seq) {
m_toolBox = seq;
emit sigToolBoxHotkeyChanged(seq);
}
void SettingManager::getToolRightBuffer(QList<ToolStructInfo> &buffer) {}
Qt::KeyboardModifier SettingManager::toolwinMod() const { return m_toolwinMod; }
void SettingManager::setToolwinMod(const Qt::KeyboardModifier &toolwinMod) {
m_toolwinMod = toolwinMod;
}
Qt::MouseButton SettingManager::toolwinMouseBtn() const { return m_toolMouse; }
void SettingManager::setToolMouseBtn(const Qt::MouseButton &toolMouse) {
m_toolMouse = toolMouse;
}

View File

@ -3,6 +3,7 @@
#include "class/hotkey.h"
#include "utilities.h"
#include <QKeySequence>
#include <QObject>
#define TOOLGRIDSIZE 40
@ -21,23 +22,41 @@ public:
void resetSettings();
public:
int toolGridSize();
void setToolGridSize(int v);
int toolGridSize() const;
void setToolGridSize(const int v);
QKeySequence toolBoxHotkey() const;
void setToolBoxHotkey(const QKeySequence seq);
Qt::KeyboardModifier toolwinMod() const;
void setToolwinMod(const Qt::KeyboardModifier &toolwinMod);
Qt::MouseButton toolwinMouseBtn() const;
void setToolMouseBtn(const Qt::MouseButton &toolwinMouseBtn);
signals:
void sigToolGridSizeChanged(int v);
void loadingFinish();
void loadedGeneral();
void sigToolBoxHotkeyChanged(const QKeySequence seq);
void sigToolWinShortCutChanged(const Qt::KeyboardModifier mod,
const Qt::MouseButton btn);
public slots:
void getHokeysBuffer(QList<Hotkey *> &hotkeysBuf,
QMap<Hotkey *, ToolStructInfo> &buffer);
void getToolLeftBuffer(ToolStructInfo buffer[]);
void getToolRightBuffer(QList<ToolStructInfo> &buffer);
void sigSaveConfig(QDataStream &stream);
// 配置添加信号
void addHotKeyInfo(ToolStructInfo &info);
void setToolWinInfo(int index, ToolStructInfo &info);
void addWinToolInfo(ToolStructInfo &info);
private:
static SettingManager *m_instance;
int m_toolGridSize = TOOLGRIDSIZE;
int m_toolGridSize;
QKeySequence m_toolBox;
Qt::KeyboardModifier m_toolwinMod;
Qt::MouseButton m_toolMouse;
};
#endif // SETTINGMANAGER_H

View File

@ -53,13 +53,26 @@ CenterWindow::CenterWindow(DMainWindow *parent) : DMainWindow(parent) {
});
vlayout->addWidget(cbauto, Qt::AlignTop);
auto gw = new QWidget(w);
vlayout->addWidget(gw);
auto hlayout = new QHBoxLayout(gw);
hlayout->addWidget(new DLabel(tr("ToolWinGridSize"), this));
hlayout->addSpacing(5);
sbGridsize = new DSpinBox(w);
sbGridsize->setRange(30, 60);
sbGridsize->setValue(40); // 默认 40 先
connect(sbGridsize, QOverload<int>::of(&DSpinBox::valueChanged), this,
[=](int v) {
});
hlayout->addWidget(sbGridsize);
vlayout->addSpacing(10);
l = new DLabel(tr("Shortcut"), this);
l->setFont(font);
vlayout->addWidget(l);
vlayout->addSpacing(5);
auto gw = new QWidget(w);
gw = new QWidget(w);
vlayout->addWidget(gw);
auto flayout = new QFormLayout(gw);
kseqTool = new DKeySequenceEdit(gw);
@ -68,7 +81,7 @@ CenterWindow::CenterWindow(DMainWindow *parent) : DMainWindow(parent) {
});
flayout->addRow(tr("ToolBox:"), kseqTool);
auto hlayout = new QHBoxLayout(gw);
hlayout = new QHBoxLayout(gw);
cbMod = new DComboBox(gw);
cbMod->addItems({"Ctrl", "Shift", "Alt", "Super"});
cbMod->setCurrentIndex(0);
@ -113,7 +126,8 @@ CenterWindow::CenterWindow(DMainWindow *parent) : DMainWindow(parent) {
vlayout->addWidget(new DLabel(QString(tr("%1 , Ver %2 , by WingSummer."))
.arg(qApp->applicationName())
.arg(qApp->applicationVersion())));
.arg(qApp->applicationVersion()),
this));
vlayout->addStretch();
tabs->addTab(w, tr("General"));
@ -650,17 +664,93 @@ void CenterWindow::on_upToolWin() {}
void CenterWindow::on_downToolWin() {}
void CenterWindow::initSettings() {
void CenterWindow::addHotKeyInfo(ToolStructInfo &info) {
// 添加 UI 项目
auto index = tbhotkeys->rowCount();
tbhotkeys->setRowCount(index + 1);
auto wt = new QTableWidgetItem;
wt->setCheckState(info.enabled ? Qt::Checked : Qt::Unchecked);
tbhotkeys->setItem(index, 0, wt);
tbhotkeys->setItem(index, 1, new QTableWidgetItem(info.seq.toString()));
wt = new QTableWidgetItem(info.process);
wt->setToolTip(info.process);
tbhotkeys->setItem(index, 2, wt);
wt = new QTableWidgetItem(info.params);
wt->setToolTip(info.params);
tbhotkeys->setItem(index, 3, wt);
// 注册热键
auto hk = manager->registerHotkey(info.seq, true);
hotkeys << hk;
scinfos.insert(hk, info);
// 修正热键状态
manager->enableHotKey(hk, info.enabled);
}
void CenterWindow::setoolWinInfo(int index, ToolStructInfo &info) {
if (index >= 4)
index++;
toolinfos[index] = info;
// 更新 UI
// TODO
}
void CenterWindow::addWinToolInfo(ToolStructInfo &info) {
wintoolinfos << info;
auto item = new QListWidgetItem(
Utilities::trimIconFromInfo(plgsys->plugin(info.pluginIndex), info),
info.isPlugin ? info.process : QFileInfo(info.process).fileName());
item->setToolTip(info.process);
lstoolwin->addItem(item);
}
void CenterWindow::initGeneralSettings() {
sm = SettingManager::instance();
auto gridsize = sm->toolGridSize();
for (auto i = 0; i < 9; i++) {
lbls[i]->setFixedSize(QSize(gridsize, gridsize));
}
emit this->getHokeysBuffer(hotkeys, scinfos);
emit this->getToolLeftBuffer(toolinfos);
emit this->getToolRightBuffer(wintoolinfos);
// 获取完数据后,开始初始化程序配置
Qt::KeyboardModifier mod = sm->toolwinMod();
Qt::MouseButton btn = sm->toolwinMouseBtn();
switch (mod) {
case Qt::KeyboardModifier::AltModifier:
cbMod->setCurrentIndex(2);
break;
case Qt::KeyboardModifier::MetaModifier:
cbMod->setCurrentIndex(3);
break;
case Qt::KeyboardModifier::ShiftModifier:
cbMod->setCurrentIndex(1);
break;
default:
cbMod->setCurrentIndex(0);
break;
}
switch (btn) {
case Qt::MouseButton::RightButton:
cbMouseBtn->setCurrentIndex(1);
break;
case Qt::MouseButton::MidButton:
cbMouseBtn->setCurrentIndex(2);
break;
case Qt::MouseButton::XButton1:
cbMouseBtn->setCurrentIndex(3);
break;
case Qt::MouseButton::XButton2:
cbMouseBtn->setCurrentIndex(4);
break;
default:
cbMouseBtn->setCurrentIndex(0);
break;
}
auto seq = sm->toolBoxHotkey();
kseqTool->setKeySequence(seq);
manager->registerHotkey(seq, true);
}
void CenterWindow::initPluginSys() {
@ -694,6 +784,60 @@ void CenterWindow::initAppManger() {
});
}
void CenterWindow::getConfig(QDataStream &f) {
// 先保存 Hotkey 的相关信息
f << hotkeys.count(); // 先存一下有几个
for (auto &p : scinfos) {
f << p.enabled << p.isPlugin << p.seq;
if (p.isPlugin) {
f << p.serviceID << p.provider.toUtf8() << p.params.toUtf8()
<< plgsys->pluginHash(p.pluginIndex); //最后存储 MD5 表示一条信息结束了
} else {
f << p.process.toUtf8()
<< p.params.toUtf8(); // 如果是打开文件就没这么多事情了
}
}
// 下面继续存储 ToolWin 相关信息只有8条
for (auto i = 0; i < 9; i++) {
if (i == 4) // 抛掉空的
continue;
auto &p = toolinfos[i];
// 对于 ToolWin 来说enabled 是决定性的
// 只有这个标志位有效,这个工具才有意义
// 只存有意义的即可
if (p.enabled) {
f << p.isPlugin;
if (p.isPlugin) {
f << p.serviceID << p.provider.toUtf8() << p.params.toUtf8()
<< plgsys->pluginHash(
p.pluginIndex); //最后存储 MD5 表示一条信息结束了
} else {
f << p.process.toUtf8()
<< p.params.toUtf8(); // 如果是打开文件就没这么多事情了
}
}
}
// 下面存取 WinTool 相关信息
f << wintoolinfos.count(); // 先存一下有几个
for (auto &p : wintoolinfos) {
// 对于 WinTool 来说, enabled 就没用了
// 只存储相关基础信息就可以了
f << p.isPlugin;
if (p.isPlugin) {
f << p.serviceID << p.provider.toUtf8() << p.params.toUtf8()
<< plgsys->pluginHash(p.pluginIndex); //最后存储 MD5 表示一条信息结束了
} else {
f << p.process.toUtf8()
<< p.params.toUtf8(); // 如果是打开文件就没这么多事情了
}
}
// 保存完毕,可以返回了
}
void CenterWindow::closeEvent(QCloseEvent *event) {
event->ignore();
hide();

View File

@ -12,6 +12,7 @@
#include <DListWidget>
#include <DMainWindow>
#include <DMenu>
#include <DSpinBox>
#include <DTabWidget>
#include <DTableWidget>
#include <DTextBrowser>
@ -57,16 +58,15 @@ private:
void on_upToolWin();
void on_downToolWin();
signals:
void getHokeysBuffer(QList<Hotkey *> &hotkeysBuf,
QMap<Hotkey *, ToolStructInfo> &buffer);
void getToolLeftBuffer(ToolStructInfo buffer[]);
void getToolRightBuffer(QList<ToolStructInfo> &buffer);
public slots:
void initSettings();
void addHotKeyInfo(ToolStructInfo &info);
void setoolWinInfo(int index, ToolStructInfo &info);
void addWinToolInfo(ToolStructInfo &info);
void initGeneralSettings();
void initPluginSys();
void initAppManger();
void getConfig(QDataStream &f);
protected:
void closeEvent(QCloseEvent *event) override;
@ -96,6 +96,8 @@ private:
DKeySequenceEdit *kseqTool;
DComboBox *cbMod, *cbMouseBtn;
DSpinBox *sbGridsize;
private:
QMap<Hotkey *, ToolStructInfo> scinfos; // 用于 Hotkeys
QList<Hotkey *> hotkeys; // Hotkeys 方便进行检索

View File

@ -9,8 +9,7 @@ ToolWindow::ToolWindow(DDialog *parent) : DDialog(parent) {
Qt::X11BypassWindowManagerHint);
setWindowFlag(Qt::FramelessWindowHint);
auto sm = SettingManager::instance();
auto gridsize = sm->toolGridSize();
auto gridsize = 40; // 默认 40 先
gridtotal = gridsize * 3;
setFixedSize(gridtotal, gridtotal);
delete layout();
@ -29,6 +28,10 @@ ToolWindow::ToolWindow(DDialog *parent) : DDialog(parent) {
}
lbls[4]->setIcon(ICONRES("close"));
}
void ToolWindow::loadSettings() {
auto sm = SettingManager::instance();
// 当设置修改时,响应调整大小
connect(sm, &SettingManager::sigToolGridSizeChanged, this, [=](int v) {

View File

@ -14,6 +14,8 @@ public:
ToolWindow(DDialog *parent = nullptr);
public slots:
void loadSettings();
void setIcons(QVector<QIcon> icons);
void setIcon(int index, QIcon icon);

View File

@ -15,6 +15,8 @@
DWIDGET_USE_NAMESPACE
Q_DECLARE_METATYPE(Qt::MouseButton)
int main(int argc, char *argv[]) {
//解决 root/ubuntu 主题样式走形
qputenv("XDG_CURRENT_DESKTOP", "Deepin");
@ -80,18 +82,7 @@ int main(int argc, char *argv[]) {
/*== 以下在主函数初始化确保单例 ==*/
/* 之后不得使用构造函数的方式使用 */
// 初始化软件配置
SettingManager sm;
QObject::connect(&sm, &SettingManager::loadingFinish, &w,
&CenterWindow::initSettings);
QObject::connect(&w, &CenterWindow::getHokeysBuffer, &sm,
&SettingManager::getHokeysBuffer);
QObject::connect(&w, &CenterWindow::getToolLeftBuffer, &sm,
&SettingManager::getToolLeftBuffer);
QObject::connect(&w, &CenterWindow::getToolRightBuffer, &sm,
&SettingManager::getToolRightBuffer);
sm.loadSettings();
qRegisterMetaType<Qt::MouseButton>();
// 初始化程序基础驱动
AppManager manager;
@ -101,6 +92,28 @@ int main(int argc, char *argv[]) {
PluginSystem plgsys;
w.initPluginSys();
// 初始化软件配置
SettingManager sm;
QObject::connect(&sm, &SettingManager::loadedGeneral, &w,
&CenterWindow::initGeneralSettings);
QObject::connect(&sm, &SettingManager::addHotKeyInfo, &w,
&CenterWindow::addHotKeyInfo);
QObject::connect(&sm, &SettingManager::setToolWinInfo, &w,
&CenterWindow::setoolWinInfo);
QObject::connect(&sm, &SettingManager::addWinToolInfo, &w,
&CenterWindow::addWinToolInfo);
QObject::connect(&sm, &SettingManager::sigSaveConfig, &w,
&CenterWindow::getConfig);
sm.loadSettings();
QObject::connect(&manager, &AppManager::checkToolShow,
[&sm, &manager](Qt::MouseButton btn) {
auto mod = manager.getKeyModifier();
return mod == sm.toolwinMod() &&
sm.toolwinMouseBtn() == btn;
});
/*===========================*/
// 初始化托盘

View File

@ -38,16 +38,6 @@ struct WingPluginInfo {
QString pluginComment;
};
enum class MouseButtonEvent {
NoneButton,
LeftButton,
RightButton,
MiddleButton,
XButton_1,
XButton_2
};
Q_DECLARE_METATYPE(MouseButtonEvent)
enum class MouseWheelEvent { None, Up, Down, Left, Right };
Q_DECLARE_METATYPE(MouseWheelEvent)
@ -135,14 +125,14 @@ public slots:
virtual QVariant pluginServicePipe(int serviceID, QList<QVariant> params) = 0;
// 当鼠标任何一个键被按下就会触发该函数,如果想处理重载
virtual void buttonPress(MouseButtonEvent btn, int x, int y) {
virtual void buttonPress(Qt::MouseButton btn, int x, int y) {
Q_UNUSED(btn);
Q_UNUSED(x);
Q_UNUSED(y);
}
// 当鼠标任何一个键从被按下的状态释放就会触发该函数,如果想处理重载
virtual void buttonRelease(MouseButtonEvent btn, int x, int y) {
virtual void buttonRelease(Qt::MouseButton btn, int x, int y) {
Q_UNUSED(btn);
Q_UNUSED(x);
Q_UNUSED(y);

View File

@ -1,4 +1,5 @@
#include "pluginsystem.h"
#include "utilities.h"
#include <QCoreApplication>
#include <QDir>
#include <QPluginLoader>
@ -32,15 +33,15 @@ PluginSystem::PluginSystem(QObject *parent)
// 初始化插件基础服务
connect(manager, &AppManager::buttonPress, this,
[=](EventMonitor::MouseButton btn, int x, int y) {
[=](Qt::MouseButton btn, int x, int y) {
for (auto item : dispatcher[HookIndex::ButtonPress]) {
item->buttonPress(MouseButtonEvent(btn), x, y);
item->buttonPress(btn, x, y);
}
});
connect(manager, &AppManager::buttonRelease, this,
[=](EventMonitor::MouseButton btn, int x, int y) {
[=](Qt::MouseButton btn, int x, int y) {
for (auto item : dispatcher[HookIndex::ButtonRelease]) {
item->buttonRelease(MouseButtonEvent(btn), x, y);
item->buttonRelease(btn, x, y);
}
});
connect(manager, &AppManager::mouseMove, this, [=](int x, int y) {
@ -216,9 +217,10 @@ void PluginSystem::loadPlugin(QFileInfo fileinfo) {
info.pluginComment = p->pluginComment();
info.pluginVersion = p->pluginVersion();
loadedplginfos.push_back(info);
m_plgs.push_back(p);
loadedplginfos << info;
m_plgs << p;
loadedProvider << p->provider();
m_plgsMD5s << Utilities::getPUID(p);
dWarning(tr("PluginInitRegister"));
@ -248,7 +250,7 @@ void PluginSystem::loadPlugin(QFileInfo fileinfo) {
auto hk = this->manager->registerHotkey(keyseq, false);
if (hk) {
auto uuid = QUuid::createUuid();
m_plghk[sender].append(uuid);
m_plghk[sender] << uuid;
uhmap.insert(uuid, hk);
return uuid;
} else {
@ -350,7 +352,7 @@ QList<QKeySequence> PluginSystem::pluginRegisteredHotkey(IWingToolPlg *plg) {
auto plist = m_plghk[plg];
for (auto &item : plist) {
auto hk = uhmap[item];
keys.append(hk->shortcut());
keys << hk->shortcut();
}
return keys;
}
@ -368,6 +370,12 @@ bool PluginSystem::pluginCall(QString provider, int serviceID,
return true;
}
QByteArray PluginSystem::pluginHash(int index) { return m_plgsMD5s[index]; }
int PluginSystem::pluginIndexByProvider(QString provider) {
return loadedProvider.indexOf(provider);
}
IWingToolPlg *PluginSystem::loopUpHotkey(QUuid uuid, int &index) {
for (auto plg : m_plgs) {
auto res = m_plghk[plg].indexOf(uuid);

View File

@ -46,6 +46,10 @@ public:
bool pluginCall(QString provider, int serviceID, QList<QVariant> params);
QByteArray pluginHash(int index);
int pluginIndexByProvider(QString provider);
private:
IWingToolPlg *loopUpHotkey(QUuid uuid, int &index);
@ -53,14 +57,16 @@ private:
static PluginSystem *m_instance;
AppManager *manager;
QStringList loadedProvider; // 已加载的插件 PUID
QList<IWingToolPlg *> m_plgs; // 已加载的插件集合
QStringList loadedProvider; // 已加载的插件 provider ,需要唯一
QList<IWingToolPlg *> m_plgs; // 已加载的插件集合
QMap<IWingToolPlg *, QList<QUuid>> m_plghk; // 注册的热键句柄集合
QMap<QUuid, Hotkey *> uhmap; // UUID 和 QHotkey 的对应图
QMap<IWingToolPlg::Catagorys, QList<IWingToolPlg *>>
m_catplgs; // 对应类别的插件集合
QMap<HookIndex, QList<IWingToolPlg *>> dispatcher;
QMap<HookIndex, QList<IWingToolPlg *>> dispatcher; // Hook 消息订阅
QList<QByteArray> m_plgsMD5s; // 已加载的插件 HASH
};
#endif // PLUGINSYSTEM_H

View File

@ -30,8 +30,6 @@ struct ToolStructInfo {
Q_DECLARE_METATYPE(ToolStructInfo)
class PluginSystem;
class Utilities {
public:
static bool activeWindowFromDock(quintptr winId) {
@ -55,6 +53,54 @@ public:
return plg->pluginIcon();
}
// 虽然 provider 是插件的唯一标识,需要进行校验
// 但是,检查兼容性的时候第一关就是看看有没有它
// 所以:没必要!
static QByteArray getPUID(IWingToolPlg *plg) {
if (!plg)
return QByteArray();
// 这个 PUID 似乎不那么高大上,仅仅就是拼凑
// 但这几个是影响插件兼容的必要因素
QByteArray buffer;
QBuffer b(&buffer);
QDataStream f(&b);
f << plg->isTool() << plg->pluginServices();
return buffer;
}
static bool isPluginCompatible(IWingToolPlg *plg, QByteArray &old) {
if (!plg)
return false;
QBuffer b(&old);
QDataStream f(&b);
bool isTool;
f >> isTool;
if (isTool != plg->isTool()) // 以前你是工具项目之一,后面不是了,肯定不兼容
return false;
QStringList services;
f >> services;
auto srv = plg->pluginServices();
auto len = services.count();
// 服务比原来的都少了,肯定不兼容
if (srv.count() < len)
return false;
// 开始评判函数,函数名不一致会导致错误的函数调用
for (auto i = 0; i < len; i++) {
if (srv[i] != services[i])
return false;
}
return true;
}
static QIcon trimIconFromInfo(IWingToolPlg *plg, ToolStructInfo &info) {
if (info.isPlugin) {
if (plg == nullptr)