2011-06-17 129 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