global_menu_bar_x11.h revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_GLOBAL_MENU_BAR_X11_H_
6#define CHROME_BROWSER_UI_VIEWS_FRAME_GLOBAL_MENU_BAR_X11_H_
7
8#include <map>
9#include <string>
10
11#include "base/compiler_specific.h"
12#include "base/memory/weak_ptr.h"
13#include "base/prefs/pref_change_registrar.h"
14#include "chrome/browser/command_observer.h"
15#include "chrome/browser/history/history_types.h"
16#include "chrome/browser/sessions/tab_restore_service.h"
17#include "chrome/browser/sessions/tab_restore_service_observer.h"
18#include "content/public/browser/notification_observer.h"
19#include "content/public/browser/notification_registrar.h"
20#include "ui/base/glib/glib_signal.h"
21#include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h"
22
23typedef struct _DbusmenuMenuitem DbusmenuMenuitem;
24typedef struct _DbusmenuServer   DbusmenuServer;
25
26namespace history {
27class TopSites;
28}
29
30namespace ui {
31class Accelerator;
32}
33
34class Browser;
35class BrowserView;
36class Profile;
37
38class BrowserDesktopWindowTreeHostX11;
39struct GlobalMenuBarCommand;
40
41// Controls the Mac style menu bar on Unity.
42//
43// Unity has an Apple-like menu bar at the top of the screen that changes
44// depending on the active window. In the GTK port, we had a hidden GtkMenuBar
45// object in each GtkWindow which existed only to be scrapped by the
46// libdbusmenu-gtk code. Since we don't have GtkWindows anymore, we need to
47// interface directly with the lower level libdbusmenu-glib, which we
48// opportunistically dlopen() since not everyone is running Ubuntu.
49class GlobalMenuBarX11 : public CommandObserver,
50                         public content::NotificationObserver,
51                         public TabRestoreServiceObserver,
52                         public views::DesktopWindowTreeHostObserverX11 {
53 public:
54  GlobalMenuBarX11(BrowserView* browser_view,
55                   BrowserDesktopWindowTreeHostX11* host);
56  virtual ~GlobalMenuBarX11();
57
58  // Creates the object path for DbusemenuServer which is attached to |xid|.
59  static std::string GetPathForWindow(unsigned long xid);
60
61 private:
62  struct HistoryItem;
63  typedef std::map<int, DbusmenuMenuitem*> CommandIDMenuItemMap;
64
65  // Builds a separator.
66  DbusmenuMenuitem* BuildSeparator();
67
68  // Creates an individual menu item from a title and command, and subscribes
69  // to the activation signal.
70  DbusmenuMenuitem* BuildMenuItem(const std::string& label, int tag_id);
71
72  // Creates a DbusmenuServer, and attaches all the menu items.
73  void InitServer(unsigned long xid);
74
75  // Stops listening to enable state changed events.
76  void Disable();
77
78  // Creates a whole menu defined with |commands| and titled with the string
79  // |menu_str_id|. Then appends it to |parent|.
80  DbusmenuMenuitem* BuildStaticMenu(DbusmenuMenuitem* parent,
81                                    int menu_str_id,
82                                    GlobalMenuBarCommand* commands);
83
84  // Sets the accelerator for |item|.
85  void RegisterAccelerator(DbusmenuMenuitem* item,
86                           const ui::Accelerator& accelerator);
87
88  // Creates a HistoryItem from the data in |entry|.
89  HistoryItem* HistoryItemForTab(const TabRestoreService::Tab& entry);
90
91  // Creates a menu item form |item| and inserts it in |menu| at |index|.
92  void AddHistoryItemToMenu(HistoryItem* item,
93                            DbusmenuMenuitem* menu,
94                            int tag,
95                            int index);
96
97  // Sends a message off to History for data.
98  void GetTopSitesData();
99
100  // Callback to receive data requested from GetTopSitesData().
101  void OnTopSitesReceived(const history::MostVisitedURLList& visited_list);
102
103  // Updates the visibility of the bookmark bar on pref changes.
104  void OnBookmarkBarVisibilityChanged();
105
106  // Find the first index of the item in |menu| with the tag |tag_id|.
107  int GetIndexOfMenuItemWithTag(DbusmenuMenuitem* menu, int tag_id);
108
109  // This will remove all menu items in |menu| with |tag| as their tag. This
110  // clears state about HistoryItems* that we keep to prevent that data from
111  // going stale. That's why this method recurses into its child menus.
112  void ClearMenuSection(DbusmenuMenuitem* menu, int tag_id);
113
114  // Deleter function for HistoryItem implementation detail.
115  static void DeleteHistoryItem(void* void_item);
116
117  // Overridden from CommandObserver:
118  virtual void EnabledStateChangedForCommand(int id, bool enabled) OVERRIDE;
119
120  // Overridden from content::NotificationObserver:
121  virtual void Observe(int type,
122                       const content::NotificationSource& source,
123                       const content::NotificationDetails& details) OVERRIDE;
124
125  // Overridden from TabRestoreServiceObserver:
126  virtual void TabRestoreServiceChanged(TabRestoreService* service) OVERRIDE;
127  virtual void TabRestoreServiceDestroyed(TabRestoreService* service) OVERRIDE;
128
129  // Overridden from views::DesktopWindowTreeHostObserverX11:
130  virtual void OnWindowMapped(unsigned long xid) OVERRIDE;
131  virtual void OnWindowUnmapped(unsigned long xid) OVERRIDE;
132
133  CHROMEG_CALLBACK_1(GlobalMenuBarX11, void, OnItemActivated, DbusmenuMenuitem*,
134                     unsigned int);
135  CHROMEG_CALLBACK_1(GlobalMenuBarX11, void, OnHistoryItemActivated,
136                     DbusmenuMenuitem*, unsigned int);
137  CHROMEG_CALLBACK_0(GlobalMenuBarX11, void, OnHistoryMenuAboutToShow,
138                     DbusmenuMenuitem*);
139
140  Browser* browser_;
141  Profile* profile_;
142  BrowserView* browser_view_;
143  BrowserDesktopWindowTreeHostX11* host_;
144
145  // Maps command ids to DbusmenuMenuitems so we can modify their
146  // enabled/checked state in response to state change notifications.
147  CommandIDMenuItemMap id_to_menu_item_;
148
149  DbusmenuServer* server_;
150  DbusmenuMenuitem* root_item_;
151  DbusmenuMenuitem* history_menu_;
152
153  // Tracks value of the kShowBookmarkBar preference.
154  PrefChangeRegistrar pref_change_registrar_;
155
156  history::TopSites* top_sites_;
157
158  TabRestoreService* tab_restore_service_;  // weak
159
160  content::NotificationRegistrar registrar_;
161
162  // For callbacks may be run after destruction.
163  base::WeakPtrFactory<GlobalMenuBarX11> weak_ptr_factory_;
164
165  DISALLOW_COPY_AND_ASSIGN(GlobalMenuBarX11);
166};
167
168#endif  // CHROME_BROWSER_UI_VIEWS_FRAME_GLOBAL_MENU_BAR_X11_H_
169