Blame SOURCES/0001-Related-rhbz-1281906-wayland-toolbar-drawn-over-menu.patch

f325b2
From 2e071f6dd64561ae173b903a76065e2fab48a266 Mon Sep 17 00:00:00 2001
f325b2
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
f325b2
Date: Fri, 24 Jul 2015 12:22:14 +0100
f325b2
Subject: [PATCH] Related: rhbz#1281906 wayland toolbar drawn over menus etc
f325b2
f325b2
gtk3: draw/paint to the fixed container
f325b2
f325b2
which fills the toplevel window, rather than directly to the toplevel window.
f325b2
f325b2
It makes no difference for X, but for wayland the window decorations are part
f325b2
of the toplevel window, dropping down a level means we don't draw out menu bar
f325b2
under the window decoration space
f325b2
f325b2
(cherry picked from commit 298c089df77d9afe2cf86bb7a6a8544a0151e8c5)
f325b2
f325b2
Change-Id: Icec400efacd16b5d901107c13b6fa90c59cad0e6
f325b2
f325b2
gtk3: insert an event box between toplevel and contents
f325b2
f325b2
Change-Id: Ic78aa62baaa4260645a80ffb6704103440339595
f325b2
(cherry picked from commit 2796d7f1723d5b45177fe6da7a6e66cb914ae6d2)
f325b2
f325b2
gtk3: connect to the eventbox and not toplevel for mouse events
f325b2
f325b2
this leaves whatever magic gtk3 under wayland is doing on the toplevel
f325b2
alone so the window can be resized and the title bar responds to
f325b2
clicks as expected
f325b2
f325b2
Change-Id: I9952cb719f3148660e17951b4f66a2525e11a6df
f325b2
(cherry picked from commit 10d2467c2532178efe3d672405839bc1d0aab1e5)
f325b2
f325b2
attach gestures to event widget instead of toplevel
f325b2
f325b2
Change-Id: Id0658cf561570a2ae15fb7fd603e6437da9cfaf2
f325b2
(cherry picked from commit 848f685ae8f614ad62d205ef628f259cafb738b3)
f325b2
---
f325b2
 vcl/inc/unx/gtk/gtkframe.hxx       |  5 +-
f325b2
 vcl/unx/gtk/a11y/atkfactory.cxx    | 21 +++++++--
f325b2
 vcl/unx/gtk/window/gtksalframe.cxx | 93 +++++++++++++++++++++++++++-----------
f325b2
 3 files changed, 88 insertions(+), 31 deletions(-)
f325b2
f325b2
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
f325b2
index 604f2a6..3531c41 100644
f325b2
--- a/vcl/inc/unx/gtk/gtkframe.hxx
f325b2
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
f325b2
@@ -173,6 +173,8 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider
f325b2
 
f325b2
     SalX11Screen                    m_nXScreen;
f325b2
     GtkWidget*                      m_pWindow;
f325b2
+    GtkEventBox*                    m_pEventBox;
f325b2
+    GtkFixed*                       m_pFixedContainer;
f325b2
     GdkWindow*                      m_pForeignParent;
f325b2
     GdkNativeWindow                 m_aForeignParentWindow;
f325b2
     GdkWindow*                      m_pForeignTopLevel;
f325b2
@@ -180,7 +182,6 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider
f325b2
     Pixmap                          m_hBackgroundPixmap;
f325b2
     sal_uLong                       m_nStyle;
f325b2
     SalExtStyle                     m_nExtStyle;
f325b2
-    GtkFixed*                       m_pFixedContainer;
f325b2
     GtkSalFrame*                    m_pParent;
f325b2
     std::list< GtkSalFrame* >       m_aChildren;
f325b2
     GdkWindowState                  m_nState;
f325b2
@@ -335,6 +336,7 @@ public:
f325b2
     guint                           m_nActionGroupExportId;
f325b2
     guint                           m_nAppActionGroupExportId;
f325b2
     guint                           m_nHudAwarenessId;
f325b2
+    std::vector<gulong>             m_aMouseSignalIds;
f325b2
 
f325b2
     // dispatches an event, returns true if dispatched
f325b2
     // and false else; if true was returned the event should
f325b2
@@ -347,6 +349,7 @@ public:
f325b2
     static GdkDisplay*     getGdkDisplay();
f325b2
     GtkWidget*  getWindow() const { return m_pWindow; }
f325b2
     GtkFixed*   getFixedContainer() const { return m_pFixedContainer; }
f325b2
+    GtkWidget*  getMouseEventWidget() const;
f325b2
     GdkWindow*  getForeignParent() const { return m_pForeignParent; }
f325b2
     GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; }
f325b2
     GdkWindow*  getForeignTopLevel() const { return m_pForeignTopLevel; }
f325b2
diff --git a/vcl/unx/gtk/a11y/atkfactory.cxx b/vcl/unx/gtk/a11y/atkfactory.cxx
f325b2
index 99ed750..9edc7ab 100644
f325b2
--- a/vcl/unx/gtk/a11y/atkfactory.cxx
f325b2
+++ b/vcl/unx/gtk/a11y/atkfactory.cxx
f325b2
@@ -101,14 +101,27 @@ wrapper_factory_get_accessible_type()
f325b2
 static AtkObject*
f325b2
 wrapper_factory_create_accessible( GObject *obj )
f325b2
 {
f325b2
-    GtkWidget* parent_widget = gtk_widget_get_parent( GTK_WIDGET( obj ) );
f325b2
+#if GTK_CHECK_VERSION(3,0,0)
f325b2
+    GtkWidget* pEventBox = gtk_widget_get_parent(GTK_WIDGET(obj));
f325b2
 
f325b2
     // gail_container_real_remove_gtk tries to re-instanciate an accessible
f325b2
     // for a widget that is about to vanish ..
f325b2
-    if( ! parent_widget )
f325b2
+    if (!pEventBox)
f325b2
         return atk_noop_object_wrapper_new();
f325b2
 
f325b2
-    GtkSalFrame* pFrame = GtkSalFrame::getFromWindow( GTK_WINDOW( parent_widget ) );
f325b2
+    GtkWidget* pTopLevel = gtk_widget_get_parent(pEventBox);
f325b2
+    if (!pTopLevel)
f325b2
+        return atk_noop_object_wrapper_new();
f325b2
+#else
f325b2
+    GtkWidget* pTopLevel = gtk_widget_get_parent(GTK_WIDGET(obj));
f325b2
+
f325b2
+    // gail_container_real_remove_gtk tries to re-instanciate an accessible
f325b2
+    // for a widget that is about to vanish ..
f325b2
+    if (!pTopLevel)
f325b2
+        return atk_noop_object_wrapper_new();
f325b2
+#endif
f325b2
+
f325b2
+    GtkSalFrame* pFrame = GtkSalFrame::getFromWindow(GTK_WINDOW(pTopLevel));
f325b2
     g_return_val_if_fail( pFrame != NULL, NULL );
f325b2
 
f325b2
     vcl::Window* pFrameWindow = pFrame->GetWindow();
f325b2
@@ -130,7 +143,7 @@ wrapper_factory_create_accessible( GObject *obj )
f325b2
                 if( accessible )
f325b2
                     g_object_ref( G_OBJECT(accessible) );
f325b2
                 else
f325b2
-                    accessible = atk_object_wrapper_new( xAccessible, gtk_widget_get_accessible(parent_widget) );
f325b2
+                    accessible = atk_object_wrapper_new( xAccessible, gtk_widget_get_accessible(pTopLevel) );
f325b2
 
f325b2
                 return accessible;
f325b2
             }
f325b2
diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
f325b2
index eef48cd..8acdf8a 100644
f325b2
--- a/vcl/unx/gtk/window/gtksalframe.cxx
f325b2
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
f325b2
@@ -414,7 +414,7 @@ void GtkSalFrame::doKeyCallback( guint state,
f325b2
     if (keyval == GDK_0)
f325b2
     {
f325b2
         fprintf( stderr, "force widget_queue_draw\n");
f325b2
-        gtk_widget_queue_draw (m_pWindow);
f325b2
+        gtk_widget_queue_draw (m_pFixedContainer);
f325b2
         return;
f325b2
     }
f325b2
     else if (keyval == GDK_1)
f325b2
@@ -894,8 +894,13 @@ GtkSalFrame::~GtkSalFrame()
f325b2
     if( m_pIMHandler )
f325b2
         delete m_pIMHandler;
f325b2
 
f325b2
+    GtkWidget *pEventWidget = getMouseEventWidget();
f325b2
+    for (auto handler_id : m_aMouseSignalIds)
f325b2
+        g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id);
f325b2
     if( m_pFixedContainer )
f325b2
         gtk_widget_destroy( GTK_WIDGET( m_pFixedContainer ) );
f325b2
+    if( m_pEventBox )
f325b2
+        gtk_widget_destroy( GTK_WIDGET(m_pEventBox) );
f325b2
     {
f325b2
         SolarMutexGuard aGuard;
f325b2
 #if defined ENABLE_GMENU_INTEGRATION
f325b2
@@ -1036,38 +1041,75 @@ void GtkSalFrame::updateScreenNumber()
f325b2
     maGeometry.nDisplayScreenNumber = nScreen;
f325b2
 }
f325b2
 
f325b2
+GtkWidget *GtkSalFrame::getMouseEventWidget() const
f325b2
+{
f325b2
+#if GTK_CHECK_VERSION(3,0,0)
f325b2
+    return GTK_WIDGET(m_pEventBox);
f325b2
+#else
f325b2
+    return m_pWindow;
f325b2
+#endif
f325b2
+}
f325b2
+
f325b2
 void GtkSalFrame::InitCommon()
f325b2
 {
f325b2
+#if GTK_CHECK_VERSION(3,0,0)
f325b2
+    m_pEventBox = GTK_EVENT_BOX(gtk_event_box_new());
f325b2
+    gtk_widget_add_events( GTK_WIDGET(m_pEventBox),
f325b2
+                           GDK_ALL_EVENTS_MASK );
f325b2
+    gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pEventBox) );
f325b2
+
f325b2
+    // add the fixed container child,
f325b2
+    // fixed is needed since we have to position plugin windows
f325b2
+    m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL ));
f325b2
+    gtk_container_add( GTK_CONTAINER(m_pEventBox), GTK_WIDGET(m_pFixedContainer) );
f325b2
+#else
f325b2
+    m_pEventBox = 0;
f325b2
+    // add the fixed container child,
f325b2
+    // fixed is needed since we have to position plugin windows
f325b2
+    m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL ));
f325b2
+    gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pFixedContainer) );
f325b2
+#endif
f325b2
+
f325b2
+    GtkWidget *pEventWidget = getMouseEventWidget();
f325b2
+
f325b2
+    gtk_widget_set_app_paintable(GTK_WIDGET(m_pFixedContainer), true);
f325b2
+    /*non-X11 displays won't show anything at all without double-buffering
f325b2
+      enabled*/
f325b2
+    if (GDK_IS_X11_DISPLAY(getGdkDisplay()))
f325b2
+        gtk_widget_set_double_buffered(GTK_WIDGET(m_pFixedContainer), false);
f325b2
+    gtk_widget_set_redraw_on_allocate(GTK_WIDGET(m_pFixedContainer), false);
f325b2
+
f325b2
+
f325b2
     // connect signals
f325b2
     g_signal_connect( G_OBJECT(m_pWindow), "style-set", G_CALLBACK(signalStyleSet), this );
f325b2
-    g_signal_connect( G_OBJECT(m_pWindow), "button-press-event", G_CALLBACK(signalButton), this );
f325b2
-    g_signal_connect( G_OBJECT(m_pWindow), "button-release-event", G_CALLBACK(signalButton), this );
f325b2
+    m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-press-event", G_CALLBACK(signalButton), this ));
f325b2
+    m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "motion-notify-event", G_CALLBACK(signalMotion), this ));
f325b2
+    m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-release-event", G_CALLBACK(signalButton), this ));
f325b2
 #if GTK_CHECK_VERSION(3,0,0)
f325b2
-    g_signal_connect( G_OBJECT(m_pWindow), "draw", G_CALLBACK(signalDraw), this );
f325b2
+    g_signal_connect( G_OBJECT(m_pFixedContainer), "draw", G_CALLBACK(signalDraw), this );
f325b2
     g_signal_connect( G_OBJECT(m_pWindow), "size-allocate", G_CALLBACK(sizeAllocated), this );
f325b2
 //    g_signal_connect( G_OBJECT(m_pWindow), "state-flags-changed", G_CALLBACK(signalFlagsChanged), this );
f325b2
 #if GTK_CHECK_VERSION(3,14,0)
f325b2
-    GtkGesture *pSwipe = gtk_gesture_swipe_new(m_pWindow);
f325b2
+    GtkGesture *pSwipe = gtk_gesture_swipe_new(pEventWidget);
f325b2
     g_signal_connect(pSwipe, "swipe", G_CALLBACK(gestureSwipe), this);
f325b2
     gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pSwipe), GTK_PHASE_TARGET);
f325b2
-    g_object_weak_ref(G_OBJECT(m_pWindow), reinterpret_cast<GWeakNotify>(g_object_unref), pSwipe);
f325b2
+    g_object_weak_ref(G_OBJECT(pEventWidget), reinterpret_cast<GWeakNotify>(g_object_unref), pSwipe);
f325b2
 
f325b2
-    GtkGesture *pLongPress = gtk_gesture_long_press_new(m_pWindow);
f325b2
+    GtkGesture *pLongPress = gtk_gesture_long_press_new(pEventWidget);
f325b2
     g_signal_connect(pLongPress, "pressed", G_CALLBACK(gestureLongPress), this);
f325b2
     gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pLongPress), GTK_PHASE_TARGET);
f325b2
-    g_object_weak_ref(G_OBJECT(m_pWindow), reinterpret_cast<GWeakNotify>(g_object_unref), pLongPress);
f325b2
+    g_object_weak_ref(G_OBJECT(pEventWidget), reinterpret_cast<GWeakNotify>(g_object_unref), pLongPress);
f325b2
 
f325b2
 #endif
f325b2
 
f325b2
 #else
f325b2
-    g_signal_connect( G_OBJECT(m_pWindow), "expose-event", G_CALLBACK(signalExpose), this );
f325b2
+    g_signal_connect( G_OBJECT(m_pFixedContainer), "expose-event", G_CALLBACK(signalExpose), this );
f325b2
 #endif
f325b2
     g_signal_connect( G_OBJECT(m_pWindow), "focus-in-event", G_CALLBACK(signalFocus), this );
f325b2
     g_signal_connect( G_OBJECT(m_pWindow), "focus-out-event", G_CALLBACK(signalFocus), this );
f325b2
     g_signal_connect( G_OBJECT(m_pWindow), "map-event", G_CALLBACK(signalMap), this );
f325b2
     g_signal_connect( G_OBJECT(m_pWindow), "unmap-event", G_CALLBACK(signalUnmap), this );
f325b2
     g_signal_connect( G_OBJECT(m_pWindow), "configure-event", G_CALLBACK(signalConfigure), this );
f325b2
-    g_signal_connect( G_OBJECT(m_pWindow), "motion-notify-event", G_CALLBACK(signalMotion), this );
f325b2
     g_signal_connect( G_OBJECT(m_pWindow), "key-press-event", G_CALLBACK(signalKey), this );
f325b2
     g_signal_connect( G_OBJECT(m_pWindow), "key-release-event", G_CALLBACK(signalKey), this );
f325b2
     g_signal_connect( G_OBJECT(m_pWindow), "delete-event", G_CALLBACK(signalDelete), this );
f325b2
@@ -1102,26 +1144,18 @@ void GtkSalFrame::InitCommon()
f325b2
     m_nAppActionGroupExportId = 0;
f325b2
     m_nHudAwarenessId   = 0;
f325b2
 
f325b2
-    gtk_widget_set_app_paintable( m_pWindow, TRUE );
f325b2
-    /*non-X11 displays won't show anything at all without double-buffering
f325b2
-      enabled*/
f325b2
-    if (GDK_IS_X11_DISPLAY(getGdkDisplay()))
f325b2
-        gtk_widget_set_double_buffered( m_pWindow, FALSE );
f325b2
-    gtk_widget_set_redraw_on_allocate( m_pWindow, FALSE );
f325b2
-
f325b2
     gtk_widget_add_events( m_pWindow,
f325b2
                            GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
f325b2
                            GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
f325b2
                            GDK_VISIBILITY_NOTIFY_MASK | GDK_SCROLL_MASK
f325b2
                            );
f325b2
 
f325b2
-    // add the fixed container child,
f325b2
-    // fixed is needed since we have to position plugin windows
f325b2
-    m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL ));
f325b2
-    gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pFixedContainer) );
f325b2
-
f325b2
     // show the widgets
f325b2
-    gtk_widget_show( GTK_WIDGET(m_pFixedContainer) );
f325b2
+#if GTK_CHECK_VERSION(3,0,0)
f325b2
+    gtk_widget_show_all( GTK_WIDGET(m_pEventBox) );
f325b2
+#else
f325b2
+    gtk_widget_show_all( GTK_WIDGET(m_pFixedContainer) );
f325b2
+#endif
f325b2
 
f325b2
     // realize the window, we need an XWindow id
f325b2
     gtk_widget_realize( m_pWindow );
f325b2
@@ -2780,7 +2814,7 @@ void GtkSalFrame::grabPointer( bool bGrab, bool bOwnerEvents )
f325b2
     GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay());
f325b2
     GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager);
f325b2
     if (bGrab)
f325b2
-        gdk_device_grab(pPointer, widget_get_window(m_pWindow), GDK_OWNERSHIP_NONE, bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, GDK_CURRENT_TIME);
f325b2
+        gdk_device_grab(pPointer, widget_get_window(getMouseEventWidget()), GDK_OWNERSHIP_NONE, bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, GDK_CURRENT_TIME);
f325b2
     else
f325b2
         gdk_device_ungrab(pPointer, GDK_CURRENT_TIME);
f325b2
 #else
f325b2
@@ -3189,8 +3223,14 @@ void GtkSalFrame::createNewWindow( ::Window aNewParent, bool bXEmbed, SalX11Scre
f325b2
     {
f325b2
         gdk_region_destroy( m_pRegion );
f325b2
     }
f325b2
+
f325b2
+    GtkWidget *pEventWidget = getMouseEventWidget();
f325b2
+    for (auto handler_id : m_aMouseSignalIds)
f325b2
+        g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id);
f325b2
     if( m_pFixedContainer )
f325b2
         gtk_widget_destroy( GTK_WIDGET(m_pFixedContainer) );
f325b2
+    if( m_pEventBox )
f325b2
+        gtk_widget_destroy( GTK_WIDGET(m_pEventBox) );
f325b2
     if( m_pWindow )
f325b2
         gtk_widget_destroy( m_pWindow );
f325b2
     if( m_pForeignParent )
f325b2
@@ -3651,7 +3691,7 @@ void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect)
f325b2
         cairo_destroy(cr);
f325b2
     }
f325b2
 
f325b2
-    gtk_widget_queue_draw_area(m_pWindow,
f325b2
+    gtk_widget_queue_draw_area(GTK_WIDGET(m_pFixedContainer),
f325b2
                                rDamageRect.getMinX(),
f325b2
                                rDamageRect.getMinY(),
f325b2
                                rDamageRect.getWidth(),
f325b2
@@ -3874,7 +3914,7 @@ void GtkSalFrame::TriggerPaintEvent()
f325b2
     SAL_INFO("vcl.gtk3", "force painting" << 0 << "," << 0 << " " << maGeometry.nWidth << "x" << maGeometry.nHeight);
f325b2
     SalPaintEvent aPaintEvt(0, 0, maGeometry.nWidth, maGeometry.nHeight, true);
f325b2
     CallCallback(SALEVENT_PAINT, &aPaintEvt);
f325b2
-    gtk_widget_queue_draw(m_pWindow);
f325b2
+    gtk_widget_queue_draw(GTK_WIDGET(m_pFixedContainer));
f325b2
 #endif
f325b2
 }
f325b2
 
f325b2
@@ -4212,6 +4252,7 @@ void GtkSalFrame::signalDestroy( GtkWidget* pObj, gpointer frame )
f325b2
     if( pObj == pThis->m_pWindow )
f325b2
     {
f325b2
         pThis->m_pFixedContainer = NULL;
f325b2
+        pThis->m_pEventBox = NULL;
f325b2
         pThis->m_pWindow = NULL;
f325b2
         pThis->InvalidateGraphics();
f325b2
     }
f325b2
-- 
f325b2
2.5.0
f325b2