Commit 4a2dcc48 authored by andresantoso's avatar andresantoso Committed by Commit bot

MacViews: Create abstraction for event monitoring

Use of aura::Env::AddPreTargetHandler won't compile on Mac, so we hide it
behind an interface and add a Mac implementation.

BUG=425229

Review URL: https://codereview.chromium.org/678823002

Cr-Commit-Position: refs/heads/master@{#301563}
parent 12bfc748
......@@ -29,12 +29,11 @@
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_function_dispatcher.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/events/event_constants.h"
#include "ui/events/gestures/gesture_recognizer.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/screen.h"
#include "ui/views/event_monitor.h"
#include "ui/views/focus/view_storage.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"
......@@ -48,6 +47,8 @@
#endif
#if defined(USE_AURA)
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/wm/core/window_modality_controller.h"
#endif
......@@ -141,17 +142,13 @@ class WindowPositionManagedUpdater : public views::WidgetObserver {
}
};
// EscapeTracker installs itself as a pre-target handler on aura::Env and runs a
// callback when it receives the escape key.
// EscapeTracker installs an event monitor and runs a callback when it receives
// the escape key.
class EscapeTracker : public ui::EventHandler {
public:
explicit EscapeTracker(const base::Closure& callback)
: escape_callback_(callback) {
aura::Env::GetInstance()->AddPreTargetHandler(this);
}
virtual ~EscapeTracker() {
aura::Env::GetInstance()->RemovePreTargetHandler(this);
: escape_callback_(callback),
event_monitor_(views::EventMonitor::Create(this)) {
}
private:
......@@ -164,6 +161,7 @@ class EscapeTracker : public ui::EventHandler {
}
base::Closure escape_callback_;
scoped_ptr<views::EventMonitor> event_monitor_;
DISALLOW_COPY_AND_ASSIGN(EscapeTracker);
};
......
// Copyright 2014 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_EVENT_MONITOR_H_
#define UI_VIEWS_EVENT_MONITOR_H_
#include "ui/gfx/geometry/point.h"
#include "ui/views/views_export.h"
namespace ui {
class EventHandler;
}
namespace views {
// RAII-style class that forwards events posted to the application to
// |event_handler| before they are dispatched.
class VIEWS_EXPORT EventMonitor {
public:
virtual ~EventMonitor() {}
static EventMonitor* Create(ui::EventHandler* event_handler);
// Returns the last mouse location seen in a mouse event in screen
// coordinates.
static gfx::Point GetLastMouseLocation();
};
} // namespace views
#endif // UI_VIEWS_EVENT_MONITOR_H_
// Copyright 2014 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/event_monitor_aura.h"
#include "base/logging.h"
#include "ui/aura/env.h"
namespace views {
// static
EventMonitor* EventMonitor::Create(ui::EventHandler* event_handler) {
return new EventMonitorAura(event_handler);
}
// static
gfx::Point EventMonitor::GetLastMouseLocation() {
return aura::Env::GetInstance()->last_mouse_location();
}
EventMonitorAura::EventMonitorAura(ui::EventHandler* event_handler)
: event_handler_(event_handler) {
DCHECK(event_handler_);
aura::Env::GetInstance()->AddPreTargetHandler(event_handler_);
}
EventMonitorAura::~EventMonitorAura() {
aura::Env::GetInstance()->RemovePreTargetHandler(event_handler_);
}
} // namespace views
// Copyright 2014 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_EVENT_MONITOR_AURA_H_
#define UI_VIEWS_EVENT_MONITOR_AURA_H_
#include "base/macros.h"
#include "ui/views/event_monitor.h"
namespace views {
class EventMonitorAura : public EventMonitor {
public:
explicit EventMonitorAura(ui::EventHandler* event_handler);
virtual ~EventMonitorAura();
private:
ui::EventHandler* event_handler_; // Weak. Owned by our owner.
DISALLOW_COPY_AND_ASSIGN(EventMonitorAura);
};
} // namespace views
#endif // UI_VIEWS_EVENT_MONITOR_AURA_H_
// Copyright 2014 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_EVENT_MONITOR_MAC_H_
#define UI_VIEWS_EVENT_MONITOR_MAC_H_
#include "base/macros.h"
#include "ui/views/event_monitor.h"
#import <Cocoa/Cocoa.h>
namespace views {
class EventMonitorMac : public EventMonitor {
public:
explicit EventMonitorMac(ui::EventHandler* event_handler);
virtual ~EventMonitorMac();
private:
id monitor_;
DISALLOW_COPY_AND_ASSIGN(EventMonitorMac);
};
} // namespace views
#endif // UI_VIEWS_EVENT_MONITOR_MAC_H_
// Copyright 2014 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/event_monitor_mac.h"
#include "base/logging.h"
#include "ui/events/event.h"
#include "ui/events/event_handler.h"
#include "ui/events/event_utils.h"
namespace views {
// static
EventMonitor* EventMonitor::Create(ui::EventHandler* event_handler) {
return new EventMonitorMac(event_handler);
}
// static
gfx::Point EventMonitor::GetLastMouseLocation() {
NSPoint mouseLocation = [NSEvent mouseLocation];
// Flip coordinates to gfx (0,0 in top-left corner) using primary screen.
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
mouseLocation.y = NSMaxY([screen frame]) - mouseLocation.y;
return gfx::Point(mouseLocation.x, mouseLocation.y);
}
EventMonitorMac::EventMonitorMac(ui::EventHandler* event_handler) {
DCHECK(event_handler);
monitor_ = [NSEvent addLocalMonitorForEventsMatchingMask:NSAnyEventMask
handler:^NSEvent*(NSEvent* event){
scoped_ptr<ui::Event> ui_event = ui::EventFromNative(event);
event_handler->OnEvent(ui_event.get());
return event;
}];
}
EventMonitorMac::~EventMonitorMac() {
[NSEvent removeMonitor:monitor_];
}
} // namespace views
// Copyright 2014 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/event_monitor_mac.h"
#include "ui/events/event.h"
#include "ui/events/event_handler.h"
#include "ui/events/event_constants.h"
#import "ui/events/test/cocoa_test_event_utils.h"
#import "ui/gfx/test/ui_cocoa_test_helper.h"
namespace views {
namespace {
class EventMonitorMacTest : public ui::CocoaTest {
public:
EventMonitorMacTest() {}
private:
DISALLOW_COPY_AND_ASSIGN(EventMonitorMacTest);
};
class EventCounter : public ui::EventHandler {
public:
EventCounter() : event_count_(0), last_event_type_(ui::ET_UNKNOWN) {}
int event_count() const { return event_count_; }
ui::EventType last_event_type() { return last_event_type_; }
// ui::EventHandler implementation:
virtual void OnEvent(ui::Event* event) override {
++event_count_;
last_event_type_ = event->type();
}
private:
int event_count_;
ui::EventType last_event_type_;
};
} // namespace
TEST_F(EventMonitorMacTest, CountEvents) {
EventCounter counter;
NSEvent* event =
cocoa_test_event_utils::EnterExitEventWithType(NSMouseExited);
// No monitor installed yet, should not receive events.
[NSApp sendEvent:event];
EXPECT_EQ(0, counter.event_count());
EXPECT_EQ(ui::ET_UNKNOWN, counter.last_event_type());
// Install monitor, should start receiving event.
scoped_ptr<EventMonitor> event_monitor(EventMonitor::Create(&counter));
[NSApp sendEvent:event];
EXPECT_EQ(1, counter.event_count());
EXPECT_EQ(ui::ET_MOUSE_EXITED, counter.last_event_type());
// Uninstall monitor, should stop receiving events.
event_monitor.reset();
[NSApp sendEvent:event];
EXPECT_EQ(1, counter.event_count());
EXPECT_EQ(ui::ET_MOUSE_EXITED, counter.last_event_type());
}
} // namespace views
......@@ -9,13 +9,11 @@
#include "base/event_types.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_handler.h"
#include "ui/events/event_utils.h"
#include "ui/gfx/screen.h"
#include "ui/views/event_monitor.h"
namespace views {
......@@ -27,16 +25,12 @@ class MouseWatcher::Observer : public ui::EventHandler {
public:
explicit Observer(MouseWatcher* mouse_watcher)
: mouse_watcher_(mouse_watcher),
event_monitor_(views::EventMonitor::Create(this)),
notify_listener_factory_(this) {
aura::Env::GetInstance()->AddPreTargetHandler(this);
}
~Observer() override {
aura::Env::GetInstance()->RemovePreTargetHandler(this);
}
// ui::EventHandler implementation:
void OnMouseEvent(ui::MouseEvent* event) override {
virtual void OnMouseEvent(ui::MouseEvent* event) override {
switch (event->type()) {
case ui::ET_MOUSE_MOVED:
case ui::ET_MOUSE_DRAGGED:
......@@ -57,8 +51,7 @@ class MouseWatcher::Observer : public ui::EventHandler {
void HandleMouseEvent(MouseWatcherHost::MouseEventType event_type) {
// It's safe to use last_mouse_location() here as this function is invoked
// during event dispatching.
if (!host()->Contains(aura::Env::GetInstance()->last_mouse_location(),
event_type)) {
if (!host()->Contains(EventMonitor::GetLastMouseLocation(), event_type)) {
// Mouse moved outside the host's zone, start a timer to notify the
// listener.
if (!notify_listener_factory_.HasWeakPtrs()) {
......@@ -84,6 +77,7 @@ class MouseWatcher::Observer : public ui::EventHandler {
private:
MouseWatcher* mouse_watcher_;
scoped_ptr<views::EventMonitor> event_monitor_;
// A factory that is used to construct a delayed callback to the listener.
base::WeakPtrFactory<Observer> notify_listener_factory_;
......
......@@ -207,6 +207,11 @@
'drag_utils.cc',
'drag_utils.h',
'drag_utils_aura.cc',
'event_monitor.h',
'event_monitor_aura.cc',
'event_monitor_aura.h',
'event_monitor_mac.h',
'event_monitor_mac.mm',
'focus/external_focus_tracker.cc',
'focus/external_focus_tracker.h',
'focus/focus_manager.cc',
......@@ -253,7 +258,7 @@
'metrics_mac.cc',
'mouse_constants.h',
'mouse_watcher.h',
'mouse_watcher_aura.cc',
'mouse_watcher.cc',
'native_cursor.h',
'native_cursor_aura.cc',
'native_cursor_mac.mm',
......@@ -529,6 +534,7 @@
'controls/textfield/textfield_unittest.cc',
'controls/textfield/textfield_model_unittest.cc',
'controls/tree/tree_view_unittest.cc',
'event_monitor_mac_unittest.mm',
'focus/focus_manager_unittest.cc',
'focus/focus_traversal_unittest.cc',
'ime/input_method_bridge_unittest.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment