Я использую Ubuntu 12.04 в виртуальной машине.
Верхний левый никогда не бывает правильным. Ширина и высота верны примерно в 90% случаев.
XMoveWindow
и друзья не влияют на визуализированное положение окна.
Источник:
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/X.h>
int main(int argc, char **argv)
{
Display *disp = XOpenDisplay(0);
GLint attr[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GX_DOUBLEBUFFER, None};
XVisualInfo *vinfo = glXChooseVisual(disp,0,attr);
Window rootWnd = DefaultRootWindow(disp);
XSetWindowAttributes setWndAttr = {0};
setWndAttr.colormap = XCreateColormap(disp,rootWnd,vinfo->visual,AllocNone);
setWndAttr.event_mask =
ExposureMask|
StructureNotifyMask;
Window wnd = XCreateWindow(
disp,rootWnd,
64,64, // can be ignored (asinine)
512,512,
0,vinfo->depth,
InputOutput,
vinfo->visual,
CWColormap|CWEventMask,
&setWndAttr
);
XStoreName(disp,wnd,"What is this crap?");
XMapWindow(disp,wnd);
// WMs allowed to completely ignore these, too?
//XMoveWindow(disp,wnd,128,128);
//XMoveResizeWindow(disp,wnd,128,128,256,256);
Atom closeWndAtom = XInternAtom(disp,"WM_DELETE_WINDOW",0);
XSetWMProtocols(disp,wnd,&closeWndAtom,1);
GLXContext ctx = glCreateContext(disp,vinfo,0,GL_TRUE);
glXMakeCurrent(disp,wnd,ctx);
bool run = true;
XEvent evt;
while(run){
XNextEvent(disp,&evt);
switch(evt.type){
case Expose:
{
XWindowAttributes wndAttr;
XGetWindowAttributes(disp,wnd,&wndAttr);
// these are NEVER correct (0,0 most of the time)
printf("%i, %i\n",wndAttr.x,wndAttr.y);
// these are correct, most of the time
//
// occasionally, either width or height will be 0
glViewport(0,0,wndAttr.width,wndAttr.height);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1,0,0);
glVertex2f(0,0);
glColor3f(0,1,0);
glVertex2f(1,0);
glColor3f(0,0,1);
glVertex2f(0,1);
glEnd();
glXSwapBuffers(disp,wnd);
}break;
case ClientMessage:
{
run = false;
}break;
}
}
glXDestroyContext(disp,ctx);
XDestroyWindow(disp,wnd);
XCloseDisplay(disp);
return 0;
}
Примечание. Возможна ошибка с двумя орфографическими ошибками, так как вставка изнутри виртуальной машины не отформатировалась бы правильно. В результате мне пришлось его перепечатывать.
Потому что здесь нужна ясность: мне все равно, что оконный менеджер делает с должностью, которую я ему предоставляю, меня интересует при получении эта информация из оконного менеджера достоверно. Положение, которое мне дано, не соответствует позиции окна на экране. Например: окно появляется в правом нижнем углу экрана, и мне возвращаются координаты (0,0)
, Перемещение окна с помощью мыши не меняет то, что XGetWindowAttributes
возвращается.
Я думаю, что одним из вариантов является использование XTranslateCoordinates:
XTranslateCoordinates(dpy,
wnd, // get position for this window
root_window, // something like macro: DefaultRootWindow(dpy)
0, 0, // local left top coordinates of the wnd
&dest_x, // these is position of wnd in root_window
&dest_y, // ...
&unused);
Вы также можете использовать XGetGeometry вместо XGetWindowAttributes чтобы получить левую, верхнюю, ширину и высоту рисования. Насколько я знаю XGetWindowAttributes звонки XGetGeometry чтобы получить некоторые из атрибутов.
Похоже, вы запрашиваете информацию об окне из события Expose, которое может не иметь новейшей информации об окне в данный момент. Используйте событие ConfigureNotify и его свойства, чтобы получить обновленную позицию и размер:
// you need to have this in your event mask(you've already got that):
EVENT_MASK |= StructureNotifyMask;
// in your event loop
// ...
case ConfigureNotify: // resize or move event
printf("x: %d, y:%d, width: %d, height: %d\n",
event.xconfigure.x,
event.xconfigure.y,
event.xconfigure.width,
event.xconfigure.height);
break;
Я знаю, что я некропостер, но я также искал ответ и обнаружил, что неправильные координаты связаны с оконным менеджером.
{
case ConfigureNotify :
printf("%d, %d : %u, %u\n",
event.xconfigure.x, event.xconfigure.y,
event.xconfigure.width, event.xconfigure.height);
break;
}
# Moving window
353, 100 : 791, 600
363, 113 : 791, 600
# Changing window size
1, 24 : 791, 600 << Pay attention to this
363, 113 : 791, 600
363, 113 : 791, 600
Для получения дополнительной информации вам необходимо прочитать ICCCM (4.1.5. Настройка окна, 4.2.3. Перемещение окна, 4.2.4. Изменение размера окна) https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.5