窗口管理 (1)
一、概述
在传统嵌入式场景下,通常只会运行一个UI程序,故相当于单窗口程序,无需桌面服务器的介入;在桌面系统下,对于每一个UI程序而言,它们的行为相比于嵌入式场景仍然没有发生改变,其对接的仍然是窗口,只不过在同一个时刻允许多个UI程序同时运行.
无论如何对于UI程序,它们需要的仅仅是一个窗口,亦或者说是一块用于渲染的画布;UI程序并不关心渲染的程序最终是否呈现在了屏幕上,对于它们而言,将UI程序正确地渲染到画布上,即完成了它们的使命.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-scurY99R-1673008813815)(…/…/image/shell/window_concept.png)]
在传统嵌入场景下, window
可能直接对接到真正意义上的物理屏幕,在 linux
上可能就是 KMS
架构中的 drm
,而在桌面系统场景下,window
大多先是对接到display server
,然后由display server
对接至KMS
;从这里可以知道UI
程序对接的是window
,进一步说是一块内存或者显存而非真正的物理设备;但是从UI
程序设计者而言,window
对其而言又像是一块完整屏幕.
实际上
weston
并非只能对接drm
, 比如对接rdp
实现远程桌面登录,对接EGL
接入OpenGL
的体系等等.
在桌面系统环境下,同一时间可能存在多个UI
程序,意味着显示服务器需要同时管理多个窗口,而大多数情况下是只有一个输出设备的;那么对于显示服务器而言,就需要把多个窗口进行合成,将其按照一定的规则排列组合,组合成一张跟屏幕尺寸相等的画布.
二、适读人群
本文结构大体上分为两个部分,第一部分从用户的角度描述 weston
有关于此的实现,第二部分而从开发者的角度,描述 weston
有关于此部分的具体主体实现,帮助读者理解 weston
有关于窗口管理部分的业务逻辑.
本文基于
weston
分支10.0.2
进行描述, ubuntu 或 deepin 下可以通过sudo apt install weston
安装weston
, 并通过终端启动weston
.
三、分层设计
在 weston
里,窗口是通过分层进行管理的,并且 window
在这里可以简单的理解为 view
视图的概念.
不同的 layer
具有不同的优先级,而同一 layer
的不同 view
则根据前后顺序确认优先级.
在 weston
中, layer
大致上分为 (优先级自上而下):
- WESTON_LAYER_POSITION_FADE : 渐变层,实现窗口切换过渡特效
- WESTON_LAYER_POSITION_CURSOR : 鼠标层
- WESTON_LAYER_POSITION_LOCK : 锁屏层
- WESTON_LAYER_POSITION_TOP_UI : 输入法层 (比如说中文输入法)
- WESTON_LAYER_POSITION_FULLSCREEN : 全屏层
- WESTON_LAYER_POSITION_UI : 系统桌面层
- WESTON_LAYER_POSITION_NORMAL : 应用层
- WESTON_LAYER_POSITION_BOTTOM_UI : 未使用
- WESTON_LAYER_POSITION_BACKGROUND : 背景层
(1) 实例描述
在讲解上面这些抽象的概念之前,先用一些实例来描述一下这些层级的使用.
在刚刚启动 weston
点击左上角的终端符号,应该可以看到:
而在长时间未操作后,应该会进入锁屏状态:
(2) 分层设计的原因
weston
的分层设计其实更多的是从业务的角度去进行考虑的,实际上 compositor
最后时并没有 view
这个概念, layer
和 view
本质上就是一个二维链表的概念,最后面会将这个二维链表转化为只包含 view
的一维链表,按照 layer
的优先级顺序.
对于正常的UI
程序,实际上只能接触到三个不同的 layer
:
- WESTON_LAYER_POSITION_FULLSCREEN
- WESTON_LAYER_POSITION_NORMAL
- WESTON_LAYER_POSITION_MINIMIZE (虚拟图层)
而对于操作系统而言,则可以操作到诸如 WESTON_LAYER_POSITION_UI
、WESTON_LAYER_POSITION_CURSOR
、WESTON_LAYER_POSITION_BACKGROUND
; 相对于UI
程序而言,系统所控制的图层所包含的 view
是相当稳定的,例如 WESTON_LAYER_POSITION_NORMAL
图层通常情况下就只有一个任务栏的 view
.
所以总体来说,不同图层的所有者大致可以分为应用和系统两者;如果在未考虑当前 weston
分层设计的情况下,可能有人会将这个layer
的设计修改为系统图层和应用图层两个图层进行管理,实际上添加部分逻辑处理之后这样做确实也是可以的.
layer
这种设计方案一种可能性是在于虽然可以分为系统图层以及应用图层,但是系统图层并不一定全部都在应用图层之下.
可以看到系统所控制的 layer
部分在应用之上,部分在应用之下,以及 (DESKTOP) UI
在夹在 NORMAL
图层以及 FULLSCREEN
图层之间;甚至于 TOP_UI
还能同时被系统以及应用同时控制 (系统可能是提供软键盘,而应用则是特殊程序如输入法).
另外一个用layer
进行设计的好处就是在于容易控制权限,例如 NORMAL
下图层可以旋转、移动、缩放,但是 FULLSCREEN
下这些行为则是禁止的.
四、分层案例描述
(1) 工作空间
weston
提供工作空间的概念,类似于 window
下的多桌面概念, 默认下 deepin
安装的 weston
是无配置启动的,默认工作空间为 1,要想测试多工作空间,则需要创建 weston.ini
,并运行 weston -c weston.ini
, weston.ini
的配置如下:
# file : weston.ini
[shell]
num-workspaces=6
然后实际运行效果如下:
快捷键为
WIN(SUPER) + Fx
,默认情况下.
这个实际上的实现就是不断地切换 WESTON_LAYER_POSITION_NORMAL
layer 实现的,具体视图如下:
(2) 权限差异
不同图层带来了不同的权限,以 NORMAL
图层进行最大化和取消最大化, FULLSCREEN
图层全屏和取消全屏进行演示:
最大化快捷键为
WIN + SHIFT + M
,全屏快捷键为WIN + SHIFT + F
.
它们反映的一方面是 FULLSCREEN
图层的优先级高于 (DESKTOP) UI
,所以可以遮挡住任务栏;另一个方面则是可活动范围,NORMAL
图层的活动范围是整个屏幕去除(DESKTOP) UI
的部分.
以上即是面向用户的所有描述,之后的章节将结合
weston
的实际代码逻辑讲解部分实例.