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

Side by Side Diff: chrome/browser/ui/views/frame/global_menu_bar_x11.cc

Issue 22562005: linux_aura: Implement the dynamic History menu in the dbusmenu. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reupload part 2 Created 7 years, 4 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 | Annotate | Revision Log
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/frame/global_menu_bar_x11.h" 5 #include "chrome/browser/ui/views/frame/global_menu_bar_x11.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <glib-object.h> 8 #include <glib-object.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/prefs/pref_service.h" 11 #include "base/prefs/pref_service.h"
12 #include "base/stl_util.h"
13 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/app/chrome_command_ids.h" 16 #include "chrome/app/chrome_command_ids.h"
17 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/browser/history/top_sites.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/sessions/tab_restore_service.h"
21 #include "chrome/browser/sessions/tab_restore_service_factory.h"
22 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_commands.h" 23 #include "chrome/browser/ui/browser_commands.h"
24 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
15 #include "chrome/browser/ui/views/frame/browser_desktop_root_window_host_x11.h" 25 #include "chrome/browser/ui/views/frame/browser_desktop_root_window_host_x11.h"
16 #include "chrome/browser/ui/views/frame/browser_view.h" 26 #include "chrome/browser/ui/views/frame/browser_view.h"
17 #include "chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h" 27 #include "chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h"
18 #include "chrome/common/pref_names.h" 28 #include "chrome/common/pref_names.h"
29 #include "content/public/browser/notification_source.h"
19 #include "grit/generated_resources.h" 30 #include "grit/generated_resources.h"
20 #include "ui/base/accelerators/menu_label_accelerator_util_linux.h" 31 #include "ui/base/accelerators/menu_label_accelerator_util_linux.h"
21 #include "ui/base/keycodes/keyboard_code_conversion_x.h" 32 #include "ui/base/keycodes/keyboard_code_conversion_x.h"
22 #include "ui/base/l10n/l10n_util.h" 33 #include "ui/base/l10n/l10n_util.h"
34 #include "ui/base/text/text_elider.h"
23 35
24 // libdbusmenu-glib types 36 // libdbusmenu-glib types
25 typedef struct _DbusmenuMenuitem DbusmenuMenuitem; 37 typedef struct _DbusmenuMenuitem DbusmenuMenuitem;
26 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_new_func)(); 38 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_new_func)();
27 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_new_with_id_func)(int id); 39 typedef bool (*dbusmenu_menuitem_child_add_position_func)(
28 40 DbusmenuMenuitem* parent,
29 typedef int (*dbusmenu_menuitem_get_id_func)(DbusmenuMenuitem* item); 41 DbusmenuMenuitem* child,
42 unsigned int position);
30 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_child_append_func)( 43 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_child_append_func)(
31 DbusmenuMenuitem* parent, 44 DbusmenuMenuitem* parent,
32 DbusmenuMenuitem* child); 45 DbusmenuMenuitem* child);
46 typedef bool (*dbusmenu_menuitem_child_delete_func)(
47 DbusmenuMenuitem* parent,
48 DbusmenuMenuitem* child);
49 typedef GList* (*dbusmenu_menuitem_get_children_func)(
50 DbusmenuMenuitem* item);
33 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_property_set_func)( 51 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_property_set_func)(
34 DbusmenuMenuitem* item, 52 DbusmenuMenuitem* item,
35 const char* property, 53 const char* property,
36 const char* value); 54 const char* value);
37 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_property_set_variant_func)( 55 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_property_set_variant_func)(
38 DbusmenuMenuitem* item, 56 DbusmenuMenuitem* item,
39 const char* property, 57 const char* property,
40 GVariant* value); 58 GVariant* value);
41 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_property_set_bool_func)( 59 typedef DbusmenuMenuitem* (*dbusmenu_menuitem_property_set_bool_func)(
42 DbusmenuMenuitem* item, 60 DbusmenuMenuitem* item,
(...skipping 15 matching lines...) Expand all
58 int command; 76 int command;
59 int tag; 77 int tag;
60 }; 78 };
61 79
62 namespace { 80 namespace {
63 81
64 // Retrieved functions from libdbusmenu-glib. 82 // Retrieved functions from libdbusmenu-glib.
65 83
66 // DbusmenuMenuItem methods: 84 // DbusmenuMenuItem methods:
67 dbusmenu_menuitem_new_func menuitem_new = NULL; 85 dbusmenu_menuitem_new_func menuitem_new = NULL;
68 dbusmenu_menuitem_new_with_id_func menuitem_new_with_id = NULL; 86 dbusmenu_menuitem_get_children_func menuitem_get_children = NULL;
69 dbusmenu_menuitem_get_id_func menuitem_get_id = NULL; 87 dbusmenu_menuitem_child_add_position_func menuitem_child_add_position = NULL;
70 dbusmenu_menuitem_child_append_func menuitem_child_append = NULL; 88 dbusmenu_menuitem_child_append_func menuitem_child_append = NULL;
89 dbusmenu_menuitem_child_delete_func menuitem_child_delete = NULL;
71 dbusmenu_menuitem_property_set_func menuitem_property_set = NULL; 90 dbusmenu_menuitem_property_set_func menuitem_property_set = NULL;
72 dbusmenu_menuitem_property_set_variant_func menuitem_property_set_variant = 91 dbusmenu_menuitem_property_set_variant_func menuitem_property_set_variant =
73 NULL; 92 NULL;
74 dbusmenu_menuitem_property_set_bool_func menuitem_property_set_bool = NULL; 93 dbusmenu_menuitem_property_set_bool_func menuitem_property_set_bool = NULL;
75 dbusmenu_menuitem_property_set_int_func menuitem_property_set_int = NULL; 94 dbusmenu_menuitem_property_set_int_func menuitem_property_set_int = NULL;
76 95
77 // DbusmenuServer methods: 96 // DbusmenuServer methods:
78 dbusmenu_server_new_func server_new = NULL; 97 dbusmenu_server_new_func server_new = NULL;
79 dbusmenu_server_set_root_func server_set_root = NULL; 98 dbusmenu_server_set_root_func server_set_root = NULL;
80 99
81 // Properties that we set on menu items: 100 // Properties that we set on menu items:
82 const char kPropertyEnabled[] = "enabled"; 101 const char kPropertyEnabled[] = "enabled";
83 const char kPropertyLabel[] = "label"; 102 const char kPropertyLabel[] = "label";
84 const char kPropertyShortcut[] = "shortcut"; 103 const char kPropertyShortcut[] = "shortcut";
85 const char kPropertyType[] = "type"; 104 const char kPropertyType[] = "type";
86 const char kPropertyToggleType[] = "toggle-type"; 105 const char kPropertyToggleType[] = "toggle-type";
87 const char kPropertyToggleState[] = "toggle-state"; 106 const char kPropertyToggleState[] = "toggle-state";
88 const char kPropertyVisible[] = "visible"; 107 const char kPropertyVisible[] = "visible";
89 108
90 const char kTypeCheckmark[] = "checkmark"; 109 const char kTypeCheckmark[] = "checkmark";
91 const char kTypeSeparator[] = "separator"; 110 const char kTypeSeparator[] = "separator";
92 111
112 // The maximum number of most visited items to display.
113 const unsigned int kMostVisitedCount = 8;
114
115 // The number of recently closed items to get.
116 const unsigned int kRecentlyClosedCount = 8;
117
118 // Menus more than this many chars long will get trimmed.
119 const int kMaximumMenuWidthInChars = 50;
120
93 // Constants used in menu definitions 121 // Constants used in menu definitions
94 const int MENU_SEPARATOR =-1; 122 const int MENU_SEPARATOR =-1;
95 const int MENU_END = -2; 123 const int MENU_END = -2;
96 const int MENU_DISABLED_LABEL = -3; 124 const int MENU_DISABLED_ID = -3;
97 125
98 GlobalMenuBarCommand file_menu[] = { 126 GlobalMenuBarCommand file_menu[] = {
99 { IDS_NEW_TAB, IDC_NEW_TAB }, 127 { IDS_NEW_TAB, IDC_NEW_TAB },
100 { IDS_NEW_WINDOW, IDC_NEW_WINDOW }, 128 { IDS_NEW_WINDOW, IDC_NEW_WINDOW },
101 { IDS_NEW_INCOGNITO_WINDOW, IDC_NEW_INCOGNITO_WINDOW }, 129 { IDS_NEW_INCOGNITO_WINDOW, IDC_NEW_INCOGNITO_WINDOW },
102 { IDS_REOPEN_CLOSED_TABS_LINUX, IDC_RESTORE_TAB }, 130 { IDS_REOPEN_CLOSED_TABS_LINUX, IDC_RESTORE_TAB },
103 { IDS_OPEN_FILE_LINUX, IDC_OPEN_FILE }, 131 { IDS_OPEN_FILE_LINUX, IDC_OPEN_FILE },
104 { IDS_OPEN_LOCATION_LINUX, IDC_FOCUS_LOCATION }, 132 { IDS_OPEN_LOCATION_LINUX, IDC_FOCUS_LOCATION },
105 133
106 { MENU_SEPARATOR, MENU_SEPARATOR }, 134 { MENU_SEPARATOR, MENU_SEPARATOR },
(...skipping 22 matching lines...) Expand all
129 157
130 { IDS_FIND, IDC_FIND }, 158 { IDS_FIND, IDC_FIND },
131 159
132 { MENU_SEPARATOR, MENU_SEPARATOR }, 160 { MENU_SEPARATOR, MENU_SEPARATOR },
133 161
134 { IDS_PREFERENCES, IDC_OPTIONS }, 162 { IDS_PREFERENCES, IDC_OPTIONS },
135 163
136 { MENU_END, MENU_END } 164 { MENU_END, MENU_END }
137 }; 165 };
138 166
139
140 GlobalMenuBarCommand view_menu[] = { 167 GlobalMenuBarCommand view_menu[] = {
141 { IDS_SHOW_BOOKMARK_BAR, IDC_SHOW_BOOKMARK_BAR }, 168 { IDS_SHOW_BOOKMARK_BAR, IDC_SHOW_BOOKMARK_BAR },
142 169
143 { MENU_SEPARATOR, MENU_SEPARATOR }, 170 { MENU_SEPARATOR, MENU_SEPARATOR },
144 171
145 { IDS_STOP_MENU_LINUX, IDC_STOP }, 172 { IDS_STOP_MENU_LINUX, IDC_STOP },
146 { IDS_RELOAD_MENU_LINUX, IDC_RELOAD }, 173 { IDS_RELOAD_MENU_LINUX, IDC_RELOAD },
147 174
148 { MENU_SEPARATOR, MENU_SEPARATOR }, 175 { MENU_SEPARATOR, MENU_SEPARATOR },
149 176
150 { IDS_FULLSCREEN, IDC_FULLSCREEN }, 177 { IDS_FULLSCREEN, IDC_FULLSCREEN },
151 { IDS_TEXT_DEFAULT_LINUX, IDC_ZOOM_NORMAL }, 178 { IDS_TEXT_DEFAULT_LINUX, IDC_ZOOM_NORMAL },
152 { IDS_TEXT_BIGGER_LINUX, IDC_ZOOM_PLUS }, 179 { IDS_TEXT_BIGGER_LINUX, IDC_ZOOM_PLUS },
153 { IDS_TEXT_SMALLER_LINUX, IDC_ZOOM_MINUS }, 180 { IDS_TEXT_SMALLER_LINUX, IDC_ZOOM_MINUS },
154 181
155 { MENU_END, MENU_END } 182 { MENU_END, MENU_END }
156 }; 183 };
157 184
158 // TODO(erg): History menu. 185 GlobalMenuBarCommand history_menu[] = {
186 { IDS_HISTORY_HOME_LINUX, IDC_HOME },
187 { IDS_HISTORY_BACK_LINUX, IDC_BACK },
188 { IDS_HISTORY_FORWARD_LINUX, IDC_FORWARD },
189
190 { MENU_SEPARATOR, MENU_SEPARATOR },
191
192 { IDS_HISTORY_VISITED_LINUX, MENU_DISABLED_ID,
193 GlobalMenuBarX11::TAG_MOST_VISITED_HEADER },
194
195 { MENU_SEPARATOR, MENU_SEPARATOR },
196
197 { IDS_HISTORY_CLOSED_LINUX, MENU_DISABLED_ID,
198 GlobalMenuBarX11::TAG_RECENTLY_CLOSED_HEADER },
199
200 { MENU_SEPARATOR, MENU_SEPARATOR },
201
202 { IDS_SHOWFULLHISTORY_LINK, IDC_SHOW_HISTORY },
203
204 { MENU_END, MENU_END }
205 };
159 206
160 GlobalMenuBarCommand tools_menu[] = { 207 GlobalMenuBarCommand tools_menu[] = {
161 { IDS_SHOW_DOWNLOADS, IDC_SHOW_DOWNLOADS }, 208 { IDS_SHOW_DOWNLOADS, IDC_SHOW_DOWNLOADS },
162 { IDS_SHOW_HISTORY, IDC_SHOW_HISTORY }, 209 { IDS_SHOW_HISTORY, IDC_SHOW_HISTORY },
163 { IDS_SHOW_EXTENSIONS, IDC_MANAGE_EXTENSIONS }, 210 { IDS_SHOW_EXTENSIONS, IDC_MANAGE_EXTENSIONS },
164 211
165 { MENU_SEPARATOR, MENU_SEPARATOR }, 212 { MENU_SEPARATOR, MENU_SEPARATOR },
166 213
167 { IDS_TASK_MANAGER, IDC_TASK_MANAGER }, 214 { IDS_TASK_MANAGER, IDC_TASK_MANAGER },
168 { IDS_CLEAR_BROWSING_DATA, IDC_CLEAR_BROWSING_DATA }, 215 { IDS_CLEAR_BROWSING_DATA, IDC_CLEAR_BROWSING_DATA },
(...skipping 20 matching lines...) Expand all
189 return; 236 return;
190 attempted_load = true; 237 attempted_load = true;
191 238
192 void* dbusmenu_lib = dlopen("libdbusmenu-glib.so", RTLD_LAZY); 239 void* dbusmenu_lib = dlopen("libdbusmenu-glib.so", RTLD_LAZY);
193 if (!dbusmenu_lib) 240 if (!dbusmenu_lib)
194 return; 241 return;
195 242
196 // DbusmenuMenuItem methods. 243 // DbusmenuMenuItem methods.
197 menuitem_new = reinterpret_cast<dbusmenu_menuitem_new_func>( 244 menuitem_new = reinterpret_cast<dbusmenu_menuitem_new_func>(
198 dlsym(dbusmenu_lib, "dbusmenu_menuitem_new")); 245 dlsym(dbusmenu_lib, "dbusmenu_menuitem_new"));
199 menuitem_new_with_id = reinterpret_cast<dbusmenu_menuitem_new_with_id_func>( 246 menuitem_child_add_position =
200 dlsym(dbusmenu_lib, "dbusmenu_menuitem_new_with_id")); 247 reinterpret_cast<dbusmenu_menuitem_child_add_position_func>(
201 menuitem_get_id = reinterpret_cast<dbusmenu_menuitem_get_id_func>( 248 dlsym(dbusmenu_lib, "dbusmenu_menuitem_child_add_position"));
202 dlsym(dbusmenu_lib, "dbusmenu_menuitem_get_id"));
203 menuitem_child_append = reinterpret_cast<dbusmenu_menuitem_child_append_func>( 249 menuitem_child_append = reinterpret_cast<dbusmenu_menuitem_child_append_func>(
204 dlsym(dbusmenu_lib, "dbusmenu_menuitem_child_append")); 250 dlsym(dbusmenu_lib, "dbusmenu_menuitem_child_append"));
251 menuitem_child_delete = reinterpret_cast<dbusmenu_menuitem_child_delete_func>(
252 dlsym(dbusmenu_lib, "dbusmenu_menuitem_child_delete"));
253 menuitem_get_children = reinterpret_cast<dbusmenu_menuitem_get_children_func>(
254 dlsym(dbusmenu_lib, "dbusmenu_menuitem_get_children"));
205 menuitem_property_set = reinterpret_cast<dbusmenu_menuitem_property_set_func>( 255 menuitem_property_set = reinterpret_cast<dbusmenu_menuitem_property_set_func>(
206 dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set")); 256 dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set"));
207 menuitem_property_set_variant = 257 menuitem_property_set_variant =
208 reinterpret_cast<dbusmenu_menuitem_property_set_variant_func>( 258 reinterpret_cast<dbusmenu_menuitem_property_set_variant_func>(
209 dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set_variant")); 259 dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set_variant"));
210 menuitem_property_set_bool = 260 menuitem_property_set_bool =
211 reinterpret_cast<dbusmenu_menuitem_property_set_bool_func>( 261 reinterpret_cast<dbusmenu_menuitem_property_set_bool_func>(
212 dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set_bool")); 262 dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set_bool"));
213 menuitem_property_set_int = 263 menuitem_property_set_int =
214 reinterpret_cast<dbusmenu_menuitem_property_set_int_func>( 264 reinterpret_cast<dbusmenu_menuitem_property_set_int_func>(
215 dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set_int")); 265 dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set_int"));
216 266
217 // DbusmenuServer methods. 267 // DbusmenuServer methods.
218 server_new = reinterpret_cast<dbusmenu_server_new_func>( 268 server_new = reinterpret_cast<dbusmenu_server_new_func>(
219 dlsym(dbusmenu_lib, "dbusmenu_server_new")); 269 dlsym(dbusmenu_lib, "dbusmenu_server_new"));
220 server_set_root = reinterpret_cast<dbusmenu_server_set_root_func>( 270 server_set_root = reinterpret_cast<dbusmenu_server_set_root_func>(
221 dlsym(dbusmenu_lib, "dbusmenu_server_set_root")); 271 dlsym(dbusmenu_lib, "dbusmenu_server_set_root"));
222 } 272 }
223 273
224 } // namespace 274 } // namespace
225 275
276 class GlobalMenuBarX11::HistoryItem {
sadrul 2013/08/09 06:38:54 This should probably be struct?
277 public:
278 HistoryItem() : session_id(0) {}
279
280 // The title for the menu item.
281 string16 title;
282 // The URL that will be navigated to if the user selects this item.
283 GURL url;
284
285 // This ID is unique for a browser session and can be passed to the
286 // TabRestoreService to re-open the closed window or tab that this
287 // references. A non-0 session ID indicates that this is an entry can be
288 // restored that way. Otherwise, the URL will be used to open the item and
289 // this ID will be 0.
290 SessionID::id_type session_id;
291
292 // If the HistoryItem is a window, this will be the vector of tabs. Note
293 // that this is a list of weak references. The |menu_item_map_| is the owner
294 // of all items. If it is not a window, then the entry is a single page and
295 // the vector will be empty.
296 std::vector<HistoryItem*> tabs;
297
298 private:
299 DISALLOW_COPY_AND_ASSIGN(HistoryItem);
300 };
301
226 GlobalMenuBarX11::GlobalMenuBarX11(BrowserView* browser_view, 302 GlobalMenuBarX11::GlobalMenuBarX11(BrowserView* browser_view,
227 BrowserDesktopRootWindowHostX11* host) 303 BrowserDesktopRootWindowHostX11* host)
228 : browser_(browser_view->browser()), 304 : browser_(browser_view->browser()),
305 profile_(browser_->profile()),
229 browser_view_(browser_view), 306 browser_view_(browser_view),
230 host_(host), 307 host_(host),
231 server_(NULL), 308 server_(NULL),
232 root_item_(NULL) { 309 root_item_(NULL),
310 history_menu_(NULL),
311 top_sites_(NULL),
312 tab_restore_service_(NULL),
313 weak_ptr_factory_(this) {
233 EnsureMethodsLoaded(); 314 EnsureMethodsLoaded();
234 315
235 if (server_new) 316 if (server_new)
236 host_->AddObserver(this); 317 host_->AddObserver(this);
237 } 318 }
238 319
239 GlobalMenuBarX11::~GlobalMenuBarX11() { 320 GlobalMenuBarX11::~GlobalMenuBarX11() {
240 if (server_) { 321 if (server_) {
241 Disable(); 322 Disable();
323
324 if (tab_restore_service_)
325 tab_restore_service_->RemoveObserver(this);
326
327 #ifndef NDEBUG
328 // In debug mode, do the slower cleanup of every HistoryItem that we know
329 // about just to assert that we didn't leak any of them during normal
330 // running.
331 ClearMenuSection(history_menu_, GlobalMenuBarX11::TAG_RECENTLY_CLOSED);
332 ClearMenuSection(history_menu_, GlobalMenuBarX11::TAG_MOST_VISITED);
333 DCHECK(menu_item_history_map_.empty());
334 #endif // NDEBUG
335
336 STLDeleteContainerPairSecondPointers(menu_item_history_map_.begin(),
337 menu_item_history_map_.end());
338 menu_item_history_map_.clear();
339
242 g_object_unref(server_); 340 g_object_unref(server_);
243 host_->RemoveObserver(this); 341 host_->RemoveObserver(this);
244 } 342 }
245 } 343 }
246 344
247 // static 345 // static
248 std::string GlobalMenuBarX11::GetPathForWindow(unsigned long xid) { 346 std::string GlobalMenuBarX11::GetPathForWindow(unsigned long xid) {
249 return base::StringPrintf("/com/canonical/menu/%lX", xid); 347 return base::StringPrintf("/com/canonical/menu/%lX", xid);
250 } 348 }
251 349
350 DbusmenuMenuitem* GlobalMenuBarX11::BuildSeparator() {
351 DbusmenuMenuitem* item = menuitem_new();
352 menuitem_property_set(item, kPropertyType, kTypeSeparator);
353 menuitem_property_set_bool(item, kPropertyVisible, true);
354 return item;
355 }
356
357 DbusmenuMenuitem* GlobalMenuBarX11::BuildMenuItem(
358 const std::string& label,
359 int tag_id) {
360 DbusmenuMenuitem* item = menuitem_new();
361 menuitem_property_set(item, kPropertyLabel, label.c_str());
362 menuitem_property_set_bool(item, kPropertyVisible, true);
363
364 if (tag_id)
365 g_object_set_data(G_OBJECT(item), "type-tag", GINT_TO_POINTER(tag_id));
366
367 return item;
368 }
369
252 void GlobalMenuBarX11::InitServer(unsigned long xid) { 370 void GlobalMenuBarX11::InitServer(unsigned long xid) {
253 std::string path = GetPathForWindow(xid); 371 std::string path = GetPathForWindow(xid);
254 server_ = server_new(path.c_str()); 372 server_ = server_new(path.c_str());
255 373
256 root_item_ = menuitem_new(); 374 root_item_ = menuitem_new();
257 menuitem_property_set(root_item_, kPropertyLabel, "Root"); 375 menuitem_property_set(root_item_, kPropertyLabel, "Root");
258 menuitem_property_set_bool(root_item_, kPropertyVisible, true); 376 menuitem_property_set_bool(root_item_, kPropertyVisible, true);
259 377
260 BuildMenuFrom(root_item_, IDS_FILE_MENU_LINUX, &id_to_menu_item_, file_menu); 378 // First build static menu content.
261 BuildMenuFrom(root_item_, IDS_EDIT_MENU_LINUX, &id_to_menu_item_, edit_menu); 379 BuildStaticMenu(root_item_, IDS_FILE_MENU_LINUX, file_menu);
262 BuildMenuFrom(root_item_, IDS_VIEW_MENU_LINUX, &id_to_menu_item_, view_menu); 380 BuildStaticMenu(root_item_, IDS_EDIT_MENU_LINUX, edit_menu);
263 // TODO(erg): History menu. 381 BuildStaticMenu(root_item_, IDS_VIEW_MENU_LINUX, view_menu);
264 BuildMenuFrom(root_item_, IDS_TOOLS_MENU_LINUX, &id_to_menu_item_, 382 history_menu_ = BuildStaticMenu(
265 tools_menu); 383 root_item_, IDS_HISTORY_MENU_LINUX, history_menu);
266 BuildMenuFrom(root_item_, IDS_HELP_MENU_LINUX, &id_to_menu_item_, help_menu); 384 BuildStaticMenu(root_item_, IDS_TOOLS_MENU_LINUX, tools_menu);
385 BuildStaticMenu(root_item_, IDS_HELP_MENU_LINUX, help_menu);
386
387 // We have to connect to |history_menu_item|'s "activate" signal instead of
388 // |history_menu|'s "show" signal because we are not supposed to modify the
389 // menu during "show"
390 g_signal_connect(history_menu_, "about-to-show",
391 G_CALLBACK(OnHistoryMenuAboutToShowThunk), this);
267 392
268 for (CommandIDMenuItemMap::const_iterator it = id_to_menu_item_.begin(); 393 for (CommandIDMenuItemMap::const_iterator it = id_to_menu_item_.begin();
269 it != id_to_menu_item_.end(); ++it) { 394 it != id_to_menu_item_.end(); ++it) {
270 menuitem_property_set_bool(it->second, kPropertyEnabled, 395 menuitem_property_set_bool(it->second, kPropertyEnabled,
271 chrome::IsCommandEnabled(browser_, it->first)); 396 chrome::IsCommandEnabled(browser_, it->first));
272 397
273 ui::Accelerator accelerator; 398 ui::Accelerator accelerator;
274 if (browser_view_->GetAccelerator(it->first, &accelerator)) 399 if (browser_view_->GetAccelerator(it->first, &accelerator))
275 RegisterAccelerator(it->second, accelerator); 400 RegisterAccelerator(it->second, accelerator);
276 401
277 chrome::AddCommandObserver(browser_, it->first, this); 402 chrome::AddCommandObserver(browser_, it->first, this);
278 } 403 }
279 404
280 pref_change_registrar_.Init(browser_->profile()->GetPrefs()); 405 pref_change_registrar_.Init(browser_->profile()->GetPrefs());
281 pref_change_registrar_.Add( 406 pref_change_registrar_.Add(
282 prefs::kShowBookmarkBar, 407 prefs::kShowBookmarkBar,
283 base::Bind(&GlobalMenuBarX11::OnBookmarkBarVisibilityChanged, 408 base::Bind(&GlobalMenuBarX11::OnBookmarkBarVisibilityChanged,
284 base::Unretained(this))); 409 base::Unretained(this)));
285 OnBookmarkBarVisibilityChanged(); 410 OnBookmarkBarVisibilityChanged();
286 411
412 top_sites_ = profile_->GetTopSites();
413 if (top_sites_) {
414 GetTopSitesData();
415
416 // Register for notification when TopSites changes so that we can update
417 // ourself.
418 registrar_.Add(this, chrome::NOTIFICATION_TOP_SITES_CHANGED,
419 content::Source<history::TopSites>(top_sites_));
420 }
421
287 server_set_root(server_, root_item_); 422 server_set_root(server_, root_item_);
288 } 423 }
289 424
290 void GlobalMenuBarX11::Disable() { 425 void GlobalMenuBarX11::Disable() {
291 for (CommandIDMenuItemMap::const_iterator it = id_to_menu_item_.begin(); 426 for (CommandIDMenuItemMap::const_iterator it = id_to_menu_item_.begin();
292 it != id_to_menu_item_.end(); ++it) { 427 it != id_to_menu_item_.end(); ++it) {
293 chrome::RemoveCommandObserver(browser_, it->first, this); 428 chrome::RemoveCommandObserver(browser_, it->first, this);
294 } 429 }
295 id_to_menu_item_.clear(); 430 id_to_menu_item_.clear();
296 431
297 pref_change_registrar_.RemoveAll(); 432 pref_change_registrar_.RemoveAll();
298 } 433 }
299 434
300 void GlobalMenuBarX11::BuildMenuFrom( 435 DbusmenuMenuitem* GlobalMenuBarX11::BuildStaticMenu(
301 DbusmenuMenuitem* parent, 436 DbusmenuMenuitem* parent,
302 int menu_str_id, 437 int menu_str_id,
303 std::map<int, DbusmenuMenuitem*>* id_to_menu_item,
304 GlobalMenuBarCommand* commands) { 438 GlobalMenuBarCommand* commands) {
305 DbusmenuMenuitem* top = menuitem_new(); 439 DbusmenuMenuitem* top = menuitem_new();
306 menuitem_property_set( 440 menuitem_property_set(
307 top, kPropertyLabel, 441 top, kPropertyLabel,
308 ui::RemoveWindowsStyleAccelerators( 442 ui::RemoveWindowsStyleAccelerators(
309 l10n_util::GetStringUTF8(menu_str_id)).c_str()); 443 l10n_util::GetStringUTF8(menu_str_id)).c_str());
310 menuitem_property_set_bool(top, kPropertyVisible, true); 444 menuitem_property_set_bool(top, kPropertyVisible, true);
311 445
312 for (int i = 0; commands[i].str_id != MENU_END; ++i) { 446 for (int i = 0; commands[i].str_id != MENU_END; ++i) {
313 DbusmenuMenuitem* menu_item = BuildMenuItem( 447 DbusmenuMenuitem* menu_item = NULL;
314 commands[i].str_id, commands[i].command, commands[i].tag, 448 int command_id = commands[i].command;
315 id_to_menu_item); 449 if (commands[i].str_id == MENU_SEPARATOR) {
450 menu_item = BuildSeparator();
451 } else {
452 std::string label = ui::ConvertAcceleratorsFromWindowsStyle(
453 l10n_util::GetStringUTF8(commands[i].str_id));
454
455 menu_item = BuildMenuItem(label, commands[i].tag);
456
457 if (command_id == MENU_DISABLED_ID) {
458 menuitem_property_set_bool(menu_item, kPropertyEnabled, false);
459 } else {
460 if (command_id == IDC_SHOW_BOOKMARK_BAR)
461 menuitem_property_set(menu_item, kPropertyToggleType, kTypeCheckmark);
462
463 id_to_menu_item_.insert(std::make_pair(command_id, menu_item));
464 g_object_set_data(G_OBJECT(menu_item), "command-id",
465 GINT_TO_POINTER(command_id));
466 g_signal_connect(menu_item, "item-activated",
467 G_CALLBACK(OnItemActivatedThunk), this);
468 }
469 }
470
316 menuitem_child_append(top, menu_item); 471 menuitem_child_append(top, menu_item);
317 } 472 }
318 473
319 menuitem_child_append(parent, top); 474 menuitem_child_append(parent, top);
320 } 475 return top;
321
322 DbusmenuMenuitem* GlobalMenuBarX11::BuildMenuItem(
323 int string_id,
324 int command_id,
325 int tag_id,
326 std::map<int, DbusmenuMenuitem*>* id_to_menu_item) {
327 DbusmenuMenuitem* item = menuitem_new();
328
329 if (string_id == MENU_SEPARATOR) {
330 menuitem_property_set(item, kPropertyType, kTypeSeparator);
331 } else {
332 std::string label = ui::ConvertAcceleratorsFromWindowsStyle(
333 l10n_util::GetStringUTF8(string_id));
334 menuitem_property_set(item, kPropertyLabel, label.c_str());
335
336 if (command_id == IDC_SHOW_BOOKMARK_BAR)
337 menuitem_property_set(item, kPropertyToggleType, kTypeCheckmark);
338
339 if (tag_id)
340 g_object_set_data(G_OBJECT(item), "type-tag", GINT_TO_POINTER(tag_id));
341
342 if (command_id == MENU_DISABLED_LABEL) {
343 menuitem_property_set_bool(item, kPropertyEnabled, false);
344 } else {
345 id_to_menu_item->insert(std::make_pair(command_id, item));
346 g_object_set_data(G_OBJECT(item), "command-id",
347 GINT_TO_POINTER(command_id));
348 g_signal_connect(item, "item-activated",
349 G_CALLBACK(OnItemActivatedThunk), this);
350 }
351 }
352
353 menuitem_property_set_bool(item, kPropertyVisible, true);
354 return item;
355 } 476 }
356 477
357 void GlobalMenuBarX11::RegisterAccelerator(DbusmenuMenuitem* item, 478 void GlobalMenuBarX11::RegisterAccelerator(DbusmenuMenuitem* item,
358 const ui::Accelerator& accelerator) { 479 const ui::Accelerator& accelerator) {
359 // A translation of libdbusmenu-gtk's menuitem_property_set_shortcut() 480 // A translation of libdbusmenu-gtk's menuitem_property_set_shortcut()
360 // translated from GDK types to ui::Accelerator types. 481 // translated from GDK types to ui::Accelerator types.
361 GVariantBuilder builder; 482 GVariantBuilder builder;
362 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); 483 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
363 484
364 if (accelerator.IsCtrlDown()) 485 if (accelerator.IsCtrlDown())
(...skipping 12 matching lines...) Expand all
377 g_variant_builder_add(&builder, "s", name); 498 g_variant_builder_add(&builder, "s", name);
378 499
379 GVariant* inside_array = g_variant_builder_end(&builder); 500 GVariant* inside_array = g_variant_builder_end(&builder);
380 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); 501 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
381 g_variant_builder_add_value(&builder, inside_array); 502 g_variant_builder_add_value(&builder, inside_array);
382 GVariant* outside_array = g_variant_builder_end(&builder); 503 GVariant* outside_array = g_variant_builder_end(&builder);
383 504
384 menuitem_property_set_variant(item, kPropertyShortcut, outside_array); 505 menuitem_property_set_variant(item, kPropertyShortcut, outside_array);
385 } 506 }
386 507
508 GlobalMenuBarX11::HistoryItem* GlobalMenuBarX11::HistoryItemForMenuItem(
509 DbusmenuMenuitem* menu_item) {
510 MenuItemToHistoryMap::iterator it = menu_item_history_map_.find(menu_item);
511 return it != menu_item_history_map_.end() ? it->second : NULL;
512 }
513
514 GlobalMenuBarX11::HistoryItem* GlobalMenuBarX11::HistoryItemForTab(
515 const TabRestoreService::Tab& entry) {
sadrul 2013/08/09 06:38:54 This could be a separate function in the anonymous
Elliot Glaysher 2013/08/09 20:19:25 It actually can't without making HistoryItem publi
516 const sessions::SerializedNavigationEntry& current_navigation =
517 entry.navigations.at(entry.current_navigation_index);
518 HistoryItem* item = new HistoryItem();
519 item->title = current_navigation.title();
520 item->url = current_navigation.virtual_url();
521 item->session_id = entry.id;
522
523 return item;
524 }
525
526 void GlobalMenuBarX11::AddHistoryItemToMenu(HistoryItem* item,
527 DbusmenuMenuitem* menu,
528 int tag,
529 int index) {
530 string16 title = item->title;
531 std::string url_string = item->url.possibly_invalid_spec();
532
533 if (title.empty())
534 title = UTF8ToUTF16(url_string);
535 ui::ElideString(title, kMaximumMenuWidthInChars, &title);
536
537 DbusmenuMenuitem* menu_item = BuildMenuItem(UTF16ToUTF8(title), tag);
538 g_signal_connect(menu_item, "item-activated",
539 G_CALLBACK(OnHistoryItemActivatedThunk), this);
540
541 menu_item_history_map_.insert(std::make_pair(menu_item, item));
sadrul 2013/08/09 06:38:54 Instead of using the map, can you use g_object_set
Elliot Glaysher 2013/08/09 20:19:25 This is a really good point. I forgot that you cou
542 menuitem_child_add_position(menu, menu_item, index);
543 }
544
545 void GlobalMenuBarX11::GetTopSitesData() {
546 DCHECK(top_sites_);
547
548 top_sites_->GetMostVisitedURLs(
549 base::Bind(&GlobalMenuBarX11::OnTopSitesReceived,
550 weak_ptr_factory_.GetWeakPtr()));
551 }
552
553 void GlobalMenuBarX11::OnTopSitesReceived(
554 const history::MostVisitedURLList& visited_list) {
555 ClearMenuSection(history_menu_, GlobalMenuBarX11::TAG_MOST_VISITED);
556
557 int index = GetIndexOfMenuItemWithTag(
558 history_menu_,
559 GlobalMenuBarX11::TAG_MOST_VISITED_HEADER) + 1;
560
561 for (size_t i = 0; i < visited_list.size() && i < kMostVisitedCount; ++i) {
562 const history::MostVisitedURL& visited = visited_list[i];
563 if (visited.url.spec().empty())
564 break; // This is the signal that there are no more real visited sites.
565
566 HistoryItem* item = new HistoryItem();
567 item->title = visited.title;
568 item->url = visited.url;
569
570 AddHistoryItemToMenu(item,
571 history_menu_,
572 GlobalMenuBarX11::TAG_MOST_VISITED,
573 index++);
574 }
575 }
576
387 void GlobalMenuBarX11::OnBookmarkBarVisibilityChanged() { 577 void GlobalMenuBarX11::OnBookmarkBarVisibilityChanged() {
388 CommandIDMenuItemMap::iterator it = 578 CommandIDMenuItemMap::iterator it =
389 id_to_menu_item_.find(IDC_SHOW_BOOKMARK_BAR); 579 id_to_menu_item_.find(IDC_SHOW_BOOKMARK_BAR);
390 if (it != id_to_menu_item_.end()) { 580 if (it != id_to_menu_item_.end()) {
391 PrefService* prefs = browser_->profile()->GetPrefs(); 581 PrefService* prefs = browser_->profile()->GetPrefs();
392 // Note: Unlike the GTK version, we don't appear to need to do tricks where 582 // Note: Unlike the GTK version, we don't appear to need to do tricks where
393 // we block activation while setting the toggle. 583 // we block activation while setting the toggle.
394 menuitem_property_set_int(it->second, kPropertyToggleState, 584 menuitem_property_set_int(it->second, kPropertyToggleState,
395 prefs->GetBoolean(prefs::kShowBookmarkBar)); 585 prefs->GetBoolean(prefs::kShowBookmarkBar));
396 } 586 }
397 } 587 }
398 588
589 int GlobalMenuBarX11::GetIndexOfMenuItemWithTag(DbusmenuMenuitem* menu,
590 int tag_id) {
591 GList* childs = menuitem_get_children(menu);
sadrul 2013/08/09 06:38:54 childs
592 int i = 0;
593 for (; childs != NULL; childs = childs->next, i++) {
594 int tag =
595 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(childs->data), "type-tag"));
596 if (tag == tag_id)
597 return i;
598 }
599
600 NOTREACHED();
601 return -1;
602 }
603
604 void GlobalMenuBarX11::ClearMenuSection(DbusmenuMenuitem* menu, int tag_id) {
605 std::vector<DbusmenuMenuitem*> menuitems_to_delete;
606
607 GList* childs = menuitem_get_children(menu);
608 for (; childs != NULL; childs = childs->next) {
609 DbusmenuMenuitem* current_item = reinterpret_cast<DbusmenuMenuitem*>(
610 childs->data);
611 ClearMenuSection(current_item, tag_id);
612
613 int tag =
614 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(childs->data), "type-tag"));
615 if (tag == tag_id)
616 menuitems_to_delete.push_back(current_item);
617 }
618
619 for (std::vector<DbusmenuMenuitem*>::const_iterator it =
620 menuitems_to_delete.begin(); it != menuitems_to_delete.end(); ++it) {
621 HistoryItem* item = HistoryItemForMenuItem(*it);
622 if (item) {
623 menu_item_history_map_.erase(*it);
624 delete item;
625 }
626
627 menuitem_child_delete(menu, *it);
628 }
629 }
630
399 void GlobalMenuBarX11::EnabledStateChangedForCommand(int id, bool enabled) { 631 void GlobalMenuBarX11::EnabledStateChangedForCommand(int id, bool enabled) {
400 CommandIDMenuItemMap::iterator it = id_to_menu_item_.find(id); 632 CommandIDMenuItemMap::iterator it = id_to_menu_item_.find(id);
401 if (it != id_to_menu_item_.end()) 633 if (it != id_to_menu_item_.end())
402 menuitem_property_set_bool(it->second, kPropertyEnabled, enabled); 634 menuitem_property_set_bool(it->second, kPropertyEnabled, enabled);
403 } 635 }
404 636
637 void GlobalMenuBarX11::Observe(int type,
638 const content::NotificationSource& source,
639 const content::NotificationDetails& details) {
640 if (type == chrome::NOTIFICATION_TOP_SITES_CHANGED) {
641 GetTopSitesData();
642 } else {
643 NOTREACHED();
644 }
645 }
646
647 void GlobalMenuBarX11::TabRestoreServiceChanged(TabRestoreService* service) {
648 const TabRestoreService::Entries& entries = service->entries();
649
650 ClearMenuSection(history_menu_, GlobalMenuBarX11::TAG_RECENTLY_CLOSED);
651
652 // We'll get the index the "Recently Closed" header. (This can vary depending
653 // on the number of "Most Visited" items.
654 int index = GetIndexOfMenuItemWithTag(
655 history_menu_,
656 GlobalMenuBarX11::TAG_RECENTLY_CLOSED_HEADER) + 1;
657
658 unsigned int added_count = 0;
659 for (TabRestoreService::Entries::const_iterator it = entries.begin();
660 it != entries.end() && added_count < kRecentlyClosedCount; ++it) {
661 TabRestoreService::Entry* entry = *it;
662
663 if (entry->type == TabRestoreService::WINDOW) {
664 TabRestoreService::Window* entry_win =
665 static_cast<TabRestoreService::Window*>(entry);
666 std::vector<TabRestoreService::Tab>& tabs = entry_win->tabs;
667 if (tabs.empty())
668 continue;
669
670 // Create the item for the parent/window.
671 HistoryItem* item = new HistoryItem();
672 item->session_id = entry_win->id;
673
674 std::string title = item->tabs.size() == 1 ?
675 l10n_util::GetStringUTF8(
676 IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_SINGLE) :
677 l10n_util::GetStringFUTF8(
678 IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_MULTIPLE,
679 base::IntToString16(item->tabs.size()));
680 DbusmenuMenuitem* parent_item = BuildMenuItem(
681 title, GlobalMenuBarX11::TAG_RECENTLY_CLOSED);
682 menuitem_child_add_position(history_menu_, parent_item, index++);
683
684 // The mac version of this code allows the user to click on the parent
685 // menu item to have the same effect as clicking the restore window
686 // submenu item. GTK+ helpfully activates a menu item when it shows a
687 // submenu so toss that feature out.
688 DbusmenuMenuitem* restore_item = BuildMenuItem(
689 l10n_util::GetStringUTF8(
690 IDS_HISTORY_CLOSED_RESTORE_WINDOW_LINUX).c_str(),
691 GlobalMenuBarX11::TAG_RECENTLY_CLOSED);
692 g_signal_connect(restore_item, "item-activated",
693 G_CALLBACK(OnHistoryItemActivatedThunk), this);
694 menu_item_history_map_.insert(std::make_pair(restore_item, item));
695 menuitem_child_append(parent_item, restore_item);
696
697 menuitem_child_append(parent_item, BuildSeparator());
698
699 // Loop over the window's tabs and add them to the submenu.
700 int subindex = 2;
701 std::vector<TabRestoreService::Tab>::const_iterator iter;
702 for (iter = tabs.begin(); iter != tabs.end(); ++iter) {
703 TabRestoreService::Tab tab = *iter;
704 HistoryItem* tab_item = HistoryItemForTab(tab);
705 item->tabs.push_back(tab_item);
706 AddHistoryItemToMenu(tab_item,
707 parent_item,
708 GlobalMenuBarX11::TAG_RECENTLY_CLOSED,
709 subindex++);
710 }
711
712 ++added_count;
713 } else if (entry->type == TabRestoreService::TAB) {
714 TabRestoreService::Tab* tab = static_cast<TabRestoreService::Tab*>(entry);
715 HistoryItem* item = HistoryItemForTab(*tab);
716 AddHistoryItemToMenu(item,
717 history_menu_,
718 GlobalMenuBarX11::TAG_RECENTLY_CLOSED,
719 index++);
720 ++added_count;
721 }
722 }
723 }
724
725 void GlobalMenuBarX11::TabRestoreServiceDestroyed(
726 TabRestoreService* service) {
727 tab_restore_service_ = NULL;
728 }
729
405 void GlobalMenuBarX11::OnWindowMapped(unsigned long xid) { 730 void GlobalMenuBarX11::OnWindowMapped(unsigned long xid) {
406 if (!server_) 731 if (!server_)
407 InitServer(xid); 732 InitServer(xid);
408 733
409 GlobalMenuBarRegistrarX11::GetInstance()->OnWindowMapped(xid); 734 GlobalMenuBarRegistrarX11::GetInstance()->OnWindowMapped(xid);
410 } 735 }
411 736
412 void GlobalMenuBarX11::OnWindowUnmapped(unsigned long xid) { 737 void GlobalMenuBarX11::OnWindowUnmapped(unsigned long xid) {
413 GlobalMenuBarRegistrarX11::GetInstance()->OnWindowUnmapped(xid); 738 GlobalMenuBarRegistrarX11::GetInstance()->OnWindowUnmapped(xid);
414 } 739 }
415 740
416 void GlobalMenuBarX11::OnItemActivated(DbusmenuMenuitem* item, 741 void GlobalMenuBarX11::OnItemActivated(DbusmenuMenuitem* item,
417 unsigned int timestamp) { 742 unsigned int timestamp) {
418 int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "command-id")); 743 int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "command-id"));
419 chrome::ExecuteCommand(browser_, id); 744 chrome::ExecuteCommand(browser_, id);
420 } 745 }
746
747 void GlobalMenuBarX11::OnHistoryItemActivated(DbusmenuMenuitem* sender,
748 unsigned int timestamp) {
749 // Note: We don't have access to the event modifiers used to click the menu
750 // item since that happens in a different process.
751 HistoryItem* item = HistoryItemForMenuItem(sender);
752
753 // If this item can be restored using TabRestoreService, do so. Otherwise,
754 // just load the URL.
755 TabRestoreService* service =
756 TabRestoreServiceFactory::GetForProfile(profile_);
757 if (item->session_id && service) {
758 service->RestoreEntryById(browser_->tab_restore_service_delegate(),
759 item->session_id, browser_->host_desktop_type(),
760 UNKNOWN);
761 } else {
762 DCHECK(item->url.is_valid());
763 browser_->OpenURL(content::OpenURLParams(
764 item->url,
765 content::Referrer(),
766 NEW_FOREGROUND_TAB,
767 content::PAGE_TRANSITION_AUTO_BOOKMARK,
768 false));
769 }
770 }
771
772 void GlobalMenuBarX11::OnHistoryMenuAboutToShow(DbusmenuMenuitem* item) {
773 if (!tab_restore_service_) {
774 tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile_);
775 if (tab_restore_service_) {
776 tab_restore_service_->LoadTabsFromLastSession();
777 tab_restore_service_->AddObserver(this);
sadrul 2013/08/09 06:38:54 Should AddObserver() happen before LoadTabsFromLas
Elliot Glaysher 2013/08/09 20:19:25 I think so. All other cases I could find ordered t
778
779 // If LoadTabsFromLastSession doesn't load tabs, it won't call
780 // TabRestoreServiceChanged(). This ensures that all new windows after
781 // the first one will have their menus populated correctly.
782 TabRestoreServiceChanged(tab_restore_service_);
783 }
784 }
785 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698