1 // Copyright (c) 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/browser/renderer_host/cursor_manager.h"
6 
7 #include "content/browser/renderer_host/render_widget_host_view_base.h"
8 
9 namespace content {
10 
CursorManager(RenderWidgetHostViewBase * root)11 CursorManager::CursorManager(RenderWidgetHostViewBase* root)
12     : view_under_cursor_(root),
13       root_view_(root),
14       tooltip_observer_for_testing_(nullptr) {}
15 
~CursorManager()16 CursorManager::~CursorManager() {}
17 
UpdateCursor(RenderWidgetHostViewBase * view,const WebCursor & cursor)18 void CursorManager::UpdateCursor(RenderWidgetHostViewBase* view,
19                                  const WebCursor& cursor) {
20   cursor_map_[view] = cursor;
21   if (view == view_under_cursor_)
22     root_view_->DisplayCursor(cursor);
23 }
24 
SetTooltipTextForView(const RenderWidgetHostViewBase * view,const base::string16 & tooltip_text)25 void CursorManager::SetTooltipTextForView(const RenderWidgetHostViewBase* view,
26                                           const base::string16& tooltip_text) {
27   if (view == view_under_cursor_) {
28     root_view_->DisplayTooltipText(tooltip_text);
29     if (tooltip_observer_for_testing_ && view) {
30       tooltip_observer_for_testing_->OnSetTooltipTextForView(view,
31                                                              tooltip_text);
32     }
33   }
34 }
35 
UpdateViewUnderCursor(RenderWidgetHostViewBase * view)36 void CursorManager::UpdateViewUnderCursor(RenderWidgetHostViewBase* view) {
37   if (view == view_under_cursor_)
38     return;
39 
40   // Whenever we switch from one view to another, clear the tooltip: as the
41   // mouse moves, the view now controlling the cursor will send a new tooltip,
42   // though this is only guaranteed if the view's tooltip is non-empty, so
43   // clearing here is important. Tooltips sent from the previous view will be
44   // ignored.
45   SetTooltipTextForView(view_under_cursor_, base::string16());
46   view_under_cursor_ = view;
47   WebCursor cursor(ui::mojom::CursorType::kPointer);
48 
49   auto it = cursor_map_.find(view);
50   if (it != cursor_map_.end())
51     cursor = it->second;
52 
53   root_view_->DisplayCursor(cursor);
54 }
55 
ViewBeingDestroyed(RenderWidgetHostViewBase * view)56 void CursorManager::ViewBeingDestroyed(RenderWidgetHostViewBase* view) {
57   cursor_map_.erase(view);
58 
59   // If the view right under the mouse is going away, use the root's cursor
60   // until UpdateViewUnderCursor is called again.
61   if (view == view_under_cursor_ && view != root_view_)
62     UpdateViewUnderCursor(root_view_);
63 }
64 
GetCursorForTesting(RenderWidgetHostViewBase * view,WebCursor & cursor)65 bool CursorManager::GetCursorForTesting(RenderWidgetHostViewBase* view,
66                                         WebCursor& cursor) {
67   if (cursor_map_.find(view) == cursor_map_.end())
68     return false;
69 
70   cursor = cursor_map_[view];
71   return true;
72 }
73 
SetTooltipObserverForTesting(TooltipObserver * observer)74 void CursorManager::SetTooltipObserverForTesting(TooltipObserver* observer) {
75   tooltip_observer_for_testing_ = observer;
76 }
77 
78 }  // namespace content
79