次のコードは、ルート ウィンドウで下位構造のリダイレクトを開始し、新しい子のサイズを変更しようとします。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#define TERMINAL "urxvt"
void start(char* what)
{
if(!fork())
{
char* const args[] = {"/bin/sh", "-c", what, NULL};
execvp("/bin/sh", args);
exit(1);
}
}
int main()
{
Display* dpy;
Window root;
XSetWindowAttributes setAttribs;
XEvent ev;
if(!(dpy = XOpenDisplay(NULL)))
exit(1);
root = XDefaultRootWindow(dpy);
XSelectInput(dpy, root, SubstructureNotifyMask | SubstructureRedirectMask);
XGrabKey(dpy, XKeysymToKeycode(dpy, XK_T), Mod4Mask, root, True, GrabModeAsync, GrabModeAsync);
while(1)
{
XNextEvent(dpy, &ev);
switch(ev.type)
{
case MapRequest:
XMapWindow(dpy, ev.xmaprequest.window);
XMoveResizeWindow(dpy, ev.xmaprequest.window, 0, 0, 800, 600);
XSync(dpy, False);
break;
case KeyPress:
start(TERMINAL);
break;
default:
break;
}
}
XUngrabKey(dpy, AnyKey, AnyModifier, root);
XSync(dpy, False);
return 0;
}
これは、単純な端末 ( TERMINAL 定数で定義されたものを Mod4+t で起動できます) では問題なく動作するように見えますが、より複雑な GUI ではさまざまな部分が台無しになります。たとえば、emacs はツールバーなしで表示され、メニュー バーは必要に応じて再描画されません。Firefox は問題ないように見えますが、[メニューを開く] ボタンを押しても目に見える効果はありません。構成要求を尊重するようにコードを変更すると、問題の一部は修正されますが ([メニューを開く] ボタンは機能しません)、もちろん、目的全体が無効になります。この時点で私が望むのは、ウィンドウを壊さずにウィンドウのサイズと位置を変更できることだけです。私は何が欠けていますか?
[アップデート]
Ingo の提案に従って、override_redirect が設定されたウィンドウに触れない更新版を次に示します。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#define TERMINAL "urxvt"
void start(char* what)
{
if(!fork())
{
char* const args[] = {"/bin/sh", "-c", what, NULL};
execvp("/bin/sh", args);
exit(1);
}
}
int hasOverrideRedirect(Display* dpy, Window win)
{
XWindowAttributes wa;
if(!XGetWindowAttributes(dpy, win, &wa))
return 0;
return wa.override_redirect;
}
int main()
{
Display* dpy;
Window root;
XSetWindowAttributes setAttribs;
XEvent ev;
if(!(dpy = XOpenDisplay(NULL)))
exit(1);
root = XDefaultRootWindow(dpy);
XSelectInput(dpy, root, SubstructureNotifyMask | SubstructureRedirectMask);
XGrabKey(dpy, XKeysymToKeycode(dpy, XK_T), Mod4Mask, root, True, GrabModeAsync, GrabModeAsync);
while(1)
{
XNextEvent(dpy, &ev);
switch(ev.type)
{
case MapRequest:
XMapWindow(dpy, ev.xmaprequest.window);
if(!hasOverrideRedirect(dpy, ev.xmaprequest.window))
{
XMoveResizeWindow(dpy, ev.xmaprequest.window, 0, 0, 800, 600);
XSync(dpy, False);
}
break;
case KeyPress:
start(TERMINAL);
break;
case ConfigureRequest:
if(hasOverrideRedirect(dpy, ev.xconfigurerequest.window))
{
XConfigureRequestEvent *e2 = &ev.xconfigurerequest;
XWindowChanges wc;
wc.x = e2->x;
wc.y = e2->y;
wc.width = e2->width;
wc.height = e2->height;
wc.border_width = e2->border_width;
wc.sibling = e2->above;
wc.stack_mode = e2->detail;
XConfigureWindow(dpy, e2->window, e2->value_mask, &wc);
}
default:
break;
}
}
XUngrabKey(dpy, AnyKey, AnyModifier, root);
XSync(dpy, False);
return 0;
}
元の問題に関する限り、顕著な違いはありません。