include/vcl/layout.hxx       |    1 
 vcl/source/window/layout.cxx |   58 +++++++++++++++++++++++++++++--------------
 2 files changed, 41 insertions(+), 18 deletions(-)

New commits:
commit b9a3ab00dfe64c7bb19277dbad3545b83aacdc21
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Fri Sep 3 17:27:54 2021 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Fri Sep 3 22:19:33 2021 +0200

    tdf#142458 Set correct ScrolledWindow BorderWidth in the ctor
    
    and keep it updated when the relevant properties that affect it change.
    This avoids the problem that the borderwidth can change during "Paint"
    (which is something we strongly want to avoid) since...
    
    since:
    
    commit f39f21d92ec83c3a5062f29dd26214fc83012c06
    Date:   Thu Nov 19 11:51:13 2020 +0100
    
        tdf#138010 (IV) VclScrolledWindow: Use actual border width
    
    hopefully after this we can then double-check to see if we can remove
    the potential change of BorderWidth during paint.
    
    Change-Id: I2ec317d86687fdb75e6323905f6d1c3b8fc655e1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121615
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/include/vcl/layout.hxx b/include/vcl/layout.hxx
index 7f3f37a479fa..14c85938d639 100644
--- a/include/vcl/layout.hxx
+++ b/include/vcl/layout.hxx
@@ -502,6 +502,7 @@ private:
     virtual void setAllocation(const Size &rAllocation) override;
     // sets new border size and adapts scrollbar and child widget 
position/size as needed
     void updateBorderWidth(tools::Long nBorderWidth);
+    int CalcBorderWidth() const;
     DECL_LINK(ScrollBarHdl, ScrollBar*, void);
     void InitScrollBars(const Size &rRequest);
     virtual bool EventNotify(NotifyEvent& rNEvt) override;
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 6ce711bea1aa..680a650f34f2 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -1809,7 +1809,6 @@ IMPL_LINK( VclExpander, ClickHdl, CheckBox&, rBtn, void )
 VclScrolledWindow::VclScrolledWindow(vcl::Window *pParent)
     : VclBin(pParent, WB_HIDE | WB_CLIPCHILDREN | WB_AUTOHSCROLL | 
WB_AUTOVSCROLL | WB_TABSTOP)
     , m_bUserManagedScrolling(false)
-    , m_nBorderWidth(1)
     , m_eDrawFrameStyle(DrawFrameStyle::NONE)
     , m_eDrawFrameFlags(DrawFrameFlags::NONE)
     , m_pVScroll(VclPtr<ScrollBar>::Create(this, WB_HIDE | WB_VERT))
@@ -1827,6 +1826,18 @@ VclScrolledWindow::VclScrolledWindow(vcl::Window 
*pParent)
     Link<ScrollBar*,void> aLink( LINK( this, VclScrolledWindow, ScrollBarHdl ) 
);
     m_pVScroll->SetScrollHdl(aLink);
     m_pHScroll->SetScrollHdl(aLink);
+
+    m_nBorderWidth = CalcBorderWidth();
+}
+
+int VclScrolledWindow::CalcBorderWidth() const
+{
+    const tools::Rectangle aRect(tools::Rectangle(Point(0, 0), Size(100, 
100)));
+    DecorationView aDecoView(const_cast<OutputDevice*>(GetOutDev()));
+    // don't actually draw anything, just measure what size it would be and 
the diff is the desired border size to reserve
+    const tools::Rectangle aContentRect = aDecoView.DrawFrame(aRect, 
m_eDrawFrameStyle, m_eDrawFrameFlags | DrawFrameFlags::NoDraw);
+    const auto nBorderWidth = (aRect.GetWidth() - aContentRect.GetWidth()) / 2;
+    return std::max<int>(nBorderWidth, 1);
 }
 
 void VclScrolledWindow::dispose()
@@ -2030,24 +2041,35 @@ Size VclScrolledWindow::getVisibleChildSize() const
 
 bool VclScrolledWindow::set_property(const OString &rKey, const OUString 
&rValue)
 {
-    if (rKey == "shadow-type")
-    {
-        // despite the style names, this looks like the best mapping
-        if (rValue == "in")
-            m_eDrawFrameStyle = DrawFrameStyle::Out;
-        else if (rValue == "out")
-            m_eDrawFrameStyle = DrawFrameStyle::In;
-        else if (rValue == "etched-in")
-            m_eDrawFrameStyle = DrawFrameStyle::DoubleOut;
-        else if (rValue == "etched-out")
-            m_eDrawFrameStyle = DrawFrameStyle::DoubleIn;
-        else if (rValue == "none")
-            m_eDrawFrameStyle = DrawFrameStyle::NONE;
-        return true;
-    }
-    else if (rKey == "name")
+    if (rKey == "shadow-type" || rKey == "name")
     {
-        m_eDrawFrameFlags = rValue == "monoborder" ? DrawFrameFlags::Mono : 
DrawFrameFlags::NONE;
+        if (rKey == "shadow-type")
+        {
+            // despite the style names, this looks like the best mapping
+            if (rValue == "in")
+                m_eDrawFrameStyle = DrawFrameStyle::Out;
+            else if (rValue == "out")
+                m_eDrawFrameStyle = DrawFrameStyle::In;
+            else if (rValue == "etched-in")
+                m_eDrawFrameStyle = DrawFrameStyle::DoubleOut;
+            else if (rValue == "etched-out")
+                m_eDrawFrameStyle = DrawFrameStyle::DoubleIn;
+            else if (rValue == "none")
+                m_eDrawFrameStyle = DrawFrameStyle::NONE;
+        }
+        else if (rKey == "name")
+        {
+            m_eDrawFrameFlags = rValue == "monoborder" ? DrawFrameFlags::Mono 
: DrawFrameFlags::NONE;
+        }
+
+        auto nBorderWidth = CalcBorderWidth();
+        if (m_nBorderWidth != nBorderWidth)
+        {
+            m_nBorderWidth = nBorderWidth;
+            queue_resize();
+        }
+
+        return true;
     }
 
     bool bRet = VclBin::set_property(rKey, rValue);

Reply via email to