electron launcher
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

414 lines
14 KiB

2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
2 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
4 years ago
  1. const {BrowserWindow, desktopCapturer} = require('electron');
  2. // const {net} = require('electron');
  3. const electron = require('electron');
  4. const ipc = require('electron').ipcMain;
  5. // const screen = require('electron').screen;
  6. const store = require('./windows/lib/store');
  7. const {create: createMainWindow} = require('./windows/main')
  8. // const { create: createLoginWindow } = require('./windows/login')
  9. // const { create: createAppWindow } = require('./windows/app')
  10. const childProcess = require('./child_process')
  11. const {create: openWindow} = require('./windows/application')
  12. // const querystring = require("querystring");
  13. const {MAIN_WINDOW_FLAG, SUSPENSION_WINDOW_FLAG} = require('./constant');
  14. const { ipcRenderer } = require('electron/renderer');
  15. // const installApp = require('./ipc/installApp');
  16. // const getApps = require('./ipc/getApps');
  17. // const removeApp = require('./ipc/removeApp');
  18. // connect redis
  19. // const {createClient} = require('redis')
  20. // ;(async () => {
  21. // /**
  22. // * createClient({
  23. // * url: 'redis://alice:foobared@awesome.redis.server:6380'
  24. // * });
  25. // */
  26. // const client = createClient(
  27. // // {
  28. // // url: "redis://localhost:3807"
  29. // // }
  30. // );
  31. // // client.on('error', (err) => console.log('Redis Client Error', err));
  32. // await client.connect()
  33. // // 订阅者
  34. // const subscriber = client.duplicate();
  35. // await subscriber.connect();
  36. // // 发布者
  37. // const publisher = client.duplicate()
  38. // await publisher.connect()
  39. // // 通过main向外发布消息
  40. // ipc.on('publishMessage', (events, {channel, ...message}) => {
  41. // publisher.publish(channel, JSON.stringify(message))
  42. // })
  43. // // 订阅外部消息
  44. // subscriber.subscribe('openMap', message => {
  45. // const windows = BrowserWindow.getAllWindows()
  46. // const found = windows.find((window) => {
  47. // return window[MAIN_WINDOW_FLAG]
  48. // });
  49. // found.webContents.send('openMap', JSON.parse(message))
  50. // })
  51. // // 订阅外部消息(正则)
  52. // subscriber.pSubscribe('openMap*', (message, channel) => {
  53. // const windows = BrowserWindow.getAllWindows()
  54. // const found = windows.find((window) => {
  55. // return window[MAIN_WINDOW_FLAG]
  56. // });
  57. // found.webContents.send(channel, JSON.parse(message))
  58. // })
  59. // })();
  60. module.exports = () => {
  61. let winStartPostion = {x: 0, y: 0};
  62. let mouseStartPosition = {x: 0, y: 0};
  63. let movingInterVal = null;
  64. ipc.on('getUnReadMessage', (events, callback) => {
  65. const msg = store.get('unReadMessage');
  66. // console.log('msg', msg);
  67. const windows = BrowserWindow.getAllWindows()
  68. const found = windows.find((window) => {
  69. return window[SUSPENSION_WINDOW_FLAG]
  70. });
  71. found.webContents.send("getUnReadMessage", [msg])
  72. });
  73. ipc.on('setUnReadMessage', (events, message) => {
  74. // console.log('set', message);
  75. store.set('unReadMessage', message);
  76. // 消息需要实时同步
  77. const windows = BrowserWindow.getAllWindows()
  78. const win = windows.find((window) => {
  79. return window[SUSPENSION_WINDOW_FLAG]
  80. });
  81. if (win) {
  82. // let winWidth = win.getSize()[0];
  83. let areaSize = require('electron').screen.getPrimaryDisplay().workAreaSize;
  84. const x = win.getPosition()[0];
  85. const y = win.getPosition()[1];
  86. let sWidth = areaSize.width;
  87. // console.log(sWidth - x);
  88. if (sWidth - x === 130) {
  89. win.setSize(410, 130, true);
  90. win.setPosition(sWidth - 660, y, true);
  91. }
  92. win.webContents.send("getUnReadMessage", [message])
  93. }
  94. });
  95. ipc.on("showSuspensionWindow", () => {
  96. let areaSize = require('electron').screen.getPrimaryDisplay().workAreaSize;
  97. const windows = BrowserWindow.getAllWindows()
  98. const win = windows.find((window) => {
  99. return window[SUSPENSION_WINDOW_FLAG]
  100. });
  101. console.log('恢复原始大小')
  102. win.setSize(410, 130, true);
  103. const y = win.getPosition()[1];
  104. win.setPosition(areaSize.width - win.getSize()[0], y, true);
  105. win.webContents.send("winResize", [win.getSize()])
  106. })
  107. ipc.on('resizeWindow', () => {
  108. let areaSize = require('electron').screen.getPrimaryDisplay().workAreaSize;
  109. const windows = BrowserWindow.getAllWindows()
  110. const win = windows.find((window) => {
  111. return window[SUSPENSION_WINDOW_FLAG]
  112. });
  113. const startWidth = win.getSize()[0];
  114. if (startWidth < 410) {
  115. const x = win.getPosition()[0];
  116. const y = win.getPosition()[1];
  117. win.setSize(410, 130, true);
  118. if (x > areaSize.width - win.getSize()[0]) {
  119. win.setPosition(areaSize.width - win.getSize()[0] - 50, y, true);
  120. }
  121. }
  122. });
  123. ipc.on('windowMoveHandle', (events, canMoving) => {
  124. const windows = BrowserWindow.getAllWindows()
  125. const win = windows.find((window) => {
  126. return window[SUSPENSION_WINDOW_FLAG]
  127. });
  128. const screen = require('electron').screen;
  129. /**
  130. * 窗口移动事件
  131. */
  132. if (!win) return;
  133. if (canMoving) {
  134. //读取原位置
  135. const winPosition = win.getPosition();
  136. winStartPostion = {x: winPosition[0], y: winPosition[1]};
  137. mouseStartPosition = screen.getCursorScreenPoint();
  138. //清除
  139. if (movingInterVal) {
  140. clearInterval(movingInterVal);
  141. }
  142. //新开
  143. movingInterVal = setInterval(() => {
  144. if(!win){
  145. clearInterval(movingInterVal);
  146. return;
  147. }
  148. const cursorPosition = screen.getCursorScreenPoint();
  149. const x = winStartPostion.x + cursorPosition.x - mouseStartPosition.x;
  150. const y = winStartPostion.y + cursorPosition.y - mouseStartPosition.y;
  151. win.setPosition(x, y, true)
  152. }, 20)
  153. } else {
  154. clearInterval(movingInterVal);
  155. let areaSize = require('electron').screen.getPrimaryDisplay().workAreaSize;
  156. const x = win.getPosition()[0];
  157. const y = win.getPosition()[1];
  158. store.set("position", {x, y});
  159. let sWidth = areaSize.width;
  160. let winWidth = win.getSize()[0];
  161. // console.log(x + winWidth >= sWidth, sWidth - x - winWidth);
  162. // 靠边吸附效果
  163. console.log("0000000", x + winWidth >= sWidth, sWidth - x - winWidth <= 20)
  164. if (x + winWidth >= sWidth || sWidth - x - winWidth <= 20) {
  165. win.setResizable(true);
  166. win.setSize(130, 130, true)
  167. win.setPosition(sWidth - 130, y, true);
  168. win.setResizable(false);
  169. console.log("靠边吸附", win.getSize(), win.getPosition())
  170. //通知渲染进程大小发生改变
  171. } else {
  172. win.setSize(410, 130, true)
  173. }
  174. win.webContents.send("winResize", [win.getSize()])
  175. movingInterVal = null;
  176. }
  177. });
  178. ipc.on('showMainWindow', (event, arg) => {
  179. const windows = BrowserWindow.getAllWindows()
  180. const found = windows.find((window) => {
  181. return window[MAIN_WINDOW_FLAG]
  182. })
  183. if (found) {
  184. found.restore();
  185. found.show();
  186. } else {
  187. createMainWindow()
  188. }
  189. return true
  190. });
  191. ipc.on('hideMainWindow', () => {
  192. console.log('最小化hideMainWindow');
  193. const windows = BrowserWindow.getAllWindows()
  194. const found = windows.find((window) => {
  195. return window[MAIN_WINDOW_FLAG]
  196. })
  197. if (found) {
  198. found.hide();
  199. }
  200. return true
  201. });
  202. ipc.on('minimize', () => {
  203. // const windows = BrowserWindow.getAllWindows()
  204. // const found = windows.find((window) => {
  205. // return window[MAIN_WINDOW_FLAG]
  206. // })
  207. // if (found) {
  208. // found.minimize();
  209. // }
  210. // return true
  211. try {
  212. const windows = BrowserWindow.getAllWindows()
  213. for (let win of windows) {
  214. win && win.minimize()
  215. }
  216. }catch (e) {}
  217. });
  218. ipc.on('hideSuspensionWindow', (event, arg) => {
  219. const windows = BrowserWindow.getAllWindows()
  220. const found = windows.find((window) => {
  221. return window[SUSPENSION_WINDOW_FLAG]
  222. });
  223. if (found) {
  224. found.close()
  225. }
  226. return true
  227. });
  228. ipc.on('openDevTools', (event, arg) => {
  229. event.sender.webContents.openDevTools()
  230. return true
  231. });
  232. ipc.on('exitSystem', () => {
  233. console.log('global',global.worker);
  234. try {
  235. const windows = BrowserWindow.getAllWindows()
  236. for (let win of windows) {
  237. win && win.close()
  238. }
  239. global.worker === 'stop'
  240. store.delete("unReadMessage");
  241. }catch (e) {
  242. }
  243. });
  244. // ipc.handle('openWidget', (event, widget = {}) => {
  245. // createAppWindow(widget)
  246. // return true
  247. // });
  248. //
  249. // ipc.handle('openDevTools', (event, arg) => {
  250. // event.sender.webContents.openDevTools()
  251. // return true
  252. // });
  253. // ipc.handle('installApp', installApp);
  254. //
  255. // ipc.handle('getApps', getApps);
  256. //
  257. // ipc.handle('removeApp', removeApp);
  258. /* ipcRenderer
  259. ipcRenderer.send('spawn', {
  260. command: '微信.exe',
  261. args: null || ['--disable-cache'],
  262. key: + new Date // 唯一key,用来做关闭识别,
  263. })
  264. */
  265. ipc.on('spawn', (event, arg) => {
  266. const {pid, promise} = childProcess.start(arg.command, arg.args, arg.key)
  267. event.sender.send('spawn-success', {
  268. key: arg.key,
  269. pid
  270. })
  271. promise.then(data => {
  272. event.sender.send('spawn-success', {
  273. key: arg.key,
  274. data
  275. })
  276. })
  277. promise.catch(err => {
  278. event.sender.send('spawn-error', {
  279. key: arg.key,
  280. err
  281. })
  282. })
  283. })
  284. // ipcRenderer.send('kill-process', [pid])
  285. ipc.on('kill-process', function (event, arg) {
  286. childProcess.kill(arg[0])
  287. })
  288. // 通信桥梁
  289. ipc.on('bridge', function (event, {channel, targetId, ...message}) {
  290. console.log('bridge message', channel, message)
  291. const windows = BrowserWindow.getAllWindows()
  292. // const found = windows.find((window) => {
  293. // return window[SUSPENSION_WINDOW_FLAG]
  294. // });
  295. for (let win of windows) {
  296. if (!targetId || win[targetId]) {
  297. win.webContents.send(channel, message);
  298. }
  299. }
  300. })
  301. const windowMap = new Map();
  302. // 通过main打开新窗口
  303. ipc.on('openWindow', function (event, arg) {
  304. //如果存在第二块屏幕,在第二块屏幕打开
  305. let displays = electron.screen.getAllDisplays();
  306. let externalDisplay = displays.find((display)=>{
  307. return display.bounds.x !== 0 || display.bounds.y !== 0
  308. });
  309. let options = {};
  310. if(externalDisplay){
  311. options = {
  312. fullscreen:true,
  313. x:externalDisplay.bounds.x,
  314. y:externalDisplay.bounds.y,
  315. };
  316. //关闭上一个,同一时间在拓展屏只能打开两个,打开多个或引起卡顿
  317. if(windowMap.size > 2){
  318. const win = windowMap.values().next().value;
  319. win.close();
  320. windowMap.delete(windowMap.keys().next().value);
  321. }
  322. }
  323. console.log('openWindow request from renderer process', arg);
  324. const windows = BrowserWindow.getAllWindows();
  325. const found = windows.find((window) => {
  326. return window[arg.id]
  327. });
  328. if (!arg.id || !arg.entry) {
  329. return;
  330. }
  331. //未打开过,新建窗口
  332. if(!found){
  333. const temp = openWindow(arg,options)
  334. windowMap.set(arg.id,temp);
  335. }else{//打开且未关闭,切换至前台
  336. found.focus()
  337. }
  338. })
  339. //返回上一个窗口
  340. ipc.on("backPreviousApp",function (event,arg) {
  341. const keys = [...windowMap.keys()];
  342. const curKey = keys.findIndex(v=>v === arg.id);
  343. if(keys.length > 1){
  344. let preKey = curKey > 0? curKey - 1 : keys.length - 1;
  345. const preId = keys[preKey];
  346. windowMap.get(preId).focus();
  347. }
  348. });
  349. //根据指定id关闭窗口
  350. ipc.on('closeWindowById', function (event, arg) {
  351. const windows = BrowserWindow.getAllWindows();
  352. const found = windows.find((window) => {
  353. return window[arg.id]
  354. });
  355. found.close();
  356. windowMap.delete(arg.id);
  357. })
  358. // 监听调用截屏事件
  359. ipc.on('PrtSc', function (event, arg) {
  360. const windows = BrowserWindow.getAllWindows()
  361. const found = windows.find((window) => {
  362. return window[MAIN_WINDOW_FLAG]
  363. })
  364. if (found) {
  365. found.webContents.send('PrtSc');
  366. }
  367. })
  368. // 监听下载截屏的图片
  369. ipc.on('downloadImg', function (event, arg) {
  370. const windows = BrowserWindow.getAllWindows()
  371. const found = windows.find((window) => {
  372. return window[MAIN_WINDOW_FLAG]
  373. })
  374. if (found) {
  375. found.webContents.send('downloadImg');
  376. }
  377. })
  378. // 取消截屏显示
  379. ipc.on('removeCanvas', function (event, arg) {
  380. const windows = BrowserWindow.getAllWindows()
  381. const found = windows.find((window) => {
  382. return window[MAIN_WINDOW_FLAG]
  383. })
  384. if (found) {
  385. found.webContents.send('removeCanvas');
  386. }
  387. })
  388. }