- 问题背景
公司软件有一个功能,在PPT播放时,我们软件悬浮窗口需要在WPS幻灯片上层显示,方便客户操作按钮。在window 上我们设置了窗口的topmost 所以能够显示在最前面。如下图所示:
但是在软件适配国产操作系统Linux统信和麒麟在wps播放时,悬浮窗不能显示到最前面
最终解决办法
把WPS播放窗口设置为其他普通窗口的子级窗口
解决过程
首先分析了下,可能解决的技术方案如下:
- 通过窗口ID 设置层级
- 通过窗口ID 设置父子级关系
- 取消wps播放窗口的全屏
最开始考虑的是把WPS播放窗口,取消全屏状态,我们软件悬浮窗口就可以显示到最上层。命令行如下:
wmctrl -ir <wps播放窗口id> -b remove,fullscreen
通过验证发现是可行的,也达到了预期。
然而,在开发的过程中发现,这样设置后当时是生效了,但是(万事就怕但是啊…)只要PPT播放下一页我们的悬浮窗口又被挡住了。发现这个问题后又开始了其他方案研究。其中考虑过很多技术方案,包括使用WPS nodeJS插件等等。
最终的解决方法刚刚说了:”把WPS播放窗口设置为其他普通窗口的子级窗口
“。
步骤如下:
-
创建一个自己的非全屏的普通窗口把任务栏的工具条和窗口标题栏隐藏。
-
获取wps播放窗口和自己创建窗口的id
-
把WPS播放的窗口通过
命令行
设置为自己创建的普通窗口的子级
命令行如下:
xdotool windowreparent <wps窗口id> <自己创建的普通窗口id>
安装上述的办法验证后(包括翻页)都没问题。
但是有个弊端PPT播放时不是全屏了,能看到任务栏。这个解决这个弊端。我们在把WPS窗口设置为普通窗口子级时,调用命令行,先把任务栏设置为自动隐藏。 PPT播放结束后,又通过命令行把任务栏设置为一直显示。
命令如下:
隐藏任务栏
dbus-send --print-reply --type=method_call --dest=com.deepin.dde.daemon.Dock /com/deepin/dde/daemon/Dock org.freedesktop.DBus.Properties.Set string:'com.deepin.dde.daemon.Dock' string:'HideMode' variant:int32:1
显示任务栏
dbus-send --print-reply --type=method_call --dest=com.deepin.dde.daemon.Dock /com/deepin/dde/daemon/Dock org.freedesktop.DBus.Properties.Set string:'com.deepin.dde.daemon.Dock' string:'HideMode' variant:int32:0
以上就是解决这个问题的全过程~~~~~!
在研究此解决方案时,了解到的命令行使用
获取窗口ID
终端运行 :xwininfo
然后在点击你想要获取的窗口,就可以获取到改窗口ID
设置某个窗口层级为最底层
wmctrl -i -r xxxxxx -b add,below
- 设置 a 窗口为 b 创建的子窗口(子窗口就可以显示在父窗口上层)
xdotool windowreparent <a窗口id> <b窗口id>
- 查看某个窗口的属性设置
xprop -id <窗口id> | grep _NET_WM_STATE
- 设置窗口的属性
xprop -id <窗口ID> -f _NET_WM_STATE 32a -set _NET_WM_STATE '属性值多个使用逗号链接'
_NET_WM_STATE 是一个由 EWMH(Extended Window Manager Hints)定义的窗口属性,用于在 X Window System 中表示窗口的各种状态。这个属性是一个ATOM类型数组,其中每个元素都是一个表示窗口状态的ATOM。
_NET_WM_STATE 属性通常包含如下几种类型的窗口状态:
_NET_WM_STATE_MODAL: 窗口是模态的,意味着它阻止了其他窗口的交互。
_NET_WM_STATE_STAYS_ON_TOP: 窗口始终显示在其他窗口的顶部。
_NET_WM_STATE_FULLSCREEN: 窗口处于全屏状态。
_NET_WM_STATE_MAXIMIZED_HORZ: 窗口在水平方向上被最大化。
_NET_WM_STATE_MAXIMIZED_VERT: 窗口在垂直方向上被最大化。
_NET_WM_STATE_HIDDEN: 窗口被隐藏。
_NET_WM_STATE_SHADED: 窗口被卷起(只显示标题栏)。
_NET_WM_STATE_SKIP_TASKBAR: 窗口不在任务栏中显示。
_NET_WM_STATE_SKIP_PAGER: 窗口不在切换器中显示。
要使用 xprop 查看窗口的 _NET_WM_STATE 属性,可以使用以下命令:
bash
xprop -id <窗口ID> _NET_WM_STATE
将 <窗口ID> 替换为你想查询的窗口的实际ID。
如果你想要修改窗口的 _NET_WM_STATE 属性,可以使用 xprop 的 -f(指定属性名)和 -set(设置属性值)选项。例如,要将窗口设置为全屏并且置顶,可以使用:
xprop -id <窗口ID> -f _NET_WM_STATE 32a -set _NET_WM_STATE '_NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_STAYS_ON_TOP, _NET_WM_STATE_SKIP_TASKBAR, _NET_WM_STATE_FULLSCREEN'
请注意,设置窗口状态属性通常需要窗口管理器的支持,不是所有的窗口管理器都会响应这些属性。此外,某些状态可能需要特定的用户交互或应用程序逻辑来生效。
_NET_WM_STATE 属性的值是一个32位的ATOM数组,其中每个ATOM都是窗口状态的一个标识符。这些状态可以组合使用,以表示窗口的多个状态。