include/svtools/editbrowsebox.hxx     |   21 ++++++++++
 svtools/source/brwbox/ebbcontrols.cxx |   33 ++++++++++++++++
 svx/source/fmcomp/gridcell.cxx        |   68 +++++++++++++++++++---------------
 svx/source/inc/gridcell.hxx           |    4 ++
 vcl/unx/gtk3/gtkinst.cxx              |    7 +++
 5 files changed, 103 insertions(+), 30 deletions(-)

New commits:
commit 1e531c31600a76e1d55e2f2e5abd351ff80bc4fd
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Mon Sep 13 17:29:27 2021 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Mon Sep 13 22:19:36 2021 +0200

    tdf#142415 mouse events not propogated to table control event handlers
    
    handle this with explicit callbacks from the cell widget for those
    events
    
    Change-Id: Ie605ca4286afc0fbd321f339fb7963771a303df5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122050
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/include/svtools/editbrowsebox.hxx 
b/include/svtools/editbrowsebox.hxx
index 159e2cedb367..5b083454ff9e 100644
--- a/include/svtools/editbrowsebox.hxx
+++ b/include/svtools/editbrowsebox.hxx
@@ -184,13 +184,34 @@ namespace svt
             m_aFocusOutHdl = rHdl;
         }
 
+        void SetMousePressHdl(const Link<const MouseEvent&,void>& rHdl)
+        {
+            m_aMousePressHdl = rHdl;
+        }
+
+        void SetMouseReleaseHdl(const Link<const MouseEvent&,void>& rHdl)
+        {
+            m_aMouseReleaseHdl = rHdl;
+        }
+
+        void SetMouseMoveHdl(const Link<const MouseEvent&,void>& rHdl)
+        {
+            m_aMouseMoveHdl = rHdl;
+        }
+
     protected:
         DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
         DECL_LINK(FocusInHdl, weld::Widget&, void);
         DECL_LINK(FocusOutHdl, weld::Widget&, void);
+        DECL_LINK(MousePressHdl, const MouseEvent&, bool);
+        DECL_LINK(MouseReleaseHdl, const MouseEvent&, bool);
+        DECL_LINK(MouseMoveHdl, const MouseEvent&, bool);
     private:
         Link<LinkParamNone*,void> m_aFocusInHdl;
         Link<LinkParamNone*,void> m_aFocusOutHdl;
+        Link<const MouseEvent&,void> m_aMousePressHdl;
+        Link<const MouseEvent&,void> m_aMouseReleaseHdl;
+        Link<const MouseEvent&,void> m_aMouseMoveHdl;
     };
 
     class SVT_DLLPUBLIC EditControlBase : public ControlBase
diff --git a/svtools/source/brwbox/ebbcontrols.cxx 
b/svtools/source/brwbox/ebbcontrols.cxx
index 32ad1e52c748..04ba4b489f08 100644
--- a/svtools/source/brwbox/ebbcontrols.cxx
+++ b/svtools/source/brwbox/ebbcontrols.cxx
@@ -32,6 +32,9 @@ namespace svt
         m_xWidget->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
         m_xWidget->connect_focus_in(LINK(this, ControlBase, FocusInHdl));
         m_xWidget->connect_focus_out(LINK(this, ControlBase, FocusOutHdl));
+        m_xWidget->connect_mouse_press(LINK(this, ControlBase, MousePressHdl));
+        m_xWidget->connect_mouse_release(LINK(this, ControlBase, 
MouseReleaseHdl));
+        m_xWidget->connect_mouse_move(LINK(this, ControlBase, MouseMoveHdl));
     }
 
     void ComboBoxControl::dispose()
@@ -119,6 +122,9 @@ namespace svt
         m_xWidget->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
         m_xWidget->connect_focus_in(LINK(this, ControlBase, FocusInHdl));
         m_xWidget->connect_focus_out(LINK(this, ControlBase, FocusOutHdl));
+        m_xWidget->connect_mouse_press(LINK(this, ControlBase, MousePressHdl));
+        m_xWidget->connect_mouse_release(LINK(this, ControlBase, 
MouseReleaseHdl));
+        m_xWidget->connect_mouse_move(LINK(this, ControlBase, MouseMoveHdl));
     }
 
     void ListBoxControl::dispose()
@@ -189,6 +195,9 @@ namespace svt
         m_xBox->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
         m_xBox->connect_focus_in(LINK(this, ControlBase, FocusInHdl));
         m_xBox->connect_focus_out(LINK(this, ControlBase, FocusOutHdl));
+        m_xBox->connect_mouse_press(LINK(this, ControlBase, MousePressHdl));
+        m_xBox->connect_mouse_release(LINK(this, ControlBase, 
MouseReleaseHdl));
+        m_xBox->connect_mouse_move(LINK(this, ControlBase, MouseMoveHdl));
         m_xBox->connect_toggled(LINK(this, CheckBoxControl, OnToggle));
     }
 
@@ -342,6 +351,9 @@ namespace svt
         m_pEntry->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
         m_pEntry->connect_focus_in(LINK(this, ControlBase, FocusInHdl));
         connect_focus_out(LINK(this, ControlBase, FocusOutHdl));
+        m_pEntry->connect_mouse_press(LINK(this, ControlBase, MousePressHdl));
+        m_pEntry->connect_mouse_release(LINK(this, ControlBase, 
MouseReleaseHdl));
+        m_pEntry->connect_mouse_move(LINK(this, ControlBase, MouseMoveHdl));
     }
 
     bool ControlBase::ProcessKey(const KeyEvent& rKEvt)
@@ -366,6 +378,24 @@ namespace svt
         
static_cast<BrowserDataWin*>(GetParent())->GetParent()->ChildFocusOut();
     }
 
+    IMPL_LINK(ControlBase, MousePressHdl, const MouseEvent&, rEvent, bool)
+    {
+        m_aMousePressHdl.Call(rEvent);
+        return false;
+    }
+
+    IMPL_LINK(ControlBase, MouseReleaseHdl, const MouseEvent&, rEvent, bool)
+    {
+        m_aMouseReleaseHdl.Call(rEvent);
+        return false;
+    }
+
+    IMPL_LINK(ControlBase, MouseMoveHdl, const MouseEvent&, rEvent, bool)
+    {
+        m_aMouseMoveHdl.Call(rEvent);
+        return false;
+    }
+
     void EditControlBase::dispose()
     {
         m_pEntry = nullptr;
@@ -640,6 +670,9 @@ namespace svt
         m_xWidget->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
         m_xWidget->connect_focus_in(LINK(this, ControlBase, FocusInHdl));
         m_xWidget->connect_focus_out(LINK(this, ControlBase, FocusOutHdl));
+        m_xWidget->connect_mouse_press(LINK(this, ControlBase, MousePressHdl));
+        m_xWidget->connect_mouse_release(LINK(this, ControlBase, 
MouseReleaseHdl));
+        m_xWidget->connect_mouse_move(LINK(this, ControlBase, MouseMoveHdl));
         // so any the natural size doesn't have an effect
         m_xWidget->set_size_request(1, 1);
     }
diff --git a/svx/source/fmcomp/gridcell.cxx b/svx/source/fmcomp/gridcell.cxx
index f5eb27fbf2b8..c0cb0d1e376c 100644
--- a/svx/source/fmcomp/gridcell.cxx
+++ b/svx/source/fmcomp/gridcell.cxx
@@ -3103,6 +3103,9 @@ void FmXGridCell::init()
         pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent 
) );
         pEventWindow->SetFocusInHdl(LINK( this, FmXGridCell, OnFocusGained));
         pEventWindow->SetFocusOutHdl(LINK( this, FmXGridCell, OnFocusLost));
+        pEventWindow->SetMousePressHdl(LINK( this, FmXGridCell, OnMousePress));
+        pEventWindow->SetMouseReleaseHdl(LINK( this, FmXGridCell, 
OnMouseRelease));
+        pEventWindow->SetMouseMoveHdl(LINK( this, FmXGridCell, OnMouseMove));
     }
 }
 
@@ -3376,45 +3379,50 @@ IMPL_LINK_NOARG(FmXGridCell, OnFocusLost, 
LinkParamNone*, void)
     onFocusLost(aEvent);
 }
 
-void FmXGridCell::onWindowEvent(const VclEventId _nEventId, const void* 
_pEventData)
+IMPL_LINK(FmXGridCell, OnMousePress, const MouseEvent&, rEventData, void)
 {
-    switch ( _nEventId )
-    {
-    case VclEventId::WindowMouseButtonDown:
-    case VclEventId::WindowMouseButtonUp:
-    {
-        if ( !m_aMouseListeners.getLength() )
-            break;
+    if (!m_aMouseListeners.getLength())
+        return;
+
+    awt::MouseEvent aEvent(VCLUnoHelper::createMouseEvent(rEventData, *this));
+    m_aMouseListeners.notifyEach(&awt::XMouseListener::mousePressed, aEvent);
+}
 
-        const bool bButtonDown = ( _nEventId == 
VclEventId::WindowMouseButtonDown );
+IMPL_LINK(FmXGridCell, OnMouseRelease, const MouseEvent&, rEventData, void)
+{
+    if (!m_aMouseListeners.getLength())
+        return;
 
-        awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast< 
const ::MouseEvent* >( _pEventData ), *this ) );
-        m_aMouseListeners.notifyEach( bButtonDown ? 
&awt::XMouseListener::mousePressed : &awt::XMouseListener::mouseReleased, 
aEvent );
-    }
-    break;
-    case VclEventId::WindowMouseMove:
+    awt::MouseEvent aEvent(VCLUnoHelper::createMouseEvent(rEventData, *this));
+    m_aMouseListeners.notifyEach(&awt::XMouseListener::mouseReleased, aEvent);
+}
+
+IMPL_LINK(FmXGridCell, OnMouseMove, const MouseEvent&, rMouseEvent, void)
+{
+    if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
     {
-        const MouseEvent& rMouseEvent = *static_cast< const ::MouseEvent* >( 
_pEventData );
-        if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
+        if ( m_aMouseListeners.getLength() != 0 )
         {
-            if ( m_aMouseListeners.getLength() != 0 )
-            {
-                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( 
rMouseEvent, *this ) );
-                m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? 
&awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
-            }
+            awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( 
rMouseEvent, *this ) );
+            m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? 
&awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
         }
-        else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() 
)
+    }
+    else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
+    {
+        if ( m_aMouseMotionListeners.getLength() != 0 )
         {
-            if ( m_aMouseMotionListeners.getLength() != 0 )
-            {
-                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( 
rMouseEvent, *this ) );
-                aEvent.ClickCount = 0;
-                const bool bSimpleMove = bool( rMouseEvent.GetMode() & 
MouseEventModifiers::SIMPLEMOVE );
-                m_aMouseMotionListeners.notifyEach( bSimpleMove ? 
&awt::XMouseMotionListener::mouseMoved: 
&awt::XMouseMotionListener::mouseDragged, aEvent );
-            }
+            awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( 
rMouseEvent, *this ) );
+            aEvent.ClickCount = 0;
+            const bool bSimpleMove = bool( rMouseEvent.GetMode() & 
MouseEventModifiers::SIMPLEMOVE );
+            m_aMouseMotionListeners.notifyEach( bSimpleMove ? 
&awt::XMouseMotionListener::mouseMoved: 
&awt::XMouseMotionListener::mouseDragged, aEvent );
         }
     }
-    break;
+}
+
+void FmXGridCell::onWindowEvent(const VclEventId _nEventId, const void* 
_pEventData)
+{
+    switch ( _nEventId )
+    {
     case VclEventId::WindowKeyInput:
     case VclEventId::WindowKeyUp:
     {
diff --git a/svx/source/inc/gridcell.hxx b/svx/source/inc/gridcell.hxx
index 306dc5764ca1..be5161d1a2b3 100644
--- a/svx/source/inc/gridcell.hxx
+++ b/svx/source/inc/gridcell.hxx
@@ -782,6 +782,10 @@ private:
     svt::ControlBase* getEventWindow() const;
     DECL_LINK(OnFocusGained, LinkParamNone*, void);
     DECL_LINK(OnFocusLost, LinkParamNone*, void);
+    DECL_LINK(OnMousePress, const MouseEvent&, void);
+    DECL_LINK(OnMouseRelease, const MouseEvent&, void);
+    DECL_LINK(OnMouseMove, const MouseEvent&, void);
+
     DECL_LINK( OnWindowEvent, VclWindowEvent&, void );
 };
 
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 79d3835f69db..79e22ea4fb3d 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -12127,6 +12127,13 @@ private:
         pThis->signal_activate();
     }
 
+    virtual void ensureMouseEventWidget() override
+    {
+        // The GtkEntry is sufficient to get mouse events without an 
intermediate GtkEventBox
+        if (!m_pMouseEventBox)
+            m_pMouseEventBox = m_pDelegate;
+    }
+
 protected:
 
     virtual void signal_activate()

Reply via email to