diff options
author | Maxim Monastirsky <momonasmon@gmail.com> | 2018-06-11 02:08:54 +0300 |
---|---|---|
committer | Maxim Monastirsky <momonasmon@gmail.com> | 2018-06-26 12:00:11 +0200 |
commit | e223e70f5d92e2ed027fc5d449bd790a123acdc2 (patch) | |
tree | 403c03932e5d17d9757498faab46207be604f74e | |
parent | 1ba347a92e3a821d35fccc8ff58b574dd2f3abd6 (diff) |
tdf#117175 wayland: Make popup windows not show off-screen
Depends on the gtk-3-24 dev branch, for the public
gdk_window_move_to_rect symbol.
(cherry picked from commit 0da89ede1fee3a9079b7b41ee8b34504ddeb5ee5)
Correctly mirror autofilter in rtl ui, tdf#117175 related
(cherry picked from commit 2bfc4cefc21ab18e9ff7cc5fdc743bcc856d103c)
Fix lists position in dialogs
Regression of 2bfc4cefc21ab18e9ff7cc5fdc743bcc856d103c
("Correctly mirror autofilter in rtl ui, tdf#117175 related")
If a window has a parent, it doesn't necessarily mean it's
not a top level.
(cherry picked from commit eb84dcb9c0a202f4917169acdce50775778b72ec)
Change-Id: Ic7a34ceb3d133ecac2addac54cf5f635eea332ed
Reviewed-on: https://gerrit.libreoffice.org/56439
Tested-by: Jenkins
Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
-rw-r--r-- | vcl/inc/salframe.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 6 | ||||
-rw-r--r-- | vcl/source/window/floatwin.cxx | 1 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkframe.cxx | 79 |
4 files changed, 86 insertions, 1 deletions
diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx index 4f73a724e377..f1d4a05e5662 100644 --- a/vcl/inc/salframe.hxx +++ b/vcl/inc/salframe.hxx @@ -159,6 +159,7 @@ public: SAL_WARN_UNUSED_RESULT virtual bool GetWindowState( SalFrameState* pState ) = 0; virtual void ShowFullScreen( bool bFullScreen, sal_Int32 nDisplay ) = 0; + virtual void PositionByToolkit( const tools::Rectangle&, FloatWinPopupFlags ) {}; // Enable/Disable ScreenSaver, SystemAgents, ... virtual void StartPresentation( bool bStart ) = 0; diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index 0ead3d4b3beb..04ec68a7854e 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -210,7 +210,10 @@ class GtkSalFrame : public SalFrame #if GTK_CHECK_VERSION(3,0,0) OUString m_aTooltip; - tools::Rectangle m_aHelpArea; + tools::Rectangle m_aHelpArea; + tools::Rectangle m_aFloatRect; + FloatWinPopupFlags m_nFloatFlags; + bool m_bFloatPositioned; long m_nWidthRequest; long m_nHeightRequest; cairo_region_t* m_pRegion; @@ -532,6 +535,7 @@ public: virtual void EndSetClipRegion() override; #if GTK_CHECK_VERSION(3,0,0) + virtual void PositionByToolkit(const tools::Rectangle& rRect, FloatWinPopupFlags nFlags) override; virtual void SetModal(bool bModal) override; virtual bool ShowTooltip(const OUString& rHelpText, const tools::Rectangle& rHelpArea) override; virtual void* ShowPopover(const OUString& rHelpText, vcl::Window* pParent, const tools::Rectangle& rHelpArea, QuickHelpFlags nFlags) override; diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx index 0ba23a39d6d8..ea1001f3351e 100644 --- a/vcl/source/window/floatwin.cxx +++ b/vcl/source/window/floatwin.cxx @@ -741,6 +741,7 @@ void FloatingWindow::StartPopupMode( const tools::Rectangle& rRect, FloatWinPopu DoInitialLayout(); mpImplData->maPos = ImplCalcPos(this, rRect, nFlags, nArrangeIndex, &mpImplData->maLOKTwipsPos); SetPosPixel( mpImplData->maPos ); + ImplGetFrame()->PositionByToolkit(rRect, nFlags); // set data and display window // convert maFloatRect to absolute device coordinates diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index 0014f176a7fa..6a443526e8db 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -1130,6 +1130,9 @@ void GtkSalFrame::InitCommon() m_bGraphics = false; m_pGraphics = nullptr; + m_nFloatFlags = FloatWinPopupFlags::NONE; + m_bFloatPositioned = false; + m_nWidthRequest = 0; m_nHeightRequest = 0; @@ -2447,6 +2450,16 @@ void GtkSalFrame::EndSetClipRegion() gdk_window_shape_combine_region( widget_get_window(m_pWindow), m_pRegion, 0, 0 ); } +void GtkSalFrame::PositionByToolkit(const tools::Rectangle& rRect, FloatWinPopupFlags nFlags) +{ + if (ImplGetSVData()->maNWFData.mbCanDetermineWindowPosition) + return; + + m_aFloatRect = rRect; + m_nFloatFlags = nFlags; + m_bFloatPositioned = true; +} + void GtkSalFrame::SetModal(bool bModal) { if (!m_pWindow) @@ -2990,6 +3003,24 @@ void GtkSalFrame::sizeAllocated(GtkWidget* pWidget, GdkRectangle *pAllocation, g pThis->TriggerPaintEvent(); } +#if GTK_CHECK_VERSION(3,23,0) +namespace { + +void swapDirection(GdkGravity& gravity) +{ + if (gravity == GDK_GRAVITY_NORTH_WEST) + gravity = GDK_GRAVITY_NORTH_EAST; + else if (gravity == GDK_GRAVITY_NORTH_EAST) + gravity = GDK_GRAVITY_NORTH_WEST; + else if (gravity == GDK_GRAVITY_SOUTH_WEST) + gravity = GDK_GRAVITY_SOUTH_EAST; + else if (gravity == GDK_GRAVITY_SOUTH_EAST) + gravity = GDK_GRAVITY_SOUTH_WEST; +} + +} +#endif + void GtkSalFrame::signalRealize(GtkWidget*, gpointer frame) { GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); @@ -2997,6 +3028,45 @@ void GtkSalFrame::signalRealize(GtkWidget*, gpointer frame) if (pThis->m_bSalObjectSetPosSize) return; pThis->TriggerPaintEvent(); + +#if GTK_CHECK_VERSION(3,23,0) + if (gtk_check_version(3, 23, 0) == nullptr && pThis->m_bFloatPositioned) + { + GdkGravity rect_anchor = GDK_GRAVITY_SOUTH_WEST, menu_anchor = GDK_GRAVITY_NORTH_WEST; + + if (pThis->m_nFloatFlags & FloatWinPopupFlags::Left) + { + rect_anchor = GDK_GRAVITY_NORTH_WEST; + menu_anchor = GDK_GRAVITY_NORTH_EAST; + } + else if (pThis->m_nFloatFlags & FloatWinPopupFlags::Up) + { + rect_anchor = GDK_GRAVITY_NORTH_WEST; + menu_anchor = GDK_GRAVITY_SOUTH_WEST; + } + else if (pThis->m_nFloatFlags & FloatWinPopupFlags::Right) + { + rect_anchor = GDK_GRAVITY_NORTH_EAST; + } + + VclPtr<vcl::Window> pVclParent = pThis->GetWindow()->GetParent(); + if (pVclParent->HasMirroredGraphics() && pVclParent->IsRTLEnabled()) + { + swapDirection(rect_anchor); + swapDirection(menu_anchor); + } + + tools::Rectangle aFloatRect = FloatingWindow::ImplConvertToAbsPos(pVclParent, pThis->m_aFloatRect); + if (gdk_window_get_window_type(widget_get_window(pThis->m_pParent->m_pWindow)) != GDK_WINDOW_TOPLEVEL) + aFloatRect.Move(-pThis->m_pParent->maGeometry.nX, -pThis->m_pParent->maGeometry.nY); + + GdkRectangle rect {static_cast<int>(aFloatRect.Left()), static_cast<int>(aFloatRect.Top()), + static_cast<int>(aFloatRect.GetWidth()), static_cast<int>(aFloatRect.GetHeight())}; + + GdkWindow* gdkWindow = widget_get_window(pThis->m_pWindow); + gdk_window_move_to_rect(gdkWindow, &rect, rect_anchor, menu_anchor, GDK_ANCHOR_FLIP, 0, 0); + } +#endif } gboolean GtkSalFrame::signalConfigure(GtkWidget*, GdkEventConfigure* pEvent, gpointer frame) @@ -3106,6 +3176,15 @@ gboolean GtkSalFrame::signalUnmap( GtkWidget*, GdkEvent*, gpointer frame ) pThis->CallCallbackExc( SalEvent::Resize, nullptr ); + if (pThis->m_bFloatPositioned) + { + // Unrealize is needed for cases where we reuse the same popup + // (e.g. the font name control), making the realize signal fire + // again on next show. + gtk_widget_unrealize(pThis->m_pWindow); + pThis->m_bFloatPositioned = false; + } + return false; } |