sd/source/ui/func/fucon3d.cxx  |    3 +++
 sd/source/ui/func/fuconarc.cxx |    3 +++
 sd/source/ui/func/fuconbez.cxx |    3 +++
 sd/source/ui/func/fuconcs.cxx  |    3 +++
 sd/source/ui/func/fuconrec.cxx |    3 +++
 sd/source/ui/func/fuconstr.cxx |   13 +++++++++++++
 sd/source/ui/func/fuconuno.cxx |    3 +++
 sd/source/ui/inc/fuconstr.hxx  |    3 +++
 8 files changed, 34 insertions(+)

New commits:
commit 634e13e9d6d9bbe2d051978538c02926f764e51b
Author:     Justin Luth <jl...@mail.com>
AuthorDate: Wed Jul 5 12:19:27 2023 -0400
Commit:     Justin Luth <jl...@mail.com>
CommitDate: Wed Jul 12 20:50:24 2023 +0200

    tdf#153446 sd fuconstruct: handle mouse-up without mouse-down
    
    The situation where this was happening occurred when the notebookbar
    had a pop-out of additional functions available. This pop-out removed
    the focus from the draw window, so the mouse-down was used
    to regain focus in Draw. The mouse-up just needed to be absorbed
    or else the "drag the shape to create" would be changed into a select.
    
    I checked as many "situations" as I could possibly have conceived of
    after reviewing the code in this area. The ones I know I need are !bMBDown
    and !IsAction(). The rest are just to try to avoid getting me into trouble.
    
    [FuText also could benefit from this,
     but that function is much more complex,
     and so I don't dare to interfere.
    
     It already does BegCreateObj on a mouse-up,
     but the textbox it creates is hard to notice.]
    
    Change-Id: I4ed2564e81d8a7ce82e7edec43e4e9acc6e97760
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154069
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>

diff --git a/sd/source/ui/func/fucon3d.cxx b/sd/source/ui/func/fucon3d.cxx
index a2f76b8d8df9..812a8e705cd7 100644
--- a/sd/source/ui/func/fucon3d.cxx
+++ b/sd/source/ui/func/fucon3d.cxx
@@ -353,6 +353,9 @@ bool FuConstruct3dObject::MouseButtonDown(const MouseEvent& 
rMEvt)
 
 bool FuConstruct3dObject::MouseButtonUp(const MouseEvent& rMEvt)
 {
+    if (rMEvt.IsLeft() && IsIgnoreUnexpectedMouseButtonUp())
+        return false;
+
     bool bReturn = false;
 
     if ( mpView->IsCreateObj() && rMEvt.IsLeft() )
diff --git a/sd/source/ui/func/fuconarc.cxx b/sd/source/ui/func/fuconarc.cxx
index 35b2c33b4ad7..b69eb0cadee1 100644
--- a/sd/source/ui/func/fuconarc.cxx
+++ b/sd/source/ui/func/fuconarc.cxx
@@ -130,6 +130,9 @@ bool FuConstructArc::MouseButtonDown( const MouseEvent& 
rMEvt )
 
 bool FuConstructArc::MouseButtonUp( const MouseEvent& rMEvt )
 {
+    if (rMEvt.IsLeft() && IsIgnoreUnexpectedMouseButtonUp())
+        return false;
+
     bool bReturn = false;
     bool bCreated = false;
 
diff --git a/sd/source/ui/func/fuconbez.cxx b/sd/source/ui/func/fuconbez.cxx
index 319c8b1b9adb..881f27343d5d 100644
--- a/sd/source/ui/func/fuconbez.cxx
+++ b/sd/source/ui/func/fuconbez.cxx
@@ -190,6 +190,9 @@ bool FuConstructBezierPolygon::MouseButtonDown(const 
MouseEvent& rMEvt)
 
 bool FuConstructBezierPolygon::MouseButtonUp(const MouseEvent& rMEvt )
 {
+    if (rMEvt.IsLeft() && IsIgnoreUnexpectedMouseButtonUp())
+        return false;
+
     bool bReturn = false;
     bool bCreated = false;
 
diff --git a/sd/source/ui/func/fuconcs.cxx b/sd/source/ui/func/fuconcs.cxx
index 7fbecef5d00d..d8df8c699b9a 100644
--- a/sd/source/ui/func/fuconcs.cxx
+++ b/sd/source/ui/func/fuconcs.cxx
@@ -115,6 +115,9 @@ bool FuConstructCustomShape::MouseButtonDown(const 
MouseEvent& rMEvt)
 
 bool FuConstructCustomShape::MouseButtonUp(const MouseEvent& rMEvt)
 {
+    if (rMEvt.IsLeft() && IsIgnoreUnexpectedMouseButtonUp())
+        return false;
+
     bool bReturn(false);
 
     if(mpView->IsCreateObj() && rMEvt.IsLeft())
diff --git a/sd/source/ui/func/fuconrec.cxx b/sd/source/ui/func/fuconrec.cxx
index 3561a6eb8c47..5d7aeb173bcc 100644
--- a/sd/source/ui/func/fuconrec.cxx
+++ b/sd/source/ui/func/fuconrec.cxx
@@ -282,6 +282,9 @@ bool FuConstructRectangle::MouseButtonDown(const 
MouseEvent& rMEvt)
 
 bool FuConstructRectangle::MouseButtonUp(const MouseEvent& rMEvt)
 {
+    if (rMEvt.IsLeft() && IsIgnoreUnexpectedMouseButtonUp())
+        return false;
+
     bool bReturn(false);
 
     if(mpView->IsCreateObj() && rMEvt.IsLeft())
diff --git a/sd/source/ui/func/fuconstr.cxx b/sd/source/ui/func/fuconstr.cxx
index fd93a3ce7c94..a3ccf35d4f40 100644
--- a/sd/source/ui/func/fuconstr.cxx
+++ b/sd/source/ui/func/fuconstr.cxx
@@ -230,6 +230,19 @@ void FuConstruct::Deactivate()
     mpView->SetEditMode(SdrViewEditMode::Edit);
 }
 
+bool FuConstruct::IsIgnoreUnexpectedMouseButtonUp()
+{
+    // tdf#153446 if there is a MouseButtonUp without a previous 
MouseButtonDown event,
+    // the MouseButtonDown was probably swallowed by a gain-focus action,
+    // and then this MouseButtonUp should be ignored
+
+    if (bMBDown || bIsInDragMode)
+        return false;
+
+    // Don't ignore if there are pending mouse-initiated tasks to complete.
+    return !mpView->IsDragObj() && !mpWindow->IsMouseCaptured() && 
!mpView->IsAction();
+}
+
 /**
  * set style sheet for the object to be created
  */
diff --git a/sd/source/ui/func/fuconuno.cxx b/sd/source/ui/func/fuconuno.cxx
index 9ff3c242d845..4bba20eade70 100644
--- a/sd/source/ui/func/fuconuno.cxx
+++ b/sd/source/ui/func/fuconuno.cxx
@@ -91,6 +91,9 @@ bool FuConstructUnoControl::MouseButtonDown(const MouseEvent& 
rMEvt)
 
 bool FuConstructUnoControl::MouseButtonUp(const MouseEvent& rMEvt)
 {
+    if (rMEvt.IsLeft() && IsIgnoreUnexpectedMouseButtonUp())
+        return false;
+
     bool bReturn = false;
 
     if ( mpView->IsCreateObj() && rMEvt.IsLeft() )
diff --git a/sd/source/ui/inc/fuconstr.hxx b/sd/source/ui/inc/fuconstr.hxx
index 743c6cd5bb31..fd61046a14c2 100644
--- a/sd/source/ui/inc/fuconstr.hxx
+++ b/sd/source/ui/inc/fuconstr.hxx
@@ -40,6 +40,9 @@ public:
 
     virtual void SelectionHasChanged() override { bSelectionChanged = true; }
 
+    // Without a preceding MouseButtonDown, a MouseButtonUp event should 
probably be ignored
+    bool IsIgnoreUnexpectedMouseButtonUp();
+
     // SJ: setting stylesheet, the use of a filled or unfilled style
     // is determined by the member nSlotId :
     void SetStyleSheet(SfxItemSet& rAttr, SdrObject* pObj);

Reply via email to