gtk4: wrap gtk_widget_get_root vs gtk_widget_get_toplevel

Change-Id: I416b157defd927e7c2fa828c5d3b3ba2a5e20c5a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115448
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/vcl/inc/unx/gtk/gtkdata.hxx b/vcl/inc/unx/gtk/gtkdata.hxx
index daa072b..da1d871 100644
--- a/vcl/inc/unx/gtk/gtkdata.hxx
+++ b/vcl/inc/unx/gtk/gtkdata.hxx
@@ -68,6 +68,15 @@ inline void css_provider_load_from_data(GtkCssProvider *css_provider,
#endif
}

inline GtkWidget* widget_get_root(GtkWidget* pWidget)
{
#if GTK_CHECK_VERSION(4, 0, 0)
    return GTK_WIDGET(gtk_widget_get_root(pWidget));
#else
    return gtk_widget_get_toplevel(pWidget);
#endif
}

class GtkSalTimer final : public SalTimer
{
    struct SalGtkTimeoutSource *m_pTimeout;
diff --git a/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx b/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx
index 441cc81..41ff066 100644
--- a/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx
+++ b/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx
@@ -34,8 +34,9 @@
#include <tools/urlobj.hxx>

#include <vcl/window.hxx>
#include <unx/gtk/gtkframe.hxx>
#include <unx/gtk/gtkdata.hxx>
#include <unx/gtk/gtkinst.hxx>
#include <unx/gtk/gtkframe.hxx>
#include "SalGtkPicker.hxx"

using namespace ::rtl;
@@ -94,23 +95,13 @@ extern "C"

GtkWindow* RunDialog::GetTransientFor()
{
    GtkWindow *pParent = nullptr;

    vcl::Window * pWindow = ::Application::GetActiveTopWindow();
    if( pWindow )
    {
        GtkSalFrame *pFrame = dynamic_cast<GtkSalFrame *>( pWindow->ImplGetFrame() );
        if( pFrame )
        {
#if !GTK_CHECK_VERSION(4, 0, 0)
            pParent = GTK_WINDOW(gtk_widget_get_toplevel(pFrame->getWindow()));
#else
            pParent = GTK_WINDOW(gtk_widget_get_root(pFrame->getWindow()));
#endif
        }
    }

    return pParent;
    if (!pWindow)
        return nullptr;
    GtkSalFrame *pFrame = dynamic_cast<GtkSalFrame*>(pWindow->ImplGetFrame());
    if (!pFrame)
        return nullptr;
    return GTK_WINDOW(widget_get_root(pFrame->getWindow()));
}

RunDialog::RunDialog(GtkWidget *pDialog, const uno::Reference<awt::XExtendedToolkit>& rToolkit,
diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx
index e6363ee..c40a6b7 100644
--- a/vcl/unx/gtk3/gtkframe.cxx
+++ b/vcl/unx/gtk3/gtkframe.cxx
@@ -1252,12 +1252,10 @@ void GtkSalFrame::Init( SalFrame* pParent, SalFrameStyleFlags nStyle )
    {
        if (m_pParent)
        {
            GtkWidget* pTopLevel = widget_get_root(m_pParent->m_pWindow);
#if !GTK_CHECK_VERSION(4,0,0)
            GtkWidget* pTopLevel = gtk_widget_get_toplevel(m_pParent->m_pWindow);
            if (!isChild())
                gtk_window_set_screen(GTK_WINDOW(m_pWindow), gtk_widget_get_screen(pTopLevel));
#else
            GtkWidget* pTopLevel = GTK_WIDGET(gtk_widget_get_root(m_pParent->m_pWindow));
#endif

            if (!(m_pParent->m_nStyle & SalFrameStyleFlags::PLUG))
@@ -3669,7 +3667,7 @@ void GtkSalFrame::signalSetFocus(GtkWindow*, GtkWidget* pWidget, gpointer frame)
    else
        pGrabWidget = GTK_WIDGET(pThis->m_pFixedContainer);

    GtkWidget* pTopLevel = gtk_widget_get_toplevel(pGrabWidget);
    GtkWidget* pTopLevel = widget_get_root(pGrabWidget);
    // see commentary in GtkSalObjectWidgetClip::Show
    if (pTopLevel && g_object_get_data(G_OBJECT(pTopLevel), "g-lo-BlockFocusChange"))
        return;
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 19ad0f0..5a2392e 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -2122,11 +2122,7 @@ protected:

    void signal_focus_in()
    {
#if !GTK_CHECK_VERSION(4, 0, 0)
        GtkWidget* pTopLevel = gtk_widget_get_toplevel(m_pWidget);
#else
        GtkWidget* pTopLevel = GTK_WIDGET(gtk_widget_get_root(m_pWidget));
#endif
        GtkWidget* pTopLevel = widget_get_root(m_pWidget);
        // see commentary in GtkSalObjectWidgetClip::Show
        if (pTopLevel && g_object_get_data(G_OBJECT(pTopLevel), "g-lo-BlockFocusChange"))
            return;
@@ -2167,11 +2163,7 @@ protected:

    void signal_focus_out()
    {
#if !GTK_CHECK_VERSION(4, 0, 0)
        GtkWidget* pTopLevel = gtk_widget_get_toplevel(m_pWidget);
#else
        GtkWidget* pTopLevel = GTK_WIDGET(gtk_widget_get_root(m_pWidget));
#endif
        GtkWidget* pTopLevel = widget_get_root(m_pWidget);
        // see commentary in GtkSalObjectWidgetClip::Show
        if (pTopLevel && g_object_get_data(G_OBJECT(pTopLevel), "g-lo-BlockFocusChange"))
            return;
@@ -2782,11 +2774,7 @@ public:

    virtual bool is_active() const override
    {
#if !GTK_CHECK_VERSION(4, 0, 0)
        GtkWindow* pTopLevel = GTK_WINDOW(gtk_widget_get_toplevel(m_pWidget));
#else
        GtkWindow* pTopLevel = GTK_WINDOW(gtk_widget_get_root(m_pWidget));
#endif
        GtkWindow* pTopLevel = GTK_WINDOW(widget_get_root(m_pWidget));
        return pTopLevel && gtk_window_is_active(pTopLevel) && has_focus();
    }

@@ -3195,11 +3183,7 @@ public:

    GtkWindow* getWindow()
    {
#if !GTK_CHECK_VERSION(4, 0, 0)
        return GTK_WINDOW(gtk_widget_get_toplevel(m_pWidget));
#else
        return GTK_WINDOW(gtk_widget_get_root(m_pWidget));
#endif
        return GTK_WINDOW(widget_get_root(m_pWidget));
    }

    virtual void connect_focus_in(const Link<Widget&, void>& rLink) override
@@ -4425,19 +4409,16 @@ namespace

    void do_collect_screenshot_data(GtkWidget* pItem, gpointer data)
    {
#if !GTK_CHECK_VERSION(4, 0, 0)
        GtkWidget* pTopLevel = gtk_widget_get_toplevel(pItem);
        GtkWidget* pTopLevel = widget_get_root(pItem);

#if !GTK_CHECK_VERSION(4, 0, 0)
        int x, y;
        gtk_widget_translate_coordinates(pItem, pTopLevel, 0, 0, &x, &y);
#else
        GtkWidget* pTopLevel = GTK_WIDGET(gtk_widget_get_root(pItem));

        double x, y;
        gtk_widget_translate_coordinates(pItem, pTopLevel, 0, 0, &x, &y);
#endif


        Point aOffset = get_csd_offset(pTopLevel);

        GtkAllocation alloc;
@@ -8006,7 +7987,7 @@ void do_ungrab(GtkWidget* pWidget)
GtkPositionType show_menu_older_gtk(GtkWidget* pMenuButton, GtkWindow* pMenu)
{
    //place the toplevel just below its launcher button
    GtkWidget* pToplevel = gtk_widget_get_toplevel(pMenuButton);
    GtkWidget* pToplevel = widget_get_root(pMenuButton);
    gint x, y, absx, absy;
    gtk_widget_translate_coordinates(pMenuButton, pToplevel, 0, 0, &x, &y);
    GdkWindow *pWindow = gtk_widget_get_window(pToplevel);
@@ -8105,7 +8086,7 @@ bool show_menu_newer_gtk(GtkWidget* pComboBox, GtkWindow* pMenu)
#endif

    //place the toplevel just below its launcher button
    GtkWidget* pToplevel = gtk_widget_get_toplevel(pComboBox);
    GtkWidget* pToplevel = widget_get_root(pComboBox);
    gint x, y;
    gtk_widget_translate_coordinates(pComboBox, pToplevel, 0, 0, &x, &y);

@@ -8146,7 +8127,7 @@ GtkPositionType show_menu(GtkWidget* pMenuButton, GtkWindow* pMenu)
    // the same top level parent. The problem is that since gtk 3.24 tooltips are also
    // implemented as popups, which means that we cannot show any popup if there is a
    // visible tooltip.
    GtkWidget* pParent = gtk_widget_get_toplevel(pMenuButton);
    GtkWidget* pParent = widget_get_root(pMenuButton);
    GtkSalFrame* pFrame = pParent ? GtkSalFrame::getFromWindow(pParent) : nullptr;
    if (pFrame)
    {
@@ -8215,7 +8196,7 @@ private:
            gtk_widget_set_size_request(GTK_WIDGET(m_pMenuHack), -1, -1);

            // undo show_menu tooltip blocking
            GtkWidget* pParent = gtk_widget_get_toplevel(GTK_WIDGET(m_pMenuButton));
            GtkWidget* pParent = widget_get_root(GTK_WIDGET(m_pMenuButton));
            GtkSalFrame* pFrame = pParent ? GtkSalFrame::getFromWindow(pParent) : nullptr;
            if (pFrame)
                pFrame->UnblockTooltip();
@@ -9567,11 +9548,7 @@ public:
        if (gtk_widget_has_focus(m_pWidget))
            return true;

#if !GTK_CHECK_VERSION(4, 0, 0)
        GtkWidget* pTopLevel = gtk_widget_get_toplevel(m_pWidget);
#else
        GtkWidget* pTopLevel = GTK_WIDGET(gtk_widget_get_root(m_pWidget));
#endif
        GtkWidget* pTopLevel = widget_get_root(m_pWidget);
        if (!GTK_IS_WINDOW(pTopLevel))
            return false;
        GtkWidget* pFocus = gtk_window_get_focus(GTK_WINDOW(pTopLevel));
@@ -15251,11 +15228,7 @@ private:
                tree_view_set_cursor(m_nPrePopupCursorPos);

            // undo show_menu tooltip blocking
#if !GTK_CHECK_VERSION(4, 0, 0)
            GtkWidget* pParent = gtk_widget_get_toplevel(m_pToggleButton);
#else
            GtkWidget* pParent = GTK_WIDGET(gtk_widget_get_root(m_pToggleButton));
#endif
            GtkWidget* pParent = widget_get_root(m_pToggleButton);
            GtkSalFrame* pFrame = pParent ? GtkSalFrame::getFromWindow(pParent) : nullptr;
            if (pFrame)
                pFrame->UnblockTooltip();
@@ -15451,11 +15424,7 @@ private:
    bool combobox_activate()
    {
        GtkWidget *pComboBox = GTK_WIDGET(m_pToggleButton);
#if !GTK_CHECK_VERSION(4, 0, 0)
        GtkWidget *pToplevel = gtk_widget_get_toplevel(pComboBox);
#else
        GtkWidget *pToplevel = GTK_WIDGET(gtk_widget_get_root(pComboBox));
#endif
        GtkWidget *pToplevel = widget_get_root(pComboBox);
        GtkWindow *pWindow = GTK_WINDOW(pToplevel);
        if (!pWindow)
            return false;
@@ -17225,11 +17194,7 @@ private:

        if (gtk_expander_get_resize_toplevel(pExpander))
        {
#if !GTK_CHECK_VERSION(4, 0, 0)
            GtkWidget *pToplevel = gtk_widget_get_toplevel(GTK_WIDGET(pExpander));
#else
            GtkWidget *pToplevel = GTK_WIDGET(gtk_widget_get_root(pExpander));
#endif
            GtkWidget *pToplevel = widget_get_root(GTK_WIDGET(pExpander));

            // https://gitlab.gnome.org/GNOME/gtk/issues/70
            // I imagine at some point a release with a fix will be available in which
@@ -17654,11 +17619,7 @@ private:
    {
        assert(!m_bAllowCycleFocusOut); // we only expect this to be called when this holds

#if !GTK_CHECK_VERSION(4, 0, 0)
        GtkWidget* pTopLevel = gtk_widget_get_toplevel(m_pParentWidget);
#else
        GtkWidget *pToplevel = GTK_WIDGET(gtk_widget_get_root(m_pParentWidget));
#endif
        GtkWidget* pTopLevel = widget_get_root(m_pParentWidget);
        assert(pTopLevel);
        GtkSalFrame* pFrame = GtkSalFrame::getFromWindow(pTopLevel);
        assert(pFrame);
@@ -17679,11 +17640,7 @@ private:
    {
        assert(!m_bAllowCycleFocusOut); // we only expect this to be called when this holds

#if !GTK_CHECK_VERSION(4, 0, 0)
        GtkWidget* pTopLevel = gtk_widget_get_toplevel(m_pParentWidget);
#else
        GtkWidget *pToplevel = GTK_WIDGET(gtk_widget_get_root(m_pParentWidget));
#endif
        GtkWidget* pTopLevel = widget_get_root(m_pParentWidget);
        assert(pTopLevel);
        GtkSalFrame* pFrame = GtkSalFrame::getFromWindow(pTopLevel);
        assert(pFrame);
@@ -17823,7 +17780,7 @@ public:
    void auto_add_parentless_widgets_to_container(GtkWidget* pWidget)
    {
#if !GTK_CHECK_VERSION(4, 0, 0)
        if (gtk_widget_get_toplevel(pWidget) == pWidget && !GTK_IS_POPOVER(pWidget) && !GTK_IS_WINDOW(pWidget))
        if (widget_get_root(pWidget) == pWidget && !GTK_IS_POPOVER(pWidget) && !GTK_IS_WINDOW(pWidget))
            gtk_container_add(GTK_CONTAINER(m_pParentWidget), pWidget);
#else
        (void)pWidget;
@@ -17835,7 +17792,7 @@ public:
        GtkMessageDialog* pMessageDialog = GTK_MESSAGE_DIALOG(gtk_builder_get_object(m_pBuilder, id.getStr()));
        if (!pMessageDialog)
            return nullptr;
        gtk_window_set_transient_for(GTK_WINDOW(pMessageDialog), GTK_WINDOW(gtk_widget_get_toplevel(m_pParentWidget)));
        gtk_window_set_transient_for(GTK_WINDOW(pMessageDialog), GTK_WINDOW(widget_get_root(m_pParentWidget)));
        return std::make_unique<GtkInstanceMessageDialog>(pMessageDialog, this, true);
    }

@@ -17845,7 +17802,7 @@ public:
        if (!pAssistant)
            return nullptr;
        if (m_pParentWidget)
            gtk_window_set_transient_for(GTK_WINDOW(pAssistant), GTK_WINDOW(gtk_widget_get_toplevel(m_pParentWidget)));
            gtk_window_set_transient_for(GTK_WINDOW(pAssistant), GTK_WINDOW(widget_get_root(m_pParentWidget)));
        return std::make_unique<GtkInstanceAssistant>(pAssistant, this, true);
    }

@@ -17855,7 +17812,7 @@ public:
        if (!pDialog)
            return nullptr;
        if (m_pParentWidget)
            gtk_window_set_transient_for(pDialog, GTK_WINDOW(gtk_widget_get_toplevel(m_pParentWidget)));
            gtk_window_set_transient_for(pDialog, GTK_WINDOW(widget_get_root(m_pParentWidget)));
        return std::make_unique<GtkInstanceDialog>(pDialog, this, true);
    }

@@ -17893,7 +17850,7 @@ public:
        }

        if (m_pParentWidget)
            gtk_window_set_transient_for(pDialog, GTK_WINDOW(gtk_widget_get_toplevel(m_pParentWidget)));
            gtk_window_set_transient_for(pDialog, GTK_WINDOW(widget_get_root(m_pParentWidget)));
        return std::make_unique<GtkInstanceDialog>(pDialog, this, true);
    }

@@ -18432,7 +18389,7 @@ weld::Window* GtkSalFrame::GetFrameWeld() const
{
#if !GTK_CHECK_VERSION(4, 0, 0)
    if (!m_xFrameWeld)
        m_xFrameWeld.reset(new GtkInstanceWindow(GTK_WINDOW(gtk_widget_get_toplevel(getWindow())), nullptr, false));
        m_xFrameWeld.reset(new GtkInstanceWindow(GTK_WINDOW(widget_get_root(getWindow())), nullptr, false));
#endif
    return m_xFrameWeld.get();
}
diff --git a/vcl/unx/gtk3/gtkobject.cxx b/vcl/unx/gtk3/gtkobject.cxx
index d44b7bc..a0fdbd4 100644
--- a/vcl/unx/gtk3/gtkobject.cxx
+++ b/vcl/unx/gtk3/gtkobject.cxx
@@ -499,11 +499,7 @@ void GtkSalObjectWidgetClip::Show( bool bVisible )
        // cursor in a sidebar comment and scroll the page so the comment is invisible, we want the focus
        // to stay in the invisible widget, so its there when we scroll back or on a keypress the widget
        // gets the keystroke and scrolls back to make it visible again
#if !GTK_CHECK_VERSION(4, 0, 0)
        GtkWidget* pTopLevel = gtk_widget_get_toplevel(m_pScrolledWindow);
#else
        GtkWidget* pTopLevel = GTK_WIDGET(gtk_widget_get_root(m_pScrolledWindow));
#endif
        GtkWidget* pTopLevel = widget_get_root(m_pScrolledWindow);
        GtkWidget* pOldFocus = GTK_IS_WINDOW(pTopLevel) ? gtk_window_get_focus(GTK_WINDOW(pTopLevel)) : nullptr;

        g_object_set_data(G_OBJECT(pTopLevel), "g-lo-BlockFocusChange", GINT_TO_POINTER(true) );
diff --git a/vcl/unx/gtk3/salnativewidgets-gtk.cxx b/vcl/unx/gtk3/salnativewidgets-gtk.cxx
index 42d7250..6cfc8b3 100644
--- a/vcl/unx/gtk3/salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk3/salnativewidgets-gtk.cxx
@@ -1024,7 +1024,7 @@ GtkStyleContext* GtkSalGraphics::makeContext(GtkWidgetPath *pPath, GtkStyleConte
    gtk_style_context_set_path(context, pPath);
    if (pParent == nullptr)
    {
        GtkWidget* pTopLevel = gtk_widget_get_toplevel(mpWindow);
        GtkWidget* pTopLevel = widget_get_root(mpWindow);
        GtkStyleContext* pStyle = gtk_widget_get_style_context(pTopLevel);
        gtk_style_context_set_parent(context, pStyle);
        gtk_style_context_set_scale (context, gtk_style_context_get_scale (pStyle));
@@ -1707,7 +1707,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
        renderType = RenderType::TabItem;
        break;
    case ControlType::WindowBackground:
        context = gtk_widget_get_style_context(gtk_widget_get_toplevel(mpWindow));
        context = gtk_widget_get_style_context(widget_get_root(mpWindow));
        break;
    case ControlType::Frame:
    {
@@ -2221,7 +2221,7 @@ vcl::Font pango_to_vcl(const PangoFontDescription* font, const css::lang::Locale
bool GtkSalGraphics::updateSettings(AllSettings& rSettings)
{
#if !GTK_CHECK_VERSION(4, 0, 0)
    GtkWidget* pTopLevel = gtk_widget_get_toplevel(mpWindow);
    GtkWidget* pTopLevel = widget_get_root(mpWindow);
    GtkStyleContext* pStyle = gtk_widget_get_style_context(pTopLevel);
    StyleContextSave aContextState;
    aContextState.save(pStyle);