[Libreoffice-commits] core.git: include/vcl vcl/inc vcl/source vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Jan 22 17:24:20 UTC 2019


 include/vcl/menu.hxx                |    3 +
 vcl/inc/salmenu.hxx                 |    4 +
 vcl/inc/unx/gtk/gtksalmenu.hxx      |   11 +++++
 vcl/source/app/salvtables.cxx       |    9 ++++
 vcl/source/window/dockingarea.cxx   |    9 ----
 vcl/source/window/menu.cxx          |   15 +++++++
 vcl/source/window/menubarwindow.cxx |    3 +
 vcl/unx/gtk/gtksalmenu.cxx          |   73 ++++++++++++++++++++++++++++++++++++
 8 files changed, 120 insertions(+), 7 deletions(-)

New commits:
commit 46efac592b76d32152353466120eea2c9800858f
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Jan 22 11:21:27 2019 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Tue Jan 22 18:23:52 2019 +0100

    Resolves: tdf#122241 support persona header in native gtk3 menubar
    
    Change-Id: Ia4485ec4c342c86f40e8e0bb7e5e1af1a47bb9b9
    Reviewed-on: https://gerrit.libreoffice.org/66725
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
index 552a596b46a0..f3fb3e7c8056 100644
--- a/include/vcl/menu.hxx
+++ b/include/vcl/menu.hxx
@@ -469,6 +469,9 @@ public:
     tools::Rectangle GetMenuBarButtonRectPixel( sal_uInt16 nId );
     void RemoveMenuBarButton( sal_uInt16 nId );
     void LayoutChanged();
+    // get the height of the menubar, return the native menubar height if that is active or the vcl
+    // one if not
+    int GetMenuBarHeight() const;
 };
 
 inline MenuBar& MenuBar::operator=( const MenuBar& rMenu )
diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx
index 169d887068da..0b6cd9e22481 100644
--- a/vcl/inc/salmenu.hxx
+++ b/vcl/inc/salmenu.hxx
@@ -90,6 +90,10 @@ public:
     // return Rectangle( Point( -1, -1 ), Size( 1, 1 ) ) if menu bar buttons implemented
     // but rectangle cannot be determined
     virtual tools::Rectangle GetMenuBarButtonRectPixel( sal_uInt16 i_nItemId, SalFrame* i_pReferenceFrame );
+
+    virtual int GetMenuBarHeight() const;
+
+    virtual void ApplyPersona();
 };
 
 #endif // INCLUDED_VCL_INC_SALMENU_HXX
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 9ab448857085..bdacee7ca178 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -20,6 +20,7 @@
 
 #include <salmenu.hxx>
 #include <unx/gtk/gtkframe.hxx>
+#include <unotools/tempfile.hxx>
 #include <vcl/idle.hxx>
 
 #if GTK_CHECK_VERSION(3,0,0)
@@ -40,6 +41,10 @@
 #  endif
 #endif
 
+#if !GTK_CHECK_VERSION(3,0,0)
+typedef void GtkCssProvider;
+#endif
+
 class MenuItemList;
 class GtkSalMenuItem;
 
@@ -55,8 +60,12 @@ private:
     bool                            mbReturnFocusToDocument;
     bool                            mbAddedGrab;
     GtkWidget*                      mpMenuBarContainerWidget;
+    std::unique_ptr<utl::TempFile>  mxPersonaImage;
+    BitmapEx                        maPersonaBitmap;
     GtkWidget*                      mpMenuAllowShrinkWidget;
     GtkWidget*                      mpMenuBarWidget;
+    GtkCssProvider*                 mpMenuBarContainerProvider;
+    GtkCssProvider*                 mpMenuBarProvider;
     GtkWidget*                      mpCloseButton;
     VclPtr<Menu>                    mpVCLMenu;
     GtkSalMenu*                     mpParentSalMenu;
@@ -137,6 +146,8 @@ public:
     virtual void ShowCloseButton(bool bShow) override;
     virtual bool CanGetFocus() const override;
     virtual bool TakeFocus() override;
+    virtual int GetMenuBarHeight() const override;
+    virtual void ApplyPersona() override;
 };
 
 class GtkSalMenuItem : public SalMenuItem
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 02f07418a44a..4c343f85d53d 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -205,6 +205,15 @@ tools::Rectangle SalMenu::GetMenuBarButtonRectPixel( sal_uInt16, SalFrame* )
     return tools::Rectangle();
 }
 
+int SalMenu::GetMenuBarHeight() const
+{
+    return 0;
+}
+
+void SalMenu::ApplyPersona()
+{
+}
+
 SalMenuItem::~SalMenuItem()
 {
 }
diff --git a/vcl/source/window/dockingarea.cxx b/vcl/source/window/dockingarea.cxx
index 2f27d3e3f520..fed3fa5c4737 100644
--- a/vcl/source/window/dockingarea.cxx
+++ b/vcl/source/window/dockingarea.cxx
@@ -131,14 +131,9 @@ void DockingAreaWindow::ApplySettings(vcl::RenderContext& rRenderContext)
 
         // we need to shift the bitmap vertically so that it spans over the
         // menubar conveniently
-        long nMenubarHeight = 0;
         SystemWindow* pSysWin = GetSystemWindow();
-        if (pSysWin && pSysWin->GetMenuBar())
-        {
-            vcl::Window* pMenubarWin = pSysWin->GetMenuBar()->GetWindow();
-            if (pMenubarWin)
-                nMenubarHeight = pMenubarWin->GetOutputHeightPixel();
-        }
+        MenuBar* pMenuBar = pSysWin ? pSysWin->GetMenuBar() : nullptr;
+        int nMenubarHeight = pMenuBar ? pMenuBar->GetMenuBarHeight() : 0;
         aWallpaper.SetRect(tools::Rectangle(Point(0, -nMenubarHeight),
                            Size(rRenderContext.GetOutputWidthPixel(),
                                 rRenderContext.GetOutputHeightPixel() + nMenubarHeight)));
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 24b0c04abc88..4509ad496557 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2671,6 +2671,21 @@ bool MenuBar::HandleMenuButtonEvent( sal_uInt16 i_nButtonId )
     return pMenuWin && pMenuWin->HandleMenuButtonEvent(i_nButtonId);
 }
 
+int MenuBar::GetMenuBarHeight() const
+{
+    MenuBar* pMenuBar = const_cast<MenuBar*>(this);
+    const SalMenu *pNativeMenu = pMenuBar->ImplGetSalMenu();
+    int nMenubarHeight;
+    if (pNativeMenu)
+        nMenubarHeight = pNativeMenu->GetMenuBarHeight();
+    else
+    {
+        vcl::Window* pMenubarWin = GetWindow();
+        nMenubarHeight = pMenubarWin ? pMenubarWin->GetOutputHeightPixel() : 0;
+    }
+    return nMenubarHeight;
+}
+
 // bool PopupMenu::bAnyPopupInExecute = false;
 
 MenuFloatingWindow * PopupMenu::ImplGetFloatingWindow() const {
diff --git a/vcl/source/window/menubarwindow.cxx b/vcl/source/window/menubarwindow.cxx
index f45cb3e64681..6607d44cc163 100644
--- a/vcl/source/window/menubarwindow.cxx
+++ b/vcl/source/window/menubarwindow.cxx
@@ -1076,6 +1076,9 @@ void MenuBarWindow::ApplySettings(vcl::RenderContext& rRenderContext)
     SetPointFont(rRenderContext, rStyleSettings.GetMenuFont());
 
     const BitmapEx& rPersonaBitmap = Application::GetSettings().GetStyleSettings().GetPersonaHeader();
+    SalMenu *pNativeMenu = pMenu ? pMenu->ImplGetSalMenu() : nullptr;
+    if (pNativeMenu)
+        pNativeMenu->ApplyPersona();
     if (!rPersonaBitmap.IsEmpty())
     {
         Wallpaper aWallpaper(rPersonaBitmap);
diff --git a/vcl/unx/gtk/gtksalmenu.cxx b/vcl/unx/gtk/gtksalmenu.cxx
index 8329c376eda7..9ad10529d500 100644
--- a/vcl/unx/gtk/gtksalmenu.cxx
+++ b/vcl/unx/gtk/gtksalmenu.cxx
@@ -534,6 +534,8 @@ GtkSalMenu::GtkSalMenu( bool bMenuBar ) :
     mpMenuBarContainerWidget( nullptr ),
     mpMenuAllowShrinkWidget( nullptr ),
     mpMenuBarWidget( nullptr ),
+    mpMenuBarContainerProvider( nullptr ),
+    mpMenuBarProvider( nullptr ),
     mpCloseButton( nullptr ),
     mpVCLMenu( nullptr ),
     mpParentSalMenu( nullptr ),
@@ -834,6 +836,7 @@ void GtkSalMenu::CreateMenuBarWidget()
     gtk_grid_attach(GTK_GRID(mpMenuBarContainerWidget), mpMenuAllowShrinkWidget, 0, 0, 1, 1);
 
     mpMenuBarWidget = gtk_menu_bar_new_from_model(mpMenuModel);
+
     gtk_widget_insert_action_group(mpMenuBarWidget, "win", mpActionGroup);
     gtk_widget_set_hexpand(GTK_WIDGET(mpMenuBarWidget), true);
     gtk_widget_set_hexpand(mpMenuAllowShrinkWidget, true);
@@ -851,6 +854,67 @@ void GtkSalMenu::CreateMenuBarWidget()
 #endif
 }
 
+void GtkSalMenu::ApplyPersona()
+{
+#if GTK_CHECK_VERSION(3,0,0)
+    assert(mbMenuBar);
+    // I'm dubious about the persona theming feature, but as it exists, lets try and support
+    // it, apply the image to the mpMenuBarContainerWidget
+    const BitmapEx& rPersonaBitmap = Application::GetSettings().GetStyleSettings().GetPersonaHeader();
+
+    GtkStyleContext *pMenuBarContainerContext = gtk_widget_get_style_context(GTK_WIDGET(mpMenuBarContainerWidget));
+    if (mpMenuBarContainerProvider)
+    {
+        gtk_style_context_remove_provider(pMenuBarContainerContext, GTK_STYLE_PROVIDER(mpMenuBarContainerProvider));
+        mpMenuBarContainerProvider = nullptr;
+    }
+    GtkStyleContext *pMenuBarContext = gtk_widget_get_style_context(GTK_WIDGET(mpMenuBarWidget));
+    if (mpMenuBarProvider)
+    {
+        gtk_style_context_remove_provider(pMenuBarContext, GTK_STYLE_PROVIDER(mpMenuBarProvider));
+        mpMenuBarProvider = nullptr;
+    }
+
+    if (!rPersonaBitmap.IsEmpty())
+    {
+        if (maPersonaBitmap != rPersonaBitmap)
+        {
+            vcl::PNGWriter aPNGWriter(rPersonaBitmap);
+            mxPersonaImage.reset(new utl::TempFile);
+            mxPersonaImage->EnableKillingFile(true);
+            SvStream* pStream = mxPersonaImage->GetStream(StreamMode::WRITE);
+            aPNGWriter.Write(*pStream);
+            mxPersonaImage->CloseStream();
+        }
+
+        mpMenuBarContainerProvider = gtk_css_provider_new();
+        OUString aBuffer = "* { background-image: url(\"" + mxPersonaImage->GetURL() + "\"); background-position: top right; }";
+        OString aResult = OUStringToOString(aBuffer, RTL_TEXTENCODING_UTF8);
+        gtk_css_provider_load_from_data(mpMenuBarContainerProvider, aResult.getStr(), aResult.getLength(), nullptr);
+        gtk_style_context_add_provider(pMenuBarContainerContext, GTK_STYLE_PROVIDER(mpMenuBarContainerProvider),
+                                       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+
+        // force the menubar to be transparent when persona is active otherwise for
+        // me the menubar becomes gray when its in the backdrop
+        mpMenuBarProvider = gtk_css_provider_new();
+        static const gchar data[] = "* { "
+          "background-image: none;"
+          "background-color: transparent;"
+          "}";
+        gtk_css_provider_load_from_data(mpMenuBarProvider, data, -1, nullptr);
+        gtk_style_context_add_provider(pMenuBarContext,
+                                       GTK_STYLE_PROVIDER(mpMenuBarProvider),
+                                       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+    }
+    maPersonaBitmap = rPersonaBitmap;
+#else
+    (void)maPersonaBitmap;
+    (void)mpMenuBarContainerProvider;
+    (void)mpMenuBarProvider;
+#endif
+}
+
 void GtkSalMenu::DestroyMenuBarWidget()
 {
 #if GTK_CHECK_VERSION(3,0,0)
@@ -1331,6 +1395,15 @@ void GtkSalMenu::GetSystemMenuData( SystemMenuData* )
 {
 }
 
+int GtkSalMenu::GetMenuBarHeight() const
+{
+#if GTK_CHECK_VERSION(3,0,0)
+    return mpMenuBarWidget ? gtk_widget_get_allocated_height(mpMenuBarWidget) : 0;
+#else
+    return 0;
+#endif
+}
+
 /*
  * GtkSalMenuItem
  */


More information about the Libreoffice-commits mailing list