Следующий фрагмент кода инициирует подструктуру перенаправлением на корневом окне и пытается изменить размер новых детей:X Несущая Перенаправление Messes Up Tool/Menu Bars
#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), но запутывает различные части в более сложных графических интерфейсах. Например, emacs появляется без панели инструментов, и панель меню при необходимости не перерисовывает. Firefox отлично выглядит, но нажатие кнопки «open menu» не имеет видимого эффекта. Изменение кода для соблюдения конфигурационных запросов устраняет некоторые проблемы (кнопка «открыть меню» все еще не работает), но это, конечно же, побеждает всю цель. Все, что я хочу в этот момент, - это возможность изменять размер и изменять положение окон, не нарушая их. Что мне не хватает?
[UPDATE]
По предложению Инго, вот обновленная версия, которая не задевает окна с 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;
}
Нет заметную разницы, насколько исходная проблема затронута.
Одна вещь, которую вы точно делаете неправильно, игнорирует override_redirect. Я бы посоветовал вам взглянуть на простой код оконного менеджера, что-то вроде dwm. –
Я думал, что override_redirect был для X-сервера. Я проверю это, как только смогу. dwm слишком загадочно для новичка, подобного мне. – user3026691
dwm довольно просто, просто проверьте, как он обрабатывает различные типы событий. Вы получите запросы на карту для всех окон, но в качестве диспетчера окон вы не должны прикасаться к переопределению окон переадресации. В частности, не изменяйте их размер и т. Д. –