Resolves: tdf#130070 keep dropdown menu fully on screen

if possible

Change-Id: I2ec3b54516ec713421288a4a30a9a7296c8d3e75
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87026
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index f4424ac..fdc09fa 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -3536,6 +3536,16 @@ namespace
            gtk_container_forall(GTK_CONTAINER(pItem), do_collect_screenshot_data, data);
    }

    tools::Rectangle get_monitor_workarea(GtkWidget* pWindow)
    {
        GdkScreen* pScreen = gtk_widget_get_screen(pWindow);
        gint nMonitor = gdk_screen_get_monitor_at_window(pScreen, gtk_widget_get_window(pWindow));
        GdkRectangle aRect;
        gdk_screen_get_monitor_workarea(pScreen, nMonitor, &aRect);
        return tools::Rectangle(aRect.x, aRect.y, aRect.x + aRect.width, aRect.y + aRect.height);
    }


class GtkInstanceWindow : public GtkInstanceContainer, public virtual weld::Window
{
private:
@@ -3634,11 +3644,7 @@ public:

    virtual tools::Rectangle get_monitor_workarea() const override
    {
        GdkScreen* pScreen = gtk_widget_get_screen(GTK_WIDGET(m_pWindow));
        gint nMonitor = gdk_screen_get_monitor_at_window(pScreen, gtk_widget_get_window(GTK_WIDGET(m_pWindow)));
        GdkRectangle aRect;
        gdk_screen_get_monitor_workarea(pScreen, nMonitor, &aRect);
        return tools::Rectangle(aRect.x, aRect.y, aRect.x + aRect.width, aRect.y + aRect.height);
        return ::get_monitor_workarea(GTK_WIDGET(m_pWindow));
    }

    virtual void set_centered_on_parent(bool bTrackGeometryRequests) override
@@ -6521,12 +6527,35 @@ private:
            gtk_widget_translate_coordinates(GTK_WIDGET(m_pMenuButton), pToplevel, 0, 0, &x, &y);
            GdkWindow *pWindow = gtk_widget_get_window(pToplevel);
            gdk_window_get_position(pWindow, &absx, &absy);
            x += absx;
            y += absy;

            gint nButtonHeight = gtk_widget_get_allocated_height(GTK_WIDGET(m_pMenuButton));
            y += nButtonHeight;

            gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(pToplevel)), m_pMenuHack);
            gtk_window_set_transient_for(m_pMenuHack, GTK_WINDOW(pToplevel));

            gtk_widget_show_all(GTK_WIDGET(m_pMenuHack));
            gtk_window_move(m_pMenuHack, x + absx, y + absy + gtk_widget_get_allocated_height(GTK_WIDGET(m_pMenuButton)));

            tools::Rectangle aWorkArea(::get_monitor_workarea(GTK_WIDGET(m_pMenuHack)));
            gint endx = x + gtk_widget_get_allocated_width(GTK_WIDGET(m_pMenuHack));
            if (endx > aWorkArea.Right())
            {
                x -= endx - aWorkArea.Right();
                if (x < 0)
                    x = 0;
            }
            gint nMenuHeight = gtk_widget_get_allocated_height(GTK_WIDGET(m_pMenuHack));
            gint endy = y + nMenuHeight;
            if (endy > aWorkArea.Bottom())
            {
                y -= nButtonHeight + nMenuHeight;
                if (y < 0)
                    y = 0;
            }

            gtk_window_move(m_pMenuHack, x, y);

            gtk_widget_grab_focus(GTK_WIDGET(m_pMenuHack));