Commit 18f0adf0 authored by sadrul@chromium.org's avatar sadrul@chromium.org

aura: Update how the tooltip manager works.

Currently, each widget's tooltip-manager listens to every single X event in the system, all the time. This can get expensive as the number of windows increase. Instead of doing this, the change here makes a TooltipManagerViews only listen to the mouse-events on the corresponding Widget. It starts its timer when the mouse enters the widget, and stops the timer when the mouse leaves the widget. So at a single time, only one TooltipManagerViews will be activated, and looking to update the its tooltip.

BUG=97249
TEST=none

Review URL: http://codereview.chromium.org/8417025

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107809 0039d316-1c4b-4281-b951-d872f2087c98
parent 64058e4c
......@@ -502,9 +502,13 @@ bool NativeWidgetAura::OnMouseEvent(aura::MouseEvent* event) {
DCHECK(window_->IsVisible());
if (event->type() == ui::ET_MOUSEWHEEL) {
MouseWheelEvent wheel_event(event);
if (tooltip_manager_.get())
tooltip_manager_->UpdateForMouseEvent(wheel_event);
return delegate_->OnMouseEvent(wheel_event);
}
MouseEvent mouse_event(event);
if (tooltip_manager_.get())
tooltip_manager_->UpdateForMouseEvent(mouse_event);
return delegate_->OnMouseEvent(mouse_event);
}
......
......@@ -22,6 +22,8 @@ class Font;
namespace views {
class TooltipManagerViews;
class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
public aura::WindowDelegate {
public:
......@@ -158,7 +160,7 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
gfx::NativeCursor cursor_;
scoped_ptr<TooltipManager> tooltip_manager_;
scoped_ptr<TooltipManagerViews> tooltip_manager_;
DISALLOW_COPY_AND_ASSIGN(NativeWidgetAura);
};
......
......@@ -12,6 +12,7 @@
#include "views/views_delegate.h"
#include "views/widget/native_widget_view.h"
#include "views/widget/root_view.h"
#include "views/widget/tooltip_manager_views.h"
#include "views/widget/window_manager.h"
#if defined(HAVE_IBUS)
......@@ -127,6 +128,12 @@ void NativeWidgetViews::OnBoundsChanged(const gfx::Rect& new_bounds,
}
bool NativeWidgetViews::OnMouseEvent(const MouseEvent& event) {
#if defined(TOUCH_UI) || defined(USE_AURA)
TooltipManagerViews* tooltip_manager =
static_cast<TooltipManagerViews*>(GetTooltipManager());
if (tooltip_manager)
tooltip_manager->UpdateForMouseEvent(event);
#endif
return HandleWindowOperation(event) ? true : delegate_->OnMouseEvent(event);
}
......
......@@ -82,17 +82,44 @@ TooltipManagerViews::TooltipManagerViews(views::View* root_view)
tooltip_widget_->SetContentsView(&tooltip_label_);
tooltip_widget_->Activate();
tooltip_widget_->SetAlwaysOnTop(true);
tooltip_timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kTooltipTimeoutMs),
this, &TooltipManagerViews::TooltipTimerFired);
MessageLoopForUI::current()->AddObserver(this);
}
TooltipManagerViews::~TooltipManagerViews() {
MessageLoopForUI::current()->RemoveObserver(this);
tooltip_widget_->CloseNow();
}
void TooltipManagerViews::UpdateForMouseEvent(const MouseEvent& event) {
switch (event.type()) {
case ui::ET_MOUSE_EXITED:
// Mouse is exiting this widget. Stop showing the tooltip and the timer.
if (tooltip_timer_.IsRunning())
tooltip_timer_.Stop();
if (tooltip_widget_->IsVisible())
tooltip_widget_->Hide();
break;
case ui::ET_MOUSE_ENTERED:
// Mouse just entered this widget. Start the timer to show the tooltip.
CHECK(!tooltip_timer_.IsRunning());
tooltip_timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kTooltipTimeoutMs),
this, &TooltipManagerViews::TooltipTimerFired);
break;
case ui::ET_MOUSE_MOVED:
OnMouseMoved(event.location().x(), event.location().y());
break;
case ui::ET_MOUSE_PRESSED:
case ui::ET_MOUSE_RELEASED:
case ui::ET_MOUSE_DRAGGED:
case ui::ET_MOUSEWHEEL:
// Hide the tooltip for click, release, drag, wheel events.
if (tooltip_widget_->IsVisible())
tooltip_widget_->Hide();
break;
default:
NOTIMPLEMENTED();
}
}
void TooltipManagerViews::UpdateTooltip() {
UpdateIfRequired(curr_mouse_pos_.x(), curr_mouse_pos_.y(), false);
}
......@@ -110,46 +137,6 @@ void TooltipManagerViews::HideKeyboardTooltip() {
NOTREACHED();
}
#if defined(USE_WAYLAND)
base::MessagePumpObserver::EventStatus TooltipManagerViews::WillProcessEvent(
ui::WaylandEvent* event) {
if (event->type == ui::WAYLAND_MOTION)
OnMouseMoved(event->motion.x, event->motion.y);
return base::MessagePumpObserver::EVENT_CONTINUE;
}
#elif defined(USE_X11)
base::EventStatus TooltipManagerViews::WillProcessEvent(
const base::NativeEvent& native_event) {
if (!ui::IsMouseEvent(native_event))
return base::EVENT_CONTINUE;
#if defined(USE_AURA)
aura::MouseEvent event(native_event);
#else
MouseEvent event(native_event);
#endif
switch (event.type()) {
case ui::ET_MOUSE_MOVED:
OnMouseMoved(event.x(), event.y());
default:
break;
}
return base::EVENT_CONTINUE;
}
void TooltipManagerViews::DidProcessEvent(const base::NativeEvent& event) {
}
#elif defined(OS_WIN)
base::EventStatus TooltipManagerViews::WillProcessEvent(
const base::NativeEvent& event) {
if (event.message == WM_MOUSEMOVE)
OnMouseMoved(GET_X_LPARAM(event.lParam), GET_Y_LPARAM(event.lParam));
return base::EVENT_CONTINUE;
}
void TooltipManagerViews::DidProcessEvent(const base::NativeEvent& event) {
}
#endif
void TooltipManagerViews::TooltipTimerFired() {
UpdateIfRequired(curr_mouse_pos_.x(), curr_mouse_pos_.y(), false);
}
......@@ -159,8 +146,6 @@ View* TooltipManagerViews::GetViewForTooltip(int x, int y, bool for_keyboard) {
if (!for_keyboard) {
// Convert x,y from screen coordinates to |root_view_| coordinates.
gfx::Point point(x, y);
gfx::Rect r = root_view_->GetWidget()->GetClientAreaScreenBounds();
point.SetPoint(point.x() - r.x(), point.y() - r.y());
View::ConvertPointFromWidget(root_view_, &point);
view = root_view_->GetEventHandlerForPoint(point);
} else {
......
......@@ -23,31 +23,26 @@ union WaylandEvent;
namespace views {
class MouseEvent;
class Widget;
// TooltipManager implementation for Views.
class TooltipManagerViews : public TooltipManager,
public MessageLoopForUI::Observer {
class TooltipManagerViews : public TooltipManager {
public:
explicit TooltipManagerViews(views::View* root_view);
virtual ~TooltipManagerViews();
// Updates the state of the tooltip based on the mouse event. The mouse event
// is the same event that goes to a Widget (i.e. it is in the Widget's
// coordinate system).
void UpdateForMouseEvent(const MouseEvent& event);
// TooltipManager.
virtual void UpdateTooltip() OVERRIDE;
virtual void TooltipTextChanged(View* view) OVERRIDE;
virtual void ShowKeyboardTooltip(View* view) OVERRIDE;
virtual void HideKeyboardTooltip() OVERRIDE;
#if defined(USE_WAYLAND)
virtual base::MessagePumpObserver::EventStatus WillProcessEvent(
ui::WaylandEvent* event) OVERRIDE;
#else
// MessageLoopForUI::Observer
virtual base::EventStatus WillProcessEvent(
const base::NativeEvent& event) OVERRIDE;
virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
#endif
private:
void TooltipTimerFired();
View* GetViewForTooltip(int x, int y, bool for_keyboard);
......
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