4

次のコードは、正しいサイズw、hのウィンドウを開きますが、正しい位置x、yでは開きません。

#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
using namespace std;

int main(int argc, char* argv[]){
  Display *display; // A connection to X server
  int screen_number;
  Window canvas_window;
  unsigned long white_pixel;
  unsigned long black_pixel;

  display = XOpenDisplay(NULL);    // Connect X server by opening a display

  if(!display){
    cerr<<"Unable to connect X server\n";
    return 1;
  }

  screen_number = DefaultScreen(display);
  white_pixel = WhitePixel(display, screen_number);
  black_pixel = BlackPixel(display, screen_number);


  int x=0, y=100, w=300, h=400;

  canvas_window = XCreateSimpleWindow(display,
                                      RootWindow(display, screen_number),
                                      x,y,  // top left corner
                                      w,h,  // width and height
                                      2,    // border width
                                      black_pixel,
                                      white_pixel);

  XMapWindow(display, canvas_window);    // Map canvas window to display
  XSync(display, False);

  cin >> x;   // just so that the program does not end
}

これをg++xwindowtest.cpp -lX11でコンパイルしました。ここで、g ++はバージョン4.6.2であり、Debian GNU/Linuxで実行されました。

4

3 に答える 3

8

上記の解決策はある程度正しいですが、完全ではありません。

デスクトップに新しいトップレベル ウィンドウを作成し、アプリケーションのトップレベル ウィンドウ内に新しい (子) ウィンドウを作成するには、同じ XCreateSimpleWindow() 呼び出しを使用しますが、実際の動作は異なる場合があります。

アプリケーション内で新しい子ウィンドウを作成するときは、あなたが責任を負い、新しいウィンドウに指定した原点座標 (親ウィンドウの原点に相対的) とサイズが適用されます。つまり、ウィンドウは目的の場所に移動します。

ただし、デスクトップに新しいトップレベル ウィンドウを作成する場合は、Motif、KDE、Gnome などの厄介なウィンドウ マネージャーを処理する必要があります。これは、トップレベル ウィンドウを作成して境界線 (「装飾」) を追加するときに介入します。 、タイトル、おそらくアイコンなど。さらに言えば、デフォルトでは、ほとんどの場合、要求された原点座標を無視し、新しいウィンドウを、要求された場所ではなく、必要な場所に配置します。XMoveWindow() で移動できるのは、(どこかに) マップされている場合のみです。

これを回避するには、ウィンドウマネージャに「いいえ、ウィンドウを置きたい場所ではなく、私が尋ねる場所に置いてほしい」と尋ねるか、X11 で言えば「ヒント」を使用します。これは、次の順序で行います。

(1) XSizeHints 構造体を定義します。(2) 指定したいもののマスクを使用して、この構造体のフラグ ビットを設定します。 (3) 関連する引数を設定します。 (4) 新しく作成されたウィンドウで (マップする前に) XSetNormalHints() を呼び出します。

したがって、C コードでは次のようにします。

XSizeHints    my_hints = {0};

my_hints.flags  = PPosition | PSize;     /* I want to specify position and size */
my_hints.x      = wanted_x_origin;       /* The origin and size coords I want */
my_hints.y      = wanted_y_origin;
my_hints.width  = wanted_width;
my_hints.height = wanted_height;

XSetNormalHints(disp, new_window, &my_hints);  /* Where new_window is the new window */

次に、それをマッピングすると、希望する場所に配置されることを願っています。

于 2013-02-26T12:47:27.313 に答える
1

私は通常、最初に宣言し、XSizeHints x、y座標などをに割り当てhintsます。

xウィンドウを作成するときに行うことができます

 XCreateSimpleWindow(display, 
                     DefaultRootWindow(display), 
                     hints.x, hints.y, 
                     hints.width,hints.height, 
                     borderWidth, 
                     blackPixel, whitePixel)

これは、100%正しいウィンドウの場所で常に機能します。

于 2013-02-12T18:02:44.103 に答える
0

私も同じ問題を抱えていました。X11から始めたばかりです。おそらく、より経験のある他の人は、これが機能する理由を明確にすることができます (XCreateSimpleWindow に x、y を指定するだけでは機能しません)。

これが私の修正です:

disp はディスプレイ、win0 は canvas_window です。

XMoveWindow(disp, win0, 200, 200);

XSync (disp, FALSE);


 ..... do something .....

XMoveWindow(disp, win0, 0, 0);

XSync (disp, FALSE);

... do something

このコード スニペットを実行すると、ウィンドウが移動します。要求 (移動など) が適切に処理されるように、XSync によって XMoveWindow に従う必要があります。

于 2012-08-07T19:46:17.553 に答える