如何在XFCE中将PyGTK窗口的WindowTypeHint设为DOCK并保持可见
XFCE下PyGTK设置非NORMAL WindowTypeHint导致窗口消失的解决方法
问题背景
在XFCE环境中使用PyGTK 3创建窗口时,一旦将Gdk.WindowTypeHint设置为DOCK等非NORMAL类型,窗口就会直接消失。通过打印属性确认类型hint已正确应用,但无法实现预期效果:像glava那样作为停靠栏固定在桌面角落,触发"显示桌面"时不被最小化,且始终处于其他窗口后方。
问题原因
XFCE的窗口管理器xfwm4对DOCK类型窗口的默认处理逻辑特殊:
- 会将这类窗口标记为桌面组件,可能自动放置到可视区域之外
- 桌面背景层会遮挡
DOCK类型窗口,导致肉眼无法看到 set_keep_below(True)与DOCK类型的属性优先级在xfwm4中存在冲突
修复步骤
- 显式指定窗口位置:强制将窗口放置在屏幕可视区域内(比如右下角)
- 调整属性设置顺序:先设置窗口类型hint,再设置层级属性,避免冲突
- 添加xfwm4专属属性:告知窗口管理器不要将该窗口归为桌面隐藏组件
- 设置窗口粘性:让窗口跟随所有工作区,实现类似停靠栏的跨桌面显示
修改后的完整代码
import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk class MyWindow(Gtk.Window): def __init__(self): super().__init__(title="Dock-like Window") # 先关闭窗口装饰 self.set_decorated(False) # 设置窗口类型为DOCK self.set_type_hint(Gdk.WindowTypeHint.DOCK) # 添加xfwm4专属属性:禁止窗口被桌面隐藏、跳过任务栏 self.get_window().set_property("_NET_WM_STATE_SKIP_SHOWING", True) self.get_window().set_property("_NET_WM_STATE_SKIP_TASKBAR", True) # 设置窗口为粘性(跟随所有工作区) self.stick() # 强制设置窗口位置和大小(右下角,宽200高100) screen = Gdk.Screen.get_default() monitor_geo = screen.get_monitor_geometry(screen.get_primary_monitor()) x_pos = monitor_geo.width - 200 y_pos = monitor_geo.height - 100 self.move(x_pos, y_pos) self.set_size_request(200, 100) # 添加测试按钮 self.button = Gtk.Button(label="Toggle Decorations") self.button.connect("clicked", self.on_button_clicked) self.add(self.button) def on_button_clicked(self, widget): current_state = self.get_decorated() self.set_decorated(not current_state) print(f"Decorated: {not current_state}") print(f"Window Type Hint: {self.props.type_hint}") if __name__ == "__main__": win = MyWindow() # 最后设置始终在窗口后方 win.set_keep_below(True) win.connect("destroy", Gtk.main_quit) win.show_all() Gtk.main()
验证效果
- 运行代码后,窗口会出现在屏幕右下角的可视区域内
- 触发XFCE的"显示桌面"操作时,窗口不会被最小化
- 打开其他应用窗口时,该窗口始终处于后方
- 点击按钮可切换窗口装饰状态,窗口正常显示
内容的提问来源于stack exchange,提问作者Shimo
相关产品推荐
相关产品推荐

