include/toolkit/awt/vclxwindow.hxx           |   17 --------
 svtools/source/control/toolbarmenu.cxx       |    2 
 svtools/source/uno/popupwindowcontroller.cxx |    3 -
 toolkit/source/awt/vclxwindow.cxx            |   46 ++++++++++++++++------
 toolkit/source/controls/unocontrol.cxx       |   55 +++++++--------------------
 vcl/source/window/menubarwindow.cxx          |    7 +++
 vcl/source/window/window.cxx                 |    2 
 7 files changed, 57 insertions(+), 75 deletions(-)

New commits:
commit 3ecf542af410536d64d217c71002799bbe48b9c3
Author: Maxim Monastirsky <momonas...@gmail.com>
Date:   Sun Jan 28 00:54:23 2018 +0200

    Different approach for tdf#115227
    
    This reverts the previous attempt of commit
    250ad9311a613d9b4e1cf5cf5fdaf33d9b326220 ("tdf#115227 svtools:
    suppress UNO notifications for color selectors"), in favor of
    a different fix. The advantage of this new approach is that
    is doesn't affect events other than activate/deativate, and that
    it covers more cases: Toolbar popups even if not based on
    svtools::ToolbarPopup, or if closed by clicking outside them,
    font name/size and paragraph style toolbar controls, notebookbar,
    context and main menus (for the non gtk3 native case, the gtk3
    native menus left for a future investigation). For now, keep this
    logic inside toolkit, but ideally it should be in vcl (after
    reviewing vcl internal listeners).
    
    One side effect that I noticed after this change, is that there is
    a deactivation/activation pair which suppressed when e.g. opening a
    new document from the start center. But I'm not sure if that's a
    problem, given that the focus state of the top window as a whole
    wasn't changed, only its contents, and there are other APIs to track
    activation of document components. This happens because the source
    and the target windows of those events are the same, and we need to
    suppress this case to fix the font name/size style controls, and also
    the color picker after 27473d1c0f8ba3006262001cbefff33f639a19ac
    ("tdf#114935 Move the focus back to the document"). Otherwise we'll
    need to find another way to move the focus to the document w/o
    triggering listeners.
    
    Another case that will see a change in behavior, is document event
    listeners in dbaccess, as the Focus/UnFocus events there are based
    on top window activation/deactivation. However, I think it's a good
    change, as currently just opening of a toolbar popup or main/context
    menus there triggers those document events, making them useless.
    
    I would like to also mention here, that in fact those top window
    activation events never really worked as tdf#115227 expects them, as
    the superfluous events for at least the font name/size, style and
    color toolbar buttons existed already in OOo. The behavior of the
    color buttons changed in LO for a few years, but regressed again in
    the work on a real focus grabbing for floating windows starting with
    commit dd46727b99d4bb5135451aa7e5e1bdb197373843 ("Resolves; tdf#87120
    no keyboard navigation inside floating windows"). That work also
    introduced superfluous events when using menus.
    
    And a note about the change in menubarwindow.cxx: When a menubar
    popup is closed it's deleted using the lazydelete mechanism, which
    reparents the popup window, so it doesn't appear anymore in the
    hierarchy of the document window. Moreover, I suspect that at some
    point the lazydelete thing will be replaced by a VclPtr mechanism,
    which might break this even further, so the event won't appear as
    coming from the popup window (which might be already disposed at
    this stage). So instead, temporarily set the menubar window as the
    current focus window, so the activation will appear as if it was
    coming from the menu bar window itself.
    
    Change-Id: I292232adfcbd1a31d66ce394cd2f1bf42a013ecb
    Reviewed-on: https://gerrit.libreoffice.org/48746
    Reviewed-by: Maxim Monastirsky <momonas...@gmail.com>
    Tested-by: Jenkins <c...@libreoffice.org>

diff --git a/include/toolkit/awt/vclxwindow.hxx 
b/include/toolkit/awt/vclxwindow.hxx
index 3c925a59143b..27be3e102d32 100644
--- a/include/toolkit/awt/vclxwindow.hxx
+++ b/include/toolkit/awt/vclxwindow.hxx
@@ -233,23 +233,6 @@ public:
     virtual css::uno::Reference< css::awt::XStyleSettings > SAL_CALL 
getStyleSettings() override;
 };
 
-class TOOLKIT_DLLPUBLIC VclListenerLock
-{
-private:
-    VCLXWindow* m_pLockWindow;
-
-public:
-    explicit VclListenerLock(VCLXWindow* _pLockWindow);
-    /**
-     * @param bSystemWindow - if pVclWindow or its first system window parent
-     * is locked.
-     */
-    explicit VclListenerLock(vcl::Window* pVclWindow, bool bSystemWindow);
-    ~VclListenerLock();
-    VclListenerLock(const VclListenerLock&) = delete;
-    VclListenerLock& operator=(const VclListenerLock&) = delete;
-};
-
 #endif // INCLUDED_TOOLKIT_AWT_VCLXWINDOW_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/control/toolbarmenu.cxx 
b/svtools/source/control/toolbarmenu.cxx
index d4b69b1a747b..eb0c3dcc9b03 100644
--- a/svtools/source/control/toolbarmenu.cxx
+++ b/svtools/source/control/toolbarmenu.cxx
@@ -35,7 +35,6 @@
 #include <svtools/framestatuslistener.hxx>
 #include <svtools/valueset.hxx>
 #include <svtools/toolbarmenu.hxx>
-#include <toolkit/awt/vclxwindow.hxx>
 #include "toolbarmenuimp.hxx"
 
 using namespace ::com::sun::star::uno;
@@ -1487,7 +1486,6 @@ bool ToolbarPopup::IsInPopupMode()
 
 void ToolbarPopup::EndPopupMode()
 {
-    VclListenerLock aLock(this, /*bSystemWindow=*/true);
     GetDockingManager()->EndPopupMode(this);
 }
 
diff --git a/svtools/source/uno/popupwindowcontroller.cxx 
b/svtools/source/uno/popupwindowcontroller.cxx
index 19276a45854f..51f2b6e10f42 100644
--- a/svtools/source/uno/popupwindowcontroller.cxx
+++ b/svtools/source/uno/popupwindowcontroller.cxx
@@ -19,7 +19,6 @@
 
 #include <cppuhelper/supportsservice.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
-#include <toolkit/awt/vclxwindow.hxx>
 
 #include <vcl/toolbox.hxx>
 #include <vcl/svapp.hxx>
@@ -214,8 +213,6 @@ Reference< awt::XWindow > SAL_CALL 
PopupWindowController::createPopupWindow()
 
             pWin->EnableDocking();
             mxImpl->SetPopupWindow(pWin,pToolBox);
-
-            VclListenerLock aLock(pWin, /*bSystemWindow=*/true);
             vcl::Window::GetDockingManager()->StartPopupMode( pToolBox, pWin, 
eFloatFlags );
         }
     }
diff --git a/toolkit/source/awt/vclxwindow.cxx 
b/toolkit/source/awt/vclxwindow.cxx
index 7d1a70a23515..0c2a44a51ce3 100644
--- a/toolkit/source/awt/vclxwindow.cxx
+++ b/toolkit/source/awt/vclxwindow.cxx
@@ -517,23 +517,43 @@ void VCLXWindow::ProcessWindowEvent( const 
VclWindowEvent& rVclWindowEvent )
         }
         break;
         case VclEventId::WindowActivate:
-        {
-            if ( mpImpl->getTopWindowListeners().getLength() )
-            {
-                css::lang::EventObject aEvent;
-                aEvent.Source = static_cast<cppu::OWeakObject*>(this);
-                mpImpl->getTopWindowListeners().windowActivated( aEvent );
-            }
-        }
-        break;
         case VclEventId::WindowDeactivate:
         {
-            if ( mpImpl->getTopWindowListeners().getLength() )
+            if (!mpImpl->getTopWindowListeners().getLength())
+                return;
+
+            // Suppress events which are unlikely to be interesting to our 
listeners.
+            vcl::Window* pWin = 
static_cast<vcl::Window*>(rVclWindowEvent.GetData());
+            bool bSuppress = false;
+
+            while (pWin)
             {
-                css::lang::EventObject aEvent;
-                aEvent.Source = static_cast<cppu::OWeakObject*>(this);
-                mpImpl->getTopWindowListeners().windowDeactivated( aEvent );
+                // Either the event came from the same window, from its
+                // child, or from a child of its border window (e.g.
+                // menubar or notebookbar).
+                if (pWin->GetWindow(GetWindowType::Client) == GetWindow())
+                    return;
+
+                if (pWin->IsMenuFloatingWindow())
+                    bSuppress = true;
+
+                if (pWin->GetType() == WindowType::FLOATINGWINDOW &&
+                    static_cast<FloatingWindow*>(pWin)->IsInPopupMode())
+                    bSuppress = true;
+
+                // Otherwise, don't suppress if the event came from a 
different frame.
+                if (!bSuppress && pWin->GetWindow(GetWindowType::Frame) == 
pWin)
+                    break;
+
+                pWin = pWin->GetWindow(GetWindowType::RealParent);
             }
+
+            css::lang::EventObject aEvent;
+            aEvent.Source = static_cast<cppu::OWeakObject*>(this);
+            if (rVclWindowEvent.GetId() == VclEventId::WindowActivate)
+                mpImpl->getTopWindowListeners().windowActivated( aEvent );
+            else
+                mpImpl->getTopWindowListeners().windowDeactivated( aEvent );
         }
         break;
         case VclEventId::WindowClose:
diff --git a/toolkit/source/controls/unocontrol.cxx 
b/toolkit/source/controls/unocontrol.cxx
index 2f41e3f367d4..6c8435791883 100644
--- a/toolkit/source/controls/unocontrol.cxx
+++ b/toolkit/source/controls/unocontrol.cxx
@@ -94,50 +94,27 @@ static Sequence< OUString> lcl_ImplGetPropertyNames( const 
Reference< XMultiProp
     return aNames;
 }
 
-namespace
-{
-VCLXWindow* GetParentSystemWindow(vcl::Window* pWindow)
-{
-    while (pWindow)
-    {
-        if (pWindow->IsSystemWindow())
-            break;
-
-        pWindow = pWindow->GetParent();
-    }
 
-    uno::Reference<awt::XWindow> xWindow = VCLUnoHelper::GetInterface(pWindow);
-    return VCLXWindow::GetImplementation(xWindow);
-}
-}
-
-VclListenerLock::VclListenerLock(VCLXWindow* _pLockWindow)
-    : m_pLockWindow(_pLockWindow)
+class VclListenerLock
 {
-    if (m_pLockWindow)
-        m_pLockWindow->suspendVclEventListening();
-}
+private:
+    VCLXWindow*  m_pLockWindow;
 
-VclListenerLock::VclListenerLock(vcl::Window* pVclWindow, bool bSystemWindow)
-    : m_pLockWindow(nullptr)
-{
-    if (bSystemWindow)
-        m_pLockWindow = GetParentSystemWindow(pVclWindow);
-    else
+public:
+    explicit VclListenerLock( VCLXWindow* _pLockWindow )
+        : m_pLockWindow( _pLockWindow )
     {
-        uno::Reference<awt::XWindow> xWindow = 
VCLUnoHelper::GetInterface(pVclWindow);
-        m_pLockWindow = VCLXWindow::GetImplementation(xWindow);
+        if ( m_pLockWindow )
+            m_pLockWindow->suspendVclEventListening( );
     }
-
-    if (m_pLockWindow)
-        m_pLockWindow->suspendVclEventListening();
-}
-
-VclListenerLock::~VclListenerLock()
-{
-    if (m_pLockWindow)
-        m_pLockWindow->resumeVclEventListening();
-}
+    ~VclListenerLock()
+    {
+        if ( m_pLockWindow )
+            m_pLockWindow->resumeVclEventListening( );
+    }
+    VclListenerLock(const VclListenerLock&) = delete;
+    VclListenerLock& operator=(const VclListenerLock&) = delete;
+};
 
 typedef ::std::map< OUString, sal_Int32 >    MapString2Int;
 struct UnoControl_Data
diff --git a/vcl/source/window/menubarwindow.cxx 
b/vcl/source/window/menubarwindow.cxx
index 09e176930b96..99e8719c79d1 100644
--- a/vcl/source/window/menubarwindow.cxx
+++ b/vcl/source/window/menubarwindow.cxx
@@ -517,7 +517,14 @@ void MenuBarWindow::ChangeHighlightItem( sal_uInt16 n, 
bool bSelectEntry, bool b
             VclPtr<vcl::Window> xTempFocusId = xSaveFocusId;
             xSaveFocusId = nullptr;
             if (bAllowRestoreFocus)
+            {
+                // tdf#115227 the popup is already killed, so temporarily set 
us as the
+                // focus window, so we could avoid sending superfluous 
activate events
+                // to top window listeners.
+                ImplGetSVData()->maWinData.mpFocusWin = this;
                 Window::EndSaveFocus(xTempFocusId);
+                assert(xTempFocusId == nullptr || 
ImplGetSVData()->maWinData.mpFocusWin != this);
+            }
             // #105406# restore focus to document if we could not save focus 
before
             if (bDefaultToDocument && xTempFocusId == nullptr && 
bAllowRestoreFocus)
                 GrabFocusToDocument();
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index a9431e72ac49..25120bea663b 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -3258,7 +3258,7 @@ void Window::ImplCallDeactivateListeners( vcl::Window 
*pNew )
     if ( !pNew || !ImplIsChild( pNew ) )
     {
         VclPtr<vcl::Window> xWindow(this);
-        CallEventListeners( VclEventId::WindowDeactivate );
+        CallEventListeners( VclEventId::WindowDeactivate, pNew );
         if( xWindow->IsDisposed() )
             return;
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to