summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2022-09-04 13:39:27 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2022-09-04 19:44:49 +0200
commit42d197ef301db68e56f7e45b6e36ace5fae04b4d (patch)
tree624dc9ea18f43361848e03e4cf664a0d219ad6bc
parentd0d6e43f9f9894f65a18f22a28ed0d8c0dbd2b61 (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.hxx11
-rw-r--r--framework/source/loadenv/loadenv.cxx32
-rw-r--r--sd/source/ui/inc/DrawViewShell.hxx5
-rw-r--r--sd/source/ui/view/drviews1.cxx19
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();
+ }
}
}