[Libreoffice-commits] core.git: vcl/inc vcl/qt5

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Sat Jun 22 14:23:26 UTC 2019


 vcl/inc/qt5/Qt5MainWindow.hxx |    3 +
 vcl/inc/salframe.hxx          |    3 +
 vcl/qt5/Qt5Frame.cxx          |   83 +++++++++++++++++++++++++-----------------
 vcl/qt5/Qt5MainWindow.cxx     |   11 ++++-
 vcl/qt5/Qt5Widget.cxx         |   35 ++++++++++-------
 5 files changed, 84 insertions(+), 51 deletions(-)

New commits:
commit 337b592a721bef2c54cbe8c4927e5cc5a68c2138
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Fri Jun 21 04:09:02 2019 +0000
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sat Jun 22 16:22:37 2019 +0200

    tdf#123779 Qt5 correctly fill Qt5Frame::maGeometry
    
    The tooltip in the bug is actually not one, but the VCL implementation
    of Gtk's popover widget triggered by SalFrame::ShowPopover. This has
    no Qt equivalent, so we currently rely on the crude VCL version.
    
    But for this maGeometry must contain the correct information, AKA the
    absolute, unmirrored, paintable system geometry of the frame. Then the
    window can be positioned correctly.
    
    The patch gets rid of most of the code initially copied from gtk, when
    this VCL backend was in a very early state.
    
    Change-Id: Id44e4dc2aac41f1f01d51c4d8107892e644ef243
    Reviewed-on: https://gerrit.libreoffice.org/74546
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

diff --git a/vcl/inc/qt5/Qt5MainWindow.hxx b/vcl/inc/qt5/Qt5MainWindow.hxx
index a2a7e184c291..a0836170f644 100644
--- a/vcl/inc/qt5/Qt5MainWindow.hxx
+++ b/vcl/inc/qt5/Qt5MainWindow.hxx
@@ -28,9 +28,10 @@ class Qt5MainWindow : public QMainWindow
 {
     Q_OBJECT
 
-    Qt5Frame* m_pFrame;
+    Qt5Frame& m_rFrame;
 
     virtual void closeEvent(QCloseEvent* pEvent) override;
+    void moveEvent(QMoveEvent*) override;
 
 public:
     Qt5MainWindow(Qt5Frame& rFrame, QWidget* parent = Q_NULLPTR,
diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx
index 86ad6da98b6e..19293b913621 100644
--- a/vcl/inc/salframe.hxx
+++ b/vcl/inc/salframe.hxx
@@ -124,7 +124,7 @@ public:
                             SalFrame();
     virtual                 ~SalFrame() override;
 
-    SalFrameGeometry        maGeometry;
+    SalFrameGeometry        maGeometry; ///< absolute, unmirrored values
 
     // SalGeometryProvider
     virtual long GetWidth() const override { return maGeometry.nWidth; }
@@ -165,6 +165,7 @@ public:
     const SalFrameGeometry& GetUnmirroredGeometry() const { return maGeometry; }
 
     virtual void            SetWindowState( const SalFrameState* pState ) = 0;
+    // return the absolute, unmirrored system frame state
     // if this returns false the structure is uninitialised
     [[nodiscard]]
     virtual bool            GetWindowState( SalFrameState* pState ) = 0;
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index 0e0b9efae5b1..dbdc51ea9465 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -171,8 +171,8 @@ Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo)
     {
         maGeometry.nDisplayScreenNumber = 0;
         Size aDefSize = CalcDefaultSize();
-        maGeometry.nX = -1;
-        maGeometry.nY = -1;
+        maGeometry.nX = 0;
+        maGeometry.nY = 0;
         maGeometry.nWidth = aDefSize.Width();
         maGeometry.nHeight = aDefSize.Height();
         maGeometry.nTopDecoration = 0;
@@ -372,8 +372,7 @@ void Qt5Frame::Show(bool bVisible, bool /*bNoActivate*/)
 {
     assert(m_pQWidget);
 
-    if (m_bDefaultSize)
-        SetDefaultSize();
+    SetDefaultSize();
 
     auto* pSalInst(static_cast<Qt5Instance*>(GetSalData()->m_pInstance));
     assert(pSalInst);
@@ -431,9 +430,13 @@ Size Qt5Frame::CalcDefaultSize()
 
 void Qt5Frame::SetDefaultSize()
 {
+    if (!m_bDefaultSize)
+        return;
+
     Size aDefSize = CalcDefaultSize();
     SetPosSize(0, 0, aDefSize.Width(), aDefSize.Height(),
                SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT);
+    assert(!m_bDefaultSize);
 }
 
 void Qt5Frame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags)
@@ -441,38 +444,57 @@ void Qt5Frame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt1
     if (!isWindow() || isChild(true, false))
         return;
 
-    if ((nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT))
-        && (nWidth > 0 && nHeight > 0) // sometimes stupid things happen
-    )
+    if (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT))
     {
         m_bDefaultSize = false;
         if (isChild(false) || !m_pQWidget->isMaximized())
         {
-            if (m_nStyle & SalFrameStyleFlags::SIZEABLE)
-                asChild()->resize(nWidth, nHeight);
-            else
-                asChild()->setFixedSize(nWidth, nHeight);
+            if (!(nFlags & SAL_FRAME_POSSIZE_WIDTH))
+                nWidth = maGeometry.nWidth;
+            else if (!(nFlags & SAL_FRAME_POSSIZE_HEIGHT))
+                nHeight = maGeometry.nHeight;
+            assert(nWidth > 0 && nHeight > 0);
+
+            if (nWidth > 0 && nHeight > 0)
+            {
+                if (m_nStyle & SalFrameStyleFlags::SIZEABLE)
+                    asChild()->resize(nWidth, nHeight);
+                else
+                    asChild()->setFixedSize(nWidth, nHeight);
+
+                // assume the resize happened
+                // needed for calculations and will eventuall be corrected by events
+                maGeometry.nWidth = nWidth;
+                maGeometry.nHeight = nHeight;
+            }
         }
     }
-    else if (m_bDefaultSize)
+    else
         SetDefaultSize();
 
-    m_bDefaultSize = false;
-
     if (nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y))
     {
         if (m_pParent)
         {
-            QRect aRect;
-            if (m_pParent->GetTopLevelWindow())
-                aRect = m_pParent->GetTopLevelWindow()->geometry();
+            const SalFrameGeometry& aParentGeometry = m_pParent->maGeometry;
+            if (QGuiApplication::isRightToLeft())
+                nX = aParentGeometry.nX + aParentGeometry.nWidth - nX - maGeometry.nWidth - 1;
             else
-                aRect = m_pParent->GetQWidget()->geometry();
+                nX += aParentGeometry.nX;
+            nY += aParentGeometry.nY;
 
-            nX += aRect.x();
-            nY += aRect.y();
+            Qt5MainWindow* pTopLevel = m_pParent->GetTopLevelWindow();
+            if (pTopLevel && pTopLevel->menuBar() && pTopLevel->menuBar()->isVisible())
+                nY += pTopLevel->menuBar()->geometry().height();
         }
 
+        if (!(nFlags & SAL_FRAME_POSSIZE_X))
+            nX = maGeometry.nX;
+        else if (!(nFlags & SAL_FRAME_POSSIZE_Y))
+            nY = maGeometry.nY;
+
+        // assume the reposition happened
+        // needed for calculations and will eventually be corrected by events later
         maGeometry.nX = nX;
         maGeometry.nY = nY;
 
@@ -553,25 +575,15 @@ void Qt5Frame::SetWindowState(const SalFrameState* pState)
                 | WindowStateMask::Height))
     {
         sal_uInt16 nPosSizeFlags = 0;
-        QPoint aPos = m_pQWidget->pos();
-        QPoint aParentPos;
-        if (m_pParent)
-            aParentPos = m_pParent->GetQWidget()->window()->pos();
-        long nX = pState->mnX - aParentPos.x();
-        long nY = pState->mnY - aParentPos.y();
         if (pState->mnMask & WindowStateMask::X)
             nPosSizeFlags |= SAL_FRAME_POSSIZE_X;
-        else
-            nX = aPos.x() - aParentPos.x();
         if (pState->mnMask & WindowStateMask::Y)
             nPosSizeFlags |= SAL_FRAME_POSSIZE_Y;
-        else
-            nY = aPos.y() - aParentPos.y();
         if (pState->mnMask & WindowStateMask::Width)
             nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH;
         if (pState->mnMask & WindowStateMask::Height)
             nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT;
-        SetPosSize(nX, nY, pState->mnWidth, pState->mnHeight, nPosSizeFlags);
+        SetPosSize(pState->mnX, pState->mnY, pState->mnWidth, pState->mnHeight, nPosSizeFlags);
     }
     else if (pState->mnMask & WindowStateMask::State && !isChild())
     {
@@ -596,11 +608,18 @@ bool Qt5Frame::GetWindowState(SalFrameState* pState)
     }
     else
     {
+        // geometry() is the drawable area, which is wanted here
         QRect rect = asChild()->geometry();
         pState->mnX = rect.x();
         pState->mnY = rect.y();
         pState->mnWidth = rect.width();
         pState->mnHeight = rect.height();
+        // the menubar is drawn natively, adjust for that
+        if (maGeometry.nTopDecoration)
+        {
+            pState->mnY += maGeometry.nTopDecoration;
+            pState->mnHeight -= maGeometry.nTopDecoration;
+        }
         pState->mnMask |= WindowStateMask::X | WindowStateMask::Y | WindowStateMask::Width
                           | WindowStateMask::Height;
     }
@@ -730,8 +749,6 @@ bool Qt5Frame::ShowTooltip(const OUString& rText, const tools::Rectangle& /*rHel
     return true;
 }
 
-// do we even need it? void Qt5Frame::Flush(const tools::Rectangle& /*rRect*/) {}
-
 void Qt5Frame::SetInputContext(SalInputContext* pContext)
 {
     if (!pContext)
diff --git a/vcl/qt5/Qt5MainWindow.cxx b/vcl/qt5/Qt5MainWindow.cxx
index fd4e09771855..a78097fb66c3 100644
--- a/vcl/qt5/Qt5MainWindow.cxx
+++ b/vcl/qt5/Qt5MainWindow.cxx
@@ -17,7 +17,7 @@
 
 Qt5MainWindow::Qt5MainWindow(Qt5Frame& rFrame, QWidget* parent, Qt::WindowFlags f)
     : QMainWindow(parent, f)
-    , m_pFrame(&rFrame)
+    , m_rFrame(rFrame)
 {
     QAccessible::installFactory(Qt5AccessibleWidget::customFactory);
 }
@@ -25,7 +25,7 @@ Qt5MainWindow::Qt5MainWindow(Qt5Frame& rFrame, QWidget* parent, Qt::WindowFlags
 void Qt5MainWindow::closeEvent(QCloseEvent* pEvent)
 {
     bool bRet = false;
-    bRet = m_pFrame->CallCallback(SalEvent::Close, nullptr);
+    bRet = m_rFrame.CallCallback(SalEvent::Close, nullptr);
 
     if (bRet)
         pEvent->accept();
@@ -35,3 +35,10 @@ void Qt5MainWindow::closeEvent(QCloseEvent* pEvent)
     else
         pEvent->ignore();
 }
+
+void Qt5MainWindow::moveEvent(QMoveEvent* pEvent)
+{
+    m_rFrame.maGeometry.nX = pEvent->pos().x();
+    m_rFrame.maGeometry.nY = pEvent->pos().y();
+    m_rFrame.CallCallback(SalEvent::Move, nullptr);
+}
diff --git a/vcl/qt5/Qt5Widget.cxx b/vcl/qt5/Qt5Widget.cxx
index dac72b0c764e..42f3353ff26b 100644
--- a/vcl/qt5/Qt5Widget.cxx
+++ b/vcl/qt5/Qt5Widget.cxx
@@ -75,23 +75,26 @@ void Qt5Widget::paintEvent(QPaintEvent* pEvent)
 
 void Qt5Widget::resizeEvent(QResizeEvent* pEvent)
 {
+    const int nWidth = pEvent->size().width();
+    const int nHeight = pEvent->size().height();
+
+    m_rFrame.maGeometry.nWidth = nWidth;
+    m_rFrame.maGeometry.nHeight = nHeight;
+
     if (m_rFrame.m_bUseCairo)
     {
-        int width = size().width();
-        int height = size().height();
-
         if (m_rFrame.m_pSvpGraphics)
         {
             cairo_surface_t* pSurface
-                = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+                = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nWidth, nHeight);
             cairo_surface_set_user_data(pSurface, SvpSalGraphics::getDamageKey(),
                                         &m_rFrame.m_aDamageHandler, nullptr);
-            m_rFrame.m_pSvpGraphics->setSurface(pSurface, basegfx::B2IVector(width, height));
+            m_rFrame.m_pSvpGraphics->setSurface(pSurface, basegfx::B2IVector(nWidth, nHeight));
             UniqueCairoSurface old_surface(m_rFrame.m_pSurface.release());
             m_rFrame.m_pSurface.reset(pSurface);
 
-            int min_width = qMin(pEvent->oldSize().width(), pEvent->size().width());
-            int min_height = qMin(pEvent->oldSize().height(), pEvent->size().height());
+            int min_width = qMin(pEvent->oldSize().width(), nWidth);
+            int min_height = qMin(pEvent->oldSize().height(), nHeight);
 
             SalTwoRect rect(0, 0, min_width, min_height, 0, 0, min_width, min_height);
 
@@ -103,11 +106,10 @@ void Qt5Widget::resizeEvent(QResizeEvent* pEvent)
         QImage* pImage = nullptr;
 
         if (m_rFrame.m_pQImage)
-            pImage = new QImage(
-                m_rFrame.m_pQImage->copy(0, 0, pEvent->size().width(), pEvent->size().height()));
+            pImage = new QImage(m_rFrame.m_pQImage->copy(0, 0, nWidth, nHeight));
         else
         {
-            pImage = new QImage(size(), Qt5_DefaultFormat32);
+            pImage = new QImage(nWidth, nHeight, Qt5_DefaultFormat32);
             pImage->fill(Qt::transparent);
         }
 
@@ -115,9 +117,6 @@ void Qt5Widget::resizeEvent(QResizeEvent* pEvent)
         m_rFrame.m_pQImage.reset(pImage);
     }
 
-    m_rFrame.maGeometry.nWidth = size().width();
-    m_rFrame.maGeometry.nHeight = size().height();
-
     m_rFrame.CallCallback(SalEvent::Resize, nullptr);
 }
 
@@ -252,7 +251,15 @@ void Qt5Widget::dropEvent(QDropEvent* event)
     QWidget::dropEvent(event);
 }
 
-void Qt5Widget::moveEvent(QMoveEvent*) { m_rFrame.CallCallback(SalEvent::Move, nullptr); }
+void Qt5Widget::moveEvent(QMoveEvent* event)
+{
+    if (m_rFrame.m_pTopLevel)
+        return;
+
+    m_rFrame.maGeometry.nX = event->pos().x();
+    m_rFrame.maGeometry.nY = event->pos().y();
+    m_rFrame.CallCallback(SalEvent::Move, nullptr);
+}
 
 void Qt5Widget::showEvent(QShowEvent*)
 {


More information about the Libreoffice-commits mailing list