include/svx/ShapeTypeHandler.hxx                    |   10 -
 svx/source/accessibility/AccessibleControlShape.cxx |  134 ++++++++++----------
 svx/source/accessibility/ShapeTypeHandler.cxx       |   21 ---
 vcl/unx/gtk3/fpicker/SalGtkPicker.cxx               |   13 +
 4 files changed, 80 insertions(+), 98 deletions(-)

New commits:
commit 93010de73bd96090389411f4d78361cc94f2d6e3
Author:     Michael Weghorn <[email protected]>
AuthorDate: Wed May 21 14:28:32 2025 +0200
Commit:     Michael Weghorn <[email protected]>
CommitDate: Thu May 22 05:50:31 2025 +0200

    svx a11y: Merge both ShapeTypeHandler::GetSlotId
    
    Change-Id: I140488bcdf9ae4df9e42170ce6d6a5a55f66c29c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185612
    Reviewed-by: Michael Weghorn <[email protected]>
    Tested-by: Jenkins

diff --git a/include/svx/ShapeTypeHandler.hxx b/include/svx/ShapeTypeHandler.hxx
index 750adbfedeb0..ee6335e0f470 100644
--- a/include/svx/ShapeTypeHandler.hxx
+++ b/include/svx/ShapeTypeHandler.hxx
@@ -170,16 +170,6 @@ private:
     typedef std::unordered_map<OUString,ShapeTypeId> tServiceNameToSlotId;
     mutable tServiceNameToSlotId maServiceNameToSlotId;
 
-    /**  Determine the slot id of the specified shape type.  With this id
-         internal methods can access the associated type descriptor.
-         @param aServiceName
-             Service name of the shape for which to return the slot id.
-         @return
-             Returns the slot id of the shape with the given service name or
-             0 when the service name is not known.
-     */
-    SVX_DLLPRIVATE tools::Long GetSlotId (const OUString& aServiceName) const;
-
     /**  Determine the slot id of the specified shape type.  With this id
          internal methods can access the associated type descriptor.
          @param rxShape
diff --git a/svx/source/accessibility/ShapeTypeHandler.cxx 
b/svx/source/accessibility/ShapeTypeHandler.cxx
index 1b169c761a3e..06b8332f524b 100644
--- a/svx/source/accessibility/ShapeTypeHandler.cxx
+++ b/svx/source/accessibility/ShapeTypeHandler.cxx
@@ -166,25 +166,16 @@ void ShapeTypeHandler::AddShapeTypeList (int 
nDescriptorCount,
     }
 }
 
-
-tools::Long ShapeTypeHandler::GetSlotId (const OUString& aServiceName) const
+tools::Long ShapeTypeHandler::GetSlotId(const uno::Reference<drawing::XShape>& 
rxShape) const
 {
-    tServiceNameToSlotId::const_iterator I (maServiceNameToSlotId.find 
(aServiceName));
-    if (I != maServiceNameToSlotId.end())
-        return I->second;
-    else
+    if (!rxShape.is())
         return 0;
-}
 
+    tServiceNameToSlotId::const_iterator I 
(maServiceNameToSlotId.find(rxShape->getShapeType()));
+    if (I != maServiceNameToSlotId.end())
+        return I->second;
 
-// Extract the given shape's service name and forward request to appropriate
-// method.
-tools::Long ShapeTypeHandler::GetSlotId (const 
uno::Reference<drawing::XShape>& rxShape) const
-{
-    if (rxShape.is())
-        return GetSlotId (rxShape->getShapeType());
-    else
-        return 0;
+    return 0;
 }
 
 /// get the accessible base name for an object
commit 3f6564fc6f0f18104d800c66a3e70f854059f234
Author:     Michael Weghorn <[email protected]>
AuthorDate: Wed May 21 14:07:59 2025 +0200
Commit:     Michael Weghorn <[email protected]>
CommitDate: Thu May 22 05:50:24 2025 +0200

    svx a11y: Flatten AccessibleControlShape::Init
    
    Return early.
    
    Change-Id: Ia1e6f1ce0eb012685b240ba7cd9d2613a0e8ed63
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185611
    Reviewed-by: Michael Weghorn <[email protected]>
    Tested-by: Jenkins

diff --git a/svx/source/accessibility/AccessibleControlShape.cxx 
b/svx/source/accessibility/AccessibleControlShape.cxx
index 84df1087e890..379156cedd04 100644
--- a/svx/source/accessibility/AccessibleControlShape.cxx
+++ b/svx/source/accessibility/AccessibleControlShape.cxx
@@ -179,82 +179,82 @@ void AccessibleControlShape::Init()
         SdrView* pView = maShapeTreeInfo.GetSdrView();
         OSL_ENSURE( pView && pViewWindow && pUnoObjectImpl, 
"AccessibleControlShape::Init: no view, or no view window, no SdrUnoObj!" );
 
-        if ( pView && pViewWindow && pUnoObjectImpl )
-        {
-            // get the context of the control - it will be our "inner" context
-            m_xUnoControl = pUnoObjectImpl->GetUnoControl( *pView, 
*pViewWindow->GetOutDev() );
+        if (!pView || !pViewWindow || !pUnoObjectImpl)
+            return;
+
+        // get the context of the control - it will be our "inner" context
+        m_xUnoControl = pUnoObjectImpl->GetUnoControl( *pView, 
*pViewWindow->GetOutDev() );
 
-            if ( !m_xUnoControl.is() )
+        if ( !m_xUnoControl.is() )
+        {
+            // the control has not yet been created. Though speaking strictly, 
it is a bug that
+            // our instance here is created without an existing control 
(because an AccessibleControlShape
+            // is a representation of a view object, and can only live if the 
view it should represent
+            // is complete, which implies a living control), it's by far the 
easiest and most riskless way
+            // to fix this here in this class.
+            // Okay, we will add as listener to the control container where we 
expect our control to appear.
+            OSL_ENSURE( !m_bWaitingForControl, "AccessibleControlShape::Init: 
already waiting for the control!" );
+
+            Reference< XContainer > xControlContainer = 
lcl_getControlContainer( pViewWindow->GetOutDev(), maShapeTreeInfo.GetSdrView() 
);
+            OSL_ENSURE( xControlContainer.is(), "AccessibleControlShape::Init: 
unable to find my ControlContainer!" );
+            if ( xControlContainer.is() )
             {
-                // the control has not yet been created. Though speaking 
strictly, it is a bug that
-                // our instance here is created without an existing control 
(because an AccessibleControlShape
-                // is a representation of a view object, and can only live if 
the view it should represent
-                // is complete, which implies a living control), it's by far 
the easiest and most riskless way
-                // to fix this here in this class.
-                // Okay, we will add as listener to the control container 
where we expect our control to appear.
-                OSL_ENSURE( !m_bWaitingForControl, 
"AccessibleControlShape::Init: already waiting for the control!" );
-
-                Reference< XContainer > xControlContainer = 
lcl_getControlContainer( pViewWindow->GetOutDev(), maShapeTreeInfo.GetSdrView() 
);
-                OSL_ENSURE( xControlContainer.is(), 
"AccessibleControlShape::Init: unable to find my ControlContainer!" );
-                if ( xControlContainer.is() )
-                {
-                    xControlContainer->addContainerListener( this );
-                    m_bWaitingForControl = true;
-                }
+                xControlContainer->addContainerListener( this );
+                m_bWaitingForControl = true;
             }
-            else
+        }
+        else
+        {
+            Reference< XModeChangeBroadcaster > xControlModes( m_xUnoControl, 
UNO_QUERY );
+            Reference< XAccessible > xControlAccessible( xControlModes, 
UNO_QUERY );
+            Reference< XAccessibleContext > xNativeControlContext;
+            if ( xControlAccessible.is() )
+                xNativeControlContext = 
xControlAccessible->getAccessibleContext();
+            OSL_ENSURE( xNativeControlContext.is(), 
"AccessibleControlShape::Init: no AccessibleContext for the control!" );
+            m_aControlContext = WeakReference< XAccessibleContext >( 
xNativeControlContext );
+
+            // add as listener to the context - we want to multiplex some 
states
+            if ( isAliveMode( m_xUnoControl ) && xNativeControlContext.is() )
+            {   // (but only in alive mode)
+                startStateMultiplexing( );
+            }
+
+            // now that we have all information about our control, do some 
adjustments
+            adjustAccessibleRole();
+            initializeComposedState();
+
+            // some initialization for our child manager, which is used in 
alive mode only
+            if ( isAliveMode( m_xUnoControl ) )
             {
-                Reference< XModeChangeBroadcaster > xControlModes( 
m_xUnoControl, UNO_QUERY );
-                Reference< XAccessible > xControlAccessible( xControlModes, 
UNO_QUERY );
-                Reference< XAccessibleContext > xNativeControlContext;
-                if ( xControlAccessible.is() )
-                    xNativeControlContext = 
xControlAccessible->getAccessibleContext();
-                OSL_ENSURE( xNativeControlContext.is(), 
"AccessibleControlShape::Init: no AccessibleContext for the control!" );
-                m_aControlContext = WeakReference< XAccessibleContext >( 
xNativeControlContext );
-
-                // add as listener to the context - we want to multiplex some 
states
-                if ( isAliveMode( m_xUnoControl ) && 
xNativeControlContext.is() )
-                {   // (but only in alive mode)
-                    startStateMultiplexing( );
-                }
+                sal_Int64 nStates( getAccessibleStateSet( ) );
+                m_pChildManager->setTransientChildren( nStates & 
AccessibleStateType::MANAGES_DESCENDANTS );
+            }
 
-                // now that we have all information about our control, do some 
adjustments
-                adjustAccessibleRole();
-                initializeComposedState();
+            // finally, aggregate a proxy for the control context
+            // first a factory for the proxy
+            Reference< XProxyFactory > xFactory = ProxyFactory::create( 
comphelper::getProcessComponentContext() );
+            // then the proxy itself
+            if ( xNativeControlContext.is() )
+            {
+                m_xControlContextProxy = xFactory->createProxy( 
xNativeControlContext );
+                m_xControlContextTypeAccess.set( xNativeControlContext, 
UNO_QUERY_THROW );
+                m_xControlContextComponent.set( xNativeControlContext, 
UNO_QUERY_THROW );
 
-                // some initialization for our child manager, which is used in 
alive mode only
-                if ( isAliveMode( m_xUnoControl ) )
+                // aggregate the proxy
+                osl_atomic_increment( &m_refCount );
+                if ( m_xControlContextProxy.is() )
                 {
-                    sal_Int64 nStates( getAccessibleStateSet( ) );
-                    m_pChildManager->setTransientChildren( nStates & 
AccessibleStateType::MANAGES_DESCENDANTS );
+                    // At this point in time, the proxy has a ref count of 
exactly one - in m_xControlContextProxy.
+                    // Remember to _not_ reset this member unless the 
delegator of the proxy has been reset, too!
+                    m_xControlContextProxy->setDelegator( *this );
                 }
+                osl_atomic_decrement( &m_refCount );
 
-                // finally, aggregate a proxy for the control context
-                // first a factory for the proxy
-                Reference< XProxyFactory > xFactory = ProxyFactory::create( 
comphelper::getProcessComponentContext() );
-                // then the proxy itself
-                if ( xNativeControlContext.is() )
-                {
-                    m_xControlContextProxy = xFactory->createProxy( 
xNativeControlContext );
-                    m_xControlContextTypeAccess.set( xNativeControlContext, 
UNO_QUERY_THROW );
-                    m_xControlContextComponent.set( xNativeControlContext, 
UNO_QUERY_THROW );
-
-                    // aggregate the proxy
-                    osl_atomic_increment( &m_refCount );
-                    if ( m_xControlContextProxy.is() )
-                    {
-                        // At this point in time, the proxy has a ref count of 
exactly one - in m_xControlContextProxy.
-                        // Remember to _not_ reset this member unless the 
delegator of the proxy has been reset, too!
-                        m_xControlContextProxy->setDelegator( *this );
-                    }
-                    osl_atomic_decrement( &m_refCount );
-
-                    m_bDisposeNativeContext = true;
-
-                    // Finally, we need to add ourself as mode listener to the 
control. In case the mode switches,
-                    // we need to dispose ourself.
-                    xControlModes->addModeChangeListener( this );
-                }
+                m_bDisposeNativeContext = true;
+
+                // Finally, we need to add ourself as mode listener to the 
control. In case the mode switches,
+                // we need to dispose ourself.
+                xControlModes->addModeChangeListener( this );
             }
         }
     }
commit 5cbd1c00c61cbda91adb836d4cd100be7bdde125
Author:     Michael Weghorn <[email protected]>
AuthorDate: Wed May 21 12:13:33 2025 +0200
Commit:     Michael Weghorn <[email protected]>
CommitDate: Thu May 22 05:50:16 2025 +0200

    gtk3: Don't depend on a11y to detect tooltip win
    
    In RunDialog::windowOpened, don't rely on the
    the VCLXWindow currently usually is also being
    the XAccessible for a vcl::Window, which is an
    implementation detail and subject to change, see
    commit messsage of
    
            Change-Id: Id81ab5f90955ecc600e179164b5f9c7a771182d1
            Author: Michael Weghorn <[email protected]>
            Date:   Wed May 21 11:03:56 2025 +0200
    
                sw a11y test: Don't rely on XWindow being XAccessible
    
    for further background.
    
    Instead, retrieve the vcl::Window and check the window
    type of that one directly to detect a tooltip.
    (See the mapping from window type to accessible role
    in Window::getDefaultAccessibleRole.)
    
    If continuing to use the a11y layer were necessary for
    any reason, an alternative could be to get the
    vcl::Window's XAccessible without it relying on it
    being the VCLXWindow, see the above-mentioned commit
    for an example.
    
    Sample scenario that triggers this code path and
    still behaves the same as without this commit in
    place:
    
    * start Writer with the gtk3 VCL plugin on Linux, create
      new doc
    * press Ctrl+N to create another new document
    * press Ctrl+S to open the file dialog for the second doc
    * switch back to the first doc
    * press Ctrl+N to open yet another doc
    
    -> The file dialog is popped down after a few moments
    because the logic in RunDialog::windowOpened still
    detects that the new window isn't a tooltip.
    
    Change-Id: I66c9d4c87c7ba96502d08ebc8ec52fdaabe132ba
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185603
    Reviewed-by: Michael Weghorn <[email protected]>
    Tested-by: Jenkins

diff --git a/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx 
b/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx
index 0e81b9149eab..5bbf94d7b74f 100644
--- a/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx
+++ b/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx
@@ -26,6 +26,7 @@
 #include <sal/log.hxx>
 #include <utility>
 #include <vcl/svapp.hxx>
+#include <vcl/toolkit/unowrap.hxx>
 #include <tools/urlobj.hxx>
 
 #include <vcl/window.hxx>
@@ -122,14 +123,14 @@ void SAL_CALL RunDialog::windowOpened(const 
css::lang::EventObject& e)
 
     //Don't popdown dialogs if a tooltip appears elsewhere, that's ok, but do 
pop down
     //if another dialog/frame is launched.
-    css::uno::Reference<css::accessibility::XAccessible> xAccessible(e.Source, 
css::uno::UNO_QUERY);
-    if (xAccessible.is())
+    css::uno::Reference<css::awt::XWindow> xWindow(e.Source, 
css::uno::UNO_QUERY);
+    if (xWindow.is())
     {
-        css::uno::Reference<css::accessibility::XAccessibleContext> 
xContext(xAccessible->getAccessibleContext());
-        if (xContext.is() && xContext->getAccessibleRole() == 
css::accessibility::AccessibleRole::TOOL_TIP)
-        {
+        UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
+        assert(pWrapper);
+        VclPtr<vcl::Window> pWindow = pWrapper->GetWindow(xWindow);
+        if (pWindow && pWindow->GetType() == WindowType::HELPTEXTWINDOW)
             return;
-        }
     }
 
     g_timeout_add_full(G_PRIORITY_HIGH_IDLE, 0, 
reinterpret_cast<GSourceFunc>(canceldialog), this, nullptr);

Reply via email to