【问题标题】:Xlib multiple windows events handlingXlib 多窗口事件处理
【发布时间】:2014-05-17 03:17:35
【问题描述】:

我是 xlib 的新手。我有一个程序,它有两个显示器和两个窗口。我的问题是当用户调整窗口大小时内容消失了。

当一个人可以在它们上画画时,两个窗户都会转动。我有每个窗口轮到的while循环来获取事件并处理它们。我的问题是,如果我尝试使用 XNextEvent() 监听非活动窗口的事件,程序将随机运行。我在下面粘贴了其中一个 while 循环。

非常感谢您的帮助。

while(drawThings2) {
  XNextEvent( dpy2, & e2 );// Get event

  switch( e2.type ){
  case ButtonPress :
     switch( e2.xbutton.button ){
     case Button1 :
        //Start drawing
        break;
     case Button2 :
     case Button3 :
        break;
     }
     break;
  case ButtonRelease :
  switch( e2.xbutton.button ){
      case Button1 :
         //Draw things
        break;
  }
  break;
  case MotionNotify :
     if( drawing && (e2.xmotion.state & Button1Mask) )
     {
        //Draw things
     }
  break;
  case Expose :
     if( e2.xexpose.count >= 0 )
     {
         //Redraw content if current window is resized by user
     }
  break;
  }

  if(XCheckWindowEvent( dpy, w, ExposureMask, & e )>0)
  {
        //Redraw the second window's content if the second window is resized by user
  }
}

【问题讨论】:

  • 一种可能性是拥有单独的线程,每个线程处理一个显示连接。

标签: c++ linux xlib x11


【解决方案1】:

您需要从您的两个 X11 Display-s 复用输入(和输出)。换句话说,你需要一个真正的单一event loop 使用像poll(2) 这样的多路复用系统调用(你不应该嵌套两个循环)。

我建议使用真正的工具包(如QtGTK),它将为您提供复杂的事件循环(Qt 中的QApplication 及其exec,Gtk 中的gtk_main;这两个工具包为它们的事件循环提供了许多较低级别的接口)。

如果您想继续使用原始 Xlib 调用(这很痛苦),请轮询两个显示文件描述符(通过 XConnectionNumber 获得),然后使用 XPeekEvent(3)(在可读文件描述符上)。

有关poll 的事件循环示例,请参阅this answer(并根据您的需要进行调整)。

【讨论】:

  • 常用工具包是否支持使用多个显示器?
  • 使用 GTK,您可能需要使用较低级别的 GdkDisplay & GdkVisual & GdkWindow。
【解决方案2】:

感谢您的帮助!我将开始学习 Qt。

我通过使用一个大的 while 循环解决了我的问题。在 while 循环中,每个显示都有两个 if(XPending(display)) 。该程序非常简单,所以我给出了一个简单的答案,而且我还是大一新生,所以我真的不明白投票发生了什么。这是我的解决方案:

while( !Finished ){
   //If drawing to display1
  if(XPending(dpy)) {
      XEvent e;
      XNextEvent( dpy, & e ); // Get event
      switch( e.type ){
      case ButtonPress :
         switch( e.xbutton.button ){
         case Button1 :
            //Start drawing         
            break;
         case Button2 :
         case Button3 :
            break;
         }
         break;
      case ButtonRelease :
      switch( e.xbutton.button ){
          case Button1 :
            //Draw things
            break;
      }
      break;
      case MotionNotify :
         if( drawing && (e.xmotion.state & Button1Mask) )
         {
            //Draw things
         }
      break;
      case Expose :
         if( e.xexpose.count == 0 ) {
            //Redraw content if current window is resized by user
         }
         break;
      }//switch
  }//if


  else if(XPending(display2)) { //if drawing to display2
    //same things as display1 but changed to display2
  }
}//while

【讨论】:

  • 谢谢。我正在编写一个独立于平台的小型 GUI 系统。我从来没有意识到每个窗口使用不同的显示值。
猜你喜欢
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 2019-04-03
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多