framework/source/loadenv/loadenv.cxx | 8 +++++--- include/vcl/ctrl.hxx | 2 ++ include/vcl/window.hxx | 4 ++-- vcl/inc/brdwin.hxx | 2 -- vcl/source/window/brdwin.cxx | 12 ------------ vcl/source/window/stacking.cxx | 4 ++-- vcl/source/window/window.cxx | 18 ++++++++++++------ vcl/source/window/window3.cxx | 9 ++++++++- 8 files changed, 31 insertions(+), 28 deletions(-)
New commits: commit e0b930e1ddf008d202c3620fdc6652483f914835 Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Sat Apr 27 14:14:04 2024 +0200 Commit: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> CommitDate: Thu May 16 12:50:31 2024 +0200 VCL: Windows: more usecases for FlashWindow() API to inform on changes FlashWindow() can be used to bring user attention to application in background. Right now in LO it has implementation only for Windows. Here some new cases were added when flashing is used: * dialog window did open * document loaded * LO started Some redesign of previous solution is also performed: no manual search for top window, let's reuse existing code. Changed behavior for bringing LO window to foreground: it is made always and not depending on current value of NewDocumentHandling:ForceFocusAndToFront. It has no sense to tweak this behavior: if user clicks on document in file explorer, LO should came to foreground, no exceptions. Change-Id: I22b5b4e2b170cd25632083a55b3e9f0358bcae03 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166615 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx index 40b9917064ee..299b0fcd5ba4 100644 --- a/framework/source/loadenv/loadenv.cxx +++ b/framework/source/loadenv/loadenv.cxx @@ -1596,11 +1596,11 @@ void LoadEnv::impl_reactForLoadingState() css::uno::Reference< css::awt::XWindow > xWindow = m_xTargetFrame->getContainerWindow(); bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false); bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_MINIMIZED, false); + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow); if (bMinimized) { SolarMutexGuard aSolarGuard; - VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow); // check for system window is necessary to guarantee correct pointer cast! if (pWindow && pWindow->IsSystemWindow()) static_cast<WorkWindow*>(pWindow.get())->Minimize(); @@ -1612,6 +1612,9 @@ void LoadEnv::impl_reactForLoadingState() impl_makeFrameWindowVisible(xWindow, !m_bFocusedAndToFront && shouldFocusAndToFront()); } + if (pWindow) + pWindow->FlashWindow(); + // Note: Only if an existing property "FrameName" is given by this media descriptor, // it should be used. Otherwise we should do nothing. May be the outside code has already // set a frame name on the target! @@ -1700,8 +1703,7 @@ bool LoadEnv::shouldFocusAndToFront() const { bool const preview( m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW, false)); - return !preview - && officecfg::Office::Common::View::NewDocumentHandling::ForceFocusAndToFront::get(); + return !preview; } // static diff --git a/include/vcl/ctrl.hxx b/include/vcl/ctrl.hxx index 3f838aba1a70..4e61822abf7a 100644 --- a/include/vcl/ctrl.hxx +++ b/include/vcl/ctrl.hxx @@ -230,6 +230,8 @@ public: /// Notify the LOK client about an invalidated area. virtual void LogicInvalidate( const tools::Rectangle* pRectangle ) override; + + virtual void FlashWindow() const override {}; }; #endif // INCLUDED_VCL_CTRL_HXX diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx index c71c0891c572..c78c214a5b60 100644 --- a/include/vcl/window.hxx +++ b/include/vcl/window.hxx @@ -694,7 +694,7 @@ private: // retrieves the list of owner draw decorated windows for this window hierarchy SAL_DLLPRIVATE ::std::vector<VclPtr<vcl::Window> >& ImplGetOwnerDrawList(); - SAL_DLLPRIVATE vcl::Window* ImplGetTopmostFrameWindow(); + SAL_DLLPRIVATE vcl::Window* ImplGetTopmostFrameWindow() const; SAL_DLLPRIVATE bool ImplStopDnd(); SAL_DLLPRIVATE void ImplStartDnd(); @@ -1119,7 +1119,7 @@ public: /// Dumps itself and potentially its children to a property tree, to be written easily to JSON. virtual void DumpAsPropertyTree(tools::JsonWriter&); - + /// Use OS specific way to bring user attention to current window virtual void FlashWindow() const; /** @name Accessibility diff --git a/vcl/inc/brdwin.hxx b/vcl/inc/brdwin.hxx index dbaa52ed02b2..f9c8a8edb894 100644 --- a/vcl/inc/brdwin.hxx +++ b/vcl/inc/brdwin.hxx @@ -169,8 +169,6 @@ public: tools::Rectangle GetMenuRect() const; virtual Size GetOptimalSize() const override; - - virtual void FlashWindow() const override; }; struct ImplBorderFrameData diff --git a/vcl/source/window/brdwin.cxx b/vcl/source/window/brdwin.cxx index 677da2047d1b..fb7c3a1b2db4 100644 --- a/vcl/source/window/brdwin.cxx +++ b/vcl/source/window/brdwin.cxx @@ -2001,16 +2001,4 @@ void ImplBorderWindow::queue_resize(StateChangedType eReason) vcl::Window::queue_resize(eReason); } -void ImplBorderWindow::FlashWindow() const -{ - // We are showing top level window without focus received. Let's flash it - // Use OS features to bring user attention to this window: find topmost one and FlashWindow - vcl::Window* pMyParent = mpWindowImpl->mpParent; - while (pMyParent && pMyParent->mpWindowImpl && pMyParent->mpWindowImpl->mpParent) - pMyParent = pMyParent->mpWindowImpl->mpParent; - - if (pMyParent && pMyParent->mpWindowImpl) - pMyParent->mpWindowImpl->mpFrame->FlashWindow(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/stacking.cxx b/vcl/source/window/stacking.cxx index d3c73916425a..84b4efadc27b 100644 --- a/vcl/source/window/stacking.cxx +++ b/vcl/source/window/stacking.cxx @@ -47,9 +47,9 @@ struct ImplCalcToTopData namespace vcl { -vcl::Window* Window::ImplGetTopmostFrameWindow() +vcl::Window* Window::ImplGetTopmostFrameWindow() const { - vcl::Window *pTopmostParent = this; + const vcl::Window *pTopmostParent = this; while( pTopmostParent->ImplGetParent() ) pTopmostParent = pTopmostParent->ImplGetParent(); return pTopmostParent->mpWindowImpl->mpFrameWindow; diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 3cb43a8a4a05..8411888fe9ee 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -2316,14 +2316,20 @@ void Window::Show(bool bVisible, ShowFlags nFlags) // If it is a SystemWindow it automatically pops up on top of // all other windows if needed. - if ( ImplIsOverlapWindow() && !(nFlags & ShowFlags::NoActivate) ) + if (ImplIsOverlapWindow()) { - ImplStartToTop(( nFlags & ShowFlags::ForegroundTask ) ? ToTopFlags::ForegroundTask : ToTopFlags::NONE ); - ImplFocusToTop( ToTopFlags::NONE, false ); - } + if (!(nFlags & ShowFlags::NoActivate)) + { + ImplStartToTop((nFlags & ShowFlags::ForegroundTask) ? ToTopFlags::ForegroundTask + : ToTopFlags::NONE); + ImplFocusToTop(ToTopFlags::NONE, false); - if (!HasFocus() && GetParent()) { - GetParent()->FlashWindow(); + if (!(nFlags & ShowFlags::ForegroundTask)) + { + // Inform user about window if we did not popup it at foreground + FlashWindow(); + } + } } // adjust mpWindowImpl->mbReallyVisible diff --git a/vcl/source/window/window3.cxx b/vcl/source/window/window3.cxx index 44b3d4642850..002c892f592c 100644 --- a/vcl/source/window/window3.cxx +++ b/vcl/source/window/window3.cxx @@ -20,6 +20,7 @@ #include <vcl/window.hxx> #include <window.h> #include <vcl/cursor.hxx> +#include <salframe.hxx> namespace vcl { @@ -215,7 +216,13 @@ Color Window::GetBackgroundColor() const { return GetOutDev()->GetBackgroundColo void Window::EnableRTL(bool bEnable) { GetOutDev()->EnableRTL(bEnable); } -void Window::FlashWindow() const {} +void Window::FlashWindow() const +{ + vcl::Window* pMyParent = ImplGetTopmostFrameWindow(); + + if (pMyParent && pMyParent->mpWindowImpl) + pMyParent->mpWindowImpl->mpFrame->FlashWindow(); +} } /* namespace vcl */