我正在用这个把头发拔出来.
我使用以下程序以编程方式更改屏幕的分辨率:
int FindBestVideoMode(int screen, unsigned int &width, unsigned int &height)
{
int modeCount;
XF86VidModeModeInfo** modes;
if (XF86VidModeGetAllModeLines(display, screen, &modeCount, &modes))
{
int bestMode = -1;
int bestMatch = INT_MAX;
for(int i = 0; i < modeCount; i ++)
{
int match = (width - modes[i]->hdisplay) *
(width - modes[i]->hdisplay) +
(height - modes[i]->vdisplay) *
(height - modes[i]->vdisplay);
if(match < bestMatch)
{
bestMatch = match;
bestMode = i;
}
}
width = modes[bestMode]->hdisplay;
height = modes[bestMode]->vdisplay;
XFree(modes);
return bestMode;
}
return -1;
}
void SwitchVideoMode(int screen, int mode)
{
if (mode >= 0)
{
int modeCount;
XF86VidModeModeInfo** modes;
if (XF86VidModeGetAllModeLines(display, screen, &modeCount, &modes))
{
if (mode < modeCount)
{
XF86VidModeSwitchToMode(display, screen, modes[mode]);
XF86VidModeSetViewPort(display, screen, 0, 0);
XFlush(display);
}
XFree(modes);
}
}
}
void SwitchToBestVideoMode(int screen, unsigned int &width, unsigned int &height)
{
SwitchVideoMode(screen, FindBestVideoMode(screen, width, height));
}
void RestoreVideoMode(int screen)
{
auto iVideoMode = DefaultVideoModes.Find(screen);
if (iVideoMode != nullptr)
{
XF86VidModeSwitchToMode(display, screen, &iVideoMode->value);
XF86VidModeSetViewPort(display, screen, 0, 0);
XFlush(display);
}
}
一切正常.然后,使用以下命令将窗口置于全屏模式:
XEvent e;
e.xclient.type = ClientMessage;
e.xclient.window = window;
e.xclient.message_type = _NET_WM_STATE;
e.xclient.format = 32;
e.xclient.data.l[0] = 2; // _NET_WM_STATE_TOGGLE
e.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", True);
e.xclient.data.l[2] = 0; // no second property to toggle
e.xclient.data.l[3] = 1;
e.xclient.data.l[4] = 0;
XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &e);
XMoveResizeWindow(display, window, 0, 0, width, height);
现在的问题是,在进行程序分辨率更改时,窗口的大小调整为桌面分辨率的大小,而不是新设置的分辨率.我所期望的,乃至真正的追求,是将窗口的大小调整为新分辨率的大小.
我希望我只是在这里误解一些简单的东西,但是对此的任何想法都将不胜感激.我不想在这里使用外部库,例如SDL.
谢谢!
解决方法:
您遇到的问题是,您依赖窗口管理器正确放置窗口.不幸的是,并非所有WM都关心XF86VidMode或RandR.在视频模式更改后创建全屏窗口的规范解决方案是将窗口创建为无边界和“替代重定向”,这样它就不会受到WM的管理,然后将其明确定位为覆盖(0, 0)至(vidmode宽度,vidmode高度).