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

Side by Side Diff: chrome/browser/extensions/extension_popup_api.cc

Issue 1774012: Support for clipped experimental popup repositioning (Closed) Base URL: svn://chrome-svn.corp.google.com/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 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 unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/views/extensions/extension_popup.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/views/extensions/extension_popup.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698