global_menu_bar_x11.h revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_GLOBAL_MENU_BAR_X11_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_VIEWS_FRAME_GLOBAL_MENU_BAR_X11_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/prefs/pref_change_registrar.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/command_observer.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/common/cancelable_request.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_types.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service_observer.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/glib/glib_signal.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_root_window_host_observer_x11.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _DbusmenuMenuitem DbusmenuMenuitem;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _DbusmenuServer   DbusmenuServer;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace history {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TopSites;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Accelerator;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Browser;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowserView;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Profile;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowserDesktopRootWindowHostX11;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GlobalMenuBarCommand;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Controls the Mac style menu bar on Unity.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Unity has an Apple-like menu bar at the top of the screen that changes
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// depending on the active window. In the GTK port, we had a hidden GtkMenuBar
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object in each GtkWindow which existed only to be scrapped by the
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// libdbusmenu-gtk code. Since we don't have GtkWindows anymore, we need to
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interface directly with the lower level libdbusmenu-glib, which we
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// opportunistically dlopen() since not everyone is running Ubuntu.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GlobalMenuBarX11 : public CommandObserver,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         public content::NotificationObserver,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         public TabRestoreServiceObserver,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         public views::DesktopRootWindowHostObserverX11 {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalMenuBarX11(BrowserView* browser_view,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   BrowserDesktopRootWindowHostX11* host);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~GlobalMenuBarX11();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates the object path for DbusemenuServer which is attached to |xid|.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string GetPathForWindow(unsigned long xid);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct HistoryItem;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<int, DbusmenuMenuitem*> CommandIDMenuItemMap;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Builds a separator.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbusmenuMenuitem* BuildSeparator();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates an individual menu item from a title and command, and subscribes
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the activation signal.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbusmenuMenuitem* BuildMenuItem(const std::string& label, int tag_id);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a DbusmenuServer, and attaches all the menu items.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitServer(unsigned long xid);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stops listening to enable state changed events.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Disable();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a whole menu defined with |commands| and titled with the string
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |menu_str_id|. Then appends it to |parent|.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbusmenuMenuitem* BuildStaticMenu(DbusmenuMenuitem* parent,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int menu_str_id,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    GlobalMenuBarCommand* commands);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the accelerator for |item|.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterAccelerator(DbusmenuMenuitem* item,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const ui::Accelerator& accelerator);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a HistoryItem from the data in |entry|.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryItem* HistoryItemForTab(const TabRestoreService::Tab& entry);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a menu item form |item| and inserts it in |menu| at |index|.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddHistoryItemToMenu(HistoryItem* item,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            DbusmenuMenuitem* menu,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int tag,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int index);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sends a message off to History for data.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GetTopSitesData();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback to receive data requested from GetTopSitesData().
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnTopSitesReceived(const history::MostVisitedURLList& visited_list);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates the visibility of the bookmark bar on pref changes.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnBookmarkBarVisibilityChanged();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find the first index of the item in |menu| with the tag |tag_id|.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetIndexOfMenuItemWithTag(DbusmenuMenuitem* menu, int tag_id);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will remove all menu items in |menu| with |tag| as their tag. This
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clears state about HistoryItems* that we keep to prevent that data from
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // going stale. That's why this method recurses into its child menus.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearMenuSection(DbusmenuMenuitem* menu, int tag_id);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deleter function for HistoryItem implementation detail.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DeleteHistoryItem(void* void_item);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from CommandObserver:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EnabledStateChangedForCommand(int id, bool enabled) OVERRIDE;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from content::NotificationObserver:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from TabRestoreServiceObserver:
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TabRestoreServiceChanged(TabRestoreService* service) OVERRIDE;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TabRestoreServiceDestroyed(TabRestoreService* service) OVERRIDE;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from views::DesktopRootWindowHostObserverX11:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowMapped(unsigned long xid) OVERRIDE;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowUnmapped(unsigned long xid) OVERRIDE;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROMEG_CALLBACK_1(GlobalMenuBarX11, void, OnItemActivated, DbusmenuMenuitem*,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     unsigned int);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROMEG_CALLBACK_1(GlobalMenuBarX11, void, OnHistoryItemActivated,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     DbusmenuMenuitem*, unsigned int);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROMEG_CALLBACK_0(GlobalMenuBarX11, void, OnHistoryMenuAboutToShow,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     DbusmenuMenuitem*);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* browser_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserView* browser_view_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserDesktopRootWindowHostX11* host_;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Maps command ids to DbusmenuMenuitems so we can modify their
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // enabled/checked state in response to state change notifications.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandIDMenuItemMap id_to_menu_item_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbusmenuServer* server_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbusmenuMenuitem* root_item_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbusmenuMenuitem* history_menu_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tracks value of the kShowBookmarkBar preference.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefChangeRegistrar pref_change_registrar_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::TopSites* top_sites_;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabRestoreService* tab_restore_service_;  // weak
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For callbacks may be run after destruction.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<GlobalMenuBarX11> weak_ptr_factory_;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GlobalMenuBarX11);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_VIEWS_FRAME_GLOBAL_MENU_BAR_X11_H_
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)