summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2019-08-22 17:30:43 +0200
committerMiklos Vajna <vmiklos@collabora.com>2019-08-22 20:40:01 +0200
commitd5c7657c541c1f6d17bfe5e605594c235eecfcdb (patch)
tree251a2e9962dc632d608b4141b162fbdc6dda94f7
parent055c249847548a5c28ab5b29f3603ffbe74fe1f0 (diff)
tdf#71087 sfx2: avoid flicker in the start center
There were a couple of problems here: 1) BackingWindow now does double-buffering to avoid flicker when e.g. navigating with the keyboard in sfx2::RecentDocsView 2) But then the menu background turned into white (instead of the gradient), so MenuBarWindow needs to differentiate between doing its own buffering vs painting into a buffer. 3) The focus rectangles were always painted directly, so keyboard navigation in the startcenter lost focus rectangles, making it hard to see which button is active currently. Fix this by explicitly painting a tracking rectangle in PushButton::ImplDrawPushButton(). This brings an improvement for the Windows GDI and Linux gen backends. Windows GL and Linux gtk3 is meant to be unchanged, they were already flicker-free here. Change-Id: Ib01e330c244c2b38a5b5c52399692e19ff811de3 Reviewed-on: https://gerrit.libreoffice.org/77969 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--sfx2/source/dialog/backingcomp.cxx10
-rw-r--r--vcl/source/control/button.cxx10
-rw-r--r--vcl/source/window/bufferdevice.cxx2
-rw-r--r--vcl/source/window/bufferdevice.hxx1
-rw-r--r--vcl/source/window/menubarwindow.cxx16
5 files changed, 37 insertions, 2 deletions
diff --git a/sfx2/source/dialog/backingcomp.cxx b/sfx2/source/dialog/backingcomp.cxx
index 1de9a2daa698..a810f0be9fda 100644
--- a/sfx2/source/dialog/backingcomp.cxx
+++ b/sfx2/source/dialog/backingcomp.cxx
@@ -576,6 +576,12 @@ void SAL_CALL BackingComp::dispose()
{
m_xWindow->removeEventListener(this);
m_xWindow->removeKeyListener(this);
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(m_xWindow);
+ auto pBack = dynamic_cast<BackingWindow*>(pWindow.get());
+ if (pBack)
+ {
+ pBack->RequestDoubleBuffering(false);
+ }
m_xWindow.clear();
}
@@ -660,6 +666,10 @@ void SAL_CALL BackingComp::initialize( /*IN*/ const css::uno::Sequence< css::uno
// create the component window
VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(xParentWindow);
VclPtr<vcl::Window> pWindow = VclPtr<BackingWindow>::Create(pParent);
+ if (!pWindow->IsNativeControlSupported(ControlType::Pushbutton, ControlPart::Focus))
+ {
+ pWindow->RequestDoubleBuffering(true);
+ }
m_xWindow = VCLUnoHelper::GetInterface(pWindow);
if (!m_xWindow.is())
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index 8669e655479f..27b6bd4f9b0e 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -1080,7 +1080,13 @@ void PushButton::ImplDrawPushButton(vcl::RenderContext& rRenderContext)
aInRect, bDrawMenuSep, nButtonStyle);
if (HasFocus())
+ {
ShowFocus(ImplGetFocusRect());
+ if (SupportsDoubleBuffering())
+ {
+ rRenderContext.Invert(ImplGetFocusRect(), InvertFlags::TrackFrame);
+ }
+ }
}
if (!bNativeOK)
@@ -1107,6 +1113,10 @@ void PushButton::ImplDrawPushButton(vcl::RenderContext& rRenderContext)
if (HasFocus())
{
ShowFocus(ImplGetFocusRect());
+ if (SupportsDoubleBuffering())
+ {
+ rRenderContext.Invert(ImplGetFocusRect(), InvertFlags::TrackFrame);
+ }
}
}
}
diff --git a/vcl/source/window/bufferdevice.cxx b/vcl/source/window/bufferdevice.cxx
index d1480588d48f..ccdf5415fb6b 100644
--- a/vcl/source/window/bufferdevice.cxx
+++ b/vcl/source/window/bufferdevice.cxx
@@ -31,6 +31,8 @@ BufferDevice::~BufferDevice()
vcl::RenderContext* BufferDevice::operator->() { return m_pBuffer.get(); }
vcl::RenderContext& BufferDevice::operator*() { return *m_pBuffer; }
+
+vcl::RenderContext& BufferDevice::GetRenderContext() { return *m_pBuffer; }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/bufferdevice.hxx b/vcl/source/window/bufferdevice.hxx
index 26bf28e615fa..75e89f92e657 100644
--- a/vcl/source/window/bufferdevice.hxx
+++ b/vcl/source/window/bufferdevice.hxx
@@ -25,6 +25,7 @@ class BufferDevice
public:
BufferDevice(const VclPtr<vcl::Window>& pWindow, vcl::RenderContext& rRenderContext);
~BufferDevice();
+ vcl::RenderContext& GetRenderContext();
vcl::RenderContext* operator->();
vcl::RenderContext& operator*();
diff --git a/vcl/source/window/menubarwindow.cxx b/vcl/source/window/menubarwindow.cxx
index 2cff7f1f52cd..ba9025a3367c 100644
--- a/vcl/source/window/menubarwindow.cxx
+++ b/vcl/source/window/menubarwindow.cxx
@@ -914,8 +914,20 @@ void MenuBarWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Recta
return;
}
- // Make sure that all actual rendering happens in one go to avoid flicker.
- vcl::BufferDevice pBuffer(this, rRenderContext);
+ vcl::RenderContext* pBuffer = nullptr;
+ std::unique_ptr<vcl::BufferDevice> pBufferDevice;
+ if (SupportsDoubleBuffering())
+ {
+ // No need to buffer twice, just set up the background.
+ pBuffer = &rRenderContext;
+ pBuffer->Erase(tools::Rectangle(Point(GetOutOffXPixel(), GetOutOffYPixel()), GetOutputSizePixel()));
+ }
+ else
+ {
+ // Make sure that all actual rendering happens in one go to avoid flicker.
+ pBufferDevice.reset(new vcl::BufferDevice(this, rRenderContext));
+ pBuffer = &pBufferDevice->GetRenderContext();
+ }
if (rRenderContext.IsNativeControlSupported(ControlType::Menubar, ControlPart::Entire))
{