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

Side by Side Diff: chrome/browser/ui/views/extensions/extension_popup.cc

Issue 8879045: Don't close ExtensionPopups on child window focus (Win, non-Aura). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix bad typo. Created 9 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "chrome/browser/debugger/devtools_window.h" 9 #include "chrome/browser/debugger/devtools_window.h"
10 #include "chrome/browser/extensions/extension_process_manager.h" 10 #include "chrome/browser/extensions/extension_process_manager.h"
(...skipping 21 matching lines...) Expand all
32 ExtensionHost* host, 32 ExtensionHost* host,
33 views::View* anchor_view, 33 views::View* anchor_view,
34 views::BubbleBorder::ArrowLocation arrow_location, 34 views::BubbleBorder::ArrowLocation arrow_location,
35 bool inspect_with_devtools) 35 bool inspect_with_devtools)
36 : BubbleDelegateView(anchor_view, arrow_location), 36 : BubbleDelegateView(anchor_view, arrow_location),
37 extension_host_(host), 37 extension_host_(host),
38 inspect_with_devtools_(inspect_with_devtools) { 38 inspect_with_devtools_(inspect_with_devtools) {
39 SetLayoutManager(new views::FillLayout()); 39 SetLayoutManager(new views::FillLayout());
40 AddChildView(host->view()); 40 AddChildView(host->view());
41 host->view()->SetContainer(this); 41 host->view()->SetContainer(this);
42 #if defined(OS_WIN) && !defined(USE_AURA)
43 // Use OnNativeFocusChange to check for child window activation on deactivate.
44 set_close_on_deactivate(false);
45 #else
42 set_close_on_deactivate(!inspect_with_devtools); 46 set_close_on_deactivate(!inspect_with_devtools);
47 #endif
43 48
44 // We wait to show the popup until the contained host finishes loading. 49 // We wait to show the popup until the contained host finishes loading.
45 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, 50 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
46 content::Source<Profile>(host->profile())); 51 content::Source<Profile>(host->profile()));
47 52
48 // Listen for the containing view calling window.close(); 53 // Listen for the containing view calling window.close();
49 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, 54 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
50 content::Source<Profile>(host->profile())); 55 content::Source<Profile>(host->profile()));
56
57 views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this);
51 } 58 }
52 59
53 ExtensionPopup::~ExtensionPopup() { 60 ExtensionPopup::~ExtensionPopup() {
61 views::WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(this);
54 } 62 }
55 63
56 void ExtensionPopup::Observe(int type, 64 void ExtensionPopup::Observe(int type,
57 const content::NotificationSource& source, 65 const content::NotificationSource& source,
58 const content::NotificationDetails& details) { 66 const content::NotificationDetails& details) {
59 switch (type) { 67 switch (type) {
60 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: 68 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING:
61 // Once we receive did stop loading, the content will be complete and 69 // Once we receive did stop loading, the content will be complete and
62 // the width will have been computed. Now it's safe to show. 70 // the width will have been computed. Now it's safe to show.
63 if (host() == content::Details<ExtensionHost>(details).ptr()) { 71 if (host() == content::Details<ExtensionHost>(details).ptr()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 } 104 }
97 105
98 gfx::Size ExtensionPopup::GetPreferredSize() { 106 gfx::Size ExtensionPopup::GetPreferredSize() {
99 // Constrain the size to popup min/max. 107 // Constrain the size to popup min/max.
100 gfx::Size sz = views::View::GetPreferredSize(); 108 gfx::Size sz = views::View::GetPreferredSize();
101 sz.set_width(std::max(kMinWidth, std::min(kMaxWidth, sz.width()))); 109 sz.set_width(std::max(kMinWidth, std::min(kMaxWidth, sz.width())));
102 sz.set_height(std::max(kMinHeight, std::min(kMaxHeight, sz.height()))); 110 sz.set_height(std::max(kMinHeight, std::min(kMaxHeight, sz.height())));
103 return sz; 111 return sz;
104 } 112 }
105 113
114 void ExtensionPopup::OnNativeFocusChange(gfx::NativeView focused_before,
115 gfx::NativeView focused_now) {
116 // TODO(msw): Implement something equivalent for Aura. See crbug.com/106958
117 #if defined(OS_WIN) && !defined(USE_AURA)
118 // Don't close if a child of this window is activated (only needed on Win).
119 // ExtensionPopups can create Javascipt dialogs; see crbug.com/106723.
120 gfx::NativeView this_window = GetWidget()->GetNativeView();
121 if (!inspect_with_devtools_ && focused_before == this_window) {
122 DCHECK_NE(focused_now, this_window);
123 if (::GetWindow(focused_now, GW_OWNER) == this_window)
124 return;
125 gfx::NativeView focused_parent = focused_now;
126 while (focused_parent = ::GetParent(focused_parent)) {
127 if (this_window == focused_parent)
128 return;
129 }
130 GetWidget()->Close();
131 }
132 #endif
133 }
134
106 // static 135 // static
107 ExtensionPopup* ExtensionPopup::ShowPopup( 136 ExtensionPopup* ExtensionPopup::ShowPopup(
108 const GURL& url, 137 const GURL& url,
109 Browser* browser, 138 Browser* browser,
110 views::View* anchor_view, 139 views::View* anchor_view,
111 views::BubbleBorder::ArrowLocation arrow_location, 140 views::BubbleBorder::ArrowLocation arrow_location,
112 bool inspect_with_devtools) { 141 bool inspect_with_devtools) {
113 ExtensionProcessManager* manager = 142 ExtensionProcessManager* manager =
114 browser->profile()->GetExtensionProcessManager(); 143 browser->profile()->GetExtensionProcessManager();
115 ExtensionHost* host = manager->CreatePopupHost(url, browser); 144 ExtensionHost* host = manager->CreatePopupHost(url, browser);
116 ExtensionPopup* popup = new ExtensionPopup(browser, host, anchor_view, 145 ExtensionPopup* popup = new ExtensionPopup(browser, host, anchor_view,
117 arrow_location, inspect_with_devtools); 146 arrow_location, inspect_with_devtools);
118 browser::CreateViewsBubble(popup); 147 browser::CreateViewsBubble(popup);
119 148
120 // TODO(msw): Use half the corner radius as contents margins so that contents 149 // TODO(msw): Use half the corner radius as contents margins so that contents
121 // fit better in the bubble. See http://crbug.com/80416. 150 // fit better in the bubble. See http://crbug.com/80416.
122 151
123 // If the host had somehow finished loading, then we'd miss the notification 152 // If the host had somehow finished loading, then we'd miss the notification
124 // and not show. This seems to happen in single-process mode. 153 // and not show. This seems to happen in single-process mode.
125 if (host->did_stop_loading()) { 154 if (host->did_stop_loading()) {
126 popup->Show(); 155 popup->Show();
127 // Focus on the host contents when the bubble is first shown. 156 // Focus on the host contents when the bubble is first shown.
128 host->host_contents()->Focus(); 157 host->host_contents()->Focus();
129 } 158 }
130 159
131 return popup; 160 return popup;
132 } 161 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/extensions/extension_popup.h ('k') | ui/views/focus/widget_focus_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698