diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2022-09-04 13:39:27 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2022-09-04 19:44:49 +0200 |
commit | 42d197ef301db68e56f7e45b6e36ace5fae04b4d (patch) | |
tree | 624dc9ea18f43361848e03e4cf664a0d219ad6bc | |
parent | d0d6e43f9f9894f65a18f22a28ed0d8c0dbd2b61 (diff) |
tdf#150773: Avoid bringing loading files to front several times
The change attempts to establish this logic:
1. Honor the ForceFocusAndToFront setting uniformly: previously, it
was ignored when reusing existing windows (opening in Start Center,
in place of an empty document, or trying to open an already opened
document);
2. When ForceFocusAndToFront is set, try to activate the window as
early as possible (before loading begind), as a feedback to user,
and also to avoid situations when activation would be impossible
later (e.g., there is a timespan on Windows, during which entitled
applications can bring themselves to foreground; a lengthy loading
process can exceed that time);
3. If activated once, do not activate second time after loading ends,
to avoid nagging users who deliberately switched to other tasks.
Explicit calls to impl_makeFrameWindowVisible were removed from
impl_searchAlreadyLoaded and impl_isFrameAlreadyUsedForLoading,
because those functions are called from impl_loadContent, which makes
sure that they are followed by a call to impl_makeFrameWindowVisible
(either in impl_setResult -> impl_reactForLoadingState, or directly).
A fix to tdf#83773 was adjusted; I checked that the bug doesn't
reappear after that.
Change-Id: I4bdcf978d43016d1e8979adf2fdf108a37f6ba2d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139362
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | framework/source/inc/loadenv/loadenv.hxx | 11 | ||||
-rw-r--r-- | framework/source/loadenv/loadenv.cxx | 32 | ||||
-rw-r--r-- | sd/source/ui/inc/DrawViewShell.hxx | 5 | ||||
-rw-r--r-- | sd/source/ui/view/drviews1.cxx | 19 |
4 files changed, 42 insertions, 25 deletions
diff --git a/framework/source/inc/loadenv/loadenv.hxx b/framework/source/inc/loadenv/loadenv.hxx index 351d39b94b4e..baad8fac9b7f 100644 --- a/framework/source/inc/loadenv/loadenv.hxx +++ b/framework/source/inc/loadenv/loadenv.hxx @@ -179,6 +179,12 @@ private: */ bool m_bLoaded; + /** @short If we already brought it to front; do not do that again + (the user could switch elsewhere after the first activation, + and we shouldn't nag them again). + */ + bool m_bFocusedAndToFront = false; + /** @short holds an XActionLock on the internal used task member. @seealso m_xTargetFrame @@ -533,6 +539,11 @@ private: loading the document. */ bool impl_filterHasInteractiveDialog() const; + + /** @short checks if this should bring to front and get focus on load, + according to user settings and to the load flags. + */ + bool shouldFocusAndToFront() const; }; } // namespace framework diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx index f8d0176b6276..0cd8b0b38330 100644 --- a/framework/source/loadenv/loadenv.cxx +++ b/framework/source/loadenv/loadenv.cxx @@ -1119,7 +1119,10 @@ bool LoadEnv::impl_loadContent() xHandler->initialize(aArguments); //show the frame as early as possible to make it the parent of any message dialogs if (!impl_filterHasInteractiveDialog()) - impl_makeFrameWindowVisible(xWindow, false); + { + impl_makeFrameWindowVisible(xWindow, shouldFocusAndToFront()); + m_bFocusedAndToFront = true; // no need to ask shouldFocusAndToFront second time + } } } @@ -1408,9 +1411,6 @@ css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded() // if an optional jumpmark is given too. if (!m_aURL.Mark.isEmpty()) impl_jumpToMark(xResult, m_aURL); - - // bring it to front and make sure it's visible... - impl_makeFrameWindowVisible(xResult->getContainerWindow(), true); } return xResult; @@ -1448,8 +1448,6 @@ css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget() { if (!impl_isFrameAlreadyUsedForLoading(aTasksAnalyzer.m_xBackingComponent)) { - // bring it to front... - impl_makeFrameWindowVisible(aTasksAnalyzer.m_xBackingComponent->getContainerWindow(), true); m_bReactivateControllerOnError = true; return aTasksAnalyzer.m_xBackingComponent; } @@ -1562,9 +1560,6 @@ css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget() } // <- SAFE .................................. - // bring it to front ... - impl_makeFrameWindowVisible(xTask->getContainerWindow(), true); - return xTask; } @@ -1596,7 +1591,7 @@ void LoadEnv::impl_reactForLoadingState() { // show frame ... if it's not still visible ... // But do nothing if it's already visible! - impl_makeFrameWindowVisible(xWindow, false); + impl_makeFrameWindowVisible(xWindow, !m_bFocusedAndToFront && shouldFocusAndToFront()); } // Note: Only if an existing property "FrameName" is given by this media descriptor, @@ -1683,6 +1678,14 @@ void LoadEnv::impl_reactForLoadingState() // <- SAFE ---------------------------------- } +bool LoadEnv::shouldFocusAndToFront() const +{ + bool const preview( + m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW, false)); + return !preview + && officecfg::Office::Common::View::NewDocumentHandling::ForceFocusAndToFront::get(); +} + void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow , bool bForceToFront) { @@ -1691,15 +1694,6 @@ void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::X if ( !pWindow ) return; - if (!bForceToFront) - { - bool const preview(m_lMediaDescriptor.getUnpackedValueOrDefault( - utl::MediaDescriptor::PROP_PREVIEW, false)); - bForceToFront - = !preview - && officecfg::Office::Common::View::NewDocumentHandling::ForceFocusAndToFront::get(); - } - if (pWindow->IsVisible() && bForceToFront) pWindow->ToTop( ToTopFlags::RestoreWhenMin | ToTopFlags::ForegroundTask ); else diff --git a/sd/source/ui/inc/DrawViewShell.hxx b/sd/source/ui/inc/DrawViewShell.hxx index c56a0f33e604..e75570a79638 100644 --- a/sd/source/ui/inc/DrawViewShell.hxx +++ b/sd/source/ui/inc/DrawViewShell.hxx @@ -414,6 +414,11 @@ protected: void GetMenuStateSel(SfxItemSet& rSet); private: + /** Prevents grabbing focus while loading - see tdf#83773 that intruduced + the grabbing, and tdf#150773 that needs grabbing disabled on loading + */ + bool mbFirstTimeActivation = true; + /** This flag controls whether the layer mode is active, i.e. the layer dialog is visible. */ diff --git a/sd/source/ui/view/drviews1.cxx b/sd/source/ui/view/drviews1.cxx index 9f372f67e320..64440617e611 100644 --- a/sd/source/ui/view/drviews1.cxx +++ b/sd/source/ui/view/drviews1.cxx @@ -79,13 +79,20 @@ void DrawViewShell::Activate(bool bIsMDIActivate) { ViewShell::Activate(bIsMDIActivate); - // When the mode is switched to normal the main view shell grabs focus. - // This is done for getting cut/copy/paste commands on slides in the left - // pane (slide sorter view shell) to work properly. - SfxShell* pTopViewShell = this->GetViewShellBase().GetViewShellManager()->GetTopViewShell(); - if (pTopViewShell && pTopViewShell == this) + // tdf#150773: do not grab focus on loading + if (mbFirstTimeActivation) + mbFirstTimeActivation = false; + else { - this->GetActiveWindow()->GrabFocus(); + + // When the mode is switched to normal the main view shell grabs focus. + // This is done for getting cut/copy/paste commands on slides in the left + // pane (slide sorter view shell) to work properly. + SfxShell* pTopViewShell = GetViewShellBase().GetViewShellManager()->GetTopViewShell(); + if (pTopViewShell == this) + { + GetActiveWindow()->GrabFocus(); + } } } |