vcl: support for Windows ITaskbarList3 interface

And a demo implementation for these features as a taskbar window
will become red once LO is displaying any error message.

Change-Id: Ifc04026c699059da2e457de2c69e7363e756109c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166740
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
This commit is contained in:
Vasily Melenchuk
2024-07-17 21:05:15 +02:00
committed by Thorsten Behrens
parent a7327e95ce
commit 0c6642ed3a
7 changed files with 97 additions and 0 deletions
+14
View File
@@ -196,6 +196,20 @@ enum class VclPackType
LAST = End
};
enum class VclTaskBarStates {
// Default, no specifics
Normal,
// Display some progress defined by SetTaskBarProgress
Progress,
// Something going on, but no exact progress scale
ProgressUnknown,
// Process on pause
Paused,
// Some error did happen
Error
};
// Return Values from Dialog::Execute
//!!! in case of changes adjust /basic/source/runtime/methods.cxx msgbox
+3
View File
@@ -1122,6 +1122,9 @@ public:
/// Use OS specific way to bring user attention to current window
virtual void FlashWindow() const;
virtual void SetTaskBarProgress(int nCurrentProgress);
virtual void SetTaskBarState(VclTaskBarStates eTaskBarState);
/** @name Accessibility
*/
///@{
+3
View File
@@ -316,6 +316,9 @@ public:
// in nOffset, nChars.
static Selection CalcDeleteSurroundingSelection(std::u16string_view rSurroundingText,
sal_Int32 nCursorIndex, int nOffset, int nChars);
virtual void SetTaskBarProgress(int /*nCurrentProgress*/) {}
virtual void SetTaskBarState(VclTaskBarStates /*eTaskBarState*/) {}
};
#ifdef _WIN32
+5
View File
@@ -29,10 +29,12 @@
#include <svsys.h>
class WinSalGraphics;
struct ITaskbarList3;
class WinSalFrame final: public SalFrame
{
vcl::WindowState m_eState;
ITaskbarList3* m_pTaskbarList3;
public:
HWND mhWnd; // Window handle
@@ -146,6 +148,9 @@ public:
constexpr vcl::WindowState state() const { return m_eState; }
void UpdateFrameState();
constexpr bool isFullScreen() const { return bool(m_eState & vcl::WindowState::FullScreen); }
virtual void SetTaskBarProgress(int nCurrentProgress) override;
virtual void SetTaskBarState(VclTaskBarStates eTaskBarState) override;
};
void ImplSalGetWorkArea( HWND hWnd, RECT *pRect, const RECT *pParentRect );
+3
View File
@@ -2563,6 +2563,7 @@ MessageDialog::MessageDialog(vcl::Window* pParent,
break;
case VclMessageType::Error:
SetText(GetStandardErrorBoxText());
SetTaskBarState(VclTaskBarStates::Error);
break;
case VclMessageType::Other:
SetText(Application::GetDisplayName());
@@ -2572,6 +2573,8 @@ MessageDialog::MessageDialog(vcl::Window* pParent,
void MessageDialog::dispose()
{
SetTaskBarState(VclTaskBarStates::Normal);
disposeOwnedButtons();
m_pPrimaryMessage.disposeAndClear();
m_pSecondaryMessage.disposeAndClear();
+16
View File
@@ -224,6 +224,22 @@ void Window::FlashWindow() const
pMyParent->mpWindowImpl->mpFrame->FlashWindow();
}
void Window::SetTaskBarProgress(int nCurrentProgress)
{
vcl::Window* pMyParent = ImplGetTopmostFrameWindow();
if (pMyParent && pMyParent->mpWindowImpl)
pMyParent->mpWindowImpl->mpFrame->SetTaskBarProgress(nCurrentProgress);
}
void Window::SetTaskBarState(VclTaskBarStates eTaskBarState)
{
vcl::Window* pMyParent = ImplGetTopmostFrameWindow();
if (pMyParent && pMyParent->mpWindowImpl)
pMyParent->mpWindowImpl->mpFrame->SetTaskBarState(eTaskBarState);
}
} /* namespace vcl */
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+53
View File
@@ -903,6 +903,7 @@ WinSalFrame::WinSalFrame()
mpNextClipRect = nullptr;
mnDisplay = 0;
mbPropertiesStored = false;
m_pTaskbarList3 = nullptr;
// get data, when making 1st frame
if ( !pSalData->mpFirstFrame )
@@ -985,6 +986,11 @@ WinSalFrame::~WinSalFrame()
mpLocalGraphics = nullptr;
}
if ( m_pTaskbarList3 )
{
m_pTaskbarList3->Release();
}
if ( mhWnd )
{
// reset mouse leave data
@@ -3159,6 +3165,53 @@ bool WinSalFrame::GetUseReducedAnimation() const
return !bEnableAnimation;
}
void WinSalFrame::SetTaskBarProgress(int nCurrentProgress)
{
if (!m_pTaskbarList3)
{
HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&m_pTaskbarList3);
if (!SUCCEEDED(hr) || !m_pTaskbarList3)
return;
}
m_pTaskbarList3->SetProgressValue(mhWnd, nCurrentProgress, 100);
}
void WinSalFrame::SetTaskBarState(VclTaskBarStates eTaskBarState)
{
if (!m_pTaskbarList3)
{
HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&m_pTaskbarList3);
if (!SUCCEEDED(hr) || !m_pTaskbarList3)
return;
}
TBPFLAG nFlag;
switch (eTaskBarState)
{
case VclTaskBarStates::Progress:
nFlag = TBPF_NORMAL;
break;
case VclTaskBarStates::ProgressUnknown:
nFlag = TBPF_INDETERMINATE;
break;
case VclTaskBarStates::Paused:
nFlag = TBPF_PAUSED;
SetTaskBarProgress(100);
break;
case VclTaskBarStates::Error:
nFlag = TBPF_ERROR;
SetTaskBarProgress(100);
break;
case VclTaskBarStates::Normal:
default:
nFlag = TBPF_NOPROGRESS;
break;
}
m_pTaskbarList3->SetProgressState(mhWnd, nFlag);
}
static bool ImplHandleMouseMsg( HWND hWnd, UINT nMsg,
WPARAM wParam, LPARAM lParam )
{