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

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