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/gtk/extensions/extension_popup_gtk.h" | 5 #include "chrome/browser/ui/gtk/extensions/extension_popup_gtk.h" |
6 | 6 |
7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 23 matching lines...) Expand all Loading... |
34 // The minimum/maximum dimensions of the extension popup. | 34 // The minimum/maximum dimensions of the extension popup. |
35 // The minimum is just a little larger than the size of a browser action button. | 35 // The minimum is just a little larger than the size of a browser action button. |
36 // The maximum is an arbitrary number that should be smaller than most screens. | 36 // The maximum is an arbitrary number that should be smaller than most screens. |
37 const int ExtensionPopupGtk::kMinWidth = 25; | 37 const int ExtensionPopupGtk::kMinWidth = 25; |
38 const int ExtensionPopupGtk::kMinHeight = 25; | 38 const int ExtensionPopupGtk::kMinHeight = 25; |
39 const int ExtensionPopupGtk::kMaxWidth = 800; | 39 const int ExtensionPopupGtk::kMaxWidth = 800; |
40 const int ExtensionPopupGtk::kMaxHeight = 600; | 40 const int ExtensionPopupGtk::kMaxHeight = 600; |
41 | 41 |
42 ExtensionPopupGtk::ExtensionPopupGtk(Browser* browser, | 42 ExtensionPopupGtk::ExtensionPopupGtk(Browser* browser, |
43 ExtensionHost* host, | 43 ExtensionHost* host, |
44 GtkWidget* anchor, | 44 GtkWidget* anchor) |
45 bool inspect) | |
46 : browser_(browser), | 45 : browser_(browser), |
47 bubble_(NULL), | 46 bubble_(NULL), |
48 host_(host), | 47 host_(host), |
49 anchor_(anchor), | 48 anchor_(anchor), |
50 being_inspected_(inspect), | 49 being_inspected_(false), |
51 weak_factory_(this) { | 50 weak_factory_(this) { |
52 host_->view()->SetContainer(this); | 51 host_->view()->SetContainer(this); |
53 | 52 |
54 // If the host had somehow finished loading, then we'd miss the notification | 53 // If the host had somehow finished loading, then we'd miss the notification |
55 // and not show. This seems to happen in single-process mode. | 54 // and not show. This seems to happen in single-process mode. |
56 if (host->did_stop_loading()) { | 55 if (host->did_stop_loading()) { |
57 ShowPopup(); | 56 ShowPopup(); |
58 } else { | 57 } else { |
59 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, | 58 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, |
60 content::Source<Profile>(host->profile())); | 59 content::Source<Profile>(host->profile())); |
61 } | 60 } |
62 | 61 |
63 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, | 62 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, |
64 content::Source<Profile>(host->profile())); | 63 content::Source<Profile>(host->profile())); |
65 | 64 |
66 registrar_.Add(this, content::NOTIFICATION_DEVTOOLS_WINDOW_CLOSING, | 65 registrar_.Add(this, content::NOTIFICATION_DEVTOOLS_WINDOW_CLOSING, |
67 content::Source<Profile>(host->profile())); | 66 content::Source<Profile>(host->profile())); |
68 | 67 |
69 if (!being_inspected_) { | 68 registrar_.Add(this, content::NOTIFICATION_DEVTOOLS_WINDOW_OPENING, |
70 registrar_.Add(this, content::NOTIFICATION_DEVTOOLS_WINDOW_OPENING, | 69 content::Source<Profile>(host->profile())); |
71 content::Source<Profile>(host->profile())); | |
72 } | |
73 } | 70 } |
74 | 71 |
75 ExtensionPopupGtk::~ExtensionPopupGtk() { | 72 ExtensionPopupGtk::~ExtensionPopupGtk() { |
76 } | 73 } |
77 | 74 |
78 // static | 75 // static |
79 void ExtensionPopupGtk::Show(const GURL& url, Browser* browser, | 76 void ExtensionPopupGtk::Show(const GURL& url, Browser* browser, |
80 GtkWidget* anchor, bool inspect) { | 77 GtkWidget* anchor) { |
81 ExtensionProcessManager* manager = | 78 ExtensionProcessManager* manager = |
82 browser->profile()->GetExtensionProcessManager(); | 79 browser->profile()->GetExtensionProcessManager(); |
83 DCHECK(manager); | 80 DCHECK(manager); |
84 if (!manager) | 81 if (!manager) |
85 return; | 82 return; |
86 | 83 |
87 ExtensionHost* host = manager->CreatePopupHost(url, browser); | 84 ExtensionHost* host = manager->CreatePopupHost(url, browser); |
88 // This object will delete itself when the bubble is closed. | 85 // This object will delete itself when the bubble is closed. |
89 new ExtensionPopupGtk(browser, host, anchor, inspect); | 86 new ExtensionPopupGtk(browser, host, anchor); |
90 } | 87 } |
91 | 88 |
92 void ExtensionPopupGtk::Observe(int type, | 89 void ExtensionPopupGtk::Observe(int type, |
93 const content::NotificationSource& source, | 90 const content::NotificationSource& source, |
94 const content::NotificationDetails& details) { | 91 const content::NotificationDetails& details) { |
95 switch (type) { | 92 switch (type) { |
96 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: | 93 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: |
97 if (content::Details<ExtensionHost>(host_.get()) == details) | 94 if (content::Details<ExtensionHost>(host_.get()) == details) |
98 ShowPopup(); | 95 ShowPopup(); |
99 break; | 96 break; |
100 case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: | 97 case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: |
101 if (content::Details<ExtensionHost>(host_.get()) == details) | 98 if (content::Details<ExtensionHost>(host_.get()) == details) |
102 DestroyPopup(); | 99 DestroyPopup(); |
103 break; | 100 break; |
104 case content::NOTIFICATION_DEVTOOLS_WINDOW_OPENING: | 101 case content::NOTIFICATION_DEVTOOLS_WINDOW_OPENING: |
105 // Make sure it's the devtools window that is inspecting our popup. | 102 // Make sure it's the devtools window that is inspecting our popup. |
106 if (content::Details<RenderViewHost>(host_->render_view_host()) != | 103 if (content::Details<RenderViewHost>(host_->render_view_host()) != |
107 details) | 104 details) |
108 break; | 105 break; |
109 | 106 |
110 // Make sure that the popup won't go away when the inspector is activated. | 107 // Make sure that the popup won't go away when the inspector is activated. |
111 if (bubble_) | 108 if (bubble_) |
112 bubble_->StopGrabbingInput(); | 109 bubble_->StopGrabbingInput(); |
| 110 |
| 111 being_inspected_ = true; |
113 break; | 112 break; |
114 case content::NOTIFICATION_DEVTOOLS_WINDOW_CLOSING: | 113 case content::NOTIFICATION_DEVTOOLS_WINDOW_CLOSING: |
115 // Make sure it's the devtools window that is inspecting our popup. | 114 // Make sure it's the devtools window that is inspecting our popup. |
116 if (content::Details<RenderViewHost>(host_->render_view_host()) != | 115 if (content::Details<RenderViewHost>(host_->render_view_host()) != |
117 details) | 116 details) |
118 break; | 117 break; |
119 | 118 |
120 // If the devtools window is closing, we post a task to ourselves to | 119 // If the devtools window is closing, we post a task to ourselves to |
121 // close the popup. This gives the devtools window a chance to finish | 120 // close the popup. This gives the devtools window a chance to finish |
122 // detaching from the inspected RenderViewHost. | 121 // detaching from the inspected RenderViewHost. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 bubble_->Close(); | 154 bubble_->Close(); |
156 return true; | 155 return true; |
157 } | 156 } |
158 | 157 |
159 void ExtensionPopupGtk::ShowPopup() { | 158 void ExtensionPopupGtk::ShowPopup() { |
160 if (bubble_) { | 159 if (bubble_) { |
161 NOTREACHED(); | 160 NOTREACHED(); |
162 return; | 161 return; |
163 } | 162 } |
164 | 163 |
165 if (being_inspected_) | |
166 DevToolsWindow::OpenDevToolsWindow(host_->render_view_host()); | |
167 | |
168 // Only one instance should be showing at a time. Get rid of the old one, if | 164 // Only one instance should be showing at a time. Get rid of the old one, if |
169 // any. Typically, |current_extension_popup_| will be NULL, but it can be | 165 // any. Typically, |current_extension_popup_| will be NULL, but it can be |
170 // non-NULL if a browser action button is clicked while another extension | 166 // non-NULL if a browser action button is clicked while another extension |
171 // popup's extension host is still loading. | 167 // popup's extension host is still loading. |
172 if (current_extension_popup_) | 168 if (current_extension_popup_) |
173 current_extension_popup_->DestroyPopup(); | 169 current_extension_popup_->DestroyPopup(); |
174 current_extension_popup_ = this; | 170 current_extension_popup_ = this; |
175 | 171 |
176 // We'll be in the upper-right corner of the window for LTR languages, so we | 172 // We'll be in the upper-right corner of the window for LTR languages, so we |
177 // want to put the arrow at the upper-right corner of the bubble to match the | 173 // want to put the arrow at the upper-right corner of the bubble to match the |
178 // page and app menus. | 174 // page and app menus. |
179 BubbleGtk::ArrowLocationGtk arrow_location = | 175 BubbleGtk::ArrowLocationGtk arrow_location = |
180 !base::i18n::IsRTL() ? | 176 !base::i18n::IsRTL() ? |
181 BubbleGtk::ARROW_LOCATION_TOP_RIGHT : | 177 BubbleGtk::ARROW_LOCATION_TOP_RIGHT : |
182 BubbleGtk::ARROW_LOCATION_TOP_LEFT; | 178 BubbleGtk::ARROW_LOCATION_TOP_LEFT; |
183 bubble_ = BubbleGtk::Show(anchor_, | 179 bubble_ = BubbleGtk::Show(anchor_, |
184 NULL, | 180 NULL, |
185 host_->view()->native_view(), | 181 host_->view()->native_view(), |
186 arrow_location, | 182 arrow_location, |
187 false, // match_system_theme | 183 false, // match_system_theme |
188 !being_inspected_, // grab_input | 184 true, // grab_input |
189 ThemeServiceGtk::GetFrom(browser_->profile()), | 185 ThemeServiceGtk::GetFrom(browser_->profile()), |
190 this); | 186 this); |
191 } | 187 } |
192 | 188 |
193 void ExtensionPopupGtk::DestroyPopupWithoutResult() { | 189 void ExtensionPopupGtk::DestroyPopupWithoutResult() { |
194 DestroyPopup(); | 190 DestroyPopup(); |
195 } | 191 } |
196 | 192 |
197 gfx::Rect ExtensionPopupGtk::GetViewBounds() { | 193 gfx::Rect ExtensionPopupGtk::GetViewBounds() { |
198 GtkAllocation allocation; | 194 GtkAllocation allocation; |
199 gtk_widget_get_allocation(host_->view()->native_view(), &allocation); | 195 gtk_widget_get_allocation(host_->view()->native_view(), &allocation); |
200 return gfx::Rect(allocation); | 196 return gfx::Rect(allocation); |
201 } | 197 } |
OLD | NEW |