diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-01-22 11:21:27 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-01-22 18:23:52 +0100 |
commit | 46efac592b76d32152353466120eea2c9800858f (patch) | |
tree | a9dc9e7f7ec69be79ac595ed8cf20a9a594d18df /vcl | |
parent | db4c828913cfc8c33b8cc87b576fddcc2e705176 (diff) |
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@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/salmenu.hxx | 4 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtksalmenu.hxx | 11 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 9 | ||||
-rw-r--r-- | vcl/source/window/dockingarea.cxx | 9 | ||||
-rw-r--r-- | vcl/source/window/menu.cxx | 15 | ||||
-rw-r--r-- | vcl/source/window/menubarwindow.cxx | 3 | ||||
-rw-r--r-- | vcl/unx/gtk/gtksalmenu.cxx | 73 |
7 files changed, 117 insertions, 7 deletions
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 */ |