--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -1,16 +1,20 @@
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 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/.
<menubar id="main-menubar"
onpopupshowing="if (event.target.parentNode.parentNode == this &&
+#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);"
style="border:0px;padding:0px;margin:0px;-moz-appearance:none">
<menu id="file-menu" label="&fileMenu.label;"
accesskey="&fileMenu.accesskey;">
<menupopup id="menu_FilePopup"
onpopupshowing="updateUserContextUIVisibility();">
<menuitem id="menu_newNavigatorTab"
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5045,16 +5045,18 @@ nsBrowserAccess.prototype = {
return CanCloseWindow();
},
}
function getTogglableToolbars() {
let toolbarNodes = Array.slice(gNavToolbox.childNodes);
toolbarNodes = toolbarNodes.concat(gNavToolbox.externalToolbars);
toolbarNodes = toolbarNodes.filter(node => node.getAttribute("toolbarname"));
+ if (document.documentElement.getAttribute("shellshowingmenubar") == "true")
+ toolbarNodes = toolbarNodes.filter(node => node.id != "toolbar-menubar");
return toolbarNodes;
}
function onViewToolbarsPopupShowing(aEvent, aInsertPoint) {
var popup = aEvent.target;
if (popup != aEvent.currentTarget)
return;
--- a/browser/components/places/content/places.xul
+++ b/browser/components/places/content/places.xul
@@ -152,17 +152,17 @@
command="OrganizerCommand:Forward"
tooltiptext="&forwardButton.tooltip;"
disabled="true"/>
#ifdef XP_MACOSX
<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;"
tooltiptext="&organize.tooltip;">
<menupopup id="organizeButtonPopup">
<menuitem id="newbookmark"
command="placesCmd_new:bookmark"
label="&cmd.new_bookmark.label;"
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -223,16 +223,19 @@ pref("dom.url.getters_decode_hash", fals
// significantly increase the number of compartments in the system.
pref("dom.compartment_per_addon", true);
// Fastback caching - if this pref is negative, then we calculate the number
// of content viewers to cache based on the amount of available memory.
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);
// Duration of timeout of incremental search in menus (ms). 0 means infinite.
pref("ui.menu.incremental_search.timeout", 1000);
// If true, all popups won't hide automatically on blur
pref("ui.popup.disable_autohide", false);
pref("browser.display.use_document_fonts", 1); // 0 = never, 1 = quick, 2 = always
// 0 = default: always, except in high contrast mode
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -20,18 +20,24 @@
<property name="position" onget="return this.getAttribute('position');"
onset="this.setAttribute('position', val); return val;"/>
<property name="popupBoxObject">
<getter>
return this.boxObject;
</getter>
</property>
- <property name="state" readonly="true"
- onget="return this.popupBoxObject.popupState"/>
+ <property name="state" readonly="true">
+ <getter><![CDATA[
+ if (this.hasAttribute('_moz-menupopupstate'))
+ return this.getAttribute('_moz-menupopupstate');
+ else
+ return this.popupBoxObject.popupState;
+ ]]></getter>
+ </property>
<property name="triggerNode" readonly="true"
onget="return this.popupBoxObject.triggerNode"/>
<property name="anchorNode" readonly="true"
onget="return this.popupBoxObject.anchorNode"/>
<method name="openPopup">
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -302,16 +302,28 @@ toolbar[type="menubar"][autohide="true"]
toolbar[type="menubar"][autohide="true"][inactive="true"]:not([customizing="true"]) {
min-height: 0 !important;
height: 0 !important;
-moz-appearance: none !important;
border-style: none !important;
}
%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
+
toolbarseparator {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbardecoration");
}
toolbarspacer {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbardecoration");
}
--- a/widget/gtk/moz.build
+++ b/widget/gtk/moz.build
@@ -19,32 +19,42 @@ EXPORTS.mozilla += [
UNIFIED_SOURCES += [
'IMContextWrapper.cpp',
'mozcontainer.c',
'NativeKeyBindings.cpp',
'nsAppShell.cpp',
'nsBidiKeyboard.cpp',
'nsColorPicker.cpp',
+ 'nsDbusmenu.cpp',
'nsFilePicker.cpp',
'nsGtkKeyUtils.cpp',
'nsImageToPixbuf.cpp',
'nsLookAndFeel.cpp',
+ 'nsMenuBar.cpp',
+ 'nsMenuContainer.cpp',
+ 'nsMenuItem.cpp',
+ 'nsMenuObject.cpp',
+ 'nsMenuSeparator.cpp',
+ 'nsNativeMenuAtoms.cpp',
+ 'nsNativeMenuDocListener.cpp',
'nsNativeThemeGTK.cpp',
'nsScreenGtk.cpp',
'nsScreenManagerGtk.cpp',
'nsSound.cpp',
'nsToolkit.cpp',
'nsWidgetFactory.cpp',
'WakeLockListener.cpp',
'WidgetTraceEvent.cpp',
'WidgetUtilsGtk.cpp',
]
SOURCES += [
+ 'nsMenu.cpp', # conflicts with X11 headers
+ 'nsNativeMenuService.cpp',
'nsWindow.cpp', # conflicts with X11 headers
]
if CONFIG['MOZ_X11']:
UNIFIED_SOURCES += [
'CompositorWidgetChild.cpp',
'CompositorWidgetParent.cpp',
'InProcessX11CompositorWidget.cpp',
@@ -99,16 +109,17 @@ else:
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/layout/generic',
+ '/layout/style',
'/layout/xul',
'/other-licenses/atk-1.0',
'/widget',
]
if CONFIG['MOZ_X11']:
LOCAL_INCLUDES += [
'/widget/x11',
--- a/widget/gtk/nsScreenGtk.cpp
+++ b/widget/gtk/nsScreenGtk.cpp
@@ -10,16 +10,17 @@
#include <gdk/gdk.h>
#ifdef MOZ_X11
#include <gdk/gdkx.h>
#include <X11/Xatom.h>
#endif
#include <gtk/gtk.h>
#include <dlfcn.h>
#include "gfxPlatformGtk.h"
+#include "nsIWidget.h"
static uint32_t sScreenId = 0;
nsScreenGtk :: nsScreenGtk ( )
: mScreenNum(0),
mRect(0, 0, 0, 0),
mAvailRect(0, 0, 0, 0),
--- a/widget/gtk/nsWidgetFactory.cpp
+++ b/widget/gtk/nsWidgetFactory.cpp
@@ -44,16 +44,19 @@
#include "nsImageToPixbuf.h"
#include "nsPrintDialogGTK.h"
#if defined(MOZ_X11)
#include "nsIdleServiceGTK.h"
#include "GfxInfoX11.h"
#endif
+#include "nsNativeMenuService.h"
+#include "nsNativeMenuAtoms.h"
+
#include "nsNativeThemeGTK.h"
#include "nsIComponentRegistrar.h"
#include "nsComponentManagerUtils.h"
#include "mozilla/gfx/2D.h"
#include <gtk/gtk.h>
using namespace mozilla;
@@ -116,16 +119,19 @@ nsNativeThemeGTKConstructor(nsISupports
namespace mozilla {
namespace widget {
// This constructor should really be shared with all platforms.
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init)
}
}
#endif
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsNativeMenuService,
+ nsNativeMenuService::GetInstance)
+
#ifdef NS_PRINTING
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecGTK)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintOptionsGTK, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPrinterEnumeratorGTK)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintDialogServiceGTK, Init)
#endif
@@ -218,16 +224,17 @@ NS_DEFINE_NAMED_CID(NS_PRINTSESSION_CID)
NS_DEFINE_NAMED_CID(NS_DEVICE_CONTEXT_SPEC_CID);
NS_DEFINE_NAMED_CID(NS_PRINTDIALOGSERVICE_CID);
#endif
NS_DEFINE_NAMED_CID(NS_IMAGE_TO_PIXBUF_CID);
#if defined(MOZ_X11)
NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
#endif
+NS_DEFINE_NAMED_CID(NS_NATIVEMENUSERVICE_CID);
static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
{ &kNS_WINDOW_CID, false, nullptr, nsWindowConstructor },
{ &kNS_CHILD_CID, false, nullptr, nsChildWindowConstructor },
{ &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor, Module::ALLOW_IN_GPU_PROCESS },
{ &kNS_COLORPICKER_CID, false, nullptr, nsColorPickerConstructor, Module::MAIN_PROCESS_ONLY },
{ &kNS_FILEPICKER_CID, false, nullptr, nsFilePickerConstructor, Module::MAIN_PROCESS_ONLY },
@@ -253,16 +260,17 @@ static const mozilla::Module::CIDEntry k
{ &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecGTKConstructor },
{ &kNS_PRINTDIALOGSERVICE_CID, false, nullptr, nsPrintDialogServiceGTKConstructor },
#endif
{ &kNS_IMAGE_TO_PIXBUF_CID, false, nullptr, nsImageToPixbufConstructor },
#if defined(MOZ_X11)
{ &kNS_IDLE_SERVICE_CID, false, nullptr, nsIdleServiceGTKConstructor },
{ &kNS_GFXINFO_CID, false, nullptr, mozilla::widget::GfxInfoConstructor },
#endif
+ { &kNS_NATIVEMENUSERVICE_CID, true, NULL, nsNativeMenuServiceConstructor },
{ nullptr }
};
static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
{ "@mozilla.org/widget/window/gtk;1", &kNS_WINDOW_CID },
{ "@mozilla.org/widgets/child_window/gtk;1", &kNS_CHILD_CID },
{ "@mozilla.org/widget/appshell/gtk;1", &kNS_APPSHELL_CID, Module::ALLOW_IN_GPU_PROCESS },
{ "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID, Module::MAIN_PROCESS_ONLY },
@@ -290,19 +298,29 @@ static const mozilla::Module::ContractID
{ "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
{ NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID },
#endif
{ "@mozilla.org/widget/image-to-gdk-pixbuf;1", &kNS_IMAGE_TO_PIXBUF_CID },
#if defined(MOZ_X11)
{ "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
{ "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
#endif
+ { "@mozilla.org/widget/nativemenuservice;1", &kNS_NATIVEMENUSERVICE_CID },
{ nullptr }
};
+static nsresult
+nsWidgetGtk2ModuleCtor()
+{
+ nsAppShellInit();
+ nsNativeMenuAtoms::Init();
+
+ return NS_OK;
+}
+
static void
nsWidgetGtk2ModuleDtor()
{
// Shutdown all XP level widget classes.
WidgetUtils::Shutdown();
NativeKeyBindings::Shutdown();
nsLookAndFeel::Shutdown();
@@ -318,14 +336,14 @@ nsWidgetGtk2ModuleDtor()
}
static const mozilla::Module kWidgetModule = {
mozilla::Module::kVersion,
kWidgetCIDs,
kWidgetContracts,
nullptr,
nullptr,
- nsAppShellInit,
+ nsWidgetGtk2ModuleCtor,
nsWidgetGtk2ModuleDtor,
Module::ALLOW_IN_GPU_PROCESS
};
NSMODULE_DEFN(nsWidgetGtk2Module) = &kWidgetModule;
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -5162,16 +5162,21 @@ nsWindow::HideWindowChrome(bool aShouldH
XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()) , False);
#else
gdk_flush ();
#endif /* MOZ_X11 */
return NS_OK;
}
+void
+nsWindow::SetMenuBar(nsMenuBar *aMenuBar) {
+ mMenuBar.reset(aMenuBar);
+}
+
bool
nsWindow::CheckForRollup(gdouble aMouseX, gdouble aMouseY,
bool aIsWheel, bool aAlwaysRollup)
{
nsIRollupListener* rollupListener = GetActiveRollupListener();
nsCOMPtr<nsIWidget> rollupWidget;
if (rollupListener) {
rollupWidget = rollupListener->GetRollupWidget();
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -30,16 +30,18 @@
#ifdef ACCESSIBILITY
#include "mozilla/a11y/Accessible.h"
#endif
#include "mozilla/EventForwards.h"
#include "mozilla/TouchEvents.h"
#include "IMContextWrapper.h"
+#include "nsMenuBar.h"
+
#undef LOG
#ifdef MOZ_LOGGING
#include "mozilla/Logging.h"
#include "nsTArray.h"
#include "Units.h"
extern PRLogModuleInfo *gWidgetLog;
@@ -157,16 +159,18 @@ public:
virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage,
uint16_t aDuration,
nsISupports* aData,
nsIRunnable* aCallback) override;
virtual nsresult MakeFullScreen(bool aFullScreen,
nsIScreen* aTargetScreen = nullptr) override;
NS_IMETHOD HideWindowChrome(bool aShouldHide) override;
+ void SetMenuBar(nsMenuBar *aMenuBar);
+
/**
* GetLastUserInputTime returns a timestamp for the most recent user input
* event. This is intended for pointer grab requests (including drags).
*/
static guint32 GetLastUserInputTime();
// utility method, -1 if no change should be made, otherwise returns a
// value that can be passed to gdk_window_set_decorations
@@ -564,16 +568,18 @@ private:
* ancestor widget's instance. So, one set of IM contexts is created for
* all windows in a hierarchy. If the children are released after the top
* level window is released, the children still have a valid pointer,
* however, IME doesn't work at that time.
*/
RefPtr<mozilla::widget::IMContextWrapper> mIMContext;
mozilla::UniquePtr<mozilla::CurrentX11TimeGetter> mCurrentTimeGetter;
+
+ mozilla::UniquePtr<nsMenuBar> mMenuBar;
};
class nsChildWindow : public nsWindow {
public:
nsChildWindow();
~nsChildWindow();
};
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -32,20 +32,22 @@ elif toolkit == 'cocoa':
XPIDL_SOURCES += [
'nsIMacDockSupport.idl',
'nsIMacWebAppUtils.idl',
'nsIStandaloneNativeMenu.idl',
'nsISystemStatusBar.idl',
'nsITaskbarProgress.idl',
]
EXPORTS += [
- 'nsINativeMenuService.h',
'nsIPrintDialogService.h',
]
+if toolkit in ('cocoa', 'gtk2', 'gtk3'):
+ EXPORTS += ['nsINativeMenuService.h']
+
TEST_DIRS += ['tests']
# Don't build the DSO under the 'build' directory as windows does.
#
# The DSOs get built in the toolkit dir itself. Do this so that
# multiple implementations of widget can be built on the same
# source tree.
#
--- a/xpfe/appshell/nsWebShellWindow.cpp
+++ b/xpfe/appshell/nsWebShellWindow.cpp
@@ -53,32 +53,33 @@
#include "nsIDocumentLoaderFactory.h"
#include "nsIObserverService.h"
#include "prprf.h"
#include "nsIScreenManager.h"
#include "nsIScreen.h"
#include "nsIContent.h" // for menus
+#include "nsIAtom.h"
#include "nsIScriptSecurityManager.h"
// For calculating size
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsIBaseWindow.h"
#include "nsIDocShellTreeItem.h"
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/MouseEvents.h"
#include "nsPIWindowRoot.h"
-#ifdef XP_MACOSX
+#if defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
#include "nsINativeMenuService.h"
#define USE_NATIVE_MENUS
#endif
using namespace mozilla;
using namespace mozilla::dom;
/* Define Class IDs */
@@ -493,16 +494,21 @@ static void LoadNativeMenus(nsIDOMDocume
getter_AddRefs(menubarElements));
nsCOMPtr<nsIDOMNode> menubarNode;
if (menubarElements)
menubarElements->Item(0, getter_AddRefs(menubarNode));
if (menubarNode) {
nsCOMPtr<nsIContent> menubarContent(do_QueryInterface(menubarNode));
+#ifdef MOZ_WIDGET_GTK
+ nsCOMPtr<nsIAtom> atom = NS_Atomize(NS_LITERAL_CSTRING("_moz-menubarkeeplocal"));
+ if (menubarContent->AttrValueIs(kNameSpaceID_None, atom, nsGkAtoms::_true, eCaseMatters))
+ return;
+#endif
nms->CreateNativeMenuBar(aParentWindow, menubarContent);
} else {
nms->CreateNativeMenuBar(aParentWindow, nullptr);
}
}
#endif
namespace mozilla {