Commit 900b50bc authored by Xiyuan Xia's avatar Xiyuan Xia Committed by Commit Bot

SPM: Fix VK not working after launching xls results

- Update DesktopFocusRules so that only toplevel window is allowed
  to be activated in minimized state. Otherwise, a child window could
  be activated and cause DesktopNativeWidgetAura not getting
  activation change which in turn causes more problems down the road.
- Fix DesktopNativeWidgetAura so that RestoreFocusedView happens
  for a minimized widget

Bug: 942787
Change-Id: I0e3d35f342fca16cc78e451d6bf7fe32ac2dc337
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1536554
Commit-Queue: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#644565}
parent a58562ff
......@@ -45,6 +45,7 @@
#include "ui/views/widget/widget_observer.h"
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/transient_window_manager.h"
#include "ui/wm/public/activation_client.h"
namespace views {
......@@ -1171,4 +1172,39 @@ TEST_F(DesktopWindowTreeHostMusTest, ServerBoundsChangeIngoresMinMax) {
EXPECT_EQ(server_bounds, widget->GetWindowBoundsInScreen());
}
// Verify that focusing a child window makes the toplevel window active.
TEST_F(DesktopWindowTreeHostMusTest, DontActivateNonToplevelWindow) {
std::unique_ptr<Widget> toplevel(CreateWidget());
toplevel->Show();
aura::Window* child = new aura::Window(nullptr);
child->Init(ui::LAYER_SOLID_COLOR);
toplevel->GetNativeView()->AddChild(child);
ASSERT_TRUE(child->CanFocus());
wm::ActivationClient* activation_client =
wm::GetActivationClient(toplevel->GetNativeView()->GetRootWindow());
// Focus |child| in normal state. |toplevel| is the active window and |child|
// is focused.
child->Focus();
EXPECT_EQ(toplevel->GetNativeView(), activation_client->GetActiveWindow());
EXPECT_TRUE(toplevel->IsActive());
EXPECT_TRUE(child->HasFocus());
// Minimize |toplevel|.
toplevel->Minimize();
ASSERT_TRUE(toplevel->IsMinimized());
EXPECT_EQ(nullptr, activation_client->GetActiveWindow());
EXPECT_FALSE(toplevel->IsActive());
EXPECT_FALSE(child->HasFocus());
// Focus |child| again. |toplevel| is the active window and |child| is
// focused.
child->Focus();
EXPECT_EQ(toplevel->GetNativeView(), activation_client->GetActiveWindow());
EXPECT_TRUE(toplevel->IsActive());
EXPECT_TRUE(child->HasFocus());
}
} // namespace views
......@@ -17,7 +17,8 @@ DesktopFocusRules::DesktopFocusRules(aura::Window* content_window)
DesktopFocusRules::~DesktopFocusRules() = default;
bool DesktopFocusRules::CanActivateWindow(const aura::Window* window) const {
if (window && content_window_->GetRootWindow()->Contains(window) &&
if (window && IsToplevelWindow(window) &&
content_window_->GetRootWindow()->Contains(window) &&
wm::WindowStateIs(window->GetRootWindow(), ui::SHOW_STATE_MINIMIZED)) {
return true;
}
......@@ -44,7 +45,7 @@ bool DesktopFocusRules::SupportsChildActivation(
bool DesktopFocusRules::IsWindowConsideredVisibleForActivation(
const aura::Window* window) const {
// |content_window_| is initially hidden and made visible from Show(). Even in
// this state we still want it to be active.
// this state we still want it to be activatable.
return BaseFocusRules::IsWindowConsideredVisibleForActivation(window) ||
(window == content_window_);
}
......
......@@ -6,6 +6,7 @@
#include <memory>
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/macros.h"
#include "base/trace_event/trace_event.h"
......@@ -419,6 +420,7 @@ void DesktopNativeWidgetAura::HandleActivationChanged(bool active) {
// only aura activation changes).
aura::Window* active_window = activation_client->GetActiveWindow();
if (active_window) {
base::AutoReset<bool> scoped(&is_handling_deactivation_, true);
activation_client->DeactivateWindow(active_window);
GetInputMethod()->OnBlur();
}
......@@ -1147,10 +1149,11 @@ void DesktopNativeWidgetAura::OnWindowActivated(
DCHECK(content_window_ == gained_active || content_window_ == lost_active);
if (gained_active == content_window_ && restore_focus_on_activate_) {
restore_focus_on_activate_ = false;
// For OS_LINUX, desktop native widget may not be activated when child
// widgets gets aura activation changes. Only when desktop native widget is
// active, we can rely on aura activation to restore focused view.
if (GetWidget()->IsActive())
// For OS_LINUX, desktop native widget may be activated during deactivation
// when the active aura::Window is not |content_window_|. In such case,
// skip RestoreFocusedView so that we don't activate the widget immediately
// after its deactivation.
if (!is_handling_deactivation_)
GetWidget()->GetFocusManager()->RestoreFocusedView();
} else if (lost_active == content_window_ && GetWidget()->HasFocusManager()) {
DCHECK(!restore_focus_on_activate_);
......
......@@ -319,6 +319,16 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
// See DesktopWindowTreeHost::ShouldUseDesktopNativeCursorManager().
bool use_desktop_native_cursor_manager_ = false;
// Whether HandleActivationChanged is being called for deactivation. The
// current active aura::Window is deactivated in HandleActivationChanged.
// However, the current active window could be a sibling of |content_window_|
// (e.g. aura::Window of a child bubble widget such as browser window
// bubbles). The deactivation of such window would activate |content_window_|
// and could trigger RestoreFocusedView which could activate the widget. The
// flag is used to skip RestoreFocusedView to avoid activating the widget
// immediately after it is deactivated.
bool is_handling_deactivation_ = false;
// The following factory is used for calls to close the NativeWidgetAura
// instance.
base::WeakPtrFactory<DesktopNativeWidgetAura> close_widget_factory_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment