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

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

Powered by Google App Engine
This is Rietveld 408576698