2011-06-17 123 views
5

我目前正在尝试启用alt-tab从我的全屏Xlib OpenGL窗口中退出,但遇到一些困难。我试过XUnmapWindow(..),这种工作,但解决方案不会重置(除非我应该手动做这件事),我的Xlib窗口不会显示为最小化窗口(即我不能将alt-tab回到窗口中,尽管该应用似乎仍在后台运行)。尽量减少全屏Xlib OpenGL窗口

接下来我尝试的是将窗口从全屏切换到窗口模式(即在窗口模式下重新创建窗口),但很明显,我宁愿不必这样做。

我正在收听FocusOutFocusIn事件,并且FocusOut似乎在我使用alt-tab时被调用,但我不确定如何让我的应用程序正确地最小化。如果在调用FocusOut事件时我的代码中没有执行任何操作,则我的应用程序不会执行任何操作(即,我无法将窗口最小化)。

任何帮助,将不胜感激!

编辑:不幸的是,我一直无法让X Windows正确地将全屏窗口最小化。因此,要解决此问题,我已决定在全屏窗口中输入destroy(),然后在窗口模式下输入create()新窗口。似乎运作良好。

+0

这个信息有点旧,但是当X Window处于全屏模式时,好像XIconifyWindow不起作用。这里是链接:http://www.rdesktop.org/archive/2001/msg00981.html。它提到了一些解决方法,我可能会在某些时候尝试。 – Jarrett 2011-06-17 22:35:41

+0

感谢@VJo和@datenwolf的帮助! – Jarrett 2011-06-17 22:37:19

+0

你在用什么? gnome还是kde? – 2011-06-18 07:42:44

回答

4

XUnmapWindow()完全从显示屏上移除窗口。最小化窗口通过 EMWH ICCCM状态发生,以便窗口管理器知道窗口仍以某种形式存在。 而且就像你已经认为你负责重置屏幕分辨率。这是BTW在Windows中非常相似。

编辑:

尽量减少在Xlib的一个窗口与XIconifyWindow完成,这会照顾确立正确的ICCCM属性,将取消该窗口。这两者都必须完成与WM的正确交互。然而,X11只定义了方法,而不是策略,所以当取消映射全屏窗口时,您还负责重置屏幕分辨率,就像我上面已经写过的那样。

在旁注:我建议您根本不要更改分辨率,但是如果可用,则渲染到目标大小的Framebuffer对象,并将最终结果映射到完整的本机屏幕尺寸。如果您将其与原生分辨率文本/ HUD叠加层结合使用(我假设这是用于游戏或类似的),您可以获得更高的质量并节省分辨率切换。你甚至可以把这个与桌面截图结合起来并逐渐淡入你的内容。

EDIT 2供参考XIconifyWindow只是一个辅助/便利功能,它的源代码是

/* 
* This function instructs the window manager to change this window from 
* NormalState to IconicState. 
*/ 
Status XIconifyWindow(Display *dpy, Window w, int screen) 
{ 
    XClientMessageEvent ev; 
    Atom prop; 

    prop = XInternAtom(dpy, "WM_CHANGE_STATE", False); 
    if(prop == None) 
    return False; 

    ev.type = ClientMessage; 
    ev.window = w; 
    ev.message_type = prop; 
    ev.format = 32; 
    ev.data.l[0] = IconicState; 
    return XSendEvent(dpy, RootWindow(dpy, screen), False, 
      SubstructureRedirectMask|SubstructureNotifyMask, 
      (XEvent *)&ev); 
} 
+0

嘿@datenwolf,感谢您的信息。你知道如何编码吗? :)我遇到很多麻烦,试图让这个工作。不幸的是,@ VJo的解决方案不起作用,并且我在网上找到示例非常困难。我会很感激你能提供的任何帮助。 – Jarrett 2011-06-17 18:55:33

+0

嗨@datenwolf,我担心你会说'XIconifyWindow',因为我试过没有成功。我称之为'XIconifyWindow(display_,window_,screen_);'我在哪里处理'FocusOut'事件(我已经确认IS在我全屏显示时被调用)。我已经在两台电脑(一台运行Ubuntu 10.04和一台运行Linux Mint 10)上尝试过这种方法,但无济于事。 – Jarrett 2011-06-17 20:24:03

+0

@Jarret:请问你正在使用哪一个窗口管理器? – datenwolf 2011-06-18 10:12:49

1

你可以尝试做这样的:

XEvent xev; 
Atom wm_state  = XInternAtom(dpy, "_NET_WM_STATE", False); 
Atom wm_hide_win = XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False); 

memset(&xev, 0, sizeof(xev)); 
xev.type = ClientMessage; 
xev.xclient.window = win; 
xev.xclient.message_type = wm_state; 
xev.xclient.format = 32; 
xev.xclient.data.l[0] = _NET_WM_STATE_ADD; 
xev.xclient.data.l[1] = wm_hide_win; 

XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureNotifyMask, &xev); 

编辑

如果您有权访问gnome API,则可以使用wnck_window_minimize(),或查看该函数的源代码。

+0

嗨@VJo,谢谢你的回复。我在处理'FocusOut'事件时输入了您的代码,但不幸的是,没有任何反应。我也尝试了使用'xev.xclient.data.l [0] = _NET_WM_STATE_ADD; xev.xclient.data.l [1] = WM_STATE_MAXIMIZED_VERT; xev.xclient.data.l [2] = WM_STATE_MAXIMIZED_HORZ;'无效。我需要做些什么才能使这些事件得到处理? – Jarrett 2011-06-17 18:59:55

+0

窗口图标化做得有点不同,看看我提取的源代码片段http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/Iconify.c – datenwolf 2011-06-18 10:46:36

+0

嗯..我宁愿避免如果可以的话,使用Gnome特定的代码。 – Jarrett 2011-06-18 22:22:35