include/svtools/editbrowsebox.hxx | 7 +++ svtools/source/brwbox/ebbcontrols.cxx | 1 svx/source/fmcomp/gridcell.cxx | 68 ++++++++++++++-------------------- svx/source/inc/gridcell.hxx | 4 +- 4 files changed, 39 insertions(+), 41 deletions(-)
New commits: commit ee04805e513b0f804408697fc4b93e3c025d2329 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Wed Aug 4 14:22:37 2021 +0100 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Wed Aug 4 16:50:39 2021 +0200 Resolves: tdf#143023 explicitly connect to ControlBase focus-[in/out] instead of listening to the generic vcl::Window/Control focus events. The thing which really gets/loses focus is now a Widget hosted inside the ControlBase. Change-Id: I012d0bea687aa6d5965a4e2f6ce3899bfc629f1b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120003 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/include/svtools/editbrowsebox.hxx b/include/svtools/editbrowsebox.hxx index fd111dbef4a9..159e2cedb367 100644 --- a/include/svtools/editbrowsebox.hxx +++ b/include/svtools/editbrowsebox.hxx @@ -178,12 +178,19 @@ namespace svt m_aFocusInHdl = rHdl; } + // chain after the FocusOutHdl + void SetFocusOutHdl(const Link<LinkParamNone*,void>& rHdl) + { + m_aFocusOutHdl = rHdl; + } + protected: DECL_LINK(KeyInputHdl, const KeyEvent&, bool); DECL_LINK(FocusInHdl, weld::Widget&, void); DECL_LINK(FocusOutHdl, weld::Widget&, void); private: Link<LinkParamNone*,void> m_aFocusInHdl; + Link<LinkParamNone*,void> m_aFocusOutHdl; }; class SVT_DLLPUBLIC EditControlBase : public ControlBase diff --git a/svtools/source/brwbox/ebbcontrols.cxx b/svtools/source/brwbox/ebbcontrols.cxx index 3b1819e94923..32ad1e52c748 100644 --- a/svtools/source/brwbox/ebbcontrols.cxx +++ b/svtools/source/brwbox/ebbcontrols.cxx @@ -362,6 +362,7 @@ namespace svt IMPL_LINK_NOARG(ControlBase, FocusOutHdl, weld::Widget&, void) { + m_aFocusOutHdl.Call(nullptr); static_cast<BrowserDataWin*>(GetParent())->GetParent()->ChildFocusOut(); } diff --git a/svx/source/fmcomp/gridcell.cxx b/svx/source/fmcomp/gridcell.cxx index 1a2b06311e32..4fb6d1d7f983 100644 --- a/svx/source/fmcomp/gridcell.cxx +++ b/svx/source/fmcomp/gridcell.cxx @@ -3098,7 +3098,11 @@ void FmXGridCell::init() { svt::ControlBase* pEventWindow( getEventWindow() ); if ( pEventWindow ) + { pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent ) ); + pEventWindow->SetFocusInHdl(LINK( this, FmXGridCell, OnFocusGained)); + pEventWindow->SetFocusOutHdl(LINK( this, FmXGridCell, OnFocusLost)); + } } svt::ControlBase* FmXGridCell::getEventWindow() const @@ -3319,78 +3323,62 @@ void SAL_CALL FmXGridCell::removeMouseMotionListener( const Reference< awt::XMou m_aMouseMotionListeners.removeInterface( _rxListener ); } - void SAL_CALL FmXGridCell::addPaintListener( const Reference< awt::XPaintListener >& ) { OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" ); } - void SAL_CALL FmXGridCell::removePaintListener( const Reference< awt::XPaintListener >& ) { OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" ); } - IMPL_LINK( FmXGridCell, OnWindowEvent, VclWindowEvent&, _rEvent, void ) { ENSURE_OR_THROW( _rEvent.GetWindow(), "illegal window" ); - onWindowEvent( _rEvent.GetId(), *_rEvent.GetWindow(), _rEvent.GetData() ); + onWindowEvent(_rEvent.GetId(), _rEvent.GetData()); } - void FmXGridCell::onFocusGained( const awt::FocusEvent& _rEvent ) { checkDisposed(OComponentHelper::rBHelper.bDisposed); m_aFocusListeners.notifyEach( &awt::XFocusListener::focusGained, _rEvent ); } - void FmXGridCell::onFocusLost( const awt::FocusEvent& _rEvent ) { checkDisposed(OComponentHelper::rBHelper.bDisposed); m_aFocusListeners.notifyEach( &awt::XFocusListener::focusLost, _rEvent ); } +IMPL_LINK_NOARG(FmXGridCell, OnFocusGained, LinkParamNone*, void) +{ + if (!m_aFocusListeners.getLength()) + return; + + awt::FocusEvent aEvent; + aEvent.Source = *this; + aEvent.Temporary = false; -void FmXGridCell::onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData ) + onFocusGained(aEvent); +} + +IMPL_LINK_NOARG(FmXGridCell, OnFocusLost, LinkParamNone*, void) { - switch ( _nEventId ) - { - case VclEventId::ControlGetFocus: - case VclEventId::WindowGetFocus: - case VclEventId::ControlLoseFocus: - case VclEventId::WindowLoseFocus: - { - if ( ( _rWindow.IsCompoundControl() - && ( _nEventId == VclEventId::ControlGetFocus - || _nEventId == VclEventId::ControlLoseFocus - ) - ) - || ( !_rWindow.IsCompoundControl() - && ( _nEventId == VclEventId::WindowGetFocus - || _nEventId == VclEventId::WindowLoseFocus - ) - ) - ) - { - if ( !m_aFocusListeners.getLength() ) - break; + if (!m_aFocusListeners.getLength()) + return; - bool bFocusGained = ( _nEventId == VclEventId::ControlGetFocus ) || ( _nEventId == VclEventId::WindowGetFocus ); + awt::FocusEvent aEvent; + aEvent.Source = *this; + aEvent.Temporary = false; - awt::FocusEvent aEvent; - aEvent.Source = *this; - aEvent.FocusFlags = static_cast<sal_Int16>(_rWindow.GetGetFocusFlags()); - aEvent.Temporary = false; + onFocusLost(aEvent); +} - if ( bFocusGained ) - onFocusGained( aEvent ); - else - onFocusLost( aEvent ); - } - } - break; +void FmXGridCell::onWindowEvent(const VclEventId _nEventId, const void* _pEventData) +{ + switch ( _nEventId ) + { case VclEventId::WindowMouseButtonDown: case VclEventId::WindowMouseButtonUp: { diff --git a/svx/source/inc/gridcell.hxx b/svx/source/inc/gridcell.hxx index 355c39ea1ead..306dc5764ca1 100644 --- a/svx/source/inc/gridcell.hxx +++ b/svx/source/inc/gridcell.hxx @@ -772,7 +772,7 @@ public: { m_pCellControl->AlignControl(nAlignment);} protected: - void onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData ); + void onWindowEvent(const VclEventId _nEventId, const void* _pEventData); // default implementations call our focus listeners, don't forget to call them if you override this virtual void onFocusGained( const css::awt::FocusEvent& _rEvent ); @@ -780,6 +780,8 @@ protected: private: svt::ControlBase* getEventWindow() const; + DECL_LINK(OnFocusGained, LinkParamNone*, void); + DECL_LINK(OnFocusLost, LinkParamNone*, void); DECL_LINK( OnWindowEvent, VclWindowEvent&, void ); };