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

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

Powered by Google App Engine
This is Rietveld 408576698