diff options
author | Caolán McNamara <caolanm@redhat.com> | 2022-02-08 09:11:28 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2022-02-08 21:52:41 +0100 |
commit | 50bad83484f7f36c2e43b6df8390ee280fc4d469 (patch) | |
tree | daf6bc3fc346cb6b010a5e6a8f1f39a496f36b36 /vcl | |
parent | 2f7a0b81f21f7e383808c2e5f5d532cb50b84376 (diff) |
tdf#147251 can't generally shrink popovers if they don't fit under/over
so instead forget about forcing under/over if it doesn't fit on either
side and just position so its visible
Change-Id: I529bf0d2bb1a3108a8702792ef067372441c2002
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129662
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/unx/gtk3/gtkinst.cxx | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index fd6a66ea371e..3ddd6b9e59a0 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -9745,7 +9745,8 @@ void do_ungrab(GtkWidget* pWidget) gdk_seat_ungrab(pSeat); } -GtkPositionType show_menu_older_gtk(GtkWidget* pMenuButton, GtkWindow* pMenu, const GdkRectangle& rAnchor, weld::Placement ePlace) +GtkPositionType show_menu_older_gtk(GtkWidget* pMenuButton, GtkWindow* pMenu, const GdkRectangle& rAnchor, + weld::Placement ePlace, bool bTryShrink) { //place the toplevel just below its launcher button GtkWidget* pToplevel = widget_get_toplevel(pMenuButton); @@ -9815,18 +9816,31 @@ GtkPositionType show_menu_older_gtk(GtkWidget* pMenuButton, GtkWindow* pMenu, co if (nMissingBelow > 0) { gint nNewY = y - (nButtonHeight + nMenuHeight); - if (nNewY < aWorkArea.Top()) + gint nMissingAbove = aWorkArea.Top() - nNewY; + if (nMissingAbove > 0) { - gint nMissingAbove = aWorkArea.Top() - nNewY; - if (nMissingBelow <= nMissingAbove) - nMenuHeight -= nMissingBelow; + if (bTryShrink) + { + if (nMissingBelow <= nMissingAbove) + nMenuHeight -= nMissingBelow; + else + { + nMenuHeight -= nMissingAbove; + y = aWorkArea.Top(); + ePosUsed = GTK_POS_TOP; + } + gtk_widget_set_size_request(GTK_WIDGET(pMenu), nMenuWidth, nMenuHeight); + } else { - nMenuHeight -= nMissingAbove; - y = aWorkArea.Top(); - ePosUsed = GTK_POS_TOP; + if (nMissingBelow <= nMissingAbove) + y -= nMissingBelow; + else + { + y = aWorkArea.Top(); + ePosUsed = GTK_POS_TOP; + } } - gtk_widget_set_size_request(GTK_WIDGET(pMenu), nMenuWidth, nMenuHeight); } else { @@ -9874,7 +9888,8 @@ GtkPositionType show_menu_older_gtk(GtkWidget* pMenuButton, GtkWindow* pMenu, co return ePosUsed; } -bool show_menu_newer_gtk(GtkWidget* pComboBox, GtkWindow* pMenu, const GdkRectangle &rAnchor, weld::Placement ePlace) +bool show_menu_newer_gtk(GtkWidget* pComboBox, GtkWindow* pMenu, const GdkRectangle &rAnchor, + weld::Placement ePlace, bool bTryShrink) { static auto window_move_to_rect = reinterpret_cast<void (*) (GdkWindow*, const GdkRectangle*, GdkGravity, GdkGravity, GdkAnchorHints, gint, gint)>( @@ -9913,8 +9928,9 @@ bool show_menu_newer_gtk(GtkWidget* pComboBox, GtkWindow* pMenu, const GdkRectan menu_anchor = !bSwapForRTL ? GDK_GRAVITY_NORTH_WEST : GDK_GRAVITY_NORTH_EAST; } - GdkAnchorHints anchor_hints = static_cast<GdkAnchorHints>(GDK_ANCHOR_FLIP | GDK_ANCHOR_SLIDE | GDK_ANCHOR_RESIZE); - + GdkAnchorHints anchor_hints = static_cast<GdkAnchorHints>(GDK_ANCHOR_FLIP | GDK_ANCHOR_SLIDE); + if (bTryShrink) + anchor_hints = static_cast<GdkAnchorHints>(anchor_hints | GDK_ANCHOR_RESIZE); GdkRectangle rect {x, y, rAnchor.width, rAnchor.height}; GdkSurface* toplevel = widget_get_surface(GTK_WIDGET(pMenu)); @@ -9924,7 +9940,8 @@ bool show_menu_newer_gtk(GtkWidget* pComboBox, GtkWindow* pMenu, const GdkRectan return true; } -GtkPositionType show_menu(GtkWidget* pMenuButton, GtkWindow* pMenu, const GdkRectangle& rAnchor, weld::Placement ePlace) +GtkPositionType show_menu(GtkWidget* pMenuButton, GtkWindow* pMenu, const GdkRectangle& rAnchor, + weld::Placement ePlace, bool bTryShrink) { // we only use ePosUsed in the replacement-for-X-popover case of a // MenuButton, so we only need it when show_menu_older_gtk is used @@ -9945,8 +9962,8 @@ GtkPositionType show_menu(GtkWidget* pMenuButton, GtkWindow* pMenu, const GdkRec } // try with gdk_window_move_to_rect, but if that's not available, try without - if (!show_menu_newer_gtk(pMenuButton, pMenu, rAnchor, ePlace)) - ePosUsed = show_menu_older_gtk(pMenuButton, pMenu, rAnchor, ePlace); + if (!show_menu_newer_gtk(pMenuButton, pMenu, rAnchor, ePlace, bTryShrink)) + ePosUsed = show_menu_older_gtk(pMenuButton, pMenu, rAnchor, ePlace, bTryShrink); gtk_widget_show_all(GTK_WIDGET(pMenu)); gtk_widget_grab_focus(GTK_WIDGET(pMenu)); do_grab(GTK_WIDGET(pMenu)); @@ -9996,7 +10013,7 @@ GtkPositionType MovePopoverContentsToWindow(GtkWidget* pPopover, GtkWindow* pMen gtk_container_add(GTK_CONTAINER(pMenuHack), pChild); g_object_unref(pChild); - GtkPositionType eRet = show_menu(pAnchor, pMenuHack, rAnchor, ePlace); + GtkPositionType eRet = show_menu(pAnchor, pMenuHack, rAnchor, ePlace, false); gtk_grab_add(GTK_WIDGET(pMenuHack)); @@ -20062,7 +20079,7 @@ private: tree_view_set_cursor(0); GdkRectangle aAnchor {0, 0, gtk_widget_get_allocated_width(pComboBox), gtk_widget_get_allocated_height(pComboBox) }; - show_menu(pComboBox, m_pMenuWindow, aAnchor, weld::Placement::Under); + show_menu(pComboBox, m_pMenuWindow, aAnchor, weld::Placement::Under, true); GdkSurface* pSurface = widget_get_surface(GTK_WIDGET(m_pMenuWindow)); g_object_set_data(G_OBJECT(pSurface), "g-lo-InstancePopup", GINT_TO_POINTER(true)); } |