Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: ui/views/mus/platform_window_mus.cc

Issue 1891233006: mus: Fix handled status in UI event ack, add MessageLoop::NestingObserver (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@eventresult
Patch Set: review comments, added PlatformWindowMusTest Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/mus/platform_window_mus.h ('k') | ui/views/mus/platform_window_mus_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/mus/platform_window_mus.cc
diff --git a/ui/views/mus/platform_window_mus.cc b/ui/views/mus/platform_window_mus.cc
index 4b72979b40ce92857c8d88346fcdc320a7a2eb10..f1d58a37dabfda16ce900e8ed835e42ad868bd28 100644
--- a/ui/views/mus/platform_window_mus.cc
+++ b/ui/views/mus/platform_window_mus.cc
@@ -4,6 +4,7 @@
#include "ui/views/mus/platform_window_mus.h"
+#include "base/message_loop/message_loop.h"
#include "build/build_config.h"
#include "components/bitmap_uploader/bitmap_uploader.h"
#include "components/mus/public/cpp/property_type_converters.h"
@@ -14,11 +15,40 @@
#include "ui/platform_window/platform_window_delegate.h"
#include "ui/views/mus/window_manager_connection.h"
+using mus::mojom::EventResult;
+
namespace views {
namespace {
+
static uint32_t accelerated_widget_count = 1;
+// Acknowledges an input event immediately if a nested message loop starts.
+// Needed because otherwise we appear unresponsive for the life of the nested
+// message loop.
+class EventAckNestingObserver : public base::MessageLoop::NestingObserver {
+ public:
+ explicit EventAckNestingObserver(
+ std::unique_ptr<base::Callback<void(EventResult)>>* ack_callback)
sky 2016/04/27 17:49:48 Did you consider making this take a std::unique_pt
James Cook 2016/04/27 18:11:14 Done.
+ : ack_callback_(ack_callback) {
+ DCHECK(ack_callback_);
+ }
+ ~EventAckNestingObserver() override {}
+
+ // base::MessageLoop::NestingObserver:
+ void OnBeginNestedMessageLoop() override {
+ if (*ack_callback_) {
+ (*ack_callback_)->Run(EventResult::HANDLED);
+ ack_callback_->reset(); // Signal that the event was ack'd.
+ }
+ }
+
+ private:
+ std::unique_ptr<base::Callback<void(EventResult)>>* ack_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(EventAckNestingObserver);
+};
+
} // namespace
PlatformWindowMus::PlatformWindowMus(ui::PlatformWindowDelegate* delegate,
@@ -222,17 +252,29 @@ void PlatformWindowMus::OnRequestClose(mus::Window* window) {
void PlatformWindowMus::OnWindowInputEvent(
mus::Window* view,
- const ui::Event& event,
- std::unique_ptr<base::Callback<void(mus::mojom::EventResult)>>*
- ack_callback) {
- // It's possible dispatching the event will spin a nested message loop. Ack
- // the callback now, otherwise we appear unresponsive for the life of the
- // nested message loop.
- (*ack_callback)->Run(mus::mojom::EventResult::HANDLED);
- ack_callback->reset();
- // TODO(moshayedi): Avoid cloning after updating PlatformWindowDelegate to
- // accept constant pointers.
- delegate_->DispatchEvent(ui::Event::Clone(event).get());
+ const ui::Event& event_in,
+ std::unique_ptr<base::Callback<void(EventResult)>>* ack_callback_in) {
+ // Take ownership of the callback, indicating that we will handle it.
+ std::unique_ptr<base::Callback<void(EventResult)>> ack_callback =
+ std::move(*ack_callback_in);
+
+ // If dispatching the event creates a nested message loop we need to ack the
+ // event immediately. There might be multiple nested message loops; each one
+ // needs its own observer.
+ EventAckNestingObserver nesting_observer(&ack_callback);
+ base::MessageLoop::current()->AddNestingObserver(&nesting_observer);
+
+ std::unique_ptr<ui::Event> event = ui::Event::Clone(event_in);
+ delegate_->DispatchEvent(event.get());
+ // NOTE: |this| may be deleted.
+
+ base::MessageLoop::current()->RemoveNestingObserver(&nesting_observer);
+
+ // If the callback wasn't already called by the message loop observer then
+ // ack it with the handled state.
+ if (ack_callback)
+ ack_callback->Run(event->handled() ? EventResult::HANDLED
+ : EventResult::UNHANDLED);
}
} // namespace views
« no previous file with comments | « ui/views/mus/platform_window_mus.h ('k') | ui/views/mus/platform_window_mus_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698