mirror of
https://github.com/rubickCenter/rubick
synced 2025-06-20 11:12:44 +08:00
ref: mouse-osx 替换为 iohook
This commit is contained in:
parent
5555275280
commit
f9b0177c00
@ -70,7 +70,6 @@
|
|||||||
"md5": "^2.3.0",
|
"md5": "^2.3.0",
|
||||||
"mime-types": "^2.1.31",
|
"mime-types": "^2.1.31",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"osx-mouse": "^2.0.0",
|
|
||||||
"puppeteer-core": "^10.0.0",
|
"puppeteer-core": "^10.0.0",
|
||||||
"puppeteer-in-electron": "^3.0.3",
|
"puppeteer-in-electron": "^3.0.3",
|
||||||
"query-string": "^7.0.0",
|
"query-string": "^7.0.0",
|
||||||
|
@ -30,15 +30,15 @@ module.exports = () => {
|
|||||||
enableLargerThanScreen: true,
|
enableLargerThanScreen: true,
|
||||||
hasShadow: false,
|
hasShadow: false,
|
||||||
show: false,
|
show: false,
|
||||||
|
title: 'capture',
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
enableRemoteModule: true,
|
enableRemoteModule: true,
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
webSecurity: false,
|
webSecurity: false,
|
||||||
// devTools: false,
|
devTools: false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
captureWin.setAlwaysOnTop(true, 'screen-saver')
|
captureWin.setAlwaysOnTop(true, 'screen-saver')
|
||||||
captureWin.setVisibleOnAllWorkspaces(true)
|
|
||||||
captureWin.setFullScreenable(false)
|
captureWin.setFullScreenable(false)
|
||||||
|
|
||||||
captureWin.loadFile(`${__static}/plugins/capture/index.html`);
|
captureWin.loadFile(`${__static}/plugins/capture/index.html`);
|
||||||
@ -50,6 +50,10 @@ module.exports = () => {
|
|||||||
captureWin.blur()
|
captureWin.blur()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
captureWin.on("closed", () => {
|
||||||
|
captureWin = undefined;
|
||||||
|
});
|
||||||
|
|
||||||
captureWin.once('ready-to-show', () => captureWin.show());
|
captureWin.once('ready-to-show', () => captureWin.show());
|
||||||
return captureWin
|
return captureWin
|
||||||
});
|
});
|
||||||
@ -57,15 +61,13 @@ module.exports = () => {
|
|||||||
|
|
||||||
let getWindow = () => captureWins;
|
let getWindow = () => captureWins;
|
||||||
|
|
||||||
let useCapture = () => {
|
const close = () => {
|
||||||
globalShortcut.register('Esc', () => {
|
const wins = BrowserWindow.getAllWindows();
|
||||||
if (captureWins) {
|
wins.forEach((win) => {
|
||||||
captureWins.forEach(win => win.close())
|
if (win.title === 'capture') win.close();
|
||||||
captureWins = []
|
captureWins = [];
|
||||||
|
})
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
globalShortcut.register('CmdOrCtrl+Shift+S', init)
|
|
||||||
|
|
||||||
ipcMain.on('capture-screen', (e, { type = 'start', screenId, winId, x, y } = {}) => {
|
ipcMain.on('capture-screen', (e, { type = 'start', screenId, winId, x, y } = {}) => {
|
||||||
if (type === 'start') {
|
if (type === 'start') {
|
||||||
@ -92,11 +94,10 @@ module.exports = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
getWindow: getWindow,
|
getWindow: getWindow,
|
||||||
useCapture,
|
close,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@ const { BrowserWindow, nativeImage } = require("electron");
|
|||||||
module.exports = () => {
|
module.exports = () => {
|
||||||
let win;
|
let win;
|
||||||
|
|
||||||
let init = () => {
|
let init = (x, y) => {
|
||||||
if (win === null || win === undefined) {
|
if (win === null || win === undefined) {
|
||||||
createWindow();
|
createWindow();
|
||||||
}
|
}
|
||||||
|
@ -9,17 +9,16 @@ import {
|
|||||||
import Api from './api';
|
import Api from './api';
|
||||||
import robot from 'robotjs';
|
import robot from 'robotjs';
|
||||||
import './config';
|
import './config';
|
||||||
|
import ioHook from 'iohook';
|
||||||
|
|
||||||
const browsers = require("../browsers")();
|
const browsers = require("../browsers")();
|
||||||
const mouseEvents = require("osx-mouse");
|
const {picker, separator, superPanel, capture} = browsers;
|
||||||
const {picker, separator, superPanel} = browsers;
|
|
||||||
// 需要在超级面板展示的插件
|
// 需要在超级面板展示的插件
|
||||||
let optionPlugin = [];
|
let optionPlugin = [];
|
||||||
|
|
||||||
let closePicker = (newColor) => {
|
let closePicker = () => {
|
||||||
if (picker.getWindow()) {
|
if (picker.getWindow()) {
|
||||||
ipcMain.removeListener("closePicker", closePicker);
|
ipcMain.removeListener("closePicker", closePicker);
|
||||||
ipcMain.removeListener("pickerRequested", (event) => {});
|
|
||||||
picker.getWindow().close();
|
picker.getWindow().close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -27,7 +26,7 @@ let closePicker = (newColor) => {
|
|||||||
function registerShortCut(mainWindow) {
|
function registerShortCut(mainWindow) {
|
||||||
const config = global.opConfig.get();
|
const config = global.opConfig.get();
|
||||||
globalShortcut.unregisterAll();
|
globalShortcut.unregisterAll();
|
||||||
|
// 注册偏好快捷键
|
||||||
globalShortcut.register(config.perf.shortCut.showAndHidden, () => {
|
globalShortcut.register(config.perf.shortCut.showAndHidden, () => {
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
});
|
});
|
||||||
@ -35,6 +34,18 @@ function registerShortCut(mainWindow) {
|
|||||||
globalShortcut.register(config.perf.shortCut.separate, () => {
|
globalShortcut.register(config.perf.shortCut.separate, () => {
|
||||||
mainWindow.webContents.send('new-window');
|
mainWindow.webContents.send('new-window');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 注册自定义全局快捷键
|
||||||
|
config.global.forEach(sc => {
|
||||||
|
if (!sc.key || !sc.value) return;
|
||||||
|
globalShortcut.register(sc.key, () => {
|
||||||
|
mainWindow.webContents.send('global-short-key', sc.value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
globalShortcut.register('Esc', () => {
|
||||||
|
capture.close();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSelectedText = () => {
|
const getSelectedText = () => {
|
||||||
@ -143,23 +154,35 @@ export default function init(mainWindow) {
|
|||||||
|
|
||||||
// 拾色器
|
// 拾色器
|
||||||
ipcMain.on('start-picker', () => {
|
ipcMain.on('start-picker', () => {
|
||||||
const mouseTrack = mouseEvents();
|
// 开启输入侦测
|
||||||
|
ioHook.start(false)
|
||||||
picker.init();
|
picker.init();
|
||||||
picker.getWindow().on("close", () => {
|
|
||||||
mouseTrack.destroy();
|
picker.getWindow().on('close', () => {
|
||||||
|
ioHook.stop();
|
||||||
});
|
});
|
||||||
mouseTrack.on('move', (x, y) => {
|
|
||||||
|
|
||||||
|
ioHook.on('mousemove', e => {
|
||||||
|
let x = e.x
|
||||||
|
let y = e.y
|
||||||
if (!picker.getWindow()) return;
|
if (!picker.getWindow()) return;
|
||||||
let color = "#" + robot.getPixelColor(parseInt(x), parseInt(y));
|
let color = "#" + robot.getPixelColor(parseInt(x), parseInt(y));
|
||||||
picker.getWindow().setPosition(parseInt(x) - 50, parseInt(y) - 50);
|
picker.getWindow().setPosition(parseInt(x) - 50, parseInt(y) - 50);
|
||||||
picker.getWindow().webContents.send("updatePicker", color);
|
picker.getWindow().webContents.send("updatePicker", color);
|
||||||
})
|
})
|
||||||
mouseTrack.on("left-up", (x, y) => {
|
|
||||||
|
ioHook.on('mouseup', e => {
|
||||||
|
if (e.button === 1) {
|
||||||
|
let x = e.x
|
||||||
|
let y = e.y
|
||||||
const color = "#" + robot.getPixelColor(parseInt(x), parseInt(y));
|
const color = "#" + robot.getPixelColor(parseInt(x), parseInt(y));
|
||||||
clipboard.writeText("#" + robot.getPixelColor(parseInt(x), parseInt(y)));
|
clipboard.writeText("#" + robot.getPixelColor(parseInt(x), parseInt(y)));
|
||||||
new Notification({ title: 'Rubick 通知', body: `${color} 已保存到剪切板` }).show();
|
new Notification({ title: 'Rubick 通知', body: `${color} 已保存到剪切板` }).show();
|
||||||
closePicker();
|
closePicker();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let pos = robot.getMousePos();
|
let pos = robot.getMousePos();
|
||||||
picker
|
picker
|
||||||
.getWindow()
|
.getWindow()
|
||||||
@ -173,7 +196,11 @@ export default function init(mainWindow) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
ipcMain.on("closePicker", closePicker);
|
ipcMain.on("closePicker", closePicker);
|
||||||
mouseTrack.on("right-up", closePicker);
|
ioHook.on('mouseup', e => {
|
||||||
|
if (e.button === 3) {
|
||||||
|
closePicker()
|
||||||
|
}
|
||||||
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import '../renderer/store'
|
|||||||
import init from './common/common';
|
import init from './common/common';
|
||||||
import {autoUpdate} from './common/autoUpdate';
|
import {autoUpdate} from './common/autoUpdate';
|
||||||
import createTray from './tray';
|
import createTray from './tray';
|
||||||
const {capture, main} = require("./browsers")();
|
const {main} = require("./browsers")();
|
||||||
/**
|
/**
|
||||||
* Set `__static` path to static files in production
|
* Set `__static` path to static files in production
|
||||||
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
|
||||||
@ -16,7 +16,6 @@ app.allowRendererProcessReuse = false;
|
|||||||
app.dock.hide();
|
app.dock.hide();
|
||||||
|
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
capture.useCapture();
|
|
||||||
main.init();
|
main.init();
|
||||||
init(main.getWindow());
|
init(main.getWindow());
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,9 @@
|
|||||||
<div @click="goMenu" class="suffix-tool" slot="suffix">
|
<div @click="goMenu" class="suffix-tool" slot="suffix">
|
||||||
<a-icon v-show="selected && selected.key === 'plugin-container'" class="icon-more" type="more" />
|
<a-icon v-show="selected && selected.key === 'plugin-container'" class="icon-more" type="more" />
|
||||||
<img class="icon-tool" v-if="selected && selected.icon" :src="selected.icon" />
|
<img class="icon-tool" v-if="selected && selected.icon" :src="selected.icon" />
|
||||||
<a-icon class="icon-tool" v-else type="tool"/>
|
<div v-else class="rubick-logo">
|
||||||
|
<img src="./assets/logo.png" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</a-input>
|
</a-input>
|
||||||
@ -78,7 +80,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import {mapActions, mapMutations, mapState} from "vuex";
|
import {mapActions, mapMutations, mapState} from "vuex";
|
||||||
import {ipcRenderer, remote} from "electron";
|
import {ipcRenderer, remote} from "electron";
|
||||||
import {getWindowHeight, debounce} from "./assets/common/utils";
|
import {getWindowHeight, debounce, searchKeyValues, fileLists} from "./assets/common/utils";
|
||||||
const opConfig = remote.getGlobal('opConfig');
|
const opConfig = remote.getGlobal('opConfig');
|
||||||
const {Menu, MenuItem} = remote;
|
const {Menu, MenuItem} = remote;
|
||||||
|
|
||||||
@ -105,6 +107,32 @@ export default {
|
|||||||
payload: args.data,
|
payload: args.data,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
ipcRenderer.on('global-short-key', (e, args) => {
|
||||||
|
let config;
|
||||||
|
this.devPlugins.forEach((plugin) => {
|
||||||
|
// dev 插件未开启
|
||||||
|
if (plugin.type === 'dev' && !plugin.status) return;
|
||||||
|
const feature = plugin.features;
|
||||||
|
feature.forEach(fe => {
|
||||||
|
const cmd = searchKeyValues(fe.cmds, args)[0];
|
||||||
|
const systemPlugin = fileLists.filter(plugin => plugin.name.indexOf(args) >= 0)[0];
|
||||||
|
if (cmd) {
|
||||||
|
config = {
|
||||||
|
cmd: cmd,
|
||||||
|
plugin: plugin,
|
||||||
|
feature: fe,
|
||||||
|
router: this.$router
|
||||||
|
}
|
||||||
|
} else if (systemPlugin) {
|
||||||
|
config = {
|
||||||
|
plugin: systemPlugin,
|
||||||
|
router: this.$router
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
config && this.openPlugin(config);
|
||||||
|
});
|
||||||
const searchNd = document.getElementById('search');
|
const searchNd = document.getElementById('search');
|
||||||
searchNd && searchNd.addEventListener('keydown', this.checkNeedInit)
|
searchNd && searchNd.addEventListener('keydown', this.checkNeedInit)
|
||||||
},
|
},
|
||||||
@ -211,7 +239,7 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState('main', ['showMain', 'current', 'options', 'selected', 'searchValue', 'subPlaceHolder']),
|
...mapState('main', ['showMain', 'devPlugins', 'current', 'options', 'selected', 'searchValue', 'subPlaceHolder']),
|
||||||
showOptions() {
|
showOptions() {
|
||||||
// 有选项值,且不在显示主页
|
// 有选项值,且不在显示主页
|
||||||
if (this.options.length && !this.showMain) {
|
if (this.options.length && !this.showMain) {
|
||||||
@ -242,6 +270,18 @@ export default {
|
|||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
.rubick-logo {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
background: #314659;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 100%;
|
||||||
|
img {
|
||||||
|
width: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.tag-container {
|
.tag-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 7.8 KiB |
@ -93,7 +93,7 @@
|
|||||||
<span>先按功能键(Ctrl、Shift、Alt、Option、Command),再按其他普通键。或按 F1-F12 单键</span>
|
<span>先按功能键(Ctrl、Shift、Alt、Option、Command),再按其他普通键。或按 F1-F12 单键</span>
|
||||||
</template>
|
</template>
|
||||||
<div
|
<div
|
||||||
v-for="(index, item) in config.global"
|
v-for="(item, index) in config.global"
|
||||||
class="value"
|
class="value"
|
||||||
tabIndex=-1
|
tabIndex=-1
|
||||||
@keydown="(e) => changeGlobalKey(e, index)"
|
@keydown="(e) => changeGlobalKey(e, index)"
|
||||||
@ -107,7 +107,7 @@
|
|||||||
<div>功能关键字</div>
|
<div>功能关键字</div>
|
||||||
<a-input
|
<a-input
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
v-for="(index, item) in config.global"
|
v-for="(item, index) in config.global"
|
||||||
class="value"
|
class="value"
|
||||||
:disabled="!item.key"
|
:disabled="!item.key"
|
||||||
@change="(e) => changeGlobalValue(index, e.target.value)"
|
@change="(e) => changeGlobalValue(index, e.target.value)"
|
||||||
@ -193,6 +193,13 @@ export default {
|
|||||||
if (compose) {
|
if (compose) {
|
||||||
this.$set(this.config.global[index], 'key', compose);
|
this.$set(this.config.global[index], 'key', compose);
|
||||||
}
|
}
|
||||||
|
// f1 - f12
|
||||||
|
if (e.keyCode >= 112 && e.keyCode <= 123) {
|
||||||
|
compose = keycodes[e.keyCode].toUpperCase();
|
||||||
|
}
|
||||||
|
if (compose) {
|
||||||
|
this.$set(this.config.global[index], 'key', compose);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
changeGlobalValue(index, value) {
|
changeGlobalValue(index, value) {
|
||||||
this.$set(this.config.global[index], 'value', value);
|
this.$set(this.config.global[index], 'value', value);
|
||||||
@ -204,6 +211,7 @@ export default {
|
|||||||
handler() {
|
handler() {
|
||||||
opConfig.set('perf', this.config.perf);
|
opConfig.set('perf', this.config.perf);
|
||||||
opConfig.set('superPanel', this.config.superPanel);
|
opConfig.set('superPanel', this.config.superPanel);
|
||||||
|
opConfig.set('global', this.config.global);
|
||||||
ipcRenderer.send('re-register');
|
ipcRenderer.send('re-register');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,6 @@ const actions = {
|
|||||||
...options,
|
...options,
|
||||||
...(fileLists.filter(plugin => plugin.name.indexOf(value) >= 0)).map(plugin => {
|
...(fileLists.filter(plugin => plugin.name.indexOf(value) >= 0)).map(plugin => {
|
||||||
plugin.click = () => {
|
plugin.click = () => {
|
||||||
console.log(plugin)
|
|
||||||
actions.openPlugin({commit}, {plugin});
|
actions.openPlugin({commit}, {plugin});
|
||||||
}
|
}
|
||||||
return plugin
|
return plugin
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<title>Document</title>
|
<title>capture</title>
|
||||||
<style>
|
<style>
|
||||||
@import "./assets/iconfont/iconfont.css";
|
@import "./assets/iconfont/iconfont.css";
|
||||||
|
|
||||||
|
@ -5,11 +5,6 @@ document.querySelector(
|
|||||||
"#picker"
|
"#picker"
|
||||||
).style.border = `10px solid rgba(200, 200, 200, 0.3)`;
|
).style.border = `10px solid rgba(200, 200, 200, 0.3)`;
|
||||||
|
|
||||||
document.addEventListener(
|
|
||||||
"DOMContentLoaded",
|
|
||||||
() => ipcRenderer.send("pickerRequested"),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
document.addEventListener(
|
document.addEventListener(
|
||||||
"keydown",
|
"keydown",
|
||||||
(event) => {
|
(event) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user