From 94a945d71492f4edd2c9c3d6be2f794b99f91886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= Date: Fri, 16 Mar 2018 16:50:42 +0000 Subject: [PATCH] rhbz#1392145 ensure titlebar close button matches 'outside' direction Change-Id: I20e925c58adb56acd4d1a63720d330c8b6613441 --- vcl/inc/unx/gtk/gtkframe.hxx | 1 + vcl/source/app/svmain.cxx | 11 ++++++++++- vcl/unx/gtk3/gtk3gtkframe.cxx | 32 +++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index cf644b2..ca1d38c 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -173,6 +173,7 @@ class GtkSalFrame : public SalFrame SalX11Screen m_nXScreen; GtkWidget* m_pWindow; #if GTK_CHECK_VERSION(3,0,0) + GtkHeaderBar* m_pHeaderBar; GtkGrid* m_pTopLevelGrid; #endif GtkEventBox* m_pEventBox; diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index d5bab35..d38fc19 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -31,7 +31,7 @@ #include #include - +#include #include #include #include @@ -324,6 +324,15 @@ bool InitVCL() // soffice/sfx implementation creates the global service manager pSVData->mpApp->Init(); + try + { + MsLangId::getSystemUILanguage(); //call this now to pin what the system UI really was + } + catch (const uno::Exception &e) + { + //SAL_INFO("vcl.app", "Unable to get ui language: '" << e); + } + pSVData->mpDefInst->AfterAppInit(); // Fetch AppFileName and make it absolute before the workdir changes... diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index c69aa3f..786d005 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -77,6 +77,8 @@ # include #endif +#include + #include #include @@ -484,6 +486,7 @@ bool GtkSalFrame::doKeyCallback( guint state, GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) : m_nXScreen( getDisplay()->GetDefaultXScreen() ) + , m_pHeaderBar(nullptr) , m_pGraphics(nullptr) , m_bGraphics(false) { @@ -496,6 +499,7 @@ GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) GtkSalFrame::GtkSalFrame( SystemParentData* pSysData ) : m_nXScreen( getDisplay()->GetDefaultXScreen() ) + , m_pHeaderBar(nullptr) , m_pGraphics(nullptr) , m_bGraphics(false) { @@ -1272,6 +1276,27 @@ void GtkSalFrame::Init( SalFrame* pParent, SalFrameStyleFlags nStyle ) gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), eType ); gtk_window_set_gravity( GTK_WINDOW(m_pWindow), GDK_GRAVITY_STATIC ); gtk_window_set_resizable( GTK_WINDOW(m_pWindow), bool(nStyle & SalFrameStyleFlags::SIZEABLE) ); + +#if defined(GDK_WINDOWING_WAYLAND) + //rhbz#1392145 under wayland/csd if we've overridden the default widget direction in order to set LibreOffice's + //UI to the configured ui language but the system ui locale is a different text direction, then the toplevel + //built-in close button of the titlebar follows the overridden direction rather than continue in the same + //direction as every other titlebar on the user's desktop. So if they don't match set an explicit + //header bar with the desired 'outside' direction + if ((eType == GDK_WINDOW_TYPE_HINT_NORMAL || eType == GDK_WINDOW_TYPE_HINT_DIALOG) && GDK_IS_WAYLAND_DISPLAY(GtkSalFrame::getGdkDisplay())) + { + const bool bDesktopIsRTL = MsLangId::isRightToLeft(MsLangId::getSystemUILanguage()); + const bool bAppIsRTL = gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL; + if (bDesktopIsRTL != bAppIsRTL) + { + m_pHeaderBar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_set_direction(GTK_WIDGET(m_pHeaderBar), bDesktopIsRTL ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); + gtk_header_bar_set_show_close_button(m_pHeaderBar, true); + gtk_window_set_titlebar(GTK_WINDOW(m_pWindow), GTK_WIDGET(m_pHeaderBar)); + gtk_widget_show(GTK_WIDGET(m_pHeaderBar)); + } + } +#endif } else if( (nStyle & SalFrameStyleFlags::FLOAT) ) gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), GDK_WINDOW_TYPE_HINT_POPUP_MENU ); @@ -1366,7 +1391,12 @@ void GtkSalFrame::SetTitle( const OUString& rTitle ) { m_aTitle = rTitle; if( m_pWindow && ! isChild() ) - gtk_window_set_title( GTK_WINDOW(m_pWindow), OUStringToOString( rTitle, RTL_TEXTENCODING_UTF8 ).getStr() ); + { + OString sTitle(OUStringToOString(rTitle, RTL_TEXTENCODING_UTF8)); + gtk_window_set_title(GTK_WINDOW(m_pWindow), sTitle.getStr()); + if (m_pHeaderBar) + gtk_header_bar_set_title(m_pHeaderBar, sTitle.getStr()); + } } void GtkSalFrame::SetIcon( sal_uInt16 nIcon ) -- 2.14.3