summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2022-05-28 23:47:21 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2022-06-21 17:26:06 +0200
commitafc828b9833b7a612369e95606ba56d41ef2c369 (patch)
treeb60ec391ff6f93f85eb4f88d756c2f70b79b674c
parentdbaf5f6fad2ec10f69cf46f9cb697b8760c2a01f (diff)
VCL expect correct frame size for native menubars
... and renove the wrong framesize hack in the Qt backend This wastes a few additional pixels in the frame backing store, actually covered by the real native menu bar, to get rid of all the hacks and eventually fix quite a bunch of bugs in Qt (and maybe other backends). This seems to work correct with Qt using either QPainter or Cairo as the painting backend. It's much simpler then my previous failed attempts to fix the Qt related bugs. I would like to convert every implementation to my interpretation of the API (at least I now documented the API). It looks like Win and Mac will just work, because Win has no native menu bar and Mac uses a global menu, so always returns the size of 0. And Gtk also seems to work, if it also lies about the menu bar size being zero. That just seems consequent, if the frame size is reduced by the menubar size. This fixes at least: tdf#64438 - Dockable panels in LibreOffice not dockable using KDE Works. tdf#130893 - XWindow::SetPosSize resizing based on XWindow::GetPosSize shrinks the window The document macro from tdf#130841 now doesn't resize the window. This is just fixed for Qt. tdf#134704 - KDE5 - unable to dock sidebar by dragging frame not fixed, because the sidebar window is now a dialog, which is not dockable. FWIW the same has happend the Navigator (F5), which also renders it non-dockable. No idea, if this is intentional. tdf#137471 - CMIS dialog advances beyond lower right corner of the screen So commit 3f8d3fd4649ef09e86c735617383a4bda0425540 ("tdf#137471 Qt return frame pos + client area size") was really not enought as a fix (at least it didn't break anything). The whole parent-based repositioning is wrong and it really depends on the correct frame size, so I'm keeping this as fixed by this patch. Change-Id: I7faeace61b456c2b0f42c7a826f58018b70d46ae Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135082 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
-rw-r--r--include/vcl/menu.hxx2
-rw-r--r--vcl/inc/osx/salmenu.h2
-rw-r--r--vcl/inc/qt5/QtFrame.hxx3
-rw-r--r--vcl/inc/qt5/QtMenu.hxx6
-rw-r--r--vcl/inc/qt5/QtPainter.hxx18
-rw-r--r--vcl/inc/qt5/QtTools.hxx5
-rw-r--r--vcl/inc/salmenu.hxx17
-rw-r--r--vcl/inc/unx/gtk/gtksalmenu.hxx6
-rw-r--r--vcl/inc/win/salmenu.h3
-rw-r--r--vcl/osx/salmenu.cxx2
-rw-r--r--vcl/qt5/QtFrame.cxx62
-rw-r--r--vcl/qt5/QtMenu.cxx5
-rw-r--r--vcl/qt5/QtPainter.cxx20
-rw-r--r--vcl/qt5/QtWidget.cxx28
-rw-r--r--vcl/source/app/salvtables.cxx2
-rw-r--r--vcl/source/window/menu.cxx25
-rw-r--r--vcl/source/window/menubarwindow.cxx83
-rw-r--r--vcl/source/window/menubarwindow.hxx1
-rw-r--r--vcl/unx/gtk3/gtksalmenu.cxx7
-rw-r--r--vcl/win/window/salmenu.cxx2
20 files changed, 172 insertions, 127 deletions
diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
index 54df7ee66631..538cc4c88b80 100644
--- a/include/vcl/menu.hxx
+++ b/include/vcl/menu.hxx
@@ -179,6 +179,8 @@ protected:
SAL_DLLPRIVATE void ImplFillLayoutData() const;
SAL_DLLPRIVATE SalMenu* ImplGetSalMenu() { return mpSalMenu.get(); }
+ // convenience function; just returns the SalMenu*, if HasNativeMenuBar() is true
+ SAL_DLLPRIVATE SalMenu* GetNativeMenuBar();
SAL_DLLPRIVATE OUString ImplGetHelpText( sal_uInt16 nItemId ) const;
// returns native check and option menu symbol height in rCheckHeight and rRadioHeight
diff --git a/vcl/inc/osx/salmenu.h b/vcl/inc/osx/salmenu.h
index 597180cc1ac3..274d1ecd70b2 100644
--- a/vcl/inc/osx/salmenu.h
+++ b/vcl/inc/osx/salmenu.h
@@ -55,7 +55,7 @@ public:
AquaSalMenu( bool bMenuBar );
virtual ~AquaSalMenu() override;
- virtual bool VisibleMenuBar() override;
+ virtual bool HasNativeMenuBar() override;
virtual void InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) override;
virtual void RemoveItem( unsigned nPos ) override;
diff --git a/vcl/inc/qt5/QtFrame.hxx b/vcl/inc/qt5/QtFrame.hxx
index 963572ca819b..40954f66d744 100644
--- a/vcl/inc/qt5/QtFrame.hxx
+++ b/vcl/inc/qt5/QtFrame.hxx
@@ -131,7 +131,6 @@ class VCLPLUG_QT_PUBLIC QtFrame : public QObject, public SalFrame
bool isMinimized() const;
bool isMaximized() const;
void SetWindowStateImpl(Qt::WindowStates eState);
- int menuBarOffset() const;
void fixICCCMwindowGroup();
@@ -146,6 +145,8 @@ public:
QtMainWindow* GetTopLevelWindow() const { return m_pTopLevel; }
QWidget* asChild() const;
qreal devicePixelRatioF() const;
+ QPoint mapToParent(const QPoint&) const;
+ QPoint mapFromParent(const QPoint&) const;
void Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
sal_Int32 nExtentsHeight) const;
diff --git a/vcl/inc/qt5/QtMenu.hxx b/vcl/inc/qt5/QtMenu.hxx
index a1b77687ce86..6bb0dbcab4ec 100644
--- a/vcl/inc/qt5/QtMenu.hxx
+++ b/vcl/inc/qt5/QtMenu.hxx
@@ -69,14 +69,15 @@ private:
public:
QtMenu(bool bMenuBar);
- virtual bool VisibleMenuBar() override; // must return TRUE to actually DISPLAY native menu bars
+ virtual bool HasNativeMenuBar() override;
+ virtual int GetMenuBarHeight() const override;
+ virtual void ShowMenuBar(bool bVisible) override;
virtual void InsertItem(SalMenuItem* pSalMenuItem, unsigned nPos) override;
virtual void RemoveItem(unsigned nPos) override;
virtual void SetSubMenu(SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos) override;
virtual void SetFrame(const SalFrame* pFrame) override;
const QtFrame* GetFrame() const;
- virtual void ShowMenuBar(bool bVisible) override;
virtual bool ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangle& rRect,
FloatWinPopupFlags nFlags) override;
QtMenu* GetTopLevel();
@@ -95,7 +96,6 @@ public:
virtual bool AddMenuBarButton(const SalMenuButtonItem&) override;
virtual void RemoveMenuBarButton(sal_uInt16 nId) override;
virtual tools::Rectangle GetMenuBarButtonRectPixel(sal_uInt16 nId, SalFrame*) override;
- virtual int GetMenuBarHeight() const override;
void SetMenu(Menu* pMenu) { mpVCLMenu = pMenu; }
Menu* GetMenu() { return mpVCLMenu; }
diff --git a/vcl/inc/qt5/QtPainter.hxx b/vcl/inc/qt5/QtPainter.hxx
index 9702a19bdbe4..755a51f606ef 100644
--- a/vcl/inc/qt5/QtPainter.hxx
+++ b/vcl/inc/qt5/QtPainter.hxx
@@ -34,34 +34,26 @@ class QtPainter final : public QPainter
public:
QtPainter(QtGraphicsBackend& rGraphics, bool bPrepareBrush = false,
sal_uInt8 nTransparency = 255);
- ~QtPainter()
- {
- if (m_rGraphics.m_pFrame && !m_aRegion.isEmpty())
- m_rGraphics.m_pFrame->GetQWidget()->update(m_aRegion);
- }
+ ~QtPainter();
void update(int nx, int ny, int nw, int nh)
{
if (m_rGraphics.m_pFrame)
- m_aRegion += scaledQRect({ nx, ny, nw, nh }, 1 / m_rGraphics.devicePixelRatioF());
+ m_aRegion += QRect(nx, ny, nw, nh);
}
void update(const QRect& rRect)
{
if (m_rGraphics.m_pFrame)
- m_aRegion += scaledQRect(rRect, 1 / m_rGraphics.devicePixelRatioF());
+ m_aRegion += rRect;
}
- void update(const QRectF& rRectF)
- {
- if (m_rGraphics.m_pFrame)
- update(scaledQRect(rRectF.toAlignedRect(), 1 / m_rGraphics.devicePixelRatioF()));
- }
+ void update(const QRectF& rRectF) { update(rRectF.toAlignedRect()); }
void update()
{
if (m_rGraphics.m_pFrame)
- m_aRegion += m_rGraphics.m_pFrame->GetQWidget()->rect();
+ m_aRegion += m_rGraphics.m_pFrame->GetQWidget()->geometry();
}
};
diff --git a/vcl/inc/qt5/QtTools.hxx b/vcl/inc/qt5/QtTools.hxx
index 534fe74de772..669b5bef6df0 100644
--- a/vcl/inc/qt5/QtTools.hxx
+++ b/vcl/inc/qt5/QtTools.hxx
@@ -69,6 +69,11 @@ inline QRect scaledQRect(const QRect& rRect, const qreal fScale)
ceil(rRect.height() * fScale));
}
+inline QSize scaledQSize(const QSize& rSize, const qreal fScale)
+{
+ return QSize(ceil(rSize.width() * fScale), ceil(rSize.height() * fScale));
+}
+
inline tools::Rectangle toRectangle(const QRect& rRect)
{
return tools::Rectangle(rRect.left(), rRect.top(), rRect.right(), rRect.bottom());
diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx
index 79254d9f5fd5..25a022b39c2a 100644
--- a/vcl/inc/salmenu.hxx
+++ b/vcl/inc/salmenu.hxx
@@ -59,9 +59,18 @@ class VCL_PLUGIN_PUBLIC SalMenu
public:
virtual ~SalMenu();
- virtual bool VisibleMenuBar() = 0; // must return true to actually DISPLAY native menu bars
- // otherwise only menu messages are processed (eg, OLE on Windows)
- virtual void ShowMenuBar( bool ) {}
+ /**
+ * Return true, if the implementation supports a native menu bar
+ * (or wants to suppress LO's menu bar, like on Mac).
+ *
+ * You might need to implement the matching SalFrame::SetMenu.
+ **/
+ virtual bool HasNativeMenuBar() = 0;
+ /** Return the height of the native menu bar. Must return 0, if it's hidden. */
+ virtual int GetMenuBarHeight() const;
+ /** Change visibility of the native menu bar. */
+ virtual void ShowMenuBar(bool);
+
virtual void InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) = 0;
virtual void RemoveItem( unsigned nPos ) = 0;
virtual void SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos ) = 0;
@@ -90,8 +99,6 @@ public:
// but rectangle cannot be determined
virtual tools::Rectangle GetMenuBarButtonRectPixel( sal_uInt16 i_nItemId, SalFrame* i_pReferenceFrame );
- virtual int GetMenuBarHeight() const;
-
virtual void ApplyPersona();
};
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 85c0f5d3d893..ec1e123e89d2 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -71,8 +71,8 @@ public:
GtkSalMenu( bool bMenuBar );
virtual ~GtkSalMenu() override;
- virtual bool VisibleMenuBar() override; // must return TRUE to actually DISPLAY native menu bars
- // otherwise only menu messages are processed (eg, OLE on Windows)
+ virtual bool HasNativeMenuBar() override;
+ virtual void ShowMenuBar(bool bVisible) override;
virtual void InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) override;
virtual void RemoveItem( unsigned nPos ) override;
@@ -112,7 +112,6 @@ public:
static void Activate(const gchar* pMenuCommand);
static void Deactivate(const gchar* pMenuCommand);
void EnableUnity(bool bEnable);
- virtual void ShowMenuBar( bool bVisible ) override;
bool PrepUpdate() const;
virtual void Update() override; // Update this menu only.
// Update full menu hierarchy from this menu.
@@ -139,7 +138,6 @@ public:
virtual tools::Rectangle GetMenuBarButtonRectPixel( sal_uInt16 i_nItemId, SalFrame* i_pReferenceFrame ) override;
virtual bool CanGetFocus() const override;
virtual bool TakeFocus() override;
- virtual int GetMenuBarHeight() const override;
virtual void ApplyPersona() override;
};
diff --git a/vcl/inc/win/salmenu.h b/vcl/inc/win/salmenu.h
index 7058d9c82b8a..96dc2758f08d 100644
--- a/vcl/inc/win/salmenu.h
+++ b/vcl/inc/win/salmenu.h
@@ -28,8 +28,7 @@ class WinSalMenu : public SalMenu
public:
WinSalMenu();
virtual ~WinSalMenu() override;
- virtual bool VisibleMenuBar() override; // must return TRUE to actually DISPLAY native menu bars
- // otherwise only menu messages are processed (eg, OLE on Windows)
+ virtual bool HasNativeMenuBar() override;
virtual void InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) override;
virtual void RemoveItem( unsigned nPos ) override;
diff --git a/vcl/osx/salmenu.cxx b/vcl/osx/salmenu.cxx
index c35e7487f0f6..60cafca71df4 100644
--- a/vcl/osx/salmenu.cxx
+++ b/vcl/osx/salmenu.cxx
@@ -448,7 +448,7 @@ void AquaSalMenu::removeFallbackMenuItem( NSMenuItem* pOldItem )
}
}
-bool AquaSalMenu::VisibleMenuBar()
+bool AquaSalMenu::HasNativeMenuBar()
{
return true;
}
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index 9ccfd8ec5147..3a240b2808ca 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -249,8 +249,16 @@ QtFrame::~QtFrame()
void QtFrame::Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
sal_Int32 nExtentsHeight) const
{
- m_pQWidget->update(scaledQRect(QRect(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight),
- 1 / devicePixelRatioF()));
+ QRect aParentUpdateRect(scaledQRect(QRect(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight),
+ 1 / devicePixelRatioF()));
+ if (!m_pTopLevel)
+ m_pQWidget->update(aParentUpdateRect);
+ else
+ {
+ QRect aIntersectedRect(aParentUpdateRect.intersected(m_pQWidget->geometry()));
+ if (!aIntersectedRect.isEmpty())
+ m_pQWidget->update(aIntersectedRect.translated(-m_pQWidget->geometry().topLeft()));
+ }
}
SalGraphics* QtFrame::AcquireGraphics()
@@ -264,7 +272,7 @@ SalGraphics* QtFrame::AcquireGraphics()
{
if (!m_pSvpGraphics)
{
- QSize aSize = m_pQWidget->size() * devicePixelRatioF();
+ QSize aSize = asChild()->size() * devicePixelRatioF();
m_pSvpGraphics.reset(new QtSvpGraphics(this));
m_pSurface.reset(
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, aSize.width(), aSize.height()));
@@ -281,7 +289,7 @@ SalGraphics* QtFrame::AcquireGraphics()
{
m_pQtGraphics.reset(new QtGraphics(this));
m_pQImage.reset(
- new QImage(m_pQWidget->size() * devicePixelRatioF(), Qt_DefaultFormat32));
+ new QImage(asChild()->size() * devicePixelRatioF(), Qt_DefaultFormat32));
m_pQImage->fill(Qt::transparent);
m_pQtGraphics->ChangeQImage(m_pQImage.get());
}
@@ -447,32 +455,25 @@ void QtFrame::SetMaxClientSize(tools::Long nWidth, tools::Long nHeight)
}
}
-int QtFrame::menuBarOffset() const
-{
- QtMainWindow* pTopLevel = m_pParent->GetTopLevelWindow();
- if (pTopLevel && pTopLevel->menuBar() && pTopLevel->menuBar()->isVisible())
- return round(pTopLevel->menuBar()->geometry().height() * devicePixelRatioF());
- return 0;
-}
-
void QtFrame::SetDefaultPos()
{
if (!m_bDefaultPos)
return;
- // center on parent
+ QWidget* const pChildWin = asChild()->window();
+ QPoint aPos;
+
+ // center on parent or screen
if (m_pParent)
{
- const qreal fRatio = devicePixelRatioF();
QWidget* const pParentWin = m_pParent->asChild()->window();
- QWidget* const pChildWin = asChild()->window();
- QPoint aPos = (pParentWin->rect().center() - pChildWin->rect().center()) * fRatio;
- aPos.ry() -= menuBarOffset();
- SetPosSize(aPos.x(), aPos.y(), 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y);
- assert(!m_bDefaultPos);
+ aPos = (pParentWin->rect().center() - pChildWin->rect().center()) * devicePixelRatioF();
}
else
- m_bDefaultPos = false;
+ aPos = windowHandle()->screen()->availableGeometry().center() - pChildWin->rect().center();
+
+ SetPosSize(aPos.x(), aPos.y(), 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y);
+ assert(!m_bDefaultPos);
}
Size QtFrame::CalcDefaultSize()
@@ -566,10 +567,11 @@ void QtFrame::SetPosSize(tools::Long nX, tools::Long nY, tools::Long nWidth, too
{
const SalFrameGeometry& aParentGeometry = m_pParent->maGeometry;
if (QGuiApplication::isRightToLeft())
- nX = aParentGeometry.x() + aParentGeometry.width() - nX - maGeometry.width() - 1;
+ nX = aParentGeometry.x() + aParentGeometry.width() - nX - maGeometry.width()
+ - aParentGeometry.rightDecoration() - 1;
else
- nX += aParentGeometry.x();
- nY += aParentGeometry.y() + menuBarOffset();
+ nX += aParentGeometry.x() + aParentGeometry.leftDecoration();
+ nY += aParentGeometry.y() + aParentGeometry.topDecoration();
}
if (!(nFlags & SAL_FRAME_POSSIZE_X))
@@ -587,8 +589,8 @@ void QtFrame::SetPosSize(tools::Long nX, tools::Long nY, tools::Long nWidth, too
void QtFrame::GetClientSize(tools::Long& rWidth, tools::Long& rHeight)
{
- rWidth = round(m_pQWidget->width() * devicePixelRatioF());
- rHeight = round(m_pQWidget->height() * devicePixelRatioF());
+ rWidth = maGeometry.width();
+ rHeight = maGeometry.height();
}
void QtFrame::GetWorkArea(tools::Rectangle& rRect)
@@ -1510,4 +1512,14 @@ void QtFrame::handleDragLeave()
m_bInDrag = false;
}
+QPoint QtFrame::mapToParent(const QPoint& rPos) const
+{
+ return m_pTopLevel ? m_pQWidget->mapToParent(rPos) : rPos;
+}
+
+QPoint QtFrame::mapFromParent(const QPoint& rPos) const
+{
+ return m_pTopLevel ? m_pQWidget->mapFromParent(rPos) : rPos;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx
index ccd2eb431f7e..5a4d3e859e9d 100644
--- a/vcl/qt5/QtMenu.cxx
+++ b/vcl/qt5/QtMenu.cxx
@@ -59,7 +59,7 @@ QtMenu::QtMenu(bool bMenuBar)
{
}
-bool QtMenu::VisibleMenuBar() { return true; }
+bool QtMenu::HasNativeMenuBar() { return true; }
void QtMenu::InsertMenuItem(QtMenuItem* pSalMenuItem, unsigned nPos)
{
@@ -845,8 +845,7 @@ int QtMenu::GetMenuBarHeight() const
{
if (!validateQMenuBar() || !mpQMenuBar->isVisible())
return 0;
-
- return mpQMenuBar->height();
+ return mpQMenuBar->height() * mpFrame->devicePixelRatioF();
}
QtMenuItem::QtMenuItem(const SalItemParams* pItemData)
diff --git a/vcl/qt5/QtPainter.cxx b/vcl/qt5/QtPainter.cxx
index fc0057e5618f..a4c83bbba6d8 100644
--- a/vcl/qt5/QtPainter.cxx
+++ b/vcl/qt5/QtPainter.cxx
@@ -56,3 +56,23 @@ QtPainter::QtPainter(QtGraphicsBackend& rGraphics, bool bPrepareBrush, sal_uInt8
setCompositionMode(rGraphics.m_eCompositionMode);
setRenderHint(QPainter::Antialiasing, m_rGraphics.getAntiAlias());
}
+
+QtPainter::~QtPainter()
+{
+ if (!m_rGraphics.m_pFrame || m_aRegion.isEmpty())
+ return;
+
+ QWidget* pWidget = m_rGraphics.m_pFrame->GetQWidget();
+ QRect aParentUpdateRect(
+ scaledQRect(m_aRegion.boundingRect(), 1 / m_rGraphics.devicePixelRatioF()));
+ if (!m_rGraphics.m_pFrame->GetTopLevelWindow())
+ pWidget->update(m_aRegion);
+ else
+ {
+ QRect aIntersectedRect(aParentUpdateRect.intersected(pWidget->geometry()));
+ if (!aIntersectedRect.isEmpty())
+ pWidget->update(aIntersectedRect.translated(-pWidget->geometry().topLeft()));
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index e26e1e3aee1f..ead9979fcf21 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -82,18 +82,21 @@ void QtWidget::paintEvent(QPaintEvent* pEvent)
aImage = *m_rFrame.m_pQImage;
const qreal fRatio = m_rFrame.devicePixelRatioF();
+ assert(aImage.size() == scaledQSize(m_rFrame.asChild()->size(), fRatio));
aImage.setDevicePixelRatio(fRatio);
- QRectF source(pEvent->rect().topLeft() * fRatio, pEvent->rect().size() * fRatio);
- p.drawImage(pEvent->rect(), aImage, source);
+ QPoint aPos = m_rFrame.mapToParent(pEvent->rect().topLeft());
+ QRectF source(aPos * fRatio, scaledQSize(pEvent->rect().size(), fRatio));
+ p.drawImage(pEvent->rect().topLeft(), aImage, source);
}
-void QtWidget::resizeEvent(QResizeEvent* pEvent)
+void QtWidget::resizeEvent(QResizeEvent*)
{
+ // this uses the actual frame size for the double buffering backing store.
+ // while children get a resize event before their parents, the size of the
+ // frame / window is already updated at this point.
const qreal fRatio = m_rFrame.devicePixelRatioF();
- const int nWidth = ceil(pEvent->size().width() * fRatio);
- const int nHeight = ceil(pEvent->size().height() * fRatio);
-
- m_rFrame.maGeometry.setSize({ nWidth, nHeight });
+ const int nWidth = ceil(m_rFrame.asChild()->size().width() * fRatio);
+ const int nHeight = ceil(m_rFrame.asChild()->size().height() * fRatio);
if (m_rFrame.m_bUseCairo)
{
@@ -128,6 +131,13 @@ void QtWidget::resizeEvent(QResizeEvent* pEvent)
}
}
+ const QRect aQtFrameGeometry = m_rFrame.asChild()->frameGeometry();
+ const QRect aQtGeometry = m_rFrame.asChild()->geometry();
+ m_rFrame.maGeometry.setLeftDecoration(aQtGeometry.left() - aQtFrameGeometry.left());
+ m_rFrame.maGeometry.setTopDecoration(aQtGeometry.top() - aQtFrameGeometry.top());
+ m_rFrame.maGeometry.setRightDecoration(aQtFrameGeometry.right() - aQtGeometry.right());
+ m_rFrame.maGeometry.setBottomDecoration(aQtFrameGeometry.bottom() - aQtGeometry.bottom());
+ m_rFrame.maGeometry.setSize({ nWidth, nHeight });
m_rFrame.CallCallback(SalEvent::Resize, nullptr);
}
@@ -142,7 +152,7 @@ void QtWidget::fillSalAbstractMouseEvent(const QtFrame& rFrame, const QInputEven
SalAbstractMouseEvent& aSalEvent)
{
const qreal fRatio = rFrame.devicePixelRatioF();
- const Point aPos = toPoint(rPos * fRatio);
+ const Point aPos = toPoint(rFrame.mapToParent(rPos) * fRatio);
aSalEvent.mnX = QGuiApplication::isLeftToRight() ? aPos.X() : round(nWidth * fRatio) - aPos.X();
aSalEvent.mnY = aPos.Y();
@@ -205,7 +215,7 @@ void QtWidget::mouseMoveEvent(QMouseEvent* pEvent)
void QtWidget::handleMouseEnterLeaveEvents(const QtFrame& rFrame, QEvent* pQEvent)
{
const qreal fRatio = rFrame.devicePixelRatioF();
- const QWidget* pWidget = rFrame.GetQWidget();
+ const QWidget* pWidget = rFrame.asChild();
const Point aPos = toPoint(pWidget->mapFromGlobal(QCursor::pos()) * fRatio);
SalMouseEvent aEvent;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 40c04421b8d5..0cca56bcf5b9 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -235,6 +235,8 @@ tools::Rectangle SalMenu::GetMenuBarButtonRectPixel(sal_uInt16, SalFrame*)
int SalMenu::GetMenuBarHeight() const { return 0; }
+void SalMenu::ShowMenuBar(bool) {}
+
void SalMenu::ApplyPersona() {}
SalMenuItem::~SalMenuItem() {}
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 5fb4c2ca81df..bd244319e136 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2207,6 +2207,11 @@ void Menu::ImplFillLayoutData() const
}
}
+SalMenu* Menu::GetNativeMenuBar()
+{
+ return mpSalMenu && mpSalMenu->HasNativeMenuBar() ? mpSalMenu.get() : nullptr;
+}
+
tools::Rectangle Menu::GetCharacterBounds( sal_uInt16 nItemID, tools::Long nIndex ) const
{
tools::Long nItemIndex = -1;
@@ -2440,26 +2445,16 @@ void MenuBar::SetDisplayable( bool bDisplayable )
VclPtr<vcl::Window> MenuBar::ImplCreate(vcl::Window* pParent, vcl::Window* pWindow, MenuBar* pMenu)
{
+ // can't this be a static_cast? is there a real possibility, the pWindow is not the MenuBarWindow or nullptr?
VclPtr<MenuBarWindow> pMenuBarWindow = dynamic_cast<MenuBarWindow*>(pWindow);
if (!pMenuBarWindow)
- {
- pWindow = pMenuBarWindow = VclPtr<MenuBarWindow>::Create( pParent );
- }
+ pMenuBarWindow = VclPtr<MenuBarWindow>::Create(pParent);
pMenu->pStartedFrom = nullptr;
- pMenu->pWindow = pWindow;
+ pMenu->pWindow = pMenuBarWindow;
pMenuBarWindow->SetMenu(pMenu);
- tools::Long nHeight = pWindow ? pMenu->ImplCalcSize(pWindow).Height() : 0;
-
- // depending on the native implementation or the displayable flag
- // the menubar windows is suppressed (ie, height=0)
- if (!pMenu->IsDisplayable() || (pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar()))
- {
- nHeight = 0;
- }
- pMenuBarWindow->SetHeight(nHeight);
- return pWindow;
+ return pMenuBarWindow;
}
void MenuBar::ImplDestroy( MenuBar* pMenu, bool bDelete )
@@ -2486,7 +2481,7 @@ bool MenuBar::ImplHandleKeyEvent( const KeyEvent& rKEvent )
// No keyboard processing when system handles the menu.
SalMenu *pNativeMenu = ImplGetSalMenu();
- if (pNativeMenu && pNativeMenu->VisibleMenuBar())
+ if (pNativeMenu && pNativeMenu->HasNativeMenuBar())
{
// Except when the event is the F6 cycle pane event and we can put our
// focus into it (i.e. the gtk3 menubar case but not the mac/unity case
diff --git a/vcl/source/window/menubarwindow.cxx b/vcl/source/window/menubarwindow.cxx
index 0109bb559503..552034b07284 100644
--- a/vcl/source/window/menubarwindow.cxx
+++ b/vcl/source/window/menubarwindow.cxx
@@ -167,34 +167,43 @@ void MenuBarWindow::dispose()
Window::dispose();
}
-void MenuBarWindow::SetMenu( MenuBar* pMen )
+void MenuBarWindow::SetMenu(MenuBar* pMenu)
{
- m_pMenu = pMen;
+ if (pMenu == m_pMenu)
+ return;
+ m_pMenu = pMenu;
+
KillActivePopup();
m_nHighlightedItem = ITEMPOS_INVALID;
- if (pMen)
+
+ if (!pMenu)
{
- m_aCloseBtn->ShowItem(ToolBoxItemId(IID_DOCUMENTCLOSE), pMen->HasCloseButton());
- m_aCloseBtn->Show(pMen->HasCloseButton() || !m_aAddButtons.empty());
- m_aFloatBtn->Show(pMen->HasFloatButton());
- m_aHideBtn->Show(pMen->HasHideButton());
+ LayoutChanged();
+ return;
}
- Invalidate();
-
- // show and connect native menubar
- if( m_pMenu && m_pMenu->ImplGetSalMenu() )
+ SalMenu* pSalMenu = pMenu->ImplGetSalMenu();
+ const bool bHasNativeMenuBar = pSalMenu && pSalMenu->HasNativeMenuBar();
+
+ // no menubar window drawing needed in case of a native menu bar
+ SetPaintTransparent(bHasNativeMenuBar);
+ m_aCloseBtn->ShowItem(ToolBoxItemId(IID_DOCUMENTCLOSE), !bHasNativeMenuBar && pMenu->HasCloseButton());
+ m_aCloseBtn->Show(!bHasNativeMenuBar && (pMenu->HasCloseButton() || !m_aAddButtons.empty()));
+ m_aFloatBtn->Show(!bHasNativeMenuBar && pMenu->HasFloatButton());
+ m_aHideBtn->Show(!bHasNativeMenuBar && pMenu->HasHideButton());
+
+ // connect native popup menu / menubar and show it
+ if (pSalMenu)
{
- if( m_pMenu->ImplGetSalMenu()->VisibleMenuBar() )
- ImplGetFrame()->SetMenu( m_pMenu->ImplGetSalMenu() );
-
- m_pMenu->ImplGetSalMenu()->SetFrame( ImplGetFrame() );
- m_pMenu->ImplGetSalMenu()->ShowMenuBar(true);
+ SalFrame* pFrame = ImplGetFrame();
+ assert(pFrame);
+ if (bHasNativeMenuBar)
+ pFrame->SetMenu(pSalMenu);
+ pSalMenu->SetFrame(pFrame);
+ if (bHasNativeMenuBar)
+ pSalMenu->ShowMenuBar(true);
}
-}
-void MenuBarWindow::SetHeight(tools::Long nHeight)
-{
- setPosSizePixel(0, 0, 0, nHeight, PosSizeFlags::Height);
+ LayoutChanged();
}
void MenuBarWindow::ShowButtons( bool bClose, bool bFloat, bool bHide )
@@ -724,10 +733,8 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
}
// no key events if native menus
- if (m_pMenu->ImplGetSalMenu() && m_pMenu->ImplGetSalMenu()->VisibleMenuBar())
- {
+ if (m_pMenu->GetNativeMenuBar())
return false;
- }
if ( nCode == KEY_MENU && !rKEvent.GetKeyCode().IsShift() ) // only F10, not Shift-F10
{
@@ -862,7 +869,7 @@ void MenuBarWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Recta
Size aOutputSize = GetOutputSizePixel();
// no VCL paint if native menus
- if (m_pMenu->ImplGetSalMenu() && m_pMenu->ImplGetSalMenu()->VisibleMenuBar())
+ if (m_pMenu->GetNativeMenuBar())
return;
// Make sure that all actual rendering happens in one go to avoid flicker.
@@ -1004,22 +1011,24 @@ void MenuBarWindow::LayoutChanged()
ApplySettings(*GetOutDev());
- // if the font was changed.
- tools::Long nHeight = m_pMenu->ImplCalcSize(this).Height();
-
// depending on the native implementation or the displayable flag
// the menubar windows is suppressed (ie, height=0)
- if (!static_cast<MenuBar*>(m_pMenu.get())->IsDisplayable() ||
- (m_pMenu->ImplGetSalMenu() && m_pMenu->ImplGetSalMenu()->VisibleMenuBar()))
- {
- nHeight = 0;
- }
+ tools::Long nHeight = 0;
+ const bool bHasNativeMenuBar = m_pMenu->GetNativeMenuBar();
+ if (bHasNativeMenuBar)
+ nHeight = m_pMenu->ImplGetSalMenu()->GetMenuBarHeight();
+ else if (static_cast<MenuBar*>(m_pMenu.get())->IsDisplayable())
+ nHeight = m_pMenu->ImplCalcSize(this).Height();
+
setPosSizePixel(0, 0, 0, nHeight, PosSizeFlags::Height);
GetParent()->Resize();
- Invalidate();
- Resize();
- m_pMenu->ImplKillLayoutData();
+ if (!bHasNativeMenuBar)
+ {
+ Invalidate();
+ Resize();
+ m_pMenu->ImplKillLayoutData();
+ }
}
void MenuBarWindow::ApplySettings(vcl::RenderContext& rRenderContext)
@@ -1210,8 +1219,8 @@ bool MenuBarWindow::CanGetFocus() const
this relies on MenuBar::ImplCreate setting the height of the menubar
to 0 in this case
*/
- SalMenu *pNativeMenu = m_pMenu ? m_pMenu->ImplGetSalMenu() : nullptr;
- if (pNativeMenu && pNativeMenu->VisibleMenuBar())
+ SalMenu *pNativeMenu = m_pMenu ? m_pMenu->GetNativeMenuBar() : nullptr;
+ if (pNativeMenu)
return pNativeMenu->CanGetFocus();
return GetSizePixel().Height() > 0;
}
diff --git a/vcl/source/window/menubarwindow.hxx b/vcl/source/window/menubarwindow.hxx
index cc7963a1bed0..0a9074737623 100644
--- a/vcl/source/window/menubarwindow.hxx
+++ b/vcl/source/window/menubarwindow.hxx
@@ -120,7 +120,6 @@ public:
virtual void RequestHelp( const HelpEvent& rHEvt ) override;
void SetMenu(MenuBar* pMenu);
- void SetHeight(tools::Long nHeight);
void KillActivePopup();
void PopupClosed(Menu const * pMenu);
sal_uInt16 GetHighlightedItem() const { return m_nHighlightedItem; }
diff --git a/vcl/unx/gtk3/gtksalmenu.cxx b/vcl/unx/gtk3/gtksalmenu.cxx
index bcae159ffd33..22261c62bbf4 100644
--- a/vcl/unx/gtk3/gtksalmenu.cxx
+++ b/vcl/unx/gtk3/gtksalmenu.cxx
@@ -653,7 +653,7 @@ GtkSalMenu::~GtkSalMenu()
mpFrame->SetMenu(nullptr);
}
-bool GtkSalMenu::VisibleMenuBar()
+bool GtkSalMenu::HasNativeMenuBar()
{
return mbMenuBar && (bUnityMode || mpMenuBarContainerWidget);
}
@@ -1618,11 +1618,6 @@ void GtkSalMenu::GetSystemMenuData( SystemMenuData* )
{
}
-int GtkSalMenu::GetMenuBarHeight() const
-{
- return mpMenuBarWidget ? gtk_widget_get_allocated_height(mpMenuBarWidget) : 0;
-}
-
/*
* GtkSalMenuItem
*/
diff --git a/vcl/win/window/salmenu.cxx b/vcl/win/window/salmenu.cxx
index 91a15284aeb5..4b07f231dfa5 100644
--- a/vcl/win/window/salmenu.cxx
+++ b/vcl/win/window/salmenu.cxx
@@ -115,7 +115,7 @@ WinSalMenu::~WinSalMenu()
::DestroyMenu( mhMenu );
}
-bool WinSalMenu::VisibleMenuBar()
+bool WinSalMenu::HasNativeMenuBar()
{
// The Win32 implementation never shows a native
// menubar. Thus, native menus are only visible