Blob Blame History Raw
From 241ab576b34a1d6ac6da5616296e5343d0e51801 Mon Sep 17 00:00:00 2001
From: Armin Le Grand <Armin.Le.Grand@cib.de>
Date: Thu, 21 Apr 2016 16:05:38 +0200
Subject: [PATCH] tdf#99388 suppress close comment when PopupMenu is active
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

With comments in draw/impress these use vcl::windows of type
AnnotationWindow. When the PopupMenu bottom-right is used,
this gets a LoseFocus event and gets closed since this is the
standard mechanism this window closes. This is fatal when
the PopupMenu is open since it uses it as parent window.
To avoid this, a flag is added to the AnnotationWindow
to avoid triggering the close event in that state.

Change-Id: Ic27782e56d192c0963868d9ca560945f8a34394f
Reviewed-on: https://gerrit.libreoffice.org/24280
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
(cherry picked from commit ed42a984099b8847aedbdd638c7e20e0b68a9290)

Resolves: tdf#99712 Crash in impress annotation context menu

which is an issue since...

commit dd46727b99d4bb5135451aa7e5e1bdb197373843
Author: Caolán McNamara <caolanm@redhat.com>
Date:   Tue Apr 5 15:27:38 2016 +0100

    Resolves; tdf#87120 no keyboard navigation inside floating windows

    lets try and treat these the same as we do normal toplevels
    like dialogs if they popup with GrabFocus.

    This way focus can be set on widgets inside the floating windows, and
    so keyboard traversal of widgets etc all works.

which allows keyboard focus inside floating windows to allow a11y keyboard
navigation inside them without jumping through difficult hoops.

Change-Id: I6024c048e80d09a70cb3a628378975248a55d6b6
(cherry picked from commit 26333736f103342344b9b0fa20a3a04d426fac4f)
---
 sd/source/ui/annotations/annotationmanager.cxx     | 10 ++++++++++
 sd/source/ui/annotations/annotationmanagerimpl.hxx |  5 +++++
 sd/source/ui/annotations/annotationtag.cxx         | 14 ++++++++++----
 sd/source/ui/annotations/annotationwindow.cxx      |  5 +++++
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/sd/source/ui/annotations/annotationmanager.cxx b/sd/source/ui/annotations/annotationmanager.cxx
index 2d09b7a..28e9dcf 100644
--- a/sd/source/ui/annotations/annotationmanager.cxx
+++ b/sd/source/ui/annotations/annotationmanager.cxx
@@ -172,6 +172,7 @@ AnnotationManagerImpl::AnnotationManagerImpl( ViewShellBase& rViewShellBase )
 , mrBase( rViewShellBase )
 , mpDoc( rViewShellBase.GetDocument() )
 , mbShowAnnotations( true )
+, mbPopupMenuActive( false )
 , mnUpdateTagsEvent( nullptr )
 {
     SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType());
@@ -994,7 +995,16 @@ void AnnotationManagerImpl::ExecuteAnnotationContextMenu( Reference< XAnnotation
         }
     }
 
+    // tdf#99388 and tdf#99712 make known that PopupMenu is active at parent to
+    // allow suppressing closing of that window if needed
+    setPopupMenuActive(true);
+
     nId = pMenu->Execute( pParent, rContextRect, PopupMenuFlags::ExecuteDown|PopupMenuFlags::NoMouseUpClose );
+
+    // tdf#99388 and tdf#99712 reset flag, need to be done before reacting
+    // since closing it is one possible reaction
+    setPopupMenuActive(false);
+
     switch( nId )
     {
     case SID_REPLYTO_POSTIT:
diff --git a/sd/source/ui/annotations/annotationmanagerimpl.hxx b/sd/source/ui/annotations/annotationmanagerimpl.hxx
index 643d3a0..9ea4c29 100644
--- a/sd/source/ui/annotations/annotationmanagerimpl.hxx
+++ b/sd/source/ui/annotations/annotationmanagerimpl.hxx
@@ -112,6 +112,10 @@ public:
 
     void ShowAnnotations(bool bShow);
 
+    // tdf#99388 and tdf#99712 flag to transport if the PopupMenu is active
+    bool getPopupMenuActive() const { return mbPopupMenuActive; }
+    void setPopupMenuActive(bool bNew) { mbPopupMenuActive = bNew; }
+
 private:
     ViewShellBase& mrBase;
     SdDrawDocument* mpDoc;
@@ -123,6 +127,7 @@ private:
     css::uno::Reference< css::office::XAnnotation > mxSelectedAnnotation;
 
     bool mbShowAnnotations;
+    bool mbPopupMenuActive;
     ImplSVEvent * mnUpdateTagsEvent;
     vcl::Font maFont;
 };
diff --git a/sd/source/ui/annotations/annotationtag.cxx b/sd/source/ui/annotations/annotationtag.cxx
index 0c3638f..56ec7f3 100644
--- a/sd/source/ui/annotations/annotationtag.cxx
+++ b/sd/source/ui/annotations/annotationtag.cxx
@@ -600,7 +600,7 @@ void AnnotationTag::OpenPopup( bool bEdit )
 
 void AnnotationTag::ClosePopup()
 {
-    if( mpAnnotationWindow.get() )
+    if( mpAnnotationWindow.get())
     {
         mpAnnotationWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
         mpAnnotationWindow->Deactivate();
@@ -618,10 +618,16 @@ IMPL_LINK_TYPED(AnnotationTag, WindowEventHandler, VclWindowEvent&, rEvent, void
             {
                 if( rEvent.GetId() == VCLEVENT_WINDOW_DEACTIVATE )
                 {
-                    if( mnClosePopupEvent )
-                        Application::RemoveUserEvent( mnClosePopupEvent );
+                    // tdf#99388 and tdf#99712 if PopupMenu is active, suppress
+                    // deletion of the AnnotationWindow which is triggered by
+                    // it losing focus
+                    if (!mrManager.getPopupMenuActive())
+                    {
+                        if( mnClosePopupEvent )
+                            Application::RemoveUserEvent( mnClosePopupEvent );
 
-                    mnClosePopupEvent = Application::PostUserEvent( LINK( this, AnnotationTag, ClosePopupHdl ) );
+                        mnClosePopupEvent = Application::PostUserEvent( LINK( this, AnnotationTag, ClosePopupHdl ) );
+                    }
                 }
             }
             else if( pWindow == mpListenWindow )
diff --git a/sd/source/ui/annotations/annotationwindow.cxx b/sd/source/ui/annotations/annotationwindow.cxx
index dcbeb22..44639c3 100644
--- a/sd/source/ui/annotations/annotationwindow.cxx
+++ b/sd/source/ui/annotations/annotationwindow.cxx
@@ -613,6 +613,11 @@ void AnnotationWindow::SetColor()
 
 void AnnotationWindow::Deactivate()
 {
+    //tdf#99388 and tdf#99712, don't deactivate if we lose focus because of our
+    //own popup
+    if (mrManager.getPopupMenuActive())
+        return;
+
     Reference< XAnnotation > xAnnotation( mxAnnotation );
 
     // write changed text back to annotation
-- 
2.7.4