summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2022-02-08 09:11:28 +0000
committerCaolán McNamara <caolanm@redhat.com>2022-02-08 21:52:41 +0100
commit50bad83484f7f36c2e43b6df8390ee280fc4d469 (patch)
treedaf6bc3fc346cb6b010a5e6a8f1f39a496f36b36 /vcl
parent2f7a0b81f21f7e383808c2e5f5d532cb50b84376 (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.cxx51
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));
}