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() 方法,也不会造成问题。