1

VM で 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;
}

注: VM 内からの貼り付けは正しくフォーマットされないため、スペル ミスが 2 にある可能性があります。その結果、私はそれを再入力しなければなりませんでした。

編集:

ここでは明快さが必要なので、指定した位置でウィンドウマネージャーが何をするかは気にしません。ウィンドウマネージャーからこの情報を確実に取得することに関心があります。与えられた位置は、画面上のウィンドウのレンダリングされた位置に対応していません。例: 画面の右下にウィンドウが表示され、返された座標は(0,0)です。XGetWindowAttributesマウスを使用してウィンドウを移動しても、返されるものは変わりません。

4

3 に答える 3

1

オプションの 1 つは、 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);

XGetWindowAttributesの代わりにXGetGeometryを使用して、ドローアブルの左、上、幅、および高さを取得することもできます。私が知る限り、XGetWindowAttributesはXGetGeometryを呼び出していくつかの属性を取得します。

于 2013-03-14T12:16:33.583 に答える
0

私はネクロポスターですが、答えを探していたところ、誤った座標がウィンドウマネージャーに関連していることがわかりました。

    {
    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

于 2017-01-02T08:31:31.333 に答える