Lets see how to create a child window inside a given window 'win'.
/* this variable will store the handle of the newly created child window. */ Window child_win;
/* these variables will store the window's width and height. */ int child_win_width = 50; int child_win_height = 30;
/* these variables will store the window's location. */ /* position of the child window is top-left corner of the */ /* parent window. - 0,0. */ int child_win_x = 0; int child_win_y = 0;
/* This variable will store the newly created property. */ XTextProperty window_title_property;
/* This is the string to be translated into a property. */ char* window_title = "hello, world";
/* translate the given string into an X property. */ int rc = XStringListToTextProperty(&window_title, 1, &window_title_property); /* check the success of the translation. */ if (rc == 0) { fprintf(stderr, "XStringListToTextProperty - out of memory\n"); exit(1); }
/* assume that window_title_property is our XTextProperty, and is */ /* defined to contain the desired window title. */ XSetWMName(display, win, &window_title_property);
为了设置我们的窗口的图标化名字,我们将用相同的方式使用函数XSetWMIconName()。
/* this time we assume that icon_name_property is an initialized */ /* XTextProperty variable containing the desired icon name. */ XSetWMIconName(display, win, &icon_name_property);
/* pointer to the size hints structure. */ XSizeHints* win_size_hints = XAllocSizeHints(); if (!win_size_hints) { fprintf(stderr, "XAllocSizeHints - out of memory\n"); exit(1); }
/* initialize the structure appropriately. */ /* first, specify which size hints we want to fill in. */ /* in our case - setting the minimal size as well as the initial size. */ win_size_hints->flags = PSize | PMinSize; /* next, specify the desired limits. */ /* in our case - make the window's size at least 300x200 pixels. */ /* and make its initial size 400x250. */ win_size_hints->min_width = 300; win_size_hints->min_height = 200; win_size_hints->base_width = 400; win_size_hints->base_height = 250;
/* pass the size hints to the window manager. */ XSetWMNormalHints(display, win, win_size_hints);
/* finally, we can free the size hints structure. */ XFree(win_size_hints);
/* pointer to the WM hints structure. */ XWMHints* win_hints = XAllocWMHints(); if (!win_hints) { fprintf(stderr, "XAllocWMHints - out of memory\n"); exit(1); }
/* initialize the structure appropriately. */ /* first, specify which hints we want to fill in. */ /* in our case - setting the state hint as well as the icon position hint. */ win_hints->flags = StateHint | IconPositionHint; /* next, specify the desired hints data. */ /* in our case - make the window's initial state be iconized, */ /* and set the icon position to the top-left part of the screen. */ win_hints->initial_state = IconicState; win_hints->icon_x = 0; win_hints->icon_y = 0;
/* pass the hints to the window manager. */ XSetWMHints(display, win, win_hints);
/* finally, we can free the WM hints structure. */ XFree(win_hints);
/* include the definition of the bitmap in our program. */ #include "icon.bmp";
/* pointer to the WM hints structure. */ XWMHints* win_hints;
/* load the given bitmap data and create an X pixmap containing it. */ Pixmap icon_pixmap = XCreateBitmapFromData(display, win, icon_bitmap_bits, icon_bitmap_width, icon_bitmap_height); if (!icon_pixmap) { fprintf(stderr, "XCreateBitmapFromData - error creating pixmap\n"); exit(1); }
/* allocate a WM hints structure. */ win_hints = XAllocWMHints(); if (!win_hints) { fprintf(stderr, "XAllocWMHints - out of memory\n"); exit(1); }
/* initialize the structure appropriately. */ /* first, specify which size hints we want to fill in. */ /* in our case - setting the icon's pixmap. */ win_hints->flags = IconPixmapHint; /* next, specify the desired hints data. */ /* in our case - supply the icon's desired pixmap. */ win_hints->icon_pixmap = icon_pixmap;
/* pass the hints to the window manager. */ XSetWMHints(display, win, win_hints);
/* finally, we can free the WM hints structure. */ XFree(win_hints);
/* resize the window to width=200 and height=300 pixels. */ XResizeWindow(display, win, 200, 300);
我们可以合并移动和改变尺寸操作为一个操作,使用函数XMoveResizeWindow():
/* move the window to location x=20 y=30, and change its size */ /* to width=100 and height=150 pixels. */ XMoveResizeWindow(display, win, 20, 30, 100, 150);
/* iconify our window. Make its icon window appear on the same */ /* screen as our window (assuming we created our window on the */ /* default screen). */ XIconifyWindow(display, win, DefaultScreen(display));
/* de-iconify our window. the icon window will be automatically */ /* unmapped by this operation. */ XMapWindow(display, win);
/* this variable will contain the attributes of the window. */ XWindowAttributes win_attr;
/* query the window's attributes. */ Status rc = XGetWindowAttributes(display, win, &win_attr);
结构体XWindowAttributes包含了很多数据域,下面是它的一部分:
int x, y; 窗口的位置,相对于它的父窗口。 int width, height; 窗口的宽和高(单位,像素)。 int border_width 窗口的边框宽度 Window root; 根窗口,也就是我们的窗口在那个窗口里被显示了。 这个函数有些问题,就是它返回的是相对于父窗口的位置。这对一些窗口的操作(例如XMoveWindow)是没有什么意义的。为了解决这个问题,我们需要使用两步的操作。首先,我们找出窗口的父窗口的ID。然后我们在使用它来确定窗口相对于屏幕的坐标。我们使用两个前面没有介绍的函数来完成这个计算,XQueryTree()和XTranslateCoordinates()。这两个函数的功能超出了我们的需要,所以我们只关注我们需要的:
/* these variables will eventually hold the translated coordinates. */ int screen_x, screen_y; /* this variable is here simply because it's needed by the */ /* XTranslateCoordinates function below. For its purpose, see the */ /* manual page. */ Window child_win;
/* this variable will store the ID of the parent window of our window. */ Window parent_win; /* this variable will store the ID of the root window of the screen */ /* our window is mapped on. */ Window root_win; /* this variable will store an array of IDs of the child windows of */ /* our window. */ Window* child_windows; /* and this one will store the number of child windows our window has. */ int num_child_windows;
/* finally, make the query for the above values. */ XQueryTree(display, win, &root_win, &parent_win, &child_windows, &num_child_windows);
/* we need to free the list of child IDs, as it was dynamically allocated */ /* by the XQueryTree function. */ XFree(child_windows);
/* next, we make the coordinates translation, from the coordinates system */ /* of the parent window, to the coordinates system of the root window, */ /* which happens to be the same as that of the screen, since the root */ /* window always spans the entire screen size. */ /* the 'x' and 'y' values are those previously returned by the */ /* XGetWindowAttributes function. */ XTranslateCoordinates(display, parent_win, root_win, win_attr.x, win_attr.y, &screen_x, &screen_y, &child_win);
/* at this point, screen_x and screen_y contain the location of our original */ /* window, using screen coordinates. */