office-gobmx/include/vcl/status.hxx
Caolán McNamara 6c32fade56 only "PaintImmediately" the statusbar itself (and optional children)
PaintImmediately normally checks to see if there are paints pending
on any of the original candidates parents, and if there are, optimizes
painting by painting from the top windows that is avaiting being
painted.

But in JunitTest_sc_unoapi_3 sometimes the ScGridWindow parent of the
StatusBar happens to have outstanding paint requests when the immediate
paint of the StatusBar is requested and there is deadlock on calling
ScGridWindow::Paint where the soffice main thread wants to lock the
SolarMutex at

> #0: 0x00000001a110e270 libsystem_kernel.dylib`__psynch_cvwait + 8
> #1: 0x00000001a114883c libsystem_pthread.dylib`_pthread_cond_wait + 1236
> #2: 0x0000000101081dd8 libc++.1.0.dylib`std::__1::condition_variable::wait at ~/llvm/build/include/c++/v1/__threading_support:337:10
> #3: 0x0000000101081dd4 libc++.1.0.dylib`std::__1::condition_variable::wait at ~/github.com/llvm/llvm-project/libcxx/src/condition_variable.cpp:46:14
> #4: 0x0000000112a011d4 libvclplug_osxlo.dylib`void std::__1::condition_variable::wait<SalYieldMutex::doAcquire(unsigned int)::$_0> at ~/llvm/inst/include/c++/v1/__mutex_base:398:9
> #5: 0x0000000112a00f98 libvclplug_osxlo.dylib`SalYieldMutex::doAcquire at vcl/osx/salinst.cxx:221:36
> #6: 0x0000000115e6b920 libvcllo.dylib`comphelper::SolarMutex::acquire at include/comphelper/solarmutex.hxx:86:5
> #7: 0x0000000116637178 libvcllo.dylib`SalInstance::AcquireYieldMutex at vcl/source/app/salvtables.cxx:149:73
> #8: 0x00000001166f0c38 libvcllo.dylib`Application::AcquireSolarMutex at vcl/source/app/svapp.cxx:594:25
> #9: 0x0000000112a07b38 libvclplug_osxlo.dylib`SolarMutexReleaser::~SolarMutexReleaser at include/vcl/svapp.hxx:1447:29
> #10: 0x0000000112a03320 libvclplug_osxlo.dylib`SolarMutexReleaser::~SolarMutexReleaser at include/vcl/svapp.hxx:1447:27
> #11: 0x0000000112a02d40 libvclplug_osxlo.dylib`AquaSalInstance::DoYield at vcl/osx/salinst.cxx:559:9
> #12: 0x00000001166f01c0 libvcllo.dylib`ImplYield at vcl/source/app/svapp.cxx:475:48
> #13: 0x00000001166efbc8 libvcllo.dylib`Application::Yield at vcl/source/app/svapp.cxx:559:5
> #14: 0x00000001166ef958 libvcllo.dylib`Application::Execute at vcl/source/app/svapp.cxx:453:13
> #15: 0x00000001017a41a8 libsofficeapp.dylib`desktop::Desktop::Main at desktop/source/app/app.cxx:1604:13

while another thread

> #0: 0x00000001a110e270 libsystem_kernel.dylib`__psynch_cvwait + 8
> #1: 0x00000001a114883c libsystem_pthread.dylib`_pthread_cond_wait + 1236
> #2: 0x00000001a20e87c8 Foundation`-[NSOperation waitUntilFinished] + 580
> #3: 0x00000001a11d8210 CoreFoundation`_CFXNotificationPost + 812
> #4: 0x00000001a209dc98 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 96
> #5: 0x00000001a3d6de0c AppKit`-[NSMenu insertItem:atIndex:] + 624
> #6: 0x00000001a3f92784 AppKit`-[NSApplication(NSServicesMenuPrivate) _fillSpellCheckerPopupButton:] + 1888
> #7: 0x00000001a3f91bf0 AppKit`-[NSSpellChecker _fillSpellCheckerPopupButton:] + 84
> #8: 0x00000001a3f90ae8 AppKit`-[NSSpellChecker init] + 284
> #9: 0x00000001a3f909bc AppKit`__36+[NSSpellChecker sharedSpellChecker]_block_invoke + 20
> #10: 0x00000001a0f841b4 libdispatch.dylib`_dispatch_client_callout + 20
> #11: 0x00000001a0f85a34 libdispatch.dylib`_dispatch_once_callout + 32
> #12: 0x00000001a3f909a4 AppKit`+[NSSpellChecker sharedSpellChecker] + 140
> #13: 0x000000028e51d364 libMacOSXSpelllo.dylib`MacSpellChecker::getLocales at lingucomponent/source/spellcheck/macosxspell/macspellimp.mm:117:42
> #14: 0x00000001120a99d8 liblnglo.dylib`LngSvcMgr::GetAvailableSpellSvcs_Impl at linguistic/source/lngsvcmgr.cxx:963:67
> #15: 0x00000001120ad1dc liblnglo.dylib`LngSvcMgr::getAvailableServices at linguistic/source/lngsvcmgr.cxx:1381:9
> #16: 0x00000001120ada4c liblnglo.dylib`LngSvcMgr::getAvailableLocales at linguistic/source/lngsvcmgr.cxx:1445:42
> #17: 0x00000001120a1d28 liblnglo.dylib`LngSvcMgr::UpdateAll at linguistic/source/lngsvcmgr.cxx:657:49
> #18: 0x00000001120a0fec liblnglo.dylib`LngSvcMgr::LngSvcMgr at linguistic/source/lngsvcmgr.cxx:414:5
> #19: 0x00000001120a2c50 liblnglo.dylib`LngSvcMgr::LngSvcMgr at linguistic/source/lngsvcmgr.cxx:402:1
> #20: 0x00000001120b1248 liblnglo.dylib`::linguistic_LngSvcMgr_get_implementation at linguistic/source/lngsvcmgr.cxx:1826:30
[...]
> #30: 0x000000010449a164 libeditenglo.dylib`com::sun::linguistic2::LinguServiceManager::create at workdir/UnoApiHeadersTarget/offapi/normal/com/sun/star/linguistic2/LinguServiceManager.hpp:38:129
> #31: 0x00000001044973d4 libeditenglo.dylib`GetLngSvcMgr_Impl at editeng/source/misc/unolingu.cxx:60:52
> #32: 0x000000010449bbb0 libeditenglo.dylib`(anonymous namespace)::SpellDummy_Impl::GetSpell_Impl at editeng/source/misc/unolingu.cxx:216:61
> #33: 0x000000010449b548 libeditenglo.dylib`(anonymous namespace)::SpellDummy_Impl::isValid at editeng/source/misc/unolingu.cxx:248:5
> #34: 0x000000010439f2a0 libeditenglo.dylib`ImpEditEngine::DoOnlineSpelling at editeng/source/editeng/impedit4.cxx:2268:37
> #35: 0x00000001042a3a14 libeditenglo.dylib`EditEngine::CompleteOnlineSpelling at editeng/source/editeng/editeng.cxx:2394:25
> #36: 0x000000028fb26974 libsclo.dylib`sc::SpellCheckContext::ensureResults at sc/source/ui/view/spellcheckcontext.cxx:339:15
> #37: 0x000000028fb2648c libsclo.dylib`sc::SpellCheckContext::isMisspelled const at sc/source/ui/view/spellcheckcontext.cxx:219:43
> #38: 0x000000028fabd63c libsclo.dylib`ScOutputData::LayoutStrings at sc/source/ui/view/output2.cxx:1640:61
> #39: 0x000000028fabc79c libsclo.dylib`ScOutputData::DrawStrings at sc/source/ui/view/output2.cxx:1471:5
> #40: 0x000000028fa788e4 libsclo.dylib`ScGridWindow::DrawContent at sc/source/ui/view/gridwin4.cxx:914:21
[...]
> #59: 0x0000000115d6a9c0 libvcllo.dylib`vcl::Window::ImplCallPaint at vcl/source/window/paint.cxx:623:1
> #60: 0x0000000115d6cc78 libvcllo.dylib`vcl::Window::PaintImmediately at vcl/source/window/paint.cxx:1335:24
> #61: 0x0000000115f47d7c libvcllo.dylib`StatusBar::StartProgressMode at vcl/source/window/status.cxx:1327:9
> #62: 0x00000001066ff8c4 libfwklo.dylib`framework::ProgressBarWrapper::start at framework/source/uielement/progressbarwrapper.cxx:111:21
> #63: 0x000000010671edfc libfwklo.dylib`framework::StatusIndicatorInterfaceWrapper::start at framework/source/uielement/statusindicatorinterfacewrapper.cxx:50:27
> #64: 0x00000001099ae138 libsfxlo.dylib`SfxProgress::SetState at sfx2/source/bastyp/progress.cxx:230:32
> #65: 0x000000028e94e558 libsclo.dylib`ScProgress::SetState at sc/inc/progress.hxx:85:52
> #66: 0x000000028ec7f954 libsclo.dylib`ScTable::Sort at sc/source/core/data/table3.cxx:1817:28
> #67: 0x000000028e931380 libsclo.dylib`ScDocument::Sort at sc/source/core/data/documen3.cxx:1450:23
> #68: 0x000000028f43ad90 libsclo.dylib`ScDBDocFunc::Sort at sc/source/ui/docshell/dbdocfun.cxx:611:14
> #69: 0x000000028f798e18 libsclo.dylib`ScCellRangeObj::sort at sc/source/ui/unoobj/cellsuno.cxx:5317:17
> #70: 0x0000000106268964 libgcc3_uno.dylib`callVirtualFunction at bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx:38:5
[...]
> #73: 0x000000012252f650 libbinaryurplo.dylib`binaryurp::IncomingRequest::execute_throw const at binaryurp/source/incomingrequest.cxx:236:13

Change-Id: Iecfbc7673a2c67851aede3f7ca8be24ee75d1b21
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139713
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
2022-09-16 18:30:59 +02:00

195 lines
8 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef INCLUDED_VCL_STATUS_HXX
#define INCLUDED_VCL_STATUS_HXX
#include <tools/solar.h>
#include <vcl/dllapi.h>
#include <vcl/window.hxx>
#include <o3tl/typed_flags_set.hxx>
#include <memory>
#include <vector>
class DataChangedEvent;
class HelpEvent;
class MouseEvent;
class UserDrawEvent;
struct ImplStatusItem;
void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, const Point& rPos,
tools::Long nOffset, tools::Long nPrgsWidth, tools::Long nPrgsHeight,
sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount,
const tools::Rectangle& rFramePosSize);
enum class StatusBarItemBits {
NONE = 0x0000,
Left = 0x0001,
Center = 0x0002,
Right = 0x0004,
In = 0x0008,
Out = 0x0010,
Flat = 0x0020,
AutoSize = 0x0040,
UserDraw = 0x0080,
Mandatory = 0x0100,
};
namespace o3tl
{
template<> struct typed_flags<StatusBarItemBits> : is_typed_flags<StatusBarItemBits, 0x01ff> {};
}
#define STATUSBAR_APPEND (sal_uInt16(0xFFFF))
#define STATUSBAR_ITEM_NOTFOUND (sal_uInt16(0xFFFF))
#define STATUSBAR_OFFSET (tools::Long(5))
class VCL_DLLPUBLIC StatusBar : public vcl::Window
{
class SAL_DLLPRIVATE ImplData;
private:
std::vector<std::unique_ptr<ImplStatusItem>> mvItemList;
std::unique_ptr<ImplData> mpImplData;
OUString maPrgsTxt;
Point maPrgsTxtPos;
tools::Rectangle maPrgsFrameRect;
tools::Long mnPrgsSize;
tools::Long mnItemsWidth;
tools::Long mnDX;
tools::Long mnDY;
tools::Long mnCalcHeight;
tools::Long mnTextY;
sal_uInt16 mnCurItemId;
sal_uInt16 mnPercent;
sal_uInt16 mnPercentCount;
sal_uInt32 mnLastProgressPaint_ms;
bool mbFormat;
bool mbProgressMode;
bool mbInUserDraw;
bool mbAdjustHiDPI;
Link<StatusBar*,void> maClickHdl;
Link<StatusBar*,void> maDoubleClickHdl;
using Window::ImplInit;
SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle );
SAL_DLLPRIVATE void ImplInitSettings();
SAL_DLLPRIVATE void ImplFormat();
SAL_DLLPRIVATE bool ImplIsItemUpdate() const;
SAL_DLLPRIVATE void ImplDrawText(vcl::RenderContext& rRenderContext);
SAL_DLLPRIVATE void ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen,
sal_uInt16 nPos);
SAL_DLLPRIVATE void ImplDrawProgress(vcl::RenderContext& rRenderContext, sal_uInt16 nNewPerc);
SAL_DLLPRIVATE void ImplCalcProgressRect();
SAL_DLLPRIVATE tools::Rectangle ImplGetItemRectPos( sal_uInt16 nPos ) const;
SAL_DLLPRIVATE sal_uInt16 ImplGetFirstVisiblePos() const;
SAL_DLLPRIVATE void PaintSelfAndChildrenImmediately();
protected:
virtual void ApplySettings(vcl::RenderContext& rRenderContext) override;
public:
StatusBar( vcl::Window* pParent,
WinBits nWinStyle = WB_BORDER | WB_RIGHT );
virtual ~StatusBar() override;
virtual void dispose() override;
void AdjustItemWidthsForHiDPI();
virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
virtual void Resize() override;
virtual void RequestHelp( const HelpEvent& rHEvt ) override;
virtual void StateChanged( StateChangedType nType ) override;
virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
void Click();
void DoubleClick();
virtual void UserDraw( const UserDrawEvent& rUDEvt );
void InsertItem( sal_uInt16 nItemId, sal_uLong nWidth,
StatusBarItemBits nBits = StatusBarItemBits::Center | StatusBarItemBits::In,
tools::Long nOffset = STATUSBAR_OFFSET,
sal_uInt16 nPos = STATUSBAR_APPEND );
void RemoveItem( sal_uInt16 nItemId );
void ShowItem( sal_uInt16 nItemId );
void HideItem( sal_uInt16 nItemId );
bool IsItemVisible( sal_uInt16 nItemId ) const;
void RedrawItem( sal_uInt16 nItemId );
void Clear();
sal_uInt16 GetItemCount() const;
sal_uInt16 GetItemId( sal_uInt16 nPos ) const;
sal_uInt16 GetItemId( const Point& rPos ) const;
sal_uInt16 GetItemPos( sal_uInt16 nItemId ) const;
tools::Rectangle GetItemRect( sal_uInt16 nItemId ) const;
Point GetItemTextPos( sal_uInt16 nItemId ) const;
sal_uInt16 GetCurItemId() const { return mnCurItemId; }
sal_uLong GetItemWidth( sal_uInt16 nItemId ) const;
StatusBarItemBits GetItemBits( sal_uInt16 nItemId ) const;
tools::Long GetItemOffset( sal_uInt16 nItemId ) const;
/// @param nCharsWidth, if not -1, overrides the normal width calculation
void SetItemText( sal_uInt16 nItemId, const OUString& rText, int nCharsWidth = -1 );
const OUString& GetItemText( sal_uInt16 nItemId ) const;
void SetItemData( sal_uInt16 nItemId, void* pNewData );
void* GetItemData( sal_uInt16 nItemId ) const;
void SetItemCommand( sal_uInt16 nItemId, const OUString& rCommand );
OUString GetItemCommand( sal_uInt16 nItemId );
void SetHelpText( sal_uInt16 nItemId, const OUString& rText );
const OUString& GetHelpText( sal_uInt16 nItemId ) const;
using Window::SetQuickHelpText;
void SetQuickHelpText( sal_uInt16 nItemId, const OUString& rText );
using Window::GetQuickHelpText;
const OUString& GetQuickHelpText( sal_uInt16 nItemId ) const;
void SetHelpId( sal_uInt16 nItemId, const OString& rHelpId );
void StartProgressMode( const OUString& rText );
void SetProgressValue( sal_uInt16 nPercent );
void EndProgressMode();
bool IsProgressMode() const { return mbProgressMode; }
void SetText( const OUString& rText ) override;
Size CalcWindowSizePixel() const;
void SetClickHdl( const Link<StatusBar*,void>& rLink ) { maClickHdl = rLink; }
void SetDoubleClickHdl( const Link<StatusBar*,void>& rLink ) { maDoubleClickHdl = rLink; }
using Window::SetAccessibleName;
void SetAccessibleName( sal_uInt16 nItemId, const OUString& rName );
using Window::GetAccessibleName;
const OUString& GetAccessibleName( sal_uInt16 nItemId ) const;
};
#endif // INCLUDED_VCL_STATUS_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */