2015-08-14 3 views
0

В настоящее время у меня есть 2 окна X11, которые я хочу синхронизировать. Один накладывает прозрачную графику, а другой показывает видео. У меня в настоящее время есть тот, который накладывает графику, чтобы быть всегда поверх одного из видео, но у меня возникают проблемы с тем, чтобы оба окна находились в одном и том же месте при перемещении. Я ищу событие перемещения окна в документации X11, но я не могу найти его.Переместить событие окна в окне X11

Кроме того, в моем цикле обработки событий я попытался получить местоположение одного из моих окон и переместить другое окно в это место. Это провалилось всякий раз, когда вызывается XGetWindowAttributes, он всегда возвращает x = 0 и y = 0, даже если окно перемещено.

Window win; 
int nxvisuals = 0; 
XVisualInfo visual_template; 
XVisualInfo *visual_list; 
XVisualInfo vinfo; 
Visual *visual; 
int depth; 
Atom wm_state; 
(void)wm_state; 

x_display = XOpenDisplay (NULL); // open the standard display (the primary screen) 

visual_template.screen = DefaultScreen(x_display); 
visual_list = XGetVisualInfo(x_display, VisualScreenMask, &visual_template, &nxvisuals); 

XMatchVisualInfo(x_display, XDefaultScreen(x_display), 32, TrueColor, &vinfo) 

Window parent = XDefaultRootWindow(x_display); 
XSync(x_display, True); 
visual = vinfo.visual; 
depth = vinfo.depth; 

XSetWindowAttributes swa; 
swa.event_mask = ExposureMask | PointerMotionMask | KeyPressMask; 
swa.colormap = XCreateColormap(x_display, XDefaultRootWindow(x_display), visual, AllocNone); 
swa.background_pixel = 0; 
swa.border_pixel = 0; 

win = XCreateWindow ( // create a window with the provided parameters 
      x_display, parent, 
      0, 0, 1024, 576, 0, 
      depth, InputOutput, 
      visual, CWEventMask | CWBackPixel | CWColormap | CWBorderPixel, 
      &swa); 

XSync(x_display, True); 

XSetWindowAttributes xattr; 

xattr.override_redirect = False; 
XChangeWindowAttributes (x_display, win, CWOverrideRedirect, &xattr); 

XWMHints hints; 
hints.input = True; 
hints.flags = InputHint; 
XSetWMHints(x_display, win, &hints); 

XSizeHints *size_hints = XAllocSizeHints(); 
size_hints->flags = PMinSize | PMaxSize | PSize; 
size_hints->min_width = 1024; 
size_hints->max_width = 1024; 
size_hints->min_height = 576; 
size_hints->max_height = 576; 
XSetNormalHints(x_display, win, size_hints); 
XSetWMSizeHints(x_display,win , size_hints, PSize | PMinSize | PMaxSize); 

XMapWindow (x_display , win);     // make the window visible on the screen 
XStoreName (x_display , win , "OpenGL"); // give the window a name 

/* Second window starts here */ 
int cnxvisuals = 0; 
XVisualInfo cvisual_template; 
XVisualInfo *cvisual_list; 
XVisualInfo cvinfo; 
Visual *cvisual; 
int cdepth; 

cvisual_template.screen = DefaultScreen(x_display); 
cvisual_list = XGetVisualInfo(x_display, VisualScreenMask, &cvisual_template, &cnxvisuals); 

XMatchVisualInfo(x_display, XDefaultScreen(x_display), 24, TrueColor, &cvinfo) 

Window child = XDefaultRootWindow(x_display); 
XSync(x_display, True); 
cvisual = cvinfo.visual; 
cdepth = cvinfo.depth; 

XSetWindowAttributes cswa; 
cswa.event_mask = PointerMotionMask | KeyPressMask; 
cswa.colormap = XCreateColormap(x_display, XDefaultRootWindow(x_display), cvisual, AllocNone); 
cswa.background_pixel = 0; 
cswa.border_pixel = 0; 

child = XCreateWindow ( // create a window with the provided parameters 
      x_display, parent, 
      0, 0, 1024, 576, 0, 
      cdepth, InputOutput, 
      cvisual, CWEventMask | CWBackPixel | CWColormap | CWBorderPixel, 
      &cswa); 

XSync(x_display, True); 

XSetWindowAttributes xcattr; 

xcattr.override_redirect = False; 
XChangeWindowAttributes (x_display, child, CWOverrideRedirect, &xcattr); 

XWMHints chints; 
chints.input = True; 
chints.flags = InputHint; 
XSetWMHints(x_display, child, &chints); 

XSetNormalHints(x_display, child, size_hints); 
XSetWMSizeHints(x_display,child , size_hints, PSize | PMinSize | PMaxSize); 

XMapWindow (x_display , child);     // make the window visible on the screen 
XStoreName (x_display , child , "video"); // give the window a name 

XSelectInput(x_display, child, ExposureMask | FocusChangeMask); 

int id = pthread_create(&x11loop, NULL,x11_handle_events,this); 

Вот мои ручки события называют

void* x11_handle_events(void *void_ptr) 
{ 
    Renderer* renderer = static_cast<Renderer*>(void_ptr); 
    renderer->stop = false; 
    XEvent event; 
    XWindowAttributes opengl_attrs; 
    while(!renderer->stop) 
    { 
     XNextEvent(renderer->x_display, &event); 
     switch(event.type) 
     { 
      case Expose: 
      if (event.xexpose.window == renderer->child) 
      { 
       XRaiseWindow(renderer->x_display, renderer->win); 
      } 
      break; 

      case FocusIn: 
      if (event.xfocus.window == renderer->child) 
      { 
       XRaiseWindow(renderer->x_display, renderer->win); 
      } 
      break; 

     } 

     // Make sure both windows are in the same location 
     XGetWindowAttributes(renderer->x_display, renderer->child, &opengl_attrs); 
     XMoveWindow(renderer->x_display, renderer->win, opengl_attrs.x, opengl_attrs.y); 
    } 


    pthread_exit(0); 
    return NULL; 
} 

ответ

1

событие вы ищете, ConfigureNotify

http://tronche.com/gui/x/xlib/events/window-state-change/configure.html

Х-сервер может сообщать о событиях ConfigureNotify для клиентов желающих информация о фактических изменениях состояния окна, таких как размер, положение, граница и стек порядок. Сервер X генерирует этот тип события, когда один из следующих запросов конфигурационными окна, сделанные клиентским приложением фактически завершает:

СНиП

окно перемещается по телефону XMoveWindow().

Элементы x и y установлены в координаты относительно начала родительского окна и указывают положение верхнего левого внешнего угла окна. Элементы width и height установлены на внутренний размер окна, не включая границу. Элемент border_width устанавливается в ширину границы окна в пикселях.

Маска события is iirc StructureNotifyMask.

Менеджер окон может не согласиться с вашим перемещением, хотя ... но если он все еще не работает, оставьте комментарий, и мы посмотрим глубже.

+0

Спасибо, два окна теперь вместе. Одна вещь, которую я заметил, это то, что окна не любят перекрывать друг друга в заголовке. Окно будет следовать за другим чуть ниже строки заголовка. Есть ли способ предотвратить это? – TheBlueMan

+0

Причина этого заключается в том, что строка заголовка - это другое окно, добавленное диспетчером окон, а затем окно вашего приложения переписано. Поэтому, возможно, вы можете запросить расположение * родителя * вашего окна приложения. (Вот почему вы, вероятно, получили 0,0 в вашей первой попытке.) Http://tronche.com/gui/x/xlib/window-information/XQueryTree.html может получить родительское окно ... но вы также можете просто взломать его, вычитая высоту строки заголовка, или еще лучше, чтобы ваше оверлейное окно вообще не украшало названия, поэтому оно находится в нужном месте. Это делается через атом EWMH .... –

+0

SetWMHints может это сделать. Я не помню прямо сейчас и должен бежать, попробуйте найти окно xlib make без заголовка, и ссылку здесь, если вы его найдете. –

Смежные вопросы