我正在尝试创建一个Linux应用程序 - 在这种情况下是一个屏幕保护程序 - 它证明非常很难找到关于使窗口全屏的简单任务的信息。即使现有屏保的代码也没有提到他们如何管理它,我还没有看到任何明显的功能,如XRemoveDecoration()
。
经过多次摸索后,我确实设法创建了一个与桌面大小相同的窗口,其中包含:
Window win = DefaultRootWindow(disp);
XWindowAttributes getWinAttr;
XGetWindowAttributes(disp, win, &getWinAttr);
win = XCreateWindow(disp, win, 0, 0, getWinAttr.width, getWinAttr.height, 0, vInfo->depth, InputOutput, vInfo->visual, CWBorderPixel|CWColormap|CWEventMask|CWOverrideRedirect, &winAttr );
但这并没有做任何事情来摆脱标题栏和边框。我知道有一种方法,显然 - 但是我还没有找到任何指向那个方向的东西,它不依赖于其他一些大型库被抛到顶层(现有的屏保不会使用)。
编辑:请不要删除帖子中的信息。有一个很好的理由我明确指出现有的屏保没有使用可选库,这是因为我在过去的大部分时间里一直在分析源代码。
我选择了最直接回答问题的答案,并且适用于一般的应用程序。
如果您发现此问题正在研究xscreensavers ......同样仍然适用。是的,xscreensaver有自己的API - 这很复杂,实际上涉及编写更多行代码(是的,认真的)。如果您想在屏幕保护程序中使用OpenGL,则需要通过另一个 API(xlockmore,一个竞争系统)和一个将其转换为xscreensaver的兼容层。
但是,xscreensaver能够运行任何程序,该程序可以使用虚拟根窗口(查看vroot.h)作为屏幕保护程序。所以我的建议就是这样做 - 你将拥有更多控制权,没有限制性API,以及更高的可移植性。 (我看过的一个例子甚至可以编译为Linux或Windows,使用相同的文件!)
答案 0 :(得分:13)
一种方法是绕过窗口管理器:
XSetWindowAttributes wa;
wa.override_redirect = True;
XCreateWindow( ..., &wa );
答案 1 :(得分:4)
您缺少的信息是,屏幕保护程序不负责全屏显示。屏幕保护程序守护程序将管理屏幕保护程序窗口,将其放入专用的屏幕保护程序窗口层并使其全屏显示。
因此,对于编写屏幕保护程序,您可以清楚地看到它。如果您要编写全屏游戏,则必须设置“覆盖重定向”属性以防止窗口被WM管理并使其覆盖整个屏幕。
答案 2 :(得分:2)
实现它的最佳和最简单的方法是使用适用于最新窗口管理器的ICCCM规范atom
。只需使用以下代码:
Atom wm_state = XInternAtom (display, "_NET_WM_STATE", true );
Atom wm_fullscreen = XInternAtom (display, "_NET_WM_STATE_FULLSCREEN", true );
XChangeProperty(display, window, wm_state, XA_ATOM, 32,
PropModeReplace, (unsigned char *)&wm_fullscreen, 1);
您的窗口可能是透明的,如果是这样,只需在您需要的地方使用XSetBackground()
功能即可。
答案 3 :(得分:1)
我发现freeglut全屏效果很好,即使在内部托管基于着色器的opengl应用程序时也是如此。这里是被调用的内部代码(X11分支......)。 HTH
#define _NET_WM_STATE_TOGGLE 2
static int fghResizeFullscrToggle(void)
{
XWindowAttributes attributes;
if(glutGet(GLUT_FULL_SCREEN)) {
/* restore original window size */
SFG_Window *win = fgStructure.CurrentWindow;
fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE;
fgStructure.CurrentWindow->State.Width = win->State.OldWidth;
fgStructure.CurrentWindow->State.Height = win->State.OldHeight;
} else {
/* resize the window to cover the entire screen */
XGetWindowAttributes(fgDisplay.Display,
fgStructure.CurrentWindow->Window.Handle,
&attributes);
/*
* The "x" and "y" members of "attributes" are the window's coordinates
* relative to its parent, i.e. to the decoration window.
*/
XMoveResizeWindow(fgDisplay.Display,
fgStructure.CurrentWindow->Window.Handle,
-attributes.x,
-attributes.y,
fgDisplay.ScreenWidth,
fgDisplay.ScreenHeight);
}
return 0;
}
static int fghEwmhFullscrToggle(void)
{
XEvent xev;
long evmask = SubstructureRedirectMask | SubstructureNotifyMask;
if(!fgDisplay.State || !fgDisplay.StateFullScreen) {
return -1;
}
xev.type = ClientMessage;
xev.xclient.window = fgStructure.CurrentWindow->Window.Handle;
xev.xclient.message_type = fgDisplay.State;
xev.xclient.format = 32;
xev.xclient.data.l[0] = _NET_WM_STATE_TOGGLE;
xev.xclient.data.l[1] = fgDisplay.StateFullScreen;
xev.xclient.data.l[2] = 0; /* no second property to toggle */
xev.xclient.data.l[3] = 1; /* source indication: application */
xev.xclient.data.l[4] = 0; /* unused */
if(!XSendEvent(fgDisplay.Display, fgDisplay.RootWindow, 0, evmask, &xev)) {
return -1;
}
return 0;
}
static int fghToggleFullscreen(void)
{
/* first try the EWMH (_NET_WM_STATE) method ... */
if(fghEwmhFullscrToggle() != -1) {
return 0;
}
/* fall back to resizing the window */
if(fghResizeFullscrToggle() != -1) {
return 0;
}
return -1;
}
#endif /* TARGET_HOST_POSIX_X11 */
答案 4 :(得分:1)
答案 5 :(得分:1)
绝对不难。您只需将正确的原子添加到右侧列表中,如here所述。