cacaa8c
qt-bugs@ issue : none
cacaa8c
bugs.kde.org number : none
cacaa8c
applied: no
cacaa8c
author: Lubos Lunak <l.lunak@kde.org>
cacaa8c
cacaa8c
This patch adds support for window types used for compositing (popup menu, dropdown menu,
cacaa8c
tooltip, combobox, dnd).
cacaa8c
cacaa8c
--- src/kernel/qdnd_x11.cpp.sav	2007-05-25 18:56:23.000000000 +0200
cacaa8c
+++ src/kernel/qdnd_x11.cpp	2007-05-31 10:30:58.000000000 +0200
cacaa8c
@@ -261,6 +261,7 @@ public:
cacaa8c
 	QWidget(QApplication::desktop()->screen( screen ),
cacaa8c
 		0, WStyle_Customize | WStyle_Tool | WStyle_NoBorder | WX11BypassWM ), oldpmser( 0 ), oldbmser( 0 )
cacaa8c
     {
cacaa8c
+    x11SetWindowType( X11WindowTypeDND );
cacaa8c
     }
cacaa8c
 
cacaa8c
     void setPixmap(QPixmap pm, QPoint hot)
cacaa8c
@@ -1221,6 +1222,7 @@ void QDragManager::move( const QPoint & 
cacaa8c
 	// recreate the pixmap on the new screen...
cacaa8c
 	delete qt_xdnd_deco;
cacaa8c
 	qt_xdnd_deco = new QShapedPixmapWidget( screen );
cacaa8c
+        qt_xdnd_deco->x11SetWindowTransient( dragSource->topLevelWidget());
cacaa8c
 	if (!QWidget::mouseGrabber()) {
cacaa8c
 	    updatePixmap();
cacaa8c
 	    qt_xdnd_deco->grabMouse();
cacaa8c
@@ -1774,6 +1776,7 @@ bool QDragManager::drag( QDragObject * o
cacaa8c
 
cacaa8c
     dragSource = (QWidget *)(object->parent());
cacaa8c
 
cacaa8c
+    qt_xdnd_deco->x11SetWindowTransient( dragSource->topLevelWidget());
cacaa8c
     qApp->installEventFilter( this );
cacaa8c
     qt_xdnd_source_current_time = qt_x_time;
cacaa8c
     XSetSelectionOwner( QPaintDevice::x11AppDisplay(), qt_xdnd_selection,
cacaa8c
--- src/kernel/qapplication_x11.cpp.sav	2007-05-29 16:24:58.000000000 +0200
cacaa8c
+++ src/kernel/qapplication_x11.cpp	2007-05-31 10:30:58.000000000 +0200
cacaa8c
@@ -268,6 +268,11 @@ Atom		qt_net_wm_window_type_menu	= 0;
cacaa8c
 Atom		qt_net_wm_window_type_utility	= 0;
cacaa8c
 Atom            qt_net_wm_window_type_splash    = 0;
cacaa8c
 Atom            qt_net_wm_window_type_override	= 0;	// KDE extension
cacaa8c
+Atom            qt_net_wm_window_type_dropdown_menu = 0;
cacaa8c
+Atom            qt_net_wm_window_type_popup_menu    = 0;
cacaa8c
+Atom            qt_net_wm_window_type_tooltip   = 0;
cacaa8c
+Atom            qt_net_wm_window_type_combo     = 0;
cacaa8c
+Atom            qt_net_wm_window_type_dnd       = 0;
cacaa8c
 Atom		qt_net_wm_frame_strut		= 0;	// KDE extension
cacaa8c
 Atom		qt_net_wm_state_stays_on_top	= 0;	// KDE extension
cacaa8c
 Atom		qt_net_wm_pid		= 0;
cacaa8c
@@ -1920,6 +1925,11 @@ void qt_init_internal( int *argcptr, cha
cacaa8c
 	qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_UTILITY", &qt_net_wm_window_type_utility );
cacaa8c
 	qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_SPLASH", &qt_net_wm_window_type_splash );
cacaa8c
 	qt_x11_intern_atom( "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", &qt_net_wm_window_type_override );
cacaa8c
+	qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", &qt_net_wm_window_type_dropdown_menu );
cacaa8c
+	qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_POPUP_MENU", &qt_net_wm_window_type_popup_menu );
cacaa8c
+	qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_TOOLTIP", &qt_net_wm_window_type_tooltip );
cacaa8c
+	qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_COMBO", &qt_net_wm_window_type_combo );
cacaa8c
+	qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_DND", &qt_net_wm_window_type_dnd );
cacaa8c
 	qt_x11_intern_atom( "_KDE_NET_WM_FRAME_STRUT", &qt_net_wm_frame_strut );
cacaa8c
 	qt_x11_intern_atom( "_NET_WM_STATE_STAYS_ON_TOP",
cacaa8c
 			    &qt_net_wm_state_stays_on_top );
cacaa8c
--- src/kernel/qwidget_x11.cpp.sav	2007-05-25 18:56:23.000000000 +0200
cacaa8c
+++ src/kernel/qwidget_x11.cpp	2007-05-31 10:30:58.000000000 +0200
cacaa8c
@@ -125,6 +125,11 @@ extern Atom qt_net_wm_window_type_menu;
cacaa8c
 extern Atom qt_net_wm_window_type_utility;
cacaa8c
 extern Atom qt_net_wm_window_type_splash;
cacaa8c
 extern Atom qt_net_wm_window_type_override;
cacaa8c
+extern Atom qt_net_wm_window_type_dropdown_menu;
cacaa8c
+extern Atom qt_net_wm_window_type_popup_menu;
cacaa8c
+extern Atom qt_net_wm_window_type_combo;
cacaa8c
+extern Atom qt_net_wm_window_type_dnd;
cacaa8c
+extern Atom qt_net_wm_window_type_tooltip;
cacaa8c
 extern Atom qt_net_wm_pid;
cacaa8c
 extern Atom qt_net_wm_user_time;
cacaa8c
 extern Atom qt_enlightenment_desktop;
cacaa8c
@@ -448,10 +453,6 @@ void QWidget::create( WId window, bool i
cacaa8c
 					 x11Colormap() );
cacaa8c
 #endif // QT_NO_XFTFREETYPE
cacaa8c
 
cacaa8c
-    // NET window types
cacaa8c
-    long net_wintypes[7] = { 0, 0, 0, 0, 0, 0, 0 };
cacaa8c
-    int curr_wintype = 0;
cacaa8c
-
cacaa8c
     // NET window states
cacaa8c
     long net_winstates[6] = { 0, 0, 0, 0, 0, 0 };
cacaa8c
     int curr_winstate = 0;
cacaa8c
@@ -473,7 +474,6 @@ void QWidget::create( WId window, bool i
cacaa8c
 	if ( testWFlags(WStyle_Splash) ) {
cacaa8c
             if (qt_net_supports(qt_net_wm_window_type_splash)) {
cacaa8c
                 clearWFlags( WX11BypassWM );
cacaa8c
-                net_wintypes[curr_wintype++] = qt_net_wm_window_type_splash;
cacaa8c
 	    } else {
cacaa8c
 		setWFlags( WX11BypassWM | WStyle_Tool | WStyle_NoBorder );
cacaa8c
 	    }
cacaa8c
@@ -482,27 +482,22 @@ void QWidget::create( WId window, bool i
cacaa8c
 	    mwmhints.decorations = 0L;
cacaa8c
 	    mwmhints.flags |= (1L << 1); // MWM_HINTS_DECORATIONS
cacaa8c
 
cacaa8c
-	    if ( testWFlags( WStyle_NoBorder ) ) {
cacaa8c
-		// override netwm type - quick and easy for KDE noborder
cacaa8c
-		net_wintypes[curr_wintype++] = qt_net_wm_window_type_override;
cacaa8c
-	    } else {
cacaa8c
-		if ( testWFlags( WStyle_NormalBorder | WStyle_DialogBorder ) ) {
cacaa8c
-		    mwmhints.decorations |= (1L << 1); // MWM_DECOR_BORDER
cacaa8c
-		    mwmhints.decorations |= (1L << 2); //  MWM_DECOR_RESIZEH
cacaa8c
-		}
cacaa8c
+	    if ( testWFlags( WStyle_NormalBorder | WStyle_DialogBorder ) ) {
cacaa8c
+		mwmhints.decorations |= (1L << 1); // MWM_DECOR_BORDER
cacaa8c
+		mwmhints.decorations |= (1L << 2); //  MWM_DECOR_RESIZEH
cacaa8c
+	    }
cacaa8c
 
cacaa8c
-		if ( testWFlags( WStyle_Title ) )
cacaa8c
-		    mwmhints.decorations |= (1L << 3); // MWM_DECOR_TITLE
cacaa8c
+	    if ( testWFlags( WStyle_Title ) )
cacaa8c
+		mwmhints.decorations |= (1L << 3); // MWM_DECOR_TITLE
cacaa8c
 
cacaa8c
-		if ( testWFlags( WStyle_SysMenu ) )
cacaa8c
-		    mwmhints.decorations |= (1L << 4); // MWM_DECOR_MENU
cacaa8c
+	    if ( testWFlags( WStyle_SysMenu ) )
cacaa8c
+		mwmhints.decorations |= (1L << 4); // MWM_DECOR_MENU
cacaa8c
 
cacaa8c
-		if ( testWFlags( WStyle_Minimize ) )
cacaa8c
-		    mwmhints.decorations |= (1L << 5); // MWM_DECOR_MINIMIZE
cacaa8c
+	    if ( testWFlags( WStyle_Minimize ) )
cacaa8c
+		mwmhints.decorations |= (1L << 5); // MWM_DECOR_MINIMIZE
cacaa8c
 
cacaa8c
-		if ( testWFlags( WStyle_Maximize ) )
cacaa8c
-		    mwmhints.decorations |= (1L << 6); // MWM_DECOR_MAXIMIZE
cacaa8c
-	    }
cacaa8c
+	    if ( testWFlags( WStyle_Maximize ) )
cacaa8c
+		mwmhints.decorations |= (1L << 6); // MWM_DECOR_MAXIMIZE
cacaa8c
 
cacaa8c
 	    if (testWFlags(WStyle_Tool)) {
cacaa8c
 		wsa.save_under = True;
cacaa8c
@@ -522,23 +517,6 @@ void QWidget::create( WId window, bool i
cacaa8c
 	    }
cacaa8c
 	}
cacaa8c
 
cacaa8c
-	// ### need a better way to do this
cacaa8c
-	if (inherits("QPopupMenu")) {
cacaa8c
-	    // menu netwm type
cacaa8c
-	    net_wintypes[curr_wintype++] = qt_net_wm_window_type_menu;
cacaa8c
-	} else if (inherits("QToolBar")) {
cacaa8c
-	    // toolbar netwm type
cacaa8c
-	    net_wintypes[curr_wintype++] = qt_net_wm_window_type_toolbar;
cacaa8c
-	} else if (testWFlags(WStyle_Customize) && testWFlags(WStyle_Tool)) {
cacaa8c
-	    // utility netwm type
cacaa8c
-	    net_wintypes[curr_wintype++] = qt_net_wm_window_type_utility;
cacaa8c
-	}
cacaa8c
-
cacaa8c
-	if (dialog) // dialog netwm type
cacaa8c
-            net_wintypes[curr_wintype++] = qt_net_wm_window_type_dialog;
cacaa8c
-	// normal netwm type - default
cacaa8c
-	net_wintypes[curr_wintype++] = qt_net_wm_window_type_normal;
cacaa8c
-
cacaa8c
 	// stays on top
cacaa8c
 	if (testWFlags(WStyle_StaysOnTop)) {
cacaa8c
 	    net_winstates[curr_winstate++] = qt_net_wm_state_above;
cacaa8c
@@ -573,6 +551,7 @@ void QWidget::create( WId window, bool i
cacaa8c
 	wsa.save_under = True;
cacaa8c
 	XChangeWindowAttributes( dpy, id, CWOverrideRedirect | CWSaveUnder,
cacaa8c
 				 &wsa );
cacaa8c
+	x11SetWindowType();
cacaa8c
     } else if ( topLevel && !desktop ) {	// top-level widget
cacaa8c
 	QWidget *p = parentWidget();	// real parent
cacaa8c
 	if (p)
cacaa8c
@@ -632,12 +611,7 @@ void QWidget::create( WId window, bool i
cacaa8c
         else
cacaa8c
             XDeleteProperty(dpy, id, qt_xa_motif_wm_hints);
cacaa8c
 
cacaa8c
-	// set _NET_WM_WINDOW_TYPE
cacaa8c
-	if (curr_wintype > 0)
cacaa8c
-	    XChangeProperty(dpy, id, qt_net_wm_window_type, XA_ATOM, 32, PropModeReplace,
cacaa8c
-			    (unsigned char *) net_wintypes, curr_wintype);
cacaa8c
-        else
cacaa8c
-            XDeleteProperty(dpy, id, qt_net_wm_window_type);
cacaa8c
+	x11SetWindowType();
cacaa8c
 
cacaa8c
 	// set _NET_WM_WINDOW_STATE
cacaa8c
 	if (curr_winstate > 0)
cacaa8c
@@ -896,6 +870,64 @@ void QWidget::reparentSys( QWidget *pare
cacaa8c
 	setMouseTracking(mouse_tracking);
cacaa8c
 }
cacaa8c
 
cacaa8c
+// Sets the EWMH (netwm) window type. Needed as a separate function
cacaa8c
+// because create() may be too soon in some cases.
cacaa8c
+void QWidget::x11SetWindowType( X11WindowType type )
cacaa8c
+{
cacaa8c
+    // NET window types
cacaa8c
+    long net_wintypes[7] = { 0, 0, 0, 0, 0, 0, 0 };
cacaa8c
+    int curr_wintype = 0;
cacaa8c
+    if( testWFlags(WType_Desktop))
cacaa8c
+        return;
cacaa8c
+    if( type == X11WindowTypeSelect ) {
cacaa8c
+        if ( testWFlags(WStyle_Splash)) {
cacaa8c
+            if (qt_net_supports(qt_net_wm_window_type_splash)) {
cacaa8c
+                net_wintypes[curr_wintype++] = qt_net_wm_window_type_splash;
cacaa8c
+            }
cacaa8c
+        } else if (inherits("QToolBar")) {
cacaa8c
+	    // toolbar netwm type
cacaa8c
+	    net_wintypes[curr_wintype++] = qt_net_wm_window_type_toolbar;
cacaa8c
+        } else if (testWFlags(WStyle_Customize) && testWFlags(WStyle_Tool)) {
cacaa8c
+	    // utility netwm type
cacaa8c
+	    net_wintypes[curr_wintype++] = qt_net_wm_window_type_utility;
cacaa8c
+        } else if (testWFlags(WType_Dialog)) {
cacaa8c
+            // dialog netwm type
cacaa8c
+            net_wintypes[curr_wintype++] = qt_net_wm_window_type_dialog;
cacaa8c
+        }
cacaa8c
+    } else if( type == X11WindowTypeCombo ) {
cacaa8c
+        // combo netwm type
cacaa8c
+	net_wintypes[curr_wintype++] = qt_net_wm_window_type_combo;
cacaa8c
+    } else if( type == X11WindowTypeDND ) {
cacaa8c
+        // dnd netwm type
cacaa8c
+    	net_wintypes[curr_wintype++] = qt_net_wm_window_type_dnd;
cacaa8c
+    } else if( type == X11WindowTypeDropdown ) {
cacaa8c
+        // dropdown netwm type
cacaa8c
+    	net_wintypes[curr_wintype++] = qt_net_wm_window_type_dropdown_menu;
cacaa8c
+    } else if( type == X11WindowTypePopup ) {
cacaa8c
+        // popup netwm type
cacaa8c
+    	net_wintypes[curr_wintype++] = qt_net_wm_window_type_popup_menu;
cacaa8c
+    } else if( type == X11WindowTypeMenu ) {
cacaa8c
+        // menu netwm type
cacaa8c
+	net_wintypes[curr_wintype++] = qt_net_wm_window_type_menu;
cacaa8c
+    } else if( type == X11WindowTypeTooltip ) {
cacaa8c
+        // tooltip netwm type
cacaa8c
+    	net_wintypes[curr_wintype++] = qt_net_wm_window_type_tooltip;
cacaa8c
+    }
cacaa8c
+
cacaa8c
+    // normal netwm type - default
cacaa8c
+    net_wintypes[curr_wintype++] = qt_net_wm_window_type_normal;
cacaa8c
+    // set _NET_WM_WINDOW_TYPE
cacaa8c
+    if (curr_wintype > 0)
cacaa8c
+        XChangeProperty(x11Display(), winId(), qt_net_wm_window_type, XA_ATOM, 32, PropModeReplace,
cacaa8c
+			(unsigned char *) net_wintypes, curr_wintype);
cacaa8c
+    else
cacaa8c
+        XDeleteProperty(x11Display(), winId(), qt_net_wm_window_type);
cacaa8c
+}
cacaa8c
+
cacaa8c
+void QWidget::x11SetWindowTransient( QWidget* parent )
cacaa8c
+{
cacaa8c
+    XSetTransientForHint( x11Display(), winId(), parent->winId());
cacaa8c
+}
cacaa8c
 
cacaa8c
 /*!
cacaa8c
     Translates the widget coordinate \a pos to global screen
cacaa8c
--- src/kernel/qwidget.h.sav	2007-05-25 18:56:23.000000000 +0200
cacaa8c
+++ src/kernel/qwidget.h	2007-05-31 10:30:58.000000000 +0200
cacaa8c
@@ -464,7 +464,19 @@ public:
cacaa8c
     CGContextRef macCGContext(bool clipped=TRUE) const;
cacaa8c
 #endif
cacaa8c
 #endif
cacaa8c
-
cacaa8c
+#if defined(Q_WS_X11)
cacaa8c
+    enum X11WindowType {
cacaa8c
+        X11WindowTypeSelect,
cacaa8c
+        X11WindowTypeCombo,
cacaa8c
+        X11WindowTypeDND,
cacaa8c
+        X11WindowTypeTooltip,
cacaa8c
+        X11WindowTypeMenu, // torn-off
cacaa8c
+        X11WindowTypeDropdown,
cacaa8c
+        X11WindowTypePopup
cacaa8c
+    };
cacaa8c
+    void x11SetWindowType( X11WindowType type = X11WindowTypeSelect );
cacaa8c
+    void x11SetWindowTransient( QWidget* parent );
cacaa8c
+#endif
cacaa8c
     void setWindowOpacity(double level);
cacaa8c
     double windowOpacity() const;
cacaa8c
 
cacaa8c
--- src/dialogs/qdialog.cpp.sav	2007-05-25 18:56:23.000000000 +0200
cacaa8c
+++ src/dialogs/qdialog.cpp	2007-05-31 10:30:58.000000000 +0200
cacaa8c
@@ -668,10 +668,6 @@ bool QDialog::event( QEvent *e )
cacaa8c
   Geometry management.
cacaa8c
  *****************************************************************************/
cacaa8c
 
cacaa8c
-#if defined(Q_WS_X11)
cacaa8c
-extern "C" { int XSetTransientForHint( Display *, unsigned long, unsigned long ); }
cacaa8c
-#endif // Q_WS_X11
cacaa8c
-
cacaa8c
 /*!
cacaa8c
     Shows the dialog as a \link #modeless modeless \endlink dialog.
cacaa8c
     Control returns immediately to the calling code.
cacaa8c
@@ -705,7 +701,7 @@ void QDialog::show()
cacaa8c
 	&& qApp->mainWidget() && qApp->mainWidget()->isVisible()
cacaa8c
 	&& !qApp->mainWidget()->isMinimized()) {
cacaa8c
 	// make sure the transient for hint is set properly for modal dialogs
cacaa8c
-        XSetTransientForHint( x11Display(), winId(), qApp->mainWidget()->winId() );
cacaa8c
+        x11SetWindowTransient( qApp->mainWidget());
cacaa8c
     }
cacaa8c
 #endif // Q_WS_X11
cacaa8c
 
cacaa8c
--- src/widgets/qtooltip.cpp.sav	2007-05-25 18:56:23.000000000 +0200
cacaa8c
+++ src/widgets/qtooltip.cpp	2007-05-31 10:30:58.000000000 +0200
cacaa8c
@@ -72,6 +72,7 @@ public:
cacaa8c
 	polish();
cacaa8c
 	setText(text);
cacaa8c
 	adjustSize();
cacaa8c
+        x11SetWindowType( X11WindowTypeTooltip );
cacaa8c
     }
cacaa8c
     void setWidth( int w ) { resize( sizeForWidth( w ) ); }
cacaa8c
 };
cacaa8c
@@ -528,6 +529,10 @@ void QTipManager::showTip()
cacaa8c
     if (!widget)
cacaa8c
 	return;
cacaa8c
 
cacaa8c
+#ifdef Q_WS_X11
cacaa8c
+    label->x11SetWindowTransient( widget->topLevelWidget());
cacaa8c
+#endif
cacaa8c
+
cacaa8c
 #ifdef Q_WS_MAC
cacaa8c
     QRect screen = QApplication::desktop()->availableGeometry( scr );
cacaa8c
 #else
cacaa8c
--- src/widgets/qcombobox.cpp.sav	2007-05-25 18:56:23.000000000 +0200
cacaa8c
+++ src/widgets/qcombobox.cpp	2007-05-31 10:49:13.000000000 +0200
cacaa8c
@@ -389,12 +389,8 @@ public:
cacaa8c
     inline QListBox * listBox() { return lBox; }
cacaa8c
     inline QComboBoxPopup * popup() { return pop; }
cacaa8c
     void updateLinedGeometry();
cacaa8c
-
cacaa8c
-    void setListBox( QListBox *l ) { lBox = l ; usingLBox = TRUE;
cacaa8c
-				l->setMouseTracking( TRUE );}
cacaa8c
-
cacaa8c
-    void setPopupMenu( QComboBoxPopup * pm, bool isPopup=TRUE )
cacaa8c
-	{ pop = pm; if(isPopup) usingLBox = FALSE; }
cacaa8c
+    void setListBox( QListBox *l );
cacaa8c
+    void setPopupMenu( QComboBoxPopup * pm, bool isPopup=TRUE );
cacaa8c
 
cacaa8c
     int		current;
cacaa8c
     int		maxCount;
cacaa8c
@@ -440,6 +436,30 @@ void QComboBoxData::updateLinedGeometry(
cacaa8c
 	ed->setGeometry( r );
cacaa8c
 }
cacaa8c
 
cacaa8c
+void QComboBoxData::setListBox( QListBox *l )
cacaa8c
+{
cacaa8c
+    lBox = l;
cacaa8c
+    usingLBox = TRUE;
cacaa8c
+    l->setMouseTracking( TRUE );
cacaa8c
+#ifdef Q_WS_X11
cacaa8c
+    l->x11SetWindowType( QWidget::X11WindowTypeCombo );
cacaa8c
+    l->x11SetWindowTransient( combo->topLevelWidget());
cacaa8c
+#endif
cacaa8c
+}
cacaa8c
+
cacaa8c
+void QComboBoxData::setPopupMenu( QComboBoxPopup * pm, bool isPopup )
cacaa8c
+{
cacaa8c
+    pop = pm;
cacaa8c
+    if(isPopup)
cacaa8c
+        usingLBox = FALSE;
cacaa8c
+#ifdef Q_WS_X11
cacaa8c
+    if( pm ) {
cacaa8c
+        pm->x11SetWindowType( QWidget::X11WindowTypeCombo );
cacaa8c
+        pm->x11SetWindowTransient( combo->topLevelWidget());
cacaa8c
+    }
cacaa8c
+#endif
cacaa8c
+}
cacaa8c
+
cacaa8c
 static inline bool checkInsertIndex( const char *method, const char * name,
cacaa8c
 				     int count, int *index)
cacaa8c
 {
cacaa8c
--- src/widgets/qpopupmenu.cpp.sav	2007-05-25 18:56:23.000000000 +0200
cacaa8c
+++ src/widgets/qpopupmenu.cpp	2007-05-31 11:09:22.000000000 +0200
cacaa8c
@@ -298,6 +298,9 @@ QPopupMenu::QPopupMenu( QWidget *parent,
cacaa8c
     connectModalRecursionSafety = 0;
cacaa8c
 
cacaa8c
     setFocusPolicy( StrongFocus );
cacaa8c
+#ifdef Q_WS_X11
cacaa8c
+    x11SetWindowType( X11WindowTypePopup );
cacaa8c
+#endif
cacaa8c
 }
cacaa8c
 
cacaa8c
 /*!
cacaa8c
@@ -537,6 +540,29 @@ void QPopupMenu::popup( const QPoint &po
cacaa8c
 	emit aboutToShow();
cacaa8c
 	updateSize(TRUE);
cacaa8c
     }
cacaa8c
+#ifdef Q_WS_X11
cacaa8c
+#ifndef QT_NO_MENUBAR
cacaa8c
+    QMenuData *top = this;		// find top level
cacaa8c
+    while ( top->parentMenu )
cacaa8c
+	top = top->parentMenu;
cacaa8c
+    if( top->isMenuBar )
cacaa8c
+        x11SetWindowType( X11WindowTypeDropdown );
cacaa8c
+    if( parentMenu && parentMenu->isMenuBar )
cacaa8c
+        x11SetWindowTransient( static_cast< QMenuBar* >( parentMenu )->topLevelWidget());
cacaa8c
+#endif
cacaa8c
+    if( parentMenu && !parentMenu->isMenuBar )
cacaa8c
+        x11SetWindowTransient( static_cast< QPopupMenu* >( parentMenu ));
cacaa8c
+    if( !parentMenu ) {
cacaa8c
+        // hackish ... try to find the main window related to this popup
cacaa8c
+        QWidget* parent = parentWidget() ? parentWidget()->topLevelWidget() : NULL;
cacaa8c
+        if( parent == NULL )
cacaa8c
+            parent = QApplication::widgetAt( pos );
cacaa8c
+        if( parent == NULL )
cacaa8c
+            parent = qApp->activeWindow();
cacaa8c
+        if( parent != NULL )
cacaa8c
+            x11SetWindowTransient( parent );
cacaa8c
+    }
cacaa8c
+#endif
cacaa8c
 
cacaa8c
     int sw = screen.width();			// screen width
cacaa8c
     int sh = screen.height();			// screen height
cacaa8c
@@ -1390,6 +1416,13 @@ void QPopupMenu::hide()
cacaa8c
 #if defined(QT_ACCESSIBILITY_SUPPORT)
cacaa8c
     QAccessible::updateAccessibility( this, 0, QAccessible::PopupMenuEnd );
cacaa8c
 #endif
cacaa8c
+#ifndef QT_NO_MENUBAR
cacaa8c
+    QMenuData *top = this;		// find top level
cacaa8c
+    while ( top->parentMenu )
cacaa8c
+	top = top->parentMenu;
cacaa8c
+    if( top->isMenuBar )
cacaa8c
+        x11SetWindowType( X11WindowTypePopup ); // reset
cacaa8c
+#endif
cacaa8c
     parentMenu = 0;
cacaa8c
     hidePopups();
cacaa8c
     QWidget::hide();
cacaa8c
@@ -2713,6 +2746,9 @@ void QPopupMenu::toggleTearOff()
cacaa8c
 		     geometry().topLeft(), FALSE );
cacaa8c
 	p->mitems->setAutoDelete( FALSE );
cacaa8c
 	p->tornOff = TRUE;
cacaa8c
+#ifdef Q_WS_X11
cacaa8c
+        p->x11SetWindowType( X11WindowTypeMenu );
cacaa8c
+#endif
cacaa8c
 	for ( QMenuItemListIt it( *mitems ); it.current(); ++it ) {
cacaa8c
 	    if ( it.current()->id() != QMenuData::d->aInt && !it.current()->widget() )
cacaa8c
 		p->mitems->append( it.current() );