相关文章推荐
才高八斗的椅子  ·  Python ...·  1 年前    · 
豁达的课本  ·  python 获取本周周一-掘金·  1 年前    · 

作者:陌路凡歌

来源:SegmentFault 思否社区

窗口关闭与托盘处理

本期主要涉及窗口的关闭处理以及托盘的简单处理。

关闭的概念

我们在使用官方例子,打包安装后会发现mac和win在关闭上有所不同,mac是直接缩小到程序坞,对程序坞右键退出才能关闭,win则是直接关闭软件,这是为什么呢?

窗口的关闭:

注意:窗口的关闭不一定会触发软件的关闭,但是通常情况下我们只有一个窗口,如果这个窗口关闭了,会触发app的window-all-closed(当所有的窗口都被关闭时触发)这个事件,在这个事件里我们可以调用软件的关闭app.quit(),故大多数情况下,我们把窗口关闭了,软件也就退出了。

'window-all-closed'

if

软件的关闭:

总结一下简单来说软件的关闭要满足两个条件:

所有窗口都关闭了

调用了app.quit()

所以软件的关闭一般就是下面几种情况了

所有窗口关闭触发window-all-closed,在window-all-closed里调用app.quit()

调用app.quit(),触发所有窗口的close事件

app.exit()

那么要达成我们的目标只有使用方法2了。

进程通信配置

进程通信的话,放到后面再说,这里只是介绍进程通信的配置

'electron'

'asynchronous-message'

'ping'

这样使用没问题,但是如果我们有多个页面都要使用那么我们每个页面都要require,比较麻烦,而且如果我们想既打包electron,又想打包web同样使用(可以通过process.env.IS_ELECTRON处理不同场景),那么引入的electron就无用了。electron的窗口的webPreferences提供了preload可以注入js,我们可以在这里把ipcRenderer挂载到window下面。

true

'src/renderer/preload/ipcRenderer.js'

'electron'

false

'preload.js'

''

'index.html'

if

'asynchronous-message'

'ping'

这里说明一下contextIsolation这个值,在12.0.0以前默认值为false,本例子是12.0.0版本,默认值为true,区别在于为true的话,注入的preload.js可视为一个独立运行的环境,对于渲染进程是不可见的,简单来说就是我们把ipcRenderer挂载到window上,对应的渲染进程是获取不到的,故这里设置为false。

功能实现

如何实现呢?理一下思路,win的close事件有两种触发方式:

一个是我们点击关闭触发,此时我们并不想关闭窗口,那么应该使用e.preventDefault()阻止窗口的关闭。

另一个是我们主动使用app.quit()触发关闭,这时close事件里就不做处理。

那么通过一个变量flag的切换来实现,声明一个全局变量willQuitApp,在onAppReady里添加窗口的close事件,当我们点击关闭触发close事件,此时e.preventDefault()禁止了窗口的关闭,我们再通过主进程向渲染进程发出一个关闭的通知。

主进程:

let

false

'close'

'close'

if

'win-close-tips'

true

'activate'

'before-quit'

'before-quit'

true

渲染进程:

"visible"

"true"

"关闭提示"

"确认"

"取消"

"hideModal"

"closeValue"

"radioStyle"

"1"

"radioStyle"

"2"

"closeChecked"

'vue'

'@/utils/storage'

export

setup

false

false

'block'

'30px'

'30px'

'win-close-tips'

'closeChecked'

if

'win-close'

'closeValue'

else

true

'win-focus'

'win-close-tips'

function

hideModal

if

'closeChecked'

true

'closeValue'

'win-close'

false

return

主进程接受渲染进程消息,initWindow里win赋值后调用,这里要注意的是Mac的处理,Mac在全屏状态下如果隐藏的话,那么会出现软件白屏或黑屏情况,我们这里要先退出全屏然后再隐藏掉。

'electron'

'../config/global'

export

function

'darwin'

'win-close'

if

if

'leave-full-screen'

function

true

false

else

true

else

if

true

else

'win-focus'

if

托盘设置

这里的托盘设置只是为了完成软件的退出功能,故只是简单介绍,其余的功能后面的篇章会详细介绍的。

'electron'

'darwin'

'path'

let

export

function

'16x16.png'

'icon.ico'

${iconType}

if

true

let

'显示vue-cli-electron'

'退出'

if

'click'

'vue-cli-electron'

function

if

if

else

else

false

这里的逻辑还是比较简单的,唯一疑惑的点可能是win.show()前为什么要有个win.minimize(),这里的处理呢是因为hide前如果我们渲染进程有可见的改变(我们这里是让关闭提示的弹窗关闭了),后面再show时会出现一个闪烁的问题,有兴趣的同学可以把win.minimize()注释一下再看一下效果。当然你也可以用下面的处理方式:

'show'

'hide'

补充

Mac系统在处理上有一些逻辑和Windows是不一样的,虽然并没有一个硬性的规定要这样处理,更多的是看个人喜好与约定俗成。

'enter-full-screen'

'disable-pinch'

true

'leave-full-screen'

'disable-pinch'

false

由于我们的窗口实际上就是chromium,故我们可以通过设置chromium的参数来实现,更多的参数请参考链接设置。

点击左下角阅读原文,到

SegmentFault 思否社区

和文章作者展开更多互动和交流,扫描下方”

二维码

“或在“

公众号后台

回复“

入群

”即可加入我们的

技术交流群

,收获更多的技术文章~

- END -


原文链接

作者 | Brad Fitzpatrick、David Crawshaw 译者 | 冬雨 策划 | 蔡芳芳 最初,我们把一个文件当作数据库,将数据转化为 JSON 大对象写入进去,后来,它的速度越来越慢,我们决定进行数据库的迁移,这个过程中我们遇到了一些问题和障碍,但最终我们成功完成了这一次不太可能的数据库迁移。 Brad 加入一家初创公司 大约一年前,当我刚加入 Tailscale(https://tailscale.com/)时,我问 Crawshaw(https://github.com/crawshaw)的第一件事是:“嗯……你们使用的是什么数据库呢?MySQL、PostgreSQL、SQLite?“我知道他喜欢 SQLite。 “一个文本文件,”他回答道。

今日凌晨,Java 开发工具包(JDK)16 正式发布,包含了平台功能的 17 项迭代,将进一步帮助开发者提升工作效率。 J DK 16 将是一个短期支持版本,它将在 9 月的 Java 17 长期支持(LTS)版本之后淘汰,但是它附带了很长的增强和升级列表,本次更新涉及到 17 个功能的迭代 —— 其中两个新功能旨在通过解决内存管理来提高性能: JEP 387:Elastic Metaspace 可以更快地将未使用的 HotSpot 类元数据内存返回给操作系统,减少元空间的占用空间,并简化元空间代码以降低维护成本。 JEP 376:ZGC:并发线程栈处理将 ZGC 线程栈处理从安全点移至并发阶段,以消除允许并发栈处理的重大瓶颈。 JEP