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

Side by Side Diff: chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc

Issue 2716403005: mash: Remove shelf app menu item objects. (Closed)
Patch Set: Fix ash_shell compile Created 3 years, 9 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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/ash/launcher/browser_shortcut_launcher_item_controll er.h" 5 #include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controll er.h"
6 6
7 #include <limits>
7 #include <vector> 8 #include <vector>
8 9
9 #include "ash/common/shelf/shelf_delegate.h" 10 #include "ash/common/shelf/shelf_delegate.h"
10 #include "ash/common/shelf/shelf_model.h" 11 #include "ash/common/shelf/shelf_model.h"
11 #include "ash/common/wm_shell.h" 12 #include "ash/common/wm_shell.h"
12 #include "ash/common/wm_window.h" 13 #include "ash/common/wm_window.h"
13 #include "ash/common/wm_window_property.h" 14 #include "ash/common/wm_window_property.h"
14 #include "ash/public/cpp/shelf_application_menu_item.h" 15 #include "ash/public/cpp/shelf_application_menu_item.h"
15 #include "ash/resources/grit/ash_resources.h" 16 #include "ash/resources/grit/ash_resources.h"
16 #include "ash/wm/window_util.h" 17 #include "ash/wm/window_util.h"
17 #include "base/memory/ptr_util.h" 18 #include "base/memory/ptr_util.h"
19 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.h "
20 #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_tab.h"
21 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" 21 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
22 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h" 22 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h"
23 #include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" 23 #include "chrome/browser/ui/ash/launcher/launcher_context_menu.h"
24 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
24 #include "chrome/browser/ui/browser.h" 25 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_commands.h" 26 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/browser_finder.h" 27 #include "chrome/browser/ui/browser_finder.h"
27 #include "chrome/browser/ui/browser_window.h" 28 #include "chrome/browser/ui/browser_window.h"
28 #include "chrome/browser/ui/chrome_pages.h" 29 #include "chrome/browser/ui/chrome_pages.h"
29 #include "chrome/browser/ui/settings_window_manager.h" 30 #include "chrome/browser/ui/settings_window_manager.h"
30 #include "chrome/browser/ui/tabs/tab_strip_model.h" 31 #include "chrome/browser/ui/tabs/tab_strip_model.h"
31 #include "chrome/browser/web_applications/web_app.h" 32 #include "chrome/browser/web_applications/web_app.h"
32 #include "chrome/common/extensions/extension_constants.h" 33 #include "chrome/common/extensions/extension_constants.h"
33 #include "chrome/grit/chromium_strings.h" 34 #include "chrome/grit/chromium_strings.h"
34 #include "chrome/grit/generated_resources.h" 35 #include "chrome/grit/generated_resources.h"
35 #include "components/strings/grit/components_strings.h" 36 #include "components/strings/grit/components_strings.h"
37 #include "content/public/browser/notification_service.h"
36 #include "content/public/browser/web_contents.h" 38 #include "content/public/browser/web_contents.h"
37 #include "content/public/common/url_constants.h" 39 #include "content/public/common/url_constants.h"
38 #include "ui/aura/window.h" 40 #include "ui/aura/window.h"
39 #include "ui/base/l10n/l10n_util.h" 41 #include "ui/base/l10n/l10n_util.h"
40 #include "ui/base/resource/resource_bundle.h" 42 #include "ui/base/resource/resource_bundle.h"
41 #include "ui/events/event.h" 43 #include "ui/events/event.h"
44 #include "ui/events/event_constants.h"
42 #include "ui/gfx/image/image.h" 45 #include "ui/gfx/image/image.h"
43 #include "ui/wm/core/window_animations.h" 46 #include "ui/wm/core/window_animations.h"
44 47
45 namespace { 48 namespace {
46 49
50 // The maximum number of browser or tab items supported in the application menu.
51 // Also used as a tab-index flag for browser-specific commands that ignore tabs.
James Cook 2017/03/01 19:50:48 It might be nice to have a separate constant for t
msw 2017/03/02 02:59:20 Done.
52 const uint16_t kMaxItems = std::numeric_limits<uint16_t>::max();
53
47 bool IsSettingsBrowser(Browser* browser) { 54 bool IsSettingsBrowser(Browser* browser) {
48 // Normally this test is sufficient. TODO(stevenjb): Replace this with a 55 // Normally this test is sufficient. TODO(stevenjb): Replace this with a
49 // better mechanism (Settings WebUI or Browser type). 56 // better mechanism (Settings WebUI or Browser type).
50 if (chrome::IsTrustedPopupWindowWithScheme(browser, content::kChromeUIScheme)) 57 if (chrome::IsTrustedPopupWindowWithScheme(browser, content::kChromeUIScheme))
51 return true; 58 return true;
52 // If a settings window navigates away from a kChromeUIScheme (e.g. after a 59 // If a settings window navigates away from a kChromeUIScheme (e.g. after a
53 // crash), the above may not be true, so also test against the known list 60 // crash), the above may not be true, so also test against the known list
54 // of settings browsers (which will not be valid during chrome::Navigate 61 // of settings browsers (which will not be valid during chrome::Navigate
55 // which is why we still need the above test). 62 // which is why we still need the above test).
56 if (chrome::SettingsWindowManager::GetInstance()->IsSettingsBrowser(browser)) 63 if (chrome::SettingsWindowManager::GetInstance()->IsSettingsBrowser(browser))
57 return true; 64 return true;
58 return false; 65 return false;
59 } 66 }
60 67
68 // Returns a 32-bit command id from 16-bit browser and web-contents indices.
69 uint32_t GetCommandId(uint16_t browser_index, uint16_t web_contents_index) {
70 return (browser_index << 16) | web_contents_index;
71 }
72
73 // Get the 16-bit browser index from a 32-bit command id.
74 uint16_t GetBrowserIndex(uint32_t command_id) {
75 return base::checked_cast<uint16_t>((command_id >> 16) & 0xFFFF);
76 }
77
78 // Get the 16-bit web-contents index from a 32-bit command id.
79 uint16_t GetWebContentsIndex(uint32_t command_id) {
80 return base::checked_cast<uint16_t>(command_id & 0xFFFF);
81 }
82
83 // Check if the given |web_contents| is in incognito mode.
84 bool IsIncognito(content::WebContents* web_contents) {
85 const Profile* profile =
86 Profile::FromBrowserContext(web_contents->GetBrowserContext());
87 return profile->IsOffTheRecord() && !profile->IsGuestSession();
88 }
89
90 // Get the favicon for the browser list entry for |web_contents|.
91 // Note that for incognito windows the incognito icon will be returned.
92 gfx::Image GetBrowserListIcon(content::WebContents* web_contents) {
93 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
94 return rb.GetImageNamed(IsIncognito(web_contents)
95 ? IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER
96 : IDR_ASH_SHELF_LIST_BROWSER);
97 }
98
99 // Get the title for the browser list entry for |web_contents|.
100 // If |web_contents| has not loaded, returns "New Tab".
101 base::string16 GetBrowserListTitle(content::WebContents* web_contents) {
102 const base::string16& title = web_contents->GetTitle();
103 return title.empty() ? l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE) : title;
104 }
105
61 } // namespace 106 } // namespace
62 107
63 BrowserShortcutLauncherItemController::BrowserShortcutLauncherItemController( 108 BrowserShortcutLauncherItemController::BrowserShortcutLauncherItemController(
64 ChromeLauncherController* launcher_controller, 109 ChromeLauncherController* launcher_controller,
65 ash::ShelfModel* shelf_model) 110 ash::ShelfModel* shelf_model)
66 : LauncherItemController(extension_misc::kChromeAppId, 111 : LauncherItemController(extension_misc::kChromeAppId,
67 std::string(), 112 std::string(),
68 launcher_controller), 113 launcher_controller),
69 shelf_model_(shelf_model) {} 114 shelf_model_(shelf_model) {}
70 115
71 BrowserShortcutLauncherItemController:: 116 BrowserShortcutLauncherItemController::
72 ~BrowserShortcutLauncherItemController() {} 117 ~BrowserShortcutLauncherItemController() {
118 registrar_.RemoveAll();
James Cook 2017/03/01 19:50:48 This isn't handled automatically by the registrar'
msw 2017/03/02 02:59:20 You're right, it's automatically handled; I remove
119 }
73 120
74 void BrowserShortcutLauncherItemController::UpdateBrowserItemState() { 121 void BrowserShortcutLauncherItemController::UpdateBrowserItemState() {
75 // Determine the new browser's active state and change if necessary. 122 // Determine the new browser's active state and change if necessary.
76 int browser_index = 123 int browser_index =
77 shelf_model_->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT); 124 shelf_model_->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT);
78 DCHECK_GE(browser_index, 0); 125 DCHECK_GE(browser_index, 0);
79 ash::ShelfItem browser_item = shelf_model_->items()[browser_index]; 126 ash::ShelfItem browser_item = shelf_model_->items()[browser_index];
80 ash::ShelfItemStatus browser_status = ash::STATUS_CLOSED; 127 ash::ShelfItemStatus browser_status = ash::STATUS_CLOSED;
81 128
82 aura::Window* window = ash::wm::GetActiveWindow(); 129 aura::Window* window = ash::wm::GetActiveWindow();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 chrome::NewEmptyWindow(launcher_controller()->profile()); 197 chrome::NewEmptyWindow(launcher_controller()->profile());
151 return ash::SHELF_ACTION_NEW_WINDOW_CREATED; 198 return ash::SHELF_ACTION_NEW_WINDOW_CREATED;
152 } 199 }
153 200
154 return launcher_controller()->ActivateWindowOrMinimizeIfActive( 201 return launcher_controller()->ActivateWindowOrMinimizeIfActive(
155 last_browser->window(), GetAppMenuItems(0).size() == 1); 202 last_browser->window(), GetAppMenuItems(0).size() == 1);
156 } 203 }
157 204
158 ash::ShelfAppMenuItemList 205 ash::ShelfAppMenuItemList
159 BrowserShortcutLauncherItemController::GetAppMenuItems(int event_flags) { 206 BrowserShortcutLauncherItemController::GetAppMenuItems(int event_flags) {
207 browser_menu_items_.clear();
208 registrar_.RemoveAll();
209
160 ash::ShelfAppMenuItemList items; 210 ash::ShelfAppMenuItemList items;
161 bool found_tabbed_browser = false; 211 bool found_tabbed_browser = false;
162 for (auto* browser : GetListOfActiveBrowsers()) { 212 for (auto* browser : GetListOfActiveBrowsers()) {
213 if (browser_menu_items_.size() >= kMaxItems)
James Cook 2017/03/01 19:50:48 LOL. I'd hate to meet this power-user. :-)
msw 2017/03/02 02:59:20 Haha, yeah; I'm not sure what would break first if
214 break;
163 TabStripModel* tab_strip = browser->tab_strip_model(); 215 TabStripModel* tab_strip = browser->tab_strip_model();
164 if (tab_strip->active_index() == -1) 216 const int tab_index = tab_strip->active_index();
217 if (tab_index < 0 || tab_index >= kMaxItems)
165 continue; 218 continue;
166 if (browser->is_type_tabbed()) 219 if (browser->is_type_tabbed())
167 found_tabbed_browser = true; 220 found_tabbed_browser = true;
168 if (!(event_flags & ui::EF_SHIFT_DOWN)) { 221 if (!(event_flags & ui::EF_SHIFT_DOWN)) {
169 content::WebContents* web_contents = 222 content::WebContents* tab = tab_strip->GetWebContentsAt(tab_index);
James Cook 2017/03/01 19:50:48 I like "tab" -- briefer and clearer!
msw 2017/03/02 02:59:20 Acknowledged.
170 tab_strip->GetWebContentsAt(tab_strip->active_index()); 223 gfx::Image icon = GetBrowserListIcon(tab);
171 gfx::Image app_icon = GetBrowserListIcon(web_contents); 224 base::string16 title = GetBrowserListTitle(tab);
172 base::string16 title = GetBrowserListTitle(web_contents); 225 items.push_back(base::MakeUnique<ash::ShelfApplicationMenuItem>(
173 items.push_back(base::MakeUnique<ChromeLauncherAppMenuItemBrowser>( 226 GetCommandId(browser_menu_items_.size(), kMaxItems), title, &icon));
174 title, &app_icon, browser));
175 } else { 227 } else {
176 for (int index = 0; index < tab_strip->count(); ++index) { 228 for (uint16_t i = 0; i < tab_strip->count() && i < kMaxItems; ++i) {
177 content::WebContents* web_contents = 229 content::WebContents* tab = tab_strip->GetWebContentsAt(i);
178 tab_strip->GetWebContentsAt(index); 230 gfx::Image icon = launcher_controller()->GetAppListIcon(tab);
179 gfx::Image app_icon = 231 base::string16 title = launcher_controller()->GetAppListTitle(tab);
180 launcher_controller()->GetAppListIcon(web_contents); 232 items.push_back(base::MakeUnique<ash::ShelfApplicationMenuItem>(
181 base::string16 title = 233 GetCommandId(browser_menu_items_.size(), i), title, &icon));
182 launcher_controller()->GetAppListTitle(web_contents);
183 items.push_back(base::MakeUnique<ChromeLauncherAppMenuItemTab>(
184 title, &app_icon, web_contents));
185 } 234 }
186 } 235 }
236 browser_menu_items_.push_back(browser);
237 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSING,
238 content::Source<Browser>(browser));
187 } 239 }
188 // If only windowed applications are open, we return an empty list to 240 // If only windowed applications are open, we return an empty list to
189 // enforce the creation of a new browser. 241 // enforce the creation of a new browser.
190 if (!found_tabbed_browser) 242 if (!found_tabbed_browser) {
191 items.clear(); 243 items.clear();
244 browser_menu_items_.clear();
245 registrar_.RemoveAll();
246 }
192 return items; 247 return items;
193 } 248 }
194 249
250 void BrowserShortcutLauncherItemController::ExecuteCommand(
251 uint32_t command_id,
252 int32_t event_flags) {
253 const uint16_t browser_index = GetBrowserIndex(command_id);
254 if (browser_index >= browser_menu_items_.size())
255 return;
256
257 // The indicated browser may have closed while the menu was open.
258 Browser* browser = browser_menu_items_[browser_index];
259 if (!browser)
260 return;
261
262 TabStripModel* tab_strip = browser->tab_strip_model();
263 const uint16_t tab_index = GetWebContentsIndex(command_id);
264 if (event_flags & (ui::EF_SHIFT_DOWN | ui::EF_MIDDLE_MOUSE_BUTTON)) {
265 if (tab_index == kMaxItems) {
266 tab_strip->CloseAllTabs();
267 } else if (tab_strip->ContainsIndex(tab_index)) {
268 tab_strip->CloseWebContentsAt(tab_index,
269 TabStripModel::CLOSE_USER_GESTURE);
270 }
271 } else {
272 multi_user_util::MoveWindowToCurrentDesktop(
273 browser->window()->GetNativeWindow());
274 if (tab_index != kMaxItems && tab_strip->ContainsIndex(tab_index))
275 tab_strip->ActivateTabAt(tab_index, false);
276 browser->window()->Show();
277 browser->window()->Activate();
278 }
279 }
James Cook 2017/03/01 19:50:48 Should this wipe the items and registrar?
msw 2017/03/02 02:59:20 It doesn't seem too important either way, and I'd
James Cook 2017/03/02 15:43:00 Does this controller object get deleted when the m
msw 2017/03/02 18:37:47 Done. (here and for app shortcuts' cached menu ite
280
195 void BrowserShortcutLauncherItemController::Close() { 281 void BrowserShortcutLauncherItemController::Close() {
196 for (auto* browser : GetListOfActiveBrowsers()) 282 for (auto* browser : GetListOfActiveBrowsers())
197 browser->window()->Close(); 283 browser->window()->Close();
198 } 284 }
199 285
200 bool BrowserShortcutLauncherItemController::IsListOfActiveBrowserEmpty() { 286 bool BrowserShortcutLauncherItemController::IsListOfActiveBrowserEmpty() {
201 return GetListOfActiveBrowsers().empty(); 287 return GetListOfActiveBrowsers().empty();
202 } 288 }
203 289
204 gfx::Image BrowserShortcutLauncherItemController::GetBrowserListIcon(
205 content::WebContents* web_contents) const {
206 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
207 return rb.GetImageNamed(IsIncognito(web_contents) ?
208 IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER :
209 IDR_ASH_SHELF_LIST_BROWSER);
210 }
211
212 base::string16 BrowserShortcutLauncherItemController::GetBrowserListTitle(
213 content::WebContents* web_contents) const {
214 base::string16 title = web_contents->GetTitle();
215 if (!title.empty())
216 return title;
217 return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE);
218 }
219
220 bool BrowserShortcutLauncherItemController::IsIncognito(
221 content::WebContents* web_contents) const {
222 const Profile* profile =
223 Profile::FromBrowserContext(web_contents->GetBrowserContext());
224 return profile->IsOffTheRecord() && !profile->IsGuestSession();
225 }
226
227 ash::ShelfAction 290 ash::ShelfAction
228 BrowserShortcutLauncherItemController::ActivateOrAdvanceToNextBrowser() { 291 BrowserShortcutLauncherItemController::ActivateOrAdvanceToNextBrowser() {
229 // Create a list of all suitable running browsers. 292 // Create a list of all suitable running browsers.
230 std::vector<Browser*> items; 293 std::vector<Browser*> items;
231 // We use the list in the order of how the browsers got created - not the LRU 294 // We use the list in the order of how the browsers got created - not the LRU
232 // order. 295 // order.
233 const BrowserList* browser_list = BrowserList::GetInstance(); 296 const BrowserList* browser_list = BrowserList::GetInstance();
234 for (BrowserList::const_iterator it = browser_list->begin(); 297 for (BrowserList::const_iterator it = browser_list->begin();
235 it != browser_list->end(); ++it) { 298 it != browser_list->end(); ++it) {
236 if (IsBrowserRepresentedInBrowserList(*it)) 299 if (IsBrowserRepresentedInBrowserList(*it))
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 !browser->window()->IsMinimized()) { 367 !browser->window()->IsMinimized()) {
305 continue; 368 continue;
306 } 369 }
307 if (!IsBrowserRepresentedInBrowserList(browser) && 370 if (!IsBrowserRepresentedInBrowserList(browser) &&
308 !browser->is_type_tabbed()) 371 !browser->is_type_tabbed())
309 continue; 372 continue;
310 active_browsers.push_back(browser); 373 active_browsers.push_back(browser);
311 } 374 }
312 return active_browsers; 375 return active_browsers;
313 } 376 }
377
378 void BrowserShortcutLauncherItemController::Observe(
379 int type,
380 const content::NotificationSource& source,
381 const content::NotificationDetails& details) {
382 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_CLOSING, type);
383 Browser* browser = content::Source<Browser>(source).ptr();
384 DCHECK(browser);
385 BrowserList::BrowserVector::iterator item = std::find(
386 browser_menu_items_.begin(), browser_menu_items_.end(), browser);
387 DCHECK(item != browser_menu_items_.end());
388 // Clear the entry for the closed browser and leave other indices intact.
389 *item = nullptr;
390 registrar_.Remove(this, chrome::NOTIFICATION_BROWSER_CLOSING,
391 content::Source<Browser>(browser));
392 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698