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

Side by Side Diff: chrome/browser/ui/views/toolbar/browser_action_view.cc

Issue 419023002: Move ShowPopup logic from BrowserActionsContainer to BrowserActionView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/toolbar/browser_action_view.h" 5 #include "chrome/browser/ui/views/toolbar/browser_action_view.h"
6 6
7 #include <string>
8
7 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/chrome_notification_types.h" 10 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/extensions/api/commands/command_service.h" 11 #include "chrome/browser/extensions/api/commands/command_service.h"
10 #include "chrome/browser/extensions/extension_action.h" 12 #include "chrome/browser/extensions/extension_action.h"
11 #include "chrome/browser/extensions/extension_action_manager.h" 13 #include "chrome/browser/extensions/extension_action_manager.h"
12 #include "chrome/browser/extensions/extension_context_menu_model.h" 14 #include "chrome/browser/extensions/extension_context_menu_model.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/themes/theme_service.h" 16 #include "chrome/browser/themes/theme_service.h"
16 #include "chrome/browser/themes/theme_service_factory.h" 17 #include "chrome/browser/themes/theme_service_factory.h"
17 #include "chrome/browser/ui/browser.h" 18 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/extensions/accelerator_priority.h" 19 #include "chrome/browser/ui/extensions/accelerator_priority.h"
19 #include "chrome/browser/ui/view_ids.h" 20 #include "chrome/browser/ui/view_ids.h"
20 #include "chrome/browser/ui/views/frame/browser_view.h" 21 #include "chrome/browser/ui/views/frame/browser_view.h"
21 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" 22 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
22 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" 23 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
23 #include "extensions/common/extension.h" 24 #include "extensions/common/extension.h"
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 // to GTK requires that we regrab our browser action images. 132 // to GTK requires that we regrab our browser action images.
132 registrar_.Add( 133 registrar_.Add(
133 this, 134 this,
134 chrome::NOTIFICATION_BROWSER_THEME_CHANGED, 135 chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
135 content::Source<ThemeService>( 136 content::Source<ThemeService>(
136 ThemeServiceFactory::GetForProfile(browser->profile()))); 137 ThemeServiceFactory::GetForProfile(browser->profile())));
137 } 138 }
138 139
139 void BrowserActionButton::Destroy() { 140 void BrowserActionButton::Destroy() {
140 MaybeUnregisterExtensionCommand(false); 141 MaybeUnregisterExtensionCommand(false);
141 142 HidePopup();
142 if (menu_runner_) { 143 if (menu_runner_) {
143 menu_runner_->Cancel(); 144 menu_runner_->Cancel();
144 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 145 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
145 } else { 146 } else {
146 delete this; 147 delete this;
147 } 148 }
148 } 149 }
149 150
150 void BrowserActionButton::ViewHierarchyChanged( 151 void BrowserActionButton::ViewHierarchyChanged(
151 const ViewHierarchyChangedDetails& details) { 152 const ViewHierarchyChangedDetails& details) {
(...skipping 17 matching lines...) Expand all
169 return true; 170 return true;
170 } 171 }
171 172
172 void BrowserActionButton::GetAccessibleState(ui::AXViewState* state) { 173 void BrowserActionButton::GetAccessibleState(ui::AXViewState* state) {
173 views::MenuButton::GetAccessibleState(state); 174 views::MenuButton::GetAccessibleState(state);
174 state->role = ui::AX_ROLE_BUTTON; 175 state->role = ui::AX_ROLE_BUTTON;
175 } 176 }
176 177
177 void BrowserActionButton::ButtonPressed(views::Button* sender, 178 void BrowserActionButton::ButtonPressed(views::Button* sender,
178 const ui::Event& event) { 179 const ui::Event& event) {
179 delegate_->OnBrowserActionExecuted(this); 180 ExecuteBrowserAction();
180 } 181 }
181 182
182 void BrowserActionButton::ShowContextMenuForView( 183 void BrowserActionButton::ShowContextMenuForView(
183 View* source, 184 View* source,
184 const gfx::Point& point, 185 const gfx::Point& point,
185 ui::MenuSourceType source_type) { 186 ui::MenuSourceType source_type) {
186 if (!extension()->ShowConfigureContextMenus()) 187 if (!extension()->ShowConfigureContextMenus())
187 return; 188 return;
188 189
189 SetButtonPushed(); 190 SetButtonPushed();
190 191
191 // Reconstructs the menu every time because the menu's contents are dynamic. 192 // Reconstructs the menu every time because the menu's contents are dynamic.
192 scoped_refptr<ExtensionContextMenuModel> context_menu_contents( 193 scoped_refptr<ExtensionContextMenuModel> context_menu_contents(
193 new ExtensionContextMenuModel(extension(), browser_, delegate_)); 194 new ExtensionContextMenuModel(extension(), browser_, this));
194 gfx::Point screen_loc; 195 gfx::Point screen_loc;
195 views::View::ConvertPointToScreen(this, &screen_loc); 196 views::View::ConvertPointToScreen(this, &screen_loc);
196 197
197 views::Widget* parent = NULL; 198 views::Widget* parent = NULL;
198 int run_types = views::MenuRunner::HAS_MNEMONICS | 199 int run_types = views::MenuRunner::HAS_MNEMONICS |
199 views::MenuRunner::CONTEXT_MENU; 200 views::MenuRunner::CONTEXT_MENU;
200 if (delegate_->ShownInsideMenu()) { 201 if (delegate_->ShownInsideMenu()) {
201 run_types |= views::MenuRunner::IS_NESTED; 202 run_types |= views::MenuRunner::IS_NESTED;
202 // RunMenuAt expects a nested menu to be parented by the same widget as the 203 // RunMenuAt expects a nested menu to be parented by the same widget as the
203 // already visible menu, in this case the Chrome menu. 204 // already visible menu, in this case the Chrome menu.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 bool BrowserActionButton::IsPopup() { 265 bool BrowserActionButton::IsPopup() {
265 int tab_id = delegate_->GetCurrentTabId(); 266 int tab_id = delegate_->GetCurrentTabId();
266 return (tab_id < 0) ? false : browser_action_->HasPopup(tab_id); 267 return (tab_id < 0) ? false : browser_action_->HasPopup(tab_id);
267 } 268 }
268 269
269 GURL BrowserActionButton::GetPopupUrl() { 270 GURL BrowserActionButton::GetPopupUrl() {
270 int tab_id = delegate_->GetCurrentTabId(); 271 int tab_id = delegate_->GetCurrentTabId();
271 return (tab_id < 0) ? GURL() : browser_action_->GetPopupUrl(tab_id); 272 return (tab_id < 0) ? GURL() : browser_action_->GetPopupUrl(tab_id);
272 } 273 }
273 274
275 bool BrowserActionButton::ShowPopup(
276 ExtensionPopup::ShowAction show_action,
277 bool grant_tab_permissions) {
278 GURL popup_url;
279 if (delegate_->GetModel()->ExecuteBrowserAction(
280 extension_, browser_, &popup_url, grant_tab_permissions) ==
281 extensions::ExtensionToolbarModel::ACTION_NONE) {
282 return false;
283 }
284
285 // If we're showing the same popup, just hide it and return.
Peter Kasting 2014/07/26 02:33:20 Nit: The word "same" in this sentence is slightly
Devlin 2014/07/29 19:07:14 Yeah - same means "the popup for this browser acti
286 bool already_showing = popup_ != NULL;
287
288 // Always hide the current popup, even if it's not the same.
289 // Only one popup should be visible at a time.
290 delegate_->HideActivePopup();
291 if (already_showing)
292 return false;
293
294 // Browser actions in the overflow menu can still show popups, so we may need
295 // a reference view other than this view. If so, use the overflow view.
296 views::View* reference_view =
297 parent()->visible() ? this : delegate_->GetOverflowReferenceView();
298
299 popup_ = ExtensionPopup::ShowPopup(popup_url,
300 browser_,
301 reference_view,
302 views::BubbleBorder::TOP_RIGHT,
303 show_action);
304 popup_->GetWidget()->AddObserver(this);
305 delegate_->SetPopupOwner(this);
306
307 // Only set button as pushed if it was triggered by a user click.
308 if (grant_tab_permissions)
309 SetButtonPushed();
310 return true;
311 }
312
313 void BrowserActionButton::HidePopup() {
314 if (popup_) {
315 popup_->GetWidget()->RemoveObserver(this);
316 popup_->GetWidget()->Close();
317 popup_ = NULL;
318 SetButtonNotPushed();
319 delegate_->SetPopupOwner(NULL);
320 }
321 }
322
323 void BrowserActionButton::ExecuteBrowserAction() {
324 ShowPopup(ExtensionPopup::SHOW, true);
325 }
326
274 void BrowserActionButton::Observe(int type, 327 void BrowserActionButton::Observe(int type,
275 const content::NotificationSource& source, 328 const content::NotificationSource& source,
276 const content::NotificationDetails& details) { 329 const content::NotificationDetails& details) {
277 switch (type) { 330 switch (type) {
278 case chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED: 331 case chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED:
279 UpdateState(); 332 UpdateState();
280 // The browser action may have become visible/hidden so we need to make 333 // The browser action may have become visible/hidden so we need to make
281 // sure the state gets updated. 334 // sure the state gets updated.
282 delegate_->OnBrowserActionVisibilityChanged(); 335 delegate_->OnBrowserActionVisibilityChanged();
283 break; 336 break;
(...skipping 24 matching lines...) Expand all
308 void BrowserActionButton::OnIconUpdated() { 361 void BrowserActionButton::OnIconUpdated() {
309 UpdateState(); 362 UpdateState();
310 if (icon_observer_) 363 if (icon_observer_)
311 icon_observer_->OnIconUpdated(GetIconWithBadge()); 364 icon_observer_->OnIconUpdated(GetIconWithBadge());
312 } 365 }
313 366
314 bool BrowserActionButton::Activate() { 367 bool BrowserActionButton::Activate() {
315 if (!IsPopup()) 368 if (!IsPopup())
316 return true; 369 return true;
317 370
318 delegate_->OnBrowserActionExecuted(this); 371 ExecuteBrowserAction();
319 372
320 // TODO(erikkay): Run a nested modal loop while the mouse is down to 373 // TODO(erikkay): Run a nested modal loop while the mouse is down to
321 // enable menu-like drag-select behavior. 374 // enable menu-like drag-select behavior.
322 375
323 // The return value of this method is returned via OnMousePressed. 376 // The return value of this method is returned via OnMousePressed.
324 // We need to return false here since we're handing off focus to another 377 // We need to return false here since we're handing off focus to another
325 // widget/view, and true will grab it right back and try to send events 378 // widget/view, and true will grab it right back and try to send events
326 // to us. 379 // to us.
327 return false; 380 return false;
328 } 381 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 } 432 }
380 433
381 bool BrowserActionButton::AcceleratorPressed( 434 bool BrowserActionButton::AcceleratorPressed(
382 const ui::Accelerator& accelerator) { 435 const ui::Accelerator& accelerator) {
383 // Normal priority shortcuts must be handled via standard browser commands to 436 // Normal priority shortcuts must be handled via standard browser commands to
384 // be processed at the proper time. 437 // be processed at the proper time.
385 if (GetAcceleratorPriority(accelerator, extension_) == 438 if (GetAcceleratorPriority(accelerator, extension_) ==
386 ui::AcceleratorManager::kNormalPriority) 439 ui::AcceleratorManager::kNormalPriority)
387 return false; 440 return false;
388 441
389 delegate_->OnBrowserActionExecuted(this); 442 ExecuteBrowserAction();
390 return true; 443 return true;
391 } 444 }
392 445
393 void BrowserActionButton::SetButtonPushed() { 446 void BrowserActionButton::SetButtonPushed() {
394 SetState(views::CustomButton::STATE_PRESSED); 447 SetState(views::CustomButton::STATE_PRESSED);
395 menu_visible_ = true; 448 menu_visible_ = true;
396 } 449 }
397 450
398 void BrowserActionButton::SetButtonNotPushed() { 451 void BrowserActionButton::SetButtonNotPushed() {
399 SetState(views::CustomButton::STATE_NORMAL); 452 SetState(views::CustomButton::STATE_NORMAL);
(...skipping 13 matching lines...) Expand all
413 return browser_action_->GetIconWithBadge(icon, tab_id, spacing); 466 return browser_action_->GetIconWithBadge(icon, tab_id, spacing);
414 } 467 }
415 468
416 gfx::ImageSkia BrowserActionButton::GetIconForTest() { 469 gfx::ImageSkia BrowserActionButton::GetIconForTest() {
417 return GetImage(views::Button::STATE_NORMAL); 470 return GetImage(views::Button::STATE_NORMAL);
418 } 471 }
419 472
420 BrowserActionButton::~BrowserActionButton() { 473 BrowserActionButton::~BrowserActionButton() {
421 } 474 }
422 475
476 void BrowserActionButton::InspectPopup(ExtensionAction* action) {
477 DCHECK_EQ(browser_action_, action);
478 ShowPopup(ExtensionPopup::SHOW_AND_INSPECT, true); // grant active tab
479 }
480
481 void BrowserActionButton::OnWidgetDestroying(views::Widget* widget) {
Peter Kasting 2014/07/26 02:33:20 This code sure looks a lot like HidePopup(). Can
Devlin 2014/07/29 19:07:14 I'm not 100% sure. The problem being the call to
Peter Kasting 2014/07/29 19:18:01 Widget::Close()'s definition checks whether the wi
Devlin 2014/07/29 19:51:46 That may still be problematic. In particular, wid
Peter Kasting 2014/07/29 19:56:05 There isn't from the user's perspective, but there
Devlin 2014/07/29 19:59:48 In theory, if we have a popup showing, and then we
Peter Kasting 2014/07/29 20:03:02 The async close should happen with the next messag
Devlin 2014/07/29 21:25:43 - PatchSet 2 (just calling HidePopup() from OnWidg
Devlin 2014/07/29 21:45:04 Done!
482 DCHECK(popup_);
483 DCHECK_EQ(popup_->GetWidget(), widget);
484 popup_->GetWidget()->RemoveObserver(this);
485 popup_ = NULL;
486 SetButtonNotPushed();
487 delegate_->SetPopupOwner(NULL);
488 }
489
423 void BrowserActionButton::MaybeRegisterExtensionCommand() { 490 void BrowserActionButton::MaybeRegisterExtensionCommand() {
424 extensions::CommandService* command_service = 491 extensions::CommandService* command_service =
425 extensions::CommandService::Get(browser_->profile()); 492 extensions::CommandService::Get(browser_->profile());
426 extensions::Command browser_action_command; 493 extensions::Command browser_action_command;
427 if (command_service->GetBrowserActionCommand( 494 if (command_service->GetBrowserActionCommand(
428 extension_->id(), 495 extension_->id(),
429 extensions::CommandService::ACTIVE_ONLY, 496 extensions::CommandService::ACTIVE_ONLY,
430 &browser_action_command, 497 &browser_action_command,
431 NULL)) { 498 NULL)) {
432 keybinding_.reset(new ui::Accelerator( 499 keybinding_.reset(new ui::Accelerator(
(...skipping 16 matching lines...) Expand all
449 extensions::Command browser_action_command; 516 extensions::Command browser_action_command;
450 if (!only_if_active || !command_service->GetBrowserActionCommand( 517 if (!only_if_active || !command_service->GetBrowserActionCommand(
451 extension_->id(), 518 extension_->id(),
452 extensions::CommandService::ACTIVE_ONLY, 519 extensions::CommandService::ACTIVE_ONLY,
453 &browser_action_command, 520 &browser_action_command,
454 NULL)) { 521 NULL)) {
455 GetFocusManager()->UnregisterAccelerator(*keybinding_.get(), this); 522 GetFocusManager()->UnregisterAccelerator(*keybinding_.get(), this);
456 keybinding_.reset(NULL); 523 keybinding_.reset(NULL);
457 } 524 }
458 } 525 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698