OS: Windows 10 (1903)
硬件加速
官方文档有这么一句话:
透明窗口(frameless window)不可调整大小。在某些平台上,将resizable
设置为true
可能会使透明窗口停止工作。
事实上,透明窗体可以调整大小。只要你开启硬件加速,透明窗体的边缘是可以出现调整窗口大小的光标的。然而,如果使用 electron.app.disableHardwareAcceleration()
这个方法关闭硬件加速的话,透明窗体的边缘就无法再被拖动了。同时,关闭硬件加速之后,对透明窗体中的元素的鼠标事件表现也有区别,例如选中文字必须在文字实际笔画的地方,文字中间的空白处竟然无视点选。透明的区域出现了类似于点击穿透的效果。
AeroSnap 效果
所谓的AeroSnap效果就是拖动传统窗口到边缘时,窗体吸附并自动提示最大化。这个效果非常方便,Electron的无边框窗口也支持这个特性。然而,一旦设置了 transparent属性,这个特性就无法得兼了。
研究了一下Electron的具体实现,发现这个问题是受Windows API所限。 使用透明窗体必须设使窗口样式的WS_THICKFRAME对应的这一比特置0,而一旦这一个bit置0,Windows就不认为这是个正常窗口了。因此会失去AeroSnap效果,同理包括最小化/还原时候的缩放效果等。因此,使用透明窗体就意味着某些方面用户体验的打折扣。
任务栏问题
透明窗体没有任务栏。
嵌入libmpv时的问题
Libmpv使用获取到的HWND直接绘制在一个无边框窗口上。然而如果对这个窗口进行 minimize()
或者 maximize()
或者 setFullScreen(true)
,就会导致整个窗体被一个黑色遮罩覆盖(视频仍旧绘制在黑色遮罩下层,我一开始以为是上层的透明窗体失效了,一度在错误的方向研究很久)。同上文关闭硬件加速可以避免这个问题,但是我又需要“拖动透明窗体改变大小”这一特性,我太难了。
后来尝试后发现,就算开启硬件加速,只要不调用 .show()
方法,并且避免经历系统原生的最小化->还原操作,则窗体不会发生问题。隐藏之后使用 .restore()
方法,也不会造成问题。