[Libreoffice-commits] core.git: basctl/source extensions/source include/vcl sc/source sfx2/source svtools/source vcl/inc vcl/source vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Thu Aug 27 18:14:29 UTC 2020


 basctl/source/basicide/bastypes.cxx            |    2 +-
 extensions/source/propctrlr/propcontroller.cxx |    2 +-
 include/vcl/InterimItemWindow.hxx              |    7 ++++++-
 include/vcl/svapp.hxx                          |    3 ++-
 sc/source/ui/cctrl/checklistmenu.cxx           |    2 +-
 sfx2/source/appl/newhelp.cxx                   |    2 +-
 sfx2/source/dialog/dockwin.cxx                 |    2 +-
 sfx2/source/sidebar/PanelLayout.cxx            |    2 +-
 svtools/source/control/toolbarmenu.cxx         |    2 +-
 vcl/inc/salinst.hxx                            |    3 ++-
 vcl/inc/unx/gtk/gtkframe.hxx                   |    3 +++
 vcl/inc/unx/gtk/gtkinst.hxx                    |    3 ++-
 vcl/source/app/salvtables.cxx                  |    2 +-
 vcl/source/control/InterimItemWindow.cxx       |    7 ++++---
 vcl/source/control/calendar.cxx                |    2 +-
 vcl/source/window/builder.cxx                  |    4 ++--
 vcl/unx/gtk3/gtk3gtkframe.cxx                  |   24 ++++++++++++++++++++++--
 vcl/unx/gtk3/gtk3gtkinst.cxx                   |   14 +++++++++++++-
 18 files changed, 65 insertions(+), 21 deletions(-)

New commits:
commit fce9d818e7ddeeb309e56069f67b7fb702ea31a6
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Aug 27 16:16:03 2020 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Thu Aug 27 20:13:42 2020 +0200

    add a DisableCycleFocusOut flag for an all-welded hierarchy
    
    so we can differentiate the case of embedded welded widgets co-sharing the
    tab-cycle sequence with vcl widgets vs the case its all welded widgets
    
    Change-Id: I5c57b4e98d2f5c543522a72e31d554a67c259307
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101485
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/basctl/source/basicide/bastypes.cxx b/basctl/source/basicide/bastypes.cxx
index 8430c9444dbf..5a4012b6cebb 100644
--- a/basctl/source/basicide/bastypes.cxx
+++ b/basctl/source/basicide/bastypes.cxx
@@ -263,7 +263,7 @@ DockingWindow::DockingWindow(vcl::Window* pParent, const OUString& rUIXMLDescrip
 {
     m_xVclContentArea = VclPtr<VclVBox>::Create(this);
     m_xVclContentArea->Show();
-    m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription));
+    m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription, true));
     m_xContainer = m_xBuilder->weld_container(rID);
 }
 
diff --git a/extensions/source/propctrlr/propcontroller.cxx b/extensions/source/propctrlr/propcontroller.cxx
index 7233d2df6446..9a421dd4432e 100644
--- a/extensions/source/propctrlr/propcontroller.cxx
+++ b/extensions/source/propctrlr/propcontroller.cxx
@@ -348,7 +348,7 @@ namespace pcr
             VclPtr<vcl::Window> pParentWin = pContainerWindow ? pContainerWindow->GetWindow() : VclPtr<vcl::Window>();
             if (!pParentWin)
                 throw RuntimeException("The frame is invalid. Unable to extract the container window.",*this);
-            xBuilder.reset(Application::CreateInterimBuilder(pParentWin, sUIFile));
+            xBuilder.reset(Application::CreateInterimBuilder(pParentWin, sUIFile, true));
         }
 
         Construct(xContainerWindow, std::move(xBuilder));
diff --git a/include/vcl/InterimItemWindow.hxx b/include/vcl/InterimItemWindow.hxx
index 4f8f9ece2848..3716c1e2053a 100644
--- a/include/vcl/InterimItemWindow.hxx
+++ b/include/vcl/InterimItemWindow.hxx
@@ -31,8 +31,13 @@ public:
     virtual void Draw(OutputDevice* pDevice, const Point& rPos, DrawFlags nFlags) override;
 
 protected:
+    // bAllowCycleFocusOut of true allows focus to be moved out of the Control
+    // via tab key into a parent window or sibling window, false means focus
+    // remains inside the InterimItemWindow and cycles back to the first child
+    // of this control on reaching pass the last child. This is suitable when
+    // the Control is the toplevel control and has no siblings or parent
     InterimItemWindow(vcl::Window* pParent, const OUString& rUIXMLDescription, const OString& rID,
-                      sal_uInt64 nLOKWindowId = 0);
+                      bool bAllowCycleFocusOut = true, sal_uInt64 nLOKWindowId = 0);
 
     void InitControlBase(weld::Widget* pWidget);
 
diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx
index 7102633f7a96..16356c8b93e7 100644
--- a/include/vcl/svapp.hxx
+++ b/include/vcl/svapp.hxx
@@ -1322,7 +1322,8 @@ public:
     static void setDeInitHook(Link<LinkParamNone*,void> const & hook);
 
     static weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString &rUIFile, bool bMobile = false);
-    static weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile, sal_uInt64 nLOKWindowId = 0); //for the duration of vcl parent windows
+    // For the duration of vcl parent windows
+    static weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile, bool bAllowCycleFocusOut, sal_uInt64 nLOKWindowId = 0);
 
     static weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
                                                     VclButtonsType eButtonType, const OUString& rPrimaryMessage,
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index 9cf772287d12..7422a1a93b52 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -414,7 +414,7 @@ ScCheckListMember::ScCheckListMember()
 ScCheckListMenuControl::ScCheckListMenuControl(ScCheckListMenuWindow* pParent, vcl::Window* pContainer,
                                                ScDocument* pDoc, bool bCanHaveSubMenu, int nWidth)
     : mxFrame(pParent)
-    , mxBuilder(Application::CreateInterimBuilder(pContainer, "modules/scalc/ui/filterdropdown.ui"))
+    , mxBuilder(Application::CreateInterimBuilder(pContainer, "modules/scalc/ui/filterdropdown.ui", false))
     , mxContainer(mxBuilder->weld_container("FilterDropDown"))
     , mxMenu(mxBuilder->weld_tree_view("menu"))
     , mxScratchIter(mxMenu->make_iterator())
diff --git a/sfx2/source/appl/newhelp.cxx b/sfx2/source/appl/newhelp.cxx
index 8226c637bef0..049e888d6f78 100644
--- a/sfx2/source/appl/newhelp.cxx
+++ b/sfx2/source/appl/newhelp.cxx
@@ -2466,7 +2466,7 @@ SfxHelpWindow_Impl::SfxHelpWindow_Impl(
 
     m_xVclContentArea = VclPtr<VclVBox>::Create(this);
     m_xVclContentArea->Show();
-    m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, "sfx/ui/helpwindow.ui"));
+    m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, "sfx/ui/helpwindow.ui", false));
     m_xContainer = m_xBuilder->weld_paned("HelpWindow");
     m_xContainer->connect_size_allocate(LINK(this, SfxHelpWindow_Impl, ResizeHdl));
     m_xHelpPaneWindow = m_xBuilder->weld_container("helppanewindow");
diff --git a/sfx2/source/dialog/dockwin.cxx b/sfx2/source/dialog/dockwin.cxx
index 51e179ffa811..dcde3dbbe4f6 100644
--- a/sfx2/source/dialog/dockwin.cxx
+++ b/sfx2/source/dialog/dockwin.cxx
@@ -773,7 +773,7 @@ SfxDockingWindow::SfxDockingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW,
 {
     m_xVclContentArea = VclPtr<VclVBox>::Create(this);
     m_xVclContentArea->Show();
-    m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription));
+    m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription, true));
     m_xContainer = m_xBuilder->weld_container(rID);
 
     pImpl.reset(new SfxDockingWindow_Impl(this));
diff --git a/sfx2/source/sidebar/PanelLayout.cxx b/sfx2/source/sidebar/PanelLayout.cxx
index 6a333819274b..78fcbc1714dd 100644
--- a/sfx2/source/sidebar/PanelLayout.cxx
+++ b/sfx2/source/sidebar/PanelLayout.cxx
@@ -30,7 +30,7 @@ PanelLayout::PanelLayout(vcl::Window* pParent, const OString& rID, const OUStrin
     // Builder will trigger resize and start Idle
     m_xVclContentArea = VclPtr<VclVBox>::Create(this);
     m_xVclContentArea->Show();
-    m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription));
+    m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription, true));
     m_xContainer = m_xBuilder->weld_container(rID);
 }
 
diff --git a/svtools/source/control/toolbarmenu.cxx b/svtools/source/control/toolbarmenu.cxx
index e0688f6e9fe3..04d782ec71fd 100644
--- a/svtools/source/control/toolbarmenu.cxx
+++ b/svtools/source/control/toolbarmenu.cxx
@@ -178,7 +178,7 @@ InterimToolbarPopup::InterimToolbarPopup(const css::uno::Reference<css::frame::X
     : DockingWindow(pParent, "InterimDockParent", "svx/ui/interimdockparent.ui", rFrame)
     , m_xBox(get("box"))
     , m_xFrame(rFrame)
-    , m_xBuilder(Application::CreateInterimBuilder(m_xBox.get(), "svx/ui/interimparent.ui"))
+    , m_xBuilder(Application::CreateInterimBuilder(m_xBox.get(), "svx/ui/interimparent.ui", false))
     , m_xContainer(m_xBuilder->weld_container("container"))
     , m_xPopup(std::move(xPopup))
 {
diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx
index b8f8d5bd90a8..24c172e7d0f9 100644
--- a/vcl/inc/salinst.hxx
+++ b/vcl/inc/salinst.hxx
@@ -161,7 +161,8 @@ public:
     virtual OpenGLContext*  CreateOpenGLContext() = 0;
 
     virtual weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile);
-    virtual weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile, sal_uInt64 nLOKWindowId = 0);
+    virtual weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile,
+                                                bool bAllowCycleFocusOut, sal_uInt64 nLOKWindowId = 0);
     virtual weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
                                                      VclButtonsType eButtonType, const OUString& rPrimaryMessage);
     virtual weld::Window* GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow);
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index fa08c1e64617..844f6d0c3f36 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -185,6 +185,7 @@ class GtkSalFrame final : public SalFrame
     GdkCursor                      *m_pCurrentCursor;
     PointerStyle                    m_ePointerStyle;
     ScreenSaverInhibitor            m_ScreenSaverInhibitor;
+    gulong                          m_nSetFocusSignalId;
     bool                            m_bFullscreen;
     bool                            m_bSpanMonitorsWhenFullscreen;
     bool                            m_bDefaultPos;
@@ -523,6 +524,8 @@ public:
     static SalWheelMouseEvent   GetWheelEvent(GdkEventScroll& rEvent);
     static gboolean             NativeWidgetHelpPressed(GtkAccelGroup*, GObject*, guint,
         GdkModifierType, gpointer pFrame);
+
+    void DisallowCycleFocusOut();
 };
 
 #define OOO_TYPE_FIXED ooo_fixed_get_type()
diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index ec1f7d068dc4..2352b63a4869 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -229,7 +229,8 @@ public:
     virtual css::uno::Reference< css::uno::XInterface > CreateDropTarget() override;
     virtual OpenGLContext* CreateOpenGLContext() override;
     virtual weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile) override;
-    virtual weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile, sal_uInt64 nLOKWindowId = 0) override;
+    virtual weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile,
+                                                bool bAllowCycleFocusOut, sal_uInt64 nLOKWindowId = 0) override;
     virtual weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage) override;
     virtual weld::Window* GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow) override;
 
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 0783c26dbfba..df22a2c3d784 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -6862,7 +6862,7 @@ weld::Builder* SalInstance::CreateBuilder(weld::Widget* pParent, const OUString&
 }
 
 weld::Builder* SalInstance::CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot,
-                                                 const OUString& rUIFile, sal_uInt64)
+                                                 const OUString& rUIFile, bool, sal_uInt64)
 {
     return new SalInstanceBuilder(pParent, rUIRoot, rUIFile);
 }
diff --git a/vcl/source/control/InterimItemWindow.cxx b/vcl/source/control/InterimItemWindow.cxx
index 5e7c189fdd28..588b4f22e900 100644
--- a/vcl/source/control/InterimItemWindow.cxx
+++ b/vcl/source/control/InterimItemWindow.cxx
@@ -11,7 +11,8 @@
 #include <vcl/layout.hxx>
 
 InterimItemWindow::InterimItemWindow(vcl::Window* pParent, const OUString& rUIXMLDescription,
-                                     const OString& rID, sal_uInt64 nLOKWindowId)
+                                     const OString& rID, bool bAllowCycleFocusOut,
+                                     sal_uInt64 nLOKWindowId)
     : Control(pParent, WB_TABSTOP)
     , m_pWidget(nullptr) // inheritors are expected to call InitControlBase
 {
@@ -21,8 +22,8 @@ InterimItemWindow::InterimItemWindow(vcl::Window* pParent, const OUString& rUIXM
 
     m_xVclContentArea = VclPtr<VclVBox>::Create(this);
     m_xVclContentArea->Show();
-    m_xBuilder.reset(
-        Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription, nLOKWindowId));
+    m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription,
+                                                       bAllowCycleFocusOut, nLOKWindowId));
     m_xContainer = m_xBuilder->weld_container(rID);
 
     SetBackground();
diff --git a/vcl/source/control/calendar.cxx b/vcl/source/control/calendar.cxx
index 14fcfe62f797..3913e617a4ea 100644
--- a/vcl/source/control/calendar.cxx
+++ b/vcl/source/control/calendar.cxx
@@ -1526,7 +1526,7 @@ namespace
 
     public:
         ImplCFieldFloat(vcl::Window* pContainer)
-            : mxBuilder(Application::CreateInterimBuilder(pContainer, "svt/ui/calendar.ui"))
+            : mxBuilder(Application::CreateInterimBuilder(pContainer, "svt/ui/calendar.ui", false))
             , mxContainer(mxBuilder->weld_container("Calendar"))
             , mxCalendar(mxBuilder->weld_calendar("date"))
             , mxTodayBtn(mxBuilder->weld_button("today"))
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 2fd07524b137..f51ed30232e9 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -182,7 +182,7 @@ weld::Builder* Application::CreateBuilder(weld::Widget* pParent, const OUString
         return ImplGetSVData()->mpDefInst->CreateBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile);
 }
 
-weld::Builder* Application::CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile, sal_uInt64 nLOKWindowId)
+weld::Builder* Application::CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile, bool bAllowCycleFocusOut, sal_uInt64 nLOKWindowId)
 {
     if (comphelper::LibreOfficeKit::isActive()
         && (rUIFile == "svx/ui/stylespreview.ui"
@@ -191,7 +191,7 @@ weld::Builder* Application::CreateInterimBuilder(vcl::Window* pParent, const OUS
         return new JSInstanceBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, css::uno::Reference<css::frame::XFrame>(), nLOKWindowId);
     }
 
-    return ImplGetSVData()->mpDefInst->CreateInterimBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, nLOKWindowId);
+    return ImplGetSVData()->mpDefInst->CreateInterimBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, bAllowCycleFocusOut, nLOKWindowId);
 }
 
 weld::MessageDialog* Application::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index 20a863c34f5b..75ba33d3350a 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -451,6 +451,7 @@ GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
     : m_nXScreen( getDisplay()->GetDefaultXScreen() )
     , m_pHeaderBar(nullptr)
     , m_bGraphics(false)
+    , m_nSetFocusSignalId(0)
 {
     getDisplay()->registerFrame( this );
     m_bDefaultPos       = true;
@@ -462,6 +463,7 @@ GtkSalFrame::GtkSalFrame( SystemParentData* pSysData )
     : m_nXScreen( getDisplay()->GetDefaultXScreen() )
     , m_pHeaderBar(nullptr)
     , m_bGraphics(false)
+    , m_nSetFocusSignalId(0)
 {
     getDisplay()->registerFrame( this );
     // permanently ignore errors from our unruly children ...
@@ -906,7 +908,7 @@ void GtkSalFrame::InitCommon()
     g_signal_connect_after( G_OBJECT(m_pWindow), "focus-in-event", G_CALLBACK(signalFocus), this );
     g_signal_connect_after( G_OBJECT(m_pWindow), "focus-out-event", G_CALLBACK(signalFocus), this );
     if (GTK_IS_WINDOW(m_pWindow)) // i.e. not if it's a GtkEventBox which doesn't have the signal
-        g_signal_connect( G_OBJECT(m_pWindow), "set-focus", G_CALLBACK(signalSetFocus), this );
+        m_nSetFocusSignalId = g_signal_connect( G_OBJECT(m_pWindow), "set-focus", G_CALLBACK(signalSetFocus), this );
     g_signal_connect( G_OBJECT(m_pWindow), "map-event", G_CALLBACK(signalMap), this );
     g_signal_connect( G_OBJECT(m_pWindow), "unmap-event", G_CALLBACK(signalUnmap), this );
     g_signal_connect( G_OBJECT(m_pWindow), "configure-event", G_CALLBACK(signalConfigure), this );
@@ -1007,6 +1009,21 @@ GtkSalFrame *GtkSalFrame::getFromWindow( GtkWidget *pWindow )
     return static_cast<GtkSalFrame *>(g_object_get_data( G_OBJECT( pWindow ), "SalFrame" ));
 }
 
+void GtkSalFrame::DisallowCycleFocusOut()
+{
+    if (!m_nSetFocusSignalId)
+        return;
+    // don't enable/disable can-focus as control enters and leaves
+    // embedded native gtk widgets
+    g_signal_handler_disconnect(G_OBJECT(m_pWindow), m_nSetFocusSignalId);
+    m_nSetFocusSignalId = 0;
+
+    // set container without can-focus and focus will tab between
+    // the native embedded widgets using the default gtk handling for
+    // that
+    gtk_widget_set_can_focus(GTK_WIDGET(m_pFixedContainer), false);
+}
+
 void GtkSalFrame::Init( SalFrame* pParent, SalFrameStyleFlags nStyle )
 {
     if( nStyle & SalFrameStyleFlags::DEFAULT ) // ensure default style
@@ -2540,7 +2557,10 @@ void GtkSalFrame::GrabFocus()
         pGrabWidget = GTK_WIDGET(m_pWindow);
     else
         pGrabWidget = GTK_WIDGET(m_pFixedContainer);
-    if (!gtk_widget_get_can_focus(pGrabWidget))
+    // m_nSetFocusSignalId is 0 for the DisallowCycleFocusOut case where
+    // we don't allow focus to enter the toplevel, but expect it to
+    // stay in some embedded native gtk widget
+    if (!gtk_widget_get_can_focus(pGrabWidget) && m_nSetFocusSignalId)
         gtk_widget_set_can_focus(pGrabWidget, true);
     if (!gtk_widget_has_focus(pGrabWidget))
         gtk_widget_grab_focus(pGrabWidget);
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 50068de7b280..d6a075c196cc 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -16392,7 +16392,8 @@ gboolean GtkSalFrame::NativeWidgetHelpPressed(GtkAccelGroup*, GObject*, guint, G
     return true;
 }
 
-weld::Builder* GtkInstance::CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile, sal_uInt64)
+weld::Builder* GtkInstance::CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile,
+                                                 bool bAllowCycleFocusOut, sal_uInt64)
 {
     // Create a foreign window which we know is a GtkGrid and make the native widgets a child of that, so we can
     // support GtkWidgets within a vcl::Window
@@ -16409,6 +16410,17 @@ weld::Builder* GtkInstance::CreateInterimBuilder(vcl::Window* pParent, const OUS
     GtkWidget *pWindow = static_cast<GtkWidget*>(pEnvData->pWidget);
     gtk_widget_show_all(pWindow);
 
+    if (!bAllowCycleFocusOut)
+    {
+        GtkWidget* pTopLevel = gtk_widget_get_toplevel(pWindow);
+        assert(pTopLevel);
+        GtkSalFrame* pFrame = GtkSalFrame::getFromWindow(pTopLevel);
+        assert(pFrame);
+        // unhook handler and let gtk cycle its own way through this widget's
+        // children because it has no non-gtk siblings
+        pFrame->DisallowCycleFocusOut();
+    }
+
     // build the widget tree as a child of the GtkEventBox GtkGrid parent
     return new GtkInstanceBuilder(pWindow, rUIRoot, rUIFile, xEmbedWindow.get());
 }


More information about the Libreoffice-commits mailing list