OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_popup_api.h" | 5 #include "chrome/browser/extensions/extension_popup_api.h" |
6 | 6 |
7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "chrome/browser/extensions/extension_dom_ui.h" | 9 #include "chrome/browser/extensions/extension_dom_ui.h" |
10 #include "chrome/browser/extensions/extension_host.h" | 10 #include "chrome/browser/extensions/extension_host.h" |
11 #include "chrome/browser/extensions/extension_message_service.h" | 11 #include "chrome/browser/extensions/extension_message_service.h" |
12 #include "chrome/browser/browser.h" | 12 #include "chrome/browser/browser.h" |
13 #include "chrome/browser/browser_window.h" | 13 #include "chrome/browser/browser_window.h" |
14 #include "chrome/browser/profile.h" | 14 #include "chrome/browser/profile.h" |
15 #include "chrome/browser/renderer_host/render_view_host.h" | 15 #include "chrome/browser/renderer_host/render_view_host.h" |
16 #include "chrome/browser/renderer_host/render_view_host_delegate.h" | 16 #include "chrome/browser/renderer_host/render_view_host_delegate.h" |
17 #include "chrome/browser/renderer_host/render_widget_host_view.h" | 17 #include "chrome/browser/renderer_host/render_widget_host_view.h" |
18 #include "chrome/browser/tab_contents/tab_contents.h" | 18 #include "chrome/browser/tab_contents/tab_contents.h" |
| 19 #include "chrome/browser/window_sizer.h" |
19 #include "chrome/common/extensions/extension.h" | 20 #include "chrome/common/extensions/extension.h" |
20 #include "chrome/common/notification_details.h" | 21 #include "chrome/common/notification_details.h" |
21 #include "chrome/common/notification_service.h" | 22 #include "chrome/common/notification_service.h" |
22 #include "chrome/common/notification_source.h" | 23 #include "chrome/common/notification_source.h" |
23 #include "chrome/common/notification_type.h" | 24 #include "chrome/common/notification_type.h" |
24 #include "chrome/common/url_constants.h" | 25 #include "chrome/common/url_constants.h" |
25 #include "gfx/point.h" | 26 #include "gfx/point.h" |
26 | 27 |
27 #if defined(TOOLKIT_VIEWS) | 28 #if defined(TOOLKIT_VIEWS) |
| 29 #include "chrome/browser/views/bubble_border.h" |
28 #include "chrome/browser/views/extensions/extension_popup.h" | 30 #include "chrome/browser/views/extensions/extension_popup.h" |
29 #include "views/view.h" | 31 #include "views/view.h" |
30 #include "views/focus/focus_manager.h" | 32 #include "views/focus/focus_manager.h" |
31 #endif // TOOLKIT_VIEWS | 33 #endif // TOOLKIT_VIEWS |
32 | 34 |
33 namespace extension_popup_module_events { | 35 namespace extension_popup_module_events { |
34 | 36 |
35 const char kOnPopupClosed[] = "experimental.popup.onClosed.%d"; | 37 const char kOnPopupClosed[] = "experimental.popup.onClosed.%d"; |
36 | 38 |
37 } // namespace extension_popup_module_events | 39 } // namespace extension_popup_module_events |
(...skipping 13 matching lines...) Expand all Loading... |
51 const wchar_t kHeightKey[] = L"height"; | 53 const wchar_t kHeightKey[] = L"height"; |
52 const wchar_t kTopKey[] = L"top"; | 54 const wchar_t kTopKey[] = L"top"; |
53 const wchar_t kLeftKey[] = L"left"; | 55 const wchar_t kLeftKey[] = L"left"; |
54 const wchar_t kGiveFocusKey[] = L"giveFocus"; | 56 const wchar_t kGiveFocusKey[] = L"giveFocus"; |
55 const wchar_t kDomAnchorKey[] = L"domAnchor"; | 57 const wchar_t kDomAnchorKey[] = L"domAnchor"; |
56 const wchar_t kBorderStyleKey[] = L"borderStyle"; | 58 const wchar_t kBorderStyleKey[] = L"borderStyle"; |
57 | 59 |
58 // chrome enumeration values | 60 // chrome enumeration values |
59 const char kRectangleChrome[] = "rectangle"; | 61 const char kRectangleChrome[] = "rectangle"; |
60 | 62 |
| 63 #if defined(TOOLKIT_VIEWS) |
| 64 // Returns an updated arrow location, conditioned on the type of intersection |
| 65 // between the popup window, and the screen. |location| is the current position |
| 66 // of the arrow on the popup. |intersection| is the rect representing the |
| 67 // intersection between the popup view and its working screen. |popup_rect| |
| 68 // is the rect of the popup window in screen space coordinates. |
| 69 // The returned location will be horizontally or vertically inverted based on |
| 70 // if the popup has been clipped horizontally or vertically. |
| 71 BubbleBorder::ArrowLocation ToggleArrowLocation( |
| 72 BubbleBorder::ArrowLocation location, const gfx::Rect& intersection, |
| 73 const gfx::Rect& popup_rect) { |
| 74 // If the popup has been clipped horizontally, flip the right-left position |
| 75 // of the arrow. |
| 76 if (intersection.right() != popup_rect.right() || |
| 77 intersection.x() != popup_rect.x()) { |
| 78 location = BubbleBorder::horizontal_mirror(location); |
| 79 } |
| 80 |
| 81 // If the popup has been clipped vertically, flip the bottom-top position |
| 82 // of the arrow. |
| 83 if (intersection.y() != popup_rect.y() || |
| 84 intersection.bottom() != popup_rect.bottom()) { |
| 85 location = BubbleBorder::vertical_mirror(location); |
| 86 } |
| 87 |
| 88 return location; |
| 89 } |
| 90 #endif // TOOLKIT_VIEWS |
| 91 |
61 }; // namespace | 92 }; // namespace |
62 | 93 |
63 #if defined(TOOLKIT_VIEWS) | 94 #if defined(TOOLKIT_VIEWS) |
64 // ExtensionPopupHost objects implement the environment necessary to host | 95 // ExtensionPopupHost objects implement the environment necessary to host |
65 // an ExtensionPopup views for the popup api. Its main job is to handle | 96 // an ExtensionPopup views for the popup api. Its main job is to handle |
66 // its lifetime and to fire the popup-closed event when the popup is closed. | 97 // its lifetime and to fire the popup-closed event when the popup is closed. |
67 // Because the close-on-focus-lost behavior is different from page action | 98 // Because the close-on-focus-lost behavior is different from page action |
68 // and browser action, it also manages its own focus change listening. The | 99 // and browser action, it also manages its own focus change listening. The |
69 // difference in close-on-focus-lost is that in the page action and browser | 100 // difference in close-on-focus-lost is that in the page action and browser |
70 // action cases, the popup closes when the focus leaves the popup or any of its | 101 // action cases, the popup closes when the focus leaves the popup or any of its |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 virtual void ExtensionHostCreated(ExtensionHost* host) { | 148 virtual void ExtensionHostCreated(ExtensionHost* host) { |
118 // Pop-up views should share the same automation routing configuration as | 149 // Pop-up views should share the same automation routing configuration as |
119 // their hosting views, so register the RenderViewHost of the pop-up with | 150 // their hosting views, so register the RenderViewHost of the pop-up with |
120 // the AutomationResourceRoutingDelegate interface of the dispatcher. | 151 // the AutomationResourceRoutingDelegate interface of the dispatcher. |
121 AutomationResourceRoutingDelegate* router = | 152 AutomationResourceRoutingDelegate* router = |
122 GetRoutingFromDispatcher(dispatcher_); | 153 GetRoutingFromDispatcher(dispatcher_); |
123 if (router) | 154 if (router) |
124 router->RegisterRenderViewHost(host->render_view_host()); | 155 router->RegisterRenderViewHost(host->render_view_host()); |
125 } | 156 } |
126 | 157 |
| 158 virtual void ExtensionPopupResized(ExtensionPopup* popup) { |
| 159 // Reposition the location of the arrow on the popup so that the popup |
| 160 // better fits on the working monitor. |
| 161 gfx::Rect popup_rect = popup->GetOuterBounds(); |
| 162 if (popup_rect.IsEmpty()) |
| 163 return; |
| 164 |
| 165 scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_provider( |
| 166 WindowSizer::CreateDefaultMonitorInfoProvider()); |
| 167 gfx::Rect monitor_bounds( |
| 168 monitor_provider->GetMonitorWorkAreaMatching(popup_rect)); |
| 169 gfx::Rect intersection = monitor_bounds.Intersect(popup_rect); |
| 170 |
| 171 // If the popup is totally out of the bounds of the monitor, then toggling |
| 172 // the arrow location will not result in an un-clipped window. |
| 173 if (intersection.IsEmpty()) |
| 174 return; |
| 175 |
| 176 if (!intersection.Equals(popup_rect)) { |
| 177 // The popup was clipped by the monitor. Toggle the arrow position |
| 178 // to see if that improves visibility. Note: The assignment and |
| 179 // re-assignment of the arrow-position will not trigger an intermittent |
| 180 // display. |
| 181 BubbleBorder::ArrowLocation previous_location = popup->arrow_position(); |
| 182 BubbleBorder::ArrowLocation flipped_location = ToggleArrowLocation( |
| 183 previous_location, intersection, popup_rect); |
| 184 popup->SetArrowPosition(flipped_location); |
| 185 |
| 186 // Double check that toggling the position actually improved the |
| 187 // situation - the popup will be contained entirely in its working monitor |
| 188 // bounds. |
| 189 gfx::Rect flipped_bounds = popup->GetOuterBounds(); |
| 190 gfx::Rect updated_monitor_bounds = |
| 191 monitor_provider->GetMonitorWorkAreaMatching(flipped_bounds); |
| 192 if (!updated_monitor_bounds.Contains(flipped_bounds)) |
| 193 popup->SetArrowPosition(previous_location); |
| 194 } |
| 195 } |
| 196 |
127 virtual void DispatchPopupClosedEvent() { | 197 virtual void DispatchPopupClosedEvent() { |
128 PopupEventRouter::OnPopupClosed( | 198 PopupEventRouter::OnPopupClosed( |
129 dispatcher_->profile(), dispatcher_->render_view_host()->routing_id()); | 199 dispatcher_->profile(), dispatcher_->render_view_host()->routing_id()); |
130 dispatcher_ = NULL; | 200 dispatcher_ = NULL; |
131 Release(); // Balanced in ctor. | 201 Release(); // Balanced in ctor. |
132 } | 202 } |
133 | 203 |
134 // Overridden from views::WidgetFocusChangeListener | 204 // Overridden from views::WidgetFocusChangeListener |
135 virtual void NativeFocusWillChange(gfx::NativeView focused_before, | 205 virtual void NativeFocusWillChange(gfx::NativeView focused_before, |
136 gfx::NativeView focused_now) { | 206 gfx::NativeView focused_now) { |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 std::string full_event_name = StringPrintf( | 467 std::string full_event_name = StringPrintf( |
398 extension_popup_module_events::kOnPopupClosed, | 468 extension_popup_module_events::kOnPopupClosed, |
399 routing_id); | 469 routing_id); |
400 | 470 |
401 profile->GetExtensionMessageService()->DispatchEventToRenderers( | 471 profile->GetExtensionMessageService()->DispatchEventToRenderers( |
402 full_event_name, | 472 full_event_name, |
403 base::JSONWriter::kEmptyArray, | 473 base::JSONWriter::kEmptyArray, |
404 profile->IsOffTheRecord(), | 474 profile->IsOffTheRecord(), |
405 GURL()); | 475 GURL()); |
406 } | 476 } |
OLD | NEW |