Electron 中的 Kiosk 窗口
最近在产品中用到了 Electron 中的 Kiosk 模式,记录一下要点。
什么是 Kiosk 模式?
Kiosk 模式是一种专门为限制用户操作而设计的应用运行模式,通常用于构建锁定的全屏应用程序,禁止用户访问系统其他功能或退出应用。在这种模式下,应用程序占据整个屏幕,并且用户无法通过常见的方式(如键盘快捷键、窗口控制按钮等)退出或切换到其他应用。
Kiosk 模式的主要用途是为用户提供一个专注且受限的操作环境,避免对系统的其他部分产生干扰。
哪些场景下需要使用 Kiosk 模式?
Kiosk 模式被广泛应用于以下场景:
- 公共信息亭:自助服务终端,如银行 ATM、自助点餐机、自助售票机。
- 展览展示:在博物馆、展览会、零售店中,用于展示信息或广告内容的屏幕。
- 教育场景:限制学生只能使用特定的教学应用,避免访问其他不必要的内容。
- 会议或演讲:锁定演示内容,避免误操作或退出。
- 数字标牌:作为广告屏幕或公告牌,循环播放内容。
当然,我在开发的是日常效率软件,并不属于以上场景。我用到 Kiosk 模式的场景主要如下。
图几截图软件
我开发并维护着一个截图软件图几,它有三种截图模式:全屏截图、窗口截图、区域截图。
其中区域截图的交互方式是:用户点击截图按钮(或按下截图快捷键),先生成当前屏幕的截图,随后显示一个全屏无边框窗口,在窗口中显示将刚刚生成的屏幕截图,同时允许用户在窗口上进行框选等操作。
这个无边框窗口就需要使用 Kiosk 模式,以免用户无意中切换窗口。当然,等用户完成或取消截图时,需要再退出或关闭对应的 Kiosk 窗口。
WonderPen 写作软件
WonderPen 写作软件最近添加了小黑屋模式,进入这种模式后,软件将全屏显示,屏蔽一切干扰,在完成预设的写作目标之前,将无法退出或切换到其他软件。
这个禁止退出的小黑屋,自然也使用了 Kiosk 模式。
Electron 中的 Kiosk 模式
在 Electron 中,将一个窗口设为 Kiosk 模式非常简单,在创建窗口时设置 kisok
属性为 true
即可。
有时,我们的窗口在创建时需要以普通模式显示,然后再在一定条件下切换为 Kiosk 模式,只需用类似下面的代码切换即可:
win.setKiosk(flag)
其中 flag
是一个布尔值。
你还可以使用 win.isKiosk()
方法判断当前窗口是否为 Kiosk 模式。
在实践过程中,我发现很多时候只设置 Kiosk 属性还不太够,还需要设置 frame
等属性。以下是一个示例:
const win = new BrowserWindow({
// 其他属性...
closable: false,
maximizable: false,
minimizable: false,
resizable: false,
fullscreen: false,
fullscreenable: false,
frame: false,
skipTaskbar: true,
alwaysOnTop: true,
useContentSize: true.
autoHideMenuBar: true.
movable: false.
thickFrame: false.
titleBarStyle: 'default',
paintWhenInitiallyHidden: false,
roundedCorners: false,
enableLargerThanScreen: true,
acceptFirstMouse: true,
kiosk: true,
// 其他属性...
})
即使这样设置之后,在 macOS 上有时仍会出现 Docker 栏和顶部系统菜单栏出现在 Kiosk 窗口上方的情况,因此还需要进一步设置 alwaysOnTop 的属性为 screen-saver
,代码如下:
win.setAlwaysOnTop(true, 'screen-saver', 1)
在 Windows 和 macOS 中,alwaysOnTop 的窗口有多种极别,按层级由低到高分别是:
- normal
- floating
- torn-off-menu
- modal-panel
- main-menu
- status
- pop-up-menu
- screen-saver
如果只是简单地 win.setAlwaysOnTop(true)
,则窗口的级别只是 floating
,仍有可能被其他系统组件遮挡。
另外需要注意,在 macOS 下,太高的级别会挡住系统自带输入法的候选字窗口,如果你的 Kiosk 窗口需要用户输入,并且可能使用系统自带输入法的话,这个级别不能高于 modal-panel
。
一些其他注意点
Kiosk 模式只对当前窗口有效,一个窗口只能覆盖一个屏幕,若用户有多个显示器,则需先检测显示器数量,然后创建多个 Kiosk 窗口分别覆盖。
设置 Kiosk 模式后,用户仍可以使用 Cmd+Q
这样的快捷键退出应用,因此需要在代码中监听窗口的 close
事件,并检查是否处在 Kiosk 状态,如是则阻止退出。代码类似下面这样:
win.on('close', async (e: Electron.Event) => {
if (win.isKiosk()) {
e.preventDefault()
return
}
// 其他逻辑
}
Windows 下退出 Kiosk 模式后,窗口的大小可能会变成全屏大小,如希望退出时恢复原大小,可以在进入 Kiosk 模式之前先记住窗口大小,退出后再设置为原大小。
Kiosk 模式并不能阻止用户重启计算机。如果希望重启计算机后能自动恢复 Kiosk 状态,可以将软件设置为随系统启动,并且启动时自动进入 Kiosk 模式。
评论: