Skip to content

Commit

Permalink
Add Unity/Global Menu support
Browse files Browse the repository at this point in the history
Thanks for Ubuntu Mozilla Team 😄
  • Loading branch information
hawkeye116477 authored and Alex Kontos committed Nov 15, 2019
1 parent 4002bfa commit eefb998
Show file tree
Hide file tree
Showing 34 changed files with 5,011 additions and 6 deletions.
4 changes: 4 additions & 0 deletions browser/base/content/browser-menubar.inc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

<menubar id="main-menubar"
onpopupshowing="if (event.target.parentNode.parentNode == this &amp;&amp;
#ifdef MOZ_WIDGET_GTK
document.documentElement.getAttribute('shellshowingmenubar') != 'true')
#else
!('@mozilla.org/widget/nativemenuservice;1' in Cc))
#endif
this.setAttribute('openedwithkey',
event.target.parentNode.openedWithKey);">
<menu id="file-menu" label="&fileMenu.label;"
Expand Down
6 changes: 6 additions & 0 deletions browser/base/content/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7013,11 +7013,17 @@ function onViewToolbarsPopupShowing(aEvent, aInsertPoint) {

let toolbarNodes = gNavToolbox.querySelectorAll("toolbar");

let shellShowingMenubar = document.documentElement.getAttribute("shellshowingmenubar") == "true";

for (let toolbar of toolbarNodes) {
if (!toolbar.hasAttribute("toolbarname")) {
continue;
}

if (shellShowingMenubar && toolbar.id == "toolbar-menubar") {
continue;
}

let menuItem = document.createXULElement("menuitem");
let hidingAttribute =
toolbar.getAttribute("type") == "menubar" ? "autohide" : "collapsed";
Expand Down
2 changes: 1 addition & 1 deletion browser/components/places/content/places.xul
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
<toolbarbutton type="menu" class="tabbable"
onpopupshowing="document.getElementById('placeContent').focus()"
#else
<menubar id="placesMenu">
<menubar id="placesMenu" _moz-menubarkeeplocal="true">
<menu accesskey="&organize.accesskey;" class="menu-iconic"
#endif
id="organizeButton" label="&organize.label;"
Expand Down
9 changes: 9 additions & 0 deletions dom/xul/XULPopupElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ void XULPopupElement::GetState(nsString& aState) {
// set this here in case there's no frame for the popup
aState.AssignLiteral("closed");

#ifdef MOZ_WIDGET_GTK
nsAutoString nativeState;
#endif

nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetPrimaryFrame());
if (menuPopupFrame) {
switch (menuPopupFrame->PopupState()) {
Expand All @@ -179,6 +183,11 @@ void XULPopupElement::GetState(nsString& aState) {
break;
}
}
#ifdef MOZ_WIDGET_GTK
else if (GetAttr(kNameSpaceID_None, nsGkAtoms::_moz_nativemenupopupstate, nativeState)) {
aState = nativeState;
}
#endif
}

nsINode* XULPopupElement::GetTriggerNode() const {
Expand Down
5 changes: 5 additions & 0 deletions dom/xul/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ LOCAL_INCLUDES += [

include('/ipc/chromium/chromium-config.mozbuild')

if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
LOCAL_INCLUDES += [
'/widget/gtk',
]

FINAL_LIBRARY = 'xul'

if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
Expand Down
4 changes: 4 additions & 0 deletions layout/build/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
'/dom/system',
'/dom/system/android',
]
elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
LOCAL_INCLUDES += [
'/widget/gtk',
]

XPCOM_MANIFESTS += [
'components.conf',
Expand Down
3 changes: 3 additions & 0 deletions modules/libpref/init/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ pref("dom.window.event.enabled", true);
pref("browser.sessionhistory.max_total_viewers", -1);

pref("ui.use_native_colors", true);
#ifdef MOZ_WIDGET_GTK
pref("ui.use_unity_menubar", true);
#endif
pref("ui.click_hold_context_menus", false);
// 0 = false, 1 = true, 2 = autodetect.
pref("ui.android.mouse_as_touch", 1);
Expand Down
12 changes: 12 additions & 0 deletions toolkit/content/xul.css
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,18 @@ toolbar[type="menubar"] {
}
%endif

%ifdef MOZ_WIDGET_GTK
window[shellshowingmenubar="true"] menubar {
display: none !important;
}

window[shellshowingmenubar="true"]
toolbar[type="menubar"]:not([customizing="true"]) {
min-height: 0 !important;
border: 0 !important;
}
%endif

toolbarspring {
-moz-box-flex: 1000;
}
Expand Down
8 changes: 8 additions & 0 deletions widget/gtk/components.conf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ Classes = [
'headers': ['/widget/gtk/nsApplicationChooser.h'],
'processes': ProcessSelector.MAIN_PROCESS_ONLY,
},
{
'cid': '{0B3FE5AA-BC72-4303-85AE-76365DF1251D}',
'contract_ids': ['@mozilla.org/widget/nativemenuservice;1'],
'singleton': True,
'type': 'nsNativeMenuService',
'constructor': 'nsNativeMenuService::GetInstanceForServiceManager',
'headers': ['/widget/gtk/nsNativeMenuService.h'],
},
]

if defined('MOZ_X11'):
Expand Down
10 changes: 10 additions & 0 deletions widget/gtk/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ UNIFIED_SOURCES += [
]

SOURCES += [
'nsDbusmenu.cpp',
'nsMenu.cpp', # conflicts with X11 headers
'nsMenuBar.cpp',
'nsMenuContainer.cpp',
'nsMenuItem.cpp',
'nsMenuObject.cpp',
'nsMenuSeparator.cpp',
'nsNativeMenuDocListener.cpp',
'nsNativeMenuService.cpp',
'nsWindow.cpp', # conflicts with X11 headers
]

Expand Down Expand Up @@ -127,6 +136,7 @@ FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/layout/base',
'/layout/generic',
'/layout/style',
'/layout/xul',
'/other-licenses/atk-1.0',
'/widget',
Expand Down
61 changes: 61 additions & 0 deletions widget/gtk/nsDbusmenu.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsDbusmenu.h"
#include "prlink.h"
#include "mozilla/ArrayUtils.h"

#define FUNC(name, type, params) \
nsDbusmenuFunctions::_##name##_fn nsDbusmenuFunctions::s_##name;
DBUSMENU_GLIB_FUNCTIONS
DBUSMENU_GTK_FUNCTIONS
#undef FUNC

static PRLibrary *gDbusmenuGlib = nullptr;
static PRLibrary *gDbusmenuGtk = nullptr;

typedef void (*nsDbusmenuFunc)();
struct nsDbusmenuDynamicFunction {
const char *functionName;
nsDbusmenuFunc *function;
};

/* static */ nsresult
nsDbusmenuFunctions::Init()
{
#define FUNC(name, type, params) \
{ #name, (nsDbusmenuFunc *)&nsDbusmenuFunctions::s_##name },
static const nsDbusmenuDynamicFunction kDbusmenuGlibSymbols[] = {
DBUSMENU_GLIB_FUNCTIONS
};
static const nsDbusmenuDynamicFunction kDbusmenuGtkSymbols[] = {
DBUSMENU_GTK_FUNCTIONS
};

#define LOAD_LIBRARY(symbol, name) \
if (!g##symbol) { \
g##symbol = PR_LoadLibrary(name); \
if (!g##symbol) { \
return NS_ERROR_FAILURE; \
} \
} \
for (uint32_t i = 0; i < mozilla::ArrayLength(k##symbol##Symbols); ++i) { \
*k##symbol##Symbols[i].function = \
PR_FindFunctionSymbol(g##symbol, k##symbol##Symbols[i].functionName); \
if (!*k##symbol##Symbols[i].function) { \
return NS_ERROR_FAILURE; \
} \
}

LOAD_LIBRARY(DbusmenuGlib, "libdbusmenu-glib.so.4")
#ifdef MOZ_WIDGET_GTK
LOAD_LIBRARY(DbusmenuGtk, "libdbusmenu-gtk3.so.4")
#endif
#undef LOAD_LIBRARY

return NS_OK;
}
101 changes: 101 additions & 0 deletions widget/gtk/nsDbusmenu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef __nsDbusmenu_h__
#define __nsDbusmenu_h__

#include "nsError.h"

#include <glib.h>
#include <gdk/gdk.h>

#define DBUSMENU_GLIB_FUNCTIONS \
FUNC(dbusmenu_menuitem_child_add_position, gboolean, (DbusmenuMenuitem *mi, DbusmenuMenuitem *child, guint position)) \
FUNC(dbusmenu_menuitem_child_append, gboolean, (DbusmenuMenuitem *mi, DbusmenuMenuitem *child)) \
FUNC(dbusmenu_menuitem_child_delete, gboolean, (DbusmenuMenuitem *mi, DbusmenuMenuitem *child)) \
FUNC(dbusmenu_menuitem_get_children, GList*, (DbusmenuMenuitem *mi)) \
FUNC(dbusmenu_menuitem_new, DbusmenuMenuitem*, (void)) \
FUNC(dbusmenu_menuitem_property_get, const gchar*, (DbusmenuMenuitem *mi, const gchar *property)) \
FUNC(dbusmenu_menuitem_property_get_bool, gboolean, (DbusmenuMenuitem *mi, const gchar *property)) \
FUNC(dbusmenu_menuitem_property_remove, void, (DbusmenuMenuitem *mi, const gchar *property)) \
FUNC(dbusmenu_menuitem_property_set, gboolean, (DbusmenuMenuitem *mi, const gchar *property, const gchar *value)) \
FUNC(dbusmenu_menuitem_property_set_bool, gboolean, (DbusmenuMenuitem *mi, const gchar *property, const gboolean value)) \
FUNC(dbusmenu_menuitem_property_set_int, gboolean, (DbusmenuMenuitem *mi, const gchar *property, const gint value)) \
FUNC(dbusmenu_menuitem_show_to_user, void, (DbusmenuMenuitem *mi, guint timestamp)) \
FUNC(dbusmenu_menuitem_take_children, GList*, (DbusmenuMenuitem *mi)) \
FUNC(dbusmenu_server_new, DbusmenuServer*, (const gchar *object)) \
FUNC(dbusmenu_server_set_root, void, (DbusmenuServer *server, DbusmenuMenuitem *root)) \
FUNC(dbusmenu_server_set_status, void, (DbusmenuServer *server, DbusmenuStatus status))

#define DBUSMENU_GTK_FUNCTIONS \
FUNC(dbusmenu_menuitem_property_set_image, gboolean, (DbusmenuMenuitem *menuitem, const gchar *property, const GdkPixbuf *data)) \
FUNC(dbusmenu_menuitem_property_set_shortcut, gboolean, (DbusmenuMenuitem *menuitem, guint key, GdkModifierType modifier))

typedef struct _DbusmenuMenuitem DbusmenuMenuitem;
typedef struct _DbusmenuServer DbusmenuServer;

enum DbusmenuStatus {
DBUSMENU_STATUS_NORMAL,
DBUSMENU_STATUS_NOTICE
};

#define DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU "submenu"
#define DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY "children-display"
#define DBUSMENU_MENUITEM_PROP_ENABLED "enabled"
#define DBUSMENU_MENUITEM_PROP_ICON_DATA "icon-data"
#define DBUSMENU_MENUITEM_PROP_LABEL "label"
#define DBUSMENU_MENUITEM_PROP_SHORTCUT "shortcut"
#define DBUSMENU_MENUITEM_PROP_TYPE "type"
#define DBUSMENU_MENUITEM_PROP_TOGGLE_STATE "toggle-state"
#define DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE "toggle-type"
#define DBUSMENU_MENUITEM_PROP_VISIBLE "visible"
#define DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW "about-to-show"
#define DBUSMENU_MENUITEM_SIGNAL_EVENT "event"
#define DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED "item-activated"
#define DBUSMENU_MENUITEM_TOGGLE_CHECK "checkmark"
#define DBUSMENU_MENUITEM_TOGGLE_RADIO "radio"
#define DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED 1
#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED 0
#define DBUSMENU_SERVER_PROP_DBUS_OBJECT "dbus-object"

class nsDbusmenuFunctions
{
public:
nsDbusmenuFunctions() = delete;

static nsresult Init();

#define FUNC(name, type, params) \
typedef type (*_##name##_fn) params; \
static _##name##_fn s_##name;
DBUSMENU_GLIB_FUNCTIONS
DBUSMENU_GTK_FUNCTIONS
#undef FUNC

};

#define dbusmenu_menuitem_child_add_position nsDbusmenuFunctions::s_dbusmenu_menuitem_child_add_position
#define dbusmenu_menuitem_child_append nsDbusmenuFunctions::s_dbusmenu_menuitem_child_append
#define dbusmenu_menuitem_child_delete nsDbusmenuFunctions::s_dbusmenu_menuitem_child_delete
#define dbusmenu_menuitem_get_children nsDbusmenuFunctions::s_dbusmenu_menuitem_get_children
#define dbusmenu_menuitem_new nsDbusmenuFunctions::s_dbusmenu_menuitem_new
#define dbusmenu_menuitem_property_get nsDbusmenuFunctions::s_dbusmenu_menuitem_property_get
#define dbusmenu_menuitem_property_get_bool nsDbusmenuFunctions::s_dbusmenu_menuitem_property_get_bool
#define dbusmenu_menuitem_property_remove nsDbusmenuFunctions::s_dbusmenu_menuitem_property_remove
#define dbusmenu_menuitem_property_set nsDbusmenuFunctions::s_dbusmenu_menuitem_property_set
#define dbusmenu_menuitem_property_set_bool nsDbusmenuFunctions::s_dbusmenu_menuitem_property_set_bool
#define dbusmenu_menuitem_property_set_int nsDbusmenuFunctions::s_dbusmenu_menuitem_property_set_int
#define dbusmenu_menuitem_show_to_user nsDbusmenuFunctions::s_dbusmenu_menuitem_show_to_user
#define dbusmenu_menuitem_take_children nsDbusmenuFunctions::s_dbusmenu_menuitem_take_children
#define dbusmenu_server_new nsDbusmenuFunctions::s_dbusmenu_server_new
#define dbusmenu_server_set_root nsDbusmenuFunctions::s_dbusmenu_server_set_root
#define dbusmenu_server_set_status nsDbusmenuFunctions::s_dbusmenu_server_set_status

#define dbusmenu_menuitem_property_set_image nsDbusmenuFunctions::s_dbusmenu_menuitem_property_set_image
#define dbusmenu_menuitem_property_set_shortcut nsDbusmenuFunctions::s_dbusmenu_menuitem_property_set_shortcut

#endif /* __nsDbusmenu_h__ */
Loading

0 comments on commit eefb998

Please sign in to comment.