[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    Re: [Kwin] Re: Embedding multible java applets and focus problems
From:       Leon Bottou <leon () bottou ! org>
Date:       2003-10-13 20:35:21
[Download RAW message or body]

On Monday 13 October 2003 03:59 pm, Koos Vriezen wrote:
> On Mon, 13 Oct 2003, Leon Bottou wrote:
> > Maybe the save set thing should not be enabled when autoDelete is
> > false... A brutal destruction of the embedding window would then cause a
> > brutal destruction of the embedded window as well.
>
> Makes sense, if one kills konqueror or a crash, seeing all those floating
> plugins isn't that nice. However it is a change with current
> behaviour...otoh this is an exceptional case..or are there apps freeing
> an embed app by killing the host :) out there?

As it is now, the XAddToSaveSet is only performed 
when the embedding is achieved by calling embed().  
Not when using QXEmbed::embedClientIntoWindow().   
Nobody noticed...

By the way your patch says
+    if (!d->autoDelete)
+        XAddToSaveSet( qt_xdisplay(), w );

It should be the other way around:
+    if (d->autoDelete)
+        XAddToSaveSet( qt_xdisplay(), w );

setAutoDelete(true) causes the QXEmbed destructor to properly unmap 
the window and send the WM_DELETE_WINDOW message.  This is the default.
You'd get the behavior you want by saying setAutoDelete(false)...

The attached patch is a compilation of everything discussed in this thread,
including the change to reduce the blinking effect, the move of the
second part of the embed() code into the ReparentNotify section of
x11_event, and some additional comments...

It compiles.  It needs testing.

- L.




["qxembed.cpp.diff" (text/x-diff)]

*** qxembed.cpp.~1.44.~	2003-09-25 14:16:54.000000000 -0400
--- qxembed.cpp	2003-10-13 16:24:04.000000000 -0400
***************
*** 51,56 ****
--- 51,76 ----
  
  #include "qxembed.h"
  
+ /* WARNING: 
+    Breaking QXEmbed breaks most of KDE.
+    To make things worse, QXEmbed is a very 
+    intricate code with inadequate comments.
+ 
+    Suggested readings:
+    - Xlib Reference Manual  
+        (sections about focus, reparenting, window management)
+    - ICCCM Manual
+        (window management)
+    - XEMBED specification 
+        (http://www.freedesktop.org/Standards/xembed-spec)
+    - XPLAIN and XEMBED.
+        <http://lists.kde.org/?w=2&r=1&s=qxembed+variants&q=t>
+    - Accumulated community knowledge.
+        <http://lists.kde.org/?w=2&r=1&s=qxembed&q=t>
+        <http://lists.kde.org/?l=kde-devel&w=2&r=1&s=qxembed&q=b>
+        <http://lists.kde.org/?l=kfm-devel&w=2&r=1&s=qxembed&q=b>
+ */
+ 
  #ifndef XK_ISO_Left_Tab
  #define XK_ISO_Left_Tab                                 0xFE20
  #endif
***************
*** 678,683 ****
--- 698,704 ----
          send_xembed_message( window, XEMBED_FOCUS_OUT );
      }
      if ( !((QPublicWidget*) topLevelWidget())->topData()->embedded )
+       if ( qApp->activeWindow() == topLevelWidget() )
          XSetInputFocus( qt_xdisplay(), d->focusProxy->winId(), 
                          RevertToParent, qt_x_time );
  }
***************
*** 735,749 ****
      kdDebug() << "************************** Embed "<< QString("0x%1").arg(w, 0, \
16) << " into " << QString("0x%1").arg(winId(), 0, 16) << " window=" << \
QString("0x%1").arg(window, 0, 16) << " **********" << endl;   if (!w)
          return;
!     XAddToSaveSet( qt_xdisplay(), w );
!     bool has_window =  w == window;
      window = w;
      if ( !has_window ) {
          if ( !wstate_withdrawn(window) ) {
              XWithdrawWindow(qt_xdisplay(), window, qt_xscreen());
              QApplication::flushX();
              while (!wstate_withdrawn(window))
!                 ;
          }
          Window parent;
          get_parent(w, &parent);
--- 756,770 ----
      kdDebug() << "************************** Embed "<< QString("0x%1").arg(w, 0, \
16) << " into " << QString("0x%1").arg(winId(), 0, 16) << " window=" << \
QString("0x%1").arg(window, 0, 16) << " **********" << endl;   if (!w)
          return;
! 
!     bool has_window =  (w == window);
      window = w;
      if ( !has_window ) {
          if ( !wstate_withdrawn(window) ) {
              XWithdrawWindow(qt_xdisplay(), window, qt_xscreen());
              QApplication::flushX();
              while (!wstate_withdrawn(window))
!                 USLEEP(1000);
          }
          Window parent;
          get_parent(w, &parent);
***************
*** 758,785 ****
              kdDebug() << QString(">>> Loop %1: reparent of 0x%2 into 0x%3 \
failed").arg(i).arg(w, 0, 16).arg(winId(), 0, 16) << endl;  USLEEP(1000);
          }
-         QApplication::syncX();
-     }
- 
-     XResizeWindow(qt_xdisplay(), w, width(), height());
-     XMapRaised(qt_xdisplay(), window);
-     sendSyntheticConfigureNotifyEvent();
-     extraData()->xDndProxy = w;
- 
-     if ( parent() ) {
-         QEvent * layoutHint = new QEvent( QEvent::LayoutHint );
-         QApplication::postEvent( parent(), layoutHint );
-     }
-     windowChanged( window );
-     if (d->xplain) {
-         checkGrab();
-         if ( hasFocus() )
-             sendFocusMessage(window, XFocusIn, NotifyNormal, NotifyPointer );
-     } else {
-         send_xembed_message( window, XEMBED_EMBEDDED_NOTIFY, 0, (long) winId() );
-         send_xembed_message( window, isActiveWindow() ? XEMBED_WINDOW_ACTIVATE : \
                XEMBED_WINDOW_DEACTIVATE );
-         if ( hasFocus() )
-             send_xembed_message( window, XEMBED_FOCUS_IN );
      }
  }
  
--- 779,784 ----
***************
*** 829,835 ****
          } else if ( e->xreparent.parent == winId() ){
              // we got a window
              window = e->xreparent.window;
!             embed( window );
          }
          break;
      case ButtonPress:
--- 828,858 ----
          } else if ( e->xreparent.parent == winId() ){
              // we got a window
              window = e->xreparent.window;
!             if (autoDelete())
!               XAddToSaveSet(qt_xdisplay(), window);
!             // finish the embedding process
!             XResizeWindow(qt_xdisplay(), window, width(), height());
!             XMapRaised(qt_xdisplay(), window);
!             sendSyntheticConfigureNotifyEvent();
!             extraData()->xDndProxy = window;
!             if ( parent() ) {
!                 QEvent * layoutHint = new QEvent( QEvent::LayoutHint );
!                 QApplication::postEvent( parent(), layoutHint );
!             }
!             windowChanged( window );
!             if (d->xplain) {
!                 checkGrab();
!                 if ( hasFocus() )
!                     sendFocusMessage(window, XFocusIn, NotifyNormal, NotifyPointer \
                );
!             } else {
!                  send_xembed_message( window, XEMBED_EMBEDDED_NOTIFY, 0, (long) \
                winId() );
!                  if (isActiveWindow())
!                      send_xembed_message( window, XEMBED_WINDOW_ACTIVATE);
!                  else
!                      send_xembed_message( window, XEMBED_WINDOW_DEACTIVATE);
!                  if ( hasFocus() )
!                      send_xembed_message( window, XEMBED_FOCUS_IN );
!             }
          }
          break;
      case ButtonPress:
***************
*** 1016,1026 ****
--- 1039,1074 ----
      return QSize( minw, minh );
  }
  
+ /*!  
+   Sets the flag indicating what shoud be done with the embedded window when
+   the embedding window is destroyed.
+ 
+   When the flag is \a true (the default), the embedded window is unmapped and
+   safely reparented into the root window.  Although the window remains
+   invisible, the embedded application receives an ICCCM message \a
+   WM_DELETE_WINDOW.  This should cause the application to exit cleanly.
+ 
+   When the flag is \a false, the embedded window is brutally destroyed.
+  */
+ 
  void QXEmbed::setAutoDelete( bool b)
  {
+     if (window && d->autoDelete != b) {
+         if (b)
+             XAddToSaveSet(qt_xdisplay(), window);
+         else
+             XRemoveFromSaveSet(qt_xdisplay(), window);
+     }
      d->autoDelete = b;
  }
  
+ /*!
+   Returns the value of flag indicating what shoud be done with the embedded
+   window when the embedding window is destroyed.
+   
+   \sa setAutoDelete()
+  */
+ 
  bool QXEmbed::autoDelete() const
  {
      return d->autoDelete;



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic