summaryrefslogtreecommitdiff
path: root/chromium/ui/views/widget
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-16 11:45:35 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-17 08:59:23 +0000
commit552906b0f222c5d5dd11b9fd73829d510980461a (patch)
tree3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/ui/views/widget
parent1b05827804eaf047779b597718c03e7d38344261 (diff)
downloadqtwebengine-chromium-552906b0f222c5d5dd11b9fd73829d510980461a.tar.gz
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/ui/views/widget')
-rw-r--r--chromium/ui/views/widget/any_widget_observer.cc70
-rw-r--r--chromium/ui/views/widget/any_widget_observer.h203
-rw-r--r--chromium/ui/views/widget/any_widget_observer_singleton.cc44
-rw-r--r--chromium/ui/views/widget/any_widget_observer_singleton.h48
-rw-r--r--chromium/ui/views/widget/any_widget_observer_unittest.cc122
-rw-r--r--chromium/ui/views/widget/ax_native_widget_mac_unittest.mm1
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_capture_client.cc3
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc1193
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h200
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc52
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc4
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc5
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.h4
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_focus_rules.cc2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc5
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h6
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc74
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h29
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc60
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.cc10
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.h4
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_win.h2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc121
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h43
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc1
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h1
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc37
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h24
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux_interactive_uitest.cc16
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h29
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc81
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h4
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_unittest.cc4
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc41
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h6
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc32
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h16
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc24
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc19
-rw-r--r--chromium/ui/views/widget/desktop_aura/window_event_filter_linux.cc2
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc141
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_desktop_handler.h90
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_desktop_handler_observer.h26
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc2
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder.h7
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc50
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc69
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h6
-rw-r--r--chromium/ui/views/widget/desktop_widget_unittest.cc9
-rw-r--r--chromium/ui/views/widget/drop_helper.cc28
-rw-r--r--chromium/ui/views/widget/native_widget_aura.cc51
-rw-r--r--chromium/ui/views/widget/native_widget_aura.h19
-rw-r--r--chromium/ui/views/widget/native_widget_aura_unittest.cc169
-rw-r--r--chromium/ui/views/widget/native_widget_delegate.h4
-rw-r--r--chromium/ui/views/widget/native_widget_mac.h41
-rw-r--r--chromium/ui/views/widget/native_widget_mac.mm241
-rw-r--r--chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm26
-rw-r--r--chromium/ui/views/widget/native_widget_mac_unittest.mm155
-rw-r--r--chromium/ui/views/widget/native_widget_private.h12
-rw-r--r--chromium/ui/views/widget/native_widget_unittest.cc7
-rw-r--r--chromium/ui/views/widget/root_view.cc99
-rw-r--r--chromium/ui/views/widget/root_view.h38
-rw-r--r--chromium/ui/views/widget/root_view_targeter.cc3
-rw-r--r--chromium/ui/views/widget/root_view_unittest.cc203
-rw-r--r--chromium/ui/views/widget/tooltip_manager_aura.cc2
-rw-r--r--chromium/ui/views/widget/widget.cc144
-rw-r--r--chromium/ui/views/widget/widget.h91
-rw-r--r--chromium/ui/views/widget/widget_delegate.cc12
-rw-r--r--chromium/ui/views/widget/widget_delegate.h27
-rw-r--r--chromium/ui/views/widget/widget_interactive_uitest.cc77
-rw-r--r--chromium/ui/views/widget/widget_observer.h5
-rw-r--r--chromium/ui/views/widget/widget_unittest.cc741
-rw-r--r--chromium/ui/views/widget/window_reorderer.cc12
-rw-r--r--chromium/ui/views/widget/window_reorderer_unittest.cc88
77 files changed, 2276 insertions, 3067 deletions
diff --git a/chromium/ui/views/widget/any_widget_observer.cc b/chromium/ui/views/widget/any_widget_observer.cc
new file mode 100644
index 00000000000..b0b1860cad2
--- /dev/null
+++ b/chromium/ui/views/widget/any_widget_observer.cc
@@ -0,0 +1,70 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/widget/any_widget_observer.h"
+#include "base/bind.h"
+#include "ui/views/widget/any_widget_observer_singleton.h"
+#include "ui/views/widget/widget.h"
+
+namespace views {
+
+AnyWidgetObserver::AnyWidgetObserver(AnyWidgetPasskey passkey)
+ : AnyWidgetObserver() {}
+AnyWidgetObserver::AnyWidgetObserver(test::AnyWidgetTestPasskey passkey)
+ : AnyWidgetObserver() {}
+
+AnyWidgetObserver::AnyWidgetObserver() {
+ internal::AnyWidgetObserverSingleton::GetInstance()->AddObserver(this);
+}
+
+AnyWidgetObserver::~AnyWidgetObserver() {
+ internal::AnyWidgetObserverSingleton::GetInstance()->RemoveObserver(this);
+}
+
+#define PROPAGATE_NOTIFICATION(method, callback) \
+ void AnyWidgetObserver::method(Widget* widget) { \
+ if (callback) \
+ callback.Run(widget); \
+ }
+
+PROPAGATE_NOTIFICATION(OnAnyWidgetInitialized, initialized_callback_)
+PROPAGATE_NOTIFICATION(OnAnyWidgetShown, shown_callback_)
+PROPAGATE_NOTIFICATION(OnAnyWidgetHidden, hidden_callback_)
+PROPAGATE_NOTIFICATION(OnAnyWidgetClosing, closing_callback_)
+
+#undef PROPAGATE_NOTIFICATION
+
+NamedWidgetShownWaiter::NamedWidgetShownWaiter(AnyWidgetPasskey passkey,
+ const std::string& name)
+ : NamedWidgetShownWaiter(name) {}
+
+NamedWidgetShownWaiter::NamedWidgetShownWaiter(
+ test::AnyWidgetTestPasskey passkey,
+ const std::string& name)
+ : NamedWidgetShownWaiter(name) {}
+
+NamedWidgetShownWaiter::~NamedWidgetShownWaiter() = default;
+
+Widget* NamedWidgetShownWaiter::WaitIfNeededAndGet() {
+ run_loop_.Run();
+ DCHECK(widget_);
+ return widget_;
+}
+
+NamedWidgetShownWaiter::NamedWidgetShownWaiter(const std::string& name)
+ : observer_(views::AnyWidgetPasskey{}), name_(name) {
+ observer_.set_shown_callback(base::BindRepeating(
+ &NamedWidgetShownWaiter::OnAnyWidgetShown, base::Unretained(this)));
+}
+
+void NamedWidgetShownWaiter::OnAnyWidgetShown(Widget* widget) {
+ if (widget->GetName() == name_) {
+ widget_ = widget;
+ run_loop_.Quit();
+ }
+}
+
+AnyWidgetPasskey::AnyWidgetPasskey() = default;
+
+} // namespace views
diff --git a/chromium/ui/views/widget/any_widget_observer.h b/chromium/ui/views/widget/any_widget_observer.h
new file mode 100644
index 00000000000..be43ee03d38
--- /dev/null
+++ b/chromium/ui/views/widget/any_widget_observer.h
@@ -0,0 +1,203 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_WIDGET_ANY_WIDGET_OBSERVER_H_
+#define UI_VIEWS_WIDGET_ANY_WIDGET_OBSERVER_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/observer_list_types.h"
+#include "base/run_loop.h"
+#include "ui/views/views_export.h"
+
+namespace views {
+
+namespace internal {
+class AnyWidgetObserverSingleton;
+}
+
+namespace test {
+class AnyWidgetTestPasskey;
+}
+
+class AnyWidgetPasskey;
+class Widget;
+
+// AnyWidgetObserver is used when you want to observe widget changes but don't
+// have an easy way to get a reference to the Widget in question, usually
+// because it is created behind a layer of abstraction that hides the Widget.
+//
+// This class should only be used as a last resort - if you find yourself
+// reaching for it in production code, it probably means some parts of your
+// system aren't coupled enough or your API boundaries are hiding too much. You
+// will need review from an owner of this class to add new uses of it, because
+// it requires a Passkey to construct it - see //docs/patterns/passkey.md for
+// details. Uses in tests can be done freely using
+// views::test::AnyWidgetTestPasskey.
+//
+// This class is useful when doing something like this:
+//
+// RunLoop run_loop;
+// AnyWidgetCallbackObserver observer(views::test::AnyWidgetTestPasskey{});
+// Widget* widget;
+// observer.set_initialized_callback(
+// base::BindLambdaForTesting([&](Widget* w) {
+// if (w->GetName() == "MyWidget") {
+// widget = w;
+// run_loop.Quit();
+// }
+// }));
+// ThingThatCreatesWidget();
+// run_loop.Run();
+//
+// with your widget getting the name "MyWidget" via InitParams::name.
+//
+// Note: if you're trying to wait for a named widget to be *shown*, there is an
+// ergonomic wrapper for that - see NamedWidgetShownWaiter below. You use it
+// like this:
+//
+// NamedWidgetShownWaiter waiter(
+// "MyWidget", views::test::AnyWidgetTestPasskey{});
+// ThingThatCreatesAndShowsWidget();
+// Widget* widget = waiter.WaitIfNeededAndGet();
+//
+// TODO(ellyjones): Add Widget::SetDebugName and add a remark about that here.
+//
+// This allows you to create a test that is robust even if
+// ThingThatCreatesAndShowsWidget() later becomes asynchronous, takes a few
+// milliseconds, etc.
+class VIEWS_EXPORT AnyWidgetObserver : public base::CheckedObserver {
+ public:
+ using AnyWidgetCallback = base::RepeatingCallback<void(Widget*)>;
+
+ // Using this in production requires an AnyWidgetPasskey, which can only be
+ // constructed by a list of allowed friend classes...
+ explicit AnyWidgetObserver(AnyWidgetPasskey passkey);
+
+ // ... but for tests or debugging, anyone can construct a
+ // views::test::AnyWidgetTestPasskey.
+ explicit AnyWidgetObserver(test::AnyWidgetTestPasskey passkey);
+
+ ~AnyWidgetObserver() override;
+
+ AnyWidgetObserver(const AnyWidgetObserver& other) = delete;
+ AnyWidgetObserver& operator=(const AnyWidgetObserver& other) = delete;
+
+ // This sets the callback for when the Widget has finished initialization and
+ // is ready to use. This is the first point at which the widget is useable.
+ void set_initialized_callback(const AnyWidgetCallback& callback) {
+ initialized_callback_ = callback;
+ }
+
+ // These set the callbacks for when the backing native widget has just been
+ // asked to change visibility. Note that the native widget may or may not
+ // actually be drawn on the screen when these callbacks are run, because there
+ // are more layers of asynchronousness at the OS layer.
+ void set_shown_callback(const AnyWidgetCallback& callback) {
+ // Check out NamedWidgetShownWaiter for an alternative to this method.
+ shown_callback_ = callback;
+ }
+ void set_hidden_callback(const AnyWidgetCallback& callback) {
+ hidden_callback_ = callback;
+ }
+
+ // This sets the callback for when the Widget has decided that it is about to
+ // close, but not yet begun to tear down the backing native Widget or the
+ // RootView. This is the last point at which the Widget is in a consistent,
+ // useable state.
+ void set_closing_callback(const AnyWidgetCallback& callback) {
+ closing_callback_ = callback;
+ }
+
+ // These two methods deliberately don't exist:
+ // void set_created_callback(...)
+ // void set_destroyed_callback(...)
+ // They would be called respectively too early and too late in the Widget's
+ // lifecycle for it to be usefully identified - at construction time the
+ // Widget has no properties or contents yet (and therefore can't be
+ // meaningfully identified as "your widget" for test purposes), and at
+ // destruction time the Widget's state is already partly destroyed by the
+ // closure process. Both methods are deliberately left out to avoid dangerous
+ // designs based on them.
+
+ private:
+ friend class internal::AnyWidgetObserverSingleton;
+
+ AnyWidgetObserver();
+
+ // Called from the singleton to propagate events to each AnyWidgetObserver.
+ void OnAnyWidgetInitialized(Widget* widget);
+ void OnAnyWidgetShown(Widget* widget);
+ void OnAnyWidgetHidden(Widget* widget);
+ void OnAnyWidgetClosing(Widget* widget);
+
+ AnyWidgetCallback initialized_callback_;
+ AnyWidgetCallback shown_callback_;
+ AnyWidgetCallback hidden_callback_;
+ AnyWidgetCallback closing_callback_;
+};
+
+// NamedWidgetShownWaiter provides a more ergonomic way to do the most common
+// thing clients want to use AnyWidgetObserver for: waiting for a Widget with a
+// specific name to be shown. Use it like:
+//
+// NamedWidgetShownWaiter waiter(Passkey{}, "MyDialogView");
+// ThingThatShowsDialog();
+// Widget* dialog_widget = waiter.WaitIfNeededAndGet();
+//
+// It is important that NamedWidgetShownWaiter be constructed before any code
+// that might show the named Widget, because if the Widget is shown before the
+// waiter is constructed, the waiter won't have observed the show and will
+// instead hang forever. Worse, if the widget *sometimes* shows before the
+// waiter is constructed and sometimes doesn't, you will be introducing flake.
+// THIS IS A DANGEROUS PATTERN, DON'T DO THIS:
+//
+// ThingThatShowsDialogAsynchronously();
+// NamedWidgetShownWaiter waiter(...);
+// waiter.WaitIfNeededAndGet();
+class VIEWS_EXPORT NamedWidgetShownWaiter {
+ public:
+ NamedWidgetShownWaiter(AnyWidgetPasskey passkey, const std::string& name);
+ NamedWidgetShownWaiter(test::AnyWidgetTestPasskey passkey,
+ const std::string& name);
+
+ virtual ~NamedWidgetShownWaiter();
+
+ Widget* WaitIfNeededAndGet();
+
+ private:
+ explicit NamedWidgetShownWaiter(const std::string& name);
+
+ void OnAnyWidgetShown(Widget* widget);
+
+ AnyWidgetObserver observer_;
+ Widget* widget_ = nullptr;
+ base::RunLoop run_loop_;
+ const std::string name_;
+};
+
+class AnyWidgetPasskey {
+ private:
+ AnyWidgetPasskey();
+
+ // Add friend classes here that are allowed to use AnyWidgetObserver in
+ // production code.
+ friend class NamedWidgetShownWaiter;
+};
+
+namespace test {
+
+// A passkey class to allow tests to use AnyWidgetObserver without needing a
+// views owner signoff.
+class AnyWidgetTestPasskey {
+ public:
+ AnyWidgetTestPasskey() = default;
+};
+
+} // namespace test
+
+} // namespace views
+
+#endif // UI_VIEWS_WIDGET_ANY_WIDGET_OBSERVER_H_
diff --git a/chromium/ui/views/widget/any_widget_observer_singleton.cc b/chromium/ui/views/widget/any_widget_observer_singleton.cc
new file mode 100644
index 00000000000..0868045de6c
--- /dev/null
+++ b/chromium/ui/views/widget/any_widget_observer_singleton.cc
@@ -0,0 +1,44 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/widget/any_widget_observer_singleton.h"
+#include "ui/views/widget/any_widget_observer.h"
+
+#include "base/no_destructor.h"
+
+namespace views {
+namespace internal {
+
+// static
+AnyWidgetObserverSingleton* AnyWidgetObserverSingleton::GetInstance() {
+ static base::NoDestructor<AnyWidgetObserverSingleton> observer;
+ return observer.get();
+}
+
+#define PROPAGATE_NOTIFICATION(method) \
+ void AnyWidgetObserverSingleton::method(Widget* widget) { \
+ for (AnyWidgetObserver & obs : observers_) \
+ obs.method(widget); \
+ }
+
+PROPAGATE_NOTIFICATION(OnAnyWidgetInitialized)
+PROPAGATE_NOTIFICATION(OnAnyWidgetShown)
+PROPAGATE_NOTIFICATION(OnAnyWidgetHidden)
+PROPAGATE_NOTIFICATION(OnAnyWidgetClosing)
+
+#undef PROPAGATE_NOTIFICATION
+
+void AnyWidgetObserverSingleton::AddObserver(AnyWidgetObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void AnyWidgetObserverSingleton::RemoveObserver(AnyWidgetObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+AnyWidgetObserverSingleton::AnyWidgetObserverSingleton() = default;
+AnyWidgetObserverSingleton::~AnyWidgetObserverSingleton() = default;
+
+} // namespace internal
+} // namespace views
diff --git a/chromium/ui/views/widget/any_widget_observer_singleton.h b/chromium/ui/views/widget/any_widget_observer_singleton.h
new file mode 100644
index 00000000000..46ed9bfc0f1
--- /dev/null
+++ b/chromium/ui/views/widget/any_widget_observer_singleton.h
@@ -0,0 +1,48 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_WIDGET_ANY_WIDGET_OBSERVER_SINGLETON_H_
+#define UI_VIEWS_WIDGET_ANY_WIDGET_OBSERVER_SINGLETON_H_
+
+#include "base/no_destructor.h"
+#include "base/observer_list.h"
+
+namespace views {
+
+class AnyWidgetObserver;
+class Widget;
+
+namespace internal {
+
+// This is not the class you want - go look at AnyWidgetObserver.
+
+// This class serves as the "thing being observed" by AnyWidgetObservers,
+// since there is no relevant singleton for Widgets. Every Widget notifies the
+// singleton instance of this class of its creation, and it handles notifying
+// all AnyWidgetObservers of that.
+class AnyWidgetObserverSingleton {
+ public:
+ static AnyWidgetObserverSingleton* GetInstance();
+
+ void OnAnyWidgetInitialized(Widget* widget);
+ void OnAnyWidgetShown(Widget* widget);
+ void OnAnyWidgetHidden(Widget* widget);
+ void OnAnyWidgetClosing(Widget* widget);
+
+ void AddObserver(AnyWidgetObserver* observer);
+ void RemoveObserver(AnyWidgetObserver* observer);
+
+ private:
+ friend class base::NoDestructor<AnyWidgetObserverSingleton>;
+
+ AnyWidgetObserverSingleton();
+ ~AnyWidgetObserverSingleton();
+
+ base::ObserverList<AnyWidgetObserver> observers_;
+};
+
+} // namespace internal
+} // namespace views
+
+#endif // UI_VIEWS_WIDGET_ANY_WIDGET_OBSERVER_SINGLETON_H_
diff --git a/chromium/ui/views/widget/any_widget_observer_unittest.cc b/chromium/ui/views/widget/any_widget_observer_unittest.cc
new file mode 100644
index 00000000000..4a1bf692f57
--- /dev/null
+++ b/chromium/ui/views/widget/any_widget_observer_unittest.cc
@@ -0,0 +1,122 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/widget/any_widget_observer.h"
+
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/test/bind_test_util.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/views/test/native_widget_factory.h"
+#include "ui/views/test/widget_test.h"
+
+namespace {
+
+using views::Widget;
+
+using AnyWidgetObserverTest = views::test::WidgetTest;
+
+TEST_F(AnyWidgetObserverTest, ObservesInitialize) {
+ views::AnyWidgetObserver observer(views::test::AnyWidgetTestPasskey{});
+
+ bool initialized = false;
+
+ observer.set_initialized_callback(
+ base::BindLambdaForTesting([&](Widget*) { initialized = true; }));
+
+ EXPECT_FALSE(initialized);
+ WidgetAutoclosePtr w0(WidgetTest::CreateTopLevelPlatformWidget());
+ EXPECT_TRUE(initialized);
+}
+
+TEST_F(AnyWidgetObserverTest, ObservesClose) {
+ views::AnyWidgetObserver observer(views::test::AnyWidgetTestPasskey{});
+
+ bool closing = false;
+
+ observer.set_closing_callback(
+ base::BindLambdaForTesting([&](Widget*) { closing = true; }));
+
+ EXPECT_FALSE(closing);
+ { WidgetAutoclosePtr w0(WidgetTest::CreateTopLevelPlatformWidget()); }
+ EXPECT_TRUE(closing);
+}
+
+TEST_F(AnyWidgetObserverTest, ObservesShow) {
+ views::AnyWidgetObserver observer(views::test::AnyWidgetTestPasskey{});
+
+ bool shown = false;
+
+ observer.set_shown_callback(
+ base::BindLambdaForTesting([&](Widget*) { shown = true; }));
+
+ EXPECT_FALSE(shown);
+ WidgetAutoclosePtr w0(WidgetTest::CreateTopLevelPlatformWidget());
+ w0->Show();
+ EXPECT_TRUE(shown);
+}
+
+TEST_F(AnyWidgetObserverTest, ObservesHide) {
+ views::AnyWidgetObserver observer(views::test::AnyWidgetTestPasskey{});
+
+ bool hidden = false;
+
+ observer.set_hidden_callback(
+ base::BindLambdaForTesting([&](Widget*) { hidden = true; }));
+
+ EXPECT_FALSE(hidden);
+ WidgetAutoclosePtr w0(WidgetTest::CreateTopLevelPlatformWidget());
+ w0->Hide();
+ EXPECT_TRUE(hidden);
+}
+
+class NamedWidgetShownWaiterTest : public views::test::WidgetTest {
+ public:
+ NamedWidgetShownWaiterTest() = default;
+ ~NamedWidgetShownWaiterTest() override = default;
+
+ views::Widget* CreateNamedWidget(const std::string& name) {
+ Widget* widget = new Widget;
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.native_widget = views::test::CreatePlatformNativeWidgetImpl(
+ params, widget, views::test::kStubCapture, nullptr);
+ params.name = name;
+ widget->Init(std::move(params));
+ return widget;
+ }
+};
+
+TEST_F(NamedWidgetShownWaiterTest, ShownAfterWait) {
+ views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{},
+ "TestWidget");
+
+ WidgetAutoclosePtr w0(CreateNamedWidget("TestWidget"));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce([](views::Widget* widget) { widget->Show(); },
+ base::Unretained(w0.get())));
+ EXPECT_EQ(waiter.WaitIfNeededAndGet(), w0.get());
+}
+
+TEST_F(NamedWidgetShownWaiterTest, ShownBeforeWait) {
+ views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{},
+ "TestWidget");
+ WidgetAutoclosePtr w0(CreateNamedWidget("TestWidget"));
+ w0->Show();
+ EXPECT_EQ(waiter.WaitIfNeededAndGet(), w0.get());
+}
+
+TEST_F(NamedWidgetShownWaiterTest, OtherWidgetShown) {
+ views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{},
+ "TestWidget");
+ WidgetAutoclosePtr w0(CreateNamedWidget("NotTestWidget"));
+ WidgetAutoclosePtr w1(CreateNamedWidget("TestWidget"));
+ w0->Show();
+ w1->Show();
+ EXPECT_EQ(waiter.WaitIfNeededAndGet(), w1.get());
+}
+
+} // namespace
diff --git a/chromium/ui/views/widget/ax_native_widget_mac_unittest.mm b/chromium/ui/views/widget/ax_native_widget_mac_unittest.mm
index c6c77c8af54..faf79e0e6c7 100644
--- a/chromium/ui/views/widget/ax_native_widget_mac_unittest.mm
+++ b/chromium/ui/views/widget/ax_native_widget_mac_unittest.mm
@@ -7,7 +7,6 @@
#import <Cocoa/Cocoa.h>
#include "base/mac/mac_util.h"
-#import "base/mac/sdk_forward_declarations.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_capture_client.cc b/chromium/ui/views/widget/desktop_aura/desktop_capture_client.cc
index 4b6586cc54b..d437e382af5 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_capture_client.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_capture_client.cc
@@ -53,8 +53,7 @@ void DesktopCaptureClient::SetCapture(aura::Window* new_capture_window) {
// We should only ever be told to capture a child of |root_|. Otherwise
// things are going to be really confused.
- DCHECK(!new_capture_window ||
- (new_capture_window->GetRootWindow() == root_));
+ DCHECK(!new_capture_window || (new_capture_window->GetRootWindow() == root_));
DCHECK(!capture_window_ || capture_window_->GetRootWindow());
aura::Window* old_capture_window = capture_window_;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
index d0a6ce719b3..707f2b4aa33 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -7,8 +7,8 @@
#include <stddef.h>
#include <stdint.h>
-#include "base/bind.h"
-#include "base/lazy_instance.h"
+#include <utility>
+
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
@@ -18,168 +18,30 @@
#include "ui/aura/client/drag_drop_delegate.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
-#include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h"
#include "ui/base/layout.h"
+#include "ui/base/mojom/cursor_type.mojom-shared.h"
#include "ui/base/x/selection_utils.h"
+#include "ui/base/x/x11_drag_context.h"
+#include "ui/base/x/x11_util.h"
#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
-#include "ui/events/platform/platform_event_source.h"
-#include "ui/events/platform_event.h"
-#include "ui/events/x/x11_window_event_manager.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/x/x11.h"
-#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
#include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h"
#include "ui/views/widget/widget.h"
-// Reading recommended for understanding the implementation in this file:
-//
-// * The X Window System Concepts section in The X New Developer’s Guide
-// * The X Selection Mechanism paper by Keith Packard
-// * The Peer-to-Peer Communication by Means of Selections section in the
-// ICCCM (X Consortium's Inter-Client Communication Conventions Manual)
-// * The XDND specification, Drag-and-Drop Protocol for the X Window System
-// * The XDS specification, The Direct Save Protocol for the X Window System
-//
-// All the readings are freely available online.
-
using aura::client::DragDropDelegate;
using ui::OSExchangeData;
namespace {
-// The lowest XDND protocol version that we understand.
-//
-// The XDND protocol specification says that we must support all versions
-// between 3 and the version we advertise in the XDndAware property.
-constexpr int kMinXdndVersion = 3;
-
-// The value used in the XdndAware property.
-//
-// The XDND protocol version used between two windows will be the minimum
-// between the two versions advertised in the XDndAware property.
-constexpr int kMaxXdndVersion = 5;
-
-constexpr int kWillAcceptDrop = 1;
-constexpr int kWantFurtherPosEvents = 2;
-
-// These actions have the same meaning as in the W3C Drag and Drop spec.
-const char kXdndActionCopy[] = "XdndActionCopy";
-const char kXdndActionMove[] = "XdndActionMove";
-const char kXdndActionLink[] = "XdndActionLink";
-
-// Triggers the XDS protocol.
-const char kXdndActionDirectSave[] = "XdndActionDirectSave";
-
-// Window property that will receive the drag and drop selection data.
-const char kChromiumDragReciever[] = "_CHROMIUM_DRAG_RECEIVER";
-
-// Window property that contains the possible actions that will be presented to
-// the user when the drag and drop action is kXdndActionAsk.
-const char kXdndActionList[] = "XdndActionList";
-
-// Window property that tells other applications the window understands XDND.
-const char kXdndAware[] = "XdndAware";
-
-// Window property on the source window and message used by the XDS protocol.
-// This atom name intentionally includes the XDS protocol version (0).
-// After the source sends the XdndDrop message, this property stores the
-// (path-less) name of the file to be saved, and has the type text/plain, with
-// an optional charset attribute.
-// When receiving an XdndDrop event, the target needs to check for the
-// XdndDirectSave property on the source window. The target then modifies the
-// XdndDirectSave on the source window, and sends an XdndDirectSave message to
-// the source.
-// After the target sends the XdndDirectSave message, this property stores an
-// URL indicating the location where the source should save the file.
-const char kXdndDirectSave0[] = "XdndDirectSave0";
-
-// Window property pointing to a proxy window to receive XDND target messages.
-// The XDND source must check the proxy window must for the XdndAware property,
-// and must send all XDND messages to the proxy instead of the target. However,
-// the target field in the messages must still represent the original target
-// window (the window pointed to by the cursor).
-const char kXdndProxy[] = "XdndProxy";
-
-// Window property that holds the supported drag and drop data types.
-// This property is set on the XDND source window when the drag and drop data
-// can be converted to more than 3 types.
-const char kXdndTypeList[] = "XdndTypeList";
-
-// Selection used by the XDND protocol to transfer data between applications.
-const char kXdndSelection[] = "XdndSelection";
-
-// Message sent from an XDND source to the target when the user confirms the
-// drag and drop operation.
-const char kXdndDrop[] = "XdndDrop";
-
-// Message sent from an XDND source to the target to start the XDND protocol.
-// The target must wait for an XDndPosition event before querying the data.
-const char kXdndEnter[] = "XdndEnter";
-
-// Message sent from an XDND target to the source in respose to an XdndDrop.
-// The message must be sent whether the target acceepts the drop or not.
-const char kXdndFinished[] = "XdndFinished";
-
-// Message sent from an XDND source to the target when the user cancels the drag
-// and drop operation.
-const char kXdndLeave[] = "XdndLeave";
-
-// Message sent by the XDND source when the cursor position changes.
-// The source will also send an XdndPosition event right after the XdndEnter
-// event, to tell the target about the initial cursor position and the desired
-// drop action.
-// The time stamp in the XdndPosition must be used when requesting selection
-// information.
-// After the target optionally acquires selection information, it must tell the
-// source if it can accept the drop via an XdndStatus message.
-const char kXdndPosition[] = "XdndPosition";
-
-// Message sent by the XDND target in response to an XdndPosition message.
-// The message informs the source if the target will accept the drop, and what
-// action will be taken if the drop is accepted.
-const char kXdndStatus[] = "XdndStatus";
-
-int XGetModifiers() {
- XDisplay* display = gfx::GetXDisplay();
-
- XID root, child;
- int root_x, root_y, win_x, win_y;
- unsigned int mask;
- XQueryPointer(display,
- DefaultRootWindow(display),
- &root,
- &child,
- &root_x,
- &root_y,
- &win_x,
- &win_y,
- &mask);
- int modifiers = ui::EF_NONE;
- if (mask & ShiftMask)
- modifiers |= ui::EF_SHIFT_DOWN;
- if (mask & ControlMask)
- modifiers |= ui::EF_CONTROL_DOWN;
- if (mask & Mod1Mask)
- modifiers |= ui::EF_ALT_DOWN;
- if (mask & Mod4Mask)
- modifiers |= ui::EF_COMMAND_DOWN;
- if (mask & Button1Mask)
- modifiers |= ui::EF_LEFT_MOUSE_BUTTON;
- if (mask & Button2Mask)
- modifiers |= ui::EF_MIDDLE_MOUSE_BUTTON;
- if (mask & Button3Mask)
- modifiers |= ui::EF_RIGHT_MOUSE_BUTTON;
- return modifiers;
-}
-
// The minimum alpha before we declare a pixel transparent when searching in
// our source image.
constexpr uint32_t kMinAlpha = 32;
@@ -187,578 +49,111 @@ constexpr uint32_t kMinAlpha = 32;
// |drag_widget_|'s opacity.
constexpr float kDragWidgetOpacity = .75f;
-static base::LazyInstance<
- std::map<::Window, views::DesktopDragDropClientAuraX11*> >::Leaky
- g_live_client_map = LAZY_INSTANCE_INITIALIZER;
-
-} // namespace
-
-namespace views {
-
-DesktopDragDropClientAuraX11*
- DesktopDragDropClientAuraX11::g_current_drag_drop_client = nullptr;
-
-class DesktopDragDropClientAuraX11::X11DragContext
- : public ui::PlatformEventDispatcher {
- public:
- X11DragContext(::Window local_window, const XClientMessageEvent& event);
- ~X11DragContext() override;
-
- // When we receive an XdndPosition message, we need to have all the data
- // copied from the other window before we process the XdndPosition
- // message. If we have that data already, dispatch immediately. Otherwise,
- // delay dispatching until we do.
- void OnXdndPositionMessage(DesktopDragDropClientAuraX11* client,
- ::Atom suggested_action,
- ::Window source_window,
- ::Time time_stamp,
- const gfx::Point& screen_point);
-
- // Called when XSelection data has been copied to our process.
- void OnSelectionNotify(const XSelectionEvent& xselection);
-
- // Clones the fetched targets.
- const ui::SelectionFormatMap& fetched_targets() { return fetched_targets_; }
-
- // Reads the kXdndActionList property from |source_window| and copies it
- // into |actions|.
- void ReadActions();
-
- // Creates a ui::DragDropTypes::DragOperation representation of the current
- // action list.
- int GetDragOperation() const;
-
- DesktopDragDropClientAuraX11* source_client() { return source_client_; }
-
- private:
- // Called to request the next target from the source window. This is only
- // done on the first XdndPosition; after that, we cache the data offered by
- // the source window.
- void RequestNextTarget();
-
- // Masks the X11 atom |xdnd_operation|'s views representation onto
- // |drag_operation|.
- void MaskOperation(::Atom xdnd_operation, int* drag_operation) const;
-
- // ui::PlatformEventDispatcher:
- bool CanDispatchEvent(const ui::PlatformEvent& event) override;
- uint32_t DispatchEvent(const ui::PlatformEvent& event) override;
-
- // The XID of our chrome local aura window handling our events.
- ::Window local_window_;
-
- // The XID of the window that's initiated the drag.
- unsigned long source_window_;
-
- // Events that we have selected on |source_window_|.
- std::unique_ptr<ui::XScopedEventSelector> source_window_events_;
-
- // The DesktopDragDropClientAuraX11 for |source_window_| if |source_window_|
- // belongs to a Chrome window.
- DesktopDragDropClientAuraX11* source_client_;
-
- // The client we inform once we're done with requesting data.
- DesktopDragDropClientAuraX11* drag_drop_client_ = nullptr;
-
- // Whether we're blocking the handling of an XdndPosition message by waiting
- // for |unfetched_targets_| to be fetched.
- bool waiting_to_handle_position_ = false;
-
- // Where the cursor is on screen.
- gfx::Point screen_point_;
-
- // The time stamp of the last XdndPosition event we received. The XDND
- // specification mandates that we use this time stamp when querying the source
- // about the drag and drop data.
- ::Time position_time_stamp_;
-
- // A SelectionFormatMap of data that we have in our process.
- ui::SelectionFormatMap fetched_targets_;
-
- // The names of various data types offered by the other window that we
- // haven't fetched and put in |fetched_targets_| yet.
- std::vector<::Atom> unfetched_targets_;
-
- // XdndPosition messages have a suggested action. Qt applications exclusively
- // use this, instead of the XdndActionList which is backed by |actions_|.
- ::Atom suggested_action_ = x11::None;
-
- // Possible actions.
- std::vector<::Atom> actions_;
-
- DISALLOW_COPY_AND_ASSIGN(X11DragContext);
-};
-
-DesktopDragDropClientAuraX11::X11DragContext::X11DragContext(
- ::Window local_window,
- const XClientMessageEvent& event)
- : local_window_(local_window),
- source_window_(event.data.l[0]),
- source_client_(
- DesktopDragDropClientAuraX11::GetForWindow(source_window_)) {
- if (!source_client_) {
- bool get_types_from_property = ((event.data.l[1] & 1) != 0);
-
- if (get_types_from_property) {
- if (!ui::GetAtomArrayProperty(source_window_, kXdndTypeList,
- &unfetched_targets_)) {
- return;
- }
- } else {
- // data.l[2,3,4] contain the first three types. Unused slots can be None.
- for (size_t i = 2; i < 5; ++i) {
- if (event.data.l[i] != x11::None)
- unfetched_targets_.push_back(event.data.l[i]);
- }
- }
-
-#if DCHECK_IS_ON()
- DVLOG(1) << "XdndEnter has " << unfetched_targets_.size() << " data types";
- for (::Atom target : unfetched_targets_)
- DVLOG(1) << "XdndEnter data type: " << target;
-#endif // DCHECK_IS_ON()
-
- // The window doesn't have a DesktopDragDropClientAuraX11, that means it's
- // created by some other process. Listen for messages on it.
- ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
- source_window_events_ = std::make_unique<ui::XScopedEventSelector>(
- source_window_, PropertyChangeMask);
-
- // We must perform a full sync here because we could be racing
- // |source_window_|.
- XSync(gfx::GetXDisplay(), x11::False);
- } else {
- // This drag originates from an aura window within our process. This means
- // that we can shortcut the X11 server and ask the owning SelectionOwner
- // for the data it's offering.
- fetched_targets_ = source_client_->GetFormatMap();
- }
-
- ReadActions();
-}
-
-DesktopDragDropClientAuraX11::X11DragContext::~X11DragContext() {
- if (!source_client_) {
- // Unsubscribe from message events.
- ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
- }
-}
-
-void DesktopDragDropClientAuraX11::X11DragContext::OnXdndPositionMessage(
- DesktopDragDropClientAuraX11* client,
- ::Atom suggested_action,
- ::Window source_window,
- ::Time time_stamp,
- const gfx::Point& screen_point) {
- DCHECK_EQ(source_window_, source_window);
- suggested_action_ = suggested_action;
-
- if (!unfetched_targets_.empty()) {
- // We have unfetched targets. That means we need to pause the handling of
- // the position message and ask the other window for its data.
- screen_point_ = screen_point;
- drag_drop_client_ = client;
- position_time_stamp_ = time_stamp;
- waiting_to_handle_position_ = true;
-
- fetched_targets_ = ui::SelectionFormatMap();
- RequestNextTarget();
- } else {
- client->CompleteXdndPosition(source_window, screen_point);
- }
-}
-
-void DesktopDragDropClientAuraX11::X11DragContext::RequestNextTarget() {
- DCHECK(!unfetched_targets_.empty());
- DCHECK(drag_drop_client_);
- DCHECK(waiting_to_handle_position_);
-
- ::Atom target = unfetched_targets_.back();
- unfetched_targets_.pop_back();
-
- XConvertSelection(gfx::GetXDisplay(), gfx::GetAtom(kXdndSelection), target,
- gfx::GetAtom(kChromiumDragReciever), local_window_,
- position_time_stamp_);
-}
-
-void DesktopDragDropClientAuraX11::X11DragContext::OnSelectionNotify(
- const XSelectionEvent& event) {
- if (!waiting_to_handle_position_) {
- // A misbehaved window may send SelectionNotify without us requesting data
- // via XConvertSelection().
- return;
- }
- DCHECK(drag_drop_client_);
-
- DVLOG(1) << "SelectionNotify, format " << event.target;
+// Returns true if |image| has any visible regions (defined as having a pixel
+// with alpha > 32).
+bool IsValidDragImage(const gfx::ImageSkia& image) {
+ if (image.isNull())
+ return false;
- if (event.property != x11::None) {
- DCHECK_EQ(event.property, gfx::GetAtom(kChromiumDragReciever));
+ // Because we need a GL context per window, we do a quick check so that we
+ // don't make another context if the window would just be displaying a mostly
+ // transparent image.
+ const SkBitmap* in_bitmap = image.bitmap();
+ for (int y = 0; y < in_bitmap->height(); ++y) {
+ uint32_t* in_row = in_bitmap->getAddr32(0, y);
- scoped_refptr<base::RefCountedMemory> data;
- ::Atom type = x11::None;
- if (ui::GetRawBytesOfProperty(local_window_, event.property, &data, nullptr,
- &type)) {
- fetched_targets_.Insert(event.target, data);
+ for (int x = 0; x < in_bitmap->width(); ++x) {
+ if (SkColorGetA(in_row[x]) > kMinAlpha)
+ return true;
}
- } else {
- // The source failed to convert the drop data to the format (target in X11
- // parlance) that we asked for. This happens, even though we only ask for
- // the formats advertised by the source. http://crbug.com/628099
- LOG(ERROR) << "XConvertSelection failed for source-advertised target "
- << event.target;
}
- if (!unfetched_targets_.empty()) {
- RequestNextTarget();
- } else {
- waiting_to_handle_position_ = false;
- drag_drop_client_->CompleteXdndPosition(source_window_, screen_point_);
- drag_drop_client_ = nullptr;
- }
+ return false;
}
-void DesktopDragDropClientAuraX11::X11DragContext::ReadActions() {
- if (!source_client_) {
- std::vector<::Atom> atom_array;
- if (!ui::GetAtomArrayProperty(source_window_, kXdndActionList,
- &atom_array)) {
- actions_.clear();
- } else {
- actions_.swap(atom_array);
- }
- } else {
- // We have a property notify set up for other windows in case they change
- // their action list. Thankfully, the views interface is static and you
- // can't change the action list after you enter StartDragAndDrop().
- actions_ = source_client_->GetOfferedDragOperations();
- }
-}
+std::unique_ptr<views::Widget> CreateDragWidget(
+ const gfx::ImageSkia& image,
+ const gfx::Vector2d& drag_widget_offset) {
+ auto widget = std::make_unique<views::Widget>();
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_DRAG);
+ if (ui::IsCompositingManagerPresent())
+ params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
+ else
+ params.opacity = views::Widget::InitParams::WindowOpacity::kOpaque;
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.accept_events = false;
-int DesktopDragDropClientAuraX11::X11DragContext::GetDragOperation() const {
- int drag_operation = ui::DragDropTypes::DRAG_NONE;
- for (const auto& action : actions_)
- MaskOperation(action, &drag_operation);
+ gfx::Point location =
+ display::Screen::GetScreen()->GetCursorScreenPoint() - drag_widget_offset;
+ params.bounds = gfx::Rect(location, image.size());
+ widget->set_focus_on_creation(false);
+ widget->set_frame_type(views::Widget::FrameType::kForceNative);
+ widget->Init(std::move(params));
+ if (params.opacity == views::Widget::InitParams::WindowOpacity::kTranslucent)
+ widget->SetOpacity(kDragWidgetOpacity);
+ widget->GetNativeWindow()->SetName("DragWindow");
- MaskOperation(suggested_action_, &drag_operation);
+ views::ImageView* image_view = new views::ImageView();
+ image_view->SetImage(image);
+ image_view->SetBoundsRect(gfx::Rect(image.size()));
+ widget->SetContentsView(image_view);
+ widget->Show();
+ widget->GetNativeWindow()->layer()->SetFillsBoundsOpaquely(false);
- return drag_operation;
+ return widget;
}
-void DesktopDragDropClientAuraX11::X11DragContext::MaskOperation(
- ::Atom xdnd_operation,
- int* drag_operation) const {
- if (xdnd_operation == gfx::GetAtom(kXdndActionCopy))
- *drag_operation |= ui::DragDropTypes::DRAG_COPY;
- else if (xdnd_operation == gfx::GetAtom(kXdndActionMove))
- *drag_operation |= ui::DragDropTypes::DRAG_MOVE;
- else if (xdnd_operation == gfx::GetAtom(kXdndActionLink))
- *drag_operation |= ui::DragDropTypes::DRAG_LINK;
-}
+} // namespace
-bool DesktopDragDropClientAuraX11::X11DragContext::CanDispatchEvent(
- const ui::PlatformEvent& event) {
- return event->xany.window == source_window_;
-}
+namespace views {
-uint32_t DesktopDragDropClientAuraX11::X11DragContext::DispatchEvent(
- const ui::PlatformEvent& event) {
- if (event->type == PropertyNotify &&
- event->xproperty.atom == gfx::GetAtom(kXdndActionList)) {
- ReadActions();
- return ui::POST_DISPATCH_STOP_PROPAGATION;
- }
- return ui::POST_DISPATCH_NONE;
-}
+DesktopDragDropClientAuraX11*
+ DesktopDragDropClientAuraX11::g_current_drag_drop_client = nullptr;
///////////////////////////////////////////////////////////////////////////////
DesktopDragDropClientAuraX11::DesktopDragDropClientAuraX11(
aura::Window* root_window,
views::DesktopNativeCursorManager* cursor_manager,
- ::Display* xdisplay,
- ::Window xwindow)
- : root_window_(root_window),
- cursor_manager_(cursor_manager),
- xdisplay_(xdisplay),
- xwindow_(xwindow) {
- // Some tests change the DesktopDragDropClientAuraX11 associated with an
- // |xwindow|.
- g_live_client_map.Get()[xwindow] = this;
-
- // Mark that we are aware of drag and drop concepts.
- unsigned long xdnd_version = kMaxXdndVersion;
- XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom(kXdndAware), XA_ATOM, 32,
- PropModeReplace,
- reinterpret_cast<unsigned char*>(&xdnd_version), 1);
-}
+ ::Display* display,
+ XID window)
+ : XDragDropClient(this, display, window),
+ root_window_(root_window),
+ cursor_manager_(cursor_manager) {}
DesktopDragDropClientAuraX11::~DesktopDragDropClientAuraX11() {
// This is necessary when the parent native widget gets destroyed while a drag
// operation is in progress.
move_loop_->EndMoveLoop();
NotifyDragLeave();
-
- g_live_client_map.Get().erase(xwindow_);
-}
-
-// static
-DesktopDragDropClientAuraX11* DesktopDragDropClientAuraX11::GetForWindow(
- ::Window window) {
- std::map<::Window, DesktopDragDropClientAuraX11*>::const_iterator it =
- g_live_client_map.Get().find(window);
- if (it == g_live_client_map.Get().end())
- return nullptr;
- return it->second;
+ ResetDragContext();
}
void DesktopDragDropClientAuraX11::Init() {
move_loop_ = CreateMoveLoop(this);
}
-void DesktopDragDropClientAuraX11::OnXdndEnter(
- const XClientMessageEvent& event) {
- int version = (event.data.l[1] & 0xff000000) >> 24;
- DVLOG(1) << "OnXdndEnter, version " << version;
-
- if (version < kMinXdndVersion) {
- // This protocol version is not documented in the XDND standard (last
- // revised in 1999), so we don't support it. Since don't understand the
- // protocol spoken by the source, we can't tell it that we can't talk to it.
- LOG(ERROR) << "XdndEnter message discarded because its version is too old.";
- return;
- }
- if (version > kMaxXdndVersion) {
- // The XDND version used should be the minimum between the versions
- // advertised by the source and the target. We advertise kMaxXdndVersion, so
- // this should never happen when talking to an XDND-compliant application.
- LOG(ERROR) << "XdndEnter message discarded because its version is too new.";
- return;
- }
-
- // Make sure that we've run ~X11DragContext() before creating another one.
- target_current_context_.reset();
- target_current_context_ = std::make_unique<X11DragContext>(xwindow_, event);
-
- // In the Windows implementation, we immediately call DesktopDropTargetWin::
- // Translate(). The XDND specification demands that we wait until we receive
- // an XdndPosition message before we use XConvertSelection or send an
- // XdndStatus message.
-}
-
-void DesktopDragDropClientAuraX11::OnXdndLeave(
- const XClientMessageEvent& event) {
- DVLOG(1) << "OnXdndLeave";
- NotifyDragLeave();
- target_current_context_.reset();
-}
-
-void DesktopDragDropClientAuraX11::OnXdndPosition(
- const XClientMessageEvent& event) {
- DVLOG(1) << "OnXdndPosition";
-
- unsigned long source_window = event.data.l[0];
- int x_root_window = event.data.l[2] >> 16;
- int y_root_window = event.data.l[2] & 0xffff;
- ::Time time_stamp = event.data.l[3];
- ::Atom suggested_action = event.data.l[4];
-
- if (!target_current_context_.get()) {
- NOTREACHED();
- return;
- }
-
- target_current_context_->OnXdndPositionMessage(
- this, suggested_action, source_window, time_stamp,
- gfx::Point(x_root_window, y_root_window));
-}
-
-void DesktopDragDropClientAuraX11::OnXdndStatus(
- const XClientMessageEvent& event) {
- DVLOG(1) << "OnXdndStatus";
-
- unsigned long source_window = event.data.l[0];
-
- if (source_window != source_current_window_)
- return;
-
- if (source_state_ != SourceState::kPendingDrop &&
- source_state_ != SourceState::kOther) {
- return;
- }
-
- waiting_on_status_ = false;
- status_received_since_enter_ = true;
-
- if (event.data.l[1] & 1) {
- ::Atom atom_operation = event.data.l[4];
- negotiated_operation_ = AtomToDragOperation(atom_operation);
- } else {
- negotiated_operation_ = ui::DragDropTypes::DRAG_NONE;
- }
-
- if (source_state_ == SourceState::kPendingDrop) {
- // We were waiting on the status message so we could send the XdndDrop.
- if (negotiated_operation_ == ui::DragDropTypes::DRAG_NONE) {
- move_loop_->EndMoveLoop();
- return;
- }
- source_state_ = SourceState::kDropped;
- SendXdndDrop(source_window);
- return;
- }
-
- ui::CursorType cursor_type = ui::CursorType::kNull;
- switch (negotiated_operation_) {
- case ui::DragDropTypes::DRAG_NONE:
- cursor_type = ui::CursorType::kDndNone;
- break;
- case ui::DragDropTypes::DRAG_MOVE:
- cursor_type = ui::CursorType::kDndMove;
- break;
- case ui::DragDropTypes::DRAG_COPY:
- cursor_type = ui::CursorType::kDndCopy;
- break;
- case ui::DragDropTypes::DRAG_LINK:
- cursor_type = ui::CursorType::kDndLink;
- break;
- }
- move_loop_->UpdateCursor(cursor_manager_->GetInitializedCursor(cursor_type));
-
- // Note: event.data.[2,3] specify a rectangle. It is a request by the other
- // window to not send further XdndPosition messages while the cursor is
- // within it. However, it is considered advisory and (at least according to
- // the spec) the other side must handle further position messages within
- // it. GTK+ doesn't bother with this, so neither should we.
-
- if (next_position_message_.get()) {
- // We were waiting on the status message so we could send off the next
- // position message we queued up.
- gfx::Point p = next_position_message_->first;
- unsigned long event_time = next_position_message_->second;
- next_position_message_.reset();
-
- SendXdndPosition(source_window, p, event_time);
- }
-}
-
-void DesktopDragDropClientAuraX11::OnXdndFinished(
- const XClientMessageEvent& event) {
- DVLOG(1) << "OnXdndFinished";
- unsigned long source_window = event.data.l[0];
- if (source_current_window_ != source_window)
- return;
-
- // Clear |negotiated_operation_| if the drag was rejected.
- if ((event.data.l[1] & 1) == 0)
- negotiated_operation_ = ui::DragDropTypes::DRAG_NONE;
-
- // Clear |source_current_window_| to avoid sending XdndLeave upon ending the
- // move loop.
- source_current_window_ = x11::None;
- move_loop_->EndMoveLoop();
-}
-
-void DesktopDragDropClientAuraX11::OnXdndDrop(
- const XClientMessageEvent& event) {
- DVLOG(1) << "OnXdndDrop";
-
- unsigned long source_window = event.data.l[0];
-
- int drag_operation = ui::DragDropTypes::DRAG_NONE;
- if (target_window_) {
- aura::client::DragDropDelegate* delegate =
- aura::client::GetDragDropDelegate(target_window_);
- if (delegate) {
- auto data(std::make_unique<ui::OSExchangeData>(
- std::make_unique<ui::OSExchangeDataProviderAuraX11>(
- xwindow_, target_current_context_->fetched_targets())));
-
- ui::DropTargetEvent drop_event(
- *data.get(), gfx::PointF(target_window_location_),
- gfx::PointF(target_window_root_location_),
- target_current_context_->GetDragOperation());
- if (target_current_context_->source_client()) {
- drop_event.set_flags(
- target_current_context_->source_client()->current_modifier_state());
- } else {
- drop_event.set_flags(XGetModifiers());
- }
-
- if (!IsDragDropInProgress()) {
- UMA_HISTOGRAM_COUNTS_1M("Event.DragDrop.ExternalOriginDrop", 1);
- }
-
- drag_operation = delegate->OnPerformDrop(drop_event, std::move(data));
- }
-
- target_window_->RemoveObserver(this);
- target_window_ = nullptr;
- }
-
- XEvent xev;
- xev.xclient.type = ClientMessage;
- xev.xclient.message_type = gfx::GetAtom(kXdndFinished);
- xev.xclient.format = 32;
- xev.xclient.window = source_window;
- xev.xclient.data.l[0] = xwindow_;
- xev.xclient.data.l[1] = (drag_operation != 0) ? 1 : 0;
- xev.xclient.data.l[2] = DragOperationToAtom(drag_operation);
-
- SendXClientEvent(source_window, &xev);
-}
-
-void DesktopDragDropClientAuraX11::OnSelectionNotify(
- const XSelectionEvent& xselection) {
- DVLOG(1) << "OnSelectionNotify";
- if (target_current_context_)
- target_current_context_->OnSelectionNotify(xselection);
-
- // ICCCM requires us to delete the property passed into SelectionNotify.
- if (xselection.property != x11::None)
- XDeleteProperty(xdisplay_, xwindow_, xselection.property);
-}
-
int DesktopDragDropClientAuraX11::StartDragAndDrop(
std::unique_ptr<ui::OSExchangeData> data,
aura::Window* root_window,
aura::Window* source_window,
- const gfx::Point& screen_location,
+ const gfx::Point& /*screen_location*/,
int operation,
ui::DragDropTypes::DragEventSource source) {
UMA_HISTOGRAM_ENUMERATION("Event.DragDrop.Start", source,
ui::DragDropTypes::DRAG_EVENT_SOURCE_COUNT);
- source_current_window_ = x11::None;
DCHECK(!g_current_drag_drop_client);
g_current_drag_drop_client = this;
- waiting_on_status_ = false;
- next_position_message_.reset();
- status_received_since_enter_ = false;
- source_state_ = SourceState::kOther;
- drag_operation_ = operation;
- negotiated_operation_ = ui::DragDropTypes::DRAG_NONE;
-
- const ui::OSExchangeData::Provider* provider = &data->provider();
- source_provider_ = static_cast<const ui::OSExchangeDataProviderAuraX11*>(
- provider);
-
- source_provider_->TakeOwnershipOfSelection();
-
- std::vector<::Atom> actions = GetOfferedDragOperations();
- if (!source_provider_->file_contents_name().empty()) {
- actions.push_back(gfx::GetAtom(kXdndActionDirectSave));
- ui::SetStringProperty(
- xwindow_, gfx::GetAtom(kXdndDirectSave0),
- gfx::GetAtom(ui::kMimeTypeText),
- source_provider_->file_contents_name().AsUTF8Unsafe());
- }
- ui::SetAtomArrayProperty(xwindow_, kXdndActionList, "ATOM", actions);
- gfx::ImageSkia drag_image = source_provider_->GetDragImage();
+ InitDrag(operation, data.get());
+
+ DCHECK(source_provider());
+ gfx::ImageSkia drag_image = source_provider()->GetDragImage();
if (IsValidDragImage(drag_image)) {
- CreateDragWidget(drag_image);
- drag_widget_offset_ = source_provider_->GetDragImageOffset();
+ drag_image_size_ = drag_image.size();
+ drag_widget_offset_ = source_provider()->GetDragImageOffset();
+ drag_widget_ = CreateDragWidget(drag_image, drag_widget_offset_);
}
// Chrome expects starting drag and drop to release capture.
@@ -777,10 +172,11 @@ int DesktopDragDropClientAuraX11::StartDragAndDrop(
// drag. We have to emulate this, so we spin off a nested runloop which will
// track all cursor movement and reroute events to a specific handler.
move_loop_->RunMoveLoop(source_window, cursor_manager_->GetInitializedCursor(
- ui::CursorType::kGrabbing));
+ ui::mojom::CursorType::kGrabbing));
if (alive) {
- if (negotiated_operation_ == ui::DragDropTypes::DRAG_NONE) {
+ auto resulting_operation = negotiated_operation();
+ if (resulting_operation == ui::DragDropTypes::DRAG_NONE) {
UMA_HISTOGRAM_ENUMERATION("Event.DragDrop.Cancel", source,
ui::DragDropTypes::DRAG_EVENT_SOURCE_COUNT);
} else {
@@ -788,14 +184,9 @@ int DesktopDragDropClientAuraX11::StartDragAndDrop(
ui::DragDropTypes::DRAG_EVENT_SOURCE_COUNT);
}
drag_widget_.reset();
-
- source_provider_ = nullptr;
g_current_drag_drop_client = nullptr;
- drag_operation_ = 0;
- XDeleteProperty(xdisplay_, xwindow_, gfx::GetAtom(kXdndActionList));
- XDeleteProperty(xdisplay_, xwindow_, gfx::GetAtom(kXdndDirectSave0));
-
- return negotiated_operation_;
+ CleanupDrag();
+ return resulting_operation;
}
UMA_HISTOGRAM_ENUMERATION("Event.DragDrop.Cancel", source,
ui::DragDropTypes::DRAG_EVENT_SOURCE_COUNT);
@@ -820,6 +211,14 @@ void DesktopDragDropClientAuraX11::RemoveObserver(
NOTIMPLEMENTED();
}
+bool DesktopDragDropClientAuraX11::DispatchXEvent(XEvent* event) {
+ if (!target_current_context() ||
+ event->xany.window != target_current_context()->source_window()) {
+ return false;
+ }
+ return target_current_context()->DispatchXEvent(event);
+}
+
void DesktopDragDropClientAuraX11::OnWindowDestroyed(aura::Window* window) {
DCHECK_EQ(target_window_, window);
target_window_ = nullptr;
@@ -838,72 +237,15 @@ void DesktopDragDropClientAuraX11::OnMouseMovement(
gfx::Rect(scaled_point - drag_widget_offset_, drag_image_size_));
drag_widget_->StackAtTop();
}
-
- const int kModifiers = ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
- ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN |
- ui::EF_LEFT_MOUSE_BUTTON |
- ui::EF_MIDDLE_MOUSE_BUTTON |
- ui::EF_RIGHT_MOUSE_BUTTON;
- current_modifier_state_ = flags & kModifiers;
-
- repeat_mouse_move_timer_.Stop();
- ProcessMouseMove(screen_point,
- (event_time - base::TimeTicks()).InMilliseconds());
+ HandleMouseMovement(screen_point, flags, event_time);
}
void DesktopDragDropClientAuraX11::OnMouseReleased() {
- repeat_mouse_move_timer_.Stop();
-
- if (source_state_ != SourceState::kOther) {
- // The user has previously released the mouse and is clicking in
- // frustration.
- move_loop_->EndMoveLoop();
- return;
- }
-
- if (source_current_window_ != x11::None) {
- if (waiting_on_status_) {
- if (status_received_since_enter_) {
- // If we are waiting for an XdndStatus message, we need to wait for it
- // to complete.
- source_state_ = SourceState::kPendingDrop;
-
- // Start timer to end the move loop if the target takes too long to send
- // the XdndStatus and XdndFinished messages.
- StartEndMoveLoopTimer();
- return;
- }
-
- move_loop_->EndMoveLoop();
- return;
- }
-
- if (negotiated_operation_ != ui::DragDropTypes::DRAG_NONE) {
- // Start timer to end the move loop if the target takes too long to send
- // an XdndFinished message. It is important that StartEndMoveLoopTimer()
- // is called before SendXdndDrop() because SendXdndDrop()
- // sends XdndFinished synchronously if the drop target is a Chrome
- // window.
- StartEndMoveLoopTimer();
-
- // We have negotiated an action with the other end.
- source_state_ = SourceState::kDropped;
- SendXdndDrop(source_current_window_);
- return;
- }
- }
-
- move_loop_->EndMoveLoop();
+ XDragDropClient::HandleMouseReleased();
}
void DesktopDragDropClientAuraX11::OnMoveLoopEnded() {
- if (source_current_window_ != x11::None) {
- SendXdndLeave(source_current_window_);
- source_current_window_ = x11::None;
- }
- target_current_context_.reset();
- repeat_mouse_move_timer_.Stop();
- end_move_loop_timer_.Stop();
+ XDragDropClient::HandleMoveLoopEnded();
}
std::unique_ptr<X11MoveLoop> DesktopDragDropClientAuraX11::CreateMoveLoop(
@@ -911,115 +253,6 @@ std::unique_ptr<X11MoveLoop> DesktopDragDropClientAuraX11::CreateMoveLoop(
return base::WrapUnique(new X11WholeScreenMoveLoop(this));
}
-XID DesktopDragDropClientAuraX11::FindWindowFor(
- const gfx::Point& screen_point) {
- views::X11TopmostWindowFinder finder;
- ::Window target = finder.FindWindowAt(screen_point);
-
- if (target == x11::None)
- return x11::None;
-
- // TODO(crbug/651775): The proxy window should be reported separately from the
- // target window. XDND messages should be sent to the proxy, and their
- // window field should point to the target.
-
- // Figure out which window we should test as XdndAware. If |target| has
- // XdndProxy, it will set that proxy on target, and if not, |target|'s
- // original value will remain.
- ui::GetXIDProperty(target, kXdndProxy, &target);
-
- int version;
- if (ui::GetIntProperty(target, kXdndAware, &version) &&
- version >= kMaxXdndVersion) {
- return target;
- }
- return x11::None;
-}
-
-void DesktopDragDropClientAuraX11::SendXClientEvent(::Window xid,
- XEvent* xev) {
- DCHECK_EQ(ClientMessage, xev->type);
-
- // Don't send messages to the X11 message queue if we can help it.
- DesktopDragDropClientAuraX11* short_circuit = GetForWindow(xid);
- if (short_circuit) {
- Atom message_type = xev->xclient.message_type;
- if (message_type == gfx::GetAtom(kXdndEnter)) {
- short_circuit->OnXdndEnter(xev->xclient);
- return;
- } else if (message_type == gfx::GetAtom(kXdndLeave)) {
- short_circuit->OnXdndLeave(xev->xclient);
- return;
- } else if (message_type == gfx::GetAtom(kXdndPosition)) {
- short_circuit->OnXdndPosition(xev->xclient);
- return;
- } else if (message_type == gfx::GetAtom(kXdndStatus)) {
- short_circuit->OnXdndStatus(xev->xclient);
- return;
- } else if (message_type == gfx::GetAtom(kXdndFinished)) {
- short_circuit->OnXdndFinished(xev->xclient);
- return;
- } else if (message_type == gfx::GetAtom(kXdndDrop)) {
- short_circuit->OnXdndDrop(xev->xclient);
- return;
- }
- }
-
- // I don't understand why the GTK+ code is doing what it's doing here. It
- // goes out of its way to send the XEvent so that it receives a callback on
- // success or failure, and when it fails, it then sends an internal
- // GdkEvent about the failed drag. (And sending this message doesn't appear
- // to go through normal xlib machinery, but instead passes through the low
- // level xProto (the x11 wire format) that I don't understand.
- //
- // I'm unsure if I have to jump through those hoops, or if XSendEvent is
- // sufficient.
- XSendEvent(xdisplay_, xid, x11::False, 0, xev);
-}
-
-void DesktopDragDropClientAuraX11::ProcessMouseMove(
- const gfx::Point& screen_point,
- unsigned long event_time) {
- if (source_state_ != SourceState::kOther)
- return;
-
- // Find the current window the cursor is over.
- ::Window dest_window = FindWindowFor(screen_point);
-
- if (source_current_window_ != dest_window) {
- if (source_current_window_ != x11::None)
- SendXdndLeave(source_current_window_);
-
- source_current_window_ = dest_window;
- waiting_on_status_ = false;
- next_position_message_.reset();
- status_received_since_enter_ = false;
- negotiated_operation_ = ui::DragDropTypes::DRAG_NONE;
-
- if (source_current_window_ != x11::None)
- SendXdndEnter(source_current_window_);
- }
-
- if (source_current_window_ != x11::None) {
- if (waiting_on_status_) {
- next_position_message_ =
- std::make_unique<std::pair<gfx::Point, unsigned long>>(screen_point,
- event_time);
- } else {
- SendXdndPosition(dest_window, screen_point, event_time);
- }
- }
-}
-
-void DesktopDragDropClientAuraX11::StartEndMoveLoopTimer() {
- end_move_loop_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(1000),
- this, &DesktopDragDropClientAuraX11::EndMoveLoop);
-}
-
-void DesktopDragDropClientAuraX11::EndMoveLoop() {
- move_loop_->EndMoveLoop();
-}
-
void DesktopDragDropClientAuraX11::DragTranslate(
const gfx::Point& root_window_location,
std::unique_ptr<ui::OSExchangeData>* data,
@@ -1045,16 +278,17 @@ void DesktopDragDropClientAuraX11::DragTranslate(
if (!*delegate)
return;
+ DCHECK(target_current_context());
*data = std::make_unique<OSExchangeData>(
std::make_unique<ui::OSExchangeDataProviderAuraX11>(
- xwindow_, target_current_context_->fetched_targets()));
+ xwindow(), target_current_context()->fetched_targets()));
gfx::Point location = root_location;
aura::Window::ConvertPointToTarget(root_window_, target_window_, &location);
target_window_location_ = location;
target_window_root_location_ = root_location;
- int drag_op = target_current_context_->GetDragOperation();
+ int drag_op = target_current_context()->GetDragOperation();
// KDE-based file browsers such as Dolphin change the drag operation depending
// on whether alt/ctrl/shift was pressed. However once Chromium gets control
// over the X11 events, the source application does no longer receive X11
@@ -1069,11 +303,11 @@ void DesktopDragDropClientAuraX11::DragTranslate(
*event = std::make_unique<ui::DropTargetEvent>(
*(data->get()), gfx::PointF(location), gfx::PointF(root_location),
drag_op);
- if (target_current_context_->source_client()) {
+ if (target_current_context()->source_client()) {
(*event)->set_flags(
- target_current_context_->source_client()->current_modifier_state());
+ target_current_context()->source_client()->current_modifier_state());
} else {
- (*event)->set_flags(XGetModifiers());
+ (*event)->set_flags(ui::XGetMaskAsEventFlags());
}
if (target_window_changed)
(*delegate)->OnDragEntered(*event->get());
@@ -1090,213 +324,106 @@ void DesktopDragDropClientAuraX11::NotifyDragLeave() {
target_window_ = nullptr;
}
-::Atom DesktopDragDropClientAuraX11::DragOperationToAtom(
- int drag_operation) {
- if (drag_operation & ui::DragDropTypes::DRAG_COPY)
- return gfx::GetAtom(kXdndActionCopy);
- if (drag_operation & ui::DragDropTypes::DRAG_MOVE)
- return gfx::GetAtom(kXdndActionMove);
- if (drag_operation & ui::DragDropTypes::DRAG_LINK)
- return gfx::GetAtom(kXdndActionLink);
-
- return x11::None;
+std::unique_ptr<ui::XTopmostWindowFinder>
+DesktopDragDropClientAuraX11::CreateWindowFinder() {
+ return std::make_unique<X11TopmostWindowFinder>();
}
-ui::DragDropTypes::DragOperation
-DesktopDragDropClientAuraX11::AtomToDragOperation(::Atom atom) {
- if (atom == gfx::GetAtom(kXdndActionCopy))
- return ui::DragDropTypes::DRAG_COPY;
- if (atom == gfx::GetAtom(kXdndActionMove))
- return ui::DragDropTypes::DRAG_MOVE;
- if (atom == gfx::GetAtom(kXdndActionLink))
- return ui::DragDropTypes::DRAG_LINK;
-
- return ui::DragDropTypes::DRAG_NONE;
-}
-
-std::vector<::Atom> DesktopDragDropClientAuraX11::GetOfferedDragOperations() {
- std::vector<::Atom> operations;
- if (drag_operation_ & ui::DragDropTypes::DRAG_COPY)
- operations.push_back(gfx::GetAtom(kXdndActionCopy));
- if (drag_operation_ & ui::DragDropTypes::DRAG_MOVE)
- operations.push_back(gfx::GetAtom(kXdndActionMove));
- if (drag_operation_ & ui::DragDropTypes::DRAG_LINK)
- operations.push_back(gfx::GetAtom(kXdndActionLink));
- return operations;
-}
-
-ui::SelectionFormatMap DesktopDragDropClientAuraX11::GetFormatMap() const {
- return source_provider_ ? source_provider_->GetFormatMap() :
- ui::SelectionFormatMap();
-}
-
-void DesktopDragDropClientAuraX11::CompleteXdndPosition(
- ::Window source_window,
- const gfx::Point& screen_point) {
- int drag_operation = ui::DragDropTypes::DRAG_NONE;
+int DesktopDragDropClientAuraX11::UpdateDrag(const gfx::Point& screen_point) {
+ // The drop target event holds a reference to data, that's why we have to hold
+ // the data until the event is handled.
std::unique_ptr<ui::OSExchangeData> data;
std::unique_ptr<ui::DropTargetEvent> drop_target_event;
DragDropDelegate* delegate = nullptr;
DragTranslate(screen_point, &data, &drop_target_event, &delegate);
- if (delegate)
- drag_operation = delegate->OnDragUpdated(*drop_target_event);
+ int drag_operation =
+ delegate ? drag_operation = delegate->OnDragUpdated(*drop_target_event)
+ : ui::DragDropTypes::DRAG_NONE;
UMA_HISTOGRAM_BOOLEAN("Event.DragDrop.AcceptDragUpdate",
drag_operation != ui::DragDropTypes::DRAG_NONE);
- // Sends an XdndStatus message back to the source_window. l[2,3]
- // theoretically represent an area in the window where the current action is
- // the same as what we're returning, but I can't find any implementation that
- // actually making use of this. A client can return (0, 0) and/or set the
- // first bit of l[1] to disable the feature, and it appears that gtk neither
- // sets this nor respects it if set.
- XEvent xev;
- xev.xclient.type = ClientMessage;
- xev.xclient.message_type = gfx::GetAtom(kXdndStatus);
- xev.xclient.format = 32;
- xev.xclient.window = source_window;
- xev.xclient.data.l[0] = xwindow_;
- xev.xclient.data.l[1] = (drag_operation != 0) ?
- (kWantFurtherPosEvents | kWillAcceptDrop) : 0;
- xev.xclient.data.l[2] = 0;
- xev.xclient.data.l[3] = 0;
- xev.xclient.data.l[4] = DragOperationToAtom(drag_operation);
-
- SendXClientEvent(source_window, &xev);
+ return drag_operation;
}
-void DesktopDragDropClientAuraX11::SendXdndEnter(::Window dest_window) {
- XEvent xev;
- xev.xclient.type = ClientMessage;
- xev.xclient.message_type = gfx::GetAtom(kXdndEnter);
- xev.xclient.format = 32;
- xev.xclient.window = dest_window;
- xev.xclient.data.l[0] = xwindow_;
- xev.xclient.data.l[1] = (kMaxXdndVersion << 24); // The version number.
- xev.xclient.data.l[2] = 0;
- xev.xclient.data.l[3] = 0;
- xev.xclient.data.l[4] = 0;
-
- std::vector<Atom> targets;
- source_provider_->RetrieveTargets(&targets);
-
- if (targets.size() > 3) {
- xev.xclient.data.l[1] |= 1;
- ui::SetAtomArrayProperty(xwindow_, kXdndTypeList, "ATOM", targets);
- } else {
- // Pack the targets into the enter message.
- for (size_t i = 0; i < targets.size(); ++i)
- xev.xclient.data.l[2 + i] = targets[i];
+void DesktopDragDropClientAuraX11::UpdateCursor(
+ ui::DragDropTypes::DragOperation negotiated_operation) {
+ ui::mojom::CursorType cursor_type = ui::mojom::CursorType::kNull;
+ switch (negotiated_operation) {
+ case ui::DragDropTypes::DRAG_NONE:
+ cursor_type = ui::mojom::CursorType::kDndNone;
+ break;
+ case ui::DragDropTypes::DRAG_MOVE:
+ cursor_type = ui::mojom::CursorType::kDndMove;
+ break;
+ case ui::DragDropTypes::DRAG_COPY:
+ cursor_type = ui::mojom::CursorType::kDndCopy;
+ break;
+ case ui::DragDropTypes::DRAG_LINK:
+ cursor_type = ui::mojom::CursorType::kDndLink;
+ break;
}
-
- SendXClientEvent(dest_window, &xev);
+ move_loop_->UpdateCursor(cursor_manager_->GetInitializedCursor(cursor_type));
}
-void DesktopDragDropClientAuraX11::SendXdndLeave(::Window dest_window) {
- XEvent xev;
- xev.xclient.type = ClientMessage;
- xev.xclient.message_type = gfx::GetAtom(kXdndLeave);
- xev.xclient.format = 32;
- xev.xclient.window = dest_window;
- xev.xclient.data.l[0] = xwindow_;
- xev.xclient.data.l[1] = 0;
- xev.xclient.data.l[2] = 0;
- xev.xclient.data.l[3] = 0;
- xev.xclient.data.l[4] = 0;
- SendXClientEvent(dest_window, &xev);
+void DesktopDragDropClientAuraX11::OnBeginForeignDrag(XID window) {
+ DCHECK(target_current_context());
+ DCHECK(!target_current_context()->source_client());
+
+ ui::X11EventSource::GetInstance()->AddXEventDispatcher(this);
+ source_window_events_ =
+ std::make_unique<ui::XScopedEventSelector>(window, PropertyChangeMask);
}
-void DesktopDragDropClientAuraX11::SendXdndPosition(
- ::Window dest_window,
- const gfx::Point& screen_point,
- unsigned long event_time) {
- waiting_on_status_ = true;
-
- XEvent xev;
- xev.xclient.type = ClientMessage;
- xev.xclient.message_type = gfx::GetAtom(kXdndPosition);
- xev.xclient.format = 32;
- xev.xclient.window = dest_window;
- xev.xclient.data.l[0] = xwindow_;
- xev.xclient.data.l[1] = 0;
- xev.xclient.data.l[2] = (screen_point.x() << 16) | screen_point.y();
- xev.xclient.data.l[3] = event_time;
- xev.xclient.data.l[4] = DragOperationToAtom(drag_operation_);
- SendXClientEvent(dest_window, &xev);
-
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html and
- // the Xdnd protocol both recommend that drag events should be sent
- // periodically.
- repeat_mouse_move_timer_.Start(
- FROM_HERE, base::TimeDelta::FromMilliseconds(350),
- base::BindOnce(&DesktopDragDropClientAuraX11::ProcessMouseMove,
- base::Unretained(this), screen_point, event_time));
+void DesktopDragDropClientAuraX11::OnEndForeignDrag() {
+ DCHECK(target_current_context());
+ DCHECK(!target_current_context()->source_client());
+
+ ui::X11EventSource::GetInstance()->RemoveXEventDispatcher(this);
}
-void DesktopDragDropClientAuraX11::SendXdndDrop(::Window dest_window) {
- XEvent xev;
- xev.xclient.type = ClientMessage;
- xev.xclient.message_type = gfx::GetAtom(kXdndDrop);
- xev.xclient.format = 32;
- xev.xclient.window = dest_window;
- xev.xclient.data.l[0] = xwindow_;
- xev.xclient.data.l[1] = 0;
- xev.xclient.data.l[2] = x11::CurrentTime;
- xev.xclient.data.l[3] = x11::None;
- xev.xclient.data.l[4] = x11::None;
- SendXClientEvent(dest_window, &xev);
+void DesktopDragDropClientAuraX11::OnBeforeDragLeave() {
+ NotifyDragLeave();
}
-void DesktopDragDropClientAuraX11::CreateDragWidget(
- const gfx::ImageSkia& image) {
- Widget* widget = new Widget;
- Widget::InitParams params(Widget::InitParams::TYPE_DRAG);
- if (ui::IsCompositingManagerPresent())
- params.opacity = Widget::InitParams::WindowOpacity::kTranslucent;
- else
- params.opacity = Widget::InitParams::WindowOpacity::kOpaque;
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.accept_events = false;
+int DesktopDragDropClientAuraX11::PerformDrop() {
+ DCHECK(target_current_context());
- gfx::Point location = display::Screen::GetScreen()->GetCursorScreenPoint() -
- drag_widget_offset_;
- params.bounds = gfx::Rect(location, image.size());
- widget->set_focus_on_creation(false);
- widget->set_frame_type(Widget::FrameType::kForceNative);
- widget->Init(std::move(params));
- if (params.opacity == Widget::InitParams::WindowOpacity::kTranslucent)
- widget->SetOpacity(kDragWidgetOpacity);
- widget->GetNativeWindow()->SetName("DragWindow");
-
- drag_image_size_ = image.size();
- ImageView* image_view = new ImageView();
- image_view->SetImage(image);
- image_view->SetBoundsRect(gfx::Rect(drag_image_size_));
- widget->SetContentsView(image_view);
- widget->Show();
- widget->GetNativeWindow()->layer()->SetFillsBoundsOpaquely(false);
-
- drag_widget_.reset(widget);
-}
+ int drag_operation = ui::DragDropTypes::DRAG_NONE;
+ if (target_window_) {
+ aura::client::DragDropDelegate* delegate =
+ aura::client::GetDragDropDelegate(target_window_);
+ if (delegate) {
+ auto data(std::make_unique<ui::OSExchangeData>(
+ std::make_unique<ui::OSExchangeDataProviderAuraX11>(
+ xwindow(), target_current_context()->fetched_targets())));
-bool DesktopDragDropClientAuraX11::IsValidDragImage(
- const gfx::ImageSkia& image) {
- if (image.isNull())
- return false;
+ ui::DropTargetEvent drop_event(
+ *data.get(), gfx::PointF(target_window_location_),
+ gfx::PointF(target_window_root_location_),
+ target_current_context()->GetDragOperation());
+ if (target_current_context()->source_client()) {
+ drop_event.set_flags(target_current_context()
+ ->source_client()
+ ->current_modifier_state());
+ } else {
+ drop_event.set_flags(ui::XGetMaskAsEventFlags());
+ }
- // Because we need a GL context per window, we do a quick check so that we
- // don't make another context if the window would just be displaying a mostly
- // transparent image.
- const SkBitmap* in_bitmap = image.bitmap();
- for (int y = 0; y < in_bitmap->height(); ++y) {
- uint32_t* in_row = in_bitmap->getAddr32(0, y);
+ if (!IsDragDropInProgress()) {
+ UMA_HISTOGRAM_COUNTS_1M("Event.DragDrop.ExternalOriginDrop", 1);
+ }
- for (int x = 0; x < in_bitmap->width(); ++x) {
- if (SkColorGetA(in_row[x]) > kMinAlpha)
- return true;
+ drag_operation = delegate->OnPerformDrop(drop_event, std::move(data));
}
+
+ target_window_->RemoveObserver(this);
+ target_window_ = nullptr;
}
+ return drag_operation;
+}
- return false;
+void DesktopDragDropClientAuraX11::EndMoveLoop() {
+ move_loop_->EndMoveLoop();
}
} // namespace views
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
index f719b1ad8db..7ae53151b9e 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
@@ -9,15 +9,16 @@
#include <set>
#include <vector>
-#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/timer/timer.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/window_observer.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/dragdrop/drag_drop_types.h"
+#include "ui/base/x/x11_drag_drop_client.h"
#include "ui/events/event_constants.h"
+#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/events/x/x11_window_event_manager.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/x/x11.h"
@@ -28,20 +29,18 @@ namespace aura {
namespace client {
class DragDropClientObserver;
class DragDropDelegate;
-}
-}
+} // namespace client
+} // namespace aura
namespace gfx {
-class ImageSkia;
class Point;
}
namespace ui {
class DropTargetEvent;
class OSExchangeData;
-class OSExchangeDataProviderAuraX11;
-class SelectionFormatMap;
-}
+class XTopmostWindowFinder;
+} // namespace ui
namespace views {
class DesktopNativeCursorManager;
@@ -52,36 +51,23 @@ class X11MoveLoop;
// X11 events forwarded from DesktopWindowTreeHostLinux, while on the other, it
// handles the views drag events.
class VIEWS_EXPORT DesktopDragDropClientAuraX11
- : public aura::client::DragDropClient,
+ : public ui::XDragDropClient,
+ public ui::XDragDropClient::Delegate,
+ public aura::client::DragDropClient,
+ public ui::XEventDispatcher,
public aura::WindowObserver,
public X11MoveLoopDelegate {
public:
DesktopDragDropClientAuraX11(
aura::Window* root_window,
views::DesktopNativeCursorManager* cursor_manager,
- ::Display* xdisplay,
- ::Window xwindow);
+ Display* xdisplay,
+ XID xwindow);
~DesktopDragDropClientAuraX11() override;
- // We maintain a mapping of live DesktopDragDropClientAuraX11 objects to
- // their ::Windows. We do this so that we're able to short circuit sending
- // X11 messages to windows in our process.
- static DesktopDragDropClientAuraX11* GetForWindow(::Window window);
-
void Init();
- // These methods handle the various X11 client messages from the platform.
- void OnXdndEnter(const XClientMessageEvent& event);
- void OnXdndLeave(const XClientMessageEvent& event);
- void OnXdndPosition(const XClientMessageEvent& event);
- void OnXdndStatus(const XClientMessageEvent& event);
- void OnXdndFinished(const XClientMessageEvent& event);
- void OnXdndDrop(const XClientMessageEvent& event);
-
- // Called when XSelection data has been copied to our process.
- void OnSelectionNotify(const XSelectionEvent& xselection);
-
- // Overridden from aura::client::DragDropClient:
+ // aura::client::DragDropClient:
int StartDragAndDrop(std::unique_ptr<ui::OSExchangeData> data,
aura::Window* root_window,
aura::Window* source_window,
@@ -93,10 +79,13 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
void AddObserver(aura::client::DragDropClientObserver* observer) override;
void RemoveObserver(aura::client::DragDropClientObserver* observer) override;
- // Overridden from aura::WindowObserver:
+ // XEventDispatcher:
+ bool DispatchXEvent(XEvent* event) override;
+
+ // aura::WindowObserver:
void OnWindowDestroyed(aura::Window* window) override;
- // Overridden from X11WholeScreenMoveLoopDelegate:
+ // X11MoveLoopDelegate:
void OnMouseMovement(const gfx::Point& screen_point,
int flags,
base::TimeTicks event_time) override;
@@ -104,51 +93,15 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
void OnMoveLoopEnded() override;
protected:
- // The following methods are virtual for the sake of testing.
+ // Getter for tests.
+ Widget* drag_widget() { return drag_widget_.get(); }
- // Creates a move loop.
+ // Creates a move loop. Virtual for testing.
virtual std::unique_ptr<X11MoveLoop> CreateMoveLoop(
X11MoveLoopDelegate* delegate);
- // Finds the topmost X11 window at |screen_point| and returns it if it is
- // Xdnd aware. Returns NULL otherwise.
- virtual ::Window FindWindowFor(const gfx::Point& screen_point);
-
- // Sends |xev| to |xid|, optionally short circuiting the round trip to the X
- // server.
- virtual void SendXClientEvent(::Window xid, XEvent* xev);
-
- protected:
- Widget* drag_widget() { return drag_widget_.get(); }
-
private:
- enum class SourceState {
- // |source_current_window_| will receive a drop once we receive an
- // XdndStatus from it.
- kPendingDrop,
-
- // The move looped will be ended once we receive XdndFinished from
- // |source_current_window_|. We should not send XdndPosition to
- // |source_current_window_| while in this state.
- kDropped,
-
- // There is no drag in progress or there is a drag in progress and the
- // user has not yet released the mouse.
- kOther,
- };
-
- // Processes a mouse move at |screen_point|.
- void ProcessMouseMove(const gfx::Point& screen_point,
- unsigned long event_time);
-
- // Start timer to end the move loop if the target is too slow to respond after
- // the mouse is released.
- void StartEndMoveLoopTimer();
-
- // Ends the move loop.
- void EndMoveLoop();
-
- // When we receive an position x11 message, we need to translate that into
+ // When we receive a position X11 message, we need to translate that into
// the underlying aura::Window representation, as moves internal to the X11
// window can cause internal drag leave and enter messages.
void DragTranslate(const gfx::Point& root_window_location,
@@ -156,52 +109,20 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
std::unique_ptr<ui::DropTargetEvent>* event,
aura::client::DragDropDelegate** delegate);
- // Called when we need to notify the current aura::Window that we're no
- // longer dragging over it.
+ // Notifies |target_window_|'s drag delegate that we're no longer dragging,
+ // then unsubscribes |target_window_| from ourselves and forgets it.
void NotifyDragLeave();
- // Converts our bitfield of actions into an Atom that represents what action
- // we're most likely to take on drop.
- ::Atom DragOperationToAtom(int drag_operation);
-
- // Converts a single action atom to a drag operation.
- ui::DragDropTypes::DragOperation AtomToDragOperation(::Atom atom);
-
- // During the blocking StartDragAndDrop() call, this converts the views-style
- // |drag_operation_| bitfield into a vector of Atoms to offer to other
- // processes.
- std::vector< ::Atom> GetOfferedDragOperations();
-
- // This returns a representation of the data we're offering in this
- // drag. This is done to bypass an asynchronous roundtrip with the X11
- // server.
- ui::SelectionFormatMap GetFormatMap() const;
-
- // Returns the modifier state for the most recent mouse move. This is done to
- // bypass an asynchronous roundtrip with the X11 server.
- int current_modifier_state() const {
- return current_modifier_state_;
- }
-
- // Handling XdndPosition can be paused while waiting for more data; this is
- // called either synchronously from OnXdndPosition, or asynchronously after
- // we've received data requested from the other window.
- void CompleteXdndPosition(::Window source_window,
- const gfx::Point& screen_point);
-
- void SendXdndEnter(::Window dest_window);
- void SendXdndLeave(::Window dest_window);
- void SendXdndPosition(::Window dest_window,
- const gfx::Point& screen_point,
- unsigned long event_time);
- void SendXdndDrop(::Window dest_window);
-
- // Creates a widget for the user to drag around.
- void CreateDragWidget(const gfx::ImageSkia& image);
-
- // Returns true if |image| has any visible regions (defined as having a pixel
- // with alpha > 32).
- bool IsValidDragImage(const gfx::ImageSkia& image);
+ // ui::XDragDropClient::Delegate
+ std::unique_ptr<ui::XTopmostWindowFinder> CreateWindowFinder() override;
+ int UpdateDrag(const gfx::Point& screen_point) override;
+ void UpdateCursor(
+ ui::DragDropTypes::DragOperation negotiated_operation) override;
+ void OnBeginForeignDrag(XID window) override;
+ void OnEndForeignDrag() override;
+ void OnBeforeDragLeave() override;
+ int PerformDrop() override;
+ void EndMoveLoop() override;
// A nested run loop that notifies this object of events through the
// X11MoveLoopDelegate interface.
@@ -211,15 +132,8 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
DesktopNativeCursorManager* cursor_manager_;
- ::Display* xdisplay_;
- ::Window xwindow_;
-
- // Target side information.
- class X11DragContext;
- std::unique_ptr<X11DragContext> target_current_context_;
-
- // The modifier state for the most recent mouse move.
- int current_modifier_state_ = ui::EF_NONE;
+ // Events that we have selected on |source_window_|.
+ std::unique_ptr<ui::XScopedEventSelector> source_window_events_;
// The Aura window that is currently under the cursor. We need to manually
// keep track of this because Windows will only call our drag enter method
@@ -234,50 +148,12 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
gfx::Point target_window_location_;
gfx::Point target_window_root_location_;
- // In the Xdnd protocol, we aren't supposed to send another XdndPosition
- // message until we have received a confirming XdndStatus message.
- bool waiting_on_status_ = false;
-
- // If we would send an XdndPosition message while we're waiting for an
- // XdndStatus response, we need to cache the latest details we'd send.
- std::unique_ptr<std::pair<gfx::Point, unsigned long>> next_position_message_;
-
- // Reprocesses the most recent mouse move event if the mouse has not moved
- // in a while in case the window stacking order has changed and
- // |source_current_window_| needs to be updated.
- base::OneShotTimer repeat_mouse_move_timer_;
-
- // When the mouse is released, we need to wait for the last XdndStatus message
- // only if we have previously received a status message from
- // |source_current_window_|.
- bool status_received_since_enter_ = false;
-
- // Source side information.
- ui::OSExchangeDataProviderAuraX11 const* source_provider_ = nullptr;
- ::Window source_current_window_ = x11::None;
- SourceState source_state_ = SourceState::kOther;
-
// The current drag-drop client that has an active operation. Since we have
// multiple root windows and multiple DesktopDragDropClientAuraX11 instances
// it is important to maintain only one drag and drop operation at any time.
static DesktopDragDropClientAuraX11* g_current_drag_drop_client;
- // The operation bitfield as requested by StartDragAndDrop.
- int drag_operation_ = 0;
-
- // We offer the other window a list of possible operations,
- // XdndActionsList. This is the requested action from the other window. This
- // is DRAG_NONE if we haven't sent out an XdndPosition message yet, haven't
- // yet received an XdndStatus or if the other window has told us that there's
- // no action that we can agree on.
- ui::DragDropTypes::DragOperation negotiated_operation_ =
- ui::DragDropTypes::DRAG_NONE;
-
- // Ends the move loop if the target is too slow to respond after the mouse is
- // released.
- base::OneShotTimer end_move_loop_timer_;
-
- // Widget that the user drags around. May be NULL.
+ // Widget that the user drags around. May be nullptr.
std::unique_ptr<Widget> drag_widget_;
// The size of drag image.
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
index e81a78ca57b..b188e6c9a40 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
@@ -4,12 +4,9 @@
#include <map>
#include <memory>
+#include <utility>
#include <vector>
-// Include views_test_base.h first because the definition of None in X.h
-// conflicts with the definition of None in gtest-type-util.h
-#include "ui/views/test/views_test_base.h"
-
#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
@@ -28,6 +25,7 @@
#include "ui/gfx/x/x11.h"
#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/gfx/x/x11_types.h"
+#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h"
#include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
@@ -48,9 +46,7 @@ class ClientMessageEventCollector {
virtual ~ClientMessageEventCollector();
// Returns true if |events_| is non-empty.
- bool HasEvents() const {
- return !events_.empty();
- }
+ bool HasEvents() const { return !events_.empty(); }
// Pops all of |events_| and returns the popped events in the order that they
// were on the stack
@@ -140,16 +136,13 @@ class TestDragDropClient : public SimpleTestDragDropClient {
~TestDragDropClient() override;
// Returns the XID of the window which initiated the drag.
- ::Window source_xwindow() {
- return source_xid_;
- }
+ ::Window source_xwindow() { return source_xid_; }
// Returns the Atom with |name|.
Atom GetAtom(const char* name);
// Returns true if the event's message has |type|.
- bool MessageHasType(const XClientMessageEvent& event,
- const char* type);
+ bool MessageHasType(const XClientMessageEvent& event, const char* type);
// Sets |collector| to collect XClientMessageEvents which would otherwise
// have been sent to the drop target window.
@@ -181,7 +174,7 @@ class TestDragDropClient : public SimpleTestDragDropClient {
// Map of ::Windows to the collector which intercepts XClientMessageEvents
// for that window.
- std::map< ::Window, ClientMessageEventCollector*> collectors_;
+ std::map<::Window, ClientMessageEventCollector*> collectors_;
DISALLOW_COPY_AND_ASSIGN(TestDragDropClient);
};
@@ -192,8 +185,7 @@ class TestDragDropClient : public SimpleTestDragDropClient {
ClientMessageEventCollector::ClientMessageEventCollector(
::Window xid,
TestDragDropClient* client)
- : xid_(xid),
- client_(client) {
+ : xid_(xid), client_(client) {
client->SetEventCollectorFor(xid, this);
}
@@ -224,9 +216,7 @@ bool TestMoveLoop::IsRunning() const {
return is_running_;
}
-bool TestMoveLoop::RunMoveLoop(
- aura::Window* window,
- gfx::NativeCursor cursor) {
+bool TestMoveLoop::RunMoveLoop(aura::Window* window, gfx::NativeCursor cursor) {
is_running_ = true;
base::RunLoop run_loop;
quit_closure_ = run_loop.QuitClosure();
@@ -234,8 +224,7 @@ bool TestMoveLoop::RunMoveLoop(
return true;
}
-void TestMoveLoop::UpdateCursor(gfx::NativeCursor cursor) {
-}
+void TestMoveLoop::UpdateCursor(gfx::NativeCursor cursor) {}
void TestMoveLoop::EndMoveLoop() {
if (is_running_) {
@@ -397,9 +386,7 @@ class DesktopDragDropClientAuraX11Test : public ViewsTestBase {
ViewsTestBase::TearDown();
}
- TestDragDropClient* client() {
- return client_.get();
- }
+ TestDragDropClient* client() { return client_.get(); }
private:
std::unique_ptr<TestDragDropClient> client_;
@@ -425,17 +412,15 @@ void BasicStep2(TestDragDropClient* client, XID toplevel) {
ASSERT_EQ(2u, events.size());
EXPECT_TRUE(client->MessageHasType(events[0], "XdndEnter"));
- EXPECT_EQ(client->source_xwindow(),
- static_cast<XID>(events[0].data.l[0]));
+ EXPECT_EQ(client->source_xwindow(), static_cast<XID>(events[0].data.l[0]));
EXPECT_EQ(1, events[0].data.l[1] & 1);
std::vector<Atom> targets;
ui::GetAtomArrayProperty(client->source_xwindow(), "XdndTypeList", &targets);
EXPECT_FALSE(targets.empty());
EXPECT_TRUE(client->MessageHasType(events[1], "XdndPosition"));
- EXPECT_EQ(client->source_xwindow(),
- static_cast<XID>(events[0].data.l[0]));
- const long kCoords =
+ EXPECT_EQ(client->source_xwindow(), static_cast<XID>(events[0].data.l[0]));
+ const int kCoords =
TestDragDropClient::kMouseMoveX << 16 | TestDragDropClient::kMouseMoveY;
EXPECT_EQ(kCoords, events[1].data.l[2]);
EXPECT_EQ(client->GetAtom("XdndActionCopy"),
@@ -450,8 +435,7 @@ void BasicStep2(TestDragDropClient* client, XID toplevel) {
events = collector.PopAllEvents();
ASSERT_EQ(1u, events.size());
EXPECT_TRUE(client->MessageHasType(events[0], "XdndDrop"));
- EXPECT_EQ(client->source_xwindow(),
- static_cast<XID>(events[0].data.l[0]));
+ EXPECT_EQ(client->source_xwindow(), static_cast<XID>(events[0].data.l[0]));
// Send XdndFinished to indicate that the drag drop client can cleanup any
// data related to this drag. The move loop should end only after the
@@ -793,9 +777,7 @@ class TestDragDropDelegate : public aura::client::DragDropDelegate {
return ui::DragDropTypes::DRAG_COPY;
}
- void OnDragExited() override {
- ++num_exits_;
- }
+ void OnDragExited() override { ++num_exits_; }
int OnPerformDrop(const ui::DropTargetEvent& event,
std::unique_ptr<OSExchangeData> data) override {
@@ -864,9 +846,7 @@ class DesktopDragDropClientAuraX11ChromeSourceTargetTest
ViewsTestBase::TearDown();
}
- SimpleTestDragDropClient* client() {
- return client_.get();
- }
+ SimpleTestDragDropClient* client() { return client_.get(); }
private:
std::unique_ptr<SimpleTestDragDropClient> client_;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc
index 7f08e6a6141..1ed740d20ce 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc
@@ -5,6 +5,7 @@
#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h"
#include <memory>
+#include <utility>
#include "base/bind.h"
#include "base/run_loop.h"
@@ -20,6 +21,7 @@
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
+#include "ui/base/mojom/cursor_type.mojom-shared.h"
#include "ui/platform_window/platform_window_delegate.h"
#include "ui/platform_window/platform_window_handler/wm_drag_handler.h"
#include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
@@ -78,7 +80,7 @@ int DesktopDragDropClientOzone::StartDragAndDrop(
initial_cursor_ = source_window->GetHost()->last_cursor();
drag_operation_ = operation;
cursor_client->SetCursor(
- cursor_manager_->GetInitializedCursor(ui::CursorType::kGrabbing));
+ cursor_manager_->GetInitializedCursor(ui::mojom::CursorType::kGrabbing));
drag_handler_->StartDrag(
*data.get(), operation, cursor_client->GetCursor(),
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc
index 984d4098eff..806e4a883a0 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc
@@ -4,6 +4,8 @@
#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h"
+#include <memory>
+
#include "base/metrics/histogram_macros.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/drag_source_win.h"
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
index 9e6208cb096..74c40adff7e 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
@@ -7,6 +7,8 @@
#include <wrl/client.h>
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc
index 052d82cbea1..a1703ed51c4 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc
@@ -4,6 +4,8 @@
#include "ui/views/widget/desktop_aura/desktop_drop_target_win.h"
+#include <utility>
+
#include "base/metrics/histogram_macros.h"
#include "base/win/win_util.h"
#include "ui/aura/client/drag_drop_client.h"
@@ -22,8 +24,7 @@ using ui::OSExchangeDataProviderWin;
namespace {
-int ConvertKeyStateToAuraEventFlags(DWORD key_state)
-{
+int ConvertKeyStateToAuraEventFlags(DWORD key_state) {
int flags = 0;
if (key_state & MK_CONTROL)
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.h b/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.h
index f13016028f1..88b92c66cc1 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.h
@@ -15,12 +15,12 @@ namespace aura {
namespace client {
class DragDropDelegate;
}
-}
+} // namespace aura
namespace ui {
class DropTargetEvent;
class OSExchangeData;
-}
+} // namespace ui
namespace views {
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_focus_rules.cc b/chromium/ui/views/widget/desktop_aura/desktop_focus_rules.cc
index ec25062629a..22339eed132 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_focus_rules.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_focus_rules.cc
@@ -51,7 +51,7 @@ bool DesktopFocusRules::IsWindowConsideredVisibleForActivation(
// |content_window_| is initially hidden and made visible from Show(). Even in
// this state we still want it to be activatable.
return BaseFocusRules::IsWindowConsideredVisibleForActivation(window) ||
- (window == content_window_);
+ (window == content_window_);
}
const aura::Window* DesktopFocusRules::GetToplevelWindow(
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
index d33e3209023..478b16bc606 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
@@ -9,6 +9,7 @@
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/cursor/cursor_loader.h"
+#include "ui/base/mojom/cursor_type.mojom-shared.h"
namespace views {
@@ -18,7 +19,7 @@ DesktopNativeCursorManager::DesktopNativeCursorManager()
DesktopNativeCursorManager::~DesktopNativeCursorManager() = default;
gfx::NativeCursor DesktopNativeCursorManager::GetInitializedCursor(
- ui::CursorType type) {
+ ui::mojom::CursorType type) {
gfx::NativeCursor cursor(type);
cursor_loader_->SetPlatformCursor(&cursor);
return cursor;
@@ -63,7 +64,7 @@ void DesktopNativeCursorManager::SetVisibility(
if (visible) {
SetCursor(delegate->GetCursor(), delegate);
} else {
- gfx::NativeCursor invisible_cursor(ui::CursorType::kNone);
+ gfx::NativeCursor invisible_cursor(ui::mojom::CursorType::kNone);
cursor_loader_->SetPlatformCursor(&invisible_cursor);
for (auto* host : hosts_)
host->SetCursor(invisible_cursor);
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h b/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
index 31cf5781ab5..fdb5d86b797 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
@@ -10,6 +10,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
+#include "ui/base/mojom/cursor_type.mojom-forward.h"
#include "ui/views/views_export.h"
#include "ui/wm/core/native_cursor_manager.h"
@@ -30,15 +31,14 @@ namespace views {
// A NativeCursorManager that performs the desktop-specific setting of cursor
// state. Similar to NativeCursorManagerAsh, it also communicates these changes
// to all root windows.
-class VIEWS_EXPORT DesktopNativeCursorManager
- : public wm::NativeCursorManager {
+class VIEWS_EXPORT DesktopNativeCursorManager : public wm::NativeCursorManager {
public:
DesktopNativeCursorManager();
~DesktopNativeCursorManager() override;
// Builds a cursor and sets the internal platform representation. The return
// value should not be cached.
- gfx::NativeCursor GetInitializedCursor(ui::CursorType type);
+ gfx::NativeCursor GetInitializedCursor(ui::mojom::CursorType type);
// Adds |host| to the set |hosts_|.
void AddHost(aura::WindowTreeHost* host);
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index 541a8197e4c..7578eef4f53 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -5,6 +5,7 @@
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#include <memory>
+#include <utility>
#include "base/auto_reset.h"
#include "base/bind.h"
@@ -110,9 +111,8 @@ class DesktopNativeWidgetTopLevelHandler : public aura::WindowObserver {
init_params.bounds = bounds;
init_params.ownership = Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET;
init_params.layer_type = ui::LAYER_NOT_DRAWN;
- init_params.activatable = full_screen ?
- Widget::InitParams::ACTIVATABLE_YES :
- Widget::InitParams::ACTIVATABLE_NO;
+ init_params.activatable = full_screen ? Widget::InitParams::ACTIVATABLE_YES
+ : Widget::InitParams::ACTIVATABLE_NO;
init_params.z_order = root_z_order;
// This widget instance will get deleted when the window is
@@ -143,8 +143,7 @@ class DesktopNativeWidgetTopLevelHandler : public aura::WindowObserver {
// If the widget is being destroyed by the OS then we should not try and
// destroy it again.
- if (top_level_widget_ &&
- window == top_level_widget_->GetNativeView()) {
+ if (top_level_widget_ && window == top_level_widget_->GetNativeView()) {
top_level_widget_ = nullptr;
return;
}
@@ -199,7 +198,7 @@ class DesktopNativeWidgetAuraWindowParentingClient
aura::Window* GetDefaultParent(aura::Window* window,
const gfx::Rect& bounds) override {
bool is_fullscreen = window->GetProperty(aura::client::kShowStateKey) ==
- ui::SHOW_STATE_FULLSCREEN;
+ ui::SHOW_STATE_FULLSCREEN;
bool is_menu = window->type() == aura::client::WINDOW_TYPE_MENU;
if (is_fullscreen || is_menu) {
@@ -226,7 +225,7 @@ class DesktopNativeWidgetAuraWindowParentingClient
class RootWindowDestructionObserver : public aura::WindowObserver {
public:
explicit RootWindowDestructionObserver(DesktopNativeWidgetAura* parent)
- : parent_(parent) {}
+ : parent_(parent) {}
~RootWindowDestructionObserver() override = default;
private:
@@ -482,7 +481,7 @@ void DesktopNativeWidgetAura::InitNativeWidget(Widget::InitParams params) {
}
host_.reset(desktop_window_tree_host_->AsWindowTreeHost());
}
- desktop_window_tree_host_->Init(std::move(params));
+ desktop_window_tree_host_->Init(params);
host_->window()->AddChild(content_window_);
host_->window()->SetProperty(kDesktopNativeWidgetAuraKey, this);
@@ -540,8 +539,8 @@ void DesktopNativeWidgetAura::InitNativeWidget(Widget::InitParams params) {
position_client_ = desktop_window_tree_host_->CreateScreenPositionClient();
- drag_drop_client_ = desktop_window_tree_host_->CreateDragDropClient(
- native_cursor_manager_);
+ drag_drop_client_ =
+ desktop_window_tree_host_->CreateDragDropClient(native_cursor_manager_);
// Mus returns null from CreateDragDropClient().
if (drag_drop_client_)
aura::client::SetDragDropClient(host_->window(), drag_drop_client_.get());
@@ -686,7 +685,7 @@ void DesktopNativeWidgetAura::ReleaseCapture() {
bool DesktopNativeWidgetAura::HasCapture() const {
return content_window_ && content_window_->HasCapture() &&
- desktop_window_tree_host_->HasCapture();
+ desktop_window_tree_host_->HasCapture();
}
ui::InputMethod* DesktopNativeWidgetAura::GetInputMethod() {
@@ -699,8 +698,8 @@ void DesktopNativeWidgetAura::CenterWindow(const gfx::Size& size) {
}
void DesktopNativeWidgetAura::GetWindowPlacement(
- gfx::Rect* bounds,
- ui::WindowShowState* maximized) const {
+ gfx::Rect* bounds,
+ ui::WindowShowState* maximized) const {
if (content_window_)
desktop_window_tree_host_->GetWindowPlacement(bounds, maximized);
}
@@ -728,23 +727,24 @@ void DesktopNativeWidgetAura::InitModalType(ui::ModalType modal_type) {
}
gfx::Rect DesktopNativeWidgetAura::GetWindowBoundsInScreen() const {
- return content_window_ ?
- desktop_window_tree_host_->GetWindowBoundsInScreen() : gfx::Rect();
+ return content_window_ ? desktop_window_tree_host_->GetWindowBoundsInScreen()
+ : gfx::Rect();
}
gfx::Rect DesktopNativeWidgetAura::GetClientAreaBoundsInScreen() const {
- return content_window_ ?
- desktop_window_tree_host_->GetClientAreaBoundsInScreen() : gfx::Rect();
+ return content_window_
+ ? desktop_window_tree_host_->GetClientAreaBoundsInScreen()
+ : gfx::Rect();
}
gfx::Rect DesktopNativeWidgetAura::GetRestoredBounds() const {
- return content_window_ ?
- desktop_window_tree_host_->GetRestoredBounds() : gfx::Rect();
+ return content_window_ ? desktop_window_tree_host_->GetRestoredBounds()
+ : gfx::Rect();
}
std::string DesktopNativeWidgetAura::GetWorkspace() const {
- return content_window_ ?
- desktop_window_tree_host_->GetWorkspace() : std::string();
+ return content_window_ ? desktop_window_tree_host_->GetWorkspace()
+ : std::string();
}
void DesktopNativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
@@ -963,14 +963,15 @@ void DesktopNativeWidgetAura::ClearNativeFocus() {
desktop_window_tree_host_->ClearNativeFocus();
if (ShouldActivate()) {
- aura::client::GetFocusClient(content_window_)->
- ResetFocusWithinActiveWindow(content_window_);
+ aura::client::GetFocusClient(content_window_)
+ ->ResetFocusWithinActiveWindow(content_window_);
}
}
gfx::Rect DesktopNativeWidgetAura::GetWorkAreaBoundsInScreen() const {
- return desktop_window_tree_host_ ?
- desktop_window_tree_host_->GetWorkAreaBoundsInScreen() : gfx::Rect();
+ return desktop_window_tree_host_
+ ? desktop_window_tree_host_->GetWorkAreaBoundsInScreen()
+ : gfx::Rect();
}
Widget::MoveLoopResult DesktopNativeWidgetAura::RunMoveLoop(
@@ -1021,7 +1022,7 @@ void DesktopNativeWidgetAura::SetVisibilityAnimationTransition(
bool DesktopNativeWidgetAura::IsTranslucentWindowOpacitySupported() const {
return content_window_ &&
- desktop_window_tree_host_->IsTranslucentWindowOpacitySupported();
+ desktop_window_tree_host_->IsTranslucentWindowOpacitySupported();
}
ui::GestureRecognizer* DesktopNativeWidgetAura::GetGestureRecognizer() {
@@ -1034,6 +1035,10 @@ void DesktopNativeWidgetAura::OnSizeConstraintsChanged() {
desktop_window_tree_host_->SizeConstraintsChanged();
}
+void DesktopNativeWidgetAura::OnNativeViewHierarchyWillChange() {}
+
+void DesktopNativeWidgetAura::OnNativeViewHierarchyChanged() {}
+
std::string DesktopNativeWidgetAura::GetName() const {
return name_;
}
@@ -1059,8 +1064,8 @@ int DesktopNativeWidgetAura::GetNonClientComponent(
}
bool DesktopNativeWidgetAura::ShouldDescendIntoChildForEventHandling(
- aura::Window* child,
- const gfx::Point& location) {
+ aura::Window* child,
+ const gfx::Point& location) {
return native_widget_delegate_->ShouldDescendIntoChildForEventHandling(
content_window_->layer(), child, child->layer(), location);
}
@@ -1091,8 +1096,7 @@ void DesktopNativeWidgetAura::OnWindowDestroyed(aura::Window* window) {
// here.
}
-void DesktopNativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) {
-}
+void DesktopNativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) {}
bool DesktopNativeWidgetAura::HasHitTestMask() const {
return native_widget_delegate_->HasHitTestMask();
@@ -1205,14 +1209,14 @@ void DesktopNativeWidgetAura::OnWindowFocused(aura::Window* gained_focus,
void DesktopNativeWidgetAura::OnDragEntered(const ui::DropTargetEvent& event) {
DCHECK(drop_helper_.get() != nullptr);
- last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
- event.location(), event.source_operations());
+ last_drop_operation_ = drop_helper_->OnDragOver(
+ event.data(), event.location(), event.source_operations());
}
int DesktopNativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent& event) {
DCHECK(drop_helper_.get() != nullptr);
- last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
- event.location(), event.source_operations());
+ last_drop_operation_ = drop_helper_->OnDragOver(
+ event.data(), event.location(), event.source_operations());
return last_drop_operation_;
}
@@ -1228,7 +1232,7 @@ int DesktopNativeWidgetAura::OnPerformDrop(
if (ShouldActivate())
Activate();
return drop_helper_->OnDrop(event.data(), event.location(),
- last_drop_operation_);
+ last_drop_operation_);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
index 4e47c9230f8..89f7d22cbcb 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -5,6 +5,7 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_NATIVE_WIDGET_AURA_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_NATIVE_WIDGET_AURA_H_
+#include <memory>
#include <string>
#include "base/macros.h"
@@ -26,8 +27,8 @@ namespace client {
class DragDropClient;
class ScreenPositionClient;
class WindowParentingClient;
-}
-}
+} // namespace client
+} // namespace aura
namespace wm {
class CompoundEventFilter;
@@ -36,7 +37,7 @@ class FocusController;
class ShadowController;
class VisibilityController;
class WindowModalityController;
-}
+} // namespace wm
namespace views {
namespace corewm {
@@ -87,9 +88,7 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
wm::CompoundEventFilter* root_window_event_filter() {
return root_window_event_filter_.get();
}
- aura::WindowTreeHost* host() {
- return host_.get();
- }
+ aura::WindowTreeHost* host() { return host_.get(); }
aura::Window* content_window() { return content_window_; }
@@ -107,7 +106,7 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
void UpdateWindowTransparency();
protected:
- // Overridden from internal::NativeWidgetPrivate:
+ // internal::NativeWidgetPrivate:
void InitNativeWidget(Widget::InitParams params) override;
void OnWidgetInitDone() override;
NonClientFrameView* CreateNonClientFrameView() override;
@@ -195,9 +194,11 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
bool IsTranslucentWindowOpacitySupported() const override;
ui::GestureRecognizer* GetGestureRecognizer() override;
void OnSizeConstraintsChanged() override;
+ void OnNativeViewHierarchyWillChange() override;
+ void OnNativeViewHierarchyChanged() override;
std::string GetName() const override;
- // Overridden from aura::WindowDelegate:
+ // aura::WindowDelegate:
gfx::Size GetMinimumSize() const override;
gfx::Size GetMaximumSize() const override;
void OnBoundsChanged(const gfx::Rect& old_bounds,
@@ -219,32 +220,32 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
void GetHitTestMask(SkPath* mask) const override;
void UpdateVisualState() override;
- // Overridden from ui::EventHandler:
+ // ui::EventHandler:
void OnKeyEvent(ui::KeyEvent* event) override;
void OnMouseEvent(ui::MouseEvent* event) override;
void OnScrollEvent(ui::ScrollEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
- // Overridden from wm::ActivationDelegate:
+ // wm::ActivationDelegate:
bool ShouldActivate() const override;
- // Overridden from wm::ActivationChangeObserver:
+ // wm::ActivationChangeObserver:
void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override;
- // Overridden from aura::client::FocusChangeObserver:
+ // aura::client::FocusChangeObserver:
void OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) override;
- // Overridden from aura::client::DragDropDelegate:
+ // ura::client::DragDropDelegate:
void OnDragEntered(const ui::DropTargetEvent& event) override;
int OnDragUpdated(const ui::DropTargetEvent& event) override;
void OnDragExited() override;
int OnPerformDrop(const ui::DropTargetEvent& event,
std::unique_ptr<ui::OSExchangeData> data) override;
- // Overridden from aura::WindowTreeHostObserver:
+ // aura::WindowTreeHostObserver:
void OnHostCloseRequested(aura::WindowTreeHost* host) override;
void OnHostResized(aura::WindowTreeHost* host) override;
void OnHostWorkspaceChanged(aura::WindowTreeHost* host) override;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
index e3bfa420e30..a28f778d4a5 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
@@ -4,6 +4,9 @@
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
+#include <memory>
+#include <utility>
+
#include "base/bind.h"
#include "base/macros.h"
#include "base/run_loop.h"
@@ -19,6 +22,7 @@
#include "ui/aura/test/window_occlusion_tracker_test_api.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
+#include "ui/base/mojom/cursor_type.mojom-shared.h"
#include "ui/display/screen.h"
#include "ui/events/event_processor.h"
#include "ui/events/event_utils.h"
@@ -66,8 +70,7 @@ TEST_F(DesktopNativeWidgetAuraTest, DesktopAuraWindowSizeTest) {
// On Linux we test this with popup windows because the WM may ignore the size
// suggestion for normal windows.
#if defined(OS_LINUX)
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_POPUP);
+ Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
#else
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
@@ -220,14 +223,14 @@ TEST_F(DesktopNativeWidgetAuraTest, MAYBE_GlobalCursorState) {
// Verify that setting the cursor using one cursor client
// will set it for all root windows.
- EXPECT_EQ(ui::CursorType::kNone, cursor_client_a->GetCursor().native_type());
- EXPECT_EQ(ui::CursorType::kNone, cursor_client_b->GetCursor().native_type());
+ EXPECT_EQ(ui::mojom::CursorType::kNone, cursor_client_a->GetCursor().type());
+ EXPECT_EQ(ui::mojom::CursorType::kNone, cursor_client_b->GetCursor().type());
- cursor_client_b->SetCursor(ui::CursorType::kPointer);
- EXPECT_EQ(ui::CursorType::kPointer,
- cursor_client_a->GetCursor().native_type());
- EXPECT_EQ(ui::CursorType::kPointer,
- cursor_client_b->GetCursor().native_type());
+ cursor_client_b->SetCursor(ui::mojom::CursorType::kPointer);
+ EXPECT_EQ(ui::mojom::CursorType::kPointer,
+ cursor_client_a->GetCursor().type());
+ EXPECT_EQ(ui::mojom::CursorType::kPointer,
+ cursor_client_b->GetCursor().type());
// Verify that hiding the cursor using one cursor client will
// hide it for all root windows. Note that hiding the cursor
@@ -405,8 +408,7 @@ class DesktopAuraTopLevelWindowTest : public aura::WindowObserver {
}
owned_window_->Init(ui::LAYER_TEXTURED);
aura::client::ParentWindowWithContext(
- owned_window_,
- widget_.GetNativeView()->GetRootWindow(),
+ owned_window_, widget_.GetNativeView()->GetRootWindow(),
gfx::Rect(0, 0, 1900, 1600));
owned_window_->Show();
owned_window_->AddObserver(this);
@@ -447,17 +449,11 @@ class DesktopAuraTopLevelWindowTest : public aura::WindowObserver {
}
}
- aura::Window* owned_window() {
- return owned_window_;
- }
+ aura::Window* owned_window() { return owned_window_; }
- views::Widget* top_level_widget() {
- return top_level_widget_;
- }
+ views::Widget* top_level_widget() { return top_level_widget_; }
- void set_use_async_mode(bool async_mode) {
- use_async_mode_ = async_mode;
- }
+ void set_use_async_mode(bool async_mode) { use_async_mode_ = async_mode; }
private:
views::Widget widget_;
@@ -477,8 +473,8 @@ using DesktopAuraWidgetTest = DesktopWidgetTest;
TEST_F(DesktopAuraWidgetTest, FullscreenWindowDestroyedBeforeOwnerTest) {
DesktopAuraTopLevelWindowTest fullscreen_window;
- ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow(
- gfx::Rect(0, 0, 200, 200), true));
+ ASSERT_NO_FATAL_FAILURE(
+ fullscreen_window.CreateTopLevelWindow(gfx::Rect(0, 0, 200, 200), true));
RunPendingMessages();
ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnedWindow());
@@ -487,8 +483,8 @@ TEST_F(DesktopAuraWidgetTest, FullscreenWindowDestroyedBeforeOwnerTest) {
TEST_F(DesktopAuraWidgetTest, FullscreenWindowOwnerDestroyed) {
DesktopAuraTopLevelWindowTest fullscreen_window;
- ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow(
- gfx::Rect(0, 0, 200, 200), true));
+ ASSERT_NO_FATAL_FAILURE(
+ fullscreen_window.CreateTopLevelWindow(gfx::Rect(0, 0, 200, 200), true));
RunPendingMessages();
ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnerWindow());
@@ -497,8 +493,8 @@ TEST_F(DesktopAuraWidgetTest, FullscreenWindowOwnerDestroyed) {
TEST_F(DesktopAuraWidgetTest, TopLevelOwnedPopupTest) {
DesktopAuraTopLevelWindowTest popup_window;
- ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow(
- gfx::Rect(0, 0, 200, 200), false));
+ ASSERT_NO_FATAL_FAILURE(
+ popup_window.CreateTopLevelWindow(gfx::Rect(0, 0, 200, 200), false));
RunPendingMessages();
ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow());
@@ -512,8 +508,8 @@ TEST_F(DesktopAuraWidgetTest, TopLevelOwnedPopupResizeTest) {
popup_window.set_use_async_mode(false);
- ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow(
- gfx::Rect(0, 0, 200, 200), false));
+ ASSERT_NO_FATAL_FAILURE(
+ popup_window.CreateTopLevelWindow(gfx::Rect(0, 0, 200, 200), false));
gfx::Rect new_size(0, 0, 400, 400);
popup_window.owned_window()->SetBounds(new_size);
@@ -531,8 +527,8 @@ TEST_F(DesktopAuraWidgetTest, TopLevelOwnedPopupRepositionTest) {
popup_window.set_use_async_mode(false);
- ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow(
- gfx::Rect(0, 0, 200, 200), false));
+ ASSERT_NO_FATAL_FAILURE(
+ popup_window.CreateTopLevelWindow(gfx::Rect(0, 0, 200, 200), false));
gfx::Rect new_pos(10, 10, 400, 400);
popup_window.owned_window()->SetBoundsInScreen(
@@ -733,9 +729,7 @@ TEST_F(DesktopWidgetTest, WindowModalityActivationTest) {
EXPECT_TRUE(modal_dialog_widget->IsVisible());
LRESULT activate_result = ::SendMessage(
- win32_window,
- WM_MOUSEACTIVATE,
- reinterpret_cast<WPARAM>(win32_window),
+ win32_window, WM_MOUSEACTIVATE, reinterpret_cast<WPARAM>(win32_window),
MAKELPARAM(WM_LBUTTONDOWN, HTCLIENT));
EXPECT_EQ(activate_result, MA_ACTIVATE);
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.cc
index b889969ec97..2406d29e9b4 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.cc
@@ -22,15 +22,7 @@ bool PositionWindowInScreenCoordinates(aura::Window* window) {
} // namespace
-DesktopScreenPositionClient::DesktopScreenPositionClient(
- aura::Window* root_window)
- : root_window_(root_window) {
- aura::client::SetScreenPositionClient(root_window_, this);
-}
-
-DesktopScreenPositionClient::~DesktopScreenPositionClient() {
- aura::client::SetScreenPositionClient(root_window_, nullptr);
-}
+DesktopScreenPositionClient::~DesktopScreenPositionClient() = default;
void DesktopScreenPositionClient::SetBounds(aura::Window* window,
const gfx::Rect& bounds,
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.h b/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.h
index 33fbdc2ef8d..586ac072643 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.h
@@ -16,7 +16,7 @@ namespace views {
class VIEWS_EXPORT DesktopScreenPositionClient
: public wm::DefaultScreenPositionClient {
public:
- explicit DesktopScreenPositionClient(aura::Window* root_window);
+ using DefaultScreenPositionClient::DefaultScreenPositionClient;
~DesktopScreenPositionClient() override;
// aura::client::DefaultScreenPositionClient:
@@ -25,8 +25,6 @@ class VIEWS_EXPORT DesktopScreenPositionClient
const display::Display& display) override;
private:
- aura::Window* root_window_;
-
DISALLOW_COPY_AND_ASSIGN(DesktopScreenPositionClient);
};
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h b/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h
index 87299feba93..e17fe7611d7 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h
@@ -12,7 +12,7 @@
namespace views {
class VIEWS_EXPORT DesktopScreenWin : public display::win::ScreenWin {
-public:
+ public:
DesktopScreenWin();
~DesktopScreenWin() override;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc
index 6ca1be4cc9e..0ffdc450043 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -4,6 +4,8 @@
#include "ui/views/widget/desktop_aura/desktop_screen_x11.h"
+#include <vector>
+
#include "base/command_line.h"
#include "base/trace_event/trace_event.h"
#include "ui/aura/window.h"
@@ -15,72 +17,41 @@
#include "ui/display/display.h"
#include "ui/display/display_finder.h"
#include "ui/display/util/display_util.h"
-#include "ui/events/platform/platform_event_source.h"
-#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/gfx/font_render_params.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/switches.h"
-#include "ui/views/linux_ui/linux_ui.h"
#include "ui/views/widget/desktop_aura/desktop_screen.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
-namespace {
-
-float GetDeviceScaleFactor() {
- float device_scale_factor = 1.0f;
- if (views::LinuxUI::instance()) {
- device_scale_factor = views::LinuxUI::instance()->GetDeviceScaleFactor();
- } else if (display::Display::HasForceDeviceScaleFactor()) {
- device_scale_factor = display::Display::GetForcedDeviceScaleFactor();
- }
- return device_scale_factor;
-}
-
-} // namespace
-
namespace views {
-////////////////////////////////////////////////////////////////////////////////
-// DesktopScreenX11, public:
-
-DesktopScreenX11::DesktopScreenX11()
- : x11_display_manager_(std::make_unique<ui::XDisplayManager>(this)) {
- if (auto* linux_ui = views::LinuxUI::instance())
- linux_ui->AddDeviceScaleFactorObserver(this);
+DesktopScreenX11::DesktopScreenX11() {
+ if (LinuxUI::instance())
+ display_scale_factor_observer_.Add(LinuxUI::instance());
}
-DesktopScreenX11::~DesktopScreenX11() {
- if (auto* linux_ui = views::LinuxUI::instance())
- linux_ui->RemoveDeviceScaleFactorObserver(this);
- if (x11_display_manager_->IsXrandrAvailable() &&
- ui::PlatformEventSource::GetInstance()) {
- ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
- }
-}
+DesktopScreenX11::~DesktopScreenX11() = default;
void DesktopScreenX11::Init() {
if (x11_display_manager_->IsXrandrAvailable() &&
- ui::PlatformEventSource::GetInstance()) {
- ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
- }
+ ui::X11EventSource::HasInstance())
+ event_source_observer_.Add(ui::X11EventSource::GetInstance());
x11_display_manager_->Init();
}
-////////////////////////////////////////////////////////////////////////////////
-// DesktopScreenX11, display::Screen implementation:
-
gfx::Point DesktopScreenX11::GetCursorScreenPoint() {
TRACE_EVENT0("views", "DesktopScreenX11::GetCursorScreenPoint()");
- if (auto* event_source = ui::X11EventSource::GetInstance()) {
- auto point = event_source->GetRootCursorLocationFromCurrentEvent();
- if (point)
- return gfx::ConvertPointToDIP(GetDeviceScaleFactor(), point.value());
- }
- return gfx::ConvertPointToDIP(GetDeviceScaleFactor(),
- x11_display_manager_->GetCursorLocation());
+ base::Optional<gfx::Point> point;
+ if (const auto* const event_source = ui::X11EventSource::GetInstance())
+ point = event_source->GetRootCursorLocationFromCurrentEvent();
+ return gfx::ConvertPointToDIP(
+ GetXDisplayScaleFactor(),
+ // NB: Do NOT call value_or() here, since that would defeat the purpose of
+ // caching |point|.
+ point ? point.value() : x11_display_manager_->GetCursorLocation());
}
bool DesktopScreenX11::IsWindowUnderCursor(gfx::NativeWindow window) {
@@ -89,13 +60,12 @@ bool DesktopScreenX11::IsWindowUnderCursor(gfx::NativeWindow window) {
gfx::NativeWindow DesktopScreenX11::GetWindowAtScreenPoint(
const gfx::Point& point) {
- X11TopmostWindowFinder finder;
- return finder.FindLocalProcessWindowAt(
- gfx::ConvertPointToPixel(GetDeviceScaleFactor(), point), {});
+ return X11TopmostWindowFinder().FindLocalProcessWindowAt(
+ gfx::ConvertPointToPixel(GetXDisplayScaleFactor(), point), {});
}
int DesktopScreenX11::GetNumDisplays() const {
- return x11_display_manager_->displays().size();
+ return int{x11_display_manager_->displays().size()};
}
const std::vector<display::Display>& DesktopScreenX11::GetAllDisplays() const {
@@ -104,9 +74,6 @@ const std::vector<display::Display>& DesktopScreenX11::GetAllDisplays() const {
display::Display DesktopScreenX11::GetDisplayNearestWindow(
gfx::NativeView window) const {
- if (!window)
- return GetPrimaryDisplay();
-
// Getting screen bounds here safely is hard.
//
// You'd think we'd be able to just call window->GetBoundsInScreen(), but we
@@ -116,15 +83,14 @@ display::Display DesktopScreenX11::GetDisplayNearestWindow(
// created before we create the aura::WindowEventDispatcher. So we ask what
// the DRWHX11 believes the window bounds are instead of going through the
// aura::Window's screen bounds.
- aura::WindowTreeHost* host = window->GetHost();
- if (host) {
- auto* rwh = DesktopWindowTreeHostLinux::GetHostForWidget(
- host->GetAcceleratedWidget());
- if (rwh) {
- const gfx::Rect pixel_rect = rwh->GetBoundsInPixels();
- const gfx::Rect dip_rect =
- gfx::ConvertRectToDIP(GetDeviceScaleFactor(), pixel_rect);
- return GetDisplayMatching(dip_rect);
+ if (aura::WindowTreeHost* host = window ? window->GetHost() : nullptr) {
+ const auto* const desktop_host =
+ DesktopWindowTreeHostLinux::GetHostForWidget(
+ host->GetAcceleratedWidget());
+ if (desktop_host) {
+ const gfx::Rect pixel_rect = desktop_host->GetBoundsInPixels();
+ return GetDisplayMatching(
+ gfx::ConvertRectToDIP(GetXDisplayScaleFactor(), pixel_rect));
}
}
@@ -133,16 +99,15 @@ display::Display DesktopScreenX11::GetDisplayNearestWindow(
display::Display DesktopScreenX11::GetDisplayNearestPoint(
const gfx::Point& point) const {
- if (GetNumDisplays() <= 1)
- return GetPrimaryDisplay();
- return *FindDisplayNearestPoint(GetAllDisplays(), point);
+ return (GetNumDisplays() <= 1)
+ ? GetPrimaryDisplay()
+ : *FindDisplayNearestPoint(GetAllDisplays(), point);
}
display::Display DesktopScreenX11::GetDisplayMatching(
const gfx::Rect& match_rect) const {
- const display::Display* matching =
+ const display::Display* const matching =
display::FindDisplayWithBiggestIntersection(GetAllDisplays(), match_rect);
- // Fallback to the primary display if there is no matching display.
return matching ? *matching : GetPrimaryDisplay();
}
@@ -158,13 +123,13 @@ void DesktopScreenX11::RemoveObserver(display::DisplayObserver* observer) {
x11_display_manager_->RemoveObserver(observer);
}
-bool DesktopScreenX11::CanDispatchEvent(const ui::PlatformEvent& event) {
- return x11_display_manager_->CanProcessEvent(*event);
+std::string DesktopScreenX11::GetCurrentWorkspace() {
+ return x11_display_manager_->GetCurrentWorkspace();
}
-uint32_t DesktopScreenX11::DispatchEvent(const ui::PlatformEvent& event) {
- ignore_result(x11_display_manager_->ProcessEvent(event));
- return ui::POST_DISPATCH_NONE;
+bool DesktopScreenX11::DispatchXEvent(XEvent* event) {
+ return x11_display_manager_->CanProcessEvent(*event) &&
+ x11_display_manager_->ProcessEvent(event);
}
void DesktopScreenX11::OnDeviceScaleFactorChanged() {
@@ -173,21 +138,21 @@ void DesktopScreenX11::OnDeviceScaleFactorChanged() {
// static
void DesktopScreenX11::UpdateDeviceScaleFactorForTest() {
- DesktopScreenX11* screen =
- static_cast<DesktopScreenX11*>(display::Screen::GetScreen());
+ auto* screen = static_cast<DesktopScreenX11*>(display::Screen::GetScreen());
screen->x11_display_manager_->UpdateDisplayList();
}
-////////////////////////////////////////////////////////////////////////////////
-// DesktopScreenX11, private:
-
void DesktopScreenX11::OnXDisplayListUpdated() {
gfx::SetFontRenderParamsDeviceScaleFactor(
GetPrimaryDisplay().device_scale_factor());
}
-float DesktopScreenX11::GetXDisplayScaleFactor() {
- return GetDeviceScaleFactor();
+float DesktopScreenX11::GetXDisplayScaleFactor() const {
+ if (LinuxUI::instance())
+ return LinuxUI::instance()->GetDeviceScaleFactor();
+ return display::Display::HasForceDeviceScaleFactor()
+ ? display::Display::GetForcedDeviceScaleFactor()
+ : 1.0f;
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h
index 9a5814ce14f..dcf3e0f725e 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h
@@ -5,15 +5,15 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_SCREEN_X11_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_SCREEN_X11_H_
-#include <stdint.h>
-
#include <memory>
+#include <vector>
-#include "base/macros.h"
+#include "base/scoped_observer.h"
#include "ui/base/x/x11_display_manager.h"
#include "ui/display/screen.h"
-#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/views/linux_ui/device_scale_factor_observer.h"
+#include "ui/views/linux_ui/linux_ui.h"
#include "ui/views/views_export.h"
namespace views {
@@ -25,9 +25,9 @@ class DesktopScreenX11TestApi;
// Screen implementation that talks to XRandR
class VIEWS_EXPORT DesktopScreenX11 : public display::Screen,
- public ui::PlatformEventDispatcher,
+ public ui::XEventDispatcher,
public ui::XDisplayManager::Delegate,
- public views::DeviceScaleFactorObserver {
+ public DeviceScaleFactorObserver {
public:
DesktopScreenX11();
~DesktopScreenX11() override;
@@ -36,7 +36,7 @@ class VIEWS_EXPORT DesktopScreenX11 : public display::Screen,
// fetching might not be desirable in some scenarios (e.g: unit tests)
void Init();
- // Overridden from display::Screen:
+ // display::Screen:
gfx::Point GetCursorScreenPoint() override;
bool IsWindowUnderCursor(gfx::NativeWindow window) override;
gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override;
@@ -51,12 +51,12 @@ class VIEWS_EXPORT DesktopScreenX11 : public display::Screen,
display::Display GetPrimaryDisplay() const override;
void AddObserver(display::DisplayObserver* observer) override;
void RemoveObserver(display::DisplayObserver* observer) override;
+ std::string GetCurrentWorkspace() override;
- // ui::PlatformEventDispatcher:
- bool CanDispatchEvent(const ui::PlatformEvent& event) override;
- uint32_t DispatchEvent(const ui::PlatformEvent& event) override;
+ // ui::XEventDispatcher:
+ bool DispatchXEvent(XEvent* event) override;
- // views::DeviceScaleFactorObserver:
+ // DeviceScaleFactorObserver:
void OnDeviceScaleFactorChanged() override;
static void UpdateDeviceScaleFactorForTest();
@@ -65,13 +65,22 @@ class VIEWS_EXPORT DesktopScreenX11 : public display::Screen,
friend class DesktopScreenX11Test;
friend class test::DesktopScreenX11TestApi;
- // ui::XDisplayManager::Delegate
+ // ui::XDisplayManager::Delegate:
void OnXDisplayListUpdated() override;
- float GetXDisplayScaleFactor() override;
-
- std::unique_ptr<ui::XDisplayManager> x11_display_manager_;
-
- DISALLOW_COPY_AND_ASSIGN(DesktopScreenX11);
+ float GetXDisplayScaleFactor() const override;
+
+ std::unique_ptr<ui::XDisplayManager> x11_display_manager_ =
+ std::make_unique<ui::XDisplayManager>(this);
+ ScopedObserver<LinuxUI,
+ DeviceScaleFactorObserver,
+ &LinuxUI::AddDeviceScaleFactorObserver,
+ &LinuxUI::RemoveDeviceScaleFactorObserver>
+ display_scale_factor_observer_{this};
+ ScopedObserver<ui::X11EventSource,
+ XEventDispatcher,
+ &ui::X11EventSource::AddXEventDispatcher,
+ &ui::X11EventSource::RemoveXEventDispatcher>
+ event_source_observer_{this};
};
} // namespace views
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
index b5183989b5e..d284138d2a9 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <memory>
+#include <utility>
#include <vector>
#include "base/macros.h"
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h
index da8caf2e499..9e15a572258 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h
@@ -6,6 +6,7 @@
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_H_
#include <memory>
+#include <string>
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/ui_base_types.h"
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc
index 7705e7b4135..91cfaf77bb3 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc
@@ -4,6 +4,12 @@
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
+#include <algorithm>
+#include <list>
+#include <memory>
+#include <string>
+#include <vector>
+
#include "ui/aura/null_window_targeter.h"
#include "ui/aura/scoped_window_targeter.h"
#include "ui/aura/window.h"
@@ -119,10 +125,6 @@ void DesktopWindowTreeHostLinux::CleanUpWindowList(
open_windows_ = nullptr;
}
-void DesktopWindowTreeHostLinux::SetPendingXVisualId(int x_visual_id) {
- pending_x_visual_id_ = x_visual_id;
-}
-
gfx::Rect DesktopWindowTreeHostLinux::GetXRootWindowOuterBounds() const {
// TODO(msisov): must be removed as soon as all X11 low-level bits are moved
// to Ozone.
@@ -291,6 +293,14 @@ void DesktopWindowTreeHostLinux::OnActivationChanged(bool active) {
DesktopWindowTreeHostPlatform::OnActivationChanged(active);
}
+ui::X11Extension* DesktopWindowTreeHostLinux::GetX11Extension() {
+ return ui::GetX11Extension(*(platform_window()));
+}
+
+const ui::X11Extension* DesktopWindowTreeHostLinux::GetX11Extension() const {
+ return ui::GetX11Extension(*(platform_window()));
+}
+
#if BUILDFLAG(USE_ATK)
bool DesktopWindowTreeHostLinux::OnAtkKeyEvent(AtkKeyEventStruct* atk_event) {
if (!IsActive() && !HasCapture())
@@ -300,6 +310,11 @@ bool DesktopWindowTreeHostLinux::OnAtkKeyEvent(AtkKeyEventStruct* atk_event) {
}
#endif
+bool DesktopWindowTreeHostLinux::IsOverrideRedirect() const {
+ // BrowserDesktopWindowTreeHostLinux implements this for browser windows.
+ return false;
+}
+
void DesktopWindowTreeHostLinux::AddAdditionalInitProperties(
const Widget::InitParams& params,
ui::PlatformWindowInitProperties* properties) {
@@ -333,8 +348,6 @@ void DesktopWindowTreeHostLinux::AddAdditionalInitProperties(
properties->wm_class_class = params.wm_class_class;
properties->wm_role_name = params.wm_role_name;
- properties->x_visual_id = pending_x_visual_id_;
-
DCHECK(!properties->x11_extension_delegate);
properties->x11_extension_delegate = this;
}
@@ -355,10 +368,6 @@ void DesktopWindowTreeHostLinux::DestroyNonClientEventFilter() {
non_client_window_event_filter_.reset();
}
-void DesktopWindowTreeHostLinux::OnXWindowMapped() {}
-
-void DesktopWindowTreeHostLinux::OnXWindowUnmapped() {}
-
void DesktopWindowTreeHostLinux::GetWindowMask(const gfx::Size& size,
SkPath* window_mask) {
DCHECK(window_mask);
@@ -380,14 +389,6 @@ void DesktopWindowTreeHostLinux::EnableEventListening() {
targeter_for_modal_.reset();
}
-ui::X11Extension* DesktopWindowTreeHostLinux::GetX11Extension() {
- return ui::GetX11Extension(*(platform_window()));
-}
-
-const ui::X11Extension* DesktopWindowTreeHostLinux::GetX11Extension() const {
- return ui::GetX11Extension(*(platform_window()));
-}
-
std::list<gfx::AcceleratedWidget>& DesktopWindowTreeHostLinux::open_windows() {
if (!open_windows_)
open_windows_ = new std::list<gfx::AcceleratedWidget>();
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h
index 99cc4190f27..1351c2a66c4 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h
@@ -5,6 +5,11 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_LINUX_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_LINUX_H_
+#include <list>
+#include <memory>
+#include <string>
+#include <vector>
+
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "ui/aura/scoped_window_targeter.h"
@@ -55,10 +60,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostLinux
// internal list of open windows.
static void CleanUpWindowList(void (*func)(aura::Window* window));
- // This must be called before the window is created, because the visual cannot
- // be changed after. Useful for X11. Not in use for Wayland.
- void SetPendingXVisualId(int x_visual_id);
-
// Returns the current bounds in terms of the X11 Root Window including the
// borders provided by the window manager (if any). Not in use for Wayland.
gfx::Rect GetXRootWindowOuterBounds() const;
@@ -88,7 +89,11 @@ class VIEWS_EXPORT DesktopWindowTreeHostLinux
void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override;
void OnActivationChanged(bool active) override;
+ ui::X11Extension* GetX11Extension();
+ const ui::X11Extension* GetX11Extension() const;
+
private:
+ friend class DesktopWindowTreeHostX11Test;
FRIEND_TEST_ALL_PREFIXES(DesktopWindowTreeHostLinuxTest, HitTest);
// Overridden from display::DisplayObserver via aura::WindowTreeHost:
@@ -107,20 +112,16 @@ class VIEWS_EXPORT DesktopWindowTreeHostLinux
void DestroyNonClientEventFilter();
// X11ExtensionDelegate overrides:
- void OnXWindowMapped() override;
- void OnXWindowUnmapped() override;
void GetWindowMask(const gfx::Size& size, SkPath* window_mask) override;
void OnLostMouseGrab() override;
#if BUILDFLAG(USE_ATK)
bool OnAtkKeyEvent(AtkKeyEventStruct* atk_key_event) override;
#endif
+ bool IsOverrideRedirect() const override;
// Enables event listening after closing |dialog|.
void EnableEventListening();
- ui::X11Extension* GetX11Extension();
- const ui::X11Extension* GetX11Extension() const;
-
// See comment for variable open_windows_.
static std::list<gfx::AcceleratedWidget>& open_windows();
@@ -129,11 +130,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostLinux
// other consumer handled them.
std::unique_ptr<WindowEventFilterLinux> non_client_window_event_filter_;
- // X11 may set set a visual id for the system tray icon before the host is
- // initialized. This value will be passed down to PlatformWindow during
- // initialization of the host.
- base::Optional<int> pending_x_visual_id_;
-
std::unique_ptr<CompositorObserver> compositor_observer_;
std::unique_ptr<aura::ScopedWindowTargeter> targeter_for_modal_;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux_interactive_uitest.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux_interactive_uitest.cc
index 2eb29b2909d..0b2ab7e4538 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux_interactive_uitest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_linux_interactive_uitest.cc
@@ -115,9 +115,9 @@ class HitTestNonClientFrameView : public NativeFrameView {
};
// This is used to return HitTestNonClientFrameView on create call.
-class HitTestWidgetDelegate : public views::WidgetDelegate {
+class HitTestWidgetDelegate : public WidgetDelegate {
public:
- explicit HitTestWidgetDelegate(views::Widget* widget) : widget_(widget) {}
+ explicit HitTestWidgetDelegate(Widget* widget) : widget_(widget) {}
~HitTestWidgetDelegate() override = default;
void set_can_resize(bool can_resize) {
@@ -127,11 +127,11 @@ class HitTestWidgetDelegate : public views::WidgetDelegate {
HitTestNonClientFrameView* frame_view() { return frame_view_; }
- // views::WidgetDelegate:
+ // WidgetDelegate:
bool CanResize() const override { return can_resize_; }
- views::Widget* GetWidget() override { return widget_; }
- views::Widget* GetWidget() const override { return widget_; }
- views::NonClientFrameView* CreateNonClientFrameView(Widget* widget) override {
+ Widget* GetWidget() override { return widget_; }
+ Widget* GetWidget() const override { return widget_; }
+ NonClientFrameView* CreateNonClientFrameView(Widget* widget) override {
DCHECK(widget_ == widget);
if (!frame_view_)
frame_view_ = new HitTestNonClientFrameView(widget);
@@ -140,7 +140,7 @@ class HitTestWidgetDelegate : public views::WidgetDelegate {
void DeleteDelegate() override { delete this; }
private:
- views::Widget* const widget_;
+ Widget* const widget_;
HitTestNonClientFrameView* frame_view_ = nullptr;
bool can_resize_ = false;
@@ -191,7 +191,7 @@ class DesktopWindowTreeHostLinuxTest : public ViewsInteractiveUITestBase {
delegate_ = new HitTestWidgetDelegate(toplevel);
Widget::InitParams toplevel_params =
CreateParams(Widget::InitParams::TYPE_WINDOW);
- auto* native_widget = new views::DesktopNativeWidgetAura(toplevel);
+ auto* native_widget = new DesktopNativeWidgetAura(toplevel);
toplevel_params.native_widget = native_widget;
host_ = new TestDesktopWindowTreeHostLinux(toplevel, native_widget);
toplevel_params.desktop_window_tree_host = host_;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h
deleted file mode 100644
index 544f20527aa..00000000000
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_OBSERVER_X11_H_
-#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_OBSERVER_X11_H_
-
-#include "ui/views/views_export.h"
-
-namespace views {
-
-// Allows for the observation of lower level window events.
-class VIEWS_EXPORT DesktopWindowTreeHostObserverX11 {
- public:
- virtual ~DesktopWindowTreeHostObserverX11() {}
-
- // Called after we receive a MapNotify event (the X11 server has allocated
- // resources for it).
- virtual void OnWindowMapped(unsigned long xid) = 0;
-
- // Called after we receive an UnmapNotify event (the X11 server has freed
- // resources for it).
- virtual void OnWindowUnmapped(unsigned long xid) = 0;
-};
-
-} // namespace views
-
-#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_OBSERVER_X11_H_
-
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
index 30e99b6183f..f3a3175c6c3 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -4,6 +4,10 @@
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h"
+#include <memory>
+#include <string>
+#include <utility>
+
#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -42,36 +46,43 @@ bool DetermineInactivity(ui::WindowShowState show_state) {
return show_state == ui::SHOW_STATE_INACTIVE;
}
-ui::PlatformWindowInitProperties ConvertWidgetInitParamsToInitProperties(
- const Widget::InitParams& params) {
- ui::PlatformWindowInitProperties properties;
+ui::PlatformWindowOpacity GetPlatformWindowOpacity(
+ Widget::InitParams::WindowOpacity opacity) {
+ switch (opacity) {
+ case Widget::InitParams::WindowOpacity::kInferred:
+ return ui::PlatformWindowOpacity::kInferOpacity;
+ case Widget::InitParams::WindowOpacity::kOpaque:
+ return ui::PlatformWindowOpacity::kOpaqueWindow;
+ case Widget::InitParams::WindowOpacity::kTranslucent:
+ return ui::PlatformWindowOpacity::kTranslucentWindow;
+ }
+ return ui::PlatformWindowOpacity::kOpaqueWindow;
+}
- switch (params.type) {
+ui::PlatformWindowType GetPlatformWindowType(
+ Widget::InitParams::Type window_type) {
+ switch (window_type) {
case Widget::InitParams::TYPE_WINDOW:
- properties.type = ui::PlatformWindowType::kWindow;
- break;
-
+ return ui::PlatformWindowType::kWindow;
case Widget::InitParams::TYPE_MENU:
- properties.type = ui::PlatformWindowType::kMenu;
- break;
-
+ return ui::PlatformWindowType::kMenu;
case Widget::InitParams::TYPE_TOOLTIP:
- properties.type = ui::PlatformWindowType::kTooltip;
- break;
-
+ return ui::PlatformWindowType::kTooltip;
case Widget::InitParams::TYPE_DRAG:
- properties.type = ui::PlatformWindowType::kDrag;
- break;
-
+ return ui::PlatformWindowType::kDrag;
case Widget::InitParams::TYPE_BUBBLE:
- properties.type = ui::PlatformWindowType::kBubble;
- break;
-
+ return ui::PlatformWindowType::kBubble;
default:
- properties.type = ui::PlatformWindowType::kPopup;
- break;
+ return ui::PlatformWindowType::kPopup;
}
+ NOTREACHED();
+ return ui::PlatformWindowType::kPopup;
+}
+ui::PlatformWindowInitProperties ConvertWidgetInitParamsToInitProperties(
+ const Widget::InitParams& params) {
+ ui::PlatformWindowInitProperties properties;
+ properties.type = GetPlatformWindowType(params.type);
properties.activatable =
params.activatable == Widget::InitParams::ACTIVATABLE_YES;
properties.force_show_in_taskbar = params.force_show_in_taskbar;
@@ -80,22 +91,11 @@ ui::PlatformWindowInitProperties ConvertWidgetInitParamsToInitProperties(
properties.visible_on_all_workspaces = params.visible_on_all_workspaces;
properties.remove_standard_frame = params.remove_standard_frame;
properties.workspace = params.workspace;
+ properties.opacity = GetPlatformWindowOpacity(params.opacity);
if (params.parent && params.parent->GetHost())
properties.parent_widget = params.parent->GetHost()->GetAcceleratedWidget();
- switch (params.opacity) {
- case Widget::InitParams::WindowOpacity::kInferred:
- properties.opacity = ui::PlatformWindowOpacity::kInferOpacity;
- break;
- case Widget::InitParams::WindowOpacity::kOpaque:
- properties.opacity = ui::PlatformWindowOpacity::kOpaqueWindow;
- break;
- case Widget::InitParams::WindowOpacity::kTranslucent:
- properties.opacity = ui::PlatformWindowOpacity::kTranslucentWindow;
- break;
- }
-
return properties;
}
@@ -215,7 +215,7 @@ void DesktopWindowTreeHostPlatform::Close() {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&DesktopWindowTreeHostPlatform::CloseNow,
close_widget_factory_.GetWeakPtr()));
-} // namespace views
+}
void DesktopWindowTreeHostPlatform::CloseNow() {
if (!platform_window())
@@ -504,13 +504,13 @@ Widget::MoveLoopResult DesktopWindowTreeHostPlatform::RunMoveLoop(
const gfx::Vector2d& drag_offset,
Widget::MoveLoopSource source,
Widget::MoveLoopEscapeBehavior escape_behavior) {
- // TODO: needs PlatformWindow support.
+ // TODO(crbug.com/896640): needs PlatformWindow support.
NOTIMPLEMENTED_LOG_ONCE();
return Widget::MOVE_LOOP_CANCELED;
}
void DesktopWindowTreeHostPlatform::EndMoveLoop() {
- // TODO: needs PlatformWindow support.
+ // TODO(crbug.com/896640): needs PlatformWindow support.
NOTIMPLEMENTED_LOG_ONCE();
}
@@ -560,7 +560,7 @@ void DesktopWindowTreeHostPlatform::SetFullscreen(bool fullscreen) {
DCHECK_EQ(fullscreen, IsFullscreen());
if (IsFullscreen() == fullscreen)
- Relayout();
+ ScheduleRelayout();
// Else: the widget will be relaid out either when the window bounds change
// or when |platform_window|'s fullscreen state changes.
}
@@ -673,7 +673,7 @@ void DesktopWindowTreeHostPlatform::OnWindowStateChanged(
// Now that we have different window properties, we may need to relayout the
// window. (The windows code doesn't need this because their window change is
// synchronous.)
- Relayout();
+ ScheduleRelayout();
}
void DesktopWindowTreeHostPlatform::OnCloseRequest() {
@@ -681,9 +681,12 @@ void DesktopWindowTreeHostPlatform::OnCloseRequest() {
}
void DesktopWindowTreeHostPlatform::OnActivationChanged(bool active) {
+ if (is_active_ == active)
+ return;
is_active_ = active;
aura::WindowTreeHostPlatform::OnActivationChanged(active);
desktop_native_widget_aura_->HandleActivationChanged(active);
+ ScheduleRelayout();
}
base::Optional<gfx::Size>
@@ -716,7 +719,7 @@ gfx::Rect DesktopWindowTreeHostPlatform::ToPixelRect(
return gfx::ToEnclosingRect(rect_in_pixels);
}
-void DesktopWindowTreeHostPlatform::Relayout() {
+void DesktopWindowTreeHostPlatform::ScheduleRelayout() {
Widget* widget = native_widget_delegate_->AsWidget();
NonClientView* non_client_view = widget->non_client_view();
// non_client_view may be NULL, especially during creation.
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
index 89beb8d2245..24a5fa974dd 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
@@ -5,7 +5,9 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_PLATFORM_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_PLATFORM_H_
+#include <memory>
#include <set>
+#include <string>
#include <vector>
#include "base/memory/weak_ptr.h"
@@ -129,7 +131,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostPlatform
gfx::Rect ToPixelRect(const gfx::Rect& rect_in_dip) const;
private:
- void Relayout();
+ void ScheduleRelayout();
Widget* GetWidget();
const Widget* GetWidget() const;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_unittest.cc
index d14c81e31d4..62e2a8fd5ab 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_unittest.cc
@@ -3,6 +3,10 @@
// found in the LICENSE file.
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h"
+
+#include <memory>
+#include <utility>
+
#include "base/run_loop.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index b43ff29b2bc..6f576d95707 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -4,6 +4,10 @@
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
+#include <algorithm>
+#include <utility>
+#include <vector>
+
#include "base/bind.h"
#include "base/containers/flat_set.h"
#include "base/memory/ptr_util.h"
@@ -169,8 +173,7 @@ void DesktopWindowTreeHostWin::OnWidgetInitDone() {}
std::unique_ptr<corewm::Tooltip> DesktopWindowTreeHostWin::CreateTooltip() {
bool force_legacy_tooltips =
(base::win::GetVersion() < base::win::Version::WIN8);
- if (base::FeatureList::IsEnabled(features::kEnableAuraTooltipsOnWindows) &&
- !force_legacy_tooltips)
+ if (!force_legacy_tooltips)
return std::make_unique<corewm::TooltipAura>();
DCHECK(!tooltip_);
@@ -230,8 +233,8 @@ bool DesktopWindowTreeHostWin::IsVisible() const {
}
void DesktopWindowTreeHostWin::SetSize(const gfx::Size& size) {
- gfx::Size size_in_pixels = display::win::ScreenWin::DIPToScreenSize(GetHWND(),
- size);
+ gfx::Size size_in_pixels =
+ display::win::ScreenWin::DIPToScreenSize(GetHWND(), size);
gfx::Size expanded =
GetExpandedWindowSize(message_handler_->is_translucent(), size_in_pixels);
window_enlargement_ =
@@ -251,8 +254,8 @@ void DesktopWindowTreeHostWin::StackAtTop() {
}
void DesktopWindowTreeHostWin::CenterWindow(const gfx::Size& size) {
- gfx::Size size_in_pixels = display::win::ScreenWin::DIPToScreenSize(GetHWND(),
- size);
+ gfx::Size size_in_pixels =
+ display::win::ScreenWin::DIPToScreenSize(GetHWND(), size);
gfx::Size expanded_size;
expanded_size =
GetExpandedWindowSize(message_handler_->is_translucent(), size_in_pixels);
@@ -295,9 +298,9 @@ std::string DesktopWindowTreeHostWin::GetWorkspace() const {
gfx::Rect DesktopWindowTreeHostWin::GetWorkAreaBoundsInScreen() const {
MONITORINFO monitor_info;
monitor_info.cbSize = sizeof(monitor_info);
- GetMonitorInfo(MonitorFromWindow(message_handler_->hwnd(),
- MONITOR_DEFAULTTONEAREST),
- &monitor_info);
+ GetMonitorInfo(
+ MonitorFromWindow(message_handler_->hwnd(), MONITOR_DEFAULTTONEAREST),
+ &monitor_info);
gfx::Rect pixel_bounds = gfx::Rect(monitor_info.rcWork);
return display::win::ScreenWin::ScreenToDIPRect(GetHWND(), pixel_bounds);
}
@@ -412,8 +415,9 @@ Widget::MoveLoopResult DesktopWindowTreeHostWin::RunMoveLoop(
Widget::MoveLoopEscapeBehavior escape_behavior) {
const bool hide_on_escape =
escape_behavior == Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_HIDE;
- return message_handler_->RunMoveLoop(drag_offset, hide_on_escape) ?
- Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED;
+ return message_handler_->RunMoveLoop(drag_offset, hide_on_escape)
+ ? Widget::MOVE_LOOP_SUCCESSFUL
+ : Widget::MOVE_LOOP_CANCELED;
}
void DesktopWindowTreeHostWin::EndMoveLoop() {
@@ -477,8 +481,8 @@ void DesktopWindowTreeHostWin::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
aspect_ratio.height());
}
-void DesktopWindowTreeHostWin::SetWindowIcons(
- const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
+void DesktopWindowTreeHostWin::SetWindowIcons(const gfx::ImageSkia& window_icon,
+ const gfx::ImageSkia& app_icon) {
message_handler_->SetWindowIcons(window_icon, app_icon);
}
@@ -729,8 +733,8 @@ bool DesktopWindowTreeHostWin::WillProcessWorkAreaChange() const {
int DesktopWindowTreeHostWin::GetNonClientComponent(
const gfx::Point& point) const {
- gfx::Point dip_position = display::win::ScreenWin::ClientToDIPPoint(GetHWND(),
- point);
+ gfx::Point dip_position =
+ display::win::ScreenWin::ClientToDIPPoint(GetHWND(), point);
return native_widget_delegate_->GetNonClientComponent(dip_position);
}
@@ -794,11 +798,11 @@ void DesktopWindowTreeHostWin::HandleActivationChanged(bool active) {
desktop_native_widget_aura_->HandleActivationChanged(active);
}
-bool DesktopWindowTreeHostWin::HandleAppCommand(short command) {
+bool DesktopWindowTreeHostWin::HandleAppCommand(int command) {
// We treat APPCOMMAND ids as an extension of our command namespace, and just
// let the delegate figure out what to do...
return GetWidget()->widget_delegate() &&
- GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
+ GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
}
void DesktopWindowTreeHostWin::HandleCancelMode() {
@@ -1025,8 +1029,7 @@ bool DesktopWindowTreeHostWin::PreHandleMSG(UINT message,
void DesktopWindowTreeHostWin::PostHandleMSG(UINT message,
WPARAM w_param,
- LPARAM l_param) {
-}
+ LPARAM l_param) {}
bool DesktopWindowTreeHostWin::HandleScrollEvent(ui::ScrollEvent* event) {
SendEventToSink(event);
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index b195b582fe5..4b217541512 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -19,8 +19,8 @@ namespace aura {
namespace client {
class DragDropClient;
class FocusClient;
-}
-}
+} // namespace client
+} // namespace aura
namespace ui {
enum class DomCode;
@@ -181,7 +181,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
void ResetWindowControls() override;
gfx::NativeViewAccessible GetNativeViewAccessible() override;
void HandleActivationChanged(bool active) override;
- bool HandleAppCommand(short command) override;
+ bool HandleAppCommand(int command) override;
void HandleCancelMode() override;
void HandleCaptureLost() override;
void HandleClose() override;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc
index cb045d8b402..4f4d95a5014 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc
@@ -7,6 +7,8 @@
#include <oleacc.h>
#include <windows.h>
+#include <utility>
+
#include "base/command_line.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index 34c798b2367..2c94941cf27 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -16,6 +16,7 @@
#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "base/location.h"
+#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
@@ -41,7 +42,8 @@
#include "ui/events/devices/x11/device_list_cache_x11.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
-#include "ui/events/platform/platform_event_source.h"
+#include "ui/events/keyboard_hook.h"
+#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/x/events_x_utils.h"
#include "ui/events/x/x11_window_event_manager.h"
#include "ui/gfx/geometry/size_conversions.h"
@@ -55,8 +57,6 @@
#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h"
#include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
-#include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h"
-#include "ui/views/widget/desktop_aura/x11_desktop_handler.h"
#include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.h"
#include "ui/views/window/native_frame_view.h"
#include "ui/wm/core/compound_event_filter.h"
@@ -79,16 +79,6 @@ DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() {
// also destroyes the dispatcher.
}
-void DesktopWindowTreeHostX11::AddObserver(
- DesktopWindowTreeHostObserverX11* observer) {
- observer_list_.AddObserver(observer);
-}
-
-void DesktopWindowTreeHostX11::RemoveObserver(
- DesktopWindowTreeHostObserverX11* observer) {
- observer_list_.RemoveObserver(observer);
-}
-
////////////////////////////////////////////////////////////////////////////////
// DesktopWindowTreeHostX11, DesktopWindowTreeHost implementation:
@@ -106,10 +96,6 @@ void DesktopWindowTreeHostX11::Init(const Widget::InitParams& params) {
void DesktopWindowTreeHostX11::OnNativeWidgetCreated(
const Widget::InitParams& params) {
- // Ensure that the X11DesktopHandler exists so that it tracks create/destroy
- // notify events.
- X11DesktopHandler::get();
-
x11_window_move_client_ = std::make_unique<X11DesktopWindowMoveClient>();
wm::SetWindowMoveClient(window(), x11_window_move_client_.get());
@@ -131,7 +117,7 @@ Widget::MoveLoopResult DesktopWindowTreeHostX11::RunMoveLoop(
Widget::MoveLoopSource source,
Widget::MoveLoopEscapeBehavior escape_behavior) {
wm::WindowMoveSource window_move_source =
- source == Widget::MOVE_LOOP_SOURCE_MOUSE ? wm::WINDOW_MOVE_SOURCE_MOUSE
+ source == Widget::MoveLoopSource::kMouse ? wm::WINDOW_MOVE_SOURCE_MOUSE
: wm::WINDOW_MOVE_SOURCE_TOUCH;
if (x11_window_move_client_->RunMoveLoop(GetContentWindow(), drag_offset,
window_move_source) ==
@@ -148,16 +134,6 @@ void DesktopWindowTreeHostX11::EndMoveLoop() {
////////////////////////////////////////////////////////////////////////////////
// DesktopWindowTreeHostX11 implementation:
-void DesktopWindowTreeHostX11::OnXWindowMapped() {
- for (DesktopWindowTreeHostObserverX11& observer : observer_list_)
- observer.OnWindowMapped(GetXWindow()->window());
-}
-
-void DesktopWindowTreeHostX11::OnXWindowUnmapped() {
- for (DesktopWindowTreeHostObserverX11& observer : observer_list_)
- observer.OnWindowUnmapped(GetXWindow()->window());
-}
-
void DesktopWindowTreeHostX11::OnXWindowSelectionEvent(XEvent* xev) {
DCHECK(xev);
DCHECK(drag_drop_client_);
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index 9db2bb988a7..53da309c14d 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -8,7 +8,6 @@
#include <memory>
#include "base/macros.h"
-#include "base/observer_list.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/platform_window/platform_window_delegate.h"
#include "ui/platform_window/x11/x11_window.h"
@@ -22,7 +21,6 @@ class X11Window;
namespace views {
class DesktopDragDropClientAuraX11;
-class DesktopWindowTreeHostObserverX11;
class X11DesktopWindowMoveClient;
class VIEWS_EXPORT DesktopWindowTreeHostX11 : public DesktopWindowTreeHostLinux,
@@ -33,9 +31,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 : public DesktopWindowTreeHostLinux,
DesktopNativeWidgetAura* desktop_native_widget_aura);
~DesktopWindowTreeHostX11() override;
- void AddObserver(DesktopWindowTreeHostObserverX11* observer);
- void RemoveObserver(DesktopWindowTreeHostObserverX11* observer);
-
protected:
// Overridden from DesktopWindowTreeHost:
void Init(const Widget::InitParams& params) override;
@@ -51,14 +46,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 : public DesktopWindowTreeHostLinux,
private:
friend class DesktopWindowTreeHostX11HighDPITest;
- // X11ExtensionDelegate overrides:
- //
- // DWTHX11 temporarily overrides the X11ExtensionDelegate
- // methods instead of underlying DWTHPlatform and WTHPlatform. Eventually,
- // these will be removed from here as we progress in https://crbug.com/990756.
- void OnXWindowMapped() override;
- void OnXWindowUnmapped() override;
-
// Overridden from ui::XEventDelegate.
void OnXWindowSelectionEvent(XEvent* xev) override;
void OnXWindowDragDropEvent(XEvent* xev) override;
@@ -73,9 +60,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 : public DesktopWindowTreeHostLinux,
std::unique_ptr<X11DesktopWindowMoveClient> x11_window_move_client_;
- base::ObserverList<DesktopWindowTreeHostObserverX11>::Unchecked
- observer_list_;
-
DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11);
};
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc
index 8bd27d22979..7135ad984e3 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc
@@ -14,7 +14,7 @@
#include "ui/base/x/x11_util.h"
#include "ui/events/event_handler.h"
#include "ui/events/platform/x11/x11_event_source.h"
-#include "ui/events/platform/x11/x11_event_source_glib.h"
+#include "ui/events/x/x11_event_translation.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/x/x11.h"
#include "ui/gfx/x/x11_atom_cache.h"
@@ -32,14 +32,13 @@ class ActivationWaiter : public X11PropertyChangeWaiter {
public:
explicit ActivationWaiter(XID window)
: X11PropertyChangeWaiter(ui::GetX11RootWindow(), "_NET_ACTIVE_WINDOW"),
- window_(window) {
- }
+ window_(window) {}
~ActivationWaiter() override = default;
private:
// X11PropertyChangeWaiter:
- bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override {
+ bool ShouldKeepOnWaiting(XEvent* event) override {
XID xid = 0;
ui::GetXIDProperty(ui::GetX11RootWindow(), "_NET_ACTIVE_WINDOW", &xid);
return xid != window_;
@@ -62,9 +61,7 @@ class MouseMoveCounterHandler : public ui::EventHandler {
++count_;
}
- int num_mouse_moves() const {
- return count_;
- }
+ int num_mouse_moves() const { return count_; }
private:
int count_ = 0;
@@ -84,18 +81,17 @@ std::unique_ptr<Widget> CreateWidget(const gfx::Rect& bounds) {
return widget;
}
-// Dispatches an XMotionEvent targeted at |host|'s X window with location
+// Dispatches a XMotionEvent targeted at |host|'s X window with location
// |point_in_screen|.
void DispatchMouseMotionEvent(DesktopWindowTreeHostX11* desktop_host,
const gfx::Point& point_in_screen) {
- aura::WindowTreeHost* host = static_cast<aura::WindowTreeHost*>(desktop_host);
gfx::Rect bounds_in_screen = desktop_host->window()->GetBoundsInScreen();
Display* display = gfx::GetXDisplay();
XEvent xev;
xev.xmotion.type = MotionNotify;
xev.xmotion.display = display;
- xev.xmotion.window = host->GetAcceleratedWidget();
+ xev.xmotion.window = desktop_host->GetAcceleratedWidget();
xev.xmotion.root = DefaultRootWindow(display);
xev.xmotion.subwindow = 0;
xev.xmotion.time = x11::CurrentTime;
@@ -107,8 +103,7 @@ void DispatchMouseMotionEvent(DesktopWindowTreeHostX11* desktop_host,
xev.xmotion.is_hint = NotifyNormal;
xev.xmotion.same_screen = x11::True;
- static_cast<ui::X11EventSourceGlib*>(ui::PlatformEventSource::GetInstance())
- ->ProcessXEvent(&xev);
+ ui::X11EventSource::GetInstance()->ProcessXEvent(&xev);
}
} // namespace
@@ -252,9 +247,12 @@ TEST_F(DesktopWindowTreeHostX11Test, InputMethodFocus) {
// EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
// widget->GetInputMethod()->GetTextInputType());
- widget->Activate();
+ // Waiter should be created before widget->Activate is called. Otherwise,
+ // there is a race, and waiter might not be able to set property changes mask
+ // on time and miss the events.
ActivationWaiter waiter(
widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget());
+ widget->Activate();
waiter.Wait();
EXPECT_TRUE(widget->IsActive());
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
index 8195a801561..88b625f1b59 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
@@ -3,7 +3,9 @@
// found in the LICENSE file.
#include <stddef.h>
+
#include <memory>
+#include <utility>
#include <vector>
#include "base/command_line.h"
@@ -17,9 +19,10 @@
#include "ui/base/x/x11_util.h"
#include "ui/display/display_switches.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
-#include "ui/events/platform/x11/x11_event_source_glib.h"
+#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/events/test/events_test_utils_x11.h"
#include "ui/events/test/platform_event_source_test_api.h"
+#include "ui/events/x/x11_event_translation.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/x/x11.h"
@@ -49,7 +52,7 @@ class WMStateWaiter : public X11PropertyChangeWaiter {
private:
// X11PropertyChangeWaiter:
- bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override {
+ bool ShouldKeepOnWaiting(XEvent* event) override {
std::vector<Atom> hints;
if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &hints))
return base::Contains(hints, gfx::GetAtom(hint_)) != wait_till_set_;
@@ -173,7 +176,7 @@ bool ShapeRectContainsPoint(const std::vector<gfx::Rect>& shape_rects,
class DesktopWindowTreeHostX11Test : public ViewsTestBase {
public:
DesktopWindowTreeHostX11Test()
- : event_source_(ui::PlatformEventSource::GetInstance()) {}
+ : event_source_(ui::X11EventSource::GetInstance()) {}
~DesktopWindowTreeHostX11Test() override = default;
void SetUp() override {
@@ -195,17 +198,17 @@ class DesktopWindowTreeHostX11Test : public ViewsTestBase {
ViewsTestBase::TearDown();
}
- void DispatchSingleEventToWidget(XEvent* event, Widget* widget) {
- DCHECK_EQ(GenericEvent, event->type);
+ void DispatchSingleEventToWidget(XEvent* xev, Widget* widget) {
+ DCHECK_EQ(GenericEvent, xev->type);
XIDeviceEvent* device_event =
- static_cast<XIDeviceEvent*>(event->xcookie.data);
+ static_cast<XIDeviceEvent*>(xev->xcookie.data);
device_event->event =
widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget();
- event_source_.Dispatch(event);
+ event_source_->ProcessXEvent(xev);
}
private:
- ui::test::PlatformEventSourceTestAPI event_source_;
+ ui::X11EventSource* event_source_;
DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11Test);
};
diff --git a/chromium/ui/views/widget/desktop_aura/window_event_filter_linux.cc b/chromium/ui/views/widget/desktop_aura/window_event_filter_linux.cc
index f1729e53d09..d69da05aa30 100644
--- a/chromium/ui/views/widget/desktop_aura/window_event_filter_linux.cc
+++ b/chromium/ui/views/widget/desktop_aura/window_event_filter_linux.cc
@@ -163,7 +163,7 @@ void WindowEventFilterLinux::MaybeDispatchHostWindowDragMovement(
// interactive move/resize.
auto bounds_in_px =
desktop_window_tree_host_->AsWindowTreeHost()->GetBoundsInPixels();
- auto screen_point_in_px = event->root_location();
+ auto screen_point_in_px = event->location();
screen_point_in_px.Offset(bounds_in_px.x(), bounds_in_px.y());
handler_->DispatchHostWindowDragMovement(hittest, screen_point_in_px);
event->StopPropagation();
diff --git a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc b/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc
deleted file mode 100644
index cfe62d62144..00000000000
--- a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/widget/desktop_aura/x11_desktop_handler.h"
-
-#include <memory>
-
-#include "base/strings/string_number_conversions.h"
-#include "ui/aura/env.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/base/x/x11_menu_list.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/events/platform/platform_event_source.h"
-#include "ui/events/x/x11_window_event_manager.h"
-#include "ui/gfx/x/x11.h"
-#include "ui/gfx/x/x11_atom_cache.h"
-#include "ui/gfx/x/x11_error_tracker.h"
-#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
-
-namespace {
-
-// Our global instance. Deleted when our Env() is deleted.
-views::X11DesktopHandler* g_handler = nullptr;
-
-} // namespace
-
-namespace views {
-
-// static
-X11DesktopHandler* X11DesktopHandler::get() {
- if (!g_handler)
- g_handler = new X11DesktopHandler;
-
- return g_handler;
-}
-
-// static
-X11DesktopHandler* X11DesktopHandler::get_dont_create() {
- return g_handler;
-}
-
-X11DesktopHandler::X11DesktopHandler()
- : xdisplay_(gfx::GetXDisplay()),
- x_root_window_(DefaultRootWindow(xdisplay_)) {
- if (ui::PlatformEventSource::GetInstance())
- ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
- aura::Env::GetInstance()->AddObserver(this);
-
- x_root_window_events_ = std::make_unique<ui::XScopedEventSelector>(
- x_root_window_,
- PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask);
-}
-
-X11DesktopHandler::~X11DesktopHandler() {
- aura::Env::GetInstance()->RemoveObserver(this);
- if (ui::PlatformEventSource::GetInstance())
- ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
-}
-
-void X11DesktopHandler::AddObserver(X11DesktopHandlerObserver* observer) {
- observers_.AddObserver(observer);
-}
-
-void X11DesktopHandler::RemoveObserver(X11DesktopHandlerObserver* observer) {
- observers_.RemoveObserver(observer);
-}
-
-std::string X11DesktopHandler::GetWorkspace() {
- if (workspace_.empty())
- UpdateWorkspace();
- return workspace_;
-}
-
-bool X11DesktopHandler::UpdateWorkspace() {
- int desktop;
- if (ui::GetCurrentDesktop(&desktop)) {
- workspace_ = base::NumberToString(desktop);
- return true;
- }
- return false;
-}
-
-bool X11DesktopHandler::CanDispatchEvent(const ui::PlatformEvent& event) {
- return event->type == CreateNotify || event->type == DestroyNotify ||
- (event->type == PropertyNotify &&
- event->xproperty.window == x_root_window_);
-}
-
-uint32_t X11DesktopHandler::DispatchEvent(const ui::PlatformEvent& event) {
- switch (event->type) {
- case PropertyNotify: {
- if (event->xproperty.atom == gfx::GetAtom("_NET_CURRENT_DESKTOP")) {
- if (UpdateWorkspace()) {
- for (views::X11DesktopHandlerObserver& observer : observers_)
- observer.OnWorkspaceChanged(workspace_);
- }
- }
- break;
- }
- case CreateNotify:
- OnWindowCreatedOrDestroyed(event->type, event->xcreatewindow.window);
- break;
- case DestroyNotify:
- OnWindowCreatedOrDestroyed(event->type, event->xdestroywindow.window);
- break;
- default:
- NOTREACHED();
- }
-
- return ui::POST_DISPATCH_NONE;
-}
-
-void X11DesktopHandler::OnWindowInitialized(aura::Window* window) {
-}
-
-void X11DesktopHandler::OnWillDestroyEnv() {
- g_handler = nullptr;
- delete this;
-}
-
-void X11DesktopHandler::OnWindowCreatedOrDestroyed(int event_type,
- XID window) {
- // Menus created by Chrome can be drag and drop targets. Since they are
- // direct children of the screen root window and have override_redirect
- // we cannot use regular _NET_CLIENT_LIST_STACKING property to find them
- // and use a separate cache to keep track of them.
- // TODO(varkha): Implement caching of all top level X windows and their
- // coordinates and stacking order to eliminate repeated calls to the X server
- // during mouse movement, drag and shaping events.
- if (event_type == CreateNotify) {
- // The window might be destroyed if the message pump did not get a chance to
- // run but we can safely ignore the X error.
- gfx::X11ErrorTracker error_tracker;
- ui::XMenuList::GetInstance()->MaybeRegisterMenu(window);
- } else {
- ui::XMenuList::GetInstance()->MaybeUnregisterMenu(window);
- }
-}
-
-} // namespace views
diff --git a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.h b/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.h
deleted file mode 100644
index bcf36736232..00000000000
--- a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_X11_DESKTOP_HANDLER_H_
-#define UI_VIEWS_WIDGET_DESKTOP_AURA_X11_DESKTOP_HANDLER_H_
-
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/macros.h"
-#include "base/observer_list.h"
-#include "ui/aura/env_observer.h"
-#include "ui/events/platform/platform_event_dispatcher.h"
-#include "ui/events/platform/x11/x11_event_source.h"
-#include "ui/gfx/x/x11.h"
-#include "ui/gfx/x/x11_types.h"
-#include "ui/views/views_export.h"
-#include "ui/views/widget/desktop_aura/x11_desktop_handler_observer.h"
-
-namespace base {
-template <typename T> struct DefaultSingletonTraits;
-}
-
-namespace ui {
-class XScopedEventSelector;
-}
-
-namespace views {
-
-// A singleton that owns global objects related to the desktop and listens for
-// X11 events on the X11 root window. Destroys itself when aura::Env is
-// deleted.
-class VIEWS_EXPORT X11DesktopHandler : public ui::PlatformEventDispatcher,
- public aura::EnvObserver {
- public:
- // Returns the singleton handler. Creates one if one has not
- // already been created.
- static X11DesktopHandler* get();
-
- // Returns the singleton handler, or nullptr if one has not already
- // been created.
- static X11DesktopHandler* get_dont_create();
-
- // Adds/removes X11DesktopHandlerObservers.
- void AddObserver(X11DesktopHandlerObserver* observer);
- void RemoveObserver(X11DesktopHandlerObserver* observer);
-
- // Gets the current workspace ID.
- std::string GetWorkspace();
-
- // ui::PlatformEventDispatcher
- bool CanDispatchEvent(const ui::PlatformEvent& event) override;
- uint32_t DispatchEvent(const ui::PlatformEvent& event) override;
-
- // Overridden from aura::EnvObserver:
- void OnWindowInitialized(aura::Window* window) override;
- void OnWillDestroyEnv() override;
-
- private:
- X11DesktopHandler();
- ~X11DesktopHandler() override;
-
- // Called when |window| has been created or destroyed. |window| may not be
- // managed by Chrome.
- void OnWindowCreatedOrDestroyed(int event_type, XID window);
-
- // Makes a round trip to the X server to get the current workspace.
- bool UpdateWorkspace();
-
- // The display and the native X window hosting the root window.
- XDisplay* xdisplay_;
-
- // The native root window.
- ::Window x_root_window_;
-
- // Events selected on x_root_window_.
- std::unique_ptr<ui::XScopedEventSelector> x_root_window_events_;
-
- base::ObserverList<X11DesktopHandlerObserver>::Unchecked observers_;
-
- std::string workspace_;
-
- DISALLOW_COPY_AND_ASSIGN(X11DesktopHandler);
-};
-
-} // namespace views
-
-#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_X11_DESKTOP_HANDLER_H_
diff --git a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler_observer.h b/chromium/ui/views/widget/desktop_aura/x11_desktop_handler_observer.h
deleted file mode 100644
index 679d867a0b4..00000000000
--- a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler_observer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_X11_DESKTOP_HANDLER_OBSERVER_H_
-#define UI_VIEWS_WIDGET_DESKTOP_AURA_X11_DESKTOP_HANDLER_OBSERVER_H_
-
-#include <string>
-
-#include "ui/views/views_export.h"
-
-namespace views {
-
-class VIEWS_EXPORT X11DesktopHandlerObserver {
- public:
- // Called when the (platform-specific) workspace ID changes to
- // |new_workspace|.
- virtual void OnWorkspaceChanged(const std::string& new_workspace) = 0;
-
- protected:
- virtual ~X11DesktopHandlerObserver() {}
-};
-
-} // namespace views
-
-#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_X11_DESKTOP_HANDLER_OBSERVER_H_
diff --git a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
index 670b2e179ca..9acc365e582 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
@@ -6,6 +6,8 @@
#include <stddef.h>
+#include <vector>
+
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/window.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
diff --git a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder.h b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder.h
index 31ed462855c..0d9e535153a 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder.h
+++ b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder.h
@@ -8,6 +8,7 @@
#include <set>
#include "base/macros.h"
+#include "ui/base/x/x11_topmost_window_finder.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/x/x11.h"
@@ -20,8 +21,8 @@ class Window;
namespace views {
// Utility class for finding the topmost window at a given screen position.
-class VIEWS_EXPORT X11TopmostWindowFinder
- : public ui::EnumerateWindowsDelegate {
+class VIEWS_EXPORT X11TopmostWindowFinder : public ui::EnumerateWindowsDelegate,
+ public ui::XTopmostWindowFinder {
public:
X11TopmostWindowFinder();
~X11TopmostWindowFinder() override;
@@ -33,7 +34,7 @@ class VIEWS_EXPORT X11TopmostWindowFinder
const std::set<aura::Window*>& ignore);
// Returns the topmost window at |screen_loc_in_pixels|.
- XID FindWindowAt(const gfx::Point& screen_loc_in_pixels);
+ XID FindWindowAt(const gfx::Point& screen_loc_in_pixels) override;
private:
// ui::EnumerateWindowsDelegate:
diff --git a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
index ad283d52268..ce5c9ef430d 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
@@ -21,7 +21,6 @@
#include "ui/views/test/views_interactive_ui_test_base.h"
#include "ui/views/test/x11_property_change_waiter.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
-#include "ui/views/widget/desktop_aura/x11_desktop_handler.h"
#include "ui/views/widget/widget.h"
namespace views {
@@ -38,7 +37,7 @@ class MinimizeWaiter : public X11PropertyChangeWaiter {
private:
// X11PropertyChangeWaiter:
- bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override {
+ bool ShouldKeepOnWaiting(XEvent* event) override {
std::vector<Atom> wm_states;
if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &wm_states)) {
return !base::Contains(wm_states, gfx::GetAtom("_NET_WM_STATE_HIDDEN"));
@@ -56,8 +55,7 @@ class StackingClientListWaiter : public X11PropertyChangeWaiter {
StackingClientListWaiter(XID* expected_windows, size_t count)
: X11PropertyChangeWaiter(ui::GetX11RootWindow(),
"_NET_CLIENT_LIST_STACKING"),
- expected_windows_(expected_windows, expected_windows + count) {
- }
+ expected_windows_(expected_windows, expected_windows + count) {}
~StackingClientListWaiter() override = default;
@@ -73,7 +71,7 @@ class StackingClientListWaiter : public X11PropertyChangeWaiter {
private:
// X11PropertyChangeWaiter:
- bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override {
+ bool ShouldKeepOnWaiting(XEvent* event) override {
std::vector<XID> stack;
ui::GetXWindowStack(ui::GetX11RootWindow(), &stack);
return !std::all_of(
@@ -111,9 +109,7 @@ class X11TopmostWindowFinderTest : public ViewsInteractiveUITestBase {
// Creates and shows an X window with |bounds|.
XID CreateAndShowXWindow(const gfx::Rect& bounds) {
XID root = DefaultRootWindow(xdisplay());
- XID xid = XCreateSimpleWindow(xdisplay(),
- root,
- 0, 0, 1, 1,
+ XID xid = XCreateSimpleWindow(xdisplay(), root, 0, 0, 1, 1,
0, // border_width
0, // border
0); // background
@@ -132,15 +128,10 @@ class X11TopmostWindowFinderTest : public ViewsInteractiveUITestBase {
changes.y = bounds.y();
changes.width = bounds.width();
changes.height = bounds.height();
- XConfigureWindow(xdisplay(),
- xid,
- CWX | CWY | CWWidth | CWHeight,
- &changes);
+ XConfigureWindow(xdisplay(), xid, CWX | CWY | CWWidth | CWHeight, &changes);
}
- Display* xdisplay() {
- return gfx::GetXDisplay();
- }
+ Display* xdisplay() { return gfx::GetXDisplay(); }
// Returns the topmost X window at the passed in screen position.
XID FindTopmostXWindowAt(int screen_x, int screen_y) {
@@ -177,10 +168,6 @@ class X11TopmostWindowFinderTest : public ViewsInteractiveUITestBase {
// Make X11 synchronous for our display connection. This does not force the
// window manager to behave synchronously.
XSynchronize(xdisplay(), x11::True);
-
- // Ensure that the X11DesktopHandler exists. The X11DesktopHandler is
- // necessary to properly track menu windows.
- X11DesktopHandler::get();
}
void TearDown() override {
@@ -208,7 +195,7 @@ TEST_F(X11TopmostWindowFinderTest, Basic) {
aura::Window* window3 = widget3->GetNativeWindow();
XID xid3 = window3->GetHost()->GetAcceleratedWidget();
- XID xids[] = { xid1, xid2, xid3 };
+ XID xids[] = {xid1, xid2, xid3};
StackingClientListWaiter waiter(xids, base::size(xids));
waiter.Wait();
ui::X11EventSource::GetInstance()->DispatchXEvents();
@@ -251,7 +238,7 @@ TEST_F(X11TopmostWindowFinderTest, Minimized) {
XID xid1 = window1->GetHost()->GetAcceleratedWidget();
XID xid2 = CreateAndShowXWindow(gfx::Rect(300, 100, 100, 100));
- XID xids[] = { xid1, xid2 };
+ XID xids[] = {xid1, xid2};
StackingClientListWaiter stack_waiter(xids, base::size(xids));
stack_waiter.Wait();
ui::X11EventSource::GetInstance()->DispatchXEvents();
@@ -300,7 +287,7 @@ TEST_F(X11TopmostWindowFinderTest, NonRectangular) {
region2(gfx::CreateRegionFromSkRegion(skregion2));
XShapeCombineRegion(xdisplay(), xid2, ShapeBounding, 0, 0, region2.get(),
false);
- XID xids[] = { xid1, xid2 };
+ XID xids[] = {xid1, xid2};
StackingClientListWaiter stack_waiter(xids, base::size(xids));
stack_waiter.Wait();
ui::X11EventSource::GetInstance()->DispatchXEvents();
@@ -331,7 +318,7 @@ TEST_F(X11TopmostWindowFinderTest, NonRectangularEmptyShape) {
// Widget takes ownership of |shape1|.
widget1->SetShape(std::move(shape1));
- XID xids[] = { xid1 };
+ XID xids[] = {xid1};
StackingClientListWaiter stack_waiter(xids, base::size(xids));
stack_waiter.Wait();
ui::X11EventSource::GetInstance()->DispatchXEvents();
@@ -354,7 +341,7 @@ TEST_F(X11TopmostWindowFinderTest, NonRectangularNullShape) {
// Remove the shape - this is now just a normal window.
widget1->SetShape(nullptr);
- XID xids[] = { xid1 };
+ XID xids[] = {xid1};
StackingClientListWaiter stack_waiter(xids, base::size(xids));
stack_waiter.Wait();
ui::X11EventSource::GetInstance()->DispatchXEvents();
@@ -370,15 +357,12 @@ TEST_F(X11TopmostWindowFinderTest, Menu) {
XID root = DefaultRootWindow(xdisplay());
XSetWindowAttributes swa;
swa.override_redirect = x11::True;
- XID menu_xid = XCreateWindow(xdisplay(),
- root,
- 0, 0, 1, 1,
- 0, // border width
- CopyFromParent, // depth
+ XID menu_xid = XCreateWindow(xdisplay(), root, 0, 0, 1, 1,
+ 0, // border width
+ CopyFromParent, // depth
InputOutput,
- CopyFromParent, // visual
- CWOverrideRedirect,
- &swa);
+ CopyFromParent, // visual
+ CWOverrideRedirect, &swa);
{
ui::SetAtomProperty(menu_xid, "_NET_WM_WINDOW_TYPE", "ATOM",
gfx::GetAtom("_NET_WM_WINDOW_TYPE_MENU"));
@@ -388,7 +372,7 @@ TEST_F(X11TopmostWindowFinderTest, Menu) {
ui::X11EventSource::GetInstance()->DispatchXEvents();
// |menu_xid| is never added to _NET_CLIENT_LIST_STACKING.
- XID xids[] = { xid };
+ XID xids[] = {xid};
StackingClientListWaiter stack_waiter(xids, base::size(xids));
stack_waiter.Wait();
diff --git a/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc b/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
index eb1de4a7e4b..01509c2d677 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
@@ -21,6 +21,7 @@
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
+#include "ui/base/mojom/cursor_type.mojom-shared.h"
#include "ui/base/x/x11_pointer_grab.h"
#include "ui/base/x/x11_util.h"
#include "ui/events/event.h"
@@ -29,27 +30,26 @@
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/platform/scoped_event_dispatcher.h"
#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/events/x/events_x_utils.h"
#include "ui/events/x/x11_window_event_manager.h"
#include "ui/gfx/x/x11.h"
namespace views {
// XGrabKey requires the modifier mask to explicitly be specified.
-const unsigned int kModifiersMasks[] = {
- 0, // No additional modifier.
- Mod2Mask, // Num lock
- LockMask, // Caps lock
- Mod5Mask, // Scroll lock
- Mod2Mask | LockMask,
- Mod2Mask | Mod5Mask,
- LockMask | Mod5Mask,
- Mod2Mask | LockMask | Mod5Mask
-};
+const unsigned int kModifiersMasks[] = {0, // No additional modifier.
+ Mod2Mask, // Num lock
+ LockMask, // Caps lock
+ Mod5Mask, // Scroll lock
+ Mod2Mask | LockMask,
+ Mod2Mask | Mod5Mask,
+ LockMask | Mod5Mask,
+ Mod2Mask | LockMask | Mod5Mask};
X11WholeScreenMoveLoop::X11WholeScreenMoveLoop(X11MoveLoopDelegate* delegate)
: delegate_(delegate),
in_move_loop_(false),
- initial_cursor_(ui::CursorType::kNull),
+ initial_cursor_(ui::mojom::CursorType::kNull),
should_reset_mouse_flags_(false),
grab_input_window_(x11::None),
grabbed_pointer_(false),
@@ -60,12 +60,26 @@ X11WholeScreenMoveLoop::~X11WholeScreenMoveLoop() = default;
void X11WholeScreenMoveLoop::DispatchMouseMovement() {
if (!last_motion_in_screen_)
return;
- delegate_->OnMouseMovement(last_motion_in_screen_->location(),
+ delegate_->OnMouseMovement(last_motion_in_screen_->root_location(),
last_motion_in_screen_->flags(),
last_motion_in_screen_->time_stamp());
last_motion_in_screen_.reset();
}
+void X11WholeScreenMoveLoop::PostDispatchIfNeeded(const ui::MouseEvent& event) {
+ bool dispatch_mouse_event = !last_motion_in_screen_;
+ last_motion_in_screen_ = std::make_unique<ui::MouseEvent>(event);
+ if (dispatch_mouse_event) {
+ // Post a task to dispatch mouse movement event when control returns to the
+ // message loop. This allows smoother dragging since the events are
+ // dispatched without waiting for the drag widget updates.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&X11WholeScreenMoveLoop::DispatchMouseMovement,
+ weak_factory_.GetWeakPtr()));
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// DesktopWindowTreeHostLinux, ui::PlatformEventDispatcher implementation:
@@ -80,32 +94,14 @@ uint32_t X11WholeScreenMoveLoop::DispatchEvent(const ui::PlatformEvent& event) {
if (!in_move_loop_)
return ui::POST_DISPATCH_PERFORM_DEFAULT;
- XEvent* xev = event;
- ui::EventType type = ui::EventTypeFromNative(xev);
- switch (type) {
+ switch (event->type()) {
case ui::ET_MOUSE_MOVED:
case ui::ET_MOUSE_DRAGGED: {
- bool dispatch_mouse_event = !last_motion_in_screen_.get();
- last_motion_in_screen_.reset(
- ui::EventFromNative(xev).release()->AsMouseEvent());
- last_motion_in_screen_->set_location(
- ui::EventSystemLocationFromNative(xev));
- if (dispatch_mouse_event) {
- // Post a task to dispatch mouse movement event when control returns to
- // the message loop. This allows smoother dragging since the events are
- // dispatched without waiting for the drag widget updates.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&X11WholeScreenMoveLoop::DispatchMouseMovement,
- weak_factory_.GetWeakPtr()));
- }
+ PostDispatchIfNeeded(*event->AsMouseEvent());
return ui::POST_DISPATCH_NONE;
}
case ui::ET_MOUSE_RELEASED: {
- int button = (xev->type == ButtonRelease)
- ? xev->xbutton.button
- : ui::EventButtonFromNative(xev);
- if (button == Button1) {
+ if (event->AsMouseEvent()->IsLeftMouseButton()) {
// Assume that drags are being done with the left mouse button. Only
// break the drag if the left mouse button was released.
DispatchMouseMovement();
@@ -121,7 +117,7 @@ uint32_t X11WholeScreenMoveLoop::DispatchEvent(const ui::PlatformEvent& event) {
return ui::POST_DISPATCH_NONE;
}
case ui::ET_KEY_PRESSED:
- if (ui::KeyboardCodeFromXKeyEvent(xev) == ui::VKEY_ESCAPE) {
+ if (event->AsKeyEvent()->key_code() == ui::VKEY_ESCAPE) {
canceled_ = true;
EndMoveLoop();
return ui::POST_DISPATCH_NONE;
@@ -167,7 +163,7 @@ bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source,
std::unique_ptr<ui::ScopedEventDispatcher> old_dispatcher =
std::move(nested_dispatcher_);
nested_dispatcher_ =
- ui::PlatformEventSource::GetInstance()->OverrideDispatcher(this);
+ ui::PlatformEventSource::GetInstance()->OverrideDispatcher(this);
// We are handling a mouse drag outside of the aura::Window system. We must
// manually make aura think that the mouse button is pressed so that we don't
@@ -261,13 +257,12 @@ void X11WholeScreenMoveLoop::GrabEscKey() {
}
void X11WholeScreenMoveLoop::CreateDragInputWindow(XDisplay* display) {
- unsigned long attribute_mask = CWEventMask | CWOverrideRedirect;
XSetWindowAttributes swa;
memset(&swa, 0, sizeof(swa));
swa.override_redirect = x11::True;
grab_input_window_ = XCreateWindow(display, DefaultRootWindow(display), -100,
-100, 10, 10, 0, CopyFromParent, InputOnly,
- CopyFromParent, attribute_mask, &swa);
+ CopyFromParent, CWOverrideRedirect, &swa);
uint32_t event_mask = ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | KeyPressMask | KeyReleaseMask |
StructureNotifyMask;
diff --git a/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h b/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
index 529cb62bac6..1fa5bbd5cca 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
+++ b/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
@@ -7,6 +7,8 @@
#include <stdint.h>
+#include <memory>
+
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
@@ -28,7 +30,7 @@ namespace ui {
class MouseEvent;
class ScopedEventDispatcher;
class XScopedEventSelector;
-}
+} // namespace ui
namespace views {
@@ -62,6 +64,8 @@ class X11WholeScreenMoveLoop : public X11MoveLoop,
// Dispatch mouse movement event to |delegate_| in a posted task.
void DispatchMouseMovement();
+ void PostDispatchIfNeeded(const ui::MouseEvent& event);
+
X11MoveLoopDelegate* delegate_;
// Are we running a nested run loop from RunMoveLoop()?
diff --git a/chromium/ui/views/widget/desktop_widget_unittest.cc b/chromium/ui/views/widget/desktop_widget_unittest.cc
index 411a2ede663..6295852a6cb 100644
--- a/chromium/ui/views/widget/desktop_widget_unittest.cc
+++ b/chromium/ui/views/widget/desktop_widget_unittest.cc
@@ -51,16 +51,14 @@ TEST_F(DesktopScreenPositionClientTest, PositionControlWithNonRootParent) {
// Create 3 windows. A root window, an arbitrary window parented to the root
// but NOT positioned at (0,0) relative to the root, and then a third window
// parented to the second, also not positioned at (0,0).
- Widget::InitParams params1 =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
+ Widget::InitParams params1 = CreateParams(Widget::InitParams::TYPE_WINDOW);
params1.bounds = gfx::Rect(
origin + work_area.OffsetFromOrigin(),
gfx::Size(700, work_area.height() - origin.y() - work_area.y()));
params1.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget1.Init(std::move(params1));
- Widget::InitParams params2 =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
+ Widget::InitParams params2 = CreateParams(Widget::InitParams::TYPE_WINDOW);
params2.bounds = gfx::Rect(origin, gfx::Size(600, work_area.height() - 100));
params2.parent = widget1.GetNativeView();
params2.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
@@ -69,8 +67,7 @@ TEST_F(DesktopScreenPositionClientTest, PositionControlWithNonRootParent) {
params2, &widget2, test::kStubCapture, nullptr);
widget2.Init(std::move(params2));
- Widget::InitParams params3 =
- CreateParams(Widget::InitParams::TYPE_CONTROL);
+ Widget::InitParams params3 = CreateParams(Widget::InitParams::TYPE_CONTROL);
params3.parent = widget2.GetNativeView();
params3.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params3.child = true;
diff --git a/chromium/ui/views/widget/drop_helper.cc b/chromium/ui/views/widget/drop_helper.cc
index 571361a64b4..445cd80b3e4 100644
--- a/chromium/ui/views/widget/drop_helper.cc
+++ b/chromium/ui/views/widget/drop_helper.cc
@@ -4,6 +4,8 @@
#include "ui/views/widget/drop_helper.h"
+#include <set>
+
#include "base/callback.h"
#include "base/no_destructor.h"
#include "build/build_config.h"
@@ -48,8 +50,8 @@ int DropHelper::OnDragOver(const OSExchangeData& data,
const gfx::Point& root_view_location,
int drag_operation) {
const View* old_deepest_view = deepest_view_;
- View* view = CalculateTargetViewImpl(root_view_location, data, true,
- &deepest_view_);
+ View* view =
+ CalculateTargetViewImpl(root_view_location, data, true, &deepest_view_);
if (view != target_view_) {
// Target changed. Notify old drag exited, then new drag entered.
@@ -96,19 +98,17 @@ int DropHelper::OnDrop(const OSExchangeData& data,
return drop_view->OnPerformDrop(drop_event);
}
-View* DropHelper::CalculateTargetView(
- const gfx::Point& root_view_location,
- const OSExchangeData& data,
- bool check_can_drop) {
+View* DropHelper::CalculateTargetView(const gfx::Point& root_view_location,
+ const OSExchangeData& data,
+ bool check_can_drop) {
return CalculateTargetViewImpl(root_view_location, data, check_can_drop,
nullptr);
}
-View* DropHelper::CalculateTargetViewImpl(
- const gfx::Point& root_view_location,
- const OSExchangeData& data,
- bool check_can_drop,
- View** deepest_view) {
+View* DropHelper::CalculateTargetViewImpl(const gfx::Point& root_view_location,
+ const OSExchangeData& data,
+ bool check_can_drop,
+ View** deepest_view) {
View* view = root_view_->GetEventHandlerForPoint(root_view_location);
if (view == deepest_view_) {
// The view the mouse is over hasn't changed; reuse the target.
@@ -116,9 +116,9 @@ View* DropHelper::CalculateTargetViewImpl(
}
if (deepest_view)
*deepest_view = view;
- // TODO(sky): for the time being these are separate. Once I port chrome menu
- // I can switch to the #else implementation and nuke the OS_WIN
- // implementation.
+ // TODO(sky): for the time being these are separate. Once I port chrome menu
+ // I can switch to the #else implementation and nuke the OS_WIN
+ // implementation.
#if defined(OS_WIN)
// View under mouse changed, which means a new view may want the drop.
// Walk the tree, stopping at target_view_ as we know it'll accept the
diff --git a/chromium/ui/views/widget/native_widget_aura.cc b/chromium/ui/views/widget/native_widget_aura.cc
index a30e4d8264a..efd53803fa4 100644
--- a/chromium/ui/views/widget/native_widget_aura.cc
+++ b/chromium/ui/views/widget/native_widget_aura.cc
@@ -109,8 +109,8 @@ NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate* delegate)
// static
void NativeWidgetAura::RegisterNativeWidgetForWindow(
- internal::NativeWidgetPrivate* native_widget,
- aura::Window* window) {
+ internal::NativeWidgetPrivate* native_widget,
+ aura::Window* window) {
window->SetProperty(kNativeWidgetPrivateKey, native_widget);
}
@@ -230,8 +230,8 @@ void NativeWidgetAura::InitNativeWidget(Widget::InitParams params) {
if (parent) {
parent->AddChild(window_);
} else {
- aura::client::ParentWindowWithContext(
- window_, context->GetRootWindow(), window_bounds);
+ aura::client::ParentWindowWithContext(window_, context->GetRootWindow(),
+ window_bounds);
}
window_->AddObserver(this);
@@ -400,8 +400,7 @@ void NativeWidgetAura::CenterWindow(const gfx::Size& size) {
gfx::Rect window_bounds(
parent_bounds.x() + (parent_bounds.width() - size.width()) / 2,
parent_bounds.y() + (parent_bounds.height() - size.height()) / 2,
- size.width(),
- size.height());
+ size.width(), size.height());
// Don't size the window bigger than the parent, otherwise the user may not be
// able to close or move it.
window_bounds.AdjustToFit(parent_bounds);
@@ -409,7 +408,7 @@ void NativeWidgetAura::CenterWindow(const gfx::Size& size) {
// Convert the bounds back relative to the parent.
gfx::Point origin = window_bounds.origin();
aura::Window::ConvertPointToTarget(window_->GetRootWindow(),
- window_->parent(), &origin);
+ window_->parent(), &origin);
window_bounds.set_origin(origin);
window_->SetBounds(window_bounds);
}
@@ -419,8 +418,8 @@ void NativeWidgetAura::GetWindowPlacement(
ui::WindowShowState* show_state) const {
// The interface specifies returning restored bounds, not current bounds.
*bounds = GetRestoredBounds();
- *show_state = window_ ? window_->GetProperty(aura::client::kShowStateKey) :
- ui::SHOW_STATE_DEFAULT;
+ *show_state = window_ ? window_->GetProperty(aura::client::kShowStateKey)
+ : ui::SHOW_STATE_DEFAULT;
}
bool NativeWidgetAura::SetWindowTitle(const base::string16& title) {
@@ -440,6 +439,10 @@ void NativeWidgetAura::SetWindowIcons(const gfx::ImageSkia& window_icon,
void NativeWidgetAura::InitModalType(ui::ModalType modal_type) {
if (modal_type != ui::MODAL_TYPE_NONE)
window_->SetProperty(aura::client::kModalKey, modal_type);
+ if (modal_type == ui::MODAL_TYPE_WINDOW) {
+ wm::TransientWindowManager::GetOrCreate(window_)
+ ->set_parent_controls_visibility(true);
+ }
}
gfx::Rect NativeWidgetAura::GetWindowBoundsInScreen() const {
@@ -644,12 +647,12 @@ void NativeWidgetAura::Minimize() {
bool NativeWidgetAura::IsMaximized() const {
return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
- ui::SHOW_STATE_MAXIMIZED;
+ ui::SHOW_STATE_MAXIMIZED;
}
bool NativeWidgetAura::IsMinimized() const {
return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
- ui::SHOW_STATE_MINIMIZED;
+ ui::SHOW_STATE_MINIMIZED;
}
void NativeWidgetAura::Restore() {
@@ -666,7 +669,7 @@ void NativeWidgetAura::SetFullscreen(bool fullscreen) {
bool NativeWidgetAura::IsFullscreen() const {
return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
- ui::SHOW_STATE_FULLSCREEN;
+ ui::SHOW_STATE_FULLSCREEN;
}
void NativeWidgetAura::SetCanAppearInExistingFullscreenSpaces(
@@ -761,7 +764,7 @@ Widget::MoveLoopResult NativeWidgetAura::RunMoveLoop(
SetCapture();
wm::WindowMoveSource window_move_source =
- source == Widget::MOVE_LOOP_SOURCE_MOUSE ? wm::WINDOW_MOVE_SOURCE_MOUSE
+ source == Widget::MoveLoopSource::kMouse ? wm::WINDOW_MOVE_SOURCE_MOUSE
: wm::WINDOW_MOVE_SOURCE_TOUCH;
if (move_client->RunMoveLoop(window_, drag_offset, window_move_source) ==
wm::MOVE_SUCCESSFUL) {
@@ -821,6 +824,10 @@ void NativeWidgetAura::OnSizeConstraintsChanged() {
SetResizeBehaviorFromDelegate(GetWidget()->widget_delegate(), window_);
}
+void NativeWidgetAura::OnNativeViewHierarchyWillChange() {}
+
+void NativeWidgetAura::OnNativeViewHierarchyChanged() {}
+
std::string NativeWidgetAura::GetName() const {
return window_ ? window_->GetName() : std::string();
}
@@ -860,8 +867,8 @@ int NativeWidgetAura::GetNonClientComponent(const gfx::Point& point) const {
}
bool NativeWidgetAura::ShouldDescendIntoChildForEventHandling(
- aura::Window* child,
- const gfx::Point& location) {
+ aura::Window* child,
+ const gfx::Point& location) {
return delegate_->ShouldDescendIntoChildForEventHandling(
window_->layer(), child, child->layer(), location);
}
@@ -1018,14 +1025,14 @@ void NativeWidgetAura::OnWindowFocused(aura::Window* gained_focus,
void NativeWidgetAura::OnDragEntered(const ui::DropTargetEvent& event) {
DCHECK(drop_helper_.get() != nullptr);
- last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
- event.location(), event.source_operations());
+ last_drop_operation_ = drop_helper_->OnDragOver(
+ event.data(), event.location(), event.source_operations());
}
int NativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent& event) {
DCHECK(drop_helper_.get() != nullptr);
- last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
- event.location(), event.source_operations());
+ last_drop_operation_ = drop_helper_->OnDragOver(
+ event.data(), event.location(), event.source_operations());
return last_drop_operation_;
}
@@ -1038,7 +1045,7 @@ int NativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent& event,
std::unique_ptr<ui::OSExchangeData> data) {
DCHECK(drop_helper_.get() != nullptr);
return drop_helper_->OnDrop(event.data(), event.location(),
- last_drop_operation_);
+ last_drop_operation_);
}
////////////////////////////////////////////////////////////////////////////////
@@ -1215,8 +1222,8 @@ void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view,
// matches our previous behaviour; the global stacking client would almost
// always reattach the window to the same RootWindow.
aura::Window* root_window = native_view->GetRootWindow();
- aura::client::ParentWindowWithContext(
- native_view, root_window, root_window->GetBoundsInScreen());
+ aura::client::ParentWindowWithContext(native_view, root_window,
+ root_window->GetBoundsInScreen());
}
// And now, notify them that they have a brand new parent.
diff --git a/chromium/ui/views/widget/native_widget_aura.h b/chromium/ui/views/widget/native_widget_aura.h
index b31bef115e8..df9c3d83096 100644
--- a/chromium/ui/views/widget/native_widget_aura.h
+++ b/chromium/ui/views/widget/native_widget_aura.h
@@ -5,6 +5,7 @@
#ifndef UI_VIEWS_WIDGET_NATIVE_WIDGET_AURA_H_
#define UI_VIEWS_WIDGET_NATIVE_WIDGET_AURA_H_
+#include <memory>
#include <string>
#include "base/macros.h"
@@ -67,7 +68,7 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
static void SetResizeBehaviorFromDelegate(WidgetDelegate* delegate,
aura::Window* window);
- // Overridden from internal::NativeWidgetPrivate:
+ // internal::NativeWidgetPrivate:
void InitNativeWidget(Widget::InitParams params) override;
void OnWidgetInitDone() override;
NonClientFrameView* CreateNonClientFrameView() override;
@@ -156,9 +157,11 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
bool IsTranslucentWindowOpacitySupported() const override;
ui::GestureRecognizer* GetGestureRecognizer() override;
void OnSizeConstraintsChanged() override;
+ void OnNativeViewHierarchyWillChange() override;
+ void OnNativeViewHierarchyChanged() override;
std::string GetName() const override;
- // Overridden from aura::WindowDelegate:
+ // aura::WindowDelegate:
gfx::Size GetMinimumSize() const override;
gfx::Size GetMaximumSize() const override;
void OnBoundsChanged(const gfx::Rect& old_bounds,
@@ -180,32 +183,32 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
void GetHitTestMask(SkPath* mask) const override;
void UpdateVisualState() override;
- // Overridden from aura::WindowObserver:
+ // aura::WindowObserver:
void OnWindowPropertyChanged(aura::Window* window,
const void* key,
intptr_t old) override;
void OnResizeLoopStarted(aura::Window* window) override;
void OnResizeLoopEnded(aura::Window* window) override;
- // Overridden from ui::EventHandler:
+ // ui::EventHandler:
void OnKeyEvent(ui::KeyEvent* event) override;
void OnMouseEvent(ui::MouseEvent* event) override;
void OnScrollEvent(ui::ScrollEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
- // Overridden from wm::ActivationDelegate:
+ // wm::ActivationDelegate:
bool ShouldActivate() const override;
- // Overridden from wm::ActivationChangeObserver:
+ // wm::ActivationChangeObserver:
void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override;
- // Overridden from aura::client::FocusChangeObserver:
+ // aura::client::FocusChangeObserver:
void OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) override;
- // Overridden from aura::client::DragDropDelegate:
+ // aura::client::DragDropDelegate:
void OnDragEntered(const ui::DropTargetEvent& event) override;
int OnDragUpdated(const ui::DropTargetEvent& event) override;
void OnDragExited() override;
diff --git a/chromium/ui/views/widget/native_widget_aura_unittest.cc b/chromium/ui/views/widget/native_widget_aura_unittest.cc
index 4ddad6d7a06..5bd2526da57 100644
--- a/chromium/ui/views/widget/native_widget_aura_unittest.cc
+++ b/chromium/ui/views/widget/native_widget_aura_unittest.cc
@@ -5,6 +5,7 @@
#include "ui/views/widget/native_widget_aura.h"
#include <memory>
+#include <utility>
#include "base/command_line.h"
#include "base/macros.h"
@@ -33,7 +34,7 @@ namespace {
NativeWidgetAura* Init(aura::Window* parent, Widget* widget) {
Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.parent = parent;
widget->Init(std::move(params));
return static_cast<NativeWidgetAura*>(widget->native_widget());
@@ -97,9 +98,7 @@ TEST_F(NativeWidgetAuraTest, CenterWindowLargeParent) {
NativeWidgetAura* window = Init(parent.get(), widget.get());
window->CenterWindow(gfx::Size(100, 100));
- EXPECT_EQ(gfx::Rect((640 - 100) / 2,
- (480 - 100) / 2,
- 100, 100),
+ EXPECT_EQ(gfx::Rect((640 - 100) / 2, (480 - 100) / 2, 100, 100),
window->GetNativeWindow()->bounds());
widget->CloseNow();
}
@@ -114,9 +113,7 @@ TEST_F(NativeWidgetAuraTest, CenterWindowSmallParent) {
NativeWidgetAura* window = Init(parent.get(), widget.get());
window->CenterWindow(gfx::Size(100, 100));
- EXPECT_EQ(gfx::Rect((480 - 100) / 2,
- (320 - 100) / 2,
- 100, 100),
+ EXPECT_EQ(gfx::Rect((480 - 100) / 2, (320 - 100) / 2, 100, 100),
window->GetNativeWindow()->bounds());
widget->CloseNow();
}
@@ -158,9 +155,7 @@ class TestWindowObserver : public aura::WindowObserver {
explicit TestWindowObserver(gfx::NativeWindow window) : window_(window) {
window_->AddObserver(this);
}
- ~TestWindowObserver() override {
- window_->RemoveObserver(this);
- }
+ ~TestWindowObserver() override { window_->RemoveObserver(this); }
// aura::WindowObserver:
void OnWindowPropertyChanged(aura::Window* window,
@@ -181,7 +176,7 @@ class TestWindowObserver : public aura::WindowObserver {
int count_ = 0;
ui::WindowShowState state_ = ui::WindowShowState::SHOW_STATE_DEFAULT;
- DISALLOW_COPY_AND_ASSIGN(TestWindowObserver);
+ DISALLOW_COPY_AND_ASSIGN(TestWindowObserver);
};
// Tests that window transitions from normal to minimized and back do not
@@ -255,7 +250,7 @@ class MaximizeLayoutManager : public TestLayoutManagerBase {
// This simulates BrowserView, which creates a custom RootView so that
// OnNativeWidgetSizeChanged that is invoked during Init matters.
-class TestWidget : public views::Widget {
+class TestWidget : public Widget {
public:
TestWidget() = default;
@@ -289,7 +284,7 @@ TEST_F(NativeWidgetAuraTest, ShowMaximizedDoesntBounceAround) {
root_window()->SetLayoutManager(new MaximizeLayoutManager);
std::unique_ptr<TestWidget> widget(new TestWidget());
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.parent = nullptr;
params.context = root_window();
params.show_state = ui::SHOW_STATE_MAXIMIZED;
@@ -321,13 +316,13 @@ class PropertyTestLayoutManager : public TestLayoutManagerBase {
DISALLOW_COPY_AND_ASSIGN(PropertyTestLayoutManager);
};
-class PropertyTestWidgetDelegate : public views::WidgetDelegate {
+class PropertyTestWidgetDelegate : public WidgetDelegate {
public:
explicit PropertyTestWidgetDelegate(Widget* widget) : widget_(widget) {}
~PropertyTestWidgetDelegate() override = default;
private:
- // views::WidgetDelegate:
+ // WidgetDelegate:
bool CanMaximize() const override { return true; }
bool CanMinimize() const override { return true; }
bool CanResize() const override { return true; }
@@ -346,7 +341,7 @@ TEST_F(NativeWidgetAuraTest, TestPropertiesWhenAddedToLayout) {
root_window()->SetLayoutManager(layout_manager);
std::unique_ptr<TestWidget> widget(new TestWidget());
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.delegate = new PropertyTestWidgetDelegate(widget.get());
params.parent = nullptr;
params.context = root_window();
@@ -358,7 +353,7 @@ TEST_F(NativeWidgetAuraTest, TestPropertiesWhenAddedToLayout) {
TEST_F(NativeWidgetAuraTest, GetClientAreaScreenBounds) {
// Create a widget.
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.context = root_window();
params.bounds.SetRect(10, 20, 300, 400);
std::unique_ptr<Widget> widget(new Widget());
@@ -373,20 +368,14 @@ TEST_F(NativeWidgetAuraTest, GetClientAreaScreenBounds) {
}
// View subclass that tracks whether it has gotten a gesture event.
-class GestureTrackingView : public views::View {
+class GestureTrackingView : public View {
public:
GestureTrackingView() = default;
- void set_consume_gesture_event(bool value) {
- consume_gesture_event_ = value;
- }
+ void set_consume_gesture_event(bool value) { consume_gesture_event_ = value; }
- void clear_got_gesture_event() {
- got_gesture_event_ = false;
- }
- bool got_gesture_event() const {
- return got_gesture_event_;
- }
+ void clear_got_gesture_event() { got_gesture_event_ = false; }
+ bool got_gesture_event() const { return got_gesture_event_; }
// View overrides:
void OnGestureEvent(ui::GestureEvent* event) override {
@@ -417,7 +406,7 @@ TEST_F(NativeWidgetAuraTest, DontCaptureOnGesture) {
view->AddChildView(child);
std::unique_ptr<TestWidget> widget(new TestWidget());
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.context = root_window();
params.bounds = gfx::Rect(0, 0, 100, 200);
widget->Init(std::move(params));
@@ -447,20 +436,15 @@ TEST_F(NativeWidgetAuraTest, DontCaptureOnGesture) {
EXPECT_TRUE(view->got_gesture_event());
EXPECT_FALSE(child->got_gesture_event());
view->clear_got_gesture_event();
-
- // Work around for bug in NativeWidgetAura.
- // TODO: fix bug and remove this.
- widget->Close();
}
// Verifies views with layers are targeted for events properly.
TEST_F(NativeWidgetAuraTest, PreferViewLayersToChildWindows) {
// Create two widgets: |parent| and |child|. |child| is a child of |parent|.
- views::View* parent_root = new views::View;
+ View* parent_root = new View;
std::unique_ptr<Widget> parent(new Widget());
Widget::InitParams parent_params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- parent_params.ownership =
- views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ parent_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
parent_params.context = root_window();
parent->Init(std::move(parent_params));
parent->SetContentsView(parent_root);
@@ -469,51 +453,46 @@ TEST_F(NativeWidgetAuraTest, PreferViewLayersToChildWindows) {
std::unique_ptr<Widget> child(new Widget());
Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
- child_params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
child_params.parent = parent->GetNativeWindow();
child->Init(std::move(child_params));
child->SetBounds(gfx::Rect(0, 0, 200, 200));
child->Show();
// Point is over |child|.
- EXPECT_EQ(child->GetNativeWindow(),
- parent->GetNativeWindow()->GetEventHandlerForPoint(
- gfx::Point(50, 50)));
+ EXPECT_EQ(
+ child->GetNativeWindow(),
+ parent->GetNativeWindow()->GetEventHandlerForPoint(gfx::Point(50, 50)));
// Create a view with a layer and stack it at the bottom (below |child|).
- views::View* view_with_layer = new views::View;
+ View* view_with_layer = new View;
parent_root->AddChildView(view_with_layer);
view_with_layer->SetBounds(0, 0, 50, 50);
view_with_layer->SetPaintToLayer();
// Make sure that |child| still gets the event.
- EXPECT_EQ(child->GetNativeWindow(),
- parent->GetNativeWindow()->GetEventHandlerForPoint(
- gfx::Point(20, 20)));
+ EXPECT_EQ(
+ child->GetNativeWindow(),
+ parent->GetNativeWindow()->GetEventHandlerForPoint(gfx::Point(20, 20)));
// Move |view_with_layer| to the top and make sure it gets the
// event when the point is within |view_with_layer|'s bounds.
- view_with_layer->layer()->parent()->StackAtTop(
- view_with_layer->layer());
- EXPECT_EQ(parent->GetNativeWindow(),
- parent->GetNativeWindow()->GetEventHandlerForPoint(
- gfx::Point(20, 20)));
+ view_with_layer->layer()->parent()->StackAtTop(view_with_layer->layer());
+ EXPECT_EQ(
+ parent->GetNativeWindow(),
+ parent->GetNativeWindow()->GetEventHandlerForPoint(gfx::Point(20, 20)));
// Point is over |child|, it should get the event.
- EXPECT_EQ(child->GetNativeWindow(),
- parent->GetNativeWindow()->GetEventHandlerForPoint(
- gfx::Point(70, 70)));
+ EXPECT_EQ(
+ child->GetNativeWindow(),
+ parent->GetNativeWindow()->GetEventHandlerForPoint(gfx::Point(70, 70)));
delete view_with_layer;
view_with_layer = nullptr;
- EXPECT_EQ(child->GetNativeWindow(),
- parent->GetNativeWindow()->GetEventHandlerForPoint(
- gfx::Point(20, 20)));
-
- // Work around for bug in NativeWidgetAura.
- // TODO: fix bug and remove this.
- parent->Close();
+ EXPECT_EQ(
+ child->GetNativeWindow(),
+ parent->GetNativeWindow()->GetEventHandlerForPoint(gfx::Point(20, 20)));
}
// Verifies views with layers are targeted for events properly.
@@ -570,7 +549,7 @@ TEST_F(NativeWidgetAuraTest, FlashFrame) {
std::unique_ptr<Widget> widget(new Widget());
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
params.context = root_window();
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(std::move(params));
aura::Window* window = widget->GetNativeWindow();
EXPECT_FALSE(window->GetProperty(aura::client::kDrawAttentionKey));
@@ -621,14 +600,12 @@ class MoveTestWidgetDelegate : public WidgetDelegateView {
TEST_F(NativeWidgetAuraTest, OnWidgetMovedInvokedAfterAcquireLayer) {
// |delegate| deletes itself when the widget is destroyed.
MoveTestWidgetDelegate* delegate = new MoveTestWidgetDelegate;
- Widget* widget =
- Widget::CreateWindowWithContextAndBounds(delegate,
- root_window(),
- gfx::Rect(10, 10, 100, 200));
+ Widget* widget = Widget::CreateWindowWithContext(delegate, root_window(),
+ gfx::Rect(10, 10, 100, 200));
widget->Show();
delegate->ClearGotMove();
// Simulate a maximize with animation.
- delete widget->GetNativeView()->RecreateLayer().release();
+ widget->GetNativeView()->RecreateLayer();
widget->SetBounds(gfx::Rect(0, 0, 500, 500));
EXPECT_TRUE(delegate->got_move());
widget->CloseNow();
@@ -639,12 +616,12 @@ TEST_F(NativeWidgetAuraTest, OnWidgetMovedInvokedAfterAcquireLayer) {
// can not be activated.
TEST_F(NativeWidgetAuraTest, PreventFocusOnNonActivableWindow) {
test_focus_rules()->set_can_activate(false);
- views::test::TestInitialFocusWidgetDelegate delegate(root_window());
+ test::TestInitialFocusWidgetDelegate delegate(root_window());
delegate.GetWidget()->Show();
EXPECT_FALSE(delegate.view()->HasFocus());
test_focus_rules()->set_can_activate(true);
- views::test::TestInitialFocusWidgetDelegate delegate2(root_window());
+ test::TestInitialFocusWidgetDelegate delegate2(root_window());
delegate2.GetWidget()->Show();
EXPECT_TRUE(delegate2.view()->HasFocus());
}
@@ -683,5 +660,65 @@ TEST_F(NativeWidgetAuraTest, VisibilityOfChildBubbleWindow) {
EXPECT_TRUE(child.IsVisible());
}
+class ModalWidgetDelegate : public WidgetDelegate {
+ public:
+ explicit ModalWidgetDelegate(Widget* widget) : widget_(widget) {}
+ ~ModalWidgetDelegate() override = default;
+
+ // WidgetDelegate:
+ void DeleteDelegate() override { delete this; }
+ Widget* GetWidget() override { return widget_; }
+ const Widget* GetWidget() const override { return widget_; }
+ ui::ModalType GetModalType() const override {
+ return ui::ModalType::MODAL_TYPE_WINDOW;
+ }
+
+ private:
+ Widget* widget_;
+
+ DISALLOW_COPY_AND_ASSIGN(ModalWidgetDelegate);
+};
+
+// Tests that for a child transient window, if its modal type is
+// ui::MODAL_TYPE_WINDOW, then its visibility is controlled by its transient
+// parent's visibility.
+TEST_F(NativeWidgetAuraTest, TransientChildModalWindowVisibility) {
+ // Create a parent window.
+ Widget parent;
+ Widget::InitParams parent_params(Widget::InitParams::TYPE_WINDOW);
+ parent_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ parent_params.context = root_window();
+ parent.Init(std::move(parent_params));
+ parent.SetBounds(gfx::Rect(0, 0, 400, 400));
+ parent.Show();
+ EXPECT_TRUE(parent.IsVisible());
+
+ // Create a ui::MODAL_TYPE_WINDOW modal type transient child window.
+ Widget child;
+ Widget::InitParams child_params(Widget::InitParams::TYPE_WINDOW);
+ child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ child_params.parent = parent.GetNativeWindow();
+ child_params.delegate = new ModalWidgetDelegate(&child);
+ child.Init(std::move(child_params));
+ child.SetBounds(gfx::Rect(0, 0, 200, 200));
+ child.Show();
+ EXPECT_TRUE(parent.IsVisible());
+ EXPECT_TRUE(child.IsVisible());
+
+ // Hide the parent window should also hide the child window.
+ parent.Hide();
+ EXPECT_FALSE(parent.IsVisible());
+ EXPECT_FALSE(child.IsVisible());
+
+ // The child window can't be shown if the parent window is hidden.
+ child.Show();
+ EXPECT_FALSE(parent.IsVisible());
+ EXPECT_FALSE(child.IsVisible());
+
+ parent.Show();
+ EXPECT_TRUE(parent.IsVisible());
+ EXPECT_TRUE(child.IsVisible());
+}
+
} // namespace
} // namespace views
diff --git a/chromium/ui/views/widget/native_widget_delegate.h b/chromium/ui/views/widget/native_widget_delegate.h
index ea5da66b67f..d8ed38d2de5 100644
--- a/chromium/ui/views/widget/native_widget_delegate.h
+++ b/chromium/ui/views/widget/native_widget_delegate.h
@@ -14,7 +14,7 @@ class SkPath;
namespace gfx {
class Point;
class Size;
-}
+} // namespace gfx
namespace ui {
class GestureEvent;
@@ -23,7 +23,7 @@ class Layer;
class MouseEvent;
class PaintContext;
class ScrollEvent;
-}
+} // namespace ui
namespace views {
class Widget;
diff --git a/chromium/ui/views/widget/native_widget_mac.h b/chromium/ui/views/widget/native_widget_mac.h
index dd64370ab98..24b98636751 100644
--- a/chromium/ui/views/widget/native_widget_mac.h
+++ b/chromium/ui/views/widget/native_widget_mac.h
@@ -5,7 +5,11 @@
#ifndef UI_VIEWS_WIDGET_NATIVE_WIDGET_MAC_H_
#define UI_VIEWS_WIDGET_NATIVE_WIDGET_MAC_H_
+#include <memory>
+#include <string>
+
#include "base/macros.h"
+#include "ui/base/ime/input_method_delegate.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/widget/native_widget_private.h"
@@ -31,10 +35,12 @@ namespace test {
class HitTestNativeWidgetMac;
class MockNativeWidgetMac;
class WidgetTest;
-}
+} // namespace test
class NativeWidgetMacNSWindowHost;
-class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
+class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate,
+ public FocusChangeListener,
+ public ui::internal::InputMethodDelegate {
public:
explicit NativeWidgetMac(internal::NativeWidgetDelegate* delegate);
~NativeWidgetMac() override;
@@ -49,6 +55,9 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
// destroyed.
void WindowDestroyed();
+ // Called when the backing NSWindow gains or loses key status.
+ void OnWindowKeyStatusChanged(bool is_key, bool is_content_first_responder);
+
// The vertical position from which sheets should be anchored, from the top
// of the content view.
virtual int32_t SheetOffsetY();
@@ -174,6 +183,8 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
bool IsTranslucentWindowOpacitySupported() const override;
ui::GestureRecognizer* GetGestureRecognizer() override;
void OnSizeConstraintsChanged() override;
+ void OnNativeViewHierarchyWillChange() override;
+ void OnNativeViewHierarchyChanged() override;
std::string GetName() const override;
// Calls |callback| with the newly created NativeWidget whenever a
@@ -182,6 +193,11 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
base::RepeatingCallback<void(NativeWidgetMac*)> callback);
protected:
+ // The argument to SetBounds is sometimes in screen coordinates and sometimes
+ // in parent window coordinates. This function will take that bounds argument
+ // and convert it to screen coordinates if needed.
+ gfx::Rect ConvertBoundsToScreenIfNeeded(const gfx::Rect& bounds) const;
+
virtual void PopulateCreateWindowParams(
const Widget::InitParams& widget_params,
remote_cocoa::mojom::CreateWindowParams* params) {}
@@ -220,13 +236,22 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
return ns_window_host_.get();
}
+ // Unregister focus listeners from previous focus manager, and register them
+ // with the |new_focus_manager|. Updates |focus_manager_|.
+ void SetFocusManager(FocusManager* new_focus_manager);
+
+ // FocusChangeListener:
+ void OnWillChangeFocus(View* focused_before, View* focused_now) override;
+ void OnDidChangeFocus(View* focused_before, View* focused_now) override;
+
+ // ui::internal::InputMethodDelegate:
+ ui::EventDispatchDetails DispatchKeyEventPostIME(ui::KeyEvent* key) override;
+
private:
friend class test::MockNativeWidgetMac;
friend class test::HitTestNativeWidgetMac;
friend class views::test::WidgetTest;
-
class ZoomFocusMonitor;
- std::unique_ptr<ZoomFocusMonitor> zoom_focus_monitor_;
internal::NativeWidgetDelegate* delegate_;
std::unique_ptr<NativeWidgetMacNSWindowHost> ns_window_host_;
@@ -240,6 +265,14 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
Widget::InitParams::Type type_;
+ // Weak pointer to the FocusManager with with |zoom_focus_monitor_| and
+ // |ns_window_host_| are registered.
+ FocusManager* focus_manager_ = nullptr;
+ std::unique_ptr<ui::InputMethod> input_method_;
+ std::unique_ptr<ZoomFocusMonitor> zoom_focus_monitor_;
+ // Held while this widget is active if it's a child.
+ std::unique_ptr<Widget::PaintAsActiveLock> parent_key_lock_;
+
DISALLOW_COPY_AND_ASSIGN(NativeWidgetMac);
};
diff --git a/chromium/ui/views/widget/native_widget_mac.mm b/chromium/ui/views/widget/native_widget_mac.mm
index 670250dfa9c..22e0bd3b5ce 100644
--- a/chromium/ui/views/widget/native_widget_mac.mm
+++ b/chromium/ui/views/widget/native_widget_mac.mm
@@ -23,6 +23,8 @@
#import "components/remote_cocoa/app_shim/views_nswindow_delegate.h"
#import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
#import "ui/base/cocoa/window_size_constants.h"
+#include "ui/base/ime/init/input_method_factory.h"
+#include "ui/base/ime/input_method.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/events/gestures/gesture_recognizer_impl_mac.h"
@@ -32,7 +34,9 @@
#include "ui/native_theme/native_theme_mac.h"
#import "ui/views/cocoa/drag_drop_client_mac.h"
#import "ui/views/cocoa/native_widget_mac_ns_window_host.h"
+#include "ui/views/cocoa/text_input_host.h"
#include "ui/views/widget/drop_helper.h"
+#include "ui/views/widget/widget_aura_utils.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/native_frame_view.h"
@@ -107,11 +111,10 @@ class NativeWidgetMac::ZoomFocusMonitor : public FocusChangeListener {
};
////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetMac, public:
+// NativeWidgetMac:
NativeWidgetMac::NativeWidgetMac(internal::NativeWidgetDelegate* delegate)
- : zoom_focus_monitor_(std::make_unique<ZoomFocusMonitor>()),
- delegate_(delegate),
+ : delegate_(delegate),
ns_window_host_(new NativeWidgetMacNSWindowHost(this)),
ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) {}
@@ -123,14 +126,13 @@ NativeWidgetMac::~NativeWidgetMac() {
}
void NativeWidgetMac::WindowDestroying() {
- if (auto* focus_manager = GetWidget()->GetFocusManager())
- focus_manager->RemoveFocusChangeListener(zoom_focus_monitor_.get());
OnWindowDestroying(GetNativeWindow());
delegate_->OnNativeWidgetDestroying();
}
void NativeWidgetMac::WindowDestroyed() {
DCHECK(GetNSWindowMojo());
+ SetFocusManager(nullptr);
ns_window_host_.reset();
// |OnNativeWidgetDestroyed| may delete |this| if the object does not own
// itself.
@@ -141,6 +143,35 @@ void NativeWidgetMac::WindowDestroyed() {
delete this;
}
+void NativeWidgetMac::OnWindowKeyStatusChanged(
+ bool is_key,
+ bool is_content_first_responder) {
+ Widget* widget = GetWidget();
+ if (!widget->OnNativeWidgetActivationChanged(is_key))
+ return;
+ // The contentView is the BridgedContentView hosting the views::RootView. The
+ // focus manager will already know if a native subview has focus.
+ if (!is_content_first_responder)
+ return;
+
+ if (is_key) {
+ widget->OnNativeFocus();
+ widget->GetFocusManager()->RestoreFocusedView();
+ if (NativeWidgetMacNSWindowHost* parent_host = ns_window_host_->parent()) {
+ // Unclear under what circumstances this would be null, but speculatively
+ // working around https://crbug/1050430
+ if (Widget* top_widget =
+ parent_host->native_widget_mac()->GetTopLevelWidget()) {
+ parent_key_lock_ = top_widget->LockPaintAsActive();
+ }
+ }
+ } else {
+ widget->OnNativeBlur();
+ widget->GetFocusManager()->StoreFocusedView(true);
+ parent_key_lock_.reset();
+ }
+}
+
int32_t NativeWidgetMac::SheetOffsetY() {
return 0;
}
@@ -161,9 +192,6 @@ bool NativeWidgetMac::ExecuteCommand(
return false;
}
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetMac, internal::NativeWidgetPrivate implementation:
-
void NativeWidgetMac::InitNativeWidget(Widget::InitParams params) {
ownership_ = params.ownership;
name_ = params.name;
@@ -194,7 +222,8 @@ void NativeWidgetMac::InitNativeWidget(Widget::InitParams params) {
ns_window_host_->CreateInProcessNSWindowBridge(std::move(window));
}
ns_window_host_->SetParent(parent_host);
- ns_window_host_->InitWindow(params);
+ ns_window_host_->InitWindow(params,
+ ConvertBoundsToScreenIfNeeded(params.bounds));
OnWindowInitialized();
// Only set the z-order here if it is non-default since setting it may affect
@@ -212,12 +241,12 @@ void NativeWidgetMac::InitNativeWidget(Widget::InitParams params) {
GetWidget()->GetRootView()->bounds());
if (auto* focus_manager = GetWidget()->GetFocusManager()) {
GetNSWindowMojo()->MakeFirstResponder();
- ns_window_host_->SetFocusManager(focus_manager);
- // Non-top-level widgets use the the top level widget's focus manager.
- if (GetWidget() == GetTopLevelWidget())
- focus_manager->AddFocusChangeListener(zoom_focus_monitor_.get());
+ // Only one ZoomFocusMonitor is needed per FocusManager, so create one only
+ // for top-level widgets.
+ if (GetWidget()->is_top_level())
+ zoom_focus_monitor_ = std::make_unique<ZoomFocusMonitor>();
+ SetFocusManager(focus_manager);
}
-
ns_window_host_->CreateCompositor(params);
if (g_init_native_widget_callback)
@@ -328,7 +357,13 @@ bool NativeWidgetMac::HasCapture() const {
}
ui::InputMethod* NativeWidgetMac::GetInputMethod() {
- return ns_window_host_ ? ns_window_host_->GetInputMethod() : nullptr;
+ if (!input_method_) {
+ input_method_ = ui::CreateInputMethod(this, gfx::kNullAcceleratedWidget);
+ // For now, use always-focused mode on Mac for the input method.
+ // TODO(tapted): Move this to OnWindowKeyStatusChangedTo() and balance.
+ input_method_->OnFocus();
+ }
+ return input_method_.get();
}
void NativeWidgetMac::CenterWindow(const gfx::Size& size) {
@@ -395,9 +430,35 @@ std::string NativeWidgetMac::GetWorkspace() const {
: std::string();
}
+gfx::Rect NativeWidgetMac::ConvertBoundsToScreenIfNeeded(
+ const gfx::Rect& bounds) const {
+ // If there isn't a parent widget, then bounds cannot be relative to the
+ // parent.
+ if (!ns_window_host_ || !ns_window_host_->parent() || !GetWidget())
+ return bounds;
+
+ // Replicate the logic in desktop_aura/desktop_screen_position_client.cc.
+ if (GetAuraWindowTypeForWidgetType(type_) ==
+ aura::client::WINDOW_TYPE_POPUP ||
+ GetWidget()->is_top_level()) {
+ return bounds;
+ }
+
+ // Empty bounds are only allowed to be specified at initialization and are
+ // expected not to be translated.
+ if (bounds.IsEmpty())
+ return bounds;
+
+ gfx::Rect bounds_in_screen = bounds;
+ bounds_in_screen.Offset(
+ ns_window_host_->parent()->GetWindowBoundsInScreen().OffsetFromOrigin());
+ return bounds_in_screen;
+}
+
void NativeWidgetMac::SetBounds(const gfx::Rect& bounds) {
- if (ns_window_host_)
- ns_window_host_->SetBounds(bounds);
+ if (!ns_window_host_)
+ return;
+ ns_window_host_->SetBoundsInScreen(ConvertBoundsToScreenIfNeeded(bounds));
}
void NativeWidgetMac::SetBoundsConstrained(const gfx::Rect& bounds) {
@@ -414,9 +475,12 @@ void NativeWidgetMac::SetBoundsConstrained(const gfx::Rect& bounds) {
}
void NativeWidgetMac::SetSize(const gfx::Size& size) {
+ if (!ns_window_host_)
+ return;
// Ensure the top-left corner stays in-place (rather than the bottom-left,
// which -[NSWindow setContentSize:] would do).
- SetBounds(gfx::Rect(GetWindowBoundsInScreen().origin(), size));
+ ns_window_host_->SetBoundsInScreen(
+ gfx::Rect(GetWindowBoundsInScreen().origin(), size));
}
void NativeWidgetMac::StackAbove(gfx::NativeView native_view) {
@@ -740,6 +804,19 @@ void NativeWidgetMac::OnSizeConstraintsChanged() {
widget->widget_delegate()->CanMaximize());
}
+void NativeWidgetMac::OnNativeViewHierarchyWillChange() {
+ // If this is not top-level, then the FocusManager may change, so remove our
+ // listeners.
+ if (!GetWidget()->is_top_level())
+ SetFocusManager(nullptr);
+ parent_key_lock_.reset();
+}
+
+void NativeWidgetMac::OnNativeViewHierarchyChanged() {
+ if (!GetWidget()->is_top_level())
+ SetFocusManager(GetWidget()->GetFocusManager());
+}
+
std::string NativeWidgetMac::GetName() const {
return name_;
}
@@ -759,9 +836,6 @@ void NativeWidgetMac::SetInitNativeWidgetCallback(
new base::RepeatingCallback<void(NativeWidgetMac*)>(std::move(callback));
}
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetMac, protected:
-
NativeWidgetMacNSWindow* NativeWidgetMac::CreateNSWindow(
const remote_cocoa::mojom::CreateWindowParams* params) {
return remote_cocoa::NativeWidgetNSWindowBridge::CreateNSWindow(params)
@@ -784,8 +858,56 @@ NativeWidgetMac::GetInProcessNSWindowBridge() const {
: nullptr;
}
+void NativeWidgetMac::SetFocusManager(FocusManager* new_focus_manager) {
+ if (focus_manager_) {
+ if (View* old_focus = focus_manager_->GetFocusedView())
+ OnDidChangeFocus(old_focus, nullptr);
+ focus_manager_->RemoveFocusChangeListener(this);
+ if (zoom_focus_monitor_)
+ focus_manager_->RemoveFocusChangeListener(zoom_focus_monitor_.get());
+ }
+ focus_manager_ = new_focus_manager;
+ if (focus_manager_) {
+ if (View* new_focus = focus_manager_->GetFocusedView())
+ OnDidChangeFocus(nullptr, new_focus);
+ focus_manager_->AddFocusChangeListener(this);
+ if (zoom_focus_monitor_)
+ focus_manager_->AddFocusChangeListener(zoom_focus_monitor_.get());
+ }
+}
+
+void NativeWidgetMac::OnWillChangeFocus(View* focused_before,
+ View* focused_now) {}
+
+void NativeWidgetMac::OnDidChangeFocus(View* focused_before,
+ View* focused_now) {
+ ui::InputMethod* input_method = GetWidget()->GetInputMethod();
+ if (!input_method)
+ return;
+
+ ui::TextInputClient* new_text_input_client =
+ input_method->GetTextInputClient();
+ // Sanity check: When focus moves away from the widget (i.e. |focused_now|
+ // is nil), then the textInputClient will be cleared.
+ DCHECK(!!focused_now || !new_text_input_client);
+ if (ns_window_host_) {
+ ns_window_host_->text_input_host()->SetTextInputClient(
+ new_text_input_client);
+ }
+}
+
+ui::EventDispatchDetails NativeWidgetMac::DispatchKeyEventPostIME(
+ ui::KeyEvent* key) {
+ DCHECK(focus_manager_);
+ if (!focus_manager_->OnKeyEvent(*key))
+ key->StopPropagation();
+ else
+ GetWidget()->OnKeyEvent(key);
+ return ui::EventDispatchDetails();
+}
+
////////////////////////////////////////////////////////////////////////////////
-// Widget, public:
+// Widget:
// static
void Widget::CloseAllSecondaryWidgets() {
@@ -821,7 +943,7 @@ const ui::NativeTheme* Widget::GetNativeTheme() const {
namespace internal {
////////////////////////////////////////////////////////////////////////////////
-// internal::NativeWidgetPrivate, public:
+// internal::NativeWidgetPrivate:
// static
NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget(
@@ -921,74 +1043,49 @@ void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view,
}
// static
-void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view,
+void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView child,
gfx::NativeView new_parent) {
- DCHECK_NE(native_view, new_parent);
+ DCHECK_NE(child, new_parent);
DCHECK([new_parent.GetNativeNSView() window]);
- if (!new_parent || [native_view.GetNativeNSView() superview] ==
- new_parent.GetNativeNSView()) {
+ if (!new_parent ||
+ [child.GetNativeNSView() superview] == new_parent.GetNativeNSView()) {
NOTREACHED();
return;
}
- NativeWidgetMacNSWindowHost* window_host =
- NativeWidgetMacNSWindowHost::GetFromNativeView(native_view);
- DCHECK(window_host);
- gfx::NativeView bridge_view =
- window_host->native_widget_mac()->GetNativeView();
- gfx::NativeWindow bridge_window =
- window_host->native_widget_mac()->GetNativeWindow();
- bool bridge_is_top_level =
- window_host->native_widget_mac()->GetWidget()->is_top_level();
- DCHECK([native_view.GetNativeNSView()
- isDescendantOf:bridge_view.GetNativeNSView()]);
- DCHECK(bridge_window && ![bridge_window.GetNativeNSWindow() isSheet]);
+ NativeWidgetMacNSWindowHost* child_window_host =
+ NativeWidgetMacNSWindowHost::GetFromNativeView(child);
+ DCHECK(child_window_host);
+ gfx::NativeView widget_view =
+ child_window_host->native_widget_mac()->GetNativeView();
+ DCHECK_EQ(child, widget_view);
+ gfx::NativeWindow widget_window =
+ child_window_host->native_widget_mac()->GetNativeWindow();
+ DCHECK(
+ [child.GetNativeNSView() isDescendantOf:widget_view.GetNativeNSView()]);
+ DCHECK(widget_window && ![widget_window.GetNativeNSWindow() isSheet]);
NativeWidgetMacNSWindowHost* parent_window_host =
NativeWidgetMacNSWindowHost::GetFromNativeView(new_parent);
// Early out for no-op changes.
- if (native_view == bridge_view && bridge_is_top_level &&
- window_host->parent() == parent_window_host) {
+ if (child == widget_view &&
+ child_window_host->parent() == parent_window_host) {
return;
}
// First notify all the widgets that they are being disassociated from their
// previous parent.
Widget::Widgets widgets;
- GetAllChildWidgets(native_view, &widgets);
- for (auto* child : widgets)
- child->NotifyNativeViewHierarchyWillChange();
-
- // Update |bridge_host|'s parent only if
- // NativeWidgetNSWindowBridge::ReparentNativeView will.
- if (native_view == bridge_view) {
- window_host->SetParent(parent_window_host);
- if (!bridge_is_top_level) {
- // Make |window_host|'s NSView be a child of |new_parent| by adding it as
- // a subview. Note that this will have the effect of removing
- // |window_host|'s NSView from its NSWindow. The |NSWindow| must remain
- // visible because it controls the bounds and visibility of the ui::Layer,
- // so just hide it by setting alpha value to zero.
- // TODO(ccameron): This path likely violates assumptions. Verify that this
- // path is unused and remove it.
- LOG(ERROR) << "Reparenting a non-top-level BridgedNativeWidget. This is "
- "likely unsupported.";
- [new_parent.GetNativeNSView() addSubview:native_view.GetNativeNSView()];
- [bridge_window.GetNativeNSWindow() setAlphaValue:0];
- [bridge_window.GetNativeNSWindow() setIgnoresMouseEvents:YES];
- }
- } else {
- // TODO(ccameron): This path likely violates assumptions. Verify that this
- // path is unused and remove it.
- LOG(ERROR) << "Reparenting with a non-root BridgedNativeWidget NSView. "
- "This is likely unsupported.";
- [new_parent.GetNativeNSView() addSubview:native_view.GetNativeNSView()];
- }
+ GetAllChildWidgets(child, &widgets);
+ for (auto* widget : widgets)
+ widget->NotifyNativeViewHierarchyWillChange();
+
+ child_window_host->SetParent(parent_window_host);
// And now, notify them that they have a brand new parent.
- for (auto* child : widgets)
- child->NotifyNativeViewHierarchyChanged();
+ for (auto* widget : widgets)
+ widget->NotifyNativeViewHierarchyChanged();
}
// static
diff --git a/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm b/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm
index f8cf2390153..77a8c22c22a 100644
--- a/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm
+++ b/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm
@@ -199,15 +199,21 @@ TEST_F(NativeWidgetMacInteractiveUITest, ParentWindowTrafficLights) {
EXPECT_TRUE(button);
NSData* active_button_image = ViewAsTIFF(button);
EXPECT_TRUE(active_button_image);
-
- // Pop open a bubble on the parent Widget. When the visibility of Bubbles with
- // an anchor View changes, BubbleDialogDelegateView::HandleVisibilityChanged()
- // updates Widget::ShouldPaintAsActive() accordingly.
- ShowKeyWindow(BubbleDialogDelegateView::CreateBubble(
- new TestBubbleView(parent_widget)));
+ EXPECT_TRUE(parent_widget->ShouldPaintAsActive());
+
+ // If a child widget is key, the parent should paint as active.
+ Widget* child_widget = new Widget;
+ Widget::InitParams params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ params.parent = parent_widget->GetNativeView();
+ child_widget->Init(std::move(params));
+ child_widget->SetContentsView(new View);
+ child_widget->Show();
+ NSWindow* child = child_widget->GetNativeWindow().GetNativeNSWindow();
// Ensure the button instance is still valid.
EXPECT_EQ(button, [parent standardWindowButton:NSWindowCloseButton]);
+ EXPECT_TRUE(parent_widget->ShouldPaintAsActive());
// Parent window should still be main, and have its traffic lights active.
EXPECT_TRUE([parent isMainWindow]);
@@ -226,10 +232,18 @@ TEST_F(NativeWidgetMacInteractiveUITest, ParentWindowTrafficLights) {
ShowKeyWindow(other_widget);
EXPECT_FALSE([parent isMainWindow]);
EXPECT_FALSE([parent isKeyWindow]);
+ EXPECT_FALSE(parent_widget->ShouldPaintAsActive());
EXPECT_TRUE([button isEnabled]);
NSData* inactive_button_image = ViewAsTIFF(button);
EXPECT_FALSE([active_button_image isEqualToData:inactive_button_image]);
+ // Focus the child again and assert the parent once again paints as active.
+ [child makeKeyWindow];
+ EXPECT_TRUE(parent_widget->ShouldPaintAsActive());
+ EXPECT_TRUE([child isKeyWindow]);
+ EXPECT_FALSE([parent isKeyWindow]);
+
+ child_widget->CloseNow();
other_widget->CloseNow();
parent_widget->CloseNow();
}
diff --git a/chromium/ui/views/widget/native_widget_mac_unittest.mm b/chromium/ui/views/widget/native_widget_mac_unittest.mm
index f7a9964d6d8..90c111179a7 100644
--- a/chromium/ui/views/widget/native_widget_mac_unittest.mm
+++ b/chromium/ui/views/widget/native_widget_mac_unittest.mm
@@ -69,10 +69,10 @@
@interface MockBridgedView : NSView {
@private
// Number of times -[NSView drawRect:] has been called.
- NSUInteger drawRectCount_;
+ NSUInteger _drawRectCount;
// The dirtyRect parameter passed to last invocation of drawRect:.
- NSRect lastDirtyRect_;
+ NSRect _lastDirtyRect;
}
@property(assign, nonatomic) NSUInteger drawRectCount;
@@ -1108,18 +1108,16 @@ class ModalDialogDelegate : public DialogDelegateView {
explicit ModalDialogDelegate(ui::ModalType modal_type)
: modal_type_(modal_type) {}
- void set_can_close(bool value) { can_close_ = value; }
- void set_buttons(int buttons) { buttons_ = buttons; }
+ void SetButtons(int buttons) {
+ DialogDelegate::SetButtons(buttons);
+ DialogModelChanged();
+ }
// DialogDelegateView:
- int GetDialogButtons() const override { return buttons_; }
ui::ModalType GetModalType() const override { return modal_type_; }
- bool Close() override { return can_close_; }
private:
const ui::ModalType modal_type_;
- bool can_close_ = true;
- int buttons_ = ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
DISALLOW_COPY_AND_ASSIGN(ModalDialogDelegate);
};
@@ -2081,46 +2079,6 @@ TEST_F(NativeWidgetMacTest, ChangeFocusOnChangeFirstResponder) {
widget->CloseNow();
}
-// Ensure reparented native view has correct bounds.
-TEST_F(NativeWidgetMacTest, ReparentNativeViewBounds) {
- Widget* parent = CreateTopLevelFramelessPlatformWidget();
- gfx::Rect parent_rect(100, 100, 300, 200);
- parent->SetBounds(parent_rect);
-
- Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
- params.parent = parent->GetNativeView();
- Widget* widget = new Widget;
- widget->Init(std::move(params));
- widget->SetContentsView(new View);
-
- NSView* child_view = widget->GetNativeView().GetNativeNSView();
- Widget::ReparentNativeView(child_view, parent->GetNativeView());
-
- // Reparented content view has the size of the Widget that created it.
- gfx::Rect widget_rect(0, 0, 200, 100);
- widget->SetBounds(widget_rect);
- EXPECT_EQ(200, NSWidth([child_view frame]));
- EXPECT_EQ(100, NSHeight([child_view frame]));
-
- // Reparented widget has bounds relative to the native parent
- NSRect native_parent_rect = NSMakeRect(50, 100, 200, 70);
- base::scoped_nsobject<NSView> native_parent(
- [[NSView alloc] initWithFrame:native_parent_rect]);
- [parent->GetNativeView().GetNativeNSView() addSubview:native_parent];
-
- gfx::Rect screen_rect = widget->GetWindowBoundsInScreen();
- EXPECT_EQ(100, screen_rect.x());
- EXPECT_EQ(100, screen_rect.y());
-
- Widget::ReparentNativeView(child_view, native_parent.get());
- widget->SetBounds(widget_rect);
- screen_rect = widget->GetWindowBoundsInScreen();
- EXPECT_EQ(150, screen_rect.x());
- EXPECT_EQ(130, screen_rect.y());
-
- parent->CloseNow();
-}
-
// Test two kinds of widgets to re-parent.
TEST_F(NativeWidgetMacTest, ReparentNativeViewTypes) {
std::unique_ptr<Widget> toplevel1(new Widget);
@@ -2141,16 +2099,13 @@ TEST_F(NativeWidgetMacTest, ReparentNativeViewTypes) {
Widget::ReparentNativeView(child->GetNativeView(),
toplevel1->GetNativeView());
- EXPECT_EQ([child->GetNativeView().GetNativeNSView() window],
+ EXPECT_EQ([child->GetNativeWindow().GetNativeNSWindow() parentWindow],
[toplevel1->GetNativeView().GetNativeNSView() window]);
- EXPECT_EQ(0, [child->GetNativeWindow().GetNativeNSWindow() alphaValue]);
Widget::ReparentNativeView(child->GetNativeView(),
toplevel2->GetNativeView());
- EXPECT_EQ([child->GetNativeView().GetNativeNSView() window],
+ EXPECT_EQ([child->GetNativeWindow().GetNativeNSWindow() parentWindow],
[toplevel2->GetNativeView().GetNativeNSView() window]);
- EXPECT_EQ(0, [child->GetNativeWindow().GetNativeNSWindow() alphaValue]);
- EXPECT_NE(0, [toplevel1->GetNativeWindow().GetNativeNSWindow() alphaValue]);
Widget::ReparentNativeView(toplevel2->GetNativeView(),
toplevel1->GetNativeView());
@@ -2188,6 +2143,61 @@ class NativeWidgetMacFullKeyboardAccessTest : public NativeWidgetMacTest {
ui::test::ScopedFakeFullKeyboardAccess* fake_full_keyboard_access_ = nullptr;
};
+// Ensure that calling SetSize doesn't change the origin.
+TEST_F(NativeWidgetMacTest, SetSizeDoesntChangeOrigin) {
+ Widget* parent = CreateTopLevelFramelessPlatformWidget();
+ gfx::Rect parent_rect(100, 100, 400, 200);
+ parent->SetBounds(parent_rect);
+
+ // Popup children specify their bounds relative to their parent window.
+ Widget* child_control = new Widget;
+ gfx::Rect child_control_rect(50, 70, 300, 100);
+ {
+ Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
+ params.parent = parent->GetNativeView();
+ params.bounds = child_control_rect;
+ child_control->Init(std::move(params));
+ child_control->SetContentsView(new View);
+ }
+
+ // Window children specify their bounds in screen coords.
+ Widget* child_window = new Widget;
+ gfx::Rect child_window_rect(110, 90, 200, 50);
+ {
+ Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
+ params.parent = parent->GetNativeView();
+ params.bounds = child_window_rect;
+ child_window->Init(std::move(params));
+ }
+
+ // Sanity-check the initial bounds. Note that the CONTROL should be offset by
+ // the parent's origin.
+ EXPECT_EQ(parent->GetWindowBoundsInScreen(), parent_rect);
+ EXPECT_EQ(
+ child_control->GetWindowBoundsInScreen(),
+ gfx::Rect(child_control_rect.origin() + parent_rect.OffsetFromOrigin(),
+ child_control_rect.size()));
+ EXPECT_EQ(child_window->GetWindowBoundsInScreen(), child_window_rect);
+
+ // Update the size, but not the origin.
+ parent_rect.set_size(gfx::Size(505, 310));
+ parent->SetSize(parent_rect.size());
+ child_control_rect.set_size(gfx::Size(256, 102));
+ child_control->SetSize(child_control_rect.size());
+ child_window_rect.set_size(gfx::Size(172, 96));
+ child_window->SetSize(child_window_rect.size());
+
+ // Ensure that the origin didn't change.
+ EXPECT_EQ(parent->GetWindowBoundsInScreen(), parent_rect);
+ EXPECT_EQ(
+ child_control->GetWindowBoundsInScreen(),
+ gfx::Rect(child_control_rect.origin() + parent_rect.OffsetFromOrigin(),
+ child_control_rect.size()));
+ EXPECT_EQ(child_window->GetWindowBoundsInScreen(), child_window_rect);
+
+ parent->CloseNow();
+}
+
// Test that updateFullKeyboardAccess method on BridgedContentView correctly
// sets the keyboard accessibility mode on the associated focus manager.
TEST_F(NativeWidgetMacFullKeyboardAccessTest, FullKeyboardToggle) {
@@ -2348,19 +2358,6 @@ TEST_F(NativeWidgetMacViewsOrderTest, UnassociatedViewsIsAbove) {
]]));
}
-// Test -[NSWindowDelegate windowShouldClose:].
-TEST_F(NativeWidgetMacTest, CanClose) {
- ModalDialogDelegate* delegate = new ModalDialogDelegate(ui::MODAL_TYPE_NONE);
- Widget* widget =
- views::DialogDelegate::CreateDialogWidget(delegate, nullptr, nullptr);
- NSWindow* window = widget->GetNativeWindow().GetNativeNSWindow();
- delegate->set_can_close(false);
- EXPECT_FALSE([[window delegate] windowShouldClose:window]);
- delegate->set_can_close(true);
- EXPECT_TRUE([[window delegate] windowShouldClose:window]);
- widget->CloseNow();
-}
-
namespace {
// Returns an array of NSTouchBarItemIdentifier (i.e. NSString), extracted from
@@ -2427,7 +2424,7 @@ TEST_F(NativeWidgetMacTest, TouchBar) {
}
// Remove the cancel button.
- delegate->set_buttons(ui::DIALOG_BUTTON_OK);
+ delegate->SetButtons(ui::DIALOG_BUTTON_OK);
delegate->DialogModelChanged();
EXPECT_TRUE(delegate->GetOkButton());
EXPECT_FALSE(delegate->GetCancelButton());
@@ -2479,37 +2476,37 @@ TEST_F(NativeWidgetMacTest, InitCallback) {
@implementation NativeWidgetMacTestWindow
-@synthesize invalidateShadowCount = invalidateShadowCount_;
-@synthesize fakeOnInactiveSpace = fakeOnInactiveSpace_;
-@synthesize deallocFlag = deallocFlag_;
+@synthesize invalidateShadowCount = _invalidateShadowCount;
+@synthesize fakeOnInactiveSpace = _fakeOnInactiveSpace;
+@synthesize deallocFlag = _deallocFlag;
- (void)dealloc {
- if (deallocFlag_) {
- DCHECK(!*deallocFlag_);
- *deallocFlag_ = true;
+ if (_deallocFlag) {
+ DCHECK(!*_deallocFlag);
+ *_deallocFlag = true;
}
[super dealloc];
}
- (void)invalidateShadow {
- ++invalidateShadowCount_;
+ ++_invalidateShadowCount;
[super invalidateShadow];
}
- (BOOL)isOnActiveSpace {
- return !fakeOnInactiveSpace_;
+ return !_fakeOnInactiveSpace;
}
@end
@implementation MockBridgedView
-@synthesize drawRectCount = drawRectCount_;
-@synthesize lastDirtyRect = lastDirtyRect_;
+@synthesize drawRectCount = _drawRectCount;
+@synthesize lastDirtyRect = _lastDirtyRect;
- (void)drawRect:(NSRect)dirtyRect {
- ++drawRectCount_;
- lastDirtyRect_ = dirtyRect;
+ ++_drawRectCount;
+ _lastDirtyRect = dirtyRect;
}
@end
diff --git a/chromium/ui/views/widget/native_widget_private.h b/chromium/ui/views/widget/native_widget_private.h
index 4aa5fd12c5c..1ef89be9ec0 100644
--- a/chromium/ui/views/widget/native_widget_private.h
+++ b/chromium/ui/views/widget/native_widget_private.h
@@ -17,13 +17,13 @@
namespace gfx {
class ImageSkia;
class Rect;
-}
+} // namespace gfx
namespace ui {
class InputMethod;
class GestureRecognizer;
class OSExchangeData;
-}
+} // namespace ui
namespace views {
class TooltipManager;
@@ -149,9 +149,8 @@ class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget {
// Retrieves the window's current restored bounds and "show" state, for
// persisting.
- virtual void GetWindowPlacement(
- gfx::Rect* bounds,
- ui::WindowShowState* show_state) const = 0;
+ virtual void GetWindowPlacement(gfx::Rect* bounds,
+ ui::WindowShowState* show_state) const = 0;
// Sets the NativeWindow title. Returns true if the title changed.
virtual bool SetWindowTitle(const base::string16& title) = 0;
@@ -230,6 +229,9 @@ class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget {
virtual bool IsTranslucentWindowOpacitySupported() const = 0;
virtual ui::GestureRecognizer* GetGestureRecognizer() = 0;
virtual void OnSizeConstraintsChanged() = 0;
+ // Called before and after re-parenting of this or an ancestor widget.
+ virtual void OnNativeViewHierarchyWillChange() = 0;
+ virtual void OnNativeViewHierarchyChanged() = 0;
// Returns an internal name that matches the name of the associated Widget.
virtual std::string GetName() const = 0;
diff --git a/chromium/ui/views/widget/native_widget_unittest.cc b/chromium/ui/views/widget/native_widget_unittest.cc
index 5167fabefcb..9196b811137 100644
--- a/chromium/ui/views/widget/native_widget_unittest.cc
+++ b/chromium/ui/views/widget/native_widget_unittest.cc
@@ -15,17 +15,14 @@ namespace views {
class ScopedTestWidget {
public:
explicit ScopedTestWidget(internal::NativeWidgetPrivate* native_widget)
- : native_widget_(native_widget) {
- }
+ : native_widget_(native_widget) {}
~ScopedTestWidget() {
// |CloseNow| deletes both |native_widget_| and its associated
// |Widget|.
native_widget_->GetWidget()->CloseNow();
}
- internal::NativeWidgetPrivate* operator->() const {
- return native_widget_;
- }
+ internal::NativeWidgetPrivate* operator->() const { return native_widget_; }
internal::NativeWidgetPrivate* get() const { return native_widget_; }
private:
diff --git a/chromium/ui/views/widget/root_view.cc b/chromium/ui/views/widget/root_view.cc
index 0a709e59d39..a88f7849e6b 100644
--- a/chromium/ui/views/widget/root_view.cc
+++ b/chromium/ui/views/widget/root_view.cc
@@ -5,6 +5,7 @@
#include "ui/views/widget/root_view.h"
#include <algorithm>
+#include <memory>
#include "base/logging.h"
#include "base/macros.h"
@@ -39,8 +40,7 @@ class MouseEnterExitEvent : public ui::MouseEvent {
: ui::MouseEvent(event,
static_cast<View*>(nullptr),
static_cast<View*>(nullptr)) {
- DCHECK(type == ui::ET_MOUSE_ENTERED ||
- type == ui::ET_MOUSE_EXITED);
+ DCHECK(type == ui::ET_MOUSE_ENTERED || type == ui::ET_MOUSE_EXITED);
SetType(type);
}
@@ -85,8 +85,7 @@ class AnnounceTextView : public View {
// - Shows keyboard-triggered context menus.
class PreEventDispatchHandler : public ui::EventHandler {
public:
- explicit PreEventDispatchHandler(View* owner)
- : owner_(owner) {
+ explicit PreEventDispatchHandler(View* owner) : owner_(owner) {
owner_->AddPreTargetHandler(this);
}
~PreEventDispatchHandler() override { owner_->RemovePreTargetHandler(this); }
@@ -132,8 +131,7 @@ class PreEventDispatchHandler : public ui::EventHandler {
class PostEventDispatchHandler : public ui::EventHandler {
public:
PostEventDispatchHandler()
- : touch_dnd_enabled_(::switches::IsTouchDragDropEnabled()) {
- }
+ : touch_dnd_enabled_(::switches::IsTouchDragDropEnabled()) {}
~PostEventDispatchHandler() override = default;
private:
@@ -144,14 +142,14 @@ class PostEventDispatchHandler : public ui::EventHandler {
return;
View* target = static_cast<View*>(event->target());
+
gfx::Point location = event->location();
- if (touch_dnd_enabled_ &&
- event->type() == ui::ET_GESTURE_LONG_PRESS &&
+ if (touch_dnd_enabled_ && event->type() == ui::ET_GESTURE_LONG_PRESS &&
(!target->drag_controller() ||
- target->drag_controller()->CanStartDragForView(
- target, location, location))) {
+ target->drag_controller()->CanStartDragForView(target, location,
+ location))) {
if (target->DoDrag(*event, location,
- ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH)) {
+ ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH)) {
event->StopPropagation();
return;
}
@@ -210,8 +208,8 @@ RootView::~RootView() {
// Tree operations -------------------------------------------------------------
void RootView::SetContentsView(View* contents_view) {
- DCHECK(contents_view && GetWidget()->native_widget()) <<
- "Can't be called until after the native widget is created!";
+ DCHECK(contents_view && GetWidget()->native_widget())
+ << "Can't be called until after the native widget is created!";
// The ContentsView must be set up _after_ the window is created so that its
// Widget pointer is valid.
SetLayoutManager(std::make_unique<FillLayout>());
@@ -269,8 +267,12 @@ void RootView::AnnounceText(const base::string16& text) {
NOTREACHED();
#else
DCHECK(GetWidget());
- if (!announce_view_)
+ DCHECK(GetContentsView());
+ if (!announce_view_) {
announce_view_ = AddChildView(std::make_unique<AnnounceTextView>());
+ static_cast<FillLayout*>(GetLayoutManager())
+ ->SetChildViewIgnoredByLayout(announce_view_, true);
+ }
announce_view_->Announce(text);
#endif
}
@@ -317,8 +319,7 @@ void RootView::OnEventProcessingStarted(ui::Event* event) {
// removal of the final touch point or if no gesture handler has already
// been set.
if (gesture_event->type() == ui::ET_GESTURE_END &&
- (gesture_event->details().touch_points() > 1 ||
- !gesture_handler_)) {
+ (gesture_event->details().touch_points() > 1 || !gesture_handler_)) {
event->SetHandled();
return;
}
@@ -340,8 +341,7 @@ void RootView::OnEventProcessingFinished(ui::Event* event) {
// If |event| was not handled and |gesture_handler_| was not set by the
// dispatch of a previous gesture event, then no default gesture handler
// should be set prior to the next gesture event being received.
- if (event->IsGestureEvent() &&
- !event->handled() &&
+ if (event->IsGestureEvent() && !event->handled() &&
!gesture_handler_set_before_processing_) {
gesture_handler_ = nullptr;
}
@@ -381,18 +381,14 @@ bool RootView::OnMousePressed(const ui::MouseEvent& event) {
}
DCHECK(!explicit_mouse_handler_);
- bool hit_disabled_view = false;
- // Walk up the tree until we find a view that wants the mouse event.
+ // Walk up the tree from the target until we find a view that wants
+ // the mouse event.
for (mouse_pressed_handler_ = GetEventHandlerForPoint(event.location());
mouse_pressed_handler_ && (mouse_pressed_handler_ != this);
mouse_pressed_handler_ = mouse_pressed_handler_->parent()) {
DVLOG(1) << "OnMousePressed testing "
- << mouse_pressed_handler_->GetClassName();
- if (!mouse_pressed_handler_->GetEnabled()) {
- // Disabled views should eat events instead of propagating them upwards.
- hit_disabled_view = true;
- break;
- }
+ << mouse_pressed_handler_->GetClassName();
+ DCHECK(mouse_pressed_handler_->GetEnabled());
// See if this view wants to handle the mouse press.
ui::MouseEvent mouse_pressed_event(event, static_cast<View*>(this),
@@ -425,7 +421,7 @@ bool RootView::OnMousePressed(const ui::MouseEvent& event) {
if (mouse_pressed_event.handled()) {
last_click_handler_ = mouse_pressed_handler_;
DVLOG(1) << "OnMousePressed handled by "
- << mouse_pressed_handler_->GetClassName();
+ << mouse_pressed_handler_->GetClassName();
return true;
}
}
@@ -433,15 +429,14 @@ bool RootView::OnMousePressed(const ui::MouseEvent& event) {
// Reset mouse_pressed_handler_ to indicate that no processing is occurring.
mouse_pressed_handler_ = nullptr;
+ const bool last_click_was_handled = (last_click_handler_ != nullptr);
+ last_click_handler_ = nullptr;
+
// In the event that a double-click is not handled after traversing the
// entire hierarchy (even as a single-click when sent to a different view),
// it must be marked as handled to avoid anything happening from default
// processing if it the first click-part was handled by us.
- if (last_click_handler_ && (event.flags() & ui::EF_IS_DOUBLE_CLICK))
- hit_disabled_view = true;
-
- last_click_handler_ = nullptr;
- return hit_disabled_view;
+ return last_click_was_handled && (event.flags() & ui::EF_IS_DOUBLE_CLICK);
}
bool RootView::OnMouseDragged(const ui::MouseEvent& event) {
@@ -476,8 +471,6 @@ void RootView::OnMouseReleased(const ui::MouseEvent& event) {
}
void RootView::OnMouseCaptureLost() {
- // TODO: this likely needs to reset touch handler too.
-
if (mouse_pressed_handler_ || gesture_handler_) {
// Synthesize a release event for UpdateCursor.
if (mouse_pressed_handler_) {
@@ -502,12 +495,14 @@ void RootView::OnMouseCaptureLost() {
void RootView::OnMouseMoved(const ui::MouseEvent& event) {
View* v = GetEventHandlerForPoint(event.location());
- // Find the first enabled view, or the existing move handler, whichever comes
- // first. The check for the existing handler is because if a view becomes
- // disabled while handling moves, it's wrong to suddenly send ET_MOUSE_EXITED
- // and ET_MOUSE_ENTERED events, because the mouse hasn't actually exited yet.
- while (v && !v->GetEnabled() && (v != mouse_move_handler_))
- v = v->parent();
+ // Check for a disabled move handler. If the move handler became
+ // disabled while handling moves, it's wrong to suddenly send
+ // ET_MOUSE_EXITED and ET_MOUSE_ENTERED events, because the mouse
+ // hasn't actually exited yet.
+ if (mouse_move_handler_ && !mouse_move_handler_->GetEnabled() &&
+ v->Contains(mouse_move_handler_))
+ v = mouse_move_handler_;
+
if (v && v != this) {
if (v != mouse_move_handler_) {
if (mouse_move_handler_ != nullptr &&
@@ -638,8 +633,12 @@ void RootView::SetMouseHandler(View* new_mh) {
}
void RootView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->SetName(widget_->widget_delegate()->GetAccessibleWindowTitle());
- node_data->role = widget_->widget_delegate()->GetAccessibleWindowRole();
+ DCHECK(GetWidget());
+ auto* widget_delegate = GetWidget()->widget_delegate();
+ if (!widget_delegate)
+ return;
+ node_data->SetName(widget_delegate->GetAccessibleWindowTitle());
+ node_data->role = widget_delegate->GetAccessibleWindowRole();
}
void RootView::UpdateParentLayer() {
@@ -647,14 +646,6 @@ void RootView::UpdateParentLayer() {
ReparentLayer(widget_->GetLayer());
}
-void RootView::Layout() {
- View::Layout();
- // TODO(crbug.com/1026461): when FillLayout derives from LayoutManagerBase,
- // just ignore the announce view instead of forcing it to zero size.
- if (announce_view_)
- announce_view_->SetSize({0, 0});
-}
-
////////////////////////////////////////////////////////////////////////////////
// RootView, protected:
@@ -717,8 +708,6 @@ View::DragInfo* RootView::GetDragInfo() {
////////////////////////////////////////////////////////////////////////////////
// RootView, private:
-// Input -----------------------------------------------------------------------
-
void RootView::UpdateCursor(const ui::MouseEvent& event) {
if (!(event.flags() & ui::EF_IS_NON_CLIENT)) {
View* v = GetEventHandlerForPoint(event.location());
@@ -771,12 +760,6 @@ ui::EventDispatchDetails RootView::PreDispatchEvent(ui::EventTarget* target,
// |gesture_handler_| to detect if the view has been
// removed from the tree.
gesture_handler_ = view;
-
- // Disabled views are permitted to be targets of gesture events, but
- // gesture events should never actually be dispatched to them. Prevent
- // dispatch by marking the event as handled.
- if (!view->GetEnabled())
- event->SetHandled();
}
old_dispatch_target_ = event_dispatch_target_;
diff --git a/chromium/ui/views/widget/root_view.h b/chromium/ui/views/widget/root_view.h
index f003b6e6289..c72230774d9 100644
--- a/chromium/ui/views/widget/root_view.h
+++ b/chromium/ui/views/widget/root_view.h
@@ -5,6 +5,7 @@
#ifndef UI_VIEWS_WIDGET_ROOT_VIEW_H_
#define UI_VIEWS_WIDGET_ROOT_VIEW_H_
+#include <memory>
#include <string>
#include "base/macros.h"
@@ -20,7 +21,7 @@ namespace views {
namespace test {
class ViewTargeterTest;
class WidgetTest;
-}
+} // namespace test
class RootViewTargeter;
class Widget;
@@ -34,19 +35,19 @@ class PreEventDispatchHandler;
////////////////////////////////////////////////////////////////////////////////
// RootView class
//
-// The RootView is the root of a View hierarchy. A RootView is attached to a
-// Widget. The Widget is responsible for receiving events from the host
-// environment, converting them to views-compatible events and then forwarding
-// them to the RootView for propagation into the View hierarchy.
+// The RootView is the root of a View hierarchy. A RootView is attached to a
+// Widget. The Widget is responsible for receiving events from the host
+// environment, converting them to views-compatible events and then forwarding
+// them to the RootView for propagation into the View hierarchy.
//
-// A RootView can have only one child, called its "Contents View" which is
-// sized to fill the bounds of the RootView (and hence the client area of the
-// Widget). Call SetContentsView() after the associated Widget has been
-// initialized to attach the contents view to the RootView.
-// TODO(beng): Enforce no other callers to AddChildView/tree functions by
-// overriding those methods as private here.
-// TODO(beng): Clean up API further, make Widget a friend.
-// TODO(sky): We don't really want to export this class.
+// A RootView can have only one child, called its "Contents View" which is
+// sized to fill the bounds of the RootView (and hence the client area of the
+// Widget). Call SetContentsView() after the associated Widget has been
+// initialized to attach the contents view to the RootView.
+// TODO(beng): Enforce no other callers to AddChildView/tree functions by
+// overriding those methods as private here.
+// TODO(beng): Clean up API further, make Widget a friend.
+// TODO(sky): We don't really want to export this class.
//
class VIEWS_EXPORT RootView : public View,
public ViewTargeterDelegate,
@@ -98,18 +99,18 @@ class VIEWS_EXPORT RootView : public View,
// Make an announcement through the screen reader, if present.
void AnnounceText(const base::string16& text);
- // Overridden from FocusTraversable:
+ // FocusTraversable:
FocusSearch* GetFocusSearch() override;
FocusTraversable* GetFocusTraversableParent() override;
View* GetFocusTraversableParentView() override;
- // Overridden from ui::EventProcessor:
+ // ui::EventProcessor:
ui::EventTarget* GetRootForEvent(ui::Event* event) override;
ui::EventTargeter* GetDefaultEventTargeter() override;
void OnEventProcessingStarted(ui::Event* event) override;
void OnEventProcessingFinished(ui::Event* event) override;
- // Overridden from View:
+ // View:
const Widget* GetWidget() const override;
Widget* GetWidget() override;
bool IsDrawn() const override;
@@ -123,10 +124,9 @@ class VIEWS_EXPORT RootView : public View,
void SetMouseHandler(View* new_mouse_handler) override;
void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
void UpdateParentLayer() override;
- void Layout() override;
protected:
- // Overridden from View:
+ // View:
void ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) override;
void VisibilityChanged(View* starting_from, bool is_visible) override;
@@ -166,7 +166,7 @@ class VIEWS_EXPORT RootView : public View,
View* view,
View* sibling) WARN_UNUSED_RESULT;
- // Overridden from ui::EventDispatcherDelegate:
+ // ui::EventDispatcherDelegate:
bool CanDispatchToTarget(ui::EventTarget* target) override;
ui::EventDispatchDetails PreDispatchEvent(ui::EventTarget* target,
ui::Event* event) override;
diff --git a/chromium/ui/views/widget/root_view_targeter.cc b/chromium/ui/views/widget/root_view_targeter.cc
index 1871da4ccb1..22e00035817 100644
--- a/chromium/ui/views/widget/root_view_targeter.cc
+++ b/chromium/ui/views/widget/root_view_targeter.cc
@@ -14,8 +14,7 @@ namespace views {
RootViewTargeter::RootViewTargeter(ViewTargeterDelegate* delegate,
internal::RootView* root_view)
- : ViewTargeter(delegate), root_view_(root_view) {
-}
+ : ViewTargeter(delegate), root_view_(root_view) {}
RootViewTargeter::~RootViewTargeter() = default;
diff --git a/chromium/ui/views/widget/root_view_unittest.cc b/chromium/ui/views/widget/root_view_unittest.cc
index 343ca41b540..a0640142341 100644
--- a/chromium/ui/views/widget/root_view_unittest.cc
+++ b/chromium/ui/views/widget/root_view_unittest.cc
@@ -4,15 +4,20 @@
#include "ui/views/widget/root_view.h"
+#include <memory>
+#include <utility>
+
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
+#include "ui/accessibility/ax_enums.mojom.h"
+#include "ui/accessibility/ax_node_data.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/views/context_menu_controller.h"
+#include "ui/views/test/test_views.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/view_targeter.h"
-#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget_deletion_observer.h"
#include "ui/views/window/dialog_delegate.h"
@@ -109,10 +114,8 @@ class TestContextMenuController : public ContextMenuController {
// Tests that context menus are shown for certain key events (Shift+F10
// and VKEY_APPS) by the pre-target handler installed on RootView.
TEST_F(RootViewTest, ContextMenuFromKeyEvent) {
-#if defined(OS_MACOSX)
// This behavior is intentionally unsupported on macOS.
- return;
-#endif
+#if !defined(OS_MACOSX)
Widget widget;
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
@@ -142,8 +145,8 @@ TEST_F(RootViewTest, ContextMenuFromKeyEvent) {
controller.Reset();
// A context menu should be shown for a keypress of Shift+F10.
- ui::KeyEvent menu_key_event(
- ui::ET_KEY_PRESSED, ui::VKEY_F10, ui::EF_SHIFT_DOWN);
+ ui::KeyEvent menu_key_event(ui::ET_KEY_PRESSED, ui::VKEY_F10,
+ ui::EF_SHIFT_DOWN);
details = root_view->OnEventFromSource(&menu_key_event);
EXPECT_FALSE(details.target_destroyed);
EXPECT_FALSE(details.dispatcher_destroyed);
@@ -161,6 +164,7 @@ TEST_F(RootViewTest, ContextMenuFromKeyEvent) {
EXPECT_EQ(focused_view, controller.menu_source_view());
EXPECT_EQ(ui::MENU_SOURCE_KEYBOARD, controller.menu_source_type());
controller.Reset();
+#endif
}
// View which handles all gesture events.
@@ -181,8 +185,7 @@ class GestureHandlingView : public View {
// show a context menu.
TEST_F(RootViewTest, ContextMenuFromLongPress) {
Widget widget;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_POPUP);
+ Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
init_params.bounds = gfx::Rect(100, 100);
widget.Init(std::move(init_params));
@@ -255,8 +258,7 @@ TEST_F(RootViewTest, ContextMenuFromLongPress) {
// Tests that context menus are not shown for disabled views on a long press.
TEST_F(RootViewTest, ContextMenuFromLongPressOnDisabledView) {
Widget widget;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_POPUP);
+ Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
init_params.bounds = gfx::Rect(100, 100);
widget.Init(std::move(init_params));
@@ -337,9 +339,7 @@ class DeleteViewOnEvent : public View {
DeleteViewOnEvent(ui::EventType delete_event_type, bool* was_destroyed)
: delete_event_type_(delete_event_type), was_destroyed_(was_destroyed) {}
- ~DeleteViewOnEvent() override {
- *was_destroyed_ = true;
- }
+ ~DeleteViewOnEvent() override { *was_destroyed_ = true; }
void OnEvent(ui::Event* event) override {
if (event->type() == delete_event_type_)
@@ -408,8 +408,7 @@ class NestedEventOnEvent : public View {
// Verifies deleting a View in OnMouseExited() doesn't crash.
TEST_F(RootViewTest, DeleteViewOnMouseExitDispatch) {
Widget widget;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_POPUP);
+ Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget.Init(std::move(init_params));
widget.SetBounds(gfx::Rect(10, 10, 500, 500));
@@ -428,8 +427,7 @@ TEST_F(RootViewTest, DeleteViewOnMouseExitDispatch) {
// Generate a mouse move event which ensures that |mouse_moved_handler_|
// is set in the RootView class.
ui::MouseEvent moved_event(ui::ET_MOUSE_MOVED, gfx::Point(15, 15),
- gfx::Point(15, 15), ui::EventTimeForNow(), 0,
- 0);
+ gfx::Point(15, 15), ui::EventTimeForNow(), 0, 0);
root_view->OnMouseMoved(moved_event);
ASSERT_FALSE(view_destroyed);
@@ -447,8 +445,7 @@ TEST_F(RootViewTest, DeleteViewOnMouseExitDispatch) {
// Verifies deleting a View in OnMouseEntered() doesn't crash.
TEST_F(RootViewTest, DeleteViewOnMouseEnterDispatch) {
Widget widget;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_POPUP);
+ Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget.Init(std::move(init_params));
widget.SetBounds(gfx::Rect(10, 10, 500, 500));
@@ -468,8 +465,7 @@ TEST_F(RootViewTest, DeleteViewOnMouseEnterDispatch) {
// Move the mouse within |widget| but outside of |child|.
ui::MouseEvent moved_event(ui::ET_MOUSE_MOVED, gfx::Point(15, 15),
- gfx::Point(15, 15), ui::EventTimeForNow(), 0,
- 0);
+ gfx::Point(15, 15), ui::EventTimeForNow(), 0, 0);
root_view->OnMouseMoved(moved_event);
ASSERT_FALSE(view_destroyed);
@@ -637,15 +633,11 @@ namespace {
// View class which deletes its owning Widget when it gets a mouse exit event.
class DeleteWidgetOnMouseExit : public View {
public:
- explicit DeleteWidgetOnMouseExit(Widget* widget)
- : widget_(widget) {
- }
+ explicit DeleteWidgetOnMouseExit(Widget* widget) : widget_(widget) {}
~DeleteWidgetOnMouseExit() override = default;
- void OnMouseExited(const ui::MouseEvent& event) override {
- delete widget_;
- }
+ void OnMouseExited(const ui::MouseEvent& event) override { delete widget_; }
private:
Widget* widget_;
@@ -659,8 +651,7 @@ class DeleteWidgetOnMouseExit : public View {
// View::OnMouseExited().
TEST_F(RootViewTest, DeleteWidgetOnMouseExitDispatch) {
Widget* widget = new Widget;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_POPUP);
+ Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(std::move(init_params));
widget->SetBounds(gfx::Rect(10, 10, 500, 500));
@@ -679,8 +670,7 @@ TEST_F(RootViewTest, DeleteWidgetOnMouseExitDispatch) {
// Move the mouse within |child|.
ui::MouseEvent moved_event(ui::ET_MOUSE_MOVED, gfx::Point(115, 115),
- gfx::Point(115, 115), ui::EventTimeForNow(), 0,
- 0);
+ gfx::Point(115, 115), ui::EventTimeForNow(), 0, 0);
root_view->OnMouseMoved(moved_event);
ASSERT_TRUE(widget_deletion_observer.IsWidgetAlive());
@@ -697,8 +687,7 @@ TEST_F(RootViewTest, DeleteWidgetOnMouseExitDispatch) {
// of a mouse exited event which was propagated from one of its children.
TEST_F(RootViewTest, DeleteWidgetOnMouseExitDispatchFromChild) {
Widget* widget = new Widget;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_POPUP);
+ Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(std::move(init_params));
widget->SetBounds(gfx::Rect(10, 10, 500, 500));
@@ -740,7 +729,11 @@ TEST_F(RootViewTest, DeleteWidgetOnMouseExitDispatchFromChild) {
namespace {
class RootViewTestDialogDelegate : public DialogDelegateView {
public:
- RootViewTestDialogDelegate() = default;
+ RootViewTestDialogDelegate() {
+ // Ensure that buttons don't influence the layout.
+ DialogDelegate::SetButtons(ui::DIALOG_BUTTON_NONE);
+ }
+ ~RootViewTestDialogDelegate() override = default;
int layout_count() const { return layout_count_; }
@@ -750,9 +743,6 @@ class RootViewTestDialogDelegate : public DialogDelegateView {
EXPECT_EQ(size(), preferred_size_);
++layout_count_;
}
- int GetDialogButtons() const override {
- return ui::DIALOG_BUTTON_NONE; // Ensure buttons do not influence size.
- }
private:
const gfx::Size preferred_size_ = gfx::Size(111, 111);
@@ -784,5 +774,144 @@ TEST_F(RootViewDesktopNativeWidgetTest, SingleLayoutDuringInit) {
widget->CloseNow();
}
+#if !defined(OS_MACOSX)
+
+// Tests that AnnounceText sets up the correct text value on the hidden view,
+// and that the resulting hidden view actually stays hidden.
+TEST_F(RootViewTest, AnnounceTextTest) {
+ Widget widget;
+ Widget::InitParams init_params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ init_params.bounds = {100, 100, 100, 100};
+ widget.Init(std::move(init_params));
+ widget.Show();
+ internal::RootView* root_view =
+ static_cast<internal::RootView*>(widget.GetRootView());
+ root_view->SetContentsView(new View());
+
+ EXPECT_EQ(1U, root_view->children().size());
+ const base::string16 kText = base::ASCIIToUTF16("Text");
+ root_view->AnnounceText(kText);
+ EXPECT_EQ(2U, root_view->children().size());
+ root_view->Layout();
+ EXPECT_FALSE(root_view->children()[0]->size().IsEmpty());
+ EXPECT_TRUE(root_view->children()[1]->size().IsEmpty());
+ View* const hidden_view = root_view->children()[1];
+ ui::AXNodeData node_data;
+ hidden_view->GetAccessibleNodeData(&node_data);
+ EXPECT_EQ(kText,
+ node_data.GetString16Attribute(ax::mojom::StringAttribute::kName));
+}
+
+#endif // !defined(OS_MACOSX)
+
+TEST_F(RootViewTest, MouseEventDispatchedToClosestEnabledView) {
+ Widget widget;
+ Widget::InitParams init_params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ init_params.bounds = {100, 100, 100, 100};
+ widget.Init(std::move(init_params));
+ widget.Show();
+ internal::RootView* root_view =
+ static_cast<internal::RootView*>(widget.GetRootView());
+ root_view->SetContentsView(new View());
+
+ View* const contents_view = root_view->GetContentsView();
+ EventCountView* const v1 =
+ contents_view->AddChildView(std::make_unique<EventCountView>());
+ EventCountView* const v2 =
+ v1->AddChildView(std::make_unique<EventCountView>());
+ EventCountView* const v3 =
+ v2->AddChildView(std::make_unique<EventCountView>());
+
+ contents_view->SetBoundsRect(gfx::Rect(0, 0, 10, 10));
+ v1->SetBoundsRect(gfx::Rect(0, 0, 10, 10));
+ v2->SetBoundsRect(gfx::Rect(0, 0, 10, 10));
+ v3->SetBoundsRect(gfx::Rect(0, 0, 10, 10));
+
+ v1->set_handle_mode(EventCountView::CONSUME_EVENTS);
+ v2->set_handle_mode(EventCountView::CONSUME_EVENTS);
+ v3->set_handle_mode(EventCountView::CONSUME_EVENTS);
+
+ ui::MouseEvent pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(5, 5),
+ gfx::Point(5, 5), ui::EventTimeForNow(), 0, 0);
+ ui::MouseEvent released_event(ui::ET_MOUSE_RELEASED, gfx::Point(5, 5),
+ gfx::Point(5, 5), ui::EventTimeForNow(), 0, 0);
+ root_view->OnMousePressed(pressed_event);
+ root_view->OnMouseReleased(released_event);
+ EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_PRESSED));
+ EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_PRESSED));
+ EXPECT_EQ(1, v3->GetEventCount(ui::ET_MOUSE_PRESSED));
+
+ v3->SetEnabled(false);
+ root_view->OnMousePressed(pressed_event);
+ root_view->OnMouseReleased(released_event);
+ EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_PRESSED));
+ EXPECT_EQ(1, v2->GetEventCount(ui::ET_MOUSE_PRESSED));
+ EXPECT_EQ(1, v3->GetEventCount(ui::ET_MOUSE_PRESSED));
+
+ v3->SetEnabled(true);
+ v2->SetEnabled(false);
+ root_view->OnMousePressed(pressed_event);
+ root_view->OnMouseReleased(released_event);
+ EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_PRESSED));
+ EXPECT_EQ(1, v2->GetEventCount(ui::ET_MOUSE_PRESSED));
+ EXPECT_EQ(1, v3->GetEventCount(ui::ET_MOUSE_PRESSED));
+}
+
+// If RootView::OnMousePressed() receives a double-click event that isn't
+// handled by any views, it should still report it as handled if the first click
+// was handled. However, it should *not* if the first click was unhandled.
+// Regression test for https://crbug.com/1055674.
+TEST_F(RootViewTest, DoubleClickHandledIffFirstClickHandled) {
+ Widget widget;
+ Widget::InitParams init_params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ init_params.bounds = {100, 100, 100, 100};
+ widget.Init(std::move(init_params));
+ widget.Show();
+ internal::RootView* root_view =
+ static_cast<internal::RootView*>(widget.GetRootView());
+ root_view->SetContentsView(new View());
+
+ View* const contents_view = root_view->GetContentsView();
+ EventCountView* const v1 =
+ contents_view->AddChildView(std::make_unique<EventCountView>());
+
+ contents_view->SetBoundsRect(gfx::Rect(0, 0, 10, 10));
+ v1->SetBoundsRect(gfx::Rect(0, 0, 10, 10));
+
+ ui::MouseEvent pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(5, 5),
+ gfx::Point(5, 5), ui::EventTimeForNow(), 0, 0);
+ ui::MouseEvent released_event(ui::ET_MOUSE_RELEASED, gfx::Point(5, 5),
+ gfx::Point(5, 5), ui::EventTimeForNow(), 0, 0);
+
+ // First click handled, second click unhandled.
+ v1->set_handle_mode(EventCountView::CONSUME_EVENTS);
+ pressed_event.SetClickCount(1);
+ released_event.SetClickCount(1);
+ EXPECT_TRUE(root_view->OnMousePressed(pressed_event));
+ root_view->OnMouseReleased(released_event);
+ v1->set_handle_mode(EventCountView::PROPAGATE_EVENTS);
+ pressed_event.SetClickCount(2);
+ released_event.SetClickCount(2);
+ EXPECT_TRUE(root_view->OnMousePressed(pressed_event));
+ root_view->OnMouseReleased(released_event);
+
+ // Both clicks unhandled.
+ v1->set_handle_mode(EventCountView::PROPAGATE_EVENTS);
+ pressed_event.SetClickCount(1);
+ released_event.SetClickCount(1);
+ EXPECT_FALSE(root_view->OnMousePressed(pressed_event));
+ root_view->OnMouseReleased(released_event);
+ pressed_event.SetClickCount(2);
+ released_event.SetClickCount(2);
+ EXPECT_FALSE(root_view->OnMousePressed(pressed_event));
+ root_view->OnMouseReleased(released_event);
+}
+
} // namespace test
} // namespace views
diff --git a/chromium/ui/views/widget/tooltip_manager_aura.cc b/chromium/ui/views/widget/tooltip_manager_aura.cc
index 3c4a4c11ed9..ca24a4c51b5 100644
--- a/chromium/ui/views/widget/tooltip_manager_aura.cc
+++ b/chromium/ui/views/widget/tooltip_manager_aura.cc
@@ -101,7 +101,7 @@ void TooltipManagerAura::UpdateTooltip() {
}
}
-void TooltipManagerAura::TooltipTextChanged(View* view) {
+void TooltipManagerAura::TooltipTextChanged(View* view) {
aura::Window* root_window = GetWindow()->GetRootWindow();
if (wm::GetTooltipClient(root_window)) {
gfx::Point view_point =
diff --git a/chromium/ui/views/widget/widget.cc b/chromium/ui/views/widget/widget.cc
index af72459e158..6472b4210a0 100644
--- a/chromium/ui/views/widget/widget.cc
+++ b/chromium/ui/views/widget/widget.cc
@@ -15,7 +15,6 @@
#include "base/trace_event/trace_event.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/default_style.h"
-#include "ui/base/default_theme_provider.h"
#include "ui/base/hit_test.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/l10n/l10n_font_util.h"
@@ -32,6 +31,7 @@
#include "ui/views/focus/focus_manager_factory.h"
#include "ui/views/focus/widget_focus_manager.h"
#include "ui/views/views_delegate.h"
+#include "ui/views/widget/any_widget_observer_singleton.h"
#include "ui/views/widget/native_widget_private.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/tooltip_manager.h"
@@ -92,11 +92,10 @@ bool Widget::g_disable_activation_change_handling_ = false;
// WidgetDelegate is supplied.
class DefaultWidgetDelegate : public WidgetDelegate {
public:
- explicit DefaultWidgetDelegate(Widget* widget) : widget_(widget) {
- }
+ explicit DefaultWidgetDelegate(Widget* widget) : widget_(widget) {}
~DefaultWidgetDelegate() override = default;
- // Overridden from WidgetDelegate:
+ // WidgetDelegate:
void DeleteDelegate() override { delete this; }
Widget* GetWidget() override { return widget_; }
const Widget* GetWidget() const override { return widget_; }
@@ -177,6 +176,10 @@ ui::ZOrderLevel Widget::InitParams::EffectiveZOrderLevel() const {
Widget::Widget() = default;
+Widget::Widget(InitParams params) {
+ Init(std::move(params));
+}
+
Widget::~Widget() {
DestroyRootView();
if (ownership_ == InitParams::WIDGET_OWNS_NATIVE_WIDGET) {
@@ -191,40 +194,24 @@ Widget::~Widget() {
// static
Widget* Widget::CreateWindowWithParent(WidgetDelegate* delegate,
- gfx::NativeView parent) {
- return CreateWindowWithParentAndBounds(delegate, parent, gfx::Rect());
-}
-
-// static
-Widget* Widget::CreateWindowWithParentAndBounds(WidgetDelegate* delegate,
- gfx::NativeView parent,
- const gfx::Rect& bounds) {
- Widget* widget = new Widget;
+ gfx::NativeView parent,
+ const gfx::Rect& bounds) {
Widget::InitParams params;
params.delegate = delegate;
params.parent = parent;
params.bounds = bounds;
- widget->Init(std::move(params));
- return widget;
+ return new Widget(std::move(params));
}
// static
Widget* Widget::CreateWindowWithContext(WidgetDelegate* delegate,
- gfx::NativeWindow context) {
- return CreateWindowWithContextAndBounds(delegate, context, gfx::Rect());
-}
-
-// static
-Widget* Widget::CreateWindowWithContextAndBounds(WidgetDelegate* delegate,
- gfx::NativeWindow context,
- const gfx::Rect& bounds) {
- Widget* widget = new Widget;
+ gfx::NativeWindow context,
+ const gfx::Rect& bounds) {
Widget::InitParams params;
params.delegate = delegate;
params.context = context;
params.bounds = bounds;
- widget->Init(std::move(params));
- return widget;
+ return new Widget(std::move(params));
}
// static
@@ -256,8 +243,7 @@ void Widget::GetAllChildWidgets(gfx::NativeView native_view,
}
// static
-void Widget::GetAllOwnedWidgets(gfx::NativeView native_view,
- Widgets* owned) {
+void Widget::GetAllOwnedWidgets(gfx::NativeView native_view, Widgets* owned) {
internal::NativeWidgetPrivate::GetAllOwnedWidgets(native_view, owned);
}
@@ -290,8 +276,7 @@ gfx::Size Widget::GetLocalizedContentsSize(int col_resource_id,
// static
bool Widget::RequiresNonClientView(InitParams::Type type) {
- return type == InitParams::TYPE_WINDOW ||
- type == InitParams::TYPE_BUBBLE;
+ return type == InitParams::TYPE_WINDOW || type == InitParams::TYPE_BUBBLE;
}
void Widget::Init(InitParams params) {
@@ -342,7 +327,6 @@ void Widget::Init(InitParams params) {
ownership_ = params.ownership;
native_widget_ = CreateNativeWidget(params, this)->AsNativeWidgetPrivate();
root_view_.reset(CreateRootView());
- default_theme_provider_ = std::make_unique<ui::DefaultThemeProvider>();
// Copy the elements of params that will be used after it is moved.
const InitParams::Type type = params.type;
@@ -389,19 +373,16 @@ void Widget::Init(InitParams params) {
SetContentsView(delegate->GetContentsView());
SetInitialBoundsForFramelessWindow(bounds);
}
- // TODO(https://crbug.com/953978): Use GetNativeTheme() for all platforms.
-#if defined(OS_MACOSX) || defined(OS_WIN)
- ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
- if (native_theme)
- observer_manager_.Add(native_theme);
-#else
+
observer_manager_.Add(GetNativeTheme());
-#endif
native_widget_initialized_ = true;
native_widget_->OnWidgetInitDone();
if (delegate)
delegate->OnWidgetInitialized();
+
+ internal::AnyWidgetObserverSingleton::GetInstance()->OnAnyWidgetInitialized(
+ this);
}
void Widget::ShowEmojiPanel() {
@@ -460,14 +441,17 @@ void Widget::ViewHierarchyChanged(const ViewHierarchyChangedDetails& details) {
}
void Widget::NotifyNativeViewHierarchyWillChange() {
- FocusManager* focus_manager = GetFocusManager();
- // We are being removed from a window hierarchy. Treat this as
- // the root_view_ being removed.
- if (focus_manager)
- focus_manager->ViewRemoved(root_view_.get());
+ // During tear-down the top-level focus manager becomes unavailable to
+ // GTK tabbed panes and their children, so normal deregistration via
+ // |FocusManager::ViewRemoved()| calls are fouled. We clear focus here
+ // to avoid these redundant steps and to avoid accessing deleted views
+ // that may have been in focus.
+ ClearFocusFromWidget();
+ native_widget_->OnNativeViewHierarchyChanged();
}
void Widget::NotifyNativeViewHierarchyChanged() {
+ native_widget_->OnNativeViewHierarchyWillChange();
root_view_->NotifyNativeViewHierarchyChanged();
}
@@ -613,18 +597,16 @@ void Widget::CloseWithReason(ClosedReason closed_reason) {
widget_closed_ = true;
closed_reason_ = closed_reason;
SaveWindowPlacement();
-
- // During tear-down the top-level focus manager becomes unavailable to
- // GTK tabbed panes and their children, so normal deregistration via
- // |FocusManager::ViewRemoved()| calls are fouled. We clear focus here
- // to avoid these redundant steps and to avoid accessing deleted views
- // that may have been in focus.
- if (is_top_level() && focus_manager_)
- focus_manager_->SetFocusedView(nullptr);
+ ClearFocusFromWidget();
for (WidgetObserver& observer : observers_)
observer.OnWidgetClosing(this);
+ internal::AnyWidgetObserverSingleton::GetInstance()->OnAnyWidgetClosing(this);
+
+ if (widget_delegate_)
+ widget_delegate_->WindowWillClose();
+
native_widget_->Close();
}
@@ -635,6 +617,7 @@ void Widget::Close() {
void Widget::CloseNow() {
for (WidgetObserver& observer : observers_)
observer.OnWidgetClosing(this);
+ internal::AnyWidgetObserverSingleton::GetInstance()->OnAnyWidgetClosing(this);
native_widget_->CloseNow();
}
@@ -653,8 +636,7 @@ void Widget::Show() {
// widget gets shown. In that case we stay in full screen mode, regardless
// of the |saved_show_state_| member.
if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED &&
- !initial_restored_bounds_.IsEmpty() &&
- !IsFullscreen()) {
+ !initial_restored_bounds_.IsEmpty() && !IsFullscreen()) {
native_widget_->Show(ui::SHOW_STATE_MAXIMIZED, initial_restored_bounds_);
} else {
native_widget_->Show(
@@ -668,10 +650,12 @@ void Widget::Show() {
} else {
native_widget_->Show(preferred_show_state, gfx::Rect());
}
+ internal::AnyWidgetObserverSingleton::GetInstance()->OnAnyWidgetShown(this);
}
void Widget::Hide() {
native_widget_->Hide();
+ internal::AnyWidgetObserverSingleton::GetInstance()->OnAnyWidgetHidden(this);
}
void Widget::ShowInactive() {
@@ -784,18 +768,8 @@ bool Widget::IsVisible() const {
const ui::ThemeProvider* Widget::GetThemeProvider() const {
const Widget* root_widget = GetTopLevelWidget();
- if (root_widget && root_widget != this) {
- // Attempt to get the theme provider, and fall back to the default theme
- // provider if not found.
- const ui::ThemeProvider* provider = root_widget->GetThemeProvider();
- if (provider)
- return provider;
-
- provider = root_widget->default_theme_provider_.get();
- if (provider)
- return provider;
- }
- return default_theme_provider_.get();
+ return (root_widget && root_widget != this) ? root_widget->GetThemeProvider()
+ : &default_theme_provider_;
}
FocusManager* Widget::GetFocusManager() {
@@ -1041,9 +1015,8 @@ void Widget::SynthesizeMouseMoveEvent() {
// Convert: screen coordinate -> widget coordinate.
View::ConvertPointFromScreen(root_view_.get(), &mouse_location);
last_mouse_event_was_move_ = false;
- ui::MouseEvent mouse_event(ui::ET_MOUSE_MOVED, mouse_location,
- mouse_location, ui::EventTimeForNow(),
- ui::EF_IS_SYNTHESIZED, 0);
+ ui::MouseEvent mouse_event(ui::ET_MOUSE_MOVED, mouse_location, mouse_location,
+ ui::EventTimeForNow(), ui::EF_IS_SYNTHESIZED, 0);
root_view_->OnMouseMoved(mouse_event);
}
@@ -1077,6 +1050,10 @@ std::unique_ptr<Widget::PaintAsActiveLock> Widget::LockPaintAsActive() {
weak_ptr_factory_.GetWeakPtr());
}
+base::WeakPtr<Widget> Widget::GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+}
+
bool Widget::ShouldPaintAsActive() const {
return native_widget_active_ || paint_as_active_refcount_;
}
@@ -1233,9 +1210,8 @@ void Widget::OnNativeWidgetPaint(const ui::PaintContext& context) {
}
int Widget::GetNonClientComponent(const gfx::Point& point) {
- int component = non_client_view_ ?
- non_client_view_->NonClientHitTest(point) :
- HTNOWHERE;
+ int component =
+ non_client_view_ ? non_client_view_->NonClientHitTest(point) : HTNOWHERE;
if (movement_disabled_ && (component == HTCAPTION || component == HTSYSMENU))
return HTNOWHERE;
@@ -1333,7 +1309,7 @@ void Widget::OnMouseEvent(ui::MouseEvent* event) {
case ui::ET_MOUSEWHEEL:
if (root_view && root_view->OnMouseWheel(
- static_cast<const ui::MouseWheelEvent&>(*event)))
+ static_cast<const ui::MouseWheelEvent&>(*event)))
event->SetHandled();
return;
@@ -1393,12 +1369,14 @@ const Widget* Widget::AsWidget() const {
bool Widget::SetInitialFocus(ui::WindowShowState show_state) {
FocusManager* focus_manager = GetFocusManager();
+ if (!focus_manager)
+ return false;
View* v = widget_delegate_->GetInitiallyFocusedView();
if (!focus_on_creation_ || show_state == ui::SHOW_STATE_INACTIVE ||
show_state == ui::SHOW_STATE_MINIMIZED) {
// If not focusing the window now, tell the focus manager which view to
// focus when the window is restored.
- if (v && focus_manager)
+ if (v)
focus_manager->SetStoredFocusView(v);
return true;
}
@@ -1407,10 +1385,8 @@ bool Widget::SetInitialFocus(ui::WindowShowState show_state) {
// If the Widget is active (thus allowing its child Views to receive focus),
// but the request for focus was unsuccessful, fall back to using the first
// focusable View instead.
- if (focus_manager && focus_manager->GetFocusedView() == nullptr &&
- IsActive()) {
+ if (focus_manager->GetFocusedView() == nullptr && IsActive())
focus_manager->AdvanceFocus(false);
- }
}
return !!focus_manager->GetFocusedView();
}
@@ -1525,8 +1501,7 @@ internal::RootView* Widget::CreateRootView() {
}
void Widget::DestroyRootView() {
- if (is_top_level() && focus_manager_)
- focus_manager_->SetFocusedView(nullptr);
+ ClearFocusFromWidget();
NotifyWillRemoveView(root_view_.get());
non_client_view_ = nullptr;
// Remove all children before the unique_ptr reset so that
@@ -1658,8 +1633,17 @@ void Widget::UnlockPaintAsActive() {
void Widget::UpdatePaintAsActiveState(bool paint_as_active) {
if (non_client_view_)
non_client_view_->frame_view()->PaintAsActiveChanged(paint_as_active);
- if (widget_delegate())
- widget_delegate()->OnPaintAsActiveChanged(paint_as_active);
+
+ for (WidgetObserver& observer : observers_)
+ observer.OnWidgetPaintAsActiveChanged(this, paint_as_active);
+}
+
+void Widget::ClearFocusFromWidget() {
+ FocusManager* focus_manager = GetFocusManager();
+ // We are being removed from a window hierarchy. Treat this as
+ // the root_view_ being removed.
+ if (focus_manager)
+ focus_manager->ViewRemoved(root_view_.get());
}
namespace internal {
diff --git a/chromium/ui/views/widget/widget.h b/chromium/ui/views/widget/widget.h
index 88cb98ff914..105fc39ed5e 100644
--- a/chromium/ui/views/widget/widget.h
+++ b/chromium/ui/views/widget/widget.h
@@ -16,6 +16,7 @@
#include "base/optional.h"
#include "base/scoped_observer.h"
#include "build/build_config.h"
+#include "ui/base/default_theme_provider.h"
#include "ui/base/ui_base_types.h"
#include "ui/events/event_source.h"
#include "ui/gfx/geometry/rect.h"
@@ -34,12 +35,11 @@ class TimeDelta;
namespace gfx {
class Point;
class Rect;
-}
+} // namespace gfx
namespace ui {
class Accelerator;
class Compositor;
-class DefaultThemeProvider;
class GestureRecognizer;
class InputMethod;
class Layer;
@@ -61,7 +61,7 @@ class WidgetRemovalsObserver;
namespace internal {
class NativeWidgetPrivate;
class RootView;
-}
+} // namespace internal
////////////////////////////////////////////////////////////////////////////////
// Widget class
@@ -112,9 +112,9 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
};
// Source that initiated the move loop.
- enum MoveLoopSource {
- MOVE_LOOP_SOURCE_MOUSE,
- MOVE_LOOP_SOURCE_TOUCH,
+ enum class MoveLoopSource {
+ kMouse,
+ kTouch,
};
// Behavior when escape is pressed during a move loop.
@@ -153,18 +153,17 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
struct VIEWS_EXPORT InitParams {
enum Type {
- TYPE_WINDOW, // A decorated Window, like a frame window.
- // Widgets of TYPE_WINDOW will have a NonClientView.
- TYPE_WINDOW_FRAMELESS,
- // An undecorated Window.
- TYPE_CONTROL, // A control, like a button.
- TYPE_POPUP, // An undecorated Window, with transient properties.
- TYPE_MENU, // An undecorated Window, with transient properties
- // specialized to menus.
+ TYPE_WINDOW, // A decorated Window, like a frame window.
+ // Widgets of TYPE_WINDOW will have a NonClientView.
+ TYPE_WINDOW_FRAMELESS, // An undecorated Window.
+ TYPE_CONTROL, // A control, like a button.
+ TYPE_POPUP, // An undecorated Window, with transient properties.
+ TYPE_MENU, // An undecorated Window, with transient properties
+ // specialized to menus.
TYPE_TOOLTIP,
TYPE_BUBBLE,
- TYPE_DRAG, // An undecorated Window, used during a drag-and-drop to
- // show the drag image.
+ TYPE_DRAG, // An undecorated Window, used during a drag-and-drop to
+ // show the drag image.
};
enum class WindowOpacity {
@@ -236,6 +235,11 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Internal name. Propagated to the NativeWidget. Useful for debugging.
std::string name;
+ // False if this widget behaves like a top-level widget, true otherwise. A
+ // top-level widget has its own focus and IME state, independent of any
+ // other widget. A widget for which child is true should have a parent; if
+ // it doesn't, it will not handle keyboard events or IME input at all.
+ // TODO(https://crbug.com/1057758): DCHECK(parent || !child)
bool child = false;
// If kTranslucent, the widget may be fully or partially transparent.
@@ -281,6 +285,31 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Whether the widget should be maximized or minimized.
ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT;
+ // The native *view* (not native *window*) to which this widget should be
+ // parented. If this widget has a parent, then:
+ // * If that parent closes, this widget is closed too
+ // * If that parent is hidden, this widget is hidden too
+ // * This widget is stacked above the parent widget (always on Mac, usually
+ // elsewhere)
+ // * This widget's initial bounds are constrained to the parent widget's
+ // bounds, which prevents window restoration from placing windows
+ // offscreen
+ // Note: on some platforms (Mac) this directly implies a parent-child
+ // relationship in the backing native windows, but on Aura platforms it does
+ // not necessarily.
+ //
+ // Windows with no parent window are permitted, although in Aura these
+ // windows instead need a "context". On Aura systems, if a widget has no
+ // parent set, its backing aura::Window is parented to the Aura root window.
+ //
+ // TODO(https://crbug.com/1057758): It makes no sense that this is a
+ // NativeView instead of a NativeWindow. On Aura, NativeView and
+ // NativeWindow are synonyms, and NativeWidgetAura immediately treats the
+ // provided NativeView as an aura::Window; on Mac, the NativeView is
+ // immediately converted to an NSWindow (ie a gfx::NativeWindow) and used
+ // that way throughout. This should simply be a NativeWindow - windows are
+ // parented to other windows, not to views, and it being a view confuses
+ // the concept with bubble anchoring a la BubbleDialogDelegateView.
gfx::NativeView parent = nullptr;
// Specifies the initial bounds of the Widget. Default is empty, which means
@@ -356,25 +385,22 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
};
Widget();
+ explicit Widget(InitParams params);
~Widget() override;
// Creates a decorated window Widget with the specified properties. The
// returned Widget is owned by its NativeWidget; see Widget class comment for
// details.
static Widget* CreateWindowWithParent(WidgetDelegate* delegate,
- gfx::NativeView parent);
- static Widget* CreateWindowWithParentAndBounds(WidgetDelegate* delegate,
- gfx::NativeView parent,
- const gfx::Rect& bounds);
+ gfx::NativeView parent,
+ const gfx::Rect& bounds = gfx::Rect());
// Creates a decorated window Widget in the same desktop context as |context|.
// The returned Widget is owned by its NativeWidget; see Widget class comment
// for details.
static Widget* CreateWindowWithContext(WidgetDelegate* delegate,
- gfx::NativeWindow context);
- static Widget* CreateWindowWithContextAndBounds(WidgetDelegate* delegate,
- gfx::NativeWindow context,
- const gfx::Rect& bounds);
+ gfx::NativeWindow context,
+ const gfx::Rect& bounds = gfx::Rect());
// Closes all Widgets that aren't identified as "secondary widgets". Called
// during application shutdown when the last non-secondary widget is closed.
@@ -400,8 +426,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Returns all Widgets owned by |native_view| (including child widgets, but
// not including itself).
- static void GetAllOwnedWidgets(gfx::NativeView native_view,
- Widgets* owned);
+ static void GetAllOwnedWidgets(gfx::NativeView native_view, Widgets* owned);
// Re-parent a NativeView and notify all Widgets in |native_view|'s hierarchy
// of the change.
@@ -763,9 +788,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
return const_cast<NonClientView*>(
const_cast<const Widget*>(this)->non_client_view());
}
- const NonClientView* non_client_view() const {
- return non_client_view_;
- }
+ const NonClientView* non_client_view() const { return non_client_view_; }
ClientView* client_view() {
return const_cast<ClientView*>(
@@ -786,8 +809,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Returns the widget's layer, if any.
ui::Layer* GetLayer() {
- return const_cast<ui::Layer*>(
- const_cast<const Widget*>(this)->GetLayer());
+ return const_cast<ui::Layer*>(const_cast<const Widget*>(this)->GetLayer());
}
const ui::Layer* GetLayer() const;
@@ -879,6 +901,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// returned lock can safely outlive the associated widget.
std::unique_ptr<PaintAsActiveLock> LockPaintAsActive();
+ base::WeakPtr<Widget> GetWeakPtr();
+
// Overridden from NativeWidgetDelegate:
bool IsModal() const override;
bool IsDialogBox() const override;
@@ -994,6 +1018,9 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Notifies the window frame that the active rendering state has changed.
void UpdatePaintAsActiveState(bool paint_as_active);
+ // If a descendent of |root_view_| is focused, then clear the focus.
+ void ClearFocusFromWidget();
+
static bool g_disable_activation_change_handling_;
internal::NativeWidgetPrivate* native_widget_ = nullptr;
@@ -1024,7 +1051,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
std::unique_ptr<FocusManager> focus_manager_;
// A theme provider to use when no other theme provider is specified.
- std::unique_ptr<ui::DefaultThemeProvider> default_theme_provider_;
+ const ui::DefaultThemeProvider default_theme_provider_;
// Valid for the lifetime of RunShellDrag(), indicates the view the drag
// started from.
diff --git a/chromium/ui/views/widget/widget_delegate.cc b/chromium/ui/views/widget/widget_delegate.cc
index 1ffec627df2..1d7c735d497 100644
--- a/chromium/ui/views/widget/widget_delegate.cc
+++ b/chromium/ui/views/widget/widget_delegate.cc
@@ -29,21 +29,16 @@ void WidgetDelegate::SetCanActivate(bool can_activate) {
can_activate_ = can_activate;
}
-void WidgetDelegate::OnWidgetMove() {
-}
+void WidgetDelegate::OnWidgetMove() {}
-void WidgetDelegate::OnDisplayChanged() {
-}
+void WidgetDelegate::OnDisplayChanged() {}
-void WidgetDelegate::OnWorkAreaChanged() {
-}
+void WidgetDelegate::OnWorkAreaChanged() {}
bool WidgetDelegate::OnCloseRequested(Widget::ClosedReason close_reason) {
return true;
}
-void WidgetDelegate::OnPaintAsActiveChanged(bool paint_as_active) {}
-
View* WidgetDelegate::GetInitiallyFocusedView() {
return nullptr;
}
@@ -193,7 +188,6 @@ bool WidgetDelegate::ShouldDescendIntoChildForEventHandling(
////////////////////////////////////////////////////////////////////////////////
// WidgetDelegateView:
-
WidgetDelegateView::WidgetDelegateView() {
// A WidgetDelegate should be deleted on DeleteDelegate.
set_owned_by_client();
diff --git a/chromium/ui/views/widget/widget_delegate.h b/chromium/ui/views/widget/widget_delegate.h
index 82ad1562232..a3ec229f11c 100644
--- a/chromium/ui/views/widget/widget_delegate.h
+++ b/chromium/ui/views/widget/widget_delegate.h
@@ -17,7 +17,7 @@
namespace gfx {
class ImageSkia;
class Rect;
-}
+} // namespace gfx
namespace views {
class BubbleDialogDelegateView;
@@ -56,10 +56,6 @@ class VIEWS_EXPORT WidgetDelegate {
// ClientView.
virtual bool OnCloseRequested(Widget::ClosedReason close_reason);
- // Called when the widget transitions from a state in which it should render
- // as active to one in which it should render as inactive or vice-versa.
- virtual void OnPaintAsActiveChanged(bool paint_as_active);
-
// Returns the view that should have the focus when the widget is shown. If
// NULL no view is focused.
virtual View* GetInitiallyFocusedView();
@@ -136,13 +132,22 @@ class VIEWS_EXPORT WidgetDelegate {
// Default is true.
virtual bool ShouldRestoreWindowSize() const;
- // Called when the window closes. The delegate MUST NOT delete itself during
- // this call, since it can be called afterwards. See DeleteDelegate().
+ // Hooks for the end of the Widget/Window lifecycle. As of this writing, these
+ // callbacks happen like so:
+ // 1. Client code calls Widget::CloseWithReason()
+ // 2. WidgetDelegate::WindowWillClose() is called
+ // 3. NativeWidget teardown (maybe async) starts OR the operating system
+ // abruptly closes the backing native window
+ // 4. WidgetDelegate::WindowClosing() is called
+ // 5. NativeWidget teardown completes, Widget teardown starts
+ // 6. WidgetDelegate::DeleteDelegate() is called
+ // 7. Widget teardown finishes, Widget is deleted
+ // At step 3, the "maybe async" is controlled by whether the close is done via
+ // Close() or CloseNow().
+ // Important note: for OS-initiated window closes, steps 1 and 2 don't happen
+ // - i.e, WindowWillClose() is never invoked.
+ virtual void WindowWillClose() {}
virtual void WindowClosing() {}
-
- // Called when the window is destroyed. No events must be sent or received
- // after this point. The delegate can use this opportunity to delete itself at
- // this time if necessary.
virtual void DeleteDelegate() {}
// Called when the user begins/ends to change the bounds of the window.
diff --git a/chromium/ui/views/widget/widget_interactive_uitest.cc b/chromium/ui/views/widget/widget_interactive_uitest.cc
index 4639c1e4ccd..0f50819e3c4 100644
--- a/chromium/ui/views/widget/widget_interactive_uitest.cc
+++ b/chromium/ui/views/widget/widget_interactive_uitest.cc
@@ -169,11 +169,13 @@ class NestedLoopCaptureView : public View {
ui::WindowShowState GetWidgetShowState(const Widget* widget) {
// Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement
// because the former is implemented on all platforms but the latter is not.
- return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN :
- widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED :
- widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED :
- widget->IsActive() ? ui::SHOW_STATE_NORMAL :
- ui::SHOW_STATE_INACTIVE;
+ if (widget->IsFullscreen())
+ return ui::SHOW_STATE_FULLSCREEN;
+ if (widget->IsMaximized())
+ return ui::SHOW_STATE_MAXIMIZED;
+ if (widget->IsMinimized())
+ return ui::SHOW_STATE_MINIMIZED;
+ return widget->IsActive() ? ui::SHOW_STATE_NORMAL : ui::SHOW_STATE_INACTIVE;
}
// Give the OS an opportunity to process messages for an activation change, when
@@ -759,7 +761,7 @@ TEST_F(WidgetTestInteractive, ChildStackedRelativeToParent) {
// Showing the parent again should raise it and its child above the popover.
ShowSync(parent.get());
EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
- EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
+ EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
// Test grandchildren.
Widget* grandchild = CreateChildPlatformWidget(child->GetNativeView());
@@ -767,15 +769,15 @@ TEST_F(WidgetTestInteractive, ChildStackedRelativeToParent) {
grandchild->ShowInactive();
EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
- EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
+ EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
ShowSync(popover.get());
- EXPECT_TRUE(IsWindowStackedAbove(popover.get(), grandchild));
+ EXPECT_TRUE(IsWindowStackedAbove(popover.get(), grandchild));
EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
ShowSync(parent.get());
EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
- EXPECT_TRUE(IsWindowStackedAbove(child, popover.get()));
+ EXPECT_TRUE(IsWindowStackedAbove(child, popover.get()));
// Test hiding and reshowing.
parent->Hide();
@@ -784,7 +786,7 @@ TEST_F(WidgetTestInteractive, ChildStackedRelativeToParent) {
EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
- EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
+ EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
grandchild->Hide();
EXPECT_FALSE(grandchild->IsVisible());
@@ -792,7 +794,7 @@ TEST_F(WidgetTestInteractive, ChildStackedRelativeToParent) {
EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
- EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
+ EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
}
#if defined(OS_WIN)
@@ -902,8 +904,7 @@ TEST_F(WidgetTestInteractive, WidgetNotActivatedOnFakeActivationMessages) {
// activation. This test verifies the same.
TEST_F(WidgetTestInteractive, FullscreenBoundsReducedOnActivationLoss) {
Widget widget1;
- Widget::InitParams params =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.native_widget = new DesktopNativeWidgetAura(&widget1);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget1.Init(std::move(params));
@@ -942,7 +943,8 @@ TEST_F(WidgetTestInteractive, FullscreenBoundsReducedOnActivationLoss) {
// After deactivation loss the bounds of the fullscreen widget should be
// reduced by 1px.
EXPECT_EQ(fullscreen_bounds.height() -
- fullscreen_bounds_after_activation_loss.height(), 1);
+ fullscreen_bounds_after_activation_loss.height(),
+ 1);
widget1.Activate();
RunPendingMessages();
@@ -1097,7 +1099,7 @@ TEST_F(DesktopWidgetTestInteractive, WindowModalWindowDestroyedActivationTest) {
// Investigate enabling for Chrome OS. It probably requires help from the window
// service.
#define MAYBE_SystemModalWindowReleasesCapture \
- DISABLED_SystemModalWindowReleasesCapture
+ DISABLED_SystemModalWindowReleasesCapture
#else
#define MAYBE_SystemModalWindowReleasesCapture SystemModalWindowReleasesCapture
#endif
@@ -1248,7 +1250,7 @@ TEST_F(WidgetTestInteractive, DisableViewDoesNotActivateWidget) {
EXPECT_NE(view1, focus_manager1->GetFocusedView());
EXPECT_FALSE(widget1.IsActive());
EXPECT_TRUE(widget2.IsActive());
-}
+} // namespace test
TEST_F(WidgetTestInteractive, ShowCreatesActiveWindow) {
Widget* widget = CreateTopLevelPlatformWidget();
@@ -1458,6 +1460,42 @@ TEST_F(DesktopWidgetTestInteractive, RestoreAndMinimizeVisibility) {
EXPECT_TRUE(root_window->IsVisible());
widget->CloseNow();
}
+
+// Test that focus is restored to the widget after a minimized window
+// is activated.
+TEST_F(DesktopWidgetTestInteractive, MinimizeAndActivateFocus) {
+ Widget* widget = CreateWidget();
+ aura::Window* root_window = GetRootWindow(widget);
+ auto* widget_window = widget->GetNativeWindow();
+ ShowSync(widget);
+ ASSERT_FALSE(widget->IsMinimized());
+ EXPECT_TRUE(root_window->IsVisible());
+ widget_window->Focus();
+ EXPECT_TRUE(widget_window->HasFocus());
+ widget->GetContentsView()->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+ widget->GetContentsView()->RequestFocus();
+ EXPECT_TRUE(widget->GetContentsView()->HasFocus());
+
+ PropertyWaiter minimize_widget_waiter(
+ base::BindRepeating(&Widget::IsMinimized, base::Unretained(widget)),
+ true);
+ widget->Minimize();
+ EXPECT_TRUE(minimize_widget_waiter.Wait());
+ EXPECT_TRUE(widget->IsVisible());
+ EXPECT_FALSE(root_window->IsVisible());
+
+ PropertyWaiter restore_widget_waiter(
+ base::BindRepeating(&Widget::IsMinimized, base::Unretained(widget)),
+ false);
+ widget->Activate();
+ EXPECT_TRUE(widget->GetContentsView()->HasFocus());
+ EXPECT_TRUE(restore_widget_waiter.Wait());
+ EXPECT_TRUE(widget->IsVisible());
+ EXPECT_TRUE(root_window->IsVisible());
+ EXPECT_TRUE(widget_window->CanFocus());
+ widget->CloseNow();
+}
+
#endif // defined(OS_WIN)
#if BUILDFLAG(ENABLE_DESKTOP_AURA) || defined(OS_MACOSX)
@@ -1834,7 +1872,6 @@ TEST_F(WidgetCaptureTest, SetCaptureToNonToplevel) {
child->RemoveObserver(&observer);
}
-
#if defined(OS_WIN)
namespace {
@@ -2085,12 +2122,10 @@ TEST_F(WidgetInputMethodInteractiveTest, AcceleratorInTextfield) {
textfield->SetTextInputType(ui::TEXT_INPUT_TYPE_TEXT);
textfield->RequestFocus();
- ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
- ui::VKEY_F, ui::EF_ALT_DOWN);
+ ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_F, ui::EF_ALT_DOWN);
ui::Accelerator accelerator(key_event);
widget->GetFocusManager()->RegisterAccelerator(
- accelerator, ui::AcceleratorManager::kNormalPriority,
- textfield);
+ accelerator, ui::AcceleratorManager::kNormalPriority, textfield);
widget->OnKeyEvent(&key_event);
EXPECT_TRUE(key_event.stopped_propagation());
diff --git a/chromium/ui/views/widget/widget_observer.h b/chromium/ui/views/widget/widget_observer.h
index 51adacfee40..e1168897442 100644
--- a/chromium/ui/views/widget/widget_observer.h
+++ b/chromium/ui/views/widget/widget_observer.h
@@ -41,6 +41,11 @@ class VIEWS_EXPORT WidgetObserver : public base::CheckedObserver {
virtual void OnWidgetDragWillStart(Widget* widget) {}
virtual void OnWidgetDragComplete(Widget* widget) {}
+ // Called when the widget transitions from a state in which it should render
+ // as active to one in which it should render as inactive or vice-versa.
+ virtual void OnWidgetPaintAsActiveChanged(Widget* widget,
+ bool paint_as_active) {}
+
virtual void OnWidgetVisibilityChanging(Widget* widget, bool visible) {}
virtual void OnWidgetVisibilityChanged(Widget* widget, bool visible) {}
diff --git a/chromium/ui/views/widget/widget_unittest.cc b/chromium/ui/views/widget/widget_unittest.cc
index 02a43cf961f..e932006a39a 100644
--- a/chromium/ui/views/widget/widget_unittest.cc
+++ b/chromium/ui/views/widget/widget_unittest.cc
@@ -129,7 +129,7 @@ class ScrollableEventCountView : public EventCountView {
// A view that implements GetMinimumSize.
class MinimumSizeFrameView : public NativeFrameView {
public:
- explicit MinimumSizeFrameView(Widget* frame): NativeFrameView(frame) {}
+ explicit MinimumSizeFrameView(Widget* frame) : NativeFrameView(frame) {}
~MinimumSizeFrameView() override = default;
private:
@@ -146,13 +146,9 @@ class EventCountHandler : public ui::EventHandler {
EventCountHandler() = default;
~EventCountHandler() override = default;
- int GetEventCount(ui::EventType type) {
- return event_count_[type];
- }
+ int GetEventCount(ui::EventType type) { return event_count_[type]; }
- void ResetCounts() {
- event_count_.clear();
- }
+ void ResetCounts() { event_count_.clear(); }
protected:
// Overridden from ui::EventHandler:
@@ -162,9 +158,7 @@ class EventCountHandler : public ui::EventHandler {
}
private:
- void RecordEvent(const ui::Event& event) {
- ++event_count_[event.type()];
- }
+ void RecordEvent(const ui::Event& event) { ++event_count_[event.type()]; }
std::map<ui::EventType, int> event_count_;
@@ -179,15 +173,20 @@ TEST_F(WidgetTest, WidgetInitParams) {
// Tests that the internal name is propagated through widget initialization to
// the native widget and back.
-TEST_F(WidgetTest, GetName) {
- Widget widget;
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.name = "MyWidget";
- widget.Init(std::move(params));
+class WidgetNameTest : public WidgetTest {
+ public:
+ Widget::InitParams CreateParams(Widget::InitParams::Type type) override {
+ Widget::InitParams params = WidgetTest::CreateParams(type);
+ params.name = "MyWidget";
+ return params;
+ }
+};
+
+TEST_F(WidgetNameTest, GetName) {
+ std::unique_ptr<Widget> widget = CreateTestWidget();
- EXPECT_EQ("MyWidget", widget.native_widget_private()->GetName());
- EXPECT_EQ("MyWidget", widget.GetName());
+ EXPECT_EQ("MyWidget", widget->native_widget_private()->GetName());
+ EXPECT_EQ("MyWidget", widget->GetName());
}
TEST_F(WidgetTest, NativeWindowProperty) {
@@ -349,11 +348,10 @@ class OwnershipTestWidget : public Widget {
TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
OwnershipTestState state;
- std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state));
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
+ auto widget = std::make_unique<OwnershipTestWidget>(&state);
+ Widget::InitParams params = CreateParamsForTestWidget();
params.native_widget = CreatePlatformNativeWidgetImpl(
params, widget.get(), kStubCapture, &state.native_widget_deleted);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(std::move(params));
// Now delete the Widget, which should delete the NativeWidget.
@@ -370,11 +368,10 @@ TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) {
OwnershipTestState state;
- std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state));
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
+ auto widget = std::make_unique<OwnershipTestWidget>(&state);
+ Widget::InitParams params = CreateParamsForTestWidget();
params.native_widget = CreatePlatformNativeWidgetImpl(
params, widget.get(), kStubCapture, &state.native_widget_deleted);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(std::move(params));
// Now delete the Widget, which should delete the NativeWidget.
@@ -395,12 +392,11 @@ TEST_F(WidgetOwnershipTest,
Widget* toplevel = CreateTopLevelPlatformWidget();
- std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state));
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
+ auto widget = std::make_unique<OwnershipTestWidget>(&state);
+ Widget::InitParams params = CreateParamsForTestWidget();
params.parent = toplevel->GetNativeView();
params.native_widget = CreatePlatformNativeWidgetImpl(
params, widget.get(), kStubCapture, &state.native_widget_deleted);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(std::move(params));
// Now close the toplevel, which deletes the view hierarchy.
@@ -509,8 +505,7 @@ TEST_F(WidgetOwnershipTest,
// NativeWidget owns its Widget, part 5: NativeWidget is a NativeWidget,
// we close it directly.
-TEST_F(WidgetOwnershipTest,
- Ownership_ViewsNativeWidgetOwnsWidget_Close) {
+TEST_F(WidgetOwnershipTest, Ownership_ViewsNativeWidgetOwnsWidget_Close) {
OwnershipTestState state;
Widget* toplevel = CreateTopLevelPlatformWidget();
@@ -541,11 +536,10 @@ TEST_F(WidgetOwnershipTest,
WidgetDelegateView* delegate_view = new WidgetDelegateView;
- std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state));
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
+ auto widget = std::make_unique<OwnershipTestWidget>(&state);
+ Widget::InitParams params = CreateParamsForTestWidget();
params.native_widget = CreatePlatformNativeWidgetImpl(
params, widget.get(), kStubCapture, &state.native_widget_deleted);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.delegate = delegate_view;
widget->Init(std::move(params));
widget->SetContentsView(delegate_view);
@@ -564,56 +558,53 @@ TEST_F(WidgetOwnershipTest,
using WidgetWithDestroyedNativeViewTest = ViewsTestBaseWithNativeWidgetType;
TEST_P(WidgetWithDestroyedNativeViewTest, Test) {
- Widget widget;
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget.Init(std::move(params));
- widget.Show();
+ std::unique_ptr<Widget> widget = CreateTestWidget();
+ widget->Show();
- widget.native_widget_private()->CloseNow();
- widget.GetNativeView();
- widget.GetNativeWindow();
+ widget->native_widget_private()->CloseNow();
+ widget->GetNativeView();
+ widget->GetNativeWindow();
ui::Accelerator accelerator;
- widget.GetAccelerator(0, &accelerator);
- widget.GetTopLevelWidget();
- widget.GetWindowBoundsInScreen();
- widget.GetClientAreaBoundsInScreen();
- widget.SetBounds(gfx::Rect(0, 0, 100, 80));
- widget.SetSize(gfx::Size(10, 11));
- widget.SetBoundsConstrained(gfx::Rect(0, 0, 120, 140));
- widget.SetVisibilityChangedAnimationsEnabled(false);
- widget.StackAtTop();
- widget.IsClosed();
- widget.Close();
- widget.Hide();
- widget.Activate();
- widget.Deactivate();
- widget.IsActive();
- widget.SetZOrderLevel(ui::ZOrderLevel::kNormal);
- widget.GetZOrderLevel();
- widget.Maximize();
- widget.Minimize();
- widget.Restore();
- widget.IsMaximized();
- widget.IsFullscreen();
- widget.SetOpacity(0.f);
- widget.FlashFrame(true);
- widget.IsVisible();
- widget.GetThemeProvider();
- widget.GetNativeTheme();
- widget.GetFocusManager();
- widget.SchedulePaintInRect(gfx::Rect(0, 0, 1, 2));
- widget.IsMouseEventsEnabled();
- widget.SetNativeWindowProperty("xx", &widget);
- widget.GetNativeWindowProperty("xx");
- widget.GetFocusTraversable();
- widget.GetLayer();
- widget.ReorderNativeViews();
- widget.SetCapture(widget.GetRootView());
- widget.ReleaseCapture();
- widget.HasCapture();
- widget.GetWorkAreaBoundsInScreen();
- widget.IsTranslucentWindowOpacitySupported();
+ widget->GetAccelerator(0, &accelerator);
+ widget->GetTopLevelWidget();
+ widget->GetWindowBoundsInScreen();
+ widget->GetClientAreaBoundsInScreen();
+ widget->SetBounds(gfx::Rect(0, 0, 100, 80));
+ widget->SetSize(gfx::Size(10, 11));
+ widget->SetBoundsConstrained(gfx::Rect(0, 0, 120, 140));
+ widget->SetVisibilityChangedAnimationsEnabled(false);
+ widget->StackAtTop();
+ widget->IsClosed();
+ widget->Close();
+ widget->Hide();
+ widget->Activate();
+ widget->Deactivate();
+ widget->IsActive();
+ widget->SetZOrderLevel(ui::ZOrderLevel::kNormal);
+ widget->GetZOrderLevel();
+ widget->Maximize();
+ widget->Minimize();
+ widget->Restore();
+ widget->IsMaximized();
+ widget->IsFullscreen();
+ widget->SetOpacity(0.f);
+ widget->FlashFrame(true);
+ widget->IsVisible();
+ widget->GetThemeProvider();
+ widget->GetNativeTheme();
+ widget->GetFocusManager();
+ widget->SchedulePaintInRect(gfx::Rect(0, 0, 1, 2));
+ widget->IsMouseEventsEnabled();
+ widget->SetNativeWindowProperty("xx", &widget);
+ widget->GetNativeWindowProperty("xx");
+ widget->GetFocusTraversable();
+ widget->GetLayer();
+ widget->ReorderNativeViews();
+ widget->SetCapture(widget->GetRootView());
+ widget->ReleaseCapture();
+ widget->HasCapture();
+ widget->GetWorkAreaBoundsInScreen();
+ widget->IsTranslucentWindowOpacitySupported();
}
INSTANTIATE_TEST_SUITE_P(
@@ -632,9 +623,7 @@ class WidgetObserverTest : public WidgetTest, public WidgetObserver {
~WidgetObserverTest() override = default;
// Set a widget to Close() the next time the Widget being observed is hidden.
- void CloseOnNextHide(Widget* widget) {
- widget_to_close_on_hide_ = widget;
- }
+ void CloseOnNextHide(Widget* widget) { widget_to_close_on_hide_ = widget; }
// Overridden from WidgetObserver:
void OnWidgetDestroying(Widget* widget) override {
@@ -1026,11 +1015,11 @@ TEST_F(WidgetObserverTest, ClosingOnHiddenParent) {
// Test behavior of NativeWidget*::GetWindowPlacement on the native desktop.
#if defined(USE_X11)
- // On desktop-Linux cheat and use non-desktop widgets. On X11, minimize is
- // asynchronous. Also (harder) showing a window doesn't activate it without
- // user interaction (or extra steps only done for interactive ui tests).
- // Without that, show_state remains in ui::SHOW_STATE_INACTIVE throughout.
- // TODO(tapted): Find a nice way to run this with desktop widgets on Linux.
+// On desktop-Linux cheat and use non-desktop widgets. On X11, minimize is
+// asynchronous. Also (harder) showing a window doesn't activate it without
+// user interaction (or extra steps only done for interactive ui tests).
+// Without that, show_state remains in ui::SHOW_STATE_INACTIVE throughout.
+// TODO(tapted): Find a nice way to run this with desktop widgets on Linux.
TEST_F(WidgetTest, GetWindowPlacement) {
#else
TEST_F(DesktopWidgetTest, GetWindowPlacement) {
@@ -1126,8 +1115,9 @@ TEST_F(DesktopWidgetTest, MinimumSizeConstraints) {
// The test environment may have dwm disabled on Windows. In this case,
// CustomFrameView is used instead of the NativeFrameView, which will
// provide a minimum size that includes frame decorations.
- minimum_size = widget->non_client_view()->GetWindowBoundsForClientBounds(
- gfx::Rect(minimum_size)).size();
+ minimum_size = widget->non_client_view()
+ ->GetWindowBoundsForClientBounds(gfx::Rect(minimum_size))
+ .size();
}
EXPECT_EQ(minimum_size, widget->GetMinimumSize());
@@ -1238,8 +1228,7 @@ TEST_F(DesktopWidgetTest, MAYBE_GetRestoredBounds) {
toplevel->SetFullscreen(true);
RunPendingMessages();
- EXPECT_NE(toplevel->GetWindowBoundsInScreen(),
- toplevel->GetRestoredBounds());
+ EXPECT_NE(toplevel->GetWindowBoundsInScreen(), toplevel->GetRestoredBounds());
EXPECT_EQ(bounds, toplevel->GetRestoredBounds());
toplevel->SetFullscreen(false);
@@ -1277,15 +1266,10 @@ TEST_F(DesktopWidgetTest, DISABLED_FocusChangesOnBubble) {
// Create a widget, show and activate it and focus the contents view.
View* contents_view = new View;
contents_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
- Widget widget;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- init_params.bounds = gfx::Rect(0, 0, 200, 200);
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget.Init(std::move(init_params));
- widget.SetContentsView(contents_view);
- widget.Show();
- widget.Activate();
+ std::unique_ptr<Widget> widget = CreateTestWidget();
+ widget->SetContentsView(contents_view);
+ widget->Show();
+ widget->Activate();
contents_view->RequestFocus();
EXPECT_TRUE(contents_view->HasFocus());
@@ -1328,22 +1312,16 @@ TEST_F(WidgetTest, BubbleControlsResetOnInit) {
// size while minimized.
TEST_F(DesktopWidgetTest, TestViewWidthAfterMinimizingWidget) {
// Create a widget.
- Widget widget;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
- init_params.show_state = ui::SHOW_STATE_NORMAL;
- gfx::Rect initial_bounds(0, 0, 300, 400);
- init_params.bounds = initial_bounds;
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget.Init(std::move(init_params));
- NonClientView* non_client_view = widget.non_client_view();
- NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
+ std::unique_ptr<Widget> widget =
+ CreateTestWidget(Widget::InitParams::TYPE_WINDOW);
+ NonClientView* non_client_view = widget->non_client_view();
+ NonClientFrameView* frame_view = new MinimumSizeFrameView(widget.get());
non_client_view->SetFrameView(frame_view);
// Setting the frame view doesn't do a layout, so force one.
non_client_view->Layout();
- widget.Show();
+ widget->Show();
EXPECT_NE(0, frame_view->width());
- widget.Minimize();
+ widget->Minimize();
EXPECT_EQ(0, frame_view->width());
}
#endif
@@ -1354,16 +1332,12 @@ TEST_F(DesktopWidgetTest, TestViewWidthAfterMinimizingWidget) {
// paints are expected.
class DesktopAuraTestValidPaintWidget : public Widget, public WidgetObserver {
public:
- DesktopAuraTestValidPaintWidget() { AddObserver(this); }
-
- ~DesktopAuraTestValidPaintWidget() override { RemoveObserver(this); }
+ DesktopAuraTestValidPaintWidget() { observer_.Add(this); }
- void InitForTest(Widget::InitParams create_params);
+ ~DesktopAuraTestValidPaintWidget() override = default;
bool ReadReceivedPaintAndReset() {
- bool result = received_paint_;
- received_paint_ = false;
- return result;
+ return std::exchange(received_paint_, false);
}
bool received_paint_while_hidden() const {
@@ -1401,73 +1375,79 @@ class DesktopAuraTestValidPaintWidget : public Widget, public WidgetObserver {
bool expect_paint_ = true;
bool received_paint_while_hidden_ = false;
base::OnceClosure quit_closure_;
+ ScopedObserver<Widget, WidgetObserver> observer_{this};
DISALLOW_COPY_AND_ASSIGN(DesktopAuraTestValidPaintWidget);
};
-void DesktopAuraTestValidPaintWidget::InitForTest(InitParams init_params) {
- init_params.bounds = gfx::Rect(0, 0, 200, 200);
- init_params.ownership = InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- Init(std::move(init_params));
+class DesktopAuraPaintWidgetTest : public DesktopWidgetTest {
+ public:
+ std::unique_ptr<views::Widget> CreateTestWidget(
+ views::Widget::InitParams::Type type =
+ views::Widget::InitParams::TYPE_WINDOW_FRAMELESS) override {
+ Widget::InitParams params = CreateParamsForTestWidget(type);
+ auto widget = std::make_unique<DesktopAuraTestValidPaintWidget>();
+ paint_widget_ = widget.get();
+ widget->Init(std::move(params));
+
+ View* contents_view = new View;
+ contents_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+ widget->SetContentsView(contents_view);
- View* contents_view = new View;
- contents_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
- SetContentsView(contents_view);
+ widget->Show();
+ widget->Activate();
- Show();
- Activate();
-}
+ return widget;
+ }
+
+ DesktopAuraTestValidPaintWidget* paint_widget() { return paint_widget_; }
+
+ private:
+ DesktopAuraTestValidPaintWidget* paint_widget_ = nullptr;
+};
-TEST_F(DesktopWidgetTest, DesktopNativeWidgetNoPaintAfterCloseTest) {
- DesktopAuraTestValidPaintWidget widget;
- widget.InitForTest(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS));
- widget.WaitUntilPaint();
- EXPECT_TRUE(widget.ReadReceivedPaintAndReset());
- widget.SchedulePaintInRect(widget.GetRestoredBounds());
- widget.Close();
+TEST_F(DesktopAuraPaintWidgetTest, DesktopNativeWidgetNoPaintAfterCloseTest) {
+ std::unique_ptr<Widget> widget = CreateTestWidget();
+ paint_widget()->WaitUntilPaint();
+ EXPECT_TRUE(paint_widget()->ReadReceivedPaintAndReset());
+ widget->SchedulePaintInRect(widget->GetRestoredBounds());
+ widget->Close();
RunPendingMessages();
- EXPECT_FALSE(widget.ReadReceivedPaintAndReset());
- EXPECT_FALSE(widget.received_paint_while_hidden());
+ EXPECT_FALSE(paint_widget()->ReadReceivedPaintAndReset());
+ EXPECT_FALSE(paint_widget()->received_paint_while_hidden());
}
-TEST_F(DesktopWidgetTest, DesktopNativeWidgetNoPaintAfterHideTest) {
- DesktopAuraTestValidPaintWidget widget;
- widget.InitForTest(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS));
- widget.WaitUntilPaint();
- EXPECT_TRUE(widget.ReadReceivedPaintAndReset());
- widget.SchedulePaintInRect(widget.GetRestoredBounds());
- widget.Hide();
+TEST_F(DesktopAuraPaintWidgetTest, DesktopNativeWidgetNoPaintAfterHideTest) {
+ std::unique_ptr<Widget> widget = CreateTestWidget();
+ paint_widget()->WaitUntilPaint();
+ EXPECT_TRUE(paint_widget()->ReadReceivedPaintAndReset());
+ widget->SchedulePaintInRect(widget->GetRestoredBounds());
+ widget->Hide();
RunPendingMessages();
- EXPECT_FALSE(widget.ReadReceivedPaintAndReset());
- EXPECT_FALSE(widget.received_paint_while_hidden());
- widget.Close();
+ EXPECT_FALSE(paint_widget()->ReadReceivedPaintAndReset());
+ EXPECT_FALSE(paint_widget()->received_paint_while_hidden());
+ widget->Close();
}
-// Test to ensure that the aura Window's visiblity state is set to visible if
+// Test to ensure that the aura Window's visibility state is set to visible if
// the underlying widget is hidden and then shown.
TEST_F(DesktopWidgetTest, TestWindowVisibilityAfterHide) {
// Create a widget.
- Widget widget;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
- init_params.show_state = ui::SHOW_STATE_NORMAL;
- gfx::Rect initial_bounds(0, 0, 300, 400);
- init_params.bounds = initial_bounds;
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget.Init(std::move(init_params));
- NonClientView* non_client_view = widget.non_client_view();
- NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
+ std::unique_ptr<Widget> widget =
+ CreateTestWidget(Widget::InitParams::TYPE_WINDOW);
+ NonClientView* non_client_view = widget->non_client_view();
+ NonClientFrameView* frame_view = new MinimumSizeFrameView(widget.get());
non_client_view->SetFrameView(frame_view);
- widget.Show();
- EXPECT_TRUE(IsNativeWindowVisible(widget.GetNativeWindow()));
- widget.Hide();
- EXPECT_FALSE(IsNativeWindowVisible(widget.GetNativeWindow()));
- widget.Show();
- EXPECT_TRUE(IsNativeWindowVisible(widget.GetNativeWindow()));
+ widget->Show();
+ EXPECT_TRUE(IsNativeWindowVisible(widget->GetNativeWindow()));
+ widget->Hide();
+ EXPECT_FALSE(IsNativeWindowVisible(widget->GetNativeWindow()));
+ widget->Show();
+ EXPECT_TRUE(IsNativeWindowVisible(widget->GetNativeWindow()));
}
-// Tests that wheel events generated from scroll events are targetted to the
+// Tests that wheel events generated from scroll events are targeted to the
// views under the cursor when the focused view does not processed them.
TEST_F(WidgetTest, WheelEventsFromScrollEventTarget) {
EventCountView* cursor_view = new EventCountView;
@@ -1477,13 +1457,8 @@ TEST_F(WidgetTest, WheelEventsFromScrollEventTarget) {
widget->GetRootView()->AddChildView(cursor_view);
// Generate a scroll event on the cursor view.
- ui::ScrollEvent scroll(ui::ET_SCROLL,
- gfx::Point(65, 5),
- ui::EventTimeForNow(),
- 0,
- 0, 20,
- 0, 20,
- 2);
+ ui::ScrollEvent scroll(ui::ET_SCROLL, gfx::Point(65, 5),
+ ui::EventTimeForNow(), 0, 0, 20, 0, 20, 2);
widget->OnScrollEvent(&scroll);
EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_SCROLL));
@@ -1491,13 +1466,8 @@ TEST_F(WidgetTest, WheelEventsFromScrollEventTarget) {
cursor_view->ResetCounts();
- ui::ScrollEvent scroll2(ui::ET_SCROLL,
- gfx::Point(5, 5),
- ui::EventTimeForNow(),
- 0,
- 0, 20,
- 0, 20,
- 2);
+ ui::ScrollEvent scroll2(ui::ET_SCROLL, gfx::Point(5, 5),
+ ui::EventTimeForNow(), 0, 0, 20, 0, 20, 2);
widget->OnScrollEvent(&scroll2);
EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_SCROLL));
@@ -1576,13 +1546,8 @@ TEST_F(WidgetTest, EventHandlersOnRootView) {
// Dispatch a ui::ET_SCROLL event. The event remains unhandled and should
// bubble up the views hierarchy to be re-dispatched on the root view.
- ui::ScrollEvent scroll(ui::ET_SCROLL,
- gfx::Point(5, 5),
- ui::EventTimeForNow(),
- 0,
- 0, 20,
- 0, 20,
- 2);
+ ui::ScrollEvent scroll(ui::ET_SCROLL, gfx::Point(5, 5), ui::EventTimeForNow(),
+ 0, 0, 20, 0, 20, 2);
widget->OnScrollEvent(&scroll);
EXPECT_EQ(2, h1.GetEventCount(ui::ET_SCROLL));
EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL));
@@ -1599,13 +1564,8 @@ TEST_F(WidgetTest, EventHandlersOnRootView) {
// Dispatch a ui::ET_SCROLL_FLING_START event. The event remains unhandled and
// should bubble up the views hierarchy to be re-dispatched on the root view.
- ui::ScrollEvent fling(ui::ET_SCROLL_FLING_START,
- gfx::Point(5, 5),
- ui::EventTimeForNow(),
- 0,
- 0, 20,
- 0, 20,
- 2);
+ ui::ScrollEvent fling(ui::ET_SCROLL_FLING_START, gfx::Point(5, 5),
+ ui::EventTimeForNow(), 0, 0, 20, 0, 20, 2);
widget->OnScrollEvent(&fling);
EXPECT_EQ(2, h1.GetEventCount(ui::ET_SCROLL_FLING_START));
EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL_FLING_START));
@@ -1628,10 +1588,7 @@ TEST_F(WidgetTest, EventHandlersOnRootView) {
// Dispatch a ui::ET_GESTURE_TAP_DOWN and a ui::ET_GESTURE_TAP_CANCEL event.
// The events are handled at the target phase and should not reach the
// post-target handler.
- ui::GestureEvent tap_down(5,
- 5,
- 0,
- ui::EventTimeForNow(),
+ ui::GestureEvent tap_down(5, 5, 0, ui::EventTimeForNow(),
ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN));
widget->OnGestureEvent(&tap_down);
EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_TAP_DOWN));
@@ -1639,10 +1596,7 @@ TEST_F(WidgetTest, EventHandlersOnRootView) {
EXPECT_EQ(0, h2.GetEventCount(ui::ET_GESTURE_TAP_DOWN));
ui::GestureEvent tap_cancel(
- 5,
- 5,
- 0,
- ui::EventTimeForNow(),
+ 5, 5, 0, ui::EventTimeForNow(),
ui::GestureEventDetails(ui::ET_GESTURE_TAP_CANCEL));
widget->OnGestureEvent(&tap_cancel);
EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
@@ -1655,13 +1609,8 @@ TEST_F(WidgetTest, EventHandlersOnRootView) {
// Dispatch a ui::ET_SCROLL event. The event is handled at the target phase
// and should not reach the post-target handler.
- ui::ScrollEvent consumed_scroll(ui::ET_SCROLL,
- gfx::Point(5, 5),
- ui::EventTimeForNow(),
- 0,
- 0, 20,
- 0, 20,
- 2);
+ ui::ScrollEvent consumed_scroll(ui::ET_SCROLL, gfx::Point(5, 5),
+ ui::EventTimeForNow(), 0, 0, 20, 0, 20, 2);
widget->OnScrollEvent(&consumed_scroll);
EXPECT_EQ(1, h1.GetEventCount(ui::ET_SCROLL));
EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL));
@@ -1996,9 +1945,7 @@ void TestNativeWidgetDestroyedWidget::OnNativeWidgetDestroyed() {
// crash in ASan.
TEST_F(DesktopWidgetTest, WidgetDestroyedItselfDoesNotCrash) {
TestDesktopWidgetDelegate delegate(new TestNativeWidgetDestroyedWidget);
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- delegate.InitWidget(std::move(params));
+ delegate.InitWidget(CreateParamsForTestWidget());
delegate.GetWidget()->Show();
delegate.GetWidget()->CloseNow();
}
@@ -2270,6 +2217,7 @@ TEST_F(DesktopWidgetTest, CloseDestroys) {
Widget::InitParams params =
CreateParams(views::Widget::InitParams::TYPE_MENU);
params.opacity = Widget::InitParams::WindowOpacity::kOpaque;
+ params.bounds = gfx::Rect(50, 50, 250, 250);
widget->Init(std::move(params));
widget->Show();
widget->Hide();
@@ -2287,11 +2235,7 @@ TEST_F(DesktopWidgetTest, CloseDestroys) {
// Tests that killing a widget while animating it does not crash.
TEST_F(WidgetTest, CloseWidgetWhileAnimating) {
- std::unique_ptr<Widget> widget(new Widget);
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.bounds = gfx::Rect(50, 50, 250, 250);
- widget->Init(std::move(params));
+ std::unique_ptr<Widget> widget = CreateTestWidget();
AnimationEndObserver animation_observer;
WidgetBoundsObserver widget_observer;
gfx::Rect bounds(100, 100, 50, 50);
@@ -2365,28 +2309,17 @@ TEST_F(DesktopWidgetTest, ValidDuringOnNativeWidgetDestroyingFromClose) {
// Tests that we do not crash when a Widget is destroyed by going out of
// scope (as opposed to being explicitly deleted by its NativeWidget).
TEST_F(WidgetTest, NoCrashOnWidgetDelete) {
- std::unique_ptr<Widget> widget(new Widget);
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget->Init(std::move(params));
+ CreateTestWidget();
}
TEST_F(WidgetTest, NoCrashOnResizeConstraintsWindowTitleOnPopup) {
- std::unique_ptr<Widget> widget(new Widget);
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget->Init(std::move(params));
- widget->OnSizeConstraintsChanged();
+ CreateTestWidget(Widget::InitParams::TYPE_POPUP)->OnSizeConstraintsChanged();
}
// Tests that we do not crash when a Widget is destroyed before it finishes
// processing of pending input events in the message loop.
TEST_F(WidgetTest, NoCrashOnWidgetDeleteWithPendingEvents) {
- std::unique_ptr<Widget> widget(new Widget);
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
- params.bounds = gfx::Rect(0, 0, 200, 200);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget->Init(std::move(params));
+ std::unique_ptr<Widget> widget = CreateTestWidget();
widget->Show();
ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
@@ -2418,11 +2351,11 @@ class RootViewTestView : public View {
// Checks if RootView::*_handler_ fields are unset when widget is hidden.
// Fails on chromium.webkit Windows bot, see crbug.com/264872.
#if defined(OS_WIN)
-#define MAYBE_DisableTestRootViewHandlersWhenHidden\
- DISABLED_TestRootViewHandlersWhenHidden
+#define MAYBE_DisableTestRootViewHandlersWhenHidden \
+ DISABLED_TestRootViewHandlersWhenHidden
#else
-#define MAYBE_DisableTestRootViewHandlersWhenHidden\
- TestRootViewHandlersWhenHidden
+#define MAYBE_DisableTestRootViewHandlersWhenHidden \
+ TestRootViewHandlersWhenHidden
#endif
TEST_F(WidgetTest, MAYBE_DisableTestRootViewHandlersWhenHidden) {
Widget* widget = CreateTopLevelNativeWidget();
@@ -2998,8 +2931,8 @@ TEST_F(WidgetTest, GestureEventLocationWhileBubbling) {
// Define a GESTURE_TAP event located at (125, 105) in root view coordinates.
// This event is contained within all of |v1|, |v2|, and |v3|.
gfx::Point location_in_root(125, 105);
- GestureEventForTest tap(
- ui::ET_GESTURE_TAP, location_in_root.x(), location_in_root.y());
+ GestureEventForTest tap(ui::ET_GESTURE_TAP, location_in_root.x(),
+ location_in_root.y());
// Calculate the location of the event in the local coordinate spaces
// of each of the views.
@@ -3031,125 +2964,6 @@ TEST_F(WidgetTest, GestureEventLocationWhileBubbling) {
widget->Close();
}
-// Verifies that disabled views are permitted to be set as the default gesture
-// handler in RootView. Also verifies that gesture events targeted to a disabled
-// view are not actually dispatched to the view, but are still marked as
-// handled.
-TEST_F(WidgetTest, DisabledGestureEventTarget) {
- Widget* widget = CreateTopLevelNativeWidget();
- widget->SetBounds(gfx::Rect(0, 0, 300, 300));
-
- // Define a hierarchy of four views (coordinates are in
- // their parent coordinate space).
- // v1 (0, 0, 300, 300)
- // v2 (0, 0, 100, 100)
- // v3 (0, 0, 50, 50)
- // v4(0, 0, 10, 10)
- EventCountView* v1 = new EventCountView();
- v1->SetBounds(0, 0, 300, 300);
- EventCountView* v2 = new EventCountView();
- v2->SetBounds(0, 0, 100, 100);
- EventCountView* v3 = new EventCountView();
- v3->SetBounds(0, 0, 50, 50);
- EventCountView* v4 = new EventCountView();
- v4->SetBounds(0, 0, 10, 10);
- internal::RootView* root_view =
- static_cast<internal::RootView*>(widget->GetRootView());
- root_view->AddChildView(v1);
- v1->AddChildView(v2);
- v2->AddChildView(v3);
- v3->AddChildView(v4);
-
- widget->Show();
-
- // |v1|, |v2|, and |v3| all handle gesture events but |v3| is marked as
- // disabled.
- v1->set_handle_mode(EventCountView::CONSUME_EVENTS);
- v2->set_handle_mode(EventCountView::CONSUME_EVENTS);
- v3->set_handle_mode(EventCountView::CONSUME_EVENTS);
- v3->SetEnabled(false);
-
- // No gesture handler is set in the root view. In this case the tap event
- // should be dispatched only to |v4|, the gesture handler should be set to
- // |v3|, and the event should be marked as handled.
- GestureEventForTest tap(ui::ET_GESTURE_TAP, 5, 5);
- widget->OnGestureEvent(&tap);
- EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(1, v4->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(v3, GetGestureHandler(root_view));
- EXPECT_TRUE(tap.handled());
- v1->ResetCounts();
- v2->ResetCounts();
- v3->ResetCounts();
- v4->ResetCounts();
-
- // A subsequent gesture event should be marked as handled but not dispatched.
- tap = GestureEventForTest(ui::ET_GESTURE_TAP, 5, 5);
- widget->OnGestureEvent(&tap);
- EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(v3, GetGestureHandler(root_view));
- EXPECT_TRUE(tap.handled());
- v1->ResetCounts();
- v2->ResetCounts();
- v3->ResetCounts();
- v4->ResetCounts();
-
- // A GESTURE_END should reset the default gesture handler to NULL. It should
- // also not be dispatched to |v3| but still marked as handled.
- GestureEventForTest end(ui::ET_GESTURE_END, 5, 5);
- widget->OnGestureEvent(&end);
- EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_END));
- EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_END));
- EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_END));
- EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_END));
- EXPECT_EQ(nullptr, GetGestureHandler(root_view));
- EXPECT_TRUE(end.handled());
- v1->ResetCounts();
- v2->ResetCounts();
- v3->ResetCounts();
- v4->ResetCounts();
-
- // Change the handle mode of |v3| to indicate that it would no longer like
- // to handle events which are dispatched to it.
- v3->set_handle_mode(EventCountView::PROPAGATE_EVENTS);
-
- // No gesture handler is set in the root view. In this case the tap event
- // should be dispatched only to |v4| and the event should be marked as
- // handled. Furthermore, the gesture handler should be set to
- // |v3|; even though |v3| does not explicitly handle events, it is a
- // valid target for the tap event because it is disabled.
- tap = GestureEventForTest(ui::ET_GESTURE_TAP, 5, 5);
- widget->OnGestureEvent(&tap);
- EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(1, v4->GetEventCount(ui::ET_GESTURE_TAP));
- EXPECT_EQ(v3, GetGestureHandler(root_view));
- EXPECT_TRUE(tap.handled());
- v1->ResetCounts();
- v2->ResetCounts();
- v3->ResetCounts();
- v4->ResetCounts();
-
- // A GESTURE_END should reset the default gesture handler to NULL. It should
- // also not be dispatched to |v3| but still marked as handled.
- end = GestureEventForTest(ui::ET_GESTURE_END, 5, 5);
- widget->OnGestureEvent(&end);
- EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_END));
- EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_END));
- EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_END));
- EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_END));
- EXPECT_EQ(nullptr, GetGestureHandler(root_view));
- EXPECT_TRUE(end.handled());
-
- widget->Close();
-}
-
// Test the result of Widget::GetAllChildWidgets().
TEST_F(WidgetTest, GetAllChildWidgets) {
// Create the following widget hierarchy:
@@ -3201,9 +3015,7 @@ class DestroyedTrackingView : public View {
public:
DestroyedTrackingView(const std::string& name,
std::vector<std::string>* add_to)
- : name_(name),
- add_to_(add_to) {
- }
+ : name_(name), add_to_(add_to) {}
~DestroyedTrackingView() override { add_to_->push_back(name_); }
@@ -3285,35 +3097,19 @@ TEST_F(WidgetChildDestructionTest, DestroyChildWidgetsInOrder) {
// Verifies nativeview visbility matches that of Widget visibility when
// SetFullscreen is invoked.
TEST_F(WidgetTest, FullscreenStatePropagated) {
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
- init_params.show_state = ui::SHOW_STATE_NORMAL;
- init_params.bounds = gfx::Rect(0, 0, 500, 500);
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
-
- Widget top_level_widget;
- top_level_widget.Init(std::move(init_params));
- top_level_widget.SetFullscreen(true);
- EXPECT_EQ(top_level_widget.IsVisible(),
- IsNativeWindowVisible(top_level_widget.GetNativeWindow()));
- top_level_widget.CloseNow();
+ std::unique_ptr<Widget> top_level_widget = CreateTestWidget();
+ top_level_widget->SetFullscreen(true);
+ EXPECT_EQ(top_level_widget->IsVisible(),
+ IsNativeWindowVisible(top_level_widget->GetNativeWindow()));
}
// Verifies nativeview visbility matches that of Widget visibility when
// SetFullscreen is invoked, for a widget provided with a desktop widget.
TEST_F(DesktopWidgetTest, FullscreenStatePropagated_DesktopWidget) {
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
- init_params.show_state = ui::SHOW_STATE_NORMAL;
- init_params.bounds = gfx::Rect(0, 0, 500, 500);
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- Widget top_level_widget;
-
- top_level_widget.Init(std::move(init_params));
- top_level_widget.SetFullscreen(true);
- EXPECT_EQ(top_level_widget.IsVisible(),
- IsNativeWindowVisible(top_level_widget.GetNativeWindow()));
- top_level_widget.CloseNow();
+ std::unique_ptr<Widget> top_level_widget = CreateTestWidget();
+ top_level_widget->SetFullscreen(true);
+ EXPECT_EQ(top_level_widget->IsVisible(),
+ IsNativeWindowVisible(top_level_widget->GetNativeWindow()));
}
namespace {
@@ -3390,28 +3186,38 @@ class IsActiveFromDestroyObserver : public WidgetObserver {
} // namespace
+class ChildDesktopWidgetTest : public DesktopWidgetTest {
+ public:
+ Widget::InitParams CreateParams(Widget::InitParams::Type type) override {
+ Widget::InitParams params = DesktopWidgetTest::CreateParams(type);
+ if (context_)
+ params.context = context_;
+ return params;
+ }
+
+ std::unique_ptr<Widget> CreateChildWidget(gfx::NativeWindow context) {
+ context_ = context;
+ return CreateTestWidget();
+ }
+
+ private:
+ gfx::NativeWindow context_ = nullptr;
+};
+
// Verifies Widget::IsActive() invoked from
// WidgetObserver::OnWidgetDestroying() in a child widget doesn't crash.
-TEST_F(DesktopWidgetTest, IsActiveFromDestroy) {
+TEST_F(ChildDesktopWidgetTest, IsActiveFromDestroy) {
// Create two widgets, one a child of the other.
IsActiveFromDestroyObserver observer;
- Widget parent_widget;
- Widget::InitParams parent_params =
- CreateParams(Widget::InitParams::TYPE_POPUP);
- parent_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- parent_widget.Init(std::move(parent_params));
- parent_widget.Show();
-
- Widget child_widget;
- Widget::InitParams child_params =
- CreateParams(Widget::InitParams::TYPE_POPUP);
- child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- child_params.context = parent_widget.GetNativeWindow();
- child_widget.Init(std::move(child_params));
- child_widget.AddObserver(&observer);
- child_widget.Show();
-
- parent_widget.CloseNow();
+ std::unique_ptr<Widget> parent_widget = CreateTestWidget();
+ parent_widget->Show();
+
+ std::unique_ptr<Widget> child_widget =
+ CreateChildWidget(parent_widget->GetNativeWindow());
+ child_widget->AddObserver(&observer);
+ child_widget->Show();
+
+ parent_widget->CloseNow();
}
// Tests that events propagate through from the dispatcher with the correct
@@ -3506,8 +3312,7 @@ TEST_F(WidgetTest, NonClientWindowValidAfterInit) {
class SubclassWindowHelper {
public:
explicit SubclassWindowHelper(HWND window)
- : window_(window),
- message_to_destroy_on_(0) {
+ : window_(window), message_to_destroy_on_(0) {
EXPECT_EQ(instance_, nullptr);
instance_ = this;
EXPECT_TRUE(Subclass());
@@ -3523,9 +3328,7 @@ class SubclassWindowHelper {
return (messages_.find(message) != messages_.end());
}
- void Clear() {
- messages_.clear();
- }
+ void Clear() { messages_.clear(); }
void set_message_to_destroy_on(unsigned int message) {
message_to_destroy_on_ = message;
@@ -3533,16 +3336,13 @@ class SubclassWindowHelper {
private:
bool Subclass() {
- old_proc_ = reinterpret_cast<WNDPROC>(
- ::SetWindowLongPtr(window_,
- GWLP_WNDPROC,
- reinterpret_cast<LONG_PTR>(WndProc)));
+ old_proc_ = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(
+ window_, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WndProc)));
return old_proc_ != nullptr;
}
void Unsubclass() {
- ::SetWindowLongPtr(window_,
- GWLP_WNDPROC,
+ ::SetWindowLongPtr(window_, GWLP_WNDPROC,
reinterpret_cast<LONG_PTR>(old_proc_));
}
@@ -3585,15 +3385,12 @@ SubclassWindowHelper* SubclassWindowHelper::instance_ = nullptr;
// Disabled because of flaky timeouts: http://crbug.com/592742
TEST_F(DesktopWidgetTest,
DISABLED_SysCommandMoveOnNCLButtonDownOnCaptionAndMoveTest) {
- Widget widget;
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget.Init(std::move(params));
- widget.SetBounds(gfx::Rect(0, 0, 200, 200));
- widget.Show();
+ std::unique_ptr<Widget> widget =
+ CreateTestWidget(Widget::InitParams::TYPE_WINDOW);
+ widget->Show();
::SetCursorPos(500, 500);
- HWND window = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget();
+ HWND window = widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget();
SubclassWindowHelper subclass_helper(window);
@@ -3648,24 +3445,18 @@ TEST_F(DesktopWidgetTest,
EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
EXPECT_TRUE(subclass_helper.received_message(WM_MOUSEMOVE));
EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
-
- widget.CloseNow();
}
// This test validates that destroying the window in the context of the
// WM_SYSCOMMAND message with SC_MOVE does not crash.
// Disabled because of flaky timeouts: http://crbug.com/592742
TEST_F(DesktopWidgetTest, DISABLED_DestroyInSysCommandNCLButtonDownOnCaption) {
- Widget widget;
- Widget::InitParams params =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget.Init(std::move(params));
- widget.SetBounds(gfx::Rect(0, 0, 200, 200));
- widget.Show();
+ std::unique_ptr<Widget> widget =
+ CreateTestWidget(Widget::InitParams::TYPE_WINDOW);
+ widget->Show();
::SetCursorPos(500, 500);
- HWND window = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget();
+ HWND window = widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget();
SubclassWindowHelper subclass_helper(window);
@@ -3679,8 +3470,6 @@ TEST_F(DesktopWidgetTest, DISABLED_DestroyInSysCommandNCLButtonDownOnCaption) {
EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
-
- widget.CloseNow();
}
#endif
@@ -3875,22 +3664,19 @@ class LayoutCountingView : public View {
using WidgetInvalidateLayoutTest = ViewsTestBaseWithNativeWidgetType;
TEST_P(WidgetInvalidateLayoutTest, InvalidateLayout) {
- Widget widget;
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget.Init(std::move(params));
- widget.SetBounds(gfx::Rect(0, 0, 600, 600));
+ std::unique_ptr<Widget> widget =
+ CreateTestWidget(Widget::InitParams::TYPE_WINDOW);
LayoutCountingView* view =
- widget.widget_delegate()->GetContentsView()->AddChildView(
+ widget->widget_delegate()->GetContentsView()->AddChildView(
std::make_unique<LayoutCountingView>());
view->parent()->SetLayoutManager(std::make_unique<FillLayout>());
// Force an initial Layout().
// TODO(sky): this shouldn't be necessary, adding a child view should trigger
// ScheduleLayout().
view->Layout();
- widget.Show();
+ widget->Show();
- ui::Compositor* compositor = widget.GetCompositor();
+ ui::Compositor* compositor = widget->GetCompositor();
ASSERT_TRUE(compositor);
compositor->ScheduleDraw();
ui::DrawWaiterForTest::WaitForCompositingEnded(compositor);
@@ -3902,14 +3688,14 @@ TEST_P(WidgetInvalidateLayoutTest, InvalidateLayout) {
// wait for Layout() to be called.
view->set_layout_closure(run_loop.QuitClosure());
EXPECT_FALSE(ViewTestApi(view).needs_layout());
- EXPECT_FALSE(ViewTestApi(widget.GetRootView()).needs_layout());
+ EXPECT_FALSE(ViewTestApi(widget->GetRootView()).needs_layout());
view->InvalidateLayout();
EXPECT_TRUE(ViewTestApi(view).needs_layout());
- EXPECT_TRUE(ViewTestApi(widget.GetRootView()).needs_layout());
+ EXPECT_TRUE(ViewTestApi(widget->GetRootView()).needs_layout());
run_loop.Run();
EXPECT_EQ(1u, view->GetAndClearLayoutCount());
EXPECT_FALSE(ViewTestApi(view).needs_layout());
- EXPECT_FALSE(ViewTestApi(widget.GetRootView()).needs_layout());
+ EXPECT_FALSE(ViewTestApi(widget->GetRootView()).needs_layout());
}
INSTANTIATE_TEST_SUITE_P(
@@ -4068,14 +3854,14 @@ namespace {
// Provides functionality to create a window modal dialog.
class ModalDialogDelegate : public DialogDelegateView {
-public:
+ public:
explicit ModalDialogDelegate(ui::ModalType type) : type_(type) {}
~ModalDialogDelegate() override = default;
// WidgetDelegate overrides.
ui::ModalType GetModalType() const override { return type_; }
-private:
+ private:
const ui::ModalType type_;
DISALLOW_COPY_AND_ASSIGN(ModalDialogDelegate);
@@ -4088,18 +3874,10 @@ private:
// remaining top-level windows should be re-enabled.
TEST_F(DesktopWidgetTest, WindowModalOwnerDestroyedEnabledTest) {
// top_level_widget owns owner_dialog_widget which owns owned_dialog_widget.
- Widget top_level_widget;
- Widget owner_dialog_widget;
- Widget owned_dialog_widget;
+
// Create the top level widget.
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
- init_params.show_state = ui::SHOW_STATE_NORMAL;
- gfx::Rect initial_bounds(0, 0, 500, 500);
- init_params.bounds = initial_bounds;
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- top_level_widget.Init(std::move(init_params));
- top_level_widget.Show();
+ std::unique_ptr<Widget> top_level_widget = CreateTestWidget();
+ top_level_widget->Show();
// Create the owner modal dialog.
// owner_dialog_delegate instance will be destroyed when the dialog
@@ -4107,12 +3885,11 @@ TEST_F(DesktopWidgetTest, WindowModalOwnerDestroyedEnabledTest) {
ModalDialogDelegate* owner_dialog_delegate =
new ModalDialogDelegate(ui::MODAL_TYPE_WINDOW);
- init_params = CreateParams(Widget::InitParams::TYPE_WINDOW);
- init_params.show_state = ui::SHOW_STATE_NORMAL;
- init_params.bounds = gfx::Rect(100, 100, 200, 200);
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ Widget owner_dialog_widget;
+ Widget::InitParams init_params =
+ CreateParamsForTestWidget(Widget::InitParams::TYPE_WINDOW);
init_params.delegate = owner_dialog_delegate;
- init_params.parent = top_level_widget.GetNativeView();
+ init_params.parent = top_level_widget->GetNativeView();
init_params.native_widget =
new test::TestPlatformNativeWidget<DesktopNativeWidgetAura>(
&owner_dialog_widget, false, nullptr);
@@ -4128,10 +3905,7 @@ TEST_F(DesktopWidgetTest, WindowModalOwnerDestroyedEnabledTest) {
ModalDialogDelegate* owned_dialog_delegate =
new ModalDialogDelegate(ui::MODAL_TYPE_WINDOW);
- init_params = CreateParams(Widget::InitParams::TYPE_WINDOW);
- init_params.show_state = ui::SHOW_STATE_NORMAL;
- init_params.bounds = gfx::Rect(150, 150, 250, 250);
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ Widget owned_dialog_widget;
init_params.delegate = owned_dialog_delegate;
init_params.parent = owner_dialog_widget.GetNativeView();
init_params.native_widget =
@@ -4144,7 +3918,7 @@ TEST_F(DesktopWidgetTest, WindowModalOwnerDestroyedEnabledTest) {
owned_dialog_widget.Show();
RunPendingMessages();
- HWND top_hwnd = HWNDForWidget(&top_level_widget);
+ HWND top_hwnd = HWNDForWidget(top_level_widget.get());
EXPECT_FALSE(!!IsWindowEnabled(owner_hwnd));
EXPECT_FALSE(!!IsWindowEnabled(top_hwnd));
@@ -4157,7 +3931,7 @@ TEST_F(DesktopWidgetTest, WindowModalOwnerDestroyedEnabledTest) {
EXPECT_FALSE(!!IsWindow(owned_hwnd));
EXPECT_TRUE(!!IsWindowEnabled(top_hwnd));
- top_level_widget.CloseNow();
+ top_level_widget->CloseNow();
}
#endif // defined(OS_WIN)
@@ -4166,17 +3940,6 @@ TEST_F(DesktopWidgetTest, WindowModalOwnerDestroyedEnabledTest) {
namespace {
-void InitializeWidgetForOpacity(
- Widget& widget,
- Widget::InitParams init_params,
- const Widget::InitParams::WindowOpacity opacity) {
- init_params.opacity = opacity;
- init_params.show_state = ui::SHOW_STATE_NORMAL;
- init_params.bounds = gfx::Rect(0, 0, 500, 500);
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget.Init(std::move(init_params));
-}
-
class CompositingWidgetTest : public DesktopWidgetTest {
public:
CompositingWidgetTest()
@@ -4190,8 +3953,15 @@ class CompositingWidgetTest : public DesktopWidgetTest {
Widget::InitParams::TYPE_DRAG} {}
~CompositingWidgetTest() override = default;
+ Widget::InitParams CreateParams(Widget::InitParams::Type type) override {
+ Widget::InitParams params = DesktopWidgetTest::CreateParams(type);
+ params.opacity = opacity_;
+ return params;
+ }
+
void CheckAllWidgetsForOpacity(
const Widget::InitParams::WindowOpacity opacity) {
+ opacity_ = opacity;
for (const auto& widget_type : widget_types_) {
#if defined(OS_MACOSX)
// Tooltips are native on Mac. See NativeWidgetNSWindowBridge::Init.
@@ -4203,8 +3973,7 @@ class CompositingWidgetTest : public DesktopWidgetTest {
if (widget_type != Widget::InitParams::TYPE_WINDOW)
continue;
#endif
- Widget widget;
- InitializeWidgetForOpacity(widget, CreateParams(widget_type), opacity);
+ std::unique_ptr<Widget> widget = CreateTestWidget(widget_type);
// Use NativeWidgetAura directly.
if (widget_type == Widget::InitParams::TYPE_WINDOW_FRAMELESS ||
@@ -4218,21 +3987,21 @@ class CompositingWidgetTest : public DesktopWidgetTest {
// TestViewsDelegate::use_transparent_windows_ determines the result of
// kInferOpacity: assume it is false.
bool should_be_transparent =
- opacity == Widget::InitParams::WindowOpacity::kTranslucent;
+ opacity_ == Widget::InitParams::WindowOpacity::kTranslucent;
#else
- bool should_be_transparent = widget.ShouldWindowContentsBeTransparent();
+ bool should_be_transparent = widget->ShouldWindowContentsBeTransparent();
#endif
- EXPECT_EQ(IsNativeWindowTransparent(widget.GetNativeWindow()),
+ EXPECT_EQ(IsNativeWindowTransparent(widget->GetNativeWindow()),
should_be_transparent);
#if defined(USE_X11)
if (HasCompositingManager() &&
(widget_type == Widget::InitParams::TYPE_DRAG ||
widget_type == Widget::InitParams::TYPE_WINDOW)) {
- EXPECT_TRUE(widget.IsTranslucentWindowOpacitySupported());
+ EXPECT_TRUE(widget->IsTranslucentWindowOpacitySupported());
} else {
- EXPECT_FALSE(widget.IsTranslucentWindowOpacitySupported());
+ EXPECT_FALSE(widget->IsTranslucentWindowOpacitySupported());
}
#endif
}
@@ -4240,6 +4009,8 @@ class CompositingWidgetTest : public DesktopWidgetTest {
protected:
const std::vector<Widget::InitParams::Type> widget_types_;
+ Widget::InitParams::WindowOpacity opacity_ =
+ Widget::InitParams::WindowOpacity::kInferred;
DISALLOW_COPY_AND_ASSIGN(CompositingWidgetTest);
};
diff --git a/chromium/ui/views/widget/window_reorderer.cc b/chromium/ui/views/widget/window_reorderer.cc
index ce52ff296c5..b1ac11fc465 100644
--- a/chromium/ui/views/widget/window_reorderer.cc
+++ b/chromium/ui/views/widget/window_reorderer.cc
@@ -8,6 +8,7 @@
#include <algorithm>
#include <map>
+#include <set>
#include <vector>
#include "base/containers/adapters.h"
@@ -87,8 +88,7 @@ class WindowReorderer::AssociationObserver : public aura::WindowObserver {
WindowReorderer::AssociationObserver::AssociationObserver(
WindowReorderer* reorderer)
- : reorderer_(reorderer) {
-}
+ : reorderer_(reorderer) {}
WindowReorderer::AssociationObserver::~AssociationObserver() {
while (!windows_.empty())
@@ -101,8 +101,7 @@ void WindowReorderer::AssociationObserver::StartObserving(
window->AddObserver(this);
}
-void WindowReorderer::AssociationObserver::StopObserving(
- aura::Window* window) {
+void WindowReorderer::AssociationObserver::StopObserving(aura::Window* window) {
windows_.erase(window);
window->RemoveObserver(this);
}
@@ -121,8 +120,7 @@ void WindowReorderer::AssociationObserver::OnWindowDestroying(
window->RemoveObserver(this);
}
-WindowReorderer::WindowReorderer(aura::Window* parent_window,
- View* root_view)
+WindowReorderer::WindowReorderer(aura::Window* parent_window, View* root_view)
: parent_window_(parent_window),
root_view_(root_view),
association_observer_(new AssociationObserver(this)) {
@@ -158,7 +156,7 @@ void WindowReorderer::ReorderChildWindows() {
// with layers and views with associated windows in the view tree.
std::vector<View*> view_with_layer_order;
GetOrderOfViewsWithLayers(root_view_, parent_window_->layer(), hosted_windows,
- &view_with_layer_order);
+ &view_with_layer_order);
std::vector<ui::Layer*> children_layer_order;
diff --git a/chromium/ui/views/widget/window_reorderer_unittest.cc b/chromium/ui/views/widget/window_reorderer_unittest.cc
index 9ecebbc9dad..670cc0f1238 100644
--- a/chromium/ui/views/widget/window_reorderer_unittest.cc
+++ b/chromium/ui/views/widget/window_reorderer_unittest.cc
@@ -17,22 +17,10 @@
namespace views {
namespace {
-// Creates a control widget with the passed in parameters.
-// The caller takes ownership of the returned widget.
-Widget* CreateControlWidget(aura::Window* parent, const gfx::Rect& bounds) {
- Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.parent = parent;
- params.bounds = bounds;
- Widget* widget = new Widget();
- widget->Init(std::move(params));
- return widget;
-}
-
// Sets the name of |window| and |window|'s layer to |name|.
void SetWindowAndLayerName(aura::Window* window, const std::string& name) {
window->SetName(name);
- window->layer()->set_name(name);
+ window->layer()->SetName(name);
}
// Returns a string containing the name of each of the child windows (bottommost
@@ -47,13 +35,27 @@ std::string ChildWindowNamesAsString(const aura::Window& parent) {
return names;
}
-using WindowReordererTest = ViewsTestBase;
+class WindowReordererTest : public ViewsTestBase {
+ public:
+ Widget::InitParams CreateParams(Widget::InitParams::Type type) override {
+ Widget::InitParams params = ViewsTestBase::CreateParams(type);
+ params.parent = parent_;
+ return params;
+ }
+
+ std::unique_ptr<Widget> CreateControlWidget(aura::Window* parent) {
+ parent_ = parent;
+ return CreateTestWidget(Widget::InitParams::TYPE_CONTROL);
+ }
+
+ private:
+ aura::Window* parent_ = nullptr;
+};
// Test that views with layers and views with associated windows are reordered
// according to the view hierarchy.
TEST_F(WindowReordererTest, Basic) {
- std::unique_ptr<Widget> parent(
- CreateControlWidget(root_window(), gfx::Rect(0, 0, 100, 100)));
+ std::unique_ptr<Widget> parent = CreateControlWidget(root_window());
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
@@ -65,15 +67,13 @@ TEST_F(WindowReordererTest, Basic) {
// view.
View* v = new View();
v->SetPaintToLayer();
- v->layer()->set_name("v");
+ v->layer()->SetName("v");
contents_view->AddChildView(v);
- std::unique_ptr<Widget> w1(
- CreateControlWidget(parent_window, gfx::Rect(0, 1, 100, 101)));
+ std::unique_ptr<Widget> w1 = CreateControlWidget(parent_window);
SetWindowAndLayerName(w1->GetNativeView(), "w1");
w1->Show();
- std::unique_ptr<Widget> w2(
- CreateControlWidget(parent_window, gfx::Rect(0, 2, 100, 102)));
+ std::unique_ptr<Widget> w2 = CreateControlWidget(parent_window);
SetWindowAndLayerName(w2->GetNativeView(), "w2");
w2->Show();
@@ -118,10 +118,6 @@ TEST_F(WindowReordererTest, Basic) {
EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("w1 v w2",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
-
- // Work around for bug in NativeWidgetAura.
- // TODO: fix bug and remove this.
- parent->Close();
}
// Test that different orderings of:
@@ -130,16 +126,15 @@ TEST_F(WindowReordererTest, Basic) {
// - associating the "host" view and window
// all correctly reorder the child windows and layers.
TEST_F(WindowReordererTest, Association) {
- std::unique_ptr<Widget> parent(
- CreateControlWidget(root_window(), gfx::Rect(0, 0, 100, 100)));
+ std::unique_ptr<Widget> parent = CreateControlWidget(root_window());
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
View* contents_view = new View();
parent->SetContentsView(contents_view);
- aura::Window* w1 = aura::test::CreateTestWindowWithId(0,
- parent->GetNativeWindow());
+ aura::Window* w1 =
+ aura::test::CreateTestWindowWithId(0, parent->GetNativeWindow());
SetWindowAndLayerName(w1, "w1");
aura::Window* w2 = aura::test::CreateTestWindowWithId(0, nullptr);
@@ -152,8 +147,7 @@ TEST_F(WindowReordererTest, Association) {
contents_view->AddChildView(host_view2);
w2->SetProperty(views::kHostViewKey, host_view2);
EXPECT_EQ("w1", ChildWindowNamesAsString(*parent_window));
- EXPECT_EQ("w1",
- ui::test::ChildLayerNamesAsString(*parent_window->layer()));
+ EXPECT_EQ("w1", ui::test::ChildLayerNamesAsString(*parent_window->layer()));
parent_window->AddChild(w2);
EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window));
@@ -180,10 +174,6 @@ TEST_F(WindowReordererTest, Association) {
EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("w2 w1",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
-
- // Work around for bug in NativeWidgetAura.
- // TODO: fix bug and remove this.
- parent->Close();
}
// It is possible to associate a window to a view which has a parent layer
@@ -191,8 +181,7 @@ TEST_F(WindowReordererTest, Association) {
// view and the parent layer of the associated window are different. Test that
// the layers and windows are properly reordered in this case.
TEST_F(WindowReordererTest, HostViewParentHasLayer) {
- std::unique_ptr<Widget> parent(
- CreateControlWidget(root_window(), gfx::Rect(0, 0, 100, 100)));
+ std::unique_ptr<Widget> parent = CreateControlWidget(root_window());
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
@@ -214,11 +203,10 @@ TEST_F(WindowReordererTest, HostViewParentHasLayer) {
View* v11 = new View();
v11->SetPaintToLayer();
- v11->layer()->set_name("v11");
+ v11->layer()->SetName("v11");
v1->AddChildView(v11);
- std::unique_ptr<Widget> w(
- CreateControlWidget(parent_window, gfx::Rect(0, 1, 100, 101)));
+ std::unique_ptr<Widget> w = CreateControlWidget(parent_window);
SetWindowAndLayerName(w->GetNativeView(), "w");
w->Show();
@@ -228,12 +216,12 @@ TEST_F(WindowReordererTest, HostViewParentHasLayer) {
View* v13 = new View();
v13->SetPaintToLayer();
- v13->layer()->set_name("v13");
+ v13->layer()->SetName("v13");
v1->AddChildView(v13);
View* v2 = new View();
v2->SetPaintToLayer();
- v2->layer()->set_name("v2");
+ v2->layer()->SetName("v2");
contents_view->AddChildView(v2);
// Test intial state.
@@ -243,7 +231,7 @@ TEST_F(WindowReordererTest, HostViewParentHasLayer) {
// |w|'s layer should be stacked above |v1|'s layer.
v1->SetPaintToLayer();
- v1->layer()->set_name("v1");
+ v1->layer()->SetName("v1");
EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("v1 w v2",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
@@ -254,16 +242,11 @@ TEST_F(WindowReordererTest, HostViewParentHasLayer) {
EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("v1 v2 w",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
-
- // Work around for bug in NativeWidgetAura.
- // TODO: fix bug and remove this.
- parent->Close();
}
// Test that a layer added beneath a view is restacked correctly.
TEST_F(WindowReordererTest, ViewWithLayerBeneath) {
- std::unique_ptr<Widget> parent(
- CreateControlWidget(root_window(), gfx::Rect(0, 0, 100, 100)));
+ std::unique_ptr<Widget> parent = CreateControlWidget(root_window());
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
@@ -277,8 +260,8 @@ TEST_F(WindowReordererTest, ViewWithLayerBeneath) {
view_with_layer_beneath->AddLayerBeneathView(&layer_beneath);
ASSERT_NE(nullptr, view_with_layer_beneath->layer());
- view_with_layer_beneath->layer()->set_name("view");
- layer_beneath.set_name("beneath");
+ view_with_layer_beneath->layer()->SetName("view");
+ layer_beneath.SetName("beneath");
// Verify that the initial ordering is correct.
EXPECT_EQ("beneath view",
@@ -286,8 +269,7 @@ TEST_F(WindowReordererTest, ViewWithLayerBeneath) {
// Add a hosted window to make WindowReorderer::ReorderChildWindows() restack
// layers.
- std::unique_ptr<Widget> child_widget(
- CreateControlWidget(parent_window, gfx::Rect(gfx::Rect(0, 0, 50, 50))));
+ std::unique_ptr<Widget> child_widget = CreateControlWidget(parent_window);
SetWindowAndLayerName(child_widget->GetNativeView(), "child_widget");
child_widget->Show();
View* host_view = contents_view->AddChildView(std::make_unique<View>());