| 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 |