OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/views/extensions/extension_popup.h" | 5 #include "chrome/browser/ui/views/extensions/extension_popup.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "chrome/browser/chrome_notification_types.h" | 8 #include "chrome/browser/chrome_notification_types.h" |
9 #include "chrome/browser/devtools/devtools_window.h" | 9 #include "chrome/browser/devtools/devtools_window.h" |
10 #include "chrome/browser/extensions/extension_view_host.h" | 10 #include "chrome/browser/extensions/extension_view_host.h" |
11 #include "chrome/browser/extensions/extension_view_host_factory.h" | 11 #include "chrome/browser/extensions/extension_view_host_factory.h" |
12 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
13 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 13 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
14 #include "content/public/browser/devtools_agent_host.h" | 14 #include "content/public/browser/devtools_agent_host.h" |
15 #include "content/public/browser/notification_details.h" | 15 #include "content/public/browser/notification_details.h" |
16 #include "content/public/browser/notification_source.h" | 16 #include "content/public/browser/notification_source.h" |
17 #include "content/public/browser/render_view_host.h" | 17 #include "content/public/browser/render_view_host.h" |
18 #include "content/public/browser/web_contents.h" | 18 #include "content/public/browser/web_contents.h" |
19 #include "ui/aura/window.h" | |
20 #include "ui/gfx/geometry/insets.h" | 19 #include "ui/gfx/geometry/insets.h" |
21 #include "ui/views/layout/fill_layout.h" | 20 #include "ui/views/layout/fill_layout.h" |
22 #include "ui/views/widget/widget.h" | 21 #include "ui/views/widget/widget.h" |
23 #include "ui/wm/core/window_animations.h" | |
24 #include "ui/wm/core/window_util.h" | |
25 #include "ui/wm/public/activation_client.h" | |
26 | 22 |
27 namespace { | 23 namespace { |
28 | 24 |
29 ExtensionViewViews* GetExtensionView(extensions::ExtensionViewHost* host) { | 25 ExtensionViewViews* GetExtensionView(extensions::ExtensionViewHost* host) { |
30 return static_cast<ExtensionViewViews*>(host->view()); | 26 return static_cast<ExtensionViewViews*>(host->view()); |
31 } | 27 } |
32 | 28 |
33 } // namespace | 29 } // namespace |
34 | 30 |
35 // The minimum/maximum dimensions of the popup. | 31 // The minimum/maximum dimensions of the popup. |
36 // The minimum is just a little larger than the size of the button itself. | 32 // The minimum is just a little larger than the size of the button itself. |
37 // The maximum is an arbitrary number that should be smaller than most screens. | 33 // The maximum is an arbitrary number that should be smaller than most screens. |
38 const int ExtensionPopup::kMinWidth = 25; | 34 const int ExtensionPopup::kMinWidth = 25; |
39 const int ExtensionPopup::kMinHeight = 25; | 35 const int ExtensionPopup::kMinHeight = 25; |
40 const int ExtensionPopup::kMaxWidth = 800; | 36 const int ExtensionPopup::kMaxWidth = 800; |
41 const int ExtensionPopup::kMaxHeight = 600; | 37 const int ExtensionPopup::kMaxHeight = 600; |
42 | 38 |
39 #if !defined(USE_AURA) | |
40 // static | |
41 ExtensionPopup* ExtensionPopup::Create(extensions::ExtensionViewHost* host, | |
42 views::View* anchor_view, | |
43 views::BubbleBorder::Arrow arrow, | |
44 ShowAction show_action) { | |
45 auto popup = new ExtensionPopup(host, anchor_view, arrow, show_action); | |
46 views::BubbleDelegateView::CreateBubble(popup); | |
47 return popup; | |
48 } | |
49 #endif | |
50 | |
43 ExtensionPopup::ExtensionPopup(extensions::ExtensionViewHost* host, | 51 ExtensionPopup::ExtensionPopup(extensions::ExtensionViewHost* host, |
44 views::View* anchor_view, | 52 views::View* anchor_view, |
45 views::BubbleBorder::Arrow arrow, | 53 views::BubbleBorder::Arrow arrow, |
46 ShowAction show_action) | 54 ShowAction show_action) |
47 : BubbleDelegateView(anchor_view, arrow), | 55 : BubbleDelegateView(anchor_view, arrow), |
48 host_(host), | 56 host_(host), |
49 devtools_callback_(base::Bind( | 57 devtools_callback_(base::Bind( |
50 &ExtensionPopup::OnDevToolsStateChanged, base::Unretained(this))), | 58 &ExtensionPopup::OnDevToolsStateChanged, base::Unretained(this))), |
51 widget_initialized_(false) { | 59 widget_initialized_(false) { |
52 inspect_with_devtools_ = show_action == SHOW_AND_INSPECT; | 60 inspect_with_devtools_ = show_action == SHOW_AND_INSPECT; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 } | 139 } |
132 | 140 |
133 void ExtensionPopup::ViewHierarchyChanged( | 141 void ExtensionPopup::ViewHierarchyChanged( |
134 const ViewHierarchyChangedDetails& details) { | 142 const ViewHierarchyChangedDetails& details) { |
135 // TODO(msw): Find any remaining crashes related to http://crbug.com/327776 | 143 // TODO(msw): Find any remaining crashes related to http://crbug.com/327776 |
136 // No view hierarchy changes are expected if the widget no longer exists. | 144 // No view hierarchy changes are expected if the widget no longer exists. |
137 widget_initialized_ |= details.child == this && details.is_add && GetWidget(); | 145 widget_initialized_ |= details.child == this && details.is_add && GetWidget(); |
138 CHECK(GetWidget() || !widget_initialized_); | 146 CHECK(GetWidget() || !widget_initialized_); |
139 } | 147 } |
140 | 148 |
141 void ExtensionPopup::OnWidgetDestroying(views::Widget* widget) { | |
142 BubbleDelegateView::OnWidgetDestroying(widget); | |
143 aura::Window* bubble_window = GetWidget()->GetNativeWindow(); | |
144 aura::client::ActivationClient* activation_client = | |
145 aura::client::GetActivationClient(bubble_window->GetRootWindow()); | |
146 // If the popup was being inspected with devtools and the browser window was | |
147 // closed, then the root window and activation client are already destroyed. | |
148 if (activation_client) | |
149 activation_client->RemoveObserver(this); | |
150 } | |
151 | |
152 void ExtensionPopup::OnWidgetActivationChanged(views::Widget* widget, | 149 void ExtensionPopup::OnWidgetActivationChanged(views::Widget* widget, |
153 bool active) { | 150 bool active) { |
154 // TODO(msw): Find any remaining crashes related to http://crbug.com/327776 | 151 if (active && widget == anchor_widget()) |
msw
2015/03/06 19:26:49
I feel like I had to explicitly check the NativeWi
Andre
2015/03/07 00:56:26
Ack, thanks!
| |
155 // No calls are expected if the widget isn't initialized or no longer exists. | 152 OnAnchorWindowActivation(); |
156 CHECK(widget_initialized_); | |
157 CHECK(GetWidget()); | |
158 | |
159 // Close on anchor window activation (ie. user clicked the browser window). | |
160 if (!inspect_with_devtools_ && widget && active && | |
161 widget->GetNativeWindow() == anchor_widget()->GetNativeWindow()) | |
162 GetWidget()->Close(); | |
163 } | |
164 | |
165 void ExtensionPopup::OnWindowActivated(aura::Window* gained_active, | |
166 aura::Window* lost_active) { | |
167 // TODO(msw): Find any remaining crashes related to http://crbug.com/327776 | |
168 // No calls are expected if the widget isn't initialized or no longer exists. | |
169 CHECK(widget_initialized_); | |
170 CHECK(GetWidget()); | |
171 | |
172 // Close on anchor window activation (ie. user clicked the browser window). | |
173 // DesktopNativeWidgetAura does not trigger the expected browser widget | |
174 // [de]activation events when activating widgets in its own root window. | |
175 // This additional check handles those cases. See: http://crbug.com/320889 | |
176 if (!inspect_with_devtools_ && | |
177 gained_active == anchor_widget()->GetNativeWindow()) | |
178 GetWidget()->Close(); | |
179 } | 153 } |
180 | 154 |
181 void ExtensionPopup::ActiveTabChanged(content::WebContents* old_contents, | 155 void ExtensionPopup::ActiveTabChanged(content::WebContents* old_contents, |
182 content::WebContents* new_contents, | 156 content::WebContents* new_contents, |
183 int index, | 157 int index, |
184 int reason) { | 158 int reason) { |
185 GetWidget()->Close(); | 159 GetWidget()->Close(); |
186 } | 160 } |
187 | 161 |
162 void ExtensionPopup::OnAnchorWindowActivation() { | |
163 // TODO(msw): Find any remaining crashes related to http://crbug.com/327776 | |
164 // No calls are expected if the widget isn't initialized or no longer exists. | |
165 CHECK(widget_initialized_); | |
166 CHECK(GetWidget()); | |
167 | |
168 if (!inspect_with_devtools_) | |
169 GetWidget()->Close(); | |
170 } | |
171 | |
188 // static | 172 // static |
189 ExtensionPopup* ExtensionPopup::ShowPopup(const GURL& url, | 173 ExtensionPopup* ExtensionPopup::ShowPopup(const GURL& url, |
190 Browser* browser, | 174 Browser* browser, |
191 views::View* anchor_view, | 175 views::View* anchor_view, |
192 views::BubbleBorder::Arrow arrow, | 176 views::BubbleBorder::Arrow arrow, |
193 ShowAction show_action) { | 177 ShowAction show_action) { |
194 extensions::ExtensionViewHost* host = | 178 extensions::ExtensionViewHost* host = |
195 extensions::ExtensionViewHostFactory::CreatePopupHost(url, browser); | 179 extensions::ExtensionViewHostFactory::CreatePopupHost(url, browser); |
196 ExtensionPopup* popup = new ExtensionPopup(host, anchor_view, arrow, | 180 auto popup = ExtensionPopup::Create(host, anchor_view, arrow, show_action); |
197 show_action); | |
198 views::BubbleDelegateView::CreateBubble(popup); | |
199 | |
200 gfx::NativeView native_view = popup->GetWidget()->GetNativeView(); | |
201 wm::SetWindowVisibilityAnimationType( | |
202 native_view, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL); | |
203 wm::SetWindowVisibilityAnimationVerticalPosition(native_view, -3.0f); | |
204 | 181 |
205 // If the host had somehow finished loading, then we'd miss the notification | 182 // If the host had somehow finished loading, then we'd miss the notification |
206 // and not show. This seems to happen in single-process mode. | 183 // and not show. This seems to happen in single-process mode. |
207 if (host->did_stop_loading()) | 184 if (host->did_stop_loading()) |
208 popup->ShowBubble(); | 185 popup->ShowBubble(); |
209 | 186 |
210 aura::Window* bubble_window = popup->GetWidget()->GetNativeWindow(); | |
211 aura::client::ActivationClient* activation_client = | |
212 aura::client::GetActivationClient(bubble_window->GetRootWindow()); | |
213 activation_client->AddObserver(popup); | |
214 | |
215 return popup; | 187 return popup; |
216 } | 188 } |
217 | 189 |
218 void ExtensionPopup::ShowBubble() { | 190 void ExtensionPopup::ShowBubble() { |
219 GetWidget()->Show(); | 191 GetWidget()->Show(); |
220 | 192 |
221 // Focus on the host contents when the bubble is first shown. | 193 // Focus on the host contents when the bubble is first shown. |
222 host()->host_contents()->Focus(); | 194 host()->host_contents()->Focus(); |
223 | 195 |
224 if (inspect_with_devtools_) { | 196 if (inspect_with_devtools_) { |
225 DevToolsWindow::OpenDevToolsWindow(host()->host_contents(), | 197 DevToolsWindow::OpenDevToolsWindow(host()->host_contents(), |
226 DevToolsToggleAction::ShowConsole()); | 198 DevToolsToggleAction::ShowConsole()); |
227 } | 199 } |
228 } | 200 } |
OLD | NEW |