summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Bidar2024-06-30 00:42:29 +0300
committerBjörn Bidar2024-06-30 00:42:29 +0300
commit001962ca941bce60edb8dcd201bfc08286838b3c (patch)
treea8340dbeb2bdff496066375676f32d428b089e36
parent8f850177dd0eb2d55a990b5f714e4c026740479b (diff)
downloadaur-001962ca941bce60edb8dcd201bfc08286838b3c.tar.gz
Update to 127.0-1
- New upstream release - Rebase patches Signed-off-by: Björn Bidar <bjorn.bidar@thaodan.de>
-rw-r--r--.SRCINFO75
-rw-r--r--0001-Bug-1504834-Rough-progress-patch.patch4
-rw-r--r--0004-mozilla-libavcodec58_91.patch.patch6
-rw-r--r--0005-mozilla-silence-no-return-type.patch-to-fix-build-er.patch70
-rw-r--r--0011-bsc-991344-Rpi3-Firefox-crashes-after-a-few-seconds-.patch4
-rw-r--r--0012-mozilla-fix-aarch64-libopus.patch.patch2
-rw-r--r--0016-Fix-building-with-PGO-when-using-GCC.patch14
-rw-r--r--0017-LTO-Only-enable-LTO-for-Rust-when-complete-build-use.patch2
-rw-r--r--0018-Bug-1516081-Disable-watchdog-during-FDO-train.patch4
-rw-r--r--0019-Bug-559213-Support-system-av1.patch81
-rw-r--r--0020-Bug-847568-Support-system-harfbuzz.patch49
-rw-r--r--0021-Bug-847568-Support-system-graphite2.patch65
-rw-r--r--0022-Bug-1611386-Reenable-support-for-enable-system-sqlit.patch30
-rw-r--r--0023-Bug-1419151-Add-Unity-menubar-support.patch5439
-rw-r--r--0023-Do-not-use-gconf-for-proxy-settings-if-not-running-w.patch (renamed from 0024-Do-not-use-gconf-for-proxy-settings-if-not-running-w.patch)2
-rw-r--r--0024-Add-KDE-integration-to-Firefox-toolkit-parts.patch (renamed from 0025-Add-KDE-integration-to-Firefox-toolkit-parts.patch)99
-rw-r--r--0025-Add-KDE-integration-to-Firefox.patch (renamed from 0026-Add-KDE-integration-to-Firefox.patch)12
-rw-r--r--0026-Imported-patch-firefox-branded-icons.patch.patch (renamed from 0027-Imported-patch-firefox-branded-icons.patch.patch)24
-rw-r--r--0027-Allow-Eme-for-arm-and-Aarch64.patch (renamed from 0028-Allow-Eme-for-arm-and-Aarch64.patch)4
-rw-r--r--0028-Shut-up-warnings-about-future-Rust-version-incompati.patch (renamed from 0029-Shut-up-warnings-about-future-Rust-version-incompati.patch)10
-rw-r--r--0029-Partially-revert-Bug-1768632-Make-EnumSet-compile-fo.patch (renamed from 0030-Partially-revert-Bug-1768632-Make-EnumSet-compile-fo.patch)4
-rw-r--r--0030-Bug-1796523-Workaround-source-locations-for-function.patch (renamed from 0031-Bug-1796523-Workaround-source-locations-for-function.patch)4
-rw-r--r--0031-Bug-1822730-Add-basic-blob-protocol-handling-for-blo.patch (renamed from 0032-Bug-1822730-Add-basic-blob-protocol-handling-for-blo.patch)17
-rw-r--r--0032-Bug-1862601-Part-12-Add-new-line-break-classes.-r.patch28
-rw-r--r--PKGBUILD70
-rw-r--r--firefox-kde-opensuse.changes457
26 files changed, 817 insertions, 5759 deletions
diff --git a/.SRCINFO b/.SRCINFO
index f4271127bb61..d6e7280fdb2c 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,6 +1,6 @@
pkgbase = firefox-kde-opensuse
pkgdesc = Standalone web browser from mozilla.org with OpenSUSE patch, integrate better with KDE
- pkgver = 121.0.1
+ pkgver = 127.0
pkgrel = 1
url = https://github.com/openSUSE/firefox-maintenance
arch = i686
@@ -17,7 +17,6 @@ pkgbase = firefox-kde-opensuse
makedepends = xorg-server-xvfb
makedepends = libpulse
makedepends = inetutils
- makedepends = autoconf2.13
makedepends = cargo
makedepends = mercurial
makedepends = llvm
@@ -59,12 +58,12 @@ pkgbase = firefox-kde-opensuse
optdepends = pulseaudio: Audio support
optdepends = libnotify: Notification integration
optdepends = xdg-desktop-portal: Screensharing with Wayland
- provides = firefox=121.0.1
+ provides = firefox=127.0
conflicts = firefox
options = !emptydirs
options = !lto
- source = https://archive.mozilla.org/pub/firefox/releases/121.0.1/source/firefox-121.0.1.source.tar.xz
- source = https://archive.mozilla.org/pub/firefox/releases/121.0.1/source/firefox-121.0.1.source.tar.xz.asc
+ source = https://archive.mozilla.org/pub/firefox/releases/127.0/source/firefox-127.0.source.tar.xz
+ source = https://archive.mozilla.org/pub/firefox/releases/127.0/source/firefox-127.0.source.tar.xz.asc
source = mozconfig
source = firefox.desktop
source = vendor.js
@@ -90,54 +89,54 @@ pkgbase = firefox-kde-opensuse
source = 0020-Bug-847568-Support-system-harfbuzz.patch
source = 0021-Bug-847568-Support-system-graphite2.patch
source = 0022-Bug-1611386-Reenable-support-for-enable-system-sqlit.patch
- source = 0023-Bug-1419151-Add-Unity-menubar-support.patch
- source = 0024-Do-not-use-gconf-for-proxy-settings-if-not-running-w.patch
- source = 0025-Add-KDE-integration-to-Firefox-toolkit-parts.patch
- source = 0026-Add-KDE-integration-to-Firefox.patch
- source = 0027-Imported-patch-firefox-branded-icons.patch.patch
- source = 0028-Allow-Eme-for-arm-and-Aarch64.patch
- source = 0029-Shut-up-warnings-about-future-Rust-version-incompati.patch
- source = 0030-Partially-revert-Bug-1768632-Make-EnumSet-compile-fo.patch
- source = 0031-Bug-1796523-Workaround-source-locations-for-function.patch
- source = 0032-Bug-1822730-Add-basic-blob-protocol-handling-for-blo.patch
+ source = 0023-Do-not-use-gconf-for-proxy-settings-if-not-running-w.patch
+ source = 0024-Add-KDE-integration-to-Firefox-toolkit-parts.patch
+ source = 0025-Add-KDE-integration-to-Firefox.patch
+ source = 0026-Imported-patch-firefox-branded-icons.patch.patch
+ source = 0027-Allow-Eme-for-arm-and-Aarch64.patch
+ source = 0028-Shut-up-warnings-about-future-Rust-version-incompati.patch
+ source = 0029-Partially-revert-Bug-1768632-Make-EnumSet-compile-fo.patch
+ source = 0030-Bug-1796523-Workaround-source-locations-for-function.patch
+ source = 0031-Bug-1822730-Add-basic-blob-protocol-handling-for-blo.patch
+ source = 0032-Bug-1862601-Part-12-Add-new-line-break-classes.-r.patch
validpgpkeys = 14F26682D0916CDD81E37B6D61B7B526D98F0353
- sha256sums = b3a4216e01eaeb9a7c6ef4659d8dcd956fbd90a78a8279ee3a598881e63e49ce
+ sha256sums = ea6b089ff046ca503978fdaf11ea123c64f66bbcdc4a968bed8f7c93e9994321
sha256sums = SKIP
sha256sums = be65b2421999ad5c8ffa363dc009ce2cd291badc422fbb456967616bad3e2e19
sha256sums = 4c93b2e1f1675e033ed7910fe5f379626a92903a940697430985bcfdf94afceb
sha256sums = eaad0eee76f89e0a1a241742ec5c8ec9315b096f7b3e0ea302b253b926750aae
- sha256sums = c3c785256e7497118e9e19de4c1748664e8df5930a436040f029023a1190a9a5
+ sha256sums = c9fc92d2e91d853e91af8263d71960e6c23c9ff005e139e2fa13a255f16a9a64
sha256sums = eb19d9568e8d7705b2a0c4774d4f6a758a910c0e5cf427727feb5884a2a1ee98
sha256sums = 4322124dc370ac56063837370a8107e85ca6e0d4037ff71ece5e7b0f55ed8053
- sha256sums = a8aeb8b73abe711752ebf1a561fb4af736854be5c298441b8de7a1148a47a416
- sha256sums = 111fa1040408cccf0ea52c59028ddd06bae52adc2d3387a8fc2ff89a8b6590f9
+ sha256sums = 2bf113fa4eebe0177bb418c187a5d077c1760bb1b788059f444c483d79df8e4d
+ sha256sums = 6b0c60632691f345969f0b6759428cc2d9fb8f7d7570e6d76141f6855b9bcbf4
sha256sums = 999f0f5c198f00943894639d9dd4157f3e078a40e1f8a815aef2dacd5158a67c
sha256sums = bba76c5e13952ef45362f8e53a5c030e0f5d722f8f266228787136a5312330ea
sha256sums = f2fcd4ca82b833f5e5b7e991882e24f09463cd837242b18cf163bc751f2e21d5
sha256sums = 766faefbd4898049e9913589962bf839da6785d50f0631b4eac7316f16bf2ea6
sha256sums = 1cad951e7ff0073c9b5462fa9c4d8ead78d6d494286092b5d23a6fa5949259ef
- sha256sums = 5109d3113dbf3e8e584ff2107be50bbb8d04927329b1dba3c7c08308e2ddc42e
- sha256sums = 32d40630a010ee91d2c35c814ef2f567ad7faf859f8198735829958cb055f53b
+ sha256sums = 385b77d458d02675ad791029fceb0d4168368f7aff68a7a8586f0a36d8a52c46
+ sha256sums = 6145dc18238fca575dbbe65a3c244984cb132c0a08a02520af036bf77144b7c1
sha256sums = 1ffdcff3d4e31c5cceddadfa0111c27a34480594238cdf85866ee1073d922910
sha256sums = 3144c2f38c9e60ba00f231e7a8051ca41cdc5d9f542c0144f4549f525a8c129f
sha256sums = 5ee703cddba6045a03ee882ff70423fe185d009e2c912fc49ef66f7703ea46fe
- sha256sums = 2400173d2c84573194c6af9031663a5b2332ccb4929b246b216c61c97d8b0a54
- sha256sums = 469065ad1535e0798f8e1a3dc3285cbbb003ed12c62af5d6b9e1184e9383b5f8
- sha256sums = 72d30acbe1e8488c6bd3af2e0813223842a63b859d6e7aff66d2f23612b7ad8b
- sha256sums = 2a54aedc86f72dfe070b8f7a609a09b20f44fb90cf6add94ac451067dbe379d1
- sha256sums = 4f4f08bee921a1c0a78272cf08ff3e198895074e892aba8c172e7e12a97eaac6
- sha256sums = 057f4c0dd6c0564438fecf909eb5365714f633416f438fb8b7a8e4b8356347ed
- sha256sums = 6b2156bc3a0c8ae138a257dabe89ff6eac778f0230edb43b8f68eb659ae11ef3
- sha256sums = ce4ebd0b0bf19a292c6d4f199e05878b67bc45ec040916bcc84c50bb87367243
- sha256sums = dfb11575e7d43071c9046762408b7267507c645020678d57689d55d3f68c0c28
- sha256sums = abfd58b5296c16642a99e0dba7f27366d6b532306e13458d7d9d1217344f7108
- sha256sums = e6c33e08d0c839723a2379337251ab23bdb26a92edd9d5910986cf0301b3bd08
- sha256sums = c264af7b086701e5c76b47e87e4cd79ddb424e4ec6e87f81592c7ea1a37ace3a
- sha256sums = ce292fde34263f5dfd649b0b849c8f47cc5762acf8e5735e57ec8e453c2f14c1
- sha256sums = 329bd252104fcfa21f68256dec589858fc63354c56dc57f7d4d84ee32c5310f1
- sha256sums = 7038651e09bd1f1cf2561ee977e6fcc58f7295ce821f419288da6d0b2bcc8feb
- sha256sums = 0d7a0f8bd7f0a8f1319d79a433d848a3eb43e81f4a14f29d5c8602be49d93cb9
- sha256sums = ca63e1a8b93eed45fe1b6dc4da087d18b866570d99cfc6abfb8a7d3187d98e83
+ sha256sums = 942c0f66b2ab1123760384accc056b54dab9467d3094d52c9f35b263ddfc4e11
+ sha256sums = c898be9b4afa0f3fc4542efadd55a5947004a84cf3c8863a870f2ab1b4c7b056
+ sha256sums = 54463246e5cfb36846907ea7924b3e43546ff55980de16517f4ff52e999765de
+ sha256sums = 40302cef8ec83d12b95404ef3338e91a0166351462e4cccb14c192698198c88f
+ sha256sums = b73389e1da6a8d8de3ebe1bf337c3777f6f815b2fd30102fb7a387d11f1d86f5
+ sha256sums = 7da9a82f78fa3120c3dea8c1b7fe1889e62a3639412bf8b6aa646716e728bcf5
+ sha256sums = 5f2bf078c4424271fb2ff999cf1bd7960faf9022e67f5f50ad0918b7216fb1e9
+ sha256sums = a983f79d0a9c8b17ce3271250dd61e49a2ea9e70bf526f4f586fb5e17c01fcba
+ sha256sums = 1d7a32f97d0bb54d6da48b5e858c119891888807c82a78146c78798269fb4307
+ sha256sums = 1efc94925aa7ca4d46e94462cb9a1ca64d130209fff70cfe142647f3d20f16b9
+ sha256sums = 6dd444248443d360dcc0d8821d65cd341f3026d44258c0149dbd4e63ea7617b0
+ sha256sums = 8738417b180fcbc59c1314c1bd5da87b53e54851ef6f8e50c53ad597d5bd69d2
+ sha256sums = faea2c6d22f755657a71996c41f92473015af57d5dee5600d0d2ec3096b49102
+ sha256sums = c053fab26e784e081018254a875cc2656a34318075753c7c1e40bb2822c5bf53
+ sha256sums = a3c56cf14d2e4d5f4872091bb5a9b765bcc60b3b1a301bef8e123af7a7182698
+ sha256sums = 8531ed52332e4290b4c1c9552236689cc8b250855ae20365eac44e1cbc7a9504
+ sha256sums = b08459d49f5fb22353e70f0c96a772ea9aa9e832b6ee9ecb02e564a858f9f52e
pkgname = firefox-kde-opensuse
depends = libxt
diff --git a/0001-Bug-1504834-Rough-progress-patch.patch b/0001-Bug-1504834-Rough-progress-patch.patch
index 0c074d0139e9..3bcde8e8fd3b 100644
--- a/0001-Bug-1504834-Rough-progress-patch.patch
+++ b/0001-Bug-1504834-Rough-progress-patch.patch
@@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1504834#c5
3 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp
-index b569438db44f5ba7869da4bc505f8950533cc8ec..1b6f70684886325d9b8b505b1f6f59a2dfb7023e 100644
+index 508dac3f6241aebe950dc702d1c2d9869d8d8b72..89fdbaa72636d5c3215281830447aae49e9d0764 100644
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -155,8 +155,7 @@ static IntRect CalculateSurfaceBounds(const IntSize& aSize, const Rect* aBounds,
@@ -25,7 +25,7 @@ index b569438db44f5ba7869da4bc505f8950533cc8ec..1b6f70684886325d9b8b505b1f6f59a2
static bool VerifyRGBXFormat(uint8_t* aData, const IntSize& aSize,
const int32_t aStride, SurfaceFormat aFormat) {
diff --git a/gfx/2d/Types.h b/gfx/2d/Types.h
-index e6f73eac3af55f46457dcaadec686a41eae2bd1d..c6833ddbcede70912d9ed4d7c341da3658d81f23 100644
+index caefacc116a0c8f366544c2a9d81c94d66f713e7..91090e59bb1c966374d95ce313cc1101a3f517db 100644
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -92,15 +92,8 @@ enum class SurfaceFormat : int8_t {
diff --git a/0004-mozilla-libavcodec58_91.patch.patch b/0004-mozilla-libavcodec58_91.patch.patch
index 76c58e41717b..d57ab384ad8c 100644
--- a/0004-mozilla-libavcodec58_91.patch.patch
+++ b/0004-mozilla-libavcodec58_91.patch.patch
@@ -8,11 +8,11 @@ Subject: [PATCH] mozilla-libavcodec58_91.patch
1 file changed, 2 insertions(+)
diff --git a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
-index 485f4c0f28b3c8d8ceeb5b76eb8aa41444b37183..6b772c5930819f8ba5095407b914b74a6408e917 100644
+index 81eb2c0441ac2b495d95de0643b9e3320a75b9b6..94a83c3e221f42c8956a5f43fd08ee1f485c46d5 100644
--- a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
-@@ -41,6 +41,8 @@ static const char* sLibs[] = {
- #else
+@@ -49,6 +49,8 @@ static const char* sLibs[] = {
+ "libavcodec.so.61",
"libavcodec.so.60",
"libavcodec.so.59",
+ "libavcodec.so.58.134",
diff --git a/0005-mozilla-silence-no-return-type.patch-to-fix-build-er.patch b/0005-mozilla-silence-no-return-type.patch-to-fix-build-er.patch
index 96d009547d5d..8ba2bb7a85a3 100644
--- a/0005-mozilla-silence-no-return-type.patch-to-fix-build-er.patch
+++ b/0005-mozilla-silence-no-return-type.patch-to-fix-build-er.patch
@@ -35,6 +35,7 @@ Subject: [PATCH] mozilla-silence-no-return-type.patch to fix build errors on
.../audio_processing/audio_processing_impl.cc | 4 +++-
.../audio_processing/include/audio_processing.cc | 2 ++
.../transient/transient_suppressor_impl.cc | 1 +
+ .../goog_cc/goog_cc_network_control.cc | 2 ++
.../linux/wayland/screencast_portal.cc | 1 +
.../libwebrtc/modules/pacing/bitrate_prober.cc | 1 +
.../source/create_video_rtp_depacketizer.cc | 1 +
@@ -43,7 +44,7 @@ Subject: [PATCH] mozilla-silence-no-return-type.patch to fix build errors on
.../codecs/vp8/default_temporal_layers.cc | 1 +
.../codecs/vp8/temporal_layers_checker.cc | 1 +
.../video_stream_encoder_resource_manager.cc | 1 +
- 38 files changed, 67 insertions(+), 5 deletions(-)
+ 39 files changed, 69 insertions(+), 5 deletions(-)
diff --git a/gfx/skia/skia/include/codec/SkEncodedOrigin.h b/gfx/skia/skia/include/codec/SkEncodedOrigin.h
index 19d083672f6b974e1df968bf4061b40002b01310..c1103223deaba0df7d97eb5ff71c0e78b3c41d03 100644
@@ -321,10 +322,10 @@ index 9438ae4d419a21030091ac88864330eb6db0b91b..bf7507ef0f3d5715c8910f4e63548520
union_.fracSig = settings;
return {RND_SIGNIFICANT, union_};
diff --git a/js/src/irregexp/imported/regexp-parser.cc b/js/src/irregexp/imported/regexp-parser.cc
-index ea2a6c6d7a3c8d9e0f40945dd486f1ede5f5914d..3399076be5288a805218953443f73d5e578a9adc 100644
+index 965fc567b716ea7cb1c2fae3f66ed705badf3ae5..6d78b127e9a1447189b3686893f76d8003b78e33 100644
--- a/js/src/irregexp/imported/regexp-parser.cc
+++ b/js/src/irregexp/imported/regexp-parser.cc
-@@ -2649,6 +2649,7 @@ bool MayContainStrings(ClassSetOperandType type, RegExpTree* operand) {
+@@ -2769,6 +2769,7 @@ bool MayContainStrings(ClassSetOperandType type, RegExpTree* operand) {
if (operand->IsClassRanges()) return false;
return operand->AsClassSetExpression()->may_contain_strings();
}
@@ -345,10 +346,10 @@ index dac03fe019d89482e91a29242b3027da80f28c8b..e18a04b4c5c95d1449662cfd8f7a7f97
ResourceListener::~ResourceListener() {}
diff --git a/third_party/libwebrtc/api/rtp_parameters.cc b/third_party/libwebrtc/api/rtp_parameters.cc
-index cf8b3ad3dcab8a802a2fb0a6b89d493417df98ba..5fbfd91517e95dc00eb563e440cdfb539be4ae26 100644
+index ad0f3c9396b47ce297455037bf4f05289fc73313..1732a74fd6bc9428c78159a57fe44d8dd8f1082a 100644
--- a/third_party/libwebrtc/api/rtp_parameters.cc
+++ b/third_party/libwebrtc/api/rtp_parameters.cc
-@@ -32,6 +32,7 @@ const char* DegradationPreferenceToString(
+@@ -33,6 +33,7 @@ const char* DegradationPreferenceToString(
return "balanced";
}
RTC_CHECK_NOTREACHED();
@@ -370,11 +371,11 @@ index 374b438adcbe961ed0b3787ca6d9a362c220e2d1..d2371b273712ef432b85e45ec478bf6d
int I420BufferInterface::ChromaWidth() const {
diff --git a/third_party/libwebrtc/api/video_codecs/video_codec.cc b/third_party/libwebrtc/api/video_codecs/video_codec.cc
-index c6122d3f6ac3056ebcc654e1c268923f6057a738..1c78e6c0071a4ae36913d47e67d05389270f5095 100644
+index 82c9bfc8ea32126fb7a7059ad1c8f85198ea16f3..3bcd1f8cef640dc8da3643cb0c076d5e30991df2 100644
--- a/third_party/libwebrtc/api/video_codecs/video_codec.cc
+++ b/third_party/libwebrtc/api/video_codecs/video_codec.cc
-@@ -118,6 +118,7 @@ const char* CodecTypeToPayloadString(VideoCodecType type) {
- return kPayloadNameGeneric;
+@@ -161,6 +161,7 @@ const char* CodecTypeToPayloadString(VideoCodecType type) {
+ return kPayloadNameH265;
}
RTC_CHECK_NOTREACHED();
+ return "";
@@ -382,10 +383,10 @@ index c6122d3f6ac3056ebcc654e1c268923f6057a738..1c78e6c0071a4ae36913d47e67d05389
VideoCodecType PayloadStringToCodecType(const std::string& name) {
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc
-index 39c52a008181cd2cf5fb2b3589816dfd3f03a6ba..24df68f62d0f27d3f0e2e099f1f694fe2fd4e982 100644
+index e50b5086e87aea3cb26f4a40e6213644106e9caf..3dd34f1a2b708f7da72c35690e426a2fadab8d9f 100644
--- a/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc
-@@ -163,6 +163,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
+@@ -189,6 +189,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
return fallback_encoder_.get();
}
RTC_CHECK_NOTREACHED();
@@ -393,7 +394,7 @@ index 39c52a008181cd2cf5fb2b3589816dfd3f03a6ba..24df68f62d0f27d3f0e2e099f1f694fe
}
// Updates encoder with last observed parameters, such as callbacks, rates,
-@@ -343,6 +344,7 @@ int32_t VideoEncoderSoftwareFallbackWrapper::Encode(
+@@ -382,6 +383,7 @@ int32_t VideoEncoderSoftwareFallbackWrapper::Encode(
return fallback_encoder_->Encode(frame, frame_types);
}
RTC_CHECK_NOTREACHED();
@@ -439,10 +440,10 @@ index 5a970fb2ef1af8069b7dd0c52a993ea7d7e6e896..0feec89ab185ab214e1f24b05efab02f
VideoStreamAdapter::RestrictionsOrState
diff --git a/third_party/libwebrtc/call/rtp_payload_params.cc b/third_party/libwebrtc/call/rtp_payload_params.cc
-index e9bfb30ae3770d2e99f3d9c991ce5b859b865617..45126fb5102d86741b2fb0752575a0d4c4a261cd 100644
+index 4b63ebefb3ffabc917f7c2d20d8c821f18444412..37e0f08e143da3b278cf0452c6fee0de592fbbd7 100644
--- a/third_party/libwebrtc/call/rtp_payload_params.cc
+++ b/third_party/libwebrtc/call/rtp_payload_params.cc
-@@ -405,7 +405,7 @@ absl::optional<FrameDependencyStructure> RtpPayloadParams::GenericStructure(
+@@ -410,7 +410,7 @@ absl::optional<FrameDependencyStructure> RtpPayloadParams::GenericStructure(
case VideoCodecType::kVideoCodecMultiplex:
return absl::nullopt;
}
@@ -464,10 +465,10 @@ index e8532a7a2669e717e79c49a1fd45020ca07dbced..c251629073b4c555c57d79d7fa7578a2
} // namespace
diff --git a/third_party/libwebrtc/media/base/codec.cc b/third_party/libwebrtc/media/base/codec.cc
-index 70a8d90e25a3ece112d0628a7bbefda26b60b36e..3226aa95ec3bb764d0f498a34d6d7f97527e6075 100644
+index d18baf7132a1d4d1140645bf09f392d905b0df1a..0d8de3480cf730ec8c13688a09e7d1d65aec1555 100644
--- a/third_party/libwebrtc/media/base/codec.cc
+++ b/third_party/libwebrtc/media/base/codec.cc
-@@ -206,6 +206,7 @@ bool Codec::Matches(const Codec& codec,
+@@ -233,6 +233,7 @@ bool Codec::Matches(const Codec& codec) const {
case Type::kVideo:
return IsSameCodecSpecific(name, params, codec.name, codec.params);
}
@@ -514,10 +515,10 @@ index a13e77461a15ad182ec5e6f8657823ed04f78291..398d4225131340ebf324e21e4ff46fa9
} // namespace
diff --git a/third_party/libwebrtc/modules/audio_processing/audio_processing_impl.cc b/third_party/libwebrtc/modules/audio_processing/audio_processing_impl.cc
-index c304453388e2b33826249a0b84d8d79699f4278c..6fca19ff17f1a63b919358616ce1f2787116adef 100644
+index 5f6dd59d026990a00447f747476299c87f8df276..736518f7c757170c757de08538f0c3d4e7796048 100644
--- a/third_party/libwebrtc/modules/audio_processing/audio_processing_impl.cc
+++ b/third_party/libwebrtc/modules/audio_processing/audio_processing_impl.cc
-@@ -99,6 +99,7 @@ GainControl::Mode Agc1ConfigModeToInterfaceMode(
+@@ -101,6 +101,7 @@ GainControl::Mode Agc1ConfigModeToInterfaceMode(
return GainControl::kFixedDigital;
}
RTC_CHECK_NOTREACHED();
@@ -525,7 +526,7 @@ index c304453388e2b33826249a0b84d8d79699f4278c..6fca19ff17f1a63b919358616ce1f278
}
bool MinimizeProcessingForUnusedOutput() {
-@@ -166,7 +167,7 @@ int AudioFormatValidityToErrorCode(AudioFormatValidity validity) {
+@@ -168,7 +169,7 @@ int AudioFormatValidityToErrorCode(AudioFormatValidity validity) {
case AudioFormatValidity::kInvalidChannelCount:
return AudioProcessing::kBadNumberChannelsError;
}
@@ -534,7 +535,7 @@ index c304453388e2b33826249a0b84d8d79699f4278c..6fca19ff17f1a63b919358616ce1f278
}
// Returns an AudioProcessing::Error together with the best possible option for
-@@ -2421,6 +2422,7 @@ void AudioProcessingImpl::InitializeNoiseSuppressor() {
+@@ -2425,6 +2426,7 @@ void AudioProcessingImpl::InitializeNoiseSuppressor() {
return NsConfig::SuppressionLevel::k21dB;
}
RTC_CHECK_NOTREACHED();
@@ -574,6 +575,19 @@ index 90428464e3bca2e8b0268e977d03d27176aedf86..8f9f8ac3ee6b743cb1d025d0f3b4088b
}
} // namespace
+diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
+index d8a0ce9d645c4554d4618846ea0423c27cba739f..b76e258e3ef9971e6e2a18b1823d12d6a741794c 100644
+--- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
++++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
+@@ -95,6 +95,8 @@ BandwidthLimitedCause GetBandwidthLimitedCause(LossBasedState loss_based_state,
+ case LossBasedState::kDelayBasedEstimate:
+ return BandwidthLimitedCause::kDelayBasedLimited;
+ }
++ // just return something by default
++ return BandwidthLimitedCause::kLossLimitedBwe;
+ }
+
+ } // namespace
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc
index 61ed84ebb532521ce9a4af69355807b04f228859..4d06c61ce6bffcd89b767932e9c7987cea6cceab 100644
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc
@@ -587,10 +601,10 @@ index 61ed84ebb532521ce9a4af69355807b04f228859..4d06c61ce6bffcd89b767932e9c7987c
ScreenCastPortal::ScreenCastPortal(CaptureType type, PortalNotifier* notifier)
diff --git a/third_party/libwebrtc/modules/pacing/bitrate_prober.cc b/third_party/libwebrtc/modules/pacing/bitrate_prober.cc
-index 3151a35075e57bad9d344f45841b61b278577a1c..fe36a4f749cf91af662fea3a96474e1ebf7ad8f0 100644
+index 17729b57752b07f9ae44da717c136a05a72e89e1..ee1ca9a5b8f3dd01a4e0b8db3418fc664bd7d8fe 100644
--- a/third_party/libwebrtc/modules/pacing/bitrate_prober.cc
+++ b/third_party/libwebrtc/modules/pacing/bitrate_prober.cc
-@@ -69,6 +69,7 @@ bool BitrateProber::ReadyToSetActiveState(DataSize packet_size) const {
+@@ -84,6 +84,7 @@ bool BitrateProber::ReadyToSetActiveState(DataSize packet_size) const {
return packet_size >=
std::min(RecommendedMinProbeSize(), config_.min_packet_size.Get());
}
@@ -599,10 +613,10 @@ index 3151a35075e57bad9d344f45841b61b278577a1c..fe36a4f749cf91af662fea3a96474e1e
void BitrateProber::OnIncomingPacket(DataSize packet_size) {
diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc
-index f1e4eddb4b9d8855f6accf24ef980cbc11d0077d..b3fde3cda3c7c636b8f37f3778fb3b735a61d66d 100644
+index 598a86d4adc7ac98636cf67705a05e71869b94da..b52fc1e14eb0842c3a374599477196e70e34355c 100644
--- a/third_party/libwebrtc/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc
+++ b/third_party/libwebrtc/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc
-@@ -38,6 +38,7 @@ std::unique_ptr<VideoRtpDepacketizer> CreateVideoRtpDepacketizer(
+@@ -47,6 +47,7 @@ std::unique_ptr<VideoRtpDepacketizer> CreateVideoRtpDepacketizer(
return std::make_unique<VideoRtpDepacketizerGeneric>();
}
RTC_CHECK_NOTREACHED();
@@ -611,7 +625,7 @@ index f1e4eddb4b9d8855f6accf24ef980cbc11d0077d..b3fde3cda3c7c636b8f37f3778fb3b73
} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender.cc
-index bdb79fe8ccc9c8c1dd58b5216030cd78aa13fe2a..bfb6754b4bc0947a9df185904f8fed66ea716c52 100644
+index 4972aa0802dbdc44e201f2bdd5c60cdb81ef48f4..8efa211ad46ca3200aade0340f9f7de7928ef8cf 100644
--- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -138,6 +138,7 @@ bool IsNonVolatile(RTPExtensionType type) {
@@ -623,10 +637,10 @@ index bdb79fe8ccc9c8c1dd58b5216030cd78aa13fe2a..bfb6754b4bc0947a9df185904f8fed66
bool HasBweExtension(const RtpHeaderExtensionMap& extensions_map) {
diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc
-index a0f1af5243a7f73f414d4401f27e1945235d3278..83ba1e5f60fe55db5fa8b953522ae7a9757e81df 100644
+index 9d2258dc66eddbfaf6c7eced1c2492ffb3c5951b..b4cb70f488118c5a931743313224413399987770 100644
--- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc
+++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc
-@@ -45,6 +45,7 @@ namespace {
+@@ -47,6 +47,7 @@ namespace {
return "audio_cn";
}
RTC_CHECK_NOTREACHED();
@@ -659,10 +673,10 @@ index 5aebd2c5268e8c58b07be4bc393f83ac5abd1c09..8d18446430ff4b7f6d0d669416e3493d
TemporalLayersChecker::TemporalLayersChecker(int num_temporal_layers)
diff --git a/third_party/libwebrtc/video/adaptation/video_stream_encoder_resource_manager.cc b/third_party/libwebrtc/video/adaptation/video_stream_encoder_resource_manager.cc
-index 46db6867033faaa9be96738d2999a7010af75da7..4178664b9c47da2c9792858c60cc38f26ecdb7ab 100644
+index eaeb0d5a467194de607fec3ed7d39c23ed2d9077..b5434b96ac1899f5ef650f5de1e274d4e89e30da 100644
--- a/third_party/libwebrtc/video/adaptation/video_stream_encoder_resource_manager.cc
+++ b/third_party/libwebrtc/video/adaptation/video_stream_encoder_resource_manager.cc
-@@ -63,6 +63,7 @@ std::string ToString(VideoAdaptationReason reason) {
+@@ -64,6 +64,7 @@ std::string ToString(VideoAdaptationReason reason) {
return "cpu";
}
RTC_CHECK_NOTREACHED();
diff --git a/0011-bsc-991344-Rpi3-Firefox-crashes-after-a-few-seconds-.patch b/0011-bsc-991344-Rpi3-Firefox-crashes-after-a-few-seconds-.patch
index 8a2fcf9061e4..c8abdbce50d4 100644
--- a/0011-bsc-991344-Rpi3-Firefox-crashes-after-a-few-seconds-.patch
+++ b/0011-bsc-991344-Rpi3-Firefox-crashes-after-a-few-seconds-.patch
@@ -10,10 +10,10 @@ bmo#1302554 - ARM/AARCH64: Firefox crashes on NULL nsIChannel** result pointer i
1 file changed, 6 insertions(+)
diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp
-index 8426135e0d08bbe697895798f38cc6ec15a96d94..3a151de880f7f841ed345c49fea2693b775a17cd 100644
+index 07dde502278bbc12ed5ead2efe1944c02703fab2..a9d0d2e2e37efa8866597caedb8e4c571e65a585 100644
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
-@@ -1152,7 +1152,13 @@ nsresult nsIOService::NewChannelFromURIWithProxyFlagsInternal(
+@@ -1163,7 +1163,13 @@ nsresult nsIOService::NewChannelFromURIWithProxyFlagsInternal(
}
}
diff --git a/0012-mozilla-fix-aarch64-libopus.patch.patch b/0012-mozilla-fix-aarch64-libopus.patch.patch
index 6012dfbf58ba..f5913e7b5e7c 100644
--- a/0012-mozilla-fix-aarch64-libopus.patch.patch
+++ b/0012-mozilla-fix-aarch64-libopus.patch.patch
@@ -8,7 +8,7 @@ Subject: [PATCH] mozilla-fix-aarch64-libopus.patch
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/media/libopus/silk/arm/arm_silk_map.c b/media/libopus/silk/arm/arm_silk_map.c
-index 0b9bfec2ca974768c59e09f448aca81ceb1d8f60..f55a96da61ebf5074089afd3680a3c5234e70b82 100644
+index a91f79b59f70f4f892aa1e373a335571d1c83ae6..a6c4193efc71ddb2b9cd111eedc10bc17580c165 100644
--- a/media/libopus/silk/arm/arm_silk_map.c
+++ b/media/libopus/silk/arm/arm_silk_map.c
@@ -28,7 +28,7 @@ POSSIBILITY OF SUCH DAMAGE.
diff --git a/0016-Fix-building-with-PGO-when-using-GCC.patch b/0016-Fix-building-with-PGO-when-using-GCC.patch
index 67f7d704b19d..bb1e79b75440 100644
--- a/0016-Fix-building-with-PGO-when-using-GCC.patch
+++ b/0016-Fix-building-with-PGO-when-using-GCC.patch
@@ -10,12 +10,12 @@ Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/build/moz.configure/lto-pgo.configure b/build/moz.configure/lto-pgo.configure
-index 99355877447e48e8c7f8569794e99375ad5b254d..879e08e7c3b1a00f8bf13cf48bfc345fc80abdb0 100644
+index 5048b367e2686169f7d3f4644b7f629d1553004c..422f7e65b6dc94d223705f954682abe2046522b1 100644
--- a/build/moz.configure/lto-pgo.configure
+++ b/build/moz.configure/lto-pgo.configure
-@@ -83,11 +83,12 @@ set_config("PGO_PROFILE_PATH", pgo_profile_path)
- @imports("multiprocessing")
- def pgo_flags(compiler, profdata, target_is_windows):
+@@ -130,11 +130,12 @@ def pgo_flags(
+ compiler, linker, target, profdata, orderfile, target_is_windows, pgo_temporal
+ ):
if compiler.type == "gcc":
+ profile_use = "-fprofile-use"
return namespace(
@@ -29,7 +29,7 @@ index 99355877447e48e8c7f8569794e99375ad5b254d..879e08e7c3b1a00f8bf13cf48bfc345f
if compiler.type in ("clang-cl", "clang"):
diff --git a/build/pgo/profileserver.py b/build/pgo/profileserver.py
-index 94f54cbd17369b2d9ebb6b808f8164a44f07589a..c37be30c21326b035cb1b67b090a89061c152dde 100755
+index aae5e7997dadbee823352d644e5c2330e077ac44..b38f03b0743d48c8a62ada6969d527250c5e3e53 100755
--- a/build/pgo/profileserver.py
+++ b/build/pgo/profileserver.py
@@ -11,7 +11,7 @@ import subprocess
@@ -41,7 +41,7 @@ index 94f54cbd17369b2d9ebb6b808f8164a44f07589a..c37be30c21326b035cb1b67b090a8906
from mozfile import TemporaryDirectory
from mozhttpd import MozHttpd
from mozprofile import FirefoxProfile, Preferences
-@@ -87,9 +87,22 @@ if __name__ == "__main__":
+@@ -97,9 +97,22 @@ if __name__ == "__main__":
locations = ServerLocations()
locations.add_host(host="127.0.0.1", port=PORT, options="primary,privileged")
@@ -67,7 +67,7 @@ index 94f54cbd17369b2d9ebb6b808f8164a44f07589a..c37be30c21326b035cb1b67b090a8906
with TemporaryDirectory() as profilePath:
# TODO: refactor this into mozprofile
-@@ -213,6 +226,11 @@ if __name__ == "__main__":
+@@ -220,6 +233,11 @@ if __name__ == "__main__":
print("Firefox exited successfully, but produced a crashreport")
sys.exit(1)
diff --git a/0017-LTO-Only-enable-LTO-for-Rust-when-complete-build-use.patch b/0017-LTO-Only-enable-LTO-for-Rust-when-complete-build-use.patch
index acbc9e03f537..ce4fe76e4752 100644
--- a/0017-LTO-Only-enable-LTO-for-Rust-when-complete-build-use.patch
+++ b/0017-LTO-Only-enable-LTO-for-Rust-when-complete-build-use.patch
@@ -9,7 +9,7 @@ Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
1 file changed, 2 insertions(+)
diff --git a/config/makefiles/rust.mk b/config/makefiles/rust.mk
-index d0f52d6c1b99e34fb7e9f162583c53c7f4ce10e3..ea2efb784b420d8905d98893cdc9dfcac134a563 100644
+index 524bc436fdf361a0f6bca339393392786efe070c..205f746ef781119faf602f656aefc68d020aa1f9 100644
--- a/config/makefiles/rust.mk
+++ b/config/makefiles/rust.mk
@@ -82,6 +82,7 @@ endif
diff --git a/0018-Bug-1516081-Disable-watchdog-during-FDO-train.patch b/0018-Bug-1516081-Disable-watchdog-during-FDO-train.patch
index 20bfd277c896..c989e9bfbb37 100644
--- a/0018-Bug-1516081-Disable-watchdog-during-FDO-train.patch
+++ b/0018-Bug-1516081-Disable-watchdog-during-FDO-train.patch
@@ -9,10 +9,10 @@ Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1516081
1 file changed, 7 insertions(+)
diff --git a/toolkit/components/terminator/nsTerminator.cpp b/toolkit/components/terminator/nsTerminator.cpp
-index 3a8f9f4ba63e64695083a70ccfe38cc8baeb7654..b96d9ef138b42fb114d755218c2622b40d6a3bee 100644
+index 6339962022cbb71a3dd990b0ddb4bf8ddb1f2c24..d68b7c15dcac3441d4720e6b34f481c6f02fdc00 100644
--- a/toolkit/components/terminator/nsTerminator.cpp
+++ b/toolkit/components/terminator/nsTerminator.cpp
-@@ -460,6 +460,13 @@ void nsTerminator::StartWatchdog() {
+@@ -332,6 +332,13 @@ void nsTerminator::StartWatchdog() {
}
#endif
diff --git a/0019-Bug-559213-Support-system-av1.patch b/0019-Bug-559213-Support-system-av1.patch
index 4583c68bd089..da08f284fe51 100644
--- a/0019-Bug-559213-Support-system-av1.patch
+++ b/0019-Bug-559213-Support-system-av1.patch
@@ -2,21 +2,55 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Thomas Deutschmann <whissi@gentoo.org>
Date: Mon, 6 Apr 2020 19:36:02 +0200
Subject: [PATCH] Bug 559213 - Support system av1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
Allow building against system-wide av1.
Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1559213
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
+Signed-off-by: Björn Bidar <bjorn.bidar@jolla.com>
---
- config/external/moz.build | 5 +++--
- config/system-headers.mozbuild | 8 ++++++++
- dom/media/platforms/moz.build | 5 +++++
- media/ffvpx/libavcodec/moz.build | 12 ++++++++----
- toolkit/moz.configure | 20 ++++++++++++++++++--
- 5 files changed, 42 insertions(+), 8 deletions(-)
+ config/external/gkcodecs/gkcodecs.symbols | 2 ++
+ config/external/gkcodecs/moz.build | 2 ++
+ config/external/moz.build | 5 +++--
+ config/system-headers.mozbuild | 5 +++++
+ dom/media/platforms/moz.build | 5 +++++
+ media/ffvpx/libavcodec/moz.build | 14 ++++++++++----
+ toolkit/moz.configure | 20 ++++++++++++++++++--
+ 7 files changed, 45 insertions(+), 8 deletions(-)
+diff --git a/config/external/gkcodecs/gkcodecs.symbols b/config/external/gkcodecs/gkcodecs.symbols
+index 8aa191be9e30bd63d0ebf37a7278470c3519f5be..dc4b414889c41de8feb4963f60b8a8598f113bdc 100644
+--- a/config/external/gkcodecs/gkcodecs.symbols
++++ b/config/external/gkcodecs/gkcodecs.symbols
+@@ -1,4 +1,5 @@
+ # libaom symbols
++#ifndef MOZ_SYSTEM_AV1
+ aom_codec_av1_cx
+ aom_codec_av1_dx
+ aom_codec_build_config
+@@ -24,6 +25,7 @@ aom_img_free
+ aom_img_plane_height
+ aom_img_plane_width
+ aom_img_wrap
++#endif
+ #if defined(X86_WIN64)
+ aom_winx64_fstcw
+ #endif
+diff --git a/config/external/gkcodecs/moz.build b/config/external/gkcodecs/moz.build
+index 040f6809deca60533771b1397dbaaccfadfbc9a9..39712e816120ee63a2e4d13e0c31630f9da38e98 100644
+--- a/config/external/gkcodecs/moz.build
++++ b/config/external/gkcodecs/moz.build
+@@ -16,3 +16,5 @@ SHARED_LIBRARY_NAME = "gkcodecs"
+ SYMBOLS_FILE = "gkcodecs.symbols"
+ if CONFIG["MOZ_SYSTEM_LIBVPX"]:
+ DEFINES["MOZ_SYSTEM_LIBVPX"] = True
++if CONFIG["MOZ_SYSTEM_AV1"]:
++ DEFINES["MOZ_SYSTEM_AV1"] = True
diff --git a/config/external/moz.build b/config/external/moz.build
-index fe765d1fa0130296b9b89129ad5bf5f55a885823..58396762e2e6950855816e4ce175b5cb29d4d5ce 100644
+index b6e174c5d65aec62d5057054593fb8506e3689f3..49fe67a7ada6857ad4af57755905075c4756ee59 100644
--- a/config/external/moz.build
+++ b/config/external/moz.build
@@ -40,8 +40,9 @@ if not CONFIG["MOZ_SYSTEM_LIBVPX"]:
@@ -32,29 +66,26 @@ index fe765d1fa0130296b9b89129ad5bf5f55a885823..58396762e2e6950855816e4ce175b5cb
if not CONFIG["MOZ_SYSTEM_PNG"]:
external_dirs += ["media/libpng"]
diff --git a/config/system-headers.mozbuild b/config/system-headers.mozbuild
-index 20145e89af1bbb02476d84340088bb7ceba7af8e..4b61063cf92a2adabb7b552328420aefbfc93242 100644
+index aa17660a106c0c7d99fc19aea2b0dac531dd6a9e..de316e2027dfa8199e6b9d05d256254fb93eaa9c 100644
--- a/config/system-headers.mozbuild
+++ b/config/system-headers.mozbuild
-@@ -1294,6 +1294,14 @@ if CONFIG['MOZ_ENABLE_LIBPROXY']:
- 'proxy.h',
+@@ -1304,6 +1304,11 @@ if CONFIG["MOZ_ENABLE_LIBPROXY"]:
+ "proxy.h",
]
-+if CONFIG['MOZ_SYSTEM_AV1']:
++if CONFIG["MOZ_SYSTEM_AV1"]:
+ system_headers += [
-+ 'aom/aom_decoder.h',
-+ 'aom/aomdx.h',
-+ 'aom/aom_image.h',
-+ 'dav1d/dav1d.h',
++ "dav1d/dav1d.h",
+ ]
+
- if CONFIG['MOZ_SYSTEM_LIBVPX']:
+ if CONFIG["MOZ_SYSTEM_ICU"]:
system_headers += [
- 'vpx_mem/vpx_mem.h',
+ "unicode/calendar.h",
diff --git a/dom/media/platforms/moz.build b/dom/media/platforms/moz.build
-index c71f22a22eeead703192edfb710cc6113d42c11c..e91f57de9017e74436b03b769f04668d9dc2a869 100644
+index 9a4f19aa4b30ebb520300e05997bf12576d9f2ff..547040577d80d78a34068fd2a58b9e29b9faacab 100644
--- a/dom/media/platforms/moz.build
+++ b/dom/media/platforms/moz.build
-@@ -80,6 +80,11 @@ if CONFIG["MOZ_AV1"]:
+@@ -71,6 +71,11 @@ if CONFIG["MOZ_AV1"]:
"agnostic/AOMDecoder.cpp",
"agnostic/DAV1DDecoder.cpp",
]
@@ -67,10 +98,10 @@ index c71f22a22eeead703192edfb710cc6113d42c11c..e91f57de9017e74436b03b769f04668d
if CONFIG["MOZ_OMX"]:
EXPORTS += [
diff --git a/media/ffvpx/libavcodec/moz.build b/media/ffvpx/libavcodec/moz.build
-index 845d0030229cc2a81eaa1a0ca341d0175af3d976..3b5d5153fc9f49ed729eb5685e8d677932af3920 100644
+index 6f09049a6068daafb1564bfa3d81a06e0754170d..07c0bab34951c160cdb7f51680fe549b58a1de2b 100644
--- a/media/ffvpx/libavcodec/moz.build
+++ b/media/ffvpx/libavcodec/moz.build
-@@ -118,10 +118,14 @@ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
+@@ -119,10 +119,16 @@ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
'vp9recon.c',
'vpx_rac.c',
]
@@ -81,6 +112,8 @@ index 845d0030229cc2a81eaa1a0ca341d0175af3d976..3b5d5153fc9f49ed729eb5685e8d6779
+ if CONFIG["MOZ_SYSTEM_AV1"]:
+ CFLAGS += CONFIG['MOZ_SYSTEM_LIBDAV1D_CFLAGS']
+ OS_LIBS += CONFIG['MOZ_SYSTEM_LIBDAV1D_LIBS']
++ CFLAGS += CONFIG["MOZ_SYSTEM_LIBAOM_CFLAGS"]
++ OS_LIBS += CONFIG["MOZ_SYSTEM_LIBAOM_LIBS"]
+ else:
+ USE_LIBS += [
+ 'dav1d',
@@ -90,10 +123,10 @@ index 845d0030229cc2a81eaa1a0ca341d0175af3d976..3b5d5153fc9f49ed729eb5685e8d6779
LOCAL_INCLUDES += ['/media/mozva']
SOURCES += [
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
-index 8b462ecde463fc4ac31278d94daaad5e513d7c00..eb7ae84b5d65df80e23b8ab503ffe0576c2a30a0 100644
+index 7282b80d811eb74aa6b51b41aa1d47d3b36bde08..26a624ed9948dd6a74173f71859617f808dcab3d 100644
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
-@@ -749,14 +749,29 @@ def av1(value):
+@@ -756,14 +756,29 @@ def av1(value):
if value:
return True
@@ -125,7 +158,7 @@ index 8b462ecde463fc4ac31278d94daaad5e513d7c00..eb7ae84b5d65df80e23b8ab503ffe057
def dav1d_nasm(target):
if target.cpu in ("x86", "x86_64"):
return namespace(version="2.14", what="AV1")
-@@ -766,6 +781,7 @@ set_config("MOZ_DAV1D_ASM", dav1d_asm)
+@@ -773,6 +788,7 @@ set_config("MOZ_DAV1D_ASM", dav1d_asm)
set_define("MOZ_DAV1D_ASM", dav1d_asm)
set_config("MOZ_AV1", av1)
set_define("MOZ_AV1", av1)
diff --git a/0020-Bug-847568-Support-system-harfbuzz.patch b/0020-Bug-847568-Support-system-harfbuzz.patch
index 7776d9a12603..c8e6f1b4ea88 100644
--- a/0020-Bug-847568-Support-system-harfbuzz.patch
+++ b/0020-Bug-847568-Support-system-harfbuzz.patch
@@ -8,7 +8,7 @@ Allow building against system-wide harfbuzz.
Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=847568
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
---
- config/system-headers.mozbuild | 7 +++++++
+ config/system-headers.mozbuild | 8 ++++++++
dom/base/moz.build | 3 +++
gfx/moz.build | 4 +++-
gfx/skia/generate_mozbuild.py | 3 +++
@@ -18,31 +18,32 @@ Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
netwerk/dns/moz.build | 3 +++
toolkit/library/moz.build | 3 +++
toolkit/moz.configure | 8 ++++++++
- 10 files changed, 39 insertions(+), 1 deletion(-)
+ 10 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/config/system-headers.mozbuild b/config/system-headers.mozbuild
-index 4b61063cf92a2adabb7b552328420aefbfc93242..f35c684e9ef6693804d8e026d8ff3fa8236f6444 100644
+index de316e2027dfa8199e6b9d05d256254fb93eaa9c..4af5ccf20d07c73ef97acae493c14340cfa30603 100644
--- a/config/system-headers.mozbuild
+++ b/config/system-headers.mozbuild
-@@ -1238,6 +1238,13 @@ if CONFIG['OS_TARGET'] == 'Android':
- 'vr/gvr/capi/include/gvr.h',
+@@ -1253,6 +1253,14 @@ if CONFIG["OS_TARGET"] == "Android":
+ "vr/gvr/capi/include/gvr.h",
]
-+if CONFIG['MOZ_SYSTEM_HARFBUZZ']:
++
++if CONFIG["MOZ_SYSTEM_HARFBUZZ"]:
+ system_headers += [
-+ 'harfbuzz/hb-glib.h',
-+ 'harfbuzz/hb-ot.h',
-+ 'harfbuzz/hb.h',
++ "harfbuzz/hb-glib.h",
++ "harfbuzz/hb-ot.h",
++ "harfbuzz/hb.h",
+ ]
+
- if CONFIG['MOZ_JACK']:
+ if CONFIG["MOZ_JACK"]:
system_headers += [
- 'jack/jack.h',
+ "jack/jack.h",
diff --git a/dom/base/moz.build b/dom/base/moz.build
-index f5dfc1b1ae258491c635a0f7f767d67ec6574826..d158b81012bc5fabd5f2668d7674b3a2d1c60d88 100644
+index e2cf2dfb78c0d8f2ceb1a2ff58fd498a567dee45..fae8c8ff924c418e1d499ab7d508e41ecce3abf9 100644
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
-@@ -608,6 +608,9 @@ FINAL_LIBRARY = "xul"
+@@ -615,6 +615,9 @@ FINAL_LIBRARY = "xul"
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"]
@@ -75,7 +76,7 @@ index 56ea317bedfc68d504248b5d3b79cd36e8bc388a..6cc19f84709bbe3be4ff830e3a6dd291
"thebes",
"ipc",
diff --git a/gfx/skia/generate_mozbuild.py b/gfx/skia/generate_mozbuild.py
-index 39675ea9c2e939580f7e11fe17c10b0b49f4ed4c..6262eec29395c873bd1d10377a54b99ca16e92e5 100755
+index c161d24df853934a64ab363658c878e3257a8afb..8c7dd395b371a5a2347ffcd9133db56ecc55df0c 100755
--- a/gfx/skia/generate_mozbuild.py
+++ b/gfx/skia/generate_mozbuild.py
@@ -91,6 +91,9 @@ if CONFIG['CC_TYPE'] in ('clang', 'clang-cl'):
@@ -89,7 +90,7 @@ index 39675ea9c2e939580f7e11fe17c10b0b49f4ed4c..6262eec29395c873bd1d10377a54b99c
LOCAL_INCLUDES += [
"/gfx/cairo/cairo/src",
diff --git a/gfx/skia/moz.build b/gfx/skia/moz.build
-index 1d92936263a091eac0dc90fdb0038982e711d5c3..afef373e62af4273aa2b21f3fd3103dc5670ea00 100644
+index 83aa2957a938e762916fb32c5454fb4791db7c1b..0859316a1f09034e57792fa5505d072bae550acc 100644
--- a/gfx/skia/moz.build
+++ b/gfx/skia/moz.build
@@ -601,6 +601,9 @@ if CONFIG['CC_TYPE'] in ('clang', 'clang-cl'):
@@ -103,10 +104,10 @@ index 1d92936263a091eac0dc90fdb0038982e711d5c3..afef373e62af4273aa2b21f3fd3103dc
LOCAL_INCLUDES += [
"/gfx/cairo/cairo/src",
diff --git a/gfx/thebes/moz.build b/gfx/thebes/moz.build
-index 97f02d59f51a7e9b06a852963cf03a8463df09f0..3067b49c8d3d069e74acd2baa04eaaf2c95094f9 100644
+index 3d99906827c63cfafea5c0cd394732c9414ed730..acb7094e2a39e18681df294b0ac01e7b87a11b30 100644
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
-@@ -292,6 +292,9 @@ LOCAL_INCLUDES += CONFIG["SKIA_INCLUDES"]
+@@ -302,6 +302,9 @@ LOCAL_INCLUDES += CONFIG["SKIA_INCLUDES"]
DEFINES["GRAPHITE2_STATIC"] = True
@@ -117,7 +118,7 @@ index 97f02d59f51a7e9b06a852963cf03a8463df09f0..3067b49c8d3d069e74acd2baa04eaaf2
include("/tools/fuzzing/libfuzzer-config.mozbuild")
diff --git a/intl/unicharutil/util/moz.build b/intl/unicharutil/util/moz.build
-index 2bbd00415cae9d6a27b66d9eef50add3ada9ba96..f66bd37695d41eea709abea1239dfcd2cbb503d1 100644
+index 2396210428ee11b660fce0cbeba9a119b9f7bcb2..092baac6f79c65aff378a97149daa7844d327a49 100644
--- a/intl/unicharutil/util/moz.build
+++ b/intl/unicharutil/util/moz.build
@@ -24,6 +24,9 @@ UNIFIED_SOURCES += [
@@ -131,10 +132,10 @@ index 2bbd00415cae9d6a27b66d9eef50add3ada9ba96..f66bd37695d41eea709abea1239dfcd2
GeneratedFile(
diff --git a/netwerk/dns/moz.build b/netwerk/dns/moz.build
-index 17612ff1b396891c8942f53d3f39fbca8bdca6cb..d6d51948da54c7fbca53662050d33019e7e0dea6 100644
+index c926d14707d15d06e24be4bda7577578904373c4..5082238fbcf9a275066e6878a67e29bbe830f169 100644
--- a/netwerk/dns/moz.build
+++ b/netwerk/dns/moz.build
-@@ -109,4 +109,7 @@ LOCAL_INCLUDES += [
+@@ -119,4 +119,7 @@ LOCAL_INCLUDES += [
"/netwerk/protocol/http",
]
@@ -143,10 +144,10 @@ index 17612ff1b396891c8942f53d3f39fbca8bdca6cb..d6d51948da54c7fbca53662050d33019
+
USE_LIBS += ["icu"]
diff --git a/toolkit/library/moz.build b/toolkit/library/moz.build
-index da1d8c47f83e2f23cd802615ab8fff822f6e05c8..7ee842def285a9a7fc805758e9f73494c0a59224 100644
+index 9fa86b386b613d3dde8429b2c479763ed435f36c..b0dfb79025db9b35ea00254001658c97c48b4539 100644
--- a/toolkit/library/moz.build
+++ b/toolkit/library/moz.build
-@@ -286,6 +286,9 @@ if CONFIG["MOZ_ANDROID_GOOGLE_VR"]:
+@@ -288,6 +288,9 @@ if CONFIG["MOZ_ANDROID_GOOGLE_VR"]:
"-lgvr",
]
@@ -157,10 +158,10 @@ index da1d8c47f83e2f23cd802615ab8fff822f6e05c8..7ee842def285a9a7fc805758e9f73494
OS_LIBS += CONFIG["MOZ_JPEG_LIBS"]
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
-index eb7ae84b5d65df80e23b8ab503ffe0576c2a30a0..5c461d746a7718befe988d48364ea5d74c0b6d48 100644
+index 26a624ed9948dd6a74173f71859617f808dcab3d..3ecba6340a007d7475cec011ad2a4e35f190fbcf 100644
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
-@@ -678,6 +678,14 @@ def freetype2_combined_info(fontconfig_info, freetype2_info):
+@@ -685,6 +685,14 @@ def freetype2_combined_info(fontconfig_info, freetype2_info):
set_define("MOZ_HAVE_FREETYPE2", depends_if(freetype2_info)(lambda _: True))
diff --git a/0021-Bug-847568-Support-system-graphite2.patch b/0021-Bug-847568-Support-system-graphite2.patch
index 6a1198412252..d5b13ae90a14 100644
--- a/0021-Bug-847568-Support-system-graphite2.patch
+++ b/0021-Bug-847568-Support-system-graphite2.patch
@@ -10,32 +10,31 @@ Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
---
config/system-headers.mozbuild | 6 ++++++
gfx/graphite2/geckoextra/moz.build | 21 +++++++++++++++++++++
- gfx/graphite2/moz-gr-update.sh | 7 ++++++-
gfx/moz.build | 6 +++++-
gfx/thebes/moz.build | 5 ++++-
old-configure.in | 21 +++++++++++++++++++++
toolkit/library/moz.build | 3 +++
toolkit/moz.configure | 13 +++++++++++++
- 8 files changed, 79 insertions(+), 3 deletions(-)
+ 7 files changed, 73 insertions(+), 2 deletions(-)
create mode 100644 gfx/graphite2/geckoextra/moz.build
diff --git a/config/system-headers.mozbuild b/config/system-headers.mozbuild
-index f35c684e9ef6693804d8e026d8ff3fa8236f6444..faac04e9d6ab8af7698aea7b3b0ec92a5b364227 100644
+index 4af5ccf20d07c73ef97acae493c14340cfa30603..4bd823dafcbcffcbae5479336ac2980a54f0fb8a 100644
--- a/config/system-headers.mozbuild
+++ b/config/system-headers.mozbuild
-@@ -1245,6 +1245,12 @@ if CONFIG['MOZ_SYSTEM_HARFBUZZ']:
- 'harfbuzz/hb.h',
+@@ -1261,6 +1261,12 @@ if CONFIG["MOZ_SYSTEM_HARFBUZZ"]:
+ "harfbuzz/hb.h",
]
-+if CONFIG['MOZ_SYSTEM_GRAPHITE2']:
++if CONFIG["MOZ_SYSTEM_GRAPHITE2"]:
+ system_headers += [
-+ 'graphite2/Font.h',
-+ 'graphite2/Segment.h',
++ "graphite2/Font.h",
++ "graphite2/Segment.h",
+ ]
+
- if CONFIG['MOZ_JACK']:
+ if CONFIG["MOZ_JACK"]:
system_headers += [
- 'jack/jack.h',
+ "jack/jack.h",
diff --git a/gfx/graphite2/geckoextra/moz.build b/gfx/graphite2/geckoextra/moz.build
new file mode 100644
index 0000000000000000000000000000000000000000..24e8d7a03274aa43ddbd64b4e740a476244b0bf0
@@ -63,36 +62,6 @@ index 0000000000000000000000000000000000000000..24e8d7a03274aa43ddbd64b4e740a476
+AllowCompilerWarnings()
+
+FINAL_LIBRARY = 'gkmedias'
-diff --git a/gfx/graphite2/moz-gr-update.sh b/gfx/graphite2/moz-gr-update.sh
-index b91d9c161cc71e89024dad9fd87e358a147d3593..a97e6eb20322f952bd504b51faf92dc72735e943 100755
---- a/gfx/graphite2/moz-gr-update.sh
-+++ b/gfx/graphite2/moz-gr-update.sh
-@@ -1,6 +1,7 @@
- #!/bin/bash
-
- # Script used to update the Graphite2 library in the mozilla source tree
-+# and bump version for --with-system-graphite2
-
- # This script lives in gfx/graphite2, along with the library source,
- # but must be run from the top level of the mozilla-central tree.
-@@ -37,12 +38,16 @@ echo "See" $0 "for update procedure." >> gfx/graphite2/README.mozilla
- #find gfx/graphite2/ -name "*.cpp" -exec perl -p -i -e "s/<cstdio>/<stdio.h>/;s/Windows.h/windows.h/;" {} \;
- #find gfx/graphite2/ -name "*.h" -exec perl -p -i -e "s/<cstdio>/<stdio.h>/;s/Windows.h/windows.h/;" {} \;
-
-+# chase version for --with-system-graphite2
-+perl -p -i -e "s/[0-9]+\,[0-9]+\,[0-9]+/$RELEASE/ and tr/./,/ \
-+ if /GR2_VERSION_REQUIRE/" old-configure.in
-+
- # summarize what's been touched
- echo Updated to $RELEASE.
- echo Here is what changed in the gfx/graphite2 directory:
- echo
-
--hg stat gfx/graphite2
-+hg stat old-configure.in gfx/graphite2
-
- echo
- echo If gfx/graphite2/src/files.mk has changed, please make corresponding
diff --git a/gfx/moz.build b/gfx/moz.build
index 6cc19f84709bbe3be4ff830e3a6dd29189048c6f..14b08dbac3e3f5d3df421d5dd6840673046d0486 100644
--- a/gfx/moz.build
@@ -118,10 +87,10 @@ index 6cc19f84709bbe3be4ff830e3a6dd29189048c6f..14b08dbac3e3f5d3df421d5dd6840673
"thebes",
"ipc",
diff --git a/gfx/thebes/moz.build b/gfx/thebes/moz.build
-index 3067b49c8d3d069e74acd2baa04eaaf2c95094f9..04c75cc7234d242fb56ca95da212e11ccf9c891e 100644
+index acb7094e2a39e18681df294b0ac01e7b87a11b30..f4ad9db9910672348d3c7382fe0b10906546f755 100644
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
-@@ -290,7 +290,10 @@ if CONFIG["MOZ_WAYLAND"]:
+@@ -300,7 +300,10 @@ if CONFIG["MOZ_WAYLAND"]:
LOCAL_INCLUDES += CONFIG["SKIA_INCLUDES"]
@@ -134,10 +103,10 @@ index 3067b49c8d3d069e74acd2baa04eaaf2c95094f9..04c75cc7234d242fb56ca95da212e11c
if CONFIG["MOZ_SYSTEM_HARFBUZZ"]:
CXXFLAGS += CONFIG["MOZ_HARFBUZZ_CFLAGS"]
diff --git a/old-configure.in b/old-configure.in
-index 57a41cb1b28592b761c51d6fbdc6ec0ce4a54936..7d6b36c150eca93b035de97ade08a78e80dd4136 100644
+index 218048fa7398744d06a35ce8793cbc706f8712f8..687668a7c872be3771914a084892786cf164195d 100644
--- a/old-configure.in
+++ b/old-configure.in
-@@ -1141,6 +1141,27 @@ fi
+@@ -886,6 +886,27 @@ fi
AC_DEFINE_UNQUOTED(MOZ_MACBUNDLE_ID,$MOZ_MACBUNDLE_ID)
AC_SUBST(MOZ_MACBUNDLE_ID)
@@ -166,10 +135,10 @@ index 57a41cb1b28592b761c51d6fbdc6ec0ce4a54936..7d6b36c150eca93b035de97ade08a78e
dnl = Child Process Name for IPC
dnl ========================================================
diff --git a/toolkit/library/moz.build b/toolkit/library/moz.build
-index 7ee842def285a9a7fc805758e9f73494c0a59224..1ac8cf64d8e079f7a1a0b57b2042d46285b2c766 100644
+index b0dfb79025db9b35ea00254001658c97c48b4539..48fb67c4c1ad47e7ba83cbfe94c133298f8e8b9c 100644
--- a/toolkit/library/moz.build
+++ b/toolkit/library/moz.build
-@@ -286,6 +286,9 @@ if CONFIG["MOZ_ANDROID_GOOGLE_VR"]:
+@@ -288,6 +288,9 @@ if CONFIG["MOZ_ANDROID_GOOGLE_VR"]:
"-lgvr",
]
@@ -180,10 +149,10 @@ index 7ee842def285a9a7fc805758e9f73494c0a59224..1ac8cf64d8e079f7a1a0b57b2042d462
OS_LIBS += CONFIG["MOZ_HARFBUZZ_LIBS"]
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
-index 5c461d746a7718befe988d48364ea5d74c0b6d48..c15d4dba75c3151fc44145bf5f114e16ca4c147f 100644
+index 3ecba6340a007d7475cec011ad2a4e35f190fbcf..c67be76b8fe11b78533c8a487b93aaea84e6e3d9 100644
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
-@@ -678,6 +678,19 @@ def freetype2_combined_info(fontconfig_info, freetype2_info):
+@@ -685,6 +685,19 @@ def freetype2_combined_info(fontconfig_info, freetype2_info):
set_define("MOZ_HAVE_FREETYPE2", depends_if(freetype2_info)(lambda _: True))
diff --git a/0022-Bug-1611386-Reenable-support-for-enable-system-sqlit.patch b/0022-Bug-1611386-Reenable-support-for-enable-system-sqlit.patch
index fc3c519b853e..c507db0ebc19 100644
--- a/0022-Bug-1611386-Reenable-support-for-enable-system-sqlit.patch
+++ b/0022-Bug-1611386-Reenable-support-for-enable-system-sqlit.patch
@@ -24,11 +24,11 @@ Signed-off-by: Björn Bidar <bjorn.bidar@jolla.com>
9 files changed, 70 insertions(+), 14 deletions(-)
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
-index b3213b8c4498b0467d7863d53c5fc4240e4609be..359fcd671f0ebeba46e2556c99ec11ce067fe23e 100644
+index 725a63981ccb58c5e47c096f39fa686a5ba5a9e8..b9950a85c2542de599f2d2bcb6eea20a658a5727 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
-@@ -145,9 +145,11 @@
- @RESPATH@/update-settings.ini
+@@ -148,9 +148,11 @@
+ #endif
#endif
@RESPATH@/platform.ini
+#ifndef MOZ_SYSTEM_SQLITE
@@ -38,7 +38,7 @@ index b3213b8c4498b0467d7863d53c5fc4240e4609be..359fcd671f0ebeba46e2556c99ec11ce
+#endif
@BINPATH@/@DLL_PREFIX@lgpllibs@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@gkcodecs@DLL_SUFFIX@
- #ifdef MOZ_FFVPX
+ @BINPATH@/@DLL_PREFIX@mozavutil@DLL_SUFFIX@
diff --git a/config/external/sqlite/moz.build b/config/external/sqlite/moz.build
index 6294924c564ae8c2ebc0033895be91069179fcd2..b978fd9caba375242de1be25072b251461010044 100644
--- a/config/external/sqlite/moz.build
@@ -104,7 +104,7 @@ index b7198b1912fdc8d1182a445421aec3450474c23d..3ecc0bb997cf376e996bff2d9c184ecf
// treat them as such.
Release(); // Call is protected by us holding the mutex.
diff --git a/storage/moz.build b/storage/moz.build
-index 38a855fce67ef30924be37f15359442b82dbbd82..0152aa5d39cd13abd36f4c0bf718e230c207dbdf 100644
+index 3dc1cd4bf7d77ff12eef33f3e5b210dc58812952..97892b920edbcefe486c8dd4a0975bd88e2c19f1 100644
--- a/storage/moz.build
+++ b/storage/moz.build
@@ -101,6 +101,12 @@ if CONFIG["MOZ_THUNDERBIRD"] or CONFIG["MOZ_SUITE"]:
@@ -121,10 +121,10 @@ index 38a855fce67ef30924be37f15359442b82dbbd82..0152aa5d39cd13abd36f4c0bf718e230
"/dom/base",
"/third_party/sqlite3/src",
diff --git a/storage/mozStorageConnection.cpp b/storage/mozStorageConnection.cpp
-index 755f6d55a7bcaa7e192c4431469e2003d78a7937..b98ea355a8b0499cbe464f0a755e1735037076f3 100644
+index b0d55b71a55f6bf5f88c00dba905e8348eaf1515..ef429f60bfa3c85d43a675502e8bdef524b51779 100644
--- a/storage/mozStorageConnection.cpp
+++ b/storage/mozStorageConnection.cpp
-@@ -1046,6 +1046,10 @@ nsresult Connection::initializeInternal() {
+@@ -1242,6 +1242,10 @@ nsresult Connection::initializeInternal() {
return convertResultCode(srv);
}
@@ -136,7 +136,7 @@ index 755f6d55a7bcaa7e192c4431469e2003d78a7937..b98ea355a8b0499cbe464f0a755e1735
srv = registerFunctions(mDBConn);
if (srv != SQLITE_OK) {
diff --git a/storage/mozStorageService.cpp b/storage/mozStorageService.cpp
-index ac5a7b17888c48fc1afde78a3713994934763843..66beae8efe4b166b6f696a300139c9ae0d770a68 100644
+index 82a3a7344dff1de7a4120c54124cde71b3139fec..9519e26d525fc0a4163964b01411ab6e609cdecc 100644
--- a/storage/mozStorageService.cpp
+++ b/storage/mozStorageService.cpp
@@ -21,6 +21,7 @@
@@ -180,10 +180,10 @@ index ac5a7b17888c48fc1afde78a3713994934763843..66beae8efe4b166b6f696a300139c9ae
// main thread.
NS_ENSURE_TRUE(NS_IsMainThread(), nullptr);
diff --git a/third_party/sqlite3/src/moz.build b/third_party/sqlite3/src/moz.build
-index 43bda4c89b651d8b959d5db67faccb914e4aa792..838e8851e5c1561755a4325ca3cd3f3f80da79d7 100644
+index 18e306f76051d2257f1ffb846393779fc13183cb..1e1e6386d546004c84be47d932f11b7c14320199 100644
--- a/third_party/sqlite3/src/moz.build
+++ b/third_party/sqlite3/src/moz.build
-@@ -79,6 +79,7 @@ DEFINES['SQLITE_OMIT_BUILTIN_TEST'] = True
+@@ -82,6 +82,7 @@ DEFINES['SQLITE_OMIT_BUILTIN_TEST'] = True
# Try to use a MEMORY temp store when possible. That allows for better
# performance and doesn't suffer from a full separate tmp partition.
# Exclude 32bit platforms due to address space fragmentation issues.
@@ -191,7 +191,7 @@ index 43bda4c89b651d8b959d5db67faccb914e4aa792..838e8851e5c1561755a4325ca3cd3f3f
if CONFIG['OS_TARGET'] == 'Android':
# On Android there's no tmp partition, so always use a MEMORY temp store.
DEFINES['SQLITE_TEMP_STORE'] = 3
-@@ -88,6 +89,7 @@ elif CONFIG['HAVE_64BIT_BUILD']:
+@@ -91,6 +92,7 @@ elif CONFIG['HAVE_64BIT_BUILD']:
# Change the default temp files prefix, to easily distinguish files we created
# vs files created by other Sqlite instances in the system.
@@ -200,10 +200,10 @@ index 43bda4c89b651d8b959d5db67faccb914e4aa792..838e8851e5c1561755a4325ca3cd3f3f
# Enabling sqlite math functions
diff --git a/third_party/sqlite3/src/sqlite.symbols b/third_party/sqlite3/src/sqlite.symbols
-index fc576f30bc6a47db5c8bfbaa77bb117f1bd68011..903d6b29f62528b6ecd762ef69fb5f206cc87fde 100644
+index 6cfe0f9f8814a5045762d6e984ceb1794de3f550..5b1fccd1ec8ff2b3b949199fd22c9e764f2d6eb8 100644
--- a/third_party/sqlite3/src/sqlite.symbols
+++ b/third_party/sqlite3/src/sqlite.symbols
-@@ -39,9 +39,7 @@ sqlite3_column_text16
+@@ -43,9 +43,7 @@ sqlite3_column_text16
sqlite3_column_type
sqlite3_column_value
sqlite3_commit_hook
@@ -214,10 +214,10 @@ index fc576f30bc6a47db5c8bfbaa77bb117f1bd68011..903d6b29f62528b6ecd762ef69fb5f20
sqlite3_complete16
sqlite3_config
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
-index c15d4dba75c3151fc44145bf5f114e16ca4c147f..527925bd8784e0dd33a79e0b7d80a53f424fcf48 100644
+index c67be76b8fe11b78533c8a487b93aaea84e6e3d9..9d691efbc37a08131a7ab0c87aa5c7521cd7112c 100644
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
-@@ -380,6 +380,20 @@ sndio = pkg_check_modules("MOZ_SNDIO", "sndio", when="--enable-sndio")
+@@ -391,6 +391,20 @@ sndio = pkg_check_modules("MOZ_SNDIO", "sndio", when="--enable-sndio")
set_config("MOZ_SNDIO", depends_if(sndio)(lambda _: True))
diff --git a/0023-Bug-1419151-Add-Unity-menubar-support.patch b/0023-Bug-1419151-Add-Unity-menubar-support.patch
deleted file mode 100644
index caeeaeaccdf5..000000000000
--- a/0023-Bug-1419151-Add-Unity-menubar-support.patch
+++ /dev/null
@@ -1,5439 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Bj=C3=B6rn=20Bidar?= <bjorn.bidar@jolla.com>
-Date: Wed, 3 May 2023 01:17:06 +0300
-Subject: [PATCH] Bug 1419151 - Add Unity menubar support
-
----
- browser/base/content/browser-menubar.inc | 7 +-
- browser/base/content/browser.js | 7 +
- .../components/places/content/places.xhtml | 1 +
- dom/xul/XULPopupElement.cpp | 9 +
- dom/xul/moz.build | 5 +
- layout/build/moz.build | 4 +
- modules/libpref/init/all.js | 3 +
- toolkit/content/xul.css | 14 +
- widget/gtk/NativeMenuSupport.cpp | 11 +-
- widget/gtk/NativeMenuSupport.h | 31 +
- widget/gtk/components.conf | 8 +
- widget/gtk/moz.build | 10 +
- widget/gtk/nsDbusmenu.cpp | 61 ++
- widget/gtk/nsDbusmenu.h | 101 +++
- widget/gtk/nsMenu.cpp | 795 ++++++++++++++++++
- widget/gtk/nsMenu.h | 123 +++
- widget/gtk/nsMenuBar.cpp | 548 ++++++++++++
- widget/gtk/nsMenuBar.h | 111 +++
- widget/gtk/nsMenuContainer.cpp | 170 ++++
- widget/gtk/nsMenuContainer.h | 70 ++
- widget/gtk/nsMenuItem.cpp | 766 +++++++++++++++++
- widget/gtk/nsMenuItem.h | 80 ++
- widget/gtk/nsMenuObject.cpp | 653 ++++++++++++++
- widget/gtk/nsMenuObject.h | 169 ++++
- widget/gtk/nsMenuSeparator.cpp | 82 ++
- widget/gtk/nsMenuSeparator.h | 37 +
- widget/gtk/nsNativeMenuDocListener.cpp | 347 ++++++++
- widget/gtk/nsNativeMenuDocListener.h | 152 ++++
- widget/gtk/nsNativeMenuService.cpp | 478 +++++++++++
- widget/gtk/nsNativeMenuService.h | 85 ++
- widget/gtk/nsWindow.cpp | 4 +
- widget/gtk/nsWindow.h | 6 +
- widget/moz.build | 5 +
- widget/nsINativeMenuService.h | 39 +
- widget/nsWidgetsCID.h | 8 +
- xpcom/ds/NativeMenuAtoms.py | 9 +
- xpcom/ds/StaticAtoms.py | 3 +-
- xpfe/appshell/AppWindow.cpp | 2 +-
- 38 files changed, 5010 insertions(+), 4 deletions(-)
- create mode 100644 widget/gtk/NativeMenuSupport.h
- create mode 100644 widget/gtk/nsDbusmenu.cpp
- create mode 100644 widget/gtk/nsDbusmenu.h
- create mode 100644 widget/gtk/nsMenu.cpp
- create mode 100644 widget/gtk/nsMenu.h
- create mode 100644 widget/gtk/nsMenuBar.cpp
- create mode 100644 widget/gtk/nsMenuBar.h
- create mode 100644 widget/gtk/nsMenuContainer.cpp
- create mode 100644 widget/gtk/nsMenuContainer.h
- create mode 100644 widget/gtk/nsMenuItem.cpp
- create mode 100644 widget/gtk/nsMenuItem.h
- create mode 100644 widget/gtk/nsMenuObject.cpp
- create mode 100644 widget/gtk/nsMenuObject.h
- create mode 100644 widget/gtk/nsMenuSeparator.cpp
- create mode 100644 widget/gtk/nsMenuSeparator.h
- create mode 100644 widget/gtk/nsNativeMenuDocListener.cpp
- create mode 100644 widget/gtk/nsNativeMenuDocListener.h
- create mode 100644 widget/gtk/nsNativeMenuService.cpp
- create mode 100644 widget/gtk/nsNativeMenuService.h
- create mode 100644 widget/nsINativeMenuService.h
- create mode 100644 xpcom/ds/NativeMenuAtoms.py
-
-diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc
-index 521e891713280b5b2bee1793949432de70e6301c..399a79d1a2d46fa3f3473f5c2338402e2628f221 100644
---- a/browser/base/content/browser-menubar.inc
-+++ b/browser/base/content/browser-menubar.inc
-@@ -7,7 +7,12 @@
- # On macOS, we don't track whether activation of the native menubar happened
- # with the keyboard.
- #ifndef XP_MACOSX
-- onpopupshowing="if (event.target.parentNode.parentNode == this)
-+ onpopupshowing="if (event.target.parentNode.parentNode == this &amp;&amp;
-+#ifdef MOZ_WIDGET_GTK
-+ document.documentElement.getAttribute('shellshowingmenubar') != 'true')
-+#else
-+ true)
-+#endif
- this.setAttribute('openedwithkey',
- event.target.parentNode.openedWithKey);"
- #endif
-diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
-index 7b22dee915cc1d4e428b6f4e70cba8090d309f7e..b5d63edafd96b3bd529ebf10f1c521da632db701 100644
---- a/browser/base/content/browser.js
-+++ b/browser/base/content/browser.js
-@@ -6372,11 +6372,18 @@ function onViewToolbarsPopupShowing(aEvent, aInsertPoint) {
- MozXULElement.insertFTLIfNeeded("browser/toolbarContextMenu.ftl");
- let firstMenuItem = aInsertPoint || popup.firstElementChild;
- 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;
-+ }
-+
- if (toolbar.id == "PersonalToolbar") {
- let menu = BookmarkingUI.buildBookmarksToolbarSubmenu(toolbar);
- popup.insertBefore(menu, firstMenuItem);
-diff --git a/browser/components/places/content/places.xhtml b/browser/components/places/content/places.xhtml
-index e1ac09878b1b66551cc96200d785ca8381999300..837709d0886ed42139ab5b3baf019b7b207067a0 100644
---- a/browser/components/places/content/places.xhtml
-+++ b/browser/components/places/content/places.xhtml
-@@ -184,6 +184,7 @@
- #else
- <menubar id="placesMenu">
- <menu class="menu-iconic" data-l10n-id="places-organize-button"
-+ _moz-menubarkeeplocal="true"
- #endif
- id="organizeButton">
- <menupopup id="organizeButtonPopup">
-diff --git a/dom/xul/XULPopupElement.cpp b/dom/xul/XULPopupElement.cpp
-index d60173900ec1e32fe7b60fecab657fb7bb875f0e..ffdf4d53135576a5723c03f0f6be09edafd5afdb 100644
---- a/dom/xul/XULPopupElement.cpp
-+++ b/dom/xul/XULPopupElement.cpp
-@@ -238,6 +238,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
-+
- if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
- switch (pm->GetPopupState(this)) {
- case ePopupShown:
-@@ -260,6 +264,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 {
-diff --git a/dom/xul/moz.build b/dom/xul/moz.build
-index cbcf964a2ba711dba0750b210ecec4668cce9e4f..1aca311d9bd8261ed58423bdd0feab812347923d 100644
---- a/dom/xul/moz.build
-+++ b/dom/xul/moz.build
-@@ -91,4 +91,9 @@ LOCAL_INCLUDES += [
-
- include("/ipc/chromium/chromium-config.mozbuild")
-
-+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
-+ LOCAL_INCLUDES += [
-+ "/widget/gtk",
-+ ]
-+
- FINAL_LIBRARY = "xul"
-diff --git a/layout/build/moz.build b/layout/build/moz.build
-index b2059e396efec51ec515540e69adfd18a74a906f..5f00ef562b374aa5d1d5792240395c4a87babef1 100644
---- a/layout/build/moz.build
-+++ b/layout/build/moz.build
-@@ -69,6 +69,10 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "android":
- "/dom/system",
- "/dom/system/android",
- ]
-+elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
-+ LOCAL_INCLUDES += [
-+ "/widget/gtk",
-+ ]
-
- XPCOM_MANIFESTS += [
- "components.conf",
-diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
-index af04cba69168f7fda36befd3820b0f0b1dbc249f..ac990fcb59c5a36c66354b1321424d290b392dc2 100644
---- a/modules/libpref/init/all.js
-+++ b/modules/libpref/init/all.js
-@@ -161,6 +161,9 @@ pref("dom.text-recognition.enabled", 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);
-+#ifdef MOZ_WIDGET_GTK
-+pref("ui.use_unity_menubar", true);
-+#endif
-
- // See http://whatwg.org/specs/web-apps/current-work/#ping
- pref("browser.send_pings", false);
-diff --git a/toolkit/content/xul.css b/toolkit/content/xul.css
-index efd523b44d08c0f0f01abc19d79414e8ff744b94..07d4501c38733d7df62013981d243ae0eefaed1a 100644
---- a/toolkit/content/xul.css
-+++ b/toolkit/content/xul.css
-@@ -342,6 +342,20 @@ toolbox {
- }
- }
-
-+@media (-moz-platform: linux) {
-+*|*:root[shellshowingmenubar="true"]
-+toolbar[type="menubar"]:not([customizing="true"]) {
-+ display: none !important;
-+}
-+}
-+
-+@media (-moz-platform: linux) {
-+*|*:root[shellshowingmenubar="true"]
-+toolbar[type="menubar"]:not([customizing="true"]) {
-+ display: none !important;
-+}
-+}
-+
- toolbarspring {
- flex: 1000 1000;
- }
-diff --git a/widget/gtk/NativeMenuSupport.cpp b/widget/gtk/NativeMenuSupport.cpp
-index 4360867fff3f849fa6bdec31f05ddbfe60777180..c3a69f31b1d310340a2546da541dda544a8056d3 100644
---- a/widget/gtk/NativeMenuSupport.cpp
-+++ b/widget/gtk/NativeMenuSupport.cpp
-@@ -7,6 +7,8 @@
-
- #include "MainThreadUtils.h"
- #include "NativeMenuGtk.h"
-+#include "nsINativeMenuService.h"
-+#include "nsServiceManagerUtils.h"
-
- namespace mozilla::widget {
-
-@@ -14,7 +16,14 @@ void NativeMenuSupport::CreateNativeMenuBar(nsIWidget* aParent,
- dom::Element* aMenuBarElement) {
- MOZ_RELEASE_ASSERT(NS_IsMainThread(),
- "Attempting to create native menu bar on wrong thread!");
-- // TODO
-+
-+ nsCOMPtr<nsINativeMenuService> nms =
-+ do_GetService("@mozilla.org/widget/nativemenuservice;1");
-+ if (!nms) {
-+ return;
-+ }
-+
-+ nms->CreateNativeMenuBar(aParent, aMenuBarElement);
- }
-
- already_AddRefed<NativeMenu> NativeMenuSupport::CreateNativeContextMenu(
-diff --git a/widget/gtk/NativeMenuSupport.h b/widget/gtk/NativeMenuSupport.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..0843d45185e51f6f59ded657cb57ac0d6a456e5e
---- /dev/null
-+++ b/widget/gtk/NativeMenuSupport.h
-@@ -0,0 +1,31 @@
-+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-+/* 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 mozilla_widget_NativeMenuSupport_h
-+#define mozilla_widget_NativeMenuSupport_h
-+
-+class nsIWidget;
-+
-+namespace mozilla {
-+
-+namespace dom {
-+class Element;
-+}
-+
-+namespace widget {
-+
-+class NativeMenuSupport final {
-+public:
-+ // Given a top-level window widget and a menu bar DOM node, sets up native
-+ // menus. Once created, native menus are controlled via the DOM, including
-+ // destruction.
-+ static void CreateNativeMenuBar(nsIWidget* aParent,
-+ dom::Element* aMenuBarElement);
-+};
-+
-+} // namespace widget
-+} // namespace mozilla
-+
-+#endif // mozilla_widget_NativeMenuSupport_h
-diff --git a/widget/gtk/components.conf b/widget/gtk/components.conf
-index 541df93378339e82c06f4f9ece9b87031018a476..4a364c27ced3828ec1e4d44b33d00a7e7121dd3b 100644
---- a/widget/gtk/components.conf
-+++ b/widget/gtk/components.conf
-@@ -115,6 +115,14 @@ Classes = [
- 'headers': ['/widget/gtk/nsUserIdleServiceGTK.h'],
- 'constructor': 'nsUserIdleServiceGTK::GetInstance',
- },
-+ {
-+ '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('NS_PRINTING'):
-diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build
-index 3e485fc428e83f0e0bd7952e40435ea1f94d081d..a6ed6f7c8cd08853f4bf1e25eb658b8fb9a4cbb1 100644
---- a/widget/gtk/moz.build
-+++ b/widget/gtk/moz.build
-@@ -100,6 +100,15 @@ UNIFIED_SOURCES += [
-
- SOURCES += [
- "MediaKeysEventSourceFactory.cpp",
-+ "nsDbusmenu.cpp",
-+ "nsMenu.cpp", # conflicts with X11 headers
-+ "nsMenuBar.cpp",
-+ "nsMenuContainer.cpp",
-+ "nsMenuItem.cpp",
-+ "nsMenuObject.cpp",
-+ "nsMenuSeparator.cpp",
-+ "nsNativeMenuDocListener.cpp",
-+ "nsNativeMenuService.cpp",
- "nsNativeThemeGTK.cpp", # conflicts with X11 headers
- "nsWindow.cpp", # conflicts with X11 headers
- "WaylandVsyncSource.cpp", # conflicts with X11 headers
-@@ -148,6 +157,7 @@ LOCAL_INCLUDES += [
- "/layout/base",
- "/layout/forms",
- "/layout/generic",
-+ "/layout/style",
- "/layout/xul",
- "/other-licenses/atk-1.0",
- "/third_party/cups/include",
-diff --git a/widget/gtk/nsDbusmenu.cpp b/widget/gtk/nsDbusmenu.cpp
-new file mode 100644
-index 0000000000000000000000000000000000000000..f3a1c4400bf225263069fab67674078f666c3e3a
---- /dev/null
-+++ b/widget/gtk/nsDbusmenu.cpp
-@@ -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;
-+}
-diff --git a/widget/gtk/nsDbusmenu.h b/widget/gtk/nsDbusmenu.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..8d46a0d27bdbd403588cc75b19256e0149d8edf5
---- /dev/null
-+++ b/widget/gtk/nsDbusmenu.h
-@@ -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__ */
-diff --git a/widget/gtk/nsMenu.cpp b/widget/gtk/nsMenu.cpp
-new file mode 100644
-index 0000000000000000000000000000000000000000..255eb390e577d59da2d05baf274e460b2c484ced
---- /dev/null
-+++ b/widget/gtk/nsMenu.cpp
-@@ -0,0 +1,795 @@
-+/* -*- 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/. */
-+
-+#define _IMPL_NS_LAYOUT
-+
-+#include "mozilla/dom/Document.h"
-+#include "mozilla/dom/Element.h"
-+#include "mozilla/Assertions.h"
-+#include "mozilla/ComputedStyleInlines.h"
-+#include "mozilla/EventDispatcher.h"
-+#include "mozilla/MouseEvents.h"
-+#include "mozilla/PresShell.h"
-+#include "mozilla/PresShellInlines.h"
-+#include "nsComponentManagerUtils.h"
-+#include "nsContentUtils.h"
-+#include "nsCSSValue.h"
-+#include "nsGkAtoms.h"
-+#include "nsGtkUtils.h"
-+#include "nsAtom.h"
-+#include "nsIContent.h"
-+#include "nsIRunnable.h"
-+#include "nsITimer.h"
-+#include "nsString.h"
-+#include "nsStyleStruct.h"
-+#include "nsThreadUtils.h"
-+
-+#include "nsNativeMenuDocListener.h"
-+
-+#include <glib-object.h>
-+
-+#include "nsMenu.h"
-+
-+using namespace mozilla;
-+
-+class nsMenuContentInsertedEvent : public Runnable
-+{
-+public:
-+ nsMenuContentInsertedEvent(nsMenu *aMenu,
-+ nsIContent *aContainer,
-+ nsIContent *aChild,
-+ nsIContent *aPrevSibling) :
-+ Runnable("nsMenuContentInsertedEvent"),
-+ mWeakMenu(aMenu),
-+ mContainer(aContainer),
-+ mChild(aChild),
-+ mPrevSibling(aPrevSibling) { }
-+
-+ NS_IMETHODIMP Run()
-+ {
-+ if (!mWeakMenu) {
-+ return NS_OK;
-+ }
-+
-+ static_cast<nsMenu *>(mWeakMenu.get())->HandleContentInserted(mContainer,
-+ mChild,
-+ mPrevSibling);
-+ return NS_OK;
-+ }
-+
-+private:
-+ nsWeakMenuObject mWeakMenu;
-+
-+ nsCOMPtr<nsIContent> mContainer;
-+ nsCOMPtr<nsIContent> mChild;
-+ nsCOMPtr<nsIContent> mPrevSibling;
-+};
-+
-+class nsMenuContentRemovedEvent : public Runnable
-+{
-+public:
-+ nsMenuContentRemovedEvent(nsMenu *aMenu,
-+ nsIContent *aContainer,
-+ nsIContent *aChild) :
-+ Runnable("nsMenuContentRemovedEvent"),
-+ mWeakMenu(aMenu),
-+ mContainer(aContainer),
-+ mChild(aChild) { }
-+
-+ NS_IMETHODIMP Run()
-+ {
-+ if (!mWeakMenu) {
-+ return NS_OK;
-+ }
-+
-+ static_cast<nsMenu *>(mWeakMenu.get())->HandleContentRemoved(mContainer,
-+ mChild);
-+ return NS_OK;
-+ }
-+
-+private:
-+ nsWeakMenuObject mWeakMenu;
-+
-+ nsCOMPtr<nsIContent> mContainer;
-+ nsCOMPtr<nsIContent> mChild;
-+};
-+
-+static void
-+DispatchMouseEvent(nsIContent *aTarget, mozilla::EventMessage aMsg)
-+{
-+ if (!aTarget) {
-+ return;
-+ }
-+
-+ WidgetMouseEvent event(true, aMsg, nullptr, WidgetMouseEvent::eReal);
-+ EventDispatcher::Dispatch(aTarget, nullptr, &event);
-+}
-+
-+void
-+nsMenu::SetPopupState(EPopupState aState)
-+{
-+ mPopupState = aState;
-+
-+ if (!mPopupContent) {
-+ return;
-+ }
-+
-+ nsAutoString state;
-+ switch (aState) {
-+ case ePopupState_Showing:
-+ state.Assign(u"showing"_ns);
-+ break;
-+ case ePopupState_Open:
-+ state.Assign(u"open"_ns);
-+ break;
-+ case ePopupState_Hiding:
-+ state.Assign(u"hiding"_ns);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (state.IsEmpty()) {
-+ mPopupContent->AsElement()->UnsetAttr(
-+ kNameSpaceID_None, nsGkAtoms::_moz_nativemenupopupstate,
-+ false);
-+ } else {
-+ mPopupContent->AsElement()->SetAttr(
-+ kNameSpaceID_None, nsGkAtoms::_moz_nativemenupopupstate,
-+ state, false);
-+ }
-+}
-+
-+/* static */ void
-+nsMenu::DoOpenCallback(nsITimer *aTimer, void *aClosure)
-+{
-+ nsMenu* self = static_cast<nsMenu *>(aClosure);
-+
-+ dbusmenu_menuitem_show_to_user(self->GetNativeData(), 0);
-+
-+ self->mOpenDelayTimer = nullptr;
-+}
-+
-+/* static */ void
-+nsMenu::menu_event_cb(DbusmenuMenuitem *menu,
-+ const gchar *name,
-+ GVariant *value,
-+ guint timestamp,
-+ gpointer user_data)
-+{
-+ nsMenu *self = static_cast<nsMenu *>(user_data);
-+
-+ nsAutoCString event(name);
-+
-+ if (event.Equals("closed"_ns)) {
-+ self->OnClose();
-+ return;
-+ }
-+
-+ if (event.Equals("opened"_ns)) {
-+ self->OnOpen();
-+ return;
-+ }
-+}
-+
-+void
-+nsMenu::MaybeAddPlaceholderItem()
-+{
-+ MOZ_ASSERT(!IsInBatchedUpdate(),
-+ "Shouldn't be modifying the native menu structure now");
-+
-+ GList *children = dbusmenu_menuitem_get_children(GetNativeData());
-+ if (!children) {
-+ MOZ_ASSERT(!mPlaceholderItem);
-+
-+ mPlaceholderItem = dbusmenu_menuitem_new();
-+ if (!mPlaceholderItem) {
-+ return;
-+ }
-+
-+ dbusmenu_menuitem_property_set_bool(mPlaceholderItem,
-+ DBUSMENU_MENUITEM_PROP_VISIBLE,
-+ false);
-+
-+ MOZ_ALWAYS_TRUE(
-+ dbusmenu_menuitem_child_append(GetNativeData(), mPlaceholderItem));
-+ }
-+}
-+
-+void
-+nsMenu::EnsureNoPlaceholderItem()
-+{
-+ MOZ_ASSERT(!IsInBatchedUpdate(),
-+ "Shouldn't be modifying the native menu structure now");
-+
-+ if (!mPlaceholderItem) {
-+ return;
-+ }
-+
-+ MOZ_ALWAYS_TRUE(
-+ dbusmenu_menuitem_child_delete(GetNativeData(), mPlaceholderItem));
-+ MOZ_ASSERT(!dbusmenu_menuitem_get_children(GetNativeData()));
-+
-+ g_object_unref(mPlaceholderItem);
-+ mPlaceholderItem = nullptr;
-+}
-+
-+void
-+nsMenu::OnOpen()
-+{
-+ if (mNeedsRebuild) {
-+ Build();
-+ }
-+
-+ nsWeakMenuObject self(this);
-+ nsCOMPtr<nsIContent> origPopupContent(mPopupContent);
-+ {
-+ nsNativeMenuDocListener::BlockUpdatesScope updatesBlocker;
-+
-+ SetPopupState(ePopupState_Showing);
-+ DispatchMouseEvent(mPopupContent, eXULPopupShowing);
-+
-+ ContentNode()->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::open,
-+ u"true"_ns, true);
-+ }
-+
-+ if (!self) {
-+ // We were deleted!
-+ return;
-+ }
-+
-+ // I guess that the popup could have changed
-+ if (origPopupContent != mPopupContent) {
-+ return;
-+ }
-+
-+ nsNativeMenuDocListener::BlockUpdatesScope updatesBlocker;
-+
-+ size_t count = ChildCount();
-+ for (size_t i = 0; i < count; ++i) {
-+ ChildAt(i)->ContainerIsOpening();
-+ }
-+
-+ SetPopupState(ePopupState_Open);
-+ DispatchMouseEvent(mPopupContent, eXULPopupShown);
-+}
-+
-+void
-+nsMenu::Build()
-+{
-+ mNeedsRebuild = false;
-+
-+ while (ChildCount() > 0) {
-+ RemoveChildAt(0);
-+ }
-+
-+ InitializePopup();
-+
-+ if (!mPopupContent) {
-+ return;
-+ }
-+
-+ uint32_t count = mPopupContent->GetChildCount();
-+ for (uint32_t i = 0; i < count; ++i) {
-+ nsIContent *childContent = mPopupContent->GetChildAt_Deprecated(i);
-+
-+ UniquePtr<nsMenuObject> child = CreateChild(childContent);
-+
-+ if (!child) {
-+ continue;
-+ }
-+
-+ AppendChild(std::move(child));
-+ }
-+}
-+
-+void
-+nsMenu::InitializePopup()
-+{
-+ nsCOMPtr<nsIContent> oldPopupContent;
-+ oldPopupContent.swap(mPopupContent);
-+
-+ for (uint32_t i = 0; i < ContentNode()->GetChildCount(); ++i) {
-+ nsIContent *child = ContentNode()->GetChildAt_Deprecated(i);
-+
-+ if (child->NodeInfo()->NameAtom() == nsGkAtoms::menupopup) {
-+ mPopupContent = child;
-+ break;
-+ }
-+ }
-+
-+ if (oldPopupContent == mPopupContent) {
-+ return;
-+ }
-+
-+ // The popup has changed
-+
-+ if (oldPopupContent) {
-+ DocListener()->UnregisterForContentChanges(oldPopupContent);
-+ }
-+
-+ SetPopupState(ePopupState_Closed);
-+
-+ if (!mPopupContent) {
-+ return;
-+ }
-+
-+ DocListener()->RegisterForContentChanges(mPopupContent, this);
-+}
-+
-+void
-+nsMenu::RemoveChildAt(size_t aIndex)
-+{
-+ MOZ_ASSERT(IsInBatchedUpdate() || !mPlaceholderItem,
-+ "Shouldn't have a placeholder menuitem");
-+
-+ nsMenuContainer::RemoveChildAt(aIndex, !IsInBatchedUpdate());
-+ StructureMutated();
-+
-+ if (!IsInBatchedUpdate()) {
-+ MaybeAddPlaceholderItem();
-+ }
-+}
-+
-+void
-+nsMenu::RemoveChild(nsIContent *aChild)
-+{
-+ size_t index = IndexOf(aChild);
-+ if (index == NoIndex) {
-+ return;
-+ }
-+
-+ RemoveChildAt(index);
-+}
-+
-+void
-+nsMenu::InsertChildAfter(UniquePtr<nsMenuObject> aChild,
-+ nsIContent *aPrevSibling)
-+{
-+ if (!IsInBatchedUpdate()) {
-+ EnsureNoPlaceholderItem();
-+ }
-+
-+ nsMenuContainer::InsertChildAfter(std::move(aChild), aPrevSibling,
-+ !IsInBatchedUpdate());
-+ StructureMutated();
-+}
-+
-+void
-+nsMenu::AppendChild(UniquePtr<nsMenuObject> aChild)
-+{
-+ if (!IsInBatchedUpdate()) {
-+ EnsureNoPlaceholderItem();
-+ }
-+
-+ nsMenuContainer::AppendChild(std::move(aChild), !IsInBatchedUpdate());
-+ StructureMutated();
-+}
-+
-+bool
-+nsMenu::IsInBatchedUpdate() const
-+{
-+ return mBatchedUpdateState != eBatchedUpdateState_Inactive;
-+}
-+
-+void
-+nsMenu::StructureMutated()
-+{
-+ if (!IsInBatchedUpdate()) {
-+ return;
-+ }
-+
-+ mBatchedUpdateState = eBatchedUpdateState_DidMutate;
-+}
-+
-+bool
-+nsMenu::CanOpen() const
-+{
-+ bool isVisible = dbusmenu_menuitem_property_get_bool(GetNativeData(),
-+ DBUSMENU_MENUITEM_PROP_VISIBLE);
-+ bool isDisabled = ContentNode()->AsElement()->AttrValueIs(kNameSpaceID_None,
-+ nsGkAtoms::disabled,
-+ nsGkAtoms::_true,
-+ eCaseMatters);
-+
-+ return (isVisible && !isDisabled);
-+}
-+
-+void
-+nsMenu::HandleContentInserted(nsIContent *aContainer,
-+ nsIContent *aChild,
-+ nsIContent *aPrevSibling)
-+{
-+ if (aContainer == mPopupContent) {
-+ UniquePtr<nsMenuObject> child = CreateChild(aChild);
-+
-+ if (child) {
-+ InsertChildAfter(std::move(child), aPrevSibling);
-+ }
-+ } else {
-+ Build();
-+ }
-+}
-+
-+void
-+nsMenu::HandleContentRemoved(nsIContent *aContainer, nsIContent *aChild)
-+{
-+ if (aContainer == mPopupContent) {
-+ RemoveChild(aChild);
-+ } else {
-+ Build();
-+ }
-+}
-+
-+void
-+nsMenu::InitializeNativeData()
-+{
-+ // Dbusmenu provides an "about-to-show" signal, and also "opened" and
-+ // "closed" events. However, Unity is the only thing that sends
-+ // both "about-to-show" and "opened" events. Unity 2D and the HUD only
-+ // send "opened" events, so we ignore "about-to-show" (I don't think
-+ // there's any real difference between them anyway).
-+ // To complicate things, there are certain conditions where we don't
-+ // get a "closed" event, so we need to be able to handle this :/
-+ g_signal_connect(G_OBJECT(GetNativeData()), "event",
-+ G_CALLBACK(menu_event_cb), this);
-+
-+ mNeedsRebuild = true;
-+ mNeedsUpdate = true;
-+
-+ MaybeAddPlaceholderItem();
-+}
-+
-+void
-+nsMenu::Update(const ComputedStyle *aComputedStyle)
-+{
-+ if (mNeedsUpdate) {
-+ mNeedsUpdate = false;
-+
-+ UpdateLabel();
-+ UpdateSensitivity();
-+ }
-+
-+ UpdateVisibility(aComputedStyle);
-+ UpdateIcon(aComputedStyle);
-+}
-+
-+nsMenuObject::PropertyFlags
-+nsMenu::SupportedProperties() const
-+{
-+ return static_cast<nsMenuObject::PropertyFlags>(
-+ nsMenuObject::ePropLabel |
-+ nsMenuObject::ePropEnabled |
-+ nsMenuObject::ePropVisible |
-+ nsMenuObject::ePropIconData |
-+ nsMenuObject::ePropChildDisplay
-+ );
-+}
-+
-+void
-+nsMenu::OnAttributeChanged(nsIContent *aContent, nsAtom *aAttribute)
-+{
-+ MOZ_ASSERT(aContent == ContentNode() || aContent == mPopupContent,
-+ "Received an event that wasn't meant for us!");
-+
-+ if (mNeedsUpdate) {
-+ return;
-+ }
-+
-+ if (aContent != ContentNode()) {
-+ return;
-+ }
-+
-+ if (!Parent()->IsBeingDisplayed()) {
-+ mNeedsUpdate = true;
-+ return;
-+ }
-+
-+ if (aAttribute == nsGkAtoms::disabled) {
-+ UpdateSensitivity();
-+ } else if (aAttribute == nsGkAtoms::label ||
-+ aAttribute == nsGkAtoms::accesskey ||
-+ aAttribute == nsGkAtoms::crop) {
-+ UpdateLabel();
-+ } else if (aAttribute == nsGkAtoms::hidden ||
-+ aAttribute == nsGkAtoms::collapsed) {
-+ RefPtr<const ComputedStyle> style = GetComputedStyle();
-+ UpdateVisibility(style);
-+ } else if (aAttribute == nsGkAtoms::image) {
-+ RefPtr<const ComputedStyle> style = GetComputedStyle();
-+ UpdateIcon(style);
-+ }
-+}
-+
-+void
-+nsMenu::OnContentInserted(nsIContent *aContainer, nsIContent *aChild,
-+ nsIContent *aPrevSibling)
-+{
-+ MOZ_ASSERT(aContainer == ContentNode() || aContainer == mPopupContent,
-+ "Received an event that wasn't meant for us!");
-+
-+ if (mNeedsRebuild) {
-+ return;
-+ }
-+
-+ if (mPopupState == ePopupState_Closed) {
-+ mNeedsRebuild = true;
-+ return;
-+ }
-+
-+ nsContentUtils::AddScriptRunner(
-+ new nsMenuContentInsertedEvent(this, aContainer, aChild,
-+ aPrevSibling));
-+}
-+
-+void
-+nsMenu::OnContentRemoved(nsIContent *aContainer, nsIContent *aChild)
-+{
-+ MOZ_ASSERT(aContainer == ContentNode() || aContainer == mPopupContent,
-+ "Received an event that wasn't meant for us!");
-+
-+ if (mNeedsRebuild) {
-+ return;
-+ }
-+
-+ if (mPopupState == ePopupState_Closed) {
-+ mNeedsRebuild = true;
-+ return;
-+ }
-+
-+ nsContentUtils::AddScriptRunner(
-+ new nsMenuContentRemovedEvent(this, aContainer, aChild));
-+}
-+
-+/*
-+ * Some menus (eg, the History menu in Firefox) refresh themselves on
-+ * opening by removing all children and then re-adding new ones. As this
-+ * happens whilst the menu is opening in Unity, it causes some flickering
-+ * as the menu popup is resized multiple times. To avoid this, we try to
-+ * reuse native menu items when the menu structure changes during a
-+ * batched update. If we can handle menu structure changes from Gecko
-+ * just by updating properties of native menu items (rather than destroying
-+ * and creating new ones), then we eliminate any flickering that occurs as
-+ * the menu is opened. To do this, we don't modify any native menu items
-+ * until the end of the update batch.
-+ */
-+
-+void
-+nsMenu::OnBeginUpdates(nsIContent *aContent)
-+{
-+ MOZ_ASSERT(aContent == ContentNode() || aContent == mPopupContent,
-+ "Received an event that wasn't meant for us!");
-+ MOZ_ASSERT(!IsInBatchedUpdate(), "Already in an update batch!");
-+
-+ if (aContent != mPopupContent) {
-+ return;
-+ }
-+
-+ mBatchedUpdateState = eBatchedUpdateState_Active;
-+}
-+
-+void
-+nsMenu::OnEndUpdates()
-+{
-+ if (!IsInBatchedUpdate()) {
-+ return;
-+ }
-+
-+ bool didMutate = mBatchedUpdateState == eBatchedUpdateState_DidMutate;
-+ mBatchedUpdateState = eBatchedUpdateState_Inactive;
-+
-+ /* Optimize for the case where we only had attribute changes */
-+ if (!didMutate) {
-+ return;
-+ }
-+
-+ EnsureNoPlaceholderItem();
-+
-+ GList *nextNativeChild = dbusmenu_menuitem_get_children(GetNativeData());
-+ DbusmenuMenuitem *nextOwnedNativeChild = nullptr;
-+
-+ size_t count = ChildCount();
-+
-+ // Find the first native menu item that is `owned` by a corresponding
-+ // Gecko menuitem
-+ for (size_t i = 0; i < count; ++i) {
-+ if (ChildAt(i)->GetNativeData()) {
-+ nextOwnedNativeChild = ChildAt(i)->GetNativeData();
-+ break;
-+ }
-+ }
-+
-+ // Now iterate over all Gecko menuitems
-+ for (size_t i = 0; i < count; ++i) {
-+ nsMenuObject *child = ChildAt(i);
-+
-+ if (child->GetNativeData()) {
-+ // This child already has a corresponding native menuitem.
-+ // Remove all preceding orphaned native items. At this point, we
-+ // modify the native menu structure.
-+ while (nextNativeChild &&
-+ nextNativeChild->data != nextOwnedNativeChild) {
-+
-+ DbusmenuMenuitem *data =
-+ static_cast<DbusmenuMenuitem *>(nextNativeChild->data);
-+ nextNativeChild = nextNativeChild->next;
-+
-+ MOZ_ALWAYS_TRUE(dbusmenu_menuitem_child_delete(GetNativeData(),
-+ data));
-+ }
-+
-+ if (nextNativeChild) {
-+ nextNativeChild = nextNativeChild->next;
-+ }
-+
-+ // Now find the next native menu item that is `owned`
-+ nextOwnedNativeChild = nullptr;
-+ for (size_t j = i + 1; j < count; ++j) {
-+ if (ChildAt(j)->GetNativeData()) {
-+ nextOwnedNativeChild = ChildAt(j)->GetNativeData();
-+ break;
-+ }
-+ }
-+ } else {
-+ // This child is new, and doesn't have a native menu item. Find one!
-+ if (nextNativeChild &&
-+ nextNativeChild->data != nextOwnedNativeChild) {
-+
-+ DbusmenuMenuitem *data =
-+ static_cast<DbusmenuMenuitem *>(nextNativeChild->data);
-+
-+ if (NS_SUCCEEDED(child->AdoptNativeData(data))) {
-+ nextNativeChild = nextNativeChild->next;
-+ }
-+ }
-+
-+ // There wasn't a suitable one available, so create a new one.
-+ // At this point, we modify the native menu structure.
-+ if (!child->GetNativeData()) {
-+ child->CreateNativeData();
-+ MOZ_ALWAYS_TRUE(
-+ dbusmenu_menuitem_child_add_position(GetNativeData(),
-+ child->GetNativeData(),
-+ i));
-+ }
-+ }
-+ }
-+
-+ while (nextNativeChild) {
-+ DbusmenuMenuitem *data =
-+ static_cast<DbusmenuMenuitem *>(nextNativeChild->data);
-+ nextNativeChild = nextNativeChild->next;
-+
-+ MOZ_ALWAYS_TRUE(dbusmenu_menuitem_child_delete(GetNativeData(), data));
-+ }
-+
-+ MaybeAddPlaceholderItem();
-+}
-+
-+nsMenu::nsMenu(nsMenuContainer *aParent, nsIContent *aContent) :
-+ nsMenuContainer(aParent, aContent),
-+ mNeedsRebuild(false),
-+ mNeedsUpdate(false),
-+ mPlaceholderItem(nullptr),
-+ mPopupState(ePopupState_Closed),
-+ mBatchedUpdateState(eBatchedUpdateState_Inactive)
-+{
-+ MOZ_COUNT_CTOR(nsMenu);
-+}
-+
-+nsMenu::~nsMenu()
-+{
-+ if (IsInBatchedUpdate()) {
-+ OnEndUpdates();
-+ }
-+
-+ // Although nsTArray will take care of this in its destructor,
-+ // we have to manually ensure children are removed from our native menu
-+ // item, just in case our parent recycles us
-+ while (ChildCount() > 0) {
-+ RemoveChildAt(0);
-+ }
-+
-+ EnsureNoPlaceholderItem();
-+
-+ if (DocListener() && mPopupContent) {
-+ DocListener()->UnregisterForContentChanges(mPopupContent);
-+ }
-+
-+ if (GetNativeData()) {
-+ g_signal_handlers_disconnect_by_func(GetNativeData(),
-+ FuncToGpointer(menu_event_cb),
-+ this);
-+ }
-+
-+ MOZ_COUNT_DTOR(nsMenu);
-+}
-+
-+nsMenuObject::EType
-+nsMenu::Type() const
-+{
-+ return eType_Menu;
-+}
-+
-+bool
-+nsMenu::IsBeingDisplayed() const
-+{
-+ return mPopupState == ePopupState_Open;
-+}
-+
-+bool
-+nsMenu::NeedsRebuild() const
-+{
-+ return mNeedsRebuild;
-+}
-+
-+void
-+nsMenu::OpenMenu()
-+{
-+ if (!CanOpen()) {
-+ return;
-+ }
-+
-+ if (mOpenDelayTimer) {
-+ return;
-+ }
-+
-+ // Here, we synchronously fire popupshowing and popupshown events and then
-+ // open the menu after a short delay. This allows the menu to refresh before
-+ // it's shown, and avoids an issue where keyboard focus is not on the first
-+ // item of the history menu in Firefox when opening it with the keyboard,
-+ // because extra items to appear at the top of the menu
-+
-+ OnOpen();
-+
-+ mOpenDelayTimer = NS_NewTimer();
-+ if (!mOpenDelayTimer) {
-+ return;
-+ }
-+
-+ if (NS_FAILED(mOpenDelayTimer->InitWithNamedFuncCallback(DoOpenCallback,
-+ this,
-+ 100,
-+ nsITimer::TYPE_ONE_SHOT,
-+ "nsMenu::DoOpenCallback"))) {
-+ mOpenDelayTimer = nullptr;
-+ }
-+}
-+
-+void
-+nsMenu::OnClose()
-+{
-+ if (mPopupState == ePopupState_Closed) {
-+ return;
-+ }
-+
-+ MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
-+
-+ // We do this to avoid mutating our view of the menu until
-+ // after we have finished
-+ nsNativeMenuDocListener::BlockUpdatesScope updatesBlocker;
-+
-+ SetPopupState(ePopupState_Hiding);
-+ DispatchMouseEvent(mPopupContent, eXULPopupHiding);
-+
-+ // Sigh, make sure all of our descendants are closed, as we don't
-+ // always get closed events for submenus when scrubbing quickly through
-+ // the menu
-+ size_t count = ChildCount();
-+ for (size_t i = 0; i < count; ++i) {
-+ if (ChildAt(i)->Type() == nsMenuObject::eType_Menu) {
-+ static_cast<nsMenu *>(ChildAt(i))->OnClose();
-+ }
-+ }
-+
-+ SetPopupState(ePopupState_Closed);
-+ DispatchMouseEvent(mPopupContent, eXULPopupHidden);
-+
-+ ContentNode()->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::open,
-+ true);
-+}
-+
-diff --git a/widget/gtk/nsMenu.h b/widget/gtk/nsMenu.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..40244d0122901dc77aa4c709e5a66efa5a358e4a
---- /dev/null
-+++ b/widget/gtk/nsMenu.h
-@@ -0,0 +1,123 @@
-+/* -*- 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 __nsMenu_h__
-+#define __nsMenu_h__
-+
-+#include "mozilla/Attributes.h"
-+#include "mozilla/UniquePtr.h"
-+#include "nsCOMPtr.h"
-+
-+#include "nsDbusmenu.h"
-+#include "nsMenuContainer.h"
-+#include "nsMenuObject.h"
-+
-+#include <glib.h>
-+
-+class nsAtom;
-+class nsIContent;
-+class nsITimer;
-+
-+#define NSMENU_NUMBER_OF_POPUPSTATE_BITS 2U
-+#define NSMENU_NUMBER_OF_FLAGS 4U
-+
-+// This class represents a menu
-+class nsMenu final : public nsMenuContainer
-+{
-+public:
-+ nsMenu(nsMenuContainer *aParent, nsIContent *aContent);
-+ ~nsMenu();
-+
-+ nsMenuObject::EType Type() const override;
-+
-+ bool IsBeingDisplayed() const override;
-+ bool NeedsRebuild() const override;
-+
-+ // Tell the desktop shell to display this menu
-+ void OpenMenu();
-+
-+ // Normally called via the shell, but it's public so that child
-+ // menuitems can do the shells work. Sigh....
-+ void OnClose();
-+
-+private:
-+ friend class nsMenuContentInsertedEvent;
-+ friend class nsMenuContentRemovedEvent;
-+
-+ enum EPopupState {
-+ ePopupState_Closed,
-+ ePopupState_Showing,
-+ ePopupState_Open,
-+ ePopupState_Hiding
-+ };
-+
-+ void SetPopupState(EPopupState aState);
-+
-+ static void DoOpenCallback(nsITimer *aTimer, void *aClosure);
-+ static void menu_event_cb(DbusmenuMenuitem *menu,
-+ const gchar *name,
-+ GVariant *value,
-+ guint timestamp,
-+ gpointer user_data);
-+
-+ // We add a placeholder item to empty menus so that Unity actually treats
-+ // us as a proper menu, rather than a menuitem without a submenu
-+ void MaybeAddPlaceholderItem();
-+
-+ // Removes a placeholder item if it exists and asserts that this succeeds
-+ void EnsureNoPlaceholderItem();
-+
-+ void OnOpen();
-+ void Build();
-+ void InitializePopup();
-+ void RemoveChildAt(size_t aIndex);
-+ void RemoveChild(nsIContent *aChild);
-+ void InsertChildAfter(mozilla::UniquePtr<nsMenuObject> aChild,
-+ nsIContent *aPrevSibling);
-+ void AppendChild(mozilla::UniquePtr<nsMenuObject> aChild);
-+ bool IsInBatchedUpdate() const;
-+ void StructureMutated();
-+ bool CanOpen() const;
-+
-+ void HandleContentInserted(nsIContent *aContainer,
-+ nsIContent *aChild,
-+ nsIContent *aPrevSibling);
-+ void HandleContentRemoved(nsIContent *aContainer,
-+ nsIContent *aChild);
-+
-+ void InitializeNativeData() override;
-+ void Update(const mozilla::ComputedStyle *aComputedStyle) override;
-+ nsMenuObject::PropertyFlags SupportedProperties() const override;
-+
-+ void OnAttributeChanged(nsIContent *aContent, nsAtom *aAttribute) override;
-+ void OnContentInserted(nsIContent *aContainer, nsIContent *aChild,
-+ nsIContent *aPrevSibling) override;
-+ void OnContentRemoved(nsIContent *aContainer, nsIContent *aChild) override;
-+ void OnBeginUpdates(nsIContent *aContent) override;
-+ void OnEndUpdates() override;
-+
-+ bool mNeedsRebuild;
-+ bool mNeedsUpdate;
-+
-+ DbusmenuMenuitem *mPlaceholderItem;
-+
-+ EPopupState mPopupState;
-+
-+ enum EBatchedUpdateState {
-+ eBatchedUpdateState_Inactive,
-+ eBatchedUpdateState_Active,
-+ eBatchedUpdateState_DidMutate
-+ };
-+
-+ EBatchedUpdateState mBatchedUpdateState;
-+
-+ nsCOMPtr<nsIContent> mPopupContent;
-+
-+ nsCOMPtr<nsITimer> mOpenDelayTimer;
-+};
-+
-+#endif /* __nsMenu_h__ */
-diff --git a/widget/gtk/nsMenuBar.cpp b/widget/gtk/nsMenuBar.cpp
-new file mode 100644
-index 0000000000000000000000000000000000000000..71834e55fad6444caa545e15c3b27915f9b4a77b
---- /dev/null
-+++ b/widget/gtk/nsMenuBar.cpp
-@@ -0,0 +1,548 @@
-+/* -*- 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 "mozilla/Assertions.h"
-+#include "mozilla/DebugOnly.h"
-+#include "mozilla/dom/Document.h"
-+#include "mozilla/dom/Element.h"
-+#include "mozilla/dom/Event.h"
-+#include "mozilla/dom/KeyboardEvent.h"
-+#include "mozilla/dom/KeyboardEventBinding.h"
-+#include "mozilla/Preferences.h"
-+#include "nsContentUtils.h"
-+#include "nsIDOMEventListener.h"
-+#include "nsIRunnable.h"
-+#include "nsIWidget.h"
-+#include "nsTArray.h"
-+#include "nsUnicharUtils.h"
-+
-+#include "nsMenu.h"
-+#include "nsNativeMenuService.h"
-+
-+#include <gdk/gdk.h>
-+#include <gdk/gdkx.h>
-+#include <glib.h>
-+#include <glib-object.h>
-+
-+#include "nsMenuBar.h"
-+
-+using namespace mozilla;
-+
-+static bool
-+ShouldHandleKeyEvent(dom::KeyboardEvent *aEvent)
-+{
-+ return !aEvent->DefaultPrevented() && aEvent->IsTrusted();
-+}
-+
-+class nsMenuBarContentInsertedEvent : public Runnable
-+{
-+public:
-+ nsMenuBarContentInsertedEvent(nsMenuBar *aMenuBar,
-+ nsIContent *aChild,
-+ nsIContent *aPrevSibling) :
-+ Runnable("nsMenuBarContentInsertedEvent"),
-+ mWeakMenuBar(aMenuBar),
-+ mChild(aChild),
-+ mPrevSibling(aPrevSibling) { }
-+
-+ NS_IMETHODIMP Run()
-+ {
-+ if (!mWeakMenuBar) {
-+ return NS_OK;
-+ }
-+
-+ static_cast<nsMenuBar *>(mWeakMenuBar.get())->HandleContentInserted(mChild,
-+ mPrevSibling);
-+ return NS_OK;
-+ }
-+
-+private:
-+ nsWeakMenuObject mWeakMenuBar;
-+
-+ nsCOMPtr<nsIContent> mChild;
-+ nsCOMPtr<nsIContent> mPrevSibling;
-+};
-+
-+class nsMenuBarContentRemovedEvent : public Runnable
-+{
-+public:
-+ nsMenuBarContentRemovedEvent(nsMenuBar *aMenuBar,
-+ nsIContent *aChild) :
-+ Runnable("nsMenuBarContentRemovedEvent"),
-+ mWeakMenuBar(aMenuBar),
-+ mChild(aChild) { }
-+
-+ NS_IMETHODIMP Run()
-+ {
-+ if (!mWeakMenuBar) {
-+ return NS_OK;
-+ }
-+
-+ static_cast<nsMenuBar *>(mWeakMenuBar.get())->HandleContentRemoved(mChild);
-+ return NS_OK;
-+ }
-+
-+private:
-+ nsWeakMenuObject mWeakMenuBar;
-+
-+ nsCOMPtr<nsIContent> mChild;
-+};
-+
-+class nsMenuBar::DocEventListener final : public nsIDOMEventListener
-+{
-+public:
-+ NS_DECL_ISUPPORTS
-+ NS_DECL_NSIDOMEVENTLISTENER
-+
-+ DocEventListener(nsMenuBar *aOwner) : mOwner(aOwner) { };
-+
-+private:
-+ ~DocEventListener() { };
-+
-+ nsMenuBar *mOwner;
-+};
-+
-+NS_IMPL_ISUPPORTS(nsMenuBar::DocEventListener, nsIDOMEventListener)
-+
-+NS_IMETHODIMP
-+nsMenuBar::DocEventListener::HandleEvent(dom::Event *aEvent)
-+{
-+ nsAutoString type;
-+ aEvent->GetType(type);
-+
-+ if (type.Equals(u"focus"_ns)) {
-+ mOwner->Focus();
-+ } else if (type.Equals(u"blur"_ns)) {
-+ mOwner->Blur();
-+ }
-+
-+ RefPtr<dom::KeyboardEvent> keyEvent = aEvent->AsKeyboardEvent();
-+ if (!keyEvent) {
-+ return NS_OK;
-+ }
-+
-+ if (type.Equals(u"keypress"_ns)) {
-+ return mOwner->Keypress(keyEvent);
-+ } else if (type.Equals(u"keydown"_ns)) {
-+ return mOwner->KeyDown(keyEvent);
-+ } else if (type.Equals(u"keyup"_ns)) {
-+ return mOwner->KeyUp(keyEvent);
-+ }
-+
-+ return NS_OK;
-+}
-+
-+nsMenuBar::nsMenuBar(nsIContent *aMenuBarNode) :
-+ nsMenuContainer(new nsNativeMenuDocListener(aMenuBarNode), aMenuBarNode),
-+ mTopLevel(nullptr),
-+ mServer(nullptr),
-+ mIsActive(false)
-+{
-+ MOZ_COUNT_CTOR(nsMenuBar);
-+}
-+
-+nsresult
-+nsMenuBar::Init(nsIWidget *aParent)
-+{
-+ MOZ_ASSERT(aParent);
-+
-+ GdkWindow *gdkWin = static_cast<GdkWindow *>(
-+ aParent->GetNativeData(NS_NATIVE_WINDOW));
-+ if (!gdkWin) {
-+ return NS_ERROR_FAILURE;
-+ }
-+
-+ gpointer user_data = nullptr;
-+ gdk_window_get_user_data(gdkWin, &user_data);
-+ if (!user_data || !GTK_IS_CONTAINER(user_data)) {
-+ return NS_ERROR_FAILURE;
-+ }
-+
-+ mTopLevel = gtk_widget_get_toplevel(GTK_WIDGET(user_data));
-+ if (!mTopLevel) {
-+ return NS_ERROR_FAILURE;
-+ }
-+
-+ g_object_ref(mTopLevel);
-+
-+ nsAutoCString path;
-+ path.Append("/com/canonical/menu/"_ns);
-+ char xid[10];
-+ sprintf(xid, "%X", static_cast<uint32_t>(
-+ GDK_WINDOW_XID(gtk_widget_get_window(mTopLevel))));
-+ path.Append(xid);
-+
-+ mServer = dbusmenu_server_new(path.get());
-+ if (!mServer) {
-+ return NS_ERROR_FAILURE;
-+ }
-+
-+ CreateNativeData();
-+ if (!GetNativeData()) {
-+ return NS_ERROR_FAILURE;
-+ }
-+
-+ dbusmenu_server_set_root(mServer, GetNativeData());
-+
-+ mEventListener = new DocEventListener(this);
-+
-+ mDocument = ContentNode()->OwnerDoc();
-+
-+ mAccessKey = Preferences::GetInt("ui.key.menuAccessKey");
-+ if (mAccessKey == dom::KeyboardEvent_Binding::DOM_VK_SHIFT) {
-+ mAccessKeyMask = eModifierShift;
-+ } else if (mAccessKey == dom::KeyboardEvent_Binding::DOM_VK_CONTROL) {
-+ mAccessKeyMask = eModifierCtrl;
-+ } else if (mAccessKey == dom::KeyboardEvent_Binding::DOM_VK_ALT) {
-+ mAccessKeyMask = eModifierAlt;
-+ } else if (mAccessKey == dom::KeyboardEvent_Binding::DOM_VK_META) {
-+ mAccessKeyMask = eModifierMeta;
-+ } else {
-+ mAccessKeyMask = eModifierAlt;
-+ }
-+
-+ return NS_OK;
-+}
-+
-+void
-+nsMenuBar::Build()
-+{
-+ uint32_t count = ContentNode()->GetChildCount();
-+ for (uint32_t i = 0; i < count; ++i) {
-+ nsIContent *childContent = ContentNode()->GetChildAt_Deprecated(i);
-+
-+ UniquePtr<nsMenuObject> child = CreateChild(childContent);
-+
-+ if (!child) {
-+ continue;
-+ }
-+
-+ AppendChild(std::move(child));
-+ }
-+}
-+
-+void
-+nsMenuBar::DisconnectDocumentEventListeners()
-+{
-+ mDocument->RemoveEventListener(u"focus"_ns,
-+ mEventListener,
-+ true);
-+ mDocument->RemoveEventListener(u"blur"_ns,
-+ mEventListener,
-+ true);
-+ mDocument->RemoveEventListener(u"keypress"_ns,
-+ mEventListener,
-+ false);
-+ mDocument->RemoveEventListener(u"keydown"_ns,
-+ mEventListener,
-+ false);
-+ mDocument->RemoveEventListener(u"keyup"_ns,
-+ mEventListener,
-+ false);
-+}
-+
-+void
-+nsMenuBar::SetShellShowingMenuBar(bool aShowing)
-+{
-+ ContentNode()->OwnerDoc()->GetRootElement()->SetAttr(
-+ kNameSpaceID_None, nsGkAtoms::shellshowingmenubar,
-+ aShowing ? u"true"_ns : u"false"_ns,
-+ true);
-+}
-+
-+void
-+nsMenuBar::Focus()
-+{
-+ ContentNode()->AsElement()->SetAttr(kNameSpaceID_None,
-+ nsGkAtoms::openedwithkey,
-+ u"false"_ns, true);
-+}
-+
-+void
-+nsMenuBar::Blur()
-+{
-+ // We do this here in case we lose focus before getting the
-+ // keyup event, which leaves the menubar state looking like
-+ // the alt key is stuck down
-+ dbusmenu_server_set_status(mServer, DBUSMENU_STATUS_NORMAL);
-+}
-+
-+nsMenuBar::ModifierFlags
-+nsMenuBar::GetModifiersFromEvent(dom::KeyboardEvent *aEvent)
-+{
-+ ModifierFlags modifiers = static_cast<ModifierFlags>(0);
-+
-+ if (aEvent->AltKey()) {
-+ modifiers = static_cast<ModifierFlags>(modifiers | eModifierAlt);
-+ }
-+
-+ if (aEvent->ShiftKey()) {
-+ modifiers = static_cast<ModifierFlags>(modifiers | eModifierShift);
-+ }
-+
-+ if (aEvent->CtrlKey()) {
-+ modifiers = static_cast<ModifierFlags>(modifiers | eModifierCtrl);
-+ }
-+
-+ if (aEvent->MetaKey()) {
-+ modifiers = static_cast<ModifierFlags>(modifiers | eModifierMeta);
-+ }
-+
-+ return modifiers;
-+}
-+
-+nsresult
-+nsMenuBar::Keypress(dom::KeyboardEvent *aEvent)
-+{
-+ if (!ShouldHandleKeyEvent(aEvent)) {
-+ return NS_OK;
-+ }
-+
-+ ModifierFlags modifiers = GetModifiersFromEvent(aEvent);
-+ if (((modifiers & mAccessKeyMask) == 0) ||
-+ ((modifiers & ~mAccessKeyMask) != 0)) {
-+ return NS_OK;
-+ }
-+
-+ uint32_t charCode = aEvent->CharCode();
-+ if (charCode == 0) {
-+ return NS_OK;
-+ }
-+
-+ char16_t ch = char16_t(charCode);
-+ char16_t chl = ToLowerCase(ch);
-+ char16_t chu = ToUpperCase(ch);
-+
-+ nsMenuObject *found = nullptr;
-+ uint32_t count = ChildCount();
-+ for (uint32_t i = 0; i < count; ++i) {
-+ nsAutoString accesskey;
-+ ChildAt(i)->ContentNode()->AsElement()->GetAttr(kNameSpaceID_None,
-+ nsGkAtoms::accesskey,
-+ accesskey);
-+ const nsAutoString::char_type *key = accesskey.BeginReading();
-+ if (*key == chu || *key == chl) {
-+ found = ChildAt(i);
-+ break;
-+ }
-+ }
-+
-+ if (!found || found->Type() != nsMenuObject::eType_Menu) {
-+ return NS_OK;
-+ }
-+
-+ ContentNode()->AsElement()->SetAttr(kNameSpaceID_None,
-+ nsGkAtoms::openedwithkey,
-+ u"true"_ns, true);
-+ static_cast<nsMenu *>(found)->OpenMenu();
-+
-+ aEvent->StopPropagation();
-+ aEvent->PreventDefault();
-+
-+ return NS_OK;
-+}
-+
-+nsresult
-+nsMenuBar::KeyDown(dom::KeyboardEvent *aEvent)
-+{
-+ if (!ShouldHandleKeyEvent(aEvent)) {
-+ return NS_OK;
-+ }
-+
-+ uint32_t keyCode = aEvent->KeyCode();
-+ ModifierFlags modifiers = GetModifiersFromEvent(aEvent);
-+ if ((keyCode != mAccessKey) || ((modifiers & ~mAccessKeyMask) != 0)) {
-+ return NS_OK;
-+ }
-+
-+ dbusmenu_server_set_status(mServer, DBUSMENU_STATUS_NOTICE);
-+
-+ return NS_OK;
-+}
-+
-+nsresult
-+nsMenuBar::KeyUp(dom::KeyboardEvent *aEvent)
-+{
-+ if (!ShouldHandleKeyEvent(aEvent)) {
-+ return NS_OK;
-+ }
-+
-+ uint32_t keyCode = aEvent->KeyCode();
-+ if (keyCode == mAccessKey) {
-+ dbusmenu_server_set_status(mServer, DBUSMENU_STATUS_NORMAL);
-+ }
-+
-+ return NS_OK;
-+}
-+
-+void
-+nsMenuBar::HandleContentInserted(nsIContent *aChild, nsIContent *aPrevSibling)
-+{
-+ UniquePtr<nsMenuObject> child = CreateChild(aChild);
-+
-+ if (!child) {
-+ return;
-+ }
-+
-+ InsertChildAfter(std::move(child), aPrevSibling);
-+}
-+
-+void
-+nsMenuBar::HandleContentRemoved(nsIContent *aChild)
-+{
-+ RemoveChild(aChild);
-+}
-+
-+void
-+nsMenuBar::OnContentInserted(nsIContent *aContainer, nsIContent *aChild,
-+ nsIContent *aPrevSibling)
-+{
-+ MOZ_ASSERT(aContainer == ContentNode(),
-+ "Received an event that wasn't meant for us");
-+
-+ nsContentUtils::AddScriptRunner(
-+ new nsMenuBarContentInsertedEvent(this, aChild, aPrevSibling));
-+}
-+
-+void
-+nsMenuBar::OnContentRemoved(nsIContent *aContainer, nsIContent *aChild)
-+{
-+ MOZ_ASSERT(aContainer == ContentNode(),
-+ "Received an event that wasn't meant for us");
-+
-+ nsContentUtils::AddScriptRunner(
-+ new nsMenuBarContentRemovedEvent(this, aChild));
-+}
-+
-+nsMenuBar::~nsMenuBar()
-+{
-+ nsNativeMenuService *service = nsNativeMenuService::GetSingleton();
-+ if (service) {
-+ service->NotifyNativeMenuBarDestroyed(this);
-+ }
-+
-+ if (ContentNode()) {
-+ SetShellShowingMenuBar(false);
-+ }
-+
-+ // We want to destroy all children before dropping our reference
-+ // to the doc listener
-+ while (ChildCount() > 0) {
-+ RemoveChildAt(0);
-+ }
-+
-+ if (mTopLevel) {
-+ g_object_unref(mTopLevel);
-+ }
-+
-+ if (DocListener()) {
-+ DocListener()->Stop();
-+ }
-+
-+ if (mDocument) {
-+ DisconnectDocumentEventListeners();
-+ }
-+
-+ if (mServer) {
-+ g_object_unref(mServer);
-+ }
-+
-+ MOZ_COUNT_DTOR(nsMenuBar);
-+}
-+
-+/* static */ UniquePtr<nsMenuBar>
-+nsMenuBar::Create(nsIWidget *aParent, nsIContent *aMenuBarNode)
-+{
-+ UniquePtr<nsMenuBar> menubar(new nsMenuBar(aMenuBarNode));
-+ if (NS_FAILED(menubar->Init(aParent))) {
-+ return nullptr;
-+ }
-+
-+ return menubar;
-+}
-+
-+nsMenuObject::EType
-+nsMenuBar::Type() const
-+{
-+ return eType_MenuBar;
-+}
-+
-+bool
-+nsMenuBar::IsBeingDisplayed() const
-+{
-+ return true;
-+}
-+
-+uint32_t
-+nsMenuBar::WindowId() const
-+{
-+ return static_cast<uint32_t>(GDK_WINDOW_XID(gtk_widget_get_window(mTopLevel)));
-+}
-+
-+nsCString
-+nsMenuBar::ObjectPath() const
-+{
-+ gchar *tmp;
-+ g_object_get(mServer, DBUSMENU_SERVER_PROP_DBUS_OBJECT, &tmp, NULL);
-+
-+ nsCString result;
-+ result.Adopt(tmp);
-+
-+ return result;
-+}
-+
-+void
-+nsMenuBar::Activate()
-+{
-+ if (mIsActive) {
-+ return;
-+ }
-+
-+ mIsActive = true;
-+
-+ mDocument->AddEventListener(u"focus"_ns,
-+ mEventListener,
-+ true);
-+ mDocument->AddEventListener(u"blur"_ns,
-+ mEventListener,
-+ true);
-+ mDocument->AddEventListener(u"keypress"_ns,
-+ mEventListener,
-+ false);
-+ mDocument->AddEventListener(u"keydown"_ns,
-+ mEventListener,
-+ false);
-+ mDocument->AddEventListener(u"keyup"_ns,
-+ mEventListener,
-+ false);
-+
-+ // Clear this. Not sure if we really need to though
-+ ContentNode()->AsElement()->SetAttr(kNameSpaceID_None,
-+ nsGkAtoms::openedwithkey,
-+ u"false"_ns, true);
-+
-+ DocListener()->Start();
-+ Build();
-+ SetShellShowingMenuBar(true);
-+}
-+
-+void
-+nsMenuBar::Deactivate()
-+{
-+ if (!mIsActive) {
-+ return;
-+ }
-+
-+ mIsActive = false;
-+
-+ SetShellShowingMenuBar(false);
-+ while (ChildCount() > 0) {
-+ RemoveChildAt(0);
-+ }
-+ DocListener()->Stop();
-+ DisconnectDocumentEventListeners();
-+}
-diff --git a/widget/gtk/nsMenuBar.h b/widget/gtk/nsMenuBar.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..7a04316330c1926ea3aabed72b5ae379814be2fc
---- /dev/null
-+++ b/widget/gtk/nsMenuBar.h
-@@ -0,0 +1,111 @@
-+/* -*- 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 __nsMenuBar_h__
-+#define __nsMenuBar_h__
-+
-+#include "mozilla/Attributes.h"
-+#include "mozilla/UniquePtr.h"
-+#include "nsCOMPtr.h"
-+#include "nsString.h"
-+
-+#include "nsDbusmenu.h"
-+#include "nsMenuContainer.h"
-+#include "nsMenuObject.h"
-+
-+#include <gtk/gtk.h>
-+
-+class nsIContent;
-+class nsIWidget;
-+class nsMenuBarDocEventListener;
-+
-+namespace mozilla {
-+namespace dom {
-+class Document;
-+class KeyboardEvent;
-+}
-+}
-+
-+/*
-+ * The menubar class. There is one of these per window (and the window
-+ * owns its menubar). Each menubar has an object path, and the service is
-+ * responsible for telling the desktop shell which object path corresponds
-+ * to a particular window. A menubar and its hierarchy also own a
-+ * nsNativeMenuDocListener.
-+ */
-+class nsMenuBar final : public nsMenuContainer
-+{
-+public:
-+ ~nsMenuBar() override;
-+
-+ static mozilla::UniquePtr<nsMenuBar> Create(nsIWidget *aParent,
-+ nsIContent *aMenuBarNode);
-+
-+ nsMenuObject::EType Type() const override;
-+
-+ bool IsBeingDisplayed() const override;
-+
-+ // Get the native window ID for this menubar
-+ uint32_t WindowId() const;
-+
-+ // Get the object path for this menubar
-+ nsCString ObjectPath() const;
-+
-+ // Get the top-level GtkWindow handle
-+ GtkWidget* TopLevelWindow() { return mTopLevel; }
-+
-+ // Called from the menuservice when the menubar is about to be registered.
-+ // Causes the native menubar to be created, and the XUL menubar to be hidden
-+ void Activate();
-+
-+ // Called from the menuservice when the menubar is no longer registered
-+ // with the desktop shell. Will cause the XUL menubar to be shown again
-+ void Deactivate();
-+
-+private:
-+ class DocEventListener;
-+ friend class nsMenuBarContentInsertedEvent;
-+ friend class nsMenuBarContentRemovedEvent;
-+
-+ enum ModifierFlags {
-+ eModifierShift = (1 << 0),
-+ eModifierCtrl = (1 << 1),
-+ eModifierAlt = (1 << 2),
-+ eModifierMeta = (1 << 3)
-+ };
-+
-+ nsMenuBar(nsIContent *aMenuBarNode);
-+ nsresult Init(nsIWidget *aParent);
-+ void Build();
-+ void DisconnectDocumentEventListeners();
-+ void SetShellShowingMenuBar(bool aShowing);
-+ void Focus();
-+ void Blur();
-+ ModifierFlags GetModifiersFromEvent(mozilla::dom::KeyboardEvent *aEvent);
-+ nsresult Keypress(mozilla::dom::KeyboardEvent *aEvent);
-+ nsresult KeyDown(mozilla::dom::KeyboardEvent *aEvent);
-+ nsresult KeyUp(mozilla::dom::KeyboardEvent *aEvent);
-+
-+ void HandleContentInserted(nsIContent *aChild,
-+ nsIContent *aPrevSibling);
-+ void HandleContentRemoved(nsIContent *aChild);
-+
-+ void OnContentInserted(nsIContent *aContainer, nsIContent *aChild,
-+ nsIContent *aPrevSibling) override;
-+ void OnContentRemoved(nsIContent *aContainer, nsIContent *aChild) override;
-+
-+ GtkWidget *mTopLevel;
-+ DbusmenuServer *mServer;
-+ nsCOMPtr<mozilla::dom::Document> mDocument;
-+ RefPtr<DocEventListener> mEventListener;
-+
-+ uint32_t mAccessKey;
-+ ModifierFlags mAccessKeyMask;
-+ bool mIsActive;
-+};
-+
-+#endif /* __nsMenuBar_h__ */
-diff --git a/widget/gtk/nsMenuContainer.cpp b/widget/gtk/nsMenuContainer.cpp
-new file mode 100644
-index 0000000000000000000000000000000000000000..f419201f6338bc0e91539693a1c61812de0afa08
---- /dev/null
-+++ b/widget/gtk/nsMenuContainer.cpp
-@@ -0,0 +1,170 @@
-+/* -*- 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 "mozilla/DebugOnly.h"
-+#include "nsGkAtoms.h"
-+#include "nsIContent.h"
-+
-+#include "nsDbusmenu.h"
-+#include "nsMenu.h"
-+#include "nsMenuItem.h"
-+#include "nsMenuSeparator.h"
-+
-+#include "nsMenuContainer.h"
-+
-+using namespace mozilla;
-+
-+const nsMenuContainer::ChildTArray::index_type nsMenuContainer::NoIndex = nsMenuContainer::ChildTArray::NoIndex;
-+
-+typedef UniquePtr<nsMenuObject> (*nsMenuObjectConstructor)(nsMenuContainer*,
-+ nsIContent*);
-+
-+template<class T>
-+static UniquePtr<nsMenuObject> CreateMenuObject(nsMenuContainer *aContainer,
-+ nsIContent *aContent)
-+{
-+ return UniquePtr<T>(new T(aContainer, aContent));
-+}
-+
-+static nsMenuObjectConstructor
-+GetMenuObjectConstructor(nsIContent *aContent)
-+{
-+ if (aContent->IsXULElement(nsGkAtoms::menuitem)) {
-+ return CreateMenuObject<nsMenuItem>;
-+ } else if (aContent->IsXULElement(nsGkAtoms::menu)) {
-+ return CreateMenuObject<nsMenu>;
-+ } else if (aContent->IsXULElement(nsGkAtoms::menuseparator)) {
-+ return CreateMenuObject<nsMenuSeparator>;
-+ }
-+
-+ return nullptr;
-+}
-+
-+static bool
-+ContentIsSupported(nsIContent *aContent)
-+{
-+ return GetMenuObjectConstructor(aContent) ? true : false;
-+}
-+
-+nsMenuContainer::nsMenuContainer(nsMenuContainer *aParent,
-+ nsIContent *aContent) :
-+ nsMenuObject(aParent, aContent)
-+{
-+}
-+
-+nsMenuContainer::nsMenuContainer(nsNativeMenuDocListener *aListener,
-+ nsIContent *aContent) :
-+ nsMenuObject(aListener, aContent)
-+{
-+}
-+
-+UniquePtr<nsMenuObject>
-+nsMenuContainer::CreateChild(nsIContent *aContent)
-+{
-+ nsMenuObjectConstructor ctor = GetMenuObjectConstructor(aContent);
-+ if (!ctor) {
-+ // There are plenty of node types we might stumble across that
-+ // aren't supported
-+ return nullptr;
-+ }
-+
-+ UniquePtr<nsMenuObject> res = ctor(this, aContent);
-+ return res;
-+}
-+
-+size_t
-+nsMenuContainer::IndexOf(nsIContent *aChild) const
-+{
-+ if (!aChild) {
-+ return NoIndex;
-+ }
-+
-+ size_t count = ChildCount();
-+ for (size_t i = 0; i < count; ++i) {
-+ if (ChildAt(i)->ContentNode() == aChild) {
-+ return i;
-+ }
-+ }
-+
-+ return NoIndex;
-+}
-+
-+void
-+nsMenuContainer::RemoveChildAt(size_t aIndex, bool aUpdateNative)
-+{
-+ MOZ_ASSERT(aIndex < ChildCount());
-+
-+ if (aUpdateNative) {
-+ MOZ_ALWAYS_TRUE(
-+ dbusmenu_menuitem_child_delete(GetNativeData(),
-+ ChildAt(aIndex)->GetNativeData()));
-+ }
-+
-+ mChildren.RemoveElementAt(aIndex);
-+}
-+
-+void
-+nsMenuContainer::RemoveChild(nsIContent *aChild, bool aUpdateNative)
-+{
-+ size_t index = IndexOf(aChild);
-+ if (index == NoIndex) {
-+ return;
-+ }
-+
-+ RemoveChildAt(index, aUpdateNative);
-+}
-+
-+void
-+nsMenuContainer::InsertChildAfter(UniquePtr<nsMenuObject> aChild,
-+ nsIContent *aPrevSibling,
-+ bool aUpdateNative)
-+{
-+ size_t index = IndexOf(aPrevSibling);
-+ MOZ_ASSERT(!aPrevSibling || index != NoIndex);
-+
-+ ++index;
-+
-+ if (aUpdateNative) {
-+ aChild->CreateNativeData();
-+ MOZ_ALWAYS_TRUE(
-+ dbusmenu_menuitem_child_add_position(GetNativeData(),
-+ aChild->GetNativeData(),
-+ index));
-+ }
-+
-+ mChildren.InsertElementAt(index, std::move(aChild));
-+}
-+
-+void
-+nsMenuContainer::AppendChild(UniquePtr<nsMenuObject> aChild,
-+ bool aUpdateNative)
-+{
-+ if (aUpdateNative) {
-+ aChild->CreateNativeData();
-+ MOZ_ALWAYS_TRUE(
-+ dbusmenu_menuitem_child_append(GetNativeData(),
-+ aChild->GetNativeData()));
-+ }
-+
-+ mChildren.AppendElement(std::move(aChild));
-+}
-+
-+bool
-+nsMenuContainer::NeedsRebuild() const
-+{
-+ return false;
-+}
-+
-+/* static */ nsIContent*
-+nsMenuContainer::GetPreviousSupportedSibling(nsIContent *aContent)
-+{
-+ do {
-+ aContent = aContent->GetPreviousSibling();
-+ } while (aContent && !ContentIsSupported(aContent));
-+
-+ return aContent;
-+}
-diff --git a/widget/gtk/nsMenuContainer.h b/widget/gtk/nsMenuContainer.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..b7e8fa8db46fb1bfdb94ee0b04a69630f962e1c2
---- /dev/null
-+++ b/widget/gtk/nsMenuContainer.h
-@@ -0,0 +1,70 @@
-+/* -*- 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 __nsMenuContainer_h__
-+#define __nsMenuContainer_h__
-+
-+#include "mozilla/UniquePtr.h"
-+#include "nsTArray.h"
-+
-+#include "nsMenuObject.h"
-+
-+class nsIContent;
-+class nsNativeMenuDocListener;
-+
-+// Base class for containers (menus and menubars)
-+class nsMenuContainer : public nsMenuObject
-+{
-+public:
-+ typedef nsTArray<mozilla::UniquePtr<nsMenuObject> > ChildTArray;
-+
-+ // Determine if this container is being displayed on screen. Must be
-+ // implemented by subclasses. Must return true if the container is
-+ // in the fully open state, or false otherwise
-+ virtual bool IsBeingDisplayed() const = 0;
-+
-+ // Determine if this container will be rebuilt the next time it opens.
-+ // Returns false by default but can be overridden by subclasses
-+ virtual bool NeedsRebuild() const;
-+
-+ // Return the first previous sibling that is of a type supported by the
-+ // menu system
-+ static nsIContent* GetPreviousSupportedSibling(nsIContent *aContent);
-+
-+ static const ChildTArray::index_type NoIndex;
-+
-+protected:
-+ nsMenuContainer(nsMenuContainer *aParent, nsIContent *aContent);
-+ nsMenuContainer(nsNativeMenuDocListener *aListener, nsIContent *aContent);
-+
-+ // Create a new child element for the specified content node
-+ mozilla::UniquePtr<nsMenuObject> CreateChild(nsIContent *aContent);
-+
-+ // Return the index of the child for the specified content node
-+ size_t IndexOf(nsIContent *aChild) const;
-+
-+ size_t ChildCount() const { return mChildren.Length(); }
-+ nsMenuObject* ChildAt(size_t aIndex) const { return mChildren[aIndex].get(); }
-+
-+ void RemoveChildAt(size_t aIndex, bool aUpdateNative = true);
-+
-+ // Remove the child that owns the specified content node
-+ void RemoveChild(nsIContent *aChild, bool aUpdateNative = true);
-+
-+ // Insert a new child after the child that owns the specified content node
-+ void InsertChildAfter(mozilla::UniquePtr<nsMenuObject> aChild,
-+ nsIContent *aPrevSibling,
-+ bool aUpdateNative = true);
-+
-+ void AppendChild(mozilla::UniquePtr<nsMenuObject> aChild,
-+ bool aUpdateNative = true);
-+
-+private:
-+ ChildTArray mChildren;
-+};
-+
-+#endif /* __nsMenuContainer_h__ */
-diff --git a/widget/gtk/nsMenuItem.cpp b/widget/gtk/nsMenuItem.cpp
-new file mode 100644
-index 0000000000000000000000000000000000000000..3a9915e609f599df501c1a6f3baa34e4cd651832
---- /dev/null
-+++ b/widget/gtk/nsMenuItem.cpp
-@@ -0,0 +1,766 @@
-+/* -*- 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 "mozilla/ArrayUtils.h"
-+#include "mozilla/Assertions.h"
-+#include "mozilla/dom/Document.h"
-+#include "mozilla/dom/Element.h"
-+#include "mozilla/dom/KeyboardEventBinding.h"
-+#include "mozilla/dom/XULCommandEvent.h"
-+#include "mozilla/Preferences.h"
-+#include "mozilla/TextEvents.h"
-+#include "nsContentUtils.h"
-+#include "nsCRT.h"
-+#include "nsGkAtoms.h"
-+#include "nsGlobalWindowInner.h"
-+#include "nsGtkUtils.h"
-+#include "nsIContent.h"
-+#include "nsIRunnable.h"
-+#include "nsQueryObject.h"
-+#include "nsReadableUtils.h"
-+#include "nsString.h"
-+#include "nsThreadUtils.h"
-+
-+#include "nsMenu.h"
-+#include "nsMenuBar.h"
-+#include "nsMenuContainer.h"
-+#include "nsNativeMenuDocListener.h"
-+
-+#include <gdk/gdk.h>
-+#include <gdk/gdkkeysyms.h>
-+#include <gdk/gdkkeysyms-compat.h>
-+#include <gdk/gdkx.h>
-+#include <gtk/gtk.h>
-+
-+#include "nsMenuItem.h"
-+
-+using namespace mozilla;
-+
-+struct KeyCodeData {
-+ const char* str;
-+ size_t strlength;
-+ uint32_t keycode;
-+};
-+
-+static struct KeyCodeData gKeyCodes[] = {
-+#define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) \
-+ { #aDOMKeyName, sizeof(#aDOMKeyName) - 1, aDOMKeyCode },
-+#include "mozilla/VirtualKeyCodeList.h"
-+#undef NS_DEFINE_VK
-+ { nullptr, 0, 0 }
-+};
-+
-+struct KeyPair {
-+ uint32_t DOMKeyCode;
-+ guint GDKKeyval;
-+};
-+
-+//
-+// Netscape keycodes are defined in widget/public/nsGUIEvent.h
-+// GTK keycodes are defined in <gdk/gdkkeysyms.h>
-+//
-+static const KeyPair gKeyPairs[] = {
-+ { NS_VK_CANCEL, GDK_Cancel },
-+ { NS_VK_BACK, GDK_BackSpace },
-+ { NS_VK_TAB, GDK_Tab },
-+ { NS_VK_TAB, GDK_ISO_Left_Tab },
-+ { NS_VK_CLEAR, GDK_Clear },
-+ { NS_VK_RETURN, GDK_Return },
-+ { NS_VK_SHIFT, GDK_Shift_L },
-+ { NS_VK_SHIFT, GDK_Shift_R },
-+ { NS_VK_SHIFT, GDK_Shift_Lock },
-+ { NS_VK_CONTROL, GDK_Control_L },
-+ { NS_VK_CONTROL, GDK_Control_R },
-+ { NS_VK_ALT, GDK_Alt_L },
-+ { NS_VK_ALT, GDK_Alt_R },
-+ { NS_VK_META, GDK_Meta_L },
-+ { NS_VK_META, GDK_Meta_R },
-+
-+ // Assume that Super or Hyper is always mapped to physical Win key.
-+ { NS_VK_WIN, GDK_Super_L },
-+ { NS_VK_WIN, GDK_Super_R },
-+ { NS_VK_WIN, GDK_Hyper_L },
-+ { NS_VK_WIN, GDK_Hyper_R },
-+
-+ // GTK's AltGraph key is similar to Mac's Option (Alt) key. However,
-+ // unfortunately, browsers on Mac are using NS_VK_ALT for it even though
-+ // it's really different from Alt key on Windows.
-+ // On the other hand, GTK's AltGrapsh keys are really different from
-+ // Alt key. However, there is no AltGrapsh key on Windows. On Windows,
-+ // both Ctrl and Alt keys are pressed internally when AltGr key is pressed.
-+ // For some languages' users, AltGraph key is important, so, web
-+ // applications on such locale may want to know AltGraph key press.
-+ // Therefore, we should map AltGr keycode for them only on GTK.
-+ { NS_VK_ALTGR, GDK_ISO_Level3_Shift },
-+ { NS_VK_ALTGR, GDK_ISO_Level5_Shift },
-+ // We assume that Mode_switch is always used for level3 shift.
-+ { NS_VK_ALTGR, GDK_Mode_switch },
-+
-+ { NS_VK_PAUSE, GDK_Pause },
-+ { NS_VK_CAPS_LOCK, GDK_Caps_Lock },
-+ { NS_VK_KANA, GDK_Kana_Lock },
-+ { NS_VK_KANA, GDK_Kana_Shift },
-+ { NS_VK_HANGUL, GDK_Hangul },
-+ // { NS_VK_JUNJA, GDK_XXX },
-+ // { NS_VK_FINAL, GDK_XXX },
-+ { NS_VK_HANJA, GDK_Hangul_Hanja },
-+ { NS_VK_KANJI, GDK_Kanji },
-+ { NS_VK_ESCAPE, GDK_Escape },
-+ { NS_VK_CONVERT, GDK_Henkan },
-+ { NS_VK_NONCONVERT, GDK_Muhenkan },
-+ // { NS_VK_ACCEPT, GDK_XXX },
-+ // { NS_VK_MODECHANGE, GDK_XXX },
-+ { NS_VK_SPACE, GDK_space },
-+ { NS_VK_PAGE_UP, GDK_Page_Up },
-+ { NS_VK_PAGE_DOWN, GDK_Page_Down },
-+ { NS_VK_END, GDK_End },
-+ { NS_VK_HOME, GDK_Home },
-+ { NS_VK_LEFT, GDK_Left },
-+ { NS_VK_UP, GDK_Up },
-+ { NS_VK_RIGHT, GDK_Right },
-+ { NS_VK_DOWN, GDK_Down },
-+ { NS_VK_SELECT, GDK_Select },
-+ { NS_VK_PRINT, GDK_Print },
-+ { NS_VK_EXECUTE, GDK_Execute },
-+ { NS_VK_PRINTSCREEN, GDK_Print },
-+ { NS_VK_INSERT, GDK_Insert },
-+ { NS_VK_DELETE, GDK_Delete },
-+ { NS_VK_HELP, GDK_Help },
-+
-+ // keypad keys
-+ { NS_VK_LEFT, GDK_KP_Left },
-+ { NS_VK_RIGHT, GDK_KP_Right },
-+ { NS_VK_UP, GDK_KP_Up },
-+ { NS_VK_DOWN, GDK_KP_Down },
-+ { NS_VK_PAGE_UP, GDK_KP_Page_Up },
-+ // Not sure what these are
-+ //{ NS_VK_, GDK_KP_Prior },
-+ //{ NS_VK_, GDK_KP_Next },
-+ { NS_VK_CLEAR, GDK_KP_Begin }, // Num-unlocked 5
-+ { NS_VK_PAGE_DOWN, GDK_KP_Page_Down },
-+ { NS_VK_HOME, GDK_KP_Home },
-+ { NS_VK_END, GDK_KP_End },
-+ { NS_VK_INSERT, GDK_KP_Insert },
-+ { NS_VK_DELETE, GDK_KP_Delete },
-+ { NS_VK_RETURN, GDK_KP_Enter },
-+
-+ { NS_VK_NUM_LOCK, GDK_Num_Lock },
-+ { NS_VK_SCROLL_LOCK,GDK_Scroll_Lock },
-+
-+ // Function keys
-+ { NS_VK_F1, GDK_F1 },
-+ { NS_VK_F2, GDK_F2 },
-+ { NS_VK_F3, GDK_F3 },
-+ { NS_VK_F4, GDK_F4 },
-+ { NS_VK_F5, GDK_F5 },
-+ { NS_VK_F6, GDK_F6 },
-+ { NS_VK_F7, GDK_F7 },
-+ { NS_VK_F8, GDK_F8 },
-+ { NS_VK_F9, GDK_F9 },
-+ { NS_VK_F10, GDK_F10 },
-+ { NS_VK_F11, GDK_F11 },
-+ { NS_VK_F12, GDK_F12 },
-+ { NS_VK_F13, GDK_F13 },
-+ { NS_VK_F14, GDK_F14 },
-+ { NS_VK_F15, GDK_F15 },
-+ { NS_VK_F16, GDK_F16 },
-+ { NS_VK_F17, GDK_F17 },
-+ { NS_VK_F18, GDK_F18 },
-+ { NS_VK_F19, GDK_F19 },
-+ { NS_VK_F20, GDK_F20 },
-+ { NS_VK_F21, GDK_F21 },
-+ { NS_VK_F22, GDK_F22 },
-+ { NS_VK_F23, GDK_F23 },
-+ { NS_VK_F24, GDK_F24 },
-+
-+ // context menu key, keysym 0xff67, typically keycode 117 on 105-key (Microsoft)
-+ // x86 keyboards, located between right 'Windows' key and right Ctrl key
-+ { NS_VK_CONTEXT_MENU, GDK_Menu },
-+ { NS_VK_SLEEP, GDK_Sleep },
-+
-+ { NS_VK_ATTN, GDK_3270_Attn },
-+ { NS_VK_CRSEL, GDK_3270_CursorSelect },
-+ { NS_VK_EXSEL, GDK_3270_ExSelect },
-+ { NS_VK_EREOF, GDK_3270_EraseEOF },
-+ { NS_VK_PLAY, GDK_3270_Play },
-+ //{ NS_VK_ZOOM, GDK_XXX },
-+ { NS_VK_PA1, GDK_3270_PA1 },
-+};
-+
-+static guint
-+ConvertGeckoKeyNameToGDKKeyval(nsAString& aKeyName)
-+{
-+ NS_ConvertUTF16toUTF8 keyName(aKeyName);
-+ ToUpperCase(keyName); // We want case-insensitive comparison with data
-+ // stored as uppercase.
-+
-+ uint32_t keyCode = 0;
-+
-+ uint32_t keyNameLength = keyName.Length();
-+ const char* keyNameStr = keyName.get();
-+ for (uint16_t i = 0; i < ArrayLength(gKeyCodes); ++i) {
-+ if (keyNameLength == gKeyCodes[i].strlength &&
-+ !nsCRT::strcmp(gKeyCodes[i].str, keyNameStr)) {
-+ keyCode = gKeyCodes[i].keycode;
-+ break;
-+ }
-+ }
-+
-+ // First, try to handle alphanumeric input, not listed in nsKeycodes:
-+ // most likely, more letters will be getting typed in than things in
-+ // the key list, so we will look through these first.
-+
-+ if (keyCode >= NS_VK_A && keyCode <= NS_VK_Z) {
-+ // gdk and DOM both use the ASCII codes for these keys.
-+ return keyCode;
-+ }
-+
-+ // numbers
-+ if (keyCode >= NS_VK_0 && keyCode <= NS_VK_9) {
-+ // gdk and DOM both use the ASCII codes for these keys.
-+ return keyCode - NS_VK_0 + GDK_0;
-+ }
-+
-+ switch (keyCode) {
-+ // keys in numpad
-+ case NS_VK_MULTIPLY: return GDK_KP_Multiply;
-+ case NS_VK_ADD: return GDK_KP_Add;
-+ case NS_VK_SEPARATOR: return GDK_KP_Separator;
-+ case NS_VK_SUBTRACT: return GDK_KP_Subtract;
-+ case NS_VK_DECIMAL: return GDK_KP_Decimal;
-+ case NS_VK_DIVIDE: return GDK_KP_Divide;
-+ case NS_VK_NUMPAD0: return GDK_KP_0;
-+ case NS_VK_NUMPAD1: return GDK_KP_1;
-+ case NS_VK_NUMPAD2: return GDK_KP_2;
-+ case NS_VK_NUMPAD3: return GDK_KP_3;
-+ case NS_VK_NUMPAD4: return GDK_KP_4;
-+ case NS_VK_NUMPAD5: return GDK_KP_5;
-+ case NS_VK_NUMPAD6: return GDK_KP_6;
-+ case NS_VK_NUMPAD7: return GDK_KP_7;
-+ case NS_VK_NUMPAD8: return GDK_KP_8;
-+ case NS_VK_NUMPAD9: return GDK_KP_9;
-+ // other prinable keys
-+ case NS_VK_SPACE: return GDK_space;
-+ case NS_VK_COLON: return GDK_colon;
-+ case NS_VK_SEMICOLON: return GDK_semicolon;
-+ case NS_VK_LESS_THAN: return GDK_less;
-+ case NS_VK_EQUALS: return GDK_equal;
-+ case NS_VK_GREATER_THAN: return GDK_greater;
-+ case NS_VK_QUESTION_MARK: return GDK_question;
-+ case NS_VK_AT: return GDK_at;
-+ case NS_VK_CIRCUMFLEX: return GDK_asciicircum;
-+ case NS_VK_EXCLAMATION: return GDK_exclam;
-+ case NS_VK_DOUBLE_QUOTE: return GDK_quotedbl;
-+ case NS_VK_HASH: return GDK_numbersign;
-+ case NS_VK_DOLLAR: return GDK_dollar;
-+ case NS_VK_PERCENT: return GDK_percent;
-+ case NS_VK_AMPERSAND: return GDK_ampersand;
-+ case NS_VK_UNDERSCORE: return GDK_underscore;
-+ case NS_VK_OPEN_PAREN: return GDK_parenleft;
-+ case NS_VK_CLOSE_PAREN: return GDK_parenright;
-+ case NS_VK_ASTERISK: return GDK_asterisk;
-+ case NS_VK_PLUS: return GDK_plus;
-+ case NS_VK_PIPE: return GDK_bar;
-+ case NS_VK_HYPHEN_MINUS: return GDK_minus;
-+ case NS_VK_OPEN_CURLY_BRACKET: return GDK_braceleft;
-+ case NS_VK_CLOSE_CURLY_BRACKET: return GDK_braceright;
-+ case NS_VK_TILDE: return GDK_asciitilde;
-+ case NS_VK_COMMA: return GDK_comma;
-+ case NS_VK_PERIOD: return GDK_period;
-+ case NS_VK_SLASH: return GDK_slash;
-+ case NS_VK_BACK_QUOTE: return GDK_grave;
-+ case NS_VK_OPEN_BRACKET: return GDK_bracketleft;
-+ case NS_VK_BACK_SLASH: return GDK_backslash;
-+ case NS_VK_CLOSE_BRACKET: return GDK_bracketright;
-+ case NS_VK_QUOTE: return GDK_apostrophe;
-+ }
-+
-+ // misc other things
-+ for (uint32_t i = 0; i < ArrayLength(gKeyPairs); ++i) {
-+ if (gKeyPairs[i].DOMKeyCode == keyCode) {
-+ return gKeyPairs[i].GDKKeyval;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+class nsMenuItemUncheckSiblingsRunnable final : public Runnable
-+{
-+public:
-+ NS_IMETHODIMP Run()
-+ {
-+ if (mMenuItem) {
-+ static_cast<nsMenuItem *>(mMenuItem.get())->UncheckSiblings();
-+ }
-+ return NS_OK;
-+ }
-+
-+ nsMenuItemUncheckSiblingsRunnable(nsMenuItem *aMenuItem) :
-+ Runnable("nsMenuItemUncheckSiblingsRunnable"),
-+ mMenuItem(aMenuItem) { };
-+
-+private:
-+ nsWeakMenuObject mMenuItem;
-+};
-+
-+bool
-+nsMenuItem::IsCheckboxOrRadioItem() const
-+{
-+ return mType == eMenuItemType_Radio ||
-+ mType == eMenuItemType_CheckBox;
-+}
-+
-+/* static */ void
-+nsMenuItem::item_activated_cb(DbusmenuMenuitem *menuitem,
-+ guint timestamp,
-+ gpointer user_data)
-+{
-+ nsMenuItem *item = static_cast<nsMenuItem *>(user_data);
-+ item->Activate(timestamp);
-+}
-+
-+void
-+nsMenuItem::Activate(uint32_t aTimestamp)
-+{
-+ GdkWindow *window = gtk_widget_get_window(MenuBar()->TopLevelWindow());
-+ gdk_x11_window_set_user_time(
-+ window, std::min(aTimestamp, gdk_x11_get_server_time(window)));
-+
-+ // We do this to avoid mutating our view of the menu until
-+ // after we have finished
-+ nsNativeMenuDocListener::BlockUpdatesScope updatesBlocker;
-+
-+ if (!ContentNode()->AsElement()->AttrValueIs(kNameSpaceID_None,
-+ nsGkAtoms::autocheck,
-+ nsGkAtoms::_false,
-+ eCaseMatters) &&
-+ (mType == eMenuItemType_CheckBox ||
-+ (mType == eMenuItemType_Radio && !mIsChecked))) {
-+ ContentNode()->AsElement()->SetAttr(kNameSpaceID_None,
-+ nsGkAtoms::checked,
-+ mIsChecked ?
-+ u"false"_ns
-+ : u"true"_ns,
-+ true);
-+ }
-+
-+ dom::Document *doc = ContentNode()->OwnerDoc();
-+ ErrorResult rv;
-+ RefPtr<dom::Event> event =
-+ doc->CreateEvent(u"xulcommandevent"_ns,
-+ dom::CallerType::System, rv);
-+ if (!rv.Failed()) {
-+ RefPtr<dom::XULCommandEvent> command = event->AsXULCommandEvent();
-+ if (command) {
-+ command->InitCommandEvent(u"command"_ns, true, true,
-+ nsGlobalWindowInner::Cast(doc->GetInnerWindow()),
-+ 0, false, false, false, false, 0, nullptr, 0, rv);
-+ if (!rv.Failed()) {
-+ event->SetTrusted(true);
-+ ContentNode()->DispatchEvent(*event, rv);
-+ if (rv.Failed()) {
-+ NS_WARNING("Failed to dispatch event");
-+ rv.SuppressException();
-+ }
-+ } else {
-+ NS_WARNING("Failed to initialize command event");
-+ rv.SuppressException();
-+ }
-+ }
-+ } else {
-+ NS_WARNING("CreateEvent failed");
-+ rv.SuppressException();
-+ }
-+
-+ // This kinda sucks, but Unity doesn't send a closed event
-+ // after activating a menuitem
-+ nsMenuObject *ancestor = Parent();
-+ while (ancestor && ancestor->Type() == eType_Menu) {
-+ static_cast<nsMenu *>(ancestor)->OnClose();
-+ ancestor = ancestor->Parent();
-+ }
-+}
-+
-+void
-+nsMenuItem::CopyAttrFromNodeIfExists(nsIContent *aContent, nsAtom *aAttribute)
-+{
-+ nsAutoString value;
-+ if (aContent->AsElement()->GetAttr(kNameSpaceID_None, aAttribute, value)) {
-+ ContentNode()->AsElement()->SetAttr(kNameSpaceID_None, aAttribute,
-+ value, true);
-+ }
-+}
-+
-+void
-+nsMenuItem::UpdateState()
-+{
-+ if (!IsCheckboxOrRadioItem()) {
-+ return;
-+ }
-+
-+ mIsChecked = ContentNode()->AsElement()->AttrValueIs(kNameSpaceID_None,
-+ nsGkAtoms::checked,
-+ nsGkAtoms::_true,
-+ eCaseMatters);
-+ dbusmenu_menuitem_property_set_int(GetNativeData(),
-+ DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
-+ mIsChecked ?
-+ DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED :
-+ DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
-+}
-+
-+void
-+nsMenuItem::UpdateTypeAndState()
-+{
-+ static mozilla::dom::Element::AttrValuesArray attrs[] =
-+ { nsGkAtoms::checkbox, nsGkAtoms::radio, nullptr };
-+ int32_t type = ContentNode()->AsElement()->FindAttrValueIn(kNameSpaceID_None,
-+ nsGkAtoms::type,
-+ attrs, eCaseMatters);
-+
-+ if (type >= 0 && type < 2) {
-+ if (type == 0) {
-+ dbusmenu_menuitem_property_set(GetNativeData(),
-+ DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE,
-+ DBUSMENU_MENUITEM_TOGGLE_CHECK);
-+ mType = eMenuItemType_CheckBox;
-+ } else if (type == 1) {
-+ dbusmenu_menuitem_property_set(GetNativeData(),
-+ DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE,
-+ DBUSMENU_MENUITEM_TOGGLE_RADIO);
-+ mType = eMenuItemType_Radio;
-+ }
-+
-+ UpdateState();
-+ } else {
-+ dbusmenu_menuitem_property_remove(GetNativeData(),
-+ DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE);
-+ dbusmenu_menuitem_property_remove(GetNativeData(),
-+ DBUSMENU_MENUITEM_PROP_TOGGLE_STATE);
-+ mType = eMenuItemType_Normal;
-+ }
-+}
-+
-+void
-+nsMenuItem::UpdateAccel()
-+{
-+ dom::Document *doc = ContentNode()->GetUncomposedDoc();
-+ if (doc) {
-+ nsCOMPtr<nsIContent> oldKeyContent;
-+ oldKeyContent.swap(mKeyContent);
-+
-+ nsAutoString key;
-+ ContentNode()->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::key,
-+ key);
-+ if (!key.IsEmpty()) {
-+ mKeyContent = doc->GetElementById(key);
-+ }
-+
-+ if (mKeyContent != oldKeyContent) {
-+ if (oldKeyContent) {
-+ DocListener()->UnregisterForContentChanges(oldKeyContent);
-+ }
-+ if (mKeyContent) {
-+ DocListener()->RegisterForContentChanges(mKeyContent, this);
-+ }
-+ }
-+ }
-+
-+ if (!mKeyContent) {
-+ dbusmenu_menuitem_property_remove(GetNativeData(),
-+ DBUSMENU_MENUITEM_PROP_SHORTCUT);
-+ return;
-+ }
-+
-+ nsAutoString modifiers;
-+ mKeyContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::modifiers,
-+ modifiers);
-+
-+ uint32_t modifier = 0;
-+
-+ if (!modifiers.IsEmpty()) {
-+ char* str = ToNewUTF8String(modifiers);
-+ char *token = strtok(str, ", \t");
-+ while(token) {
-+ if (nsCRT::strcmp(token, "shift") == 0) {
-+ modifier |= GDK_SHIFT_MASK;
-+ } else if (nsCRT::strcmp(token, "alt") == 0) {
-+ modifier |= GDK_MOD1_MASK;
-+ } else if (nsCRT::strcmp(token, "meta") == 0) {
-+ modifier |= GDK_META_MASK;
-+ } else if (nsCRT::strcmp(token, "control") == 0) {
-+ modifier |= GDK_CONTROL_MASK;
-+ } else if (nsCRT::strcmp(token, "accel") == 0) {
-+ int32_t accel = Preferences::GetInt("ui.key.accelKey");
-+ if (accel == dom::KeyboardEvent_Binding::DOM_VK_META) {
-+ modifier |= GDK_META_MASK;
-+ } else if (accel == dom::KeyboardEvent_Binding::DOM_VK_ALT) {
-+ modifier |= GDK_MOD1_MASK;
-+ } else {
-+ modifier |= GDK_CONTROL_MASK;
-+ }
-+ }
-+
-+ token = strtok(nullptr, ", \t");
-+ }
-+
-+ free(str);
-+ }
-+
-+ nsAutoString keyStr;
-+ mKeyContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::key,
-+ keyStr);
-+
-+ guint key = 0;
-+ if (!keyStr.IsEmpty()) {
-+ key = gdk_unicode_to_keyval(*keyStr.BeginReading());
-+ }
-+
-+ if (key == 0) {
-+ mKeyContent->AsElement()->GetAttr(kNameSpaceID_None,
-+ nsGkAtoms::keycode, keyStr);
-+ if (!keyStr.IsEmpty()) {
-+ key = ConvertGeckoKeyNameToGDKKeyval(keyStr);
-+ }
-+ }
-+
-+ if (key == 0) {
-+ key = GDK_VoidSymbol;
-+ }
-+
-+ if (key != GDK_VoidSymbol) {
-+ dbusmenu_menuitem_property_set_shortcut(GetNativeData(), key,
-+ static_cast<GdkModifierType>(modifier));
-+ } else {
-+ dbusmenu_menuitem_property_remove(GetNativeData(),
-+ DBUSMENU_MENUITEM_PROP_SHORTCUT);
-+ }
-+}
-+
-+nsMenuBar*
-+nsMenuItem::MenuBar()
-+{
-+ nsMenuObject *tmp = this;
-+ while (tmp->Parent()) {
-+ tmp = tmp->Parent();
-+ }
-+
-+ MOZ_ASSERT(tmp->Type() == eType_MenuBar, "The top-level should be a menubar");
-+
-+ return static_cast<nsMenuBar *>(tmp);
-+}
-+
-+void
-+nsMenuItem::UncheckSiblings()
-+{
-+ if (!ContentNode()->AsElement()->AttrValueIs(kNameSpaceID_None,
-+ nsGkAtoms::type,
-+ nsGkAtoms::radio,
-+ eCaseMatters)) {
-+ // If we're not a radio button, we don't care
-+ return;
-+ }
-+
-+ nsAutoString name;
-+ ContentNode()->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::name,
-+ name);
-+
-+ nsIContent *parent = ContentNode()->GetParent();
-+ if (!parent) {
-+ return;
-+ }
-+
-+ uint32_t count = parent->GetChildCount();
-+ for (uint32_t i = 0; i < count; ++i) {
-+ nsIContent *sibling = parent->GetChildAt_Deprecated(i);
-+
-+ if (sibling->IsComment()) {
-+ continue;
-+ }
-+
-+ nsAutoString otherName;
-+ sibling->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::name,
-+ otherName);
-+
-+ if (sibling != ContentNode() && otherName == name &&
-+ sibling->AsElement()->AttrValueIs(kNameSpaceID_None,
-+ nsGkAtoms::type,
-+ nsGkAtoms::radio,
-+ eCaseMatters)) {
-+ sibling->AsElement()->UnsetAttr(kNameSpaceID_None,
-+ nsGkAtoms::checked, true);
-+ }
-+ }
-+}
-+
-+void
-+nsMenuItem::InitializeNativeData()
-+{
-+ g_signal_connect(G_OBJECT(GetNativeData()),
-+ DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
-+ G_CALLBACK(item_activated_cb), this);
-+ mNeedsUpdate = true;
-+}
-+
-+void
-+nsMenuItem::UpdateContentAttributes()
-+{
-+ dom::Document *doc = ContentNode()->GetUncomposedDoc();
-+ if (!doc) {
-+ return;
-+ }
-+
-+ nsAutoString command;
-+ ContentNode()->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::command,
-+ command);
-+ if (command.IsEmpty()) {
-+ return;
-+ }
-+
-+ nsCOMPtr<nsIContent> commandContent = doc->GetElementById(command);
-+ if (!commandContent) {
-+ return;
-+ }
-+
-+ if (commandContent->AsElement()->AttrValueIs(kNameSpaceID_None,
-+ nsGkAtoms::disabled,
-+ nsGkAtoms::_true,
-+ eCaseMatters)) {
-+ ContentNode()->AsElement()->SetAttr(kNameSpaceID_None,
-+ nsGkAtoms::disabled,
-+ u"true"_ns, true);
-+ } else {
-+ ContentNode()->AsElement()->UnsetAttr(kNameSpaceID_None,
-+ nsGkAtoms::disabled, true);
-+ }
-+
-+ CopyAttrFromNodeIfExists(commandContent, nsGkAtoms::checked);
-+ CopyAttrFromNodeIfExists(commandContent, nsGkAtoms::accesskey);
-+ CopyAttrFromNodeIfExists(commandContent, nsGkAtoms::label);
-+ CopyAttrFromNodeIfExists(commandContent, nsGkAtoms::hidden);
-+}
-+
-+void
-+nsMenuItem::Update(const ComputedStyle *aComputedStyle)
-+{
-+ if (mNeedsUpdate) {
-+ mNeedsUpdate = false;
-+
-+ UpdateTypeAndState();
-+ UpdateAccel();
-+ UpdateLabel();
-+ UpdateSensitivity();
-+ }
-+
-+ UpdateVisibility(aComputedStyle);
-+ UpdateIcon(aComputedStyle);
-+}
-+
-+bool
-+nsMenuItem::IsCompatibleWithNativeData(DbusmenuMenuitem *aNativeData) const
-+{
-+ return nsCRT::strcmp(dbusmenu_menuitem_property_get(aNativeData,
-+ DBUSMENU_MENUITEM_PROP_TYPE),
-+ "separator") != 0;
-+}
-+
-+nsMenuObject::PropertyFlags
-+nsMenuItem::SupportedProperties() const
-+{
-+ return static_cast<nsMenuObject::PropertyFlags>(
-+ nsMenuObject::ePropLabel |
-+ nsMenuObject::ePropEnabled |
-+ nsMenuObject::ePropVisible |
-+ nsMenuObject::ePropIconData |
-+ nsMenuObject::ePropShortcut |
-+ nsMenuObject::ePropToggleType |
-+ nsMenuObject::ePropToggleState
-+ );
-+}
-+
-+void
-+nsMenuItem::OnAttributeChanged(nsIContent *aContent, nsAtom *aAttribute)
-+{
-+ MOZ_ASSERT(aContent == ContentNode() || aContent == mKeyContent,
-+ "Received an event that wasn't meant for us!");
-+
-+ if (aContent == ContentNode() && aAttribute == nsGkAtoms::checked &&
-+ aContent->AsElement()->AttrValueIs(kNameSpaceID_None,
-+ nsGkAtoms::checked,
-+ nsGkAtoms::_true, eCaseMatters)) {
-+ nsContentUtils::AddScriptRunner(
-+ new nsMenuItemUncheckSiblingsRunnable(this));
-+ }
-+
-+ if (mNeedsUpdate) {
-+ return;
-+ }
-+
-+ if (!Parent()->IsBeingDisplayed()) {
-+ mNeedsUpdate = true;
-+ return;
-+ }
-+
-+ if (aContent == ContentNode()) {
-+ if (aAttribute == nsGkAtoms::key) {
-+ UpdateAccel();
-+ } else if (aAttribute == nsGkAtoms::label ||
-+ aAttribute == nsGkAtoms::accesskey ||
-+ aAttribute == nsGkAtoms::crop) {
-+ UpdateLabel();
-+ } else if (aAttribute == nsGkAtoms::disabled) {
-+ UpdateSensitivity();
-+ } else if (aAttribute == nsGkAtoms::type) {
-+ UpdateTypeAndState();
-+ } else if (aAttribute == nsGkAtoms::checked) {
-+ UpdateState();
-+ } else if (aAttribute == nsGkAtoms::hidden ||
-+ aAttribute == nsGkAtoms::collapsed) {
-+ RefPtr<const ComputedStyle> style = GetComputedStyle();
-+ UpdateVisibility(style);
-+ } else if (aAttribute == nsGkAtoms::image) {
-+ RefPtr<const ComputedStyle> style = GetComputedStyle();
-+ UpdateIcon(style);
-+ }
-+ } else if (aContent == mKeyContent &&
-+ (aAttribute == nsGkAtoms::key ||
-+ aAttribute == nsGkAtoms::keycode ||
-+ aAttribute == nsGkAtoms::modifiers)) {
-+ UpdateAccel();
-+ }
-+}
-+
-+nsMenuItem::nsMenuItem(nsMenuContainer *aParent, nsIContent *aContent) :
-+ nsMenuObject(aParent, aContent),
-+ mType(eMenuItemType_Normal),
-+ mIsChecked(false),
-+ mNeedsUpdate(false)
-+{
-+ MOZ_COUNT_CTOR(nsMenuItem);
-+}
-+
-+nsMenuItem::~nsMenuItem()
-+{
-+ if (DocListener() && mKeyContent) {
-+ DocListener()->UnregisterForContentChanges(mKeyContent);
-+ }
-+
-+ if (GetNativeData()) {
-+ g_signal_handlers_disconnect_by_func(GetNativeData(),
-+ FuncToGpointer(item_activated_cb),
-+ this);
-+ }
-+
-+ MOZ_COUNT_DTOR(nsMenuItem);
-+}
-+
-+nsMenuObject::EType
-+nsMenuItem::Type() const
-+{
-+ return eType_MenuItem;
-+}
-diff --git a/widget/gtk/nsMenuItem.h b/widget/gtk/nsMenuItem.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..c621b4e223f1709b2b3e9c1c27affe2ce68ffbd5
---- /dev/null
-+++ b/widget/gtk/nsMenuItem.h
-@@ -0,0 +1,80 @@
-+/* -*- 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 __nsMenuItem_h__
-+#define __nsMenuItem_h__
-+
-+#include "mozilla/Attributes.h"
-+#include "nsCOMPtr.h"
-+
-+#include "nsDbusmenu.h"
-+#include "nsMenuObject.h"
-+
-+#include <glib.h>
-+
-+class nsAtom;
-+class nsIContent;
-+class nsMenuBar;
-+class nsMenuContainer;
-+
-+/*
-+ * This class represents 3 main classes of menuitems: labels, checkboxes and
-+ * radio buttons (with/without an icon)
-+ */
-+class nsMenuItem final : public nsMenuObject
-+{
-+public:
-+ nsMenuItem(nsMenuContainer *aParent, nsIContent *aContent);
-+ ~nsMenuItem() override;
-+
-+ nsMenuObject::EType Type() const override;
-+
-+private:
-+ friend class nsMenuItemUncheckSiblingsRunnable;
-+
-+ enum {
-+ eMenuItemFlag_ToggleState = (1 << 0)
-+ };
-+
-+ enum EMenuItemType {
-+ eMenuItemType_Normal,
-+ eMenuItemType_Radio,
-+ eMenuItemType_CheckBox
-+ };
-+
-+ bool IsCheckboxOrRadioItem() const;
-+
-+ static void item_activated_cb(DbusmenuMenuitem *menuitem,
-+ guint timestamp,
-+ gpointer user_data);
-+ void Activate(uint32_t aTimestamp);
-+
-+ void CopyAttrFromNodeIfExists(nsIContent *aContent, nsAtom *aAtom);
-+ void UpdateState();
-+ void UpdateTypeAndState();
-+ void UpdateAccel();
-+ nsMenuBar* MenuBar();
-+ void UncheckSiblings();
-+
-+ void InitializeNativeData() override;
-+ void UpdateContentAttributes() override;
-+ void Update(const mozilla::ComputedStyle *aComputedStyle) override;
-+ bool IsCompatibleWithNativeData(DbusmenuMenuitem *aNativeData) const override;
-+ nsMenuObject::PropertyFlags SupportedProperties() const override;
-+
-+ void OnAttributeChanged(nsIContent *aContent, nsAtom *aAttribute) override;
-+
-+ EMenuItemType mType;
-+
-+ bool mIsChecked;
-+
-+ bool mNeedsUpdate;
-+
-+ nsCOMPtr<nsIContent> mKeyContent;
-+};
-+
-+#endif /* __nsMenuItem_h__ */
-diff --git a/widget/gtk/nsMenuObject.cpp b/widget/gtk/nsMenuObject.cpp
-new file mode 100644
-index 0000000000000000000000000000000000000000..6e622a80fab852ca67fe9e77ffbc78d805844bc9
---- /dev/null
-+++ b/widget/gtk/nsMenuObject.cpp
-@@ -0,0 +1,653 @@
-+/* -*- 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 "ImageOps.h"
-+#include "imgIContainer.h"
-+#include "imgINotificationObserver.h"
-+#include "imgLoader.h"
-+#include "imgRequestProxy.h"
-+#include "mozilla/ArrayUtils.h"
-+#include "mozilla/Assertions.h"
-+#include "mozilla/dom/Document.h"
-+#include "mozilla/dom/Element.h"
-+#include "mozilla/Preferences.h"
-+#include "mozilla/PresShell.h"
-+#include "mozilla/PresShellInlines.h"
-+#include "mozilla/GRefPtr.h"
-+#include "nsAttrValue.h"
-+#include "nsComputedDOMStyle.h"
-+#include "nsContentUtils.h"
-+#include "nsGkAtoms.h"
-+#include "nsIContent.h"
-+#include "nsIContentPolicy.h"
-+#include "nsILoadGroup.h"
-+#include "nsImageToPixbuf.h"
-+#include "nsIURI.h"
-+#include "nsNetUtil.h"
-+#include "nsPresContext.h"
-+#include "nsRect.h"
-+#include "nsServiceManagerUtils.h"
-+#include "nsString.h"
-+#include "nsStyleConsts.h"
-+#include "nsStyleStruct.h"
-+#include "nsUnicharUtils.h"
-+
-+#include "nsMenuContainer.h"
-+#include "nsNativeMenuDocListener.h"
-+
-+#include <gdk/gdk.h>
-+#include <glib-object.h>
-+#include <pango/pango.h>
-+
-+#include "nsMenuObject.h"
-+
-+// X11's None clashes with StyleDisplay::None
-+#include "X11UndefineNone.h"
-+
-+#undef None
-+
-+using namespace mozilla;
-+using mozilla::image::ImageOps;
-+
-+#define MAX_WIDTH 350000
-+
-+const char *gPropertyStrings[] = {
-+#define DBUSMENU_PROPERTY(e, s, b) s,
-+ DBUSMENU_PROPERTIES
-+#undef DBUSMENU_PROPERTY
-+ nullptr
-+};
-+
-+nsWeakMenuObject* nsWeakMenuObject::sHead;
-+PangoLayout* gPangoLayout = nullptr;
-+
-+class nsMenuObjectIconLoader final : public imgINotificationObserver
-+{
-+public:
-+ NS_DECL_ISUPPORTS
-+ NS_DECL_IMGINOTIFICATIONOBSERVER
-+
-+ nsMenuObjectIconLoader(nsMenuObject *aOwner) : mOwner(aOwner) { };
-+
-+ void LoadIcon(const ComputedStyle *aComputedStyle);
-+ void Destroy();
-+
-+private:
-+ ~nsMenuObjectIconLoader() { };
-+
-+ nsMenuObject *mOwner;
-+ RefPtr<imgRequestProxy> mImageRequest;
-+ nsCOMPtr<nsIURI> mURI;
-+};
-+
-+NS_IMPL_ISUPPORTS(nsMenuObjectIconLoader, imgINotificationObserver)
-+
-+void
-+nsMenuObjectIconLoader::Notify(imgIRequest *aProxy,
-+ int32_t aType, const nsIntRect *aRect)
-+{
-+ if (!mOwner) {
-+ return;
-+ }
-+
-+ if (aProxy != mImageRequest) {
-+ return;
-+ }
-+
-+ if (aType == imgINotificationObserver::LOAD_COMPLETE) {
-+ uint32_t status = imgIRequest::STATUS_ERROR;
-+ if (NS_FAILED(mImageRequest->GetImageStatus(&status)) ||
-+ (status & imgIRequest::STATUS_ERROR)) {
-+ mImageRequest->Cancel(NS_BINDING_ABORTED);
-+ mImageRequest = nullptr;
-+ return;
-+ }
-+
-+ nsCOMPtr<imgIContainer> image;
-+ mImageRequest->GetImage(getter_AddRefs(image));
-+ MOZ_ASSERT(image);
-+
-+ // Ask the image to decode at its intrinsic size.
-+ int32_t width = 0, height = 0;
-+ image->GetWidth(&width);
-+ image->GetHeight(&height);
-+ image->RequestDecodeForSize(nsIntSize(width, height), imgIContainer::FLAG_NONE);
-+ return;
-+ }
-+
-+ if (aType == imgINotificationObserver::DECODE_COMPLETE) {
-+ mImageRequest->Cancel(NS_BINDING_ABORTED);
-+ mImageRequest = nullptr;
-+ return;
-+ }
-+
-+ if (aType != imgINotificationObserver::FRAME_COMPLETE) {
-+ return;
-+ }
-+
-+ nsCOMPtr<imgIContainer> img;
-+ mImageRequest->GetImage(getter_AddRefs(img));
-+ if (!img) {
-+ return;
-+ }
-+
-+ int32_t width, height;
-+ img->GetWidth(&width);
-+ img->GetHeight(&height);
-+
-+ if (width <= 0 || height <= 0) {
-+ mOwner->ClearIcon();
-+ return;
-+ }
-+
-+ if (width > 100 || height > 100) {
-+ // The icon data needs to go across DBus. Make sure the icon
-+ // data isn't too large, else our connection gets terminated and
-+ // GDbus helpfully aborts the application. Thank you :)
-+ NS_WARNING("Icon data too large");
-+ mOwner->ClearIcon();
-+ return;
-+ }
-+
-+ RefPtr<GdkPixbuf> pixbuf = nsImageToPixbuf::ImageToPixbuf(img);
-+ if (pixbuf) {
-+ dbusmenu_menuitem_property_set_image(mOwner->GetNativeData(),
-+ DBUSMENU_MENUITEM_PROP_ICON_DATA,
-+ pixbuf);
-+ }
-+
-+ return;
-+}
-+
-+void
-+nsMenuObjectIconLoader::LoadIcon(const ComputedStyle *aComputedStyle)
-+{
-+ dom::Document *doc = mOwner->ContentNode()->OwnerDoc();
-+
-+ nsCOMPtr<nsIURI> uri;
-+ imgRequestProxy *imageRequest = nullptr;
-+
-+ nsAutoString uriString;
-+ if (mOwner->ContentNode()->AsElement()->GetAttr(kNameSpaceID_None,
-+ nsGkAtoms::image,
-+ uriString)) {
-+ NS_NewURI(getter_AddRefs(uri), uriString);
-+ } else {
-+ PresShell *shell = doc->GetPresShell();
-+ if (!shell) {
-+ return;
-+ }
-+
-+ nsPresContext *pc = shell->GetPresContext();
-+ if (!pc || !aComputedStyle) {
-+ return;
-+ }
-+
-+ const nsStyleList *list = aComputedStyle->StyleList();
-+ imageRequest = list->mListStyleImage.GetImageRequest();
-+ if (imageRequest) {
-+ imageRequest->GetURI(getter_AddRefs(uri));
-+ }
-+ }
-+
-+ if (!uri) {
-+ mOwner->ClearIcon();
-+ mURI = nullptr;
-+
-+ if (mImageRequest) {
-+ mImageRequest->Cancel(NS_BINDING_ABORTED);
-+ mImageRequest = nullptr;
-+ }
-+
-+ return;
-+ }
-+
-+ bool same;
-+ if (mURI && NS_SUCCEEDED(mURI->Equals(uri, &same)) && same &&
-+ !imageRequest) {
-+ return;
-+ }
-+
-+ if (mImageRequest) {
-+ mImageRequest->Cancel(NS_BINDING_ABORTED);
-+ mImageRequest = nullptr;
-+ }
-+
-+ mURI = uri;
-+
-+ if (imageRequest) {
-+ imageRequest->Clone(this, nullptr, getter_AddRefs(mImageRequest));
-+ } else {
-+ nsCOMPtr<nsILoadGroup> loadGroup = doc->GetDocumentLoadGroup();
-+ RefPtr<imgLoader> loader =
-+ nsContentUtils::GetImgLoaderForDocument(doc);
-+ if (!loader || !loadGroup) {
-+ NS_WARNING("Failed to get loader or load group for image load");
-+ return;
-+ }
-+
-+ loader->LoadImage(uri, nullptr, nullptr,
-+ nullptr, 0, loadGroup, this, nullptr, nullptr,
-+ nsIRequest::LOAD_NORMAL, nullptr,
-+ nsIContentPolicy::TYPE_IMAGE, EmptyString(),
-+ false, false, 0, getter_AddRefs(mImageRequest));
-+ }
-+}
-+
-+void
-+nsMenuObjectIconLoader::Destroy()
-+{
-+ if (mImageRequest) {
-+ mImageRequest->CancelAndForgetObserver(NS_BINDING_ABORTED);
-+ mImageRequest = nullptr;
-+ }
-+
-+ mOwner = nullptr;
-+}
-+
-+static int
-+CalculateTextWidth(const nsAString& aText)
-+{
-+ if (!gPangoLayout) {
-+ PangoFontMap *fontmap = pango_cairo_font_map_get_default();
-+ PangoContext *ctx = pango_font_map_create_context(fontmap);
-+ gPangoLayout = pango_layout_new(ctx);
-+ g_object_unref(ctx);
-+ }
-+
-+ pango_layout_set_text(gPangoLayout, NS_ConvertUTF16toUTF8(aText).get(), -1);
-+
-+ int width, dummy;
-+ pango_layout_get_size(gPangoLayout, &width, &dummy);
-+
-+ return width;
-+}
-+
-+static const nsDependentString
-+GetEllipsis()
-+{
-+ static char16_t sBuf[4] = { 0, 0, 0, 0 };
-+ if (!sBuf[0]) {
-+ nsString ellipsis;
-+ Preferences::GetLocalizedString("intl.ellipsis", ellipsis);
-+ if (!ellipsis.IsEmpty()) {
-+ uint32_t l = ellipsis.Length();
-+ const nsString::char_type *c = ellipsis.BeginReading();
-+ uint32_t i = 0;
-+ while (i < 3 && i < l) {
-+ sBuf[i++] = *(c++);
-+ }
-+ } else {
-+ sBuf[0] = '.';
-+ sBuf[1] = '.';
-+ sBuf[2] = '.';
-+ }
-+ }
-+
-+ return nsDependentString(sBuf);
-+}
-+
-+static int
-+GetEllipsisWidth()
-+{
-+ static int sEllipsisWidth = -1;
-+
-+ if (sEllipsisWidth == -1) {
-+ sEllipsisWidth = CalculateTextWidth(GetEllipsis());
-+ }
-+
-+ return sEllipsisWidth;
-+}
-+
-+nsMenuObject::nsMenuObject(nsMenuContainer *aParent, nsIContent *aContent) :
-+ mContent(aContent),
-+ mListener(aParent->DocListener()),
-+ mParent(aParent),
-+ mNativeData(nullptr)
-+{
-+ MOZ_ASSERT(mContent);
-+ MOZ_ASSERT(mListener);
-+ MOZ_ASSERT(mParent);
-+}
-+
-+nsMenuObject::nsMenuObject(nsNativeMenuDocListener *aListener,
-+ nsIContent *aContent) :
-+ mContent(aContent),
-+ mListener(aListener),
-+ mParent(nullptr),
-+ mNativeData(nullptr)
-+{
-+ MOZ_ASSERT(mContent);
-+ MOZ_ASSERT(mListener);
-+}
-+
-+void
-+nsMenuObject::UpdateLabel()
-+{
-+ // Gecko stores the label and access key in separate attributes
-+ // so we need to convert label="Foo_Bar"/accesskey="F" in to
-+ // label="_Foo__Bar" for dbusmenu
-+
-+ nsAutoString label;
-+ mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::label, label);
-+
-+ nsAutoString accesskey;
-+ mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey,
-+ accesskey);
-+
-+ const nsAutoString::char_type *akey = accesskey.BeginReading();
-+ char16_t keyLower = ToLowerCase(*akey);
-+ char16_t keyUpper = ToUpperCase(*akey);
-+
-+ const nsAutoString::char_type *iter = label.BeginReading();
-+ const nsAutoString::char_type *end = label.EndReading();
-+ uint32_t length = label.Length();
-+ uint32_t pos = 0;
-+ bool foundAccessKey = false;
-+
-+ while (iter != end) {
-+ if (*iter != char16_t('_')) {
-+ if ((*iter != keyLower && *iter != keyUpper) || foundAccessKey) {
-+ ++iter;
-+ ++pos;
-+ continue;
-+ }
-+ foundAccessKey = true;
-+ }
-+
-+ label.SetLength(++length);
-+
-+ iter = label.BeginReading() + pos;
-+ end = label.EndReading();
-+ nsAutoString::char_type *cur = label.BeginWriting() + pos;
-+
-+ memmove(cur + 1, cur, (length - 1 - pos) * sizeof(nsAutoString::char_type));
-+ *cur = nsAutoString::char_type('_');
-+
-+ iter += 2;
-+ pos += 2;
-+ }
-+
-+ if (CalculateTextWidth(label) <= MAX_WIDTH) {
-+ dbusmenu_menuitem_property_set(mNativeData,
-+ DBUSMENU_MENUITEM_PROP_LABEL,
-+ NS_ConvertUTF16toUTF8(label).get());
-+ return;
-+ }
-+
-+ // This sucks.
-+ // This should be done at the point where the menu is drawn (hello Unity),
-+ // but unfortunately it doesn't do that and will happily fill your entire
-+ // screen width with a menu if you have a bookmark with a really long title.
-+ // This leaves us with no other option but to ellipsize here, with no proper
-+ // knowledge of Unity's render path, font size etc. This is better than nothing
-+ nsAutoString truncated;
-+ int target = MAX_WIDTH - GetEllipsisWidth();
-+ length = label.Length();
-+
-+ static mozilla::dom::Element::AttrValuesArray strings[] = {
-+ nsGkAtoms::left, nsGkAtoms::start,
-+ nsGkAtoms::center, nsGkAtoms::right,
-+ nsGkAtoms::end, nullptr
-+ };
-+
-+ int32_t type = mContent->AsElement()->FindAttrValueIn(kNameSpaceID_None,
-+ nsGkAtoms::crop,
-+ strings, eCaseMatters);
-+
-+ switch (type) {
-+ case 0:
-+ case 1:
-+ // FIXME: Implement left cropping
-+ case 2:
-+ // FIXME: Implement center cropping
-+ case 3:
-+ case 4:
-+ default:
-+ for (uint32_t i = 0; i < length; i++) {
-+ truncated.Append(label.CharAt(i));
-+ if (CalculateTextWidth(truncated) > target) {
-+ break;
-+ }
-+ }
-+
-+ truncated.Append(GetEllipsis());
-+ }
-+
-+ dbusmenu_menuitem_property_set(mNativeData,
-+ DBUSMENU_MENUITEM_PROP_LABEL,
-+ NS_ConvertUTF16toUTF8(truncated).get());
-+}
-+
-+void
-+nsMenuObject::UpdateVisibility(const ComputedStyle *aComputedStyle)
-+{
-+ bool vis = true;
-+
-+ if (aComputedStyle &&
-+ (aComputedStyle->StyleDisplay()->mDisplay == StyleDisplay::None ||
-+ aComputedStyle->StyleVisibility()->mVisible ==
-+ StyleVisibility::Collapse)) {
-+ vis = false;
-+ }
-+
-+ dbusmenu_menuitem_property_set_bool(mNativeData,
-+ DBUSMENU_MENUITEM_PROP_VISIBLE,
-+ vis);
-+}
-+
-+void
-+nsMenuObject::UpdateSensitivity()
-+{
-+ bool disabled = mContent->AsElement()->AttrValueIs(kNameSpaceID_None,
-+ nsGkAtoms::disabled,
-+ nsGkAtoms::_true,
-+ eCaseMatters);
-+
-+ dbusmenu_menuitem_property_set_bool(mNativeData,
-+ DBUSMENU_MENUITEM_PROP_ENABLED,
-+ !disabled);
-+
-+}
-+
-+void
-+nsMenuObject::UpdateIcon(const ComputedStyle *aComputedStyle)
-+{
-+ if (ShouldShowIcon()) {
-+ if (!mIconLoader) {
-+ mIconLoader = new nsMenuObjectIconLoader(this);
-+ }
-+
-+ mIconLoader->LoadIcon(aComputedStyle);
-+ } else {
-+ if (mIconLoader) {
-+ mIconLoader->Destroy();
-+ mIconLoader = nullptr;
-+ }
-+
-+ ClearIcon();
-+ }
-+}
-+
-+already_AddRefed<const ComputedStyle>
-+nsMenuObject::GetComputedStyle()
-+{
-+ RefPtr<const ComputedStyle> style =
-+ nsComputedDOMStyle::GetComputedStyleNoFlush(
-+ mContent->AsElement());
-+
-+ return style.forget();
-+}
-+
-+void
-+nsMenuObject::InitializeNativeData()
-+{
-+}
-+
-+nsMenuObject::PropertyFlags
-+nsMenuObject::SupportedProperties() const
-+{
-+ return static_cast<nsMenuObject::PropertyFlags>(0);
-+}
-+
-+bool
-+nsMenuObject::IsCompatibleWithNativeData(DbusmenuMenuitem *aNativeData) const
-+{
-+ return true;
-+}
-+
-+void
-+nsMenuObject::UpdateContentAttributes()
-+{
-+}
-+
-+void
-+nsMenuObject::Update(const ComputedStyle *aComputedStyle)
-+{
-+}
-+
-+bool
-+nsMenuObject::ShouldShowIcon() const
-+{
-+ // Ideally we want to know the visibility of the anonymous XUL image in
-+ // our menuitem, but this isn't created because we don't have a frame.
-+ // The following works by default (because xul.css hides images in menuitems
-+ // that don't have the "menuitem-with-favicon" class). It's possible a third
-+ // party theme could override this, but, oh well...
-+ const nsAttrValue *classes = mContent->AsElement()->GetClasses();
-+ if (!classes) {
-+ return false;
-+ }
-+
-+ for (uint32_t i = 0; i < classes->GetAtomCount(); ++i) {
-+ if (classes->AtomAt(i) == nsGkAtoms::menuitem_with_favicon) {
-+ return true;
-+ }
-+ }
-+
-+ return false;
-+}
-+
-+void
-+nsMenuObject::ClearIcon()
-+{
-+ dbusmenu_menuitem_property_remove(mNativeData,
-+ DBUSMENU_MENUITEM_PROP_ICON_DATA);
-+}
-+
-+nsMenuObject::~nsMenuObject()
-+{
-+ nsWeakMenuObject::NotifyDestroyed(this);
-+
-+ if (mIconLoader) {
-+ mIconLoader->Destroy();
-+ }
-+
-+ if (mListener) {
-+ mListener->UnregisterForContentChanges(mContent);
-+ }
-+
-+ if (mNativeData) {
-+ g_object_unref(mNativeData);
-+ mNativeData = nullptr;
-+ }
-+}
-+
-+void
-+nsMenuObject::CreateNativeData()
-+{
-+ MOZ_ASSERT(mNativeData == nullptr, "This node already has a DbusmenuMenuitem. The old one will be leaked");
-+
-+ mNativeData = dbusmenu_menuitem_new();
-+ InitializeNativeData();
-+ if (mParent && mParent->IsBeingDisplayed()) {
-+ ContainerIsOpening();
-+ }
-+
-+ mListener->RegisterForContentChanges(mContent, this);
-+}
-+
-+nsresult
-+nsMenuObject::AdoptNativeData(DbusmenuMenuitem *aNativeData)
-+{
-+ MOZ_ASSERT(mNativeData == nullptr, "This node already has a DbusmenuMenuitem. The old one will be leaked");
-+
-+ if (!IsCompatibleWithNativeData(aNativeData)) {
-+ return NS_ERROR_FAILURE;
-+ }
-+
-+ mNativeData = aNativeData;
-+ g_object_ref(mNativeData);
-+
-+ PropertyFlags supported = SupportedProperties();
-+ PropertyFlags mask = static_cast<PropertyFlags>(1);
-+
-+ for (uint32_t i = 0; gPropertyStrings[i]; ++i) {
-+ if (!(mask & supported)) {
-+ dbusmenu_menuitem_property_remove(mNativeData, gPropertyStrings[i]);
-+ }
-+ mask = static_cast<PropertyFlags>(mask << 1);
-+ }
-+
-+ InitializeNativeData();
-+ if (mParent && mParent->IsBeingDisplayed()) {
-+ ContainerIsOpening();
-+ }
-+
-+ mListener->RegisterForContentChanges(mContent, this);
-+
-+ return NS_OK;
-+}
-+
-+void
-+nsMenuObject::ContainerIsOpening()
-+{
-+ MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
-+
-+ UpdateContentAttributes();
-+
-+ RefPtr<const ComputedStyle> style = GetComputedStyle();
-+ Update(style);
-+}
-+
-+/* static */ void
-+nsWeakMenuObject::AddWeakReference(nsWeakMenuObject *aWeak)
-+{
-+ aWeak->mPrev = sHead;
-+ sHead = aWeak;
-+}
-+
-+/* static */ void
-+nsWeakMenuObject::RemoveWeakReference(nsWeakMenuObject *aWeak)
-+{
-+ if (aWeak == sHead) {
-+ sHead = aWeak->mPrev;
-+ return;
-+ }
-+
-+ nsWeakMenuObject *weak = sHead;
-+ while (weak && weak->mPrev != aWeak) {
-+ weak = weak->mPrev;
-+ }
-+
-+ if (weak) {
-+ weak->mPrev = aWeak->mPrev;
-+ }
-+}
-+
-+/* static */ void
-+nsWeakMenuObject::NotifyDestroyed(nsMenuObject *aMenuObject)
-+{
-+ nsWeakMenuObject *weak = sHead;
-+ while (weak) {
-+ if (weak->mMenuObject == aMenuObject) {
-+ weak->mMenuObject = nullptr;
-+ }
-+
-+ weak = weak->mPrev;
-+ }
-+}
-diff --git a/widget/gtk/nsMenuObject.h b/widget/gtk/nsMenuObject.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..92b1ffd8f2fae9ff368ce70b6069ad8bc918c2c6
---- /dev/null
-+++ b/widget/gtk/nsMenuObject.h
-@@ -0,0 +1,169 @@
-+/* -*- 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 __nsMenuObject_h__
-+#define __nsMenuObject_h__
-+
-+#include "mozilla/Attributes.h"
-+#include "mozilla/ComputedStyleInlines.h"
-+#include "nsCOMPtr.h"
-+
-+#include "nsDbusmenu.h"
-+#include "nsNativeMenuDocListener.h"
-+
-+class nsIContent;
-+class nsMenuContainer;
-+class nsMenuObjectIconLoader;
-+
-+#define DBUSMENU_PROPERTIES \
-+ DBUSMENU_PROPERTY(Label, DBUSMENU_MENUITEM_PROP_LABEL, 0) \
-+ DBUSMENU_PROPERTY(Enabled, DBUSMENU_MENUITEM_PROP_ENABLED, 1) \
-+ DBUSMENU_PROPERTY(Visible, DBUSMENU_MENUITEM_PROP_VISIBLE, 2) \
-+ DBUSMENU_PROPERTY(IconData, DBUSMENU_MENUITEM_PROP_ICON_DATA, 3) \
-+ DBUSMENU_PROPERTY(Type, DBUSMENU_MENUITEM_PROP_TYPE, 4) \
-+ DBUSMENU_PROPERTY(Shortcut, DBUSMENU_MENUITEM_PROP_SHORTCUT, 5) \
-+ DBUSMENU_PROPERTY(ToggleType, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, 6) \
-+ DBUSMENU_PROPERTY(ToggleState, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, 7) \
-+ DBUSMENU_PROPERTY(ChildDisplay, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, 8)
-+
-+/*
-+ * This is the base class for all menu nodes. Each instance represents
-+ * a single node in the menu hierarchy. It wraps the corresponding DOM node and
-+ * native menu node, keeps them in sync and transfers events between the two.
-+ * It is not reference counted - each node is owned by its parent (the top
-+ * level menubar is owned by the window) and keeps a weak pointer to its
-+ * parent (which is guaranteed to always be valid because a node will never
-+ * outlive its parent). It is not safe to keep a reference to nsMenuObject
-+ * externally.
-+ */
-+class nsMenuObject : public nsNativeMenuChangeObserver
-+{
-+public:
-+ enum EType {
-+ eType_MenuBar,
-+ eType_Menu,
-+ eType_MenuItem
-+ };
-+
-+ virtual ~nsMenuObject();
-+
-+ // Get the native menu item node
-+ DbusmenuMenuitem* GetNativeData() const { return mNativeData; }
-+
-+ // Get the parent menu object
-+ nsMenuContainer* Parent() const { return mParent; }
-+
-+ // Get the content node
-+ nsIContent* ContentNode() const { return mContent; }
-+
-+ // Get the type of this node. Must be provided by subclasses
-+ virtual EType Type() const = 0;
-+
-+ // Get the document listener
-+ nsNativeMenuDocListener* DocListener() const { return mListener; }
-+
-+ // Create the native menu item node (called by containers)
-+ void CreateNativeData();
-+
-+ // Adopt the specified native menu item node (called by containers)
-+ nsresult AdoptNativeData(DbusmenuMenuitem *aNativeData);
-+
-+ // Called by the container to tell us that it's opening
-+ void ContainerIsOpening();
-+
-+protected:
-+ nsMenuObject(nsMenuContainer *aParent, nsIContent *aContent);
-+ nsMenuObject(nsNativeMenuDocListener *aListener, nsIContent *aContent);
-+
-+ enum PropertyFlags {
-+#define DBUSMENU_PROPERTY(e, s, b) eProp##e = (1 << b),
-+ DBUSMENU_PROPERTIES
-+#undef DBUSMENU_PROPERTY
-+ };
-+
-+ void UpdateLabel();
-+ void UpdateVisibility(const mozilla::ComputedStyle *aComputedStyle);
-+ void UpdateSensitivity();
-+ void UpdateIcon(const mozilla::ComputedStyle *aComputedStyle);
-+
-+ already_AddRefed<const mozilla::ComputedStyle> GetComputedStyle();
-+
-+private:
-+ friend class nsMenuObjectIconLoader;
-+
-+ // Set up initial properties on the native data, connect to signals etc.
-+ // This should be implemented by subclasses
-+ virtual void InitializeNativeData();
-+
-+ // Return the properties that this menu object type supports
-+ // This should be implemented by subclasses
-+ virtual PropertyFlags SupportedProperties() const;
-+
-+ // Determine whether this menu object could use the specified
-+ // native item. Returns true by default but can be overridden by subclasses
-+ virtual bool
-+ IsCompatibleWithNativeData(DbusmenuMenuitem *aNativeData) const;
-+
-+ // Update attributes on this objects content node when the container opens.
-+ // This is called before style resolution, and should be implemented by
-+ // subclasses who want to modify attributes that might affect style.
-+ // This will not be called when there are script blockers
-+ virtual void UpdateContentAttributes();
-+
-+ // Update properties that should be refreshed when the container opens.
-+ // This should be implemented by subclasses that have properties which
-+ // need refreshing
-+ virtual void Update(const mozilla::ComputedStyle *aComputedStyle);
-+
-+ bool ShouldShowIcon() const;
-+ void ClearIcon();
-+
-+ nsCOMPtr<nsIContent> mContent;
-+ // mListener is a strong ref for simplicity - someone in the tree needs to
-+ // own it, and this only really needs to be the top-level object (as no
-+ // children outlives their parent). However, we need to keep it alive until
-+ // after running the nsMenuObject destructor for the top-level menu object,
-+ // hence the strong ref
-+ RefPtr<nsNativeMenuDocListener> mListener;
-+ nsMenuContainer *mParent; // [weak]
-+ DbusmenuMenuitem *mNativeData; // [strong]
-+ RefPtr<nsMenuObjectIconLoader> mIconLoader;
-+};
-+
-+// Keep a weak pointer to a menu object
-+class nsWeakMenuObject
-+{
-+public:
-+ nsWeakMenuObject() : mPrev(nullptr), mMenuObject(nullptr) {}
-+
-+ nsWeakMenuObject(nsMenuObject *aMenuObject) :
-+ mPrev(nullptr), mMenuObject(aMenuObject)
-+ {
-+ AddWeakReference(this);
-+ }
-+
-+ ~nsWeakMenuObject() { RemoveWeakReference(this); }
-+
-+ nsMenuObject* get() const { return mMenuObject; }
-+
-+ nsMenuObject* operator->() const { return mMenuObject; }
-+
-+ explicit operator bool() const { return !!mMenuObject; }
-+
-+ static void NotifyDestroyed(nsMenuObject *aMenuObject);
-+
-+private:
-+ static void AddWeakReference(nsWeakMenuObject *aWeak);
-+ static void RemoveWeakReference(nsWeakMenuObject *aWeak);
-+
-+ nsWeakMenuObject *mPrev;
-+ static nsWeakMenuObject *sHead;
-+
-+ nsMenuObject *mMenuObject;
-+};
-+
-+#endif /* __nsMenuObject_h__ */
-diff --git a/widget/gtk/nsMenuSeparator.cpp b/widget/gtk/nsMenuSeparator.cpp
-new file mode 100644
-index 0000000000000000000000000000000000000000..3ab135bd8a2009d9d8b943df1d1bec8e2ff47776
---- /dev/null
-+++ b/widget/gtk/nsMenuSeparator.cpp
-@@ -0,0 +1,82 @@
-+/* -*- 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 "mozilla/Assertions.h"
-+#include "nsCRT.h"
-+#include "nsGkAtoms.h"
-+
-+#include "nsDbusmenu.h"
-+
-+#include "nsMenuContainer.h"
-+#include "nsMenuSeparator.h"
-+
-+using namespace mozilla;
-+
-+void
-+nsMenuSeparator::InitializeNativeData()
-+{
-+ dbusmenu_menuitem_property_set(GetNativeData(),
-+ DBUSMENU_MENUITEM_PROP_TYPE,
-+ "separator");
-+}
-+
-+void
-+nsMenuSeparator::Update(const ComputedStyle *aComputedStyle)
-+{
-+ UpdateVisibility(aComputedStyle);
-+}
-+
-+bool
-+nsMenuSeparator::IsCompatibleWithNativeData(DbusmenuMenuitem *aNativeData) const
-+{
-+ return nsCRT::strcmp(dbusmenu_menuitem_property_get(aNativeData,
-+ DBUSMENU_MENUITEM_PROP_TYPE),
-+ "separator") == 0;
-+}
-+
-+nsMenuObject::PropertyFlags
-+nsMenuSeparator::SupportedProperties() const
-+{
-+ return static_cast<nsMenuObject::PropertyFlags>(
-+ nsMenuObject::ePropVisible |
-+ nsMenuObject::ePropType
-+ );
-+}
-+
-+void
-+nsMenuSeparator::OnAttributeChanged(nsIContent *aContent, nsAtom *aAttribute)
-+{
-+ MOZ_ASSERT(aContent == ContentNode(), "Received an event that wasn't meant for us!");
-+
-+ if (!Parent()->IsBeingDisplayed()) {
-+ return;
-+ }
-+
-+ if (aAttribute == nsGkAtoms::hidden ||
-+ aAttribute == nsGkAtoms::collapsed) {
-+ RefPtr<const ComputedStyle> style = GetComputedStyle();
-+ UpdateVisibility(style);
-+ }
-+}
-+
-+nsMenuSeparator::nsMenuSeparator(nsMenuContainer *aParent,
-+ nsIContent *aContent) :
-+ nsMenuObject(aParent, aContent)
-+{
-+ MOZ_COUNT_CTOR(nsMenuSeparator);
-+}
-+
-+nsMenuSeparator::~nsMenuSeparator()
-+{
-+ MOZ_COUNT_DTOR(nsMenuSeparator);
-+}
-+
-+nsMenuObject::EType
-+nsMenuSeparator::Type() const
-+{
-+ return eType_MenuItem;
-+}
-diff --git a/widget/gtk/nsMenuSeparator.h b/widget/gtk/nsMenuSeparator.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..dd3f5b974dd3f0955010c2edd3cafe05d24f837a
---- /dev/null
-+++ b/widget/gtk/nsMenuSeparator.h
-@@ -0,0 +1,37 @@
-+/* -*- 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 __nsMenuSeparator_h__
-+#define __nsMenuSeparator_h__
-+
-+#include "mozilla/Attributes.h"
-+
-+#include "nsMenuObject.h"
-+
-+class nsIContent;
-+class nsAtom;
-+class nsMenuContainer;
-+
-+// Menu separator class
-+class nsMenuSeparator final : public nsMenuObject
-+{
-+public:
-+ nsMenuSeparator(nsMenuContainer *aParent, nsIContent *aContent);
-+ ~nsMenuSeparator();
-+
-+ nsMenuObject::EType Type() const override;
-+
-+private:
-+ void InitializeNativeData() override;
-+ void Update(const mozilla::ComputedStyle *aComputedStyle) override;
-+ bool IsCompatibleWithNativeData(DbusmenuMenuitem *aNativeData) const override;
-+ nsMenuObject::PropertyFlags SupportedProperties() const override;
-+
-+ void OnAttributeChanged(nsIContent *aContent, nsAtom *aAttribute) override;
-+};
-+
-+#endif /* __nsMenuSeparator_h__ */
-diff --git a/widget/gtk/nsNativeMenuDocListener.cpp b/widget/gtk/nsNativeMenuDocListener.cpp
-new file mode 100644
-index 0000000000000000000000000000000000000000..05d7e09ccc3c80676d92b6104c064b8a0cabb008
---- /dev/null
-+++ b/widget/gtk/nsNativeMenuDocListener.cpp
-@@ -0,0 +1,347 @@
-+/* -*- 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 "mozilla/Assertions.h"
-+#include "mozilla/DebugOnly.h"
-+#include "mozilla/dom/Document.h"
-+#include "mozilla/dom/Element.h"
-+#include "nsContentUtils.h"
-+#include "nsAtom.h"
-+#include "nsIContent.h"
-+
-+#include "nsMenuContainer.h"
-+
-+#include "nsNativeMenuDocListener.h"
-+
-+using namespace mozilla;
-+
-+uint32_t nsNativeMenuDocListener::sUpdateBlockersCount = 0;
-+
-+nsNativeMenuDocListenerTArray *gPendingListeners;
-+
-+/*
-+ * Small helper which caches a single listener, so that consecutive
-+ * events which go to the same node avoid multiple hash table lookups
-+ */
-+class MOZ_STACK_CLASS DispatchHelper
-+{
-+public:
-+ DispatchHelper(nsNativeMenuDocListener *aListener,
-+ nsIContent *aContent) :
-+ mObserver(nullptr)
-+ {
-+ if (aContent == aListener->mLastSource) {
-+ mObserver = aListener->mLastTarget;
-+ } else {
-+ mObserver = aListener->mContentToObserverTable.Get(aContent);
-+ if (mObserver) {
-+ aListener->mLastSource = aContent;
-+ aListener->mLastTarget = mObserver;
-+ }
-+ }
-+ }
-+
-+ ~DispatchHelper() { };
-+
-+ nsNativeMenuChangeObserver* Observer() const { return mObserver; }
-+
-+ bool HasObserver() const { return !!mObserver; }
-+
-+private:
-+ nsNativeMenuChangeObserver *mObserver;
-+};
-+
-+NS_IMPL_ISUPPORTS(nsNativeMenuDocListener, nsIMutationObserver)
-+
-+nsNativeMenuDocListener::~nsNativeMenuDocListener()
-+{
-+ MOZ_ASSERT(mContentToObserverTable.Count() == 0,
-+ "Some nodes forgot to unregister listeners. This is bad! (and we're lucky we made it this far)");
-+ MOZ_COUNT_DTOR(nsNativeMenuDocListener);
-+}
-+
-+void
-+nsNativeMenuDocListener::AttributeChanged(mozilla::dom::Element *aElement,
-+ int32_t aNameSpaceID,
-+ nsAtom *aAttribute,
-+ int32_t aModType,
-+ const nsAttrValue* aOldValue)
-+{
-+ if (sUpdateBlockersCount == 0) {
-+ DoAttributeChanged(aElement, aAttribute);
-+ return;
-+ }
-+
-+ MutationRecord *m = mPendingMutations.AppendElement(MakeUnique<MutationRecord>())->get();
-+ m->mType = MutationRecord::eAttributeChanged;
-+ m->mTarget = aElement;
-+ m->mAttribute = aAttribute;
-+
-+ ScheduleFlush(this);
-+}
-+
-+void
-+nsNativeMenuDocListener::ContentAppended(nsIContent *aFirstNewContent)
-+{
-+ for (nsIContent *c = aFirstNewContent; c; c = c->GetNextSibling()) {
-+ ContentInserted(c);
-+ }
-+}
-+
-+void
-+nsNativeMenuDocListener::ContentInserted(nsIContent *aChild)
-+{
-+ nsIContent* container = aChild->GetParent();
-+ if (!container) {
-+ return;
-+ }
-+
-+ nsIContent *prevSibling = nsMenuContainer::GetPreviousSupportedSibling(aChild);
-+
-+ if (sUpdateBlockersCount == 0) {
-+ DoContentInserted(container, aChild, prevSibling);
-+ return;
-+ }
-+
-+ MutationRecord *m = mPendingMutations.AppendElement(MakeUnique<MutationRecord>())->get();
-+ m->mType = MutationRecord::eContentInserted;
-+ m->mTarget = container;
-+ m->mChild = aChild;
-+ m->mPrevSibling = prevSibling;
-+
-+ ScheduleFlush(this);
-+}
-+
-+void
-+nsNativeMenuDocListener::ContentRemoved(nsIContent *aChild,
-+ nsIContent *aPreviousSibling)
-+{
-+ nsIContent* container = aChild->GetParent();
-+ if (!container) {
-+ return;
-+ }
-+
-+ if (sUpdateBlockersCount == 0) {
-+ DoContentRemoved(container, aChild);
-+ return;
-+ }
-+
-+ MutationRecord *m = mPendingMutations.AppendElement(MakeUnique<MutationRecord>())->get();
-+ m->mType = MutationRecord::eContentRemoved;
-+ m->mTarget = container;
-+ m->mChild = aChild;
-+
-+ ScheduleFlush(this);
-+}
-+
-+void
-+nsNativeMenuDocListener::NodeWillBeDestroyed(nsINode *aNode)
-+{
-+ mDocument = nullptr;
-+}
-+
-+void
-+nsNativeMenuDocListener::DoAttributeChanged(nsIContent *aContent,
-+ nsAtom *aAttribute)
-+{
-+ DispatchHelper h(this, aContent);
-+ if (h.HasObserver()) {
-+ h.Observer()->OnAttributeChanged(aContent, aAttribute);
-+ }
-+}
-+
-+void
-+nsNativeMenuDocListener::DoContentInserted(nsIContent *aContainer,
-+ nsIContent *aChild,
-+ nsIContent *aPrevSibling)
-+{
-+ DispatchHelper h(this, aContainer);
-+ if (h.HasObserver()) {
-+ h.Observer()->OnContentInserted(aContainer, aChild, aPrevSibling);
-+ }
-+}
-+
-+void
-+nsNativeMenuDocListener::DoContentRemoved(nsIContent *aContainer,
-+ nsIContent *aChild)
-+{
-+ DispatchHelper h(this, aContainer);
-+ if (h.HasObserver()) {
-+ h.Observer()->OnContentRemoved(aContainer, aChild);
-+ }
-+}
-+
-+void
-+nsNativeMenuDocListener::DoBeginUpdates(nsIContent *aTarget)
-+{
-+ DispatchHelper h(this, aTarget);
-+ if (h.HasObserver()) {
-+ h.Observer()->OnBeginUpdates(aTarget);
-+ }
-+}
-+
-+void
-+nsNativeMenuDocListener::DoEndUpdates(nsIContent *aTarget)
-+{
-+ DispatchHelper h(this, aTarget);
-+ if (h.HasObserver()) {
-+ h.Observer()->OnEndUpdates();
-+ }
-+}
-+
-+void
-+nsNativeMenuDocListener::FlushPendingMutations()
-+{
-+ nsIContent *currentTarget = nullptr;
-+ bool inUpdateSequence = false;
-+
-+ while (mPendingMutations.Length() > 0) {
-+ MutationRecord *m = mPendingMutations[0].get();
-+
-+ if (m->mTarget != currentTarget) {
-+ if (inUpdateSequence) {
-+ DoEndUpdates(currentTarget);
-+ inUpdateSequence = false;
-+ }
-+
-+ currentTarget = m->mTarget;
-+
-+ if (mPendingMutations.Length() > 1 &&
-+ mPendingMutations[1]->mTarget == currentTarget) {
-+ DoBeginUpdates(currentTarget);
-+ inUpdateSequence = true;
-+ }
-+ }
-+
-+ switch (m->mType) {
-+ case MutationRecord::eAttributeChanged:
-+ DoAttributeChanged(m->mTarget, m->mAttribute);
-+ break;
-+ case MutationRecord::eContentInserted:
-+ DoContentInserted(m->mTarget, m->mChild, m->mPrevSibling);
-+ break;
-+ case MutationRecord::eContentRemoved:
-+ DoContentRemoved(m->mTarget, m->mChild);
-+ break;
-+ default:
-+ MOZ_ASSERT_UNREACHABLE("Invalid type");
-+ }
-+
-+ mPendingMutations.RemoveElementAt(0);
-+ }
-+
-+ if (inUpdateSequence) {
-+ DoEndUpdates(currentTarget);
-+ }
-+}
-+
-+/* static */ void
-+nsNativeMenuDocListener::ScheduleFlush(nsNativeMenuDocListener *aListener)
-+{
-+ MOZ_ASSERT(sUpdateBlockersCount > 0, "Shouldn't be doing this now");
-+
-+ if (!gPendingListeners) {
-+ gPendingListeners = new nsNativeMenuDocListenerTArray;
-+ }
-+
-+ if (gPendingListeners->IndexOf(aListener) ==
-+ nsNativeMenuDocListenerTArray::NoIndex) {
-+ gPendingListeners->AppendElement(aListener);
-+ }
-+}
-+
-+/* static */ void
-+nsNativeMenuDocListener::CancelFlush(nsNativeMenuDocListener *aListener)
-+{
-+ if (!gPendingListeners) {
-+ return;
-+ }
-+
-+ gPendingListeners->RemoveElement(aListener);
-+}
-+
-+/* static */ void
-+nsNativeMenuDocListener::RemoveUpdateBlocker()
-+{
-+ if (sUpdateBlockersCount == 1 && gPendingListeners) {
-+ while (gPendingListeners->Length() > 0) {
-+ (*gPendingListeners)[0]->FlushPendingMutations();
-+ gPendingListeners->RemoveElementAt(0);
-+ }
-+ }
-+
-+ MOZ_ASSERT(sUpdateBlockersCount > 0, "Negative update blockers count!");
-+ sUpdateBlockersCount--;
-+}
-+
-+nsNativeMenuDocListener::nsNativeMenuDocListener(nsIContent *aRootNode) :
-+ mRootNode(aRootNode),
-+ mDocument(nullptr),
-+ mLastSource(nullptr),
-+ mLastTarget(nullptr)
-+{
-+ MOZ_COUNT_CTOR(nsNativeMenuDocListener);
-+}
-+
-+void
-+nsNativeMenuDocListener::RegisterForContentChanges(nsIContent *aContent,
-+ nsNativeMenuChangeObserver *aObserver)
-+{
-+ MOZ_ASSERT(aContent, "Need content parameter");
-+ MOZ_ASSERT(aObserver, "Need observer parameter");
-+ if (!aContent || !aObserver) {
-+ return;
-+ }
-+
-+ DebugOnly<nsNativeMenuChangeObserver *> old;
-+ MOZ_ASSERT(!mContentToObserverTable.Get(aContent, &old) || old == aObserver,
-+ "Multiple observers for the same content node are not supported");
-+
-+ mContentToObserverTable.InsertOrUpdate(aContent, aObserver);
-+}
-+
-+void
-+nsNativeMenuDocListener::UnregisterForContentChanges(nsIContent *aContent)
-+{
-+ MOZ_ASSERT(aContent, "Need content parameter");
-+ if (!aContent) {
-+ return;
-+ }
-+
-+ mContentToObserverTable.Remove(aContent);
-+ if (aContent == mLastSource) {
-+ mLastSource = nullptr;
-+ mLastTarget = nullptr;
-+ }
-+}
-+
-+void
-+nsNativeMenuDocListener::Start()
-+{
-+ if (mDocument) {
-+ return;
-+ }
-+
-+ mDocument = mRootNode->OwnerDoc();
-+ if (!mDocument) {
-+ return;
-+ }
-+
-+ mDocument->AddMutationObserver(this);
-+}
-+
-+void
-+nsNativeMenuDocListener::Stop()
-+{
-+ if (mDocument) {
-+ mDocument->RemoveMutationObserver(this);
-+ mDocument = nullptr;
-+ }
-+
-+ CancelFlush(this);
-+ mPendingMutations.Clear();
-+}
-diff --git a/widget/gtk/nsNativeMenuDocListener.h b/widget/gtk/nsNativeMenuDocListener.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..5ee99cba70fd4444b31387103bd0c3e022f598fa
---- /dev/null
-+++ b/widget/gtk/nsNativeMenuDocListener.h
-@@ -0,0 +1,152 @@
-+/* -*- 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 __nsNativeMenuDocListener_h__
-+#define __nsNativeMenuDocListener_h__
-+
-+#include "mozilla/Attributes.h"
-+#include "mozilla/RefPtr.h"
-+#include "mozilla/UniquePtr.h"
-+#include "nsTHashMap.h"
-+#include "nsStubMutationObserver.h"
-+#include "nsTArray.h"
-+
-+class nsAtom;
-+class nsIContent;
-+class nsNativeMenuChangeObserver;
-+
-+namespace mozilla {
-+namespace dom {
-+class Document;
-+}
-+}
-+
-+/*
-+ * This class keeps a mapping of content nodes to observers and forwards DOM
-+ * mutations to these. There is exactly one of these for every menubar.
-+ */
-+class nsNativeMenuDocListener final : nsStubMutationObserver
-+{
-+public:
-+ NS_DECL_ISUPPORTS
-+
-+ nsNativeMenuDocListener(nsIContent *aRootNode);
-+
-+ // Register an observer to receive mutation events for the specified
-+ // content node. The caller must keep the observer alive until
-+ // UnregisterForContentChanges is called.
-+ void RegisterForContentChanges(nsIContent *aContent,
-+ nsNativeMenuChangeObserver *aObserver);
-+
-+ // Unregister the registered observer for the specified content node
-+ void UnregisterForContentChanges(nsIContent *aContent);
-+
-+ // Start listening to the document and forwarding DOM mutations to
-+ // registered observers.
-+ void Start();
-+
-+ // Stop listening to the document. No DOM mutations will be forwarded
-+ // to registered observers.
-+ void Stop();
-+
-+ /*
-+ * This class is intended to be used inside GObject signal handlers.
-+ * It allows us to queue updates until we have finished delivering
-+ * events to Gecko, and then we can batch updates to our view of the
-+ * menu. This allows us to do menu updates without altering the structure
-+ * seen by the OS.
-+ */
-+ class MOZ_STACK_CLASS BlockUpdatesScope
-+ {
-+ public:
-+ BlockUpdatesScope()
-+ {
-+ nsNativeMenuDocListener::AddUpdateBlocker();
-+ }
-+
-+ ~BlockUpdatesScope()
-+ {
-+ nsNativeMenuDocListener::RemoveUpdateBlocker();
-+ }
-+ };
-+
-+private:
-+ friend class DispatchHelper;
-+
-+ struct MutationRecord {
-+ enum RecordType {
-+ eAttributeChanged,
-+ eContentInserted,
-+ eContentRemoved
-+ } mType;
-+
-+ nsCOMPtr<nsIContent> mTarget;
-+ nsCOMPtr<nsIContent> mChild;
-+ nsCOMPtr<nsIContent> mPrevSibling;
-+ RefPtr<nsAtom> mAttribute;
-+ };
-+
-+ ~nsNativeMenuDocListener();
-+
-+ NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
-+ NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
-+ NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
-+ NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
-+ NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
-+
-+ void DoAttributeChanged(nsIContent *aContent, nsAtom *aAttribute);
-+ void DoContentInserted(nsIContent *aContainer,
-+ nsIContent *aChild,
-+ nsIContent *aPrevSibling);
-+ void DoContentRemoved(nsIContent *aContainer, nsIContent *aChild);
-+ void DoBeginUpdates(nsIContent *aTarget);
-+ void DoEndUpdates(nsIContent *aTarget);
-+
-+ void FlushPendingMutations();
-+ static void ScheduleFlush(nsNativeMenuDocListener *aListener);
-+ static void CancelFlush(nsNativeMenuDocListener *aListener);
-+
-+ static void AddUpdateBlocker() { ++sUpdateBlockersCount; }
-+ static void RemoveUpdateBlocker();
-+
-+ nsCOMPtr<nsIContent> mRootNode;
-+ mozilla::dom::Document *mDocument;
-+ nsIContent *mLastSource;
-+ nsNativeMenuChangeObserver *mLastTarget;
-+ nsTArray<mozilla::UniquePtr<MutationRecord> > mPendingMutations;
-+ nsTHashMap<nsPtrHashKey<nsIContent>, nsNativeMenuChangeObserver *> mContentToObserverTable;
-+
-+ static uint32_t sUpdateBlockersCount;
-+};
-+
-+typedef nsTArray<RefPtr<nsNativeMenuDocListener> > nsNativeMenuDocListenerTArray;
-+
-+/*
-+ * Implemented by classes that want to listen to mutation events from content
-+ * nodes.
-+ */
-+class nsNativeMenuChangeObserver
-+{
-+public:
-+ virtual void OnAttributeChanged(nsIContent *aContent, nsAtom *aAttribute) {}
-+
-+ virtual void OnContentInserted(nsIContent *aContainer,
-+ nsIContent *aChild,
-+ nsIContent *aPrevSibling) {}
-+
-+ virtual void OnContentRemoved(nsIContent *aContainer, nsIContent *aChild) {}
-+
-+ // Signals the start of a sequence of more than 1 event for the specified
-+ // node. This only happens when events are flushed as all BlockUpdatesScope
-+ // instances go out of scope
-+ virtual void OnBeginUpdates(nsIContent *aContent) {};
-+
-+ // Signals the end of a sequence of events
-+ virtual void OnEndUpdates() {};
-+};
-+
-+#endif /* __nsNativeMenuDocListener_h__ */
-diff --git a/widget/gtk/nsNativeMenuService.cpp b/widget/gtk/nsNativeMenuService.cpp
-new file mode 100644
-index 0000000000000000000000000000000000000000..5cf36a4470361a4c440fe5795a33f175847339e0
---- /dev/null
-+++ b/widget/gtk/nsNativeMenuService.cpp
-@@ -0,0 +1,478 @@
-+/* -*- 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 "mozilla/dom/Element.h"
-+#include "mozilla/Assertions.h"
-+#include "mozilla/Preferences.h"
-+#include "mozilla/UniquePtr.h"
-+#include "nsCOMPtr.h"
-+#include "nsCRT.h"
-+#include "nsGtkUtils.h"
-+#include "nsIContent.h"
-+#include "nsIWidget.h"
-+#include "nsServiceManagerUtils.h"
-+#include "nsWindow.h"
-+#include "prlink.h"
-+
-+#include "nsDbusmenu.h"
-+#include "nsMenuBar.h"
-+#include "nsNativeMenuDocListener.h"
-+
-+#include <glib-object.h>
-+#include <pango/pango.h>
-+#include <stdlib.h>
-+
-+#include "nsNativeMenuService.h"
-+
-+using namespace mozilla;
-+
-+nsNativeMenuService* nsNativeMenuService::sService = nullptr;
-+
-+extern PangoLayout* gPangoLayout;
-+extern nsNativeMenuDocListenerTArray* gPendingListeners;
-+
-+#undef g_dbus_proxy_new_for_bus
-+#undef g_dbus_proxy_new_for_bus_finish
-+#undef g_dbus_proxy_call
-+#undef g_dbus_proxy_call_finish
-+#undef g_dbus_proxy_get_name_owner
-+
-+typedef void (*_g_dbus_proxy_new_for_bus_fn)(GBusType, GDBusProxyFlags,
-+ GDBusInterfaceInfo*,
-+ const gchar*, const gchar*,
-+ const gchar*, GCancellable*,
-+ GAsyncReadyCallback, gpointer);
-+
-+typedef GDBusProxy* (*_g_dbus_proxy_new_for_bus_finish_fn)(GAsyncResult*,
-+ GError**);
-+typedef void (*_g_dbus_proxy_call_fn)(GDBusProxy*, const gchar*, GVariant*,
-+ GDBusCallFlags, gint, GCancellable*,
-+ GAsyncReadyCallback, gpointer);
-+typedef GVariant* (*_g_dbus_proxy_call_finish_fn)(GDBusProxy*, GAsyncResult*,
-+ GError**);
-+typedef gchar* (*_g_dbus_proxy_get_name_owner_fn)(GDBusProxy*);
-+
-+static _g_dbus_proxy_new_for_bus_fn _g_dbus_proxy_new_for_bus;
-+static _g_dbus_proxy_new_for_bus_finish_fn _g_dbus_proxy_new_for_bus_finish;
-+static _g_dbus_proxy_call_fn _g_dbus_proxy_call;
-+static _g_dbus_proxy_call_finish_fn _g_dbus_proxy_call_finish;
-+static _g_dbus_proxy_get_name_owner_fn _g_dbus_proxy_get_name_owner;
-+
-+#define g_dbus_proxy_new_for_bus _g_dbus_proxy_new_for_bus
-+#define g_dbus_proxy_new_for_bus_finish _g_dbus_proxy_new_for_bus_finish
-+#define g_dbus_proxy_call _g_dbus_proxy_call
-+#define g_dbus_proxy_call_finish _g_dbus_proxy_call_finish
-+#define g_dbus_proxy_get_name_owner _g_dbus_proxy_get_name_owner
-+
-+static PRLibrary *gGIOLib = nullptr;
-+
-+static nsresult
-+GDBusInit()
-+{
-+ gGIOLib = PR_LoadLibrary("libgio-2.0.so.0");
-+ if (!gGIOLib) {
-+ return NS_ERROR_FAILURE;
-+ }
-+
-+ g_dbus_proxy_new_for_bus = (_g_dbus_proxy_new_for_bus_fn)PR_FindFunctionSymbol(gGIOLib, "g_dbus_proxy_new_for_bus");
-+ g_dbus_proxy_new_for_bus_finish = (_g_dbus_proxy_new_for_bus_finish_fn)PR_FindFunctionSymbol(gGIOLib, "g_dbus_proxy_new_for_bus_finish");
-+ g_dbus_proxy_call = (_g_dbus_proxy_call_fn)PR_FindFunctionSymbol(gGIOLib, "g_dbus_proxy_call");
-+ g_dbus_proxy_call_finish = (_g_dbus_proxy_call_finish_fn)PR_FindFunctionSymbol(gGIOLib, "g_dbus_proxy_call_finish");
-+ g_dbus_proxy_get_name_owner = (_g_dbus_proxy_get_name_owner_fn)PR_FindFunctionSymbol(gGIOLib, "g_dbus_proxy_get_name_owner");
-+
-+ if (!g_dbus_proxy_new_for_bus ||
-+ !g_dbus_proxy_new_for_bus_finish ||
-+ !g_dbus_proxy_call ||
-+ !g_dbus_proxy_call_finish ||
-+ !g_dbus_proxy_get_name_owner) {
-+ return NS_ERROR_FAILURE;
-+ }
-+
-+ return NS_OK;
-+}
-+
-+NS_IMPL_ISUPPORTS(nsNativeMenuService, nsINativeMenuService)
-+
-+nsNativeMenuService::nsNativeMenuService() :
-+ mCreateProxyCancellable(nullptr), mDbusProxy(nullptr), mOnline(false)
-+{
-+}
-+
-+nsNativeMenuService::~nsNativeMenuService()
-+{
-+ SetOnline(false);
-+
-+ if (mCreateProxyCancellable) {
-+ g_cancellable_cancel(mCreateProxyCancellable);
-+ g_object_unref(mCreateProxyCancellable);
-+ mCreateProxyCancellable = nullptr;
-+ }
-+
-+ // Make sure we disconnect map-event handlers
-+ while (mMenuBars.Length() > 0) {
-+ NotifyNativeMenuBarDestroyed(mMenuBars[0]);
-+ }
-+
-+ Preferences::UnregisterCallback(PrefChangedCallback,
-+ "ui.use_unity_menubar");
-+
-+ if (mDbusProxy) {
-+ g_signal_handlers_disconnect_by_func(mDbusProxy,
-+ FuncToGpointer(name_owner_changed_cb),
-+ NULL);
-+ g_object_unref(mDbusProxy);
-+ }
-+
-+ if (gPendingListeners) {
-+ delete gPendingListeners;
-+ gPendingListeners = nullptr;
-+ }
-+ if (gPangoLayout) {
-+ g_object_unref(gPangoLayout);
-+ gPangoLayout = nullptr;
-+ }
-+
-+ MOZ_ASSERT(sService == this);
-+ sService = nullptr;
-+}
-+
-+nsresult
-+nsNativeMenuService::Init()
-+{
-+ nsresult rv = nsDbusmenuFunctions::Init();
-+ if (NS_FAILED(rv)) {
-+ return rv;
-+ }
-+
-+ rv = GDBusInit();
-+ if (NS_FAILED(rv)) {
-+ return rv;
-+ }
-+
-+ Preferences::RegisterCallback(PrefChangedCallback,
-+ "ui.use_unity_menubar");
-+
-+ mCreateProxyCancellable = g_cancellable_new();
-+
-+ g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
-+ static_cast<GDBusProxyFlags>(
-+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
-+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
-+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START),
-+ nullptr,
-+ "com.canonical.AppMenu.Registrar",
-+ "/com/canonical/AppMenu/Registrar",
-+ "com.canonical.AppMenu.Registrar",
-+ mCreateProxyCancellable, proxy_created_cb,
-+ nullptr);
-+
-+ /* We don't technically know that the shell will draw the menubar until
-+ * we know whether anybody owns the name of the menubar service on the
-+ * session bus. However, discovering this happens asynchronously so
-+ * we optimize for the common case here by assuming that the shell will
-+ * draw window menubars if we are running inside Unity. This should
-+ * mean that we avoid temporarily displaying the window menubar ourselves
-+ */
-+ const char *desktop = getenv("XDG_CURRENT_DESKTOP");
-+ if (nsCRT::strcmp(desktop, "Unity") == 0) {
-+ SetOnline(true);
-+ }
-+
-+ return NS_OK;
-+}
-+
-+/* static */ void
-+nsNativeMenuService::EnsureInitialized()
-+{
-+ if (sService) {
-+ return;
-+ }
-+ nsCOMPtr<nsINativeMenuService> service =
-+ do_GetService("@mozilla.org/widget/nativemenuservice;1");
-+}
-+
-+void
-+nsNativeMenuService::SetOnline(bool aOnline)
-+{
-+ if (!Preferences::GetBool("ui.use_unity_menubar", true)) {
-+ aOnline = false;
-+ }
-+
-+ mOnline = aOnline;
-+ if (aOnline) {
-+ for (uint32_t i = 0; i < mMenuBars.Length(); ++i) {
-+ RegisterNativeMenuBar(mMenuBars[i]);
-+ }
-+ } else {
-+ for (uint32_t i = 0; i < mMenuBars.Length(); ++i) {
-+ mMenuBars[i]->Deactivate();
-+ }
-+ }
-+}
-+
-+void
-+nsNativeMenuService::RegisterNativeMenuBar(nsMenuBar *aMenuBar)
-+{
-+ if (!mOnline) {
-+ return;
-+ }
-+
-+ // This will effectively create the native menubar for
-+ // exporting over the session bus, and hide the XUL menubar
-+ aMenuBar->Activate();
-+
-+ if (!mDbusProxy ||
-+ !gtk_widget_get_mapped(aMenuBar->TopLevelWindow()) ||
-+ mMenuBarRegistrationCancellables.Get(aMenuBar, nullptr)) {
-+ // Don't go further if we don't have a proxy for the shell menu
-+ // service, the window isn't mapped or there is a request in progress.
-+ return;
-+ }
-+
-+ uint32_t xid = aMenuBar->WindowId();
-+ nsCString path = aMenuBar->ObjectPath();
-+ if (xid == 0 || path.IsEmpty()) {
-+ NS_WARNING("Menubar has invalid XID or object path");
-+ return;
-+ }
-+
-+ GCancellable *cancellable = g_cancellable_new();
-+ mMenuBarRegistrationCancellables.InsertOrUpdate(aMenuBar, cancellable);
-+
-+ // We keep a weak ref because we can't assume that GDBus cancellation
-+ // is reliable (see https://launchpad.net/bugs/953562)
-+
-+ g_dbus_proxy_call(mDbusProxy, "RegisterWindow",
-+ g_variant_new("(uo)", xid, path.get()),
-+ G_DBUS_CALL_FLAGS_NONE, -1,
-+ cancellable,
-+ register_native_menubar_cb, aMenuBar);
-+}
-+
-+/* static */ void
-+nsNativeMenuService::name_owner_changed_cb(GObject *gobject,
-+ GParamSpec *pspec,
-+ gpointer user_data)
-+{
-+ nsNativeMenuService::GetSingleton()->OnNameOwnerChanged();
-+}
-+
-+/* static */ void
-+nsNativeMenuService::proxy_created_cb(GObject *source_object,
-+ GAsyncResult *res,
-+ gpointer user_data)
-+{
-+ GError *error = nullptr;
-+ GDBusProxy *proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
-+ if (error && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-+ g_error_free(error);
-+ return;
-+ }
-+
-+ if (error) {
-+ g_error_free(error);
-+ }
-+
-+ // We need this check because we can't assume that GDBus cancellation
-+ // is reliable (see https://launchpad.net/bugs/953562)
-+ nsNativeMenuService *self = nsNativeMenuService::GetSingleton();
-+ if (!self) {
-+ if (proxy) {
-+ g_object_unref(proxy);
-+ }
-+ return;
-+ }
-+
-+ self->OnProxyCreated(proxy);
-+}
-+
-+/* static */ void
-+nsNativeMenuService::register_native_menubar_cb(GObject *source_object,
-+ GAsyncResult *res,
-+ gpointer user_data)
-+{
-+ nsMenuBar *menuBar = static_cast<nsMenuBar *>(user_data);
-+
-+ GError *error = nullptr;
-+ GVariant *results = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object),
-+ res, &error);
-+ if (results) {
-+ // There's nothing useful in the response
-+ g_variant_unref(results);
-+ }
-+
-+ bool success = error ? false : true;
-+ if (error && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-+ g_error_free(error);
-+ return;
-+ }
-+
-+ if (error) {
-+ g_error_free(error);
-+ }
-+
-+ nsNativeMenuService *self = nsNativeMenuService::GetSingleton();
-+ if (!self) {
-+ return;
-+ }
-+
-+ self->OnNativeMenuBarRegistered(menuBar, success);
-+}
-+
-+/* static */ gboolean
-+nsNativeMenuService::map_event_cb(GtkWidget *widget,
-+ GdkEvent *event,
-+ gpointer user_data)
-+{
-+ nsMenuBar *menubar = static_cast<nsMenuBar *>(user_data);
-+ nsNativeMenuService::GetSingleton()->RegisterNativeMenuBar(menubar);
-+
-+ return FALSE;
-+}
-+
-+void
-+nsNativeMenuService::OnNameOwnerChanged()
-+{
-+ char *owner = g_dbus_proxy_get_name_owner(mDbusProxy);
-+ SetOnline(owner ? true : false);
-+ g_free(owner);
-+}
-+
-+void
-+nsNativeMenuService::OnProxyCreated(GDBusProxy *aProxy)
-+{
-+ mDbusProxy = aProxy;
-+
-+ g_object_unref(mCreateProxyCancellable);
-+ mCreateProxyCancellable = nullptr;
-+
-+ if (!mDbusProxy) {
-+ SetOnline(false);
-+ return;
-+ }
-+
-+ g_signal_connect(mDbusProxy, "notify::g-name-owner",
-+ G_CALLBACK(name_owner_changed_cb), nullptr);
-+
-+ OnNameOwnerChanged();
-+}
-+
-+void
-+nsNativeMenuService::OnNativeMenuBarRegistered(nsMenuBar *aMenuBar,
-+ bool aSuccess)
-+{
-+ // Don't assume that GDBus cancellation is reliable (ie, |aMenuBar| might
-+ // have already been deleted (see https://launchpad.net/bugs/953562)
-+ GCancellable *cancellable = nullptr;
-+ if (!mMenuBarRegistrationCancellables.Get(aMenuBar, &cancellable)) {
-+ return;
-+ }
-+
-+ g_object_unref(cancellable);
-+ mMenuBarRegistrationCancellables.Remove(aMenuBar);
-+
-+ if (!aSuccess) {
-+ aMenuBar->Deactivate();
-+ }
-+}
-+
-+/* static */ void
-+nsNativeMenuService::PrefChangedCallback(const char *aPref,
-+ void *aClosure)
-+{
-+ nsNativeMenuService::GetSingleton()->PrefChanged();
-+}
-+
-+void
-+nsNativeMenuService::PrefChanged()
-+{
-+ if (!mDbusProxy) {
-+ SetOnline(false);
-+ return;
-+ }
-+
-+ OnNameOwnerChanged();
-+}
-+
-+NS_IMETHODIMP
-+nsNativeMenuService::CreateNativeMenuBar(nsIWidget *aParent,
-+ mozilla::dom::Element *aMenuBarNode)
-+{
-+ NS_ENSURE_ARG(aParent);
-+ NS_ENSURE_ARG(aMenuBarNode);
-+
-+ if (aMenuBarNode->AttrValueIs(kNameSpaceID_None,
-+ nsGkAtoms::_moz_menubarkeeplocal,
-+ nsGkAtoms::_true,
-+ eCaseMatters)) {
-+ return NS_OK;
-+ }
-+
-+ UniquePtr<nsMenuBar> menubar(nsMenuBar::Create(aParent, aMenuBarNode));
-+ if (!menubar) {
-+ NS_WARNING("Failed to create menubar");
-+ return NS_ERROR_FAILURE;
-+ }
-+
-+ // Unity forgets our window if it is unmapped by the application, which
-+ // happens with some extensions that add "minimize to tray" type
-+ // functionality. We hook on to the MapNotify event to re-register our menu
-+ // with Unity
-+ g_signal_connect(G_OBJECT(menubar->TopLevelWindow()),
-+ "map-event", G_CALLBACK(map_event_cb),
-+ menubar.get());
-+
-+ mMenuBars.AppendElement(menubar.get());
-+ RegisterNativeMenuBar(menubar.get());
-+
-+ static_cast<nsWindow *>(aParent)->SetMenuBar(std::move(menubar));
-+
-+ return NS_OK;
-+}
-+
-+/* static */ already_AddRefed<nsNativeMenuService>
-+nsNativeMenuService::GetInstanceForServiceManager()
-+{
-+ RefPtr<nsNativeMenuService> service(sService);
-+
-+ if (service) {
-+ return service.forget();
-+ }
-+
-+ service = new nsNativeMenuService();
-+
-+ if (NS_FAILED(service->Init())) {
-+ return nullptr;
-+ }
-+
-+ sService = service.get();
-+ return service.forget();
-+}
-+
-+/* static */ nsNativeMenuService*
-+nsNativeMenuService::GetSingleton()
-+{
-+ EnsureInitialized();
-+ return sService;
-+}
-+
-+void
-+nsNativeMenuService::NotifyNativeMenuBarDestroyed(nsMenuBar *aMenuBar)
-+{
-+ g_signal_handlers_disconnect_by_func(aMenuBar->TopLevelWindow(),
-+ FuncToGpointer(map_event_cb),
-+ aMenuBar);
-+
-+ mMenuBars.RemoveElement(aMenuBar);
-+
-+ GCancellable *cancellable = nullptr;
-+ if (mMenuBarRegistrationCancellables.Get(aMenuBar, &cancellable)) {
-+ mMenuBarRegistrationCancellables.Remove(aMenuBar);
-+ g_cancellable_cancel(cancellable);
-+ g_object_unref(cancellable);
-+ }
-+}
-diff --git a/widget/gtk/nsNativeMenuService.h b/widget/gtk/nsNativeMenuService.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..2e0d429eddfdfc84620834eced6b973317a36067
---- /dev/null
-+++ b/widget/gtk/nsNativeMenuService.h
-@@ -0,0 +1,85 @@
-+/* -*- 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 __nsNativeMenuService_h__
-+#define __nsNativeMenuService_h__
-+
-+#include "mozilla/Attributes.h"
-+#include "nsCOMPtr.h"
-+#include "nsTHashMap.h"
-+#include "nsINativeMenuService.h"
-+#include "nsTArray.h"
-+
-+#include <gdk/gdk.h>
-+#include <gio/gio.h>
-+#include <gtk/gtk.h>
-+
-+class nsMenuBar;
-+
-+/*
-+ * The main native menu service singleton.
-+ * NativeMenuSupport::CreateNativeMenuBar calls in to this when a new top level
-+ * window is created.
-+ *
-+ * Menubars are owned by their nsWindow. This service holds a weak reference to
-+ * each menubar for the purpose of re-registering them with the shell if it
-+ * needs to. The menubar is responsible for notifying the service when the last
-+ * reference to it is dropped.
-+ */
-+class nsNativeMenuService final : public nsINativeMenuService
-+{
-+public:
-+ NS_DECL_ISUPPORTS
-+
-+ NS_IMETHOD CreateNativeMenuBar(nsIWidget* aParent, mozilla::dom::Element* aMenuBarNode) override;
-+
-+ // Returns the singleton addref'd for the service manager
-+ static already_AddRefed<nsNativeMenuService> GetInstanceForServiceManager();
-+
-+ // Returns the singleton without increasing the reference count
-+ static nsNativeMenuService* GetSingleton();
-+
-+ // Called by a menubar when it is deleted
-+ void NotifyNativeMenuBarDestroyed(nsMenuBar *aMenuBar);
-+
-+private:
-+ nsNativeMenuService();
-+ ~nsNativeMenuService();
-+ nsresult Init();
-+
-+ static void EnsureInitialized();
-+ void SetOnline(bool aOnline);
-+ void RegisterNativeMenuBar(nsMenuBar *aMenuBar);
-+ static void name_owner_changed_cb(GObject *gobject,
-+ GParamSpec *pspec,
-+ gpointer user_data);
-+ static void proxy_created_cb(GObject *source_object,
-+ GAsyncResult *res,
-+ gpointer user_data);
-+ static void register_native_menubar_cb(GObject *source_object,
-+ GAsyncResult *res,
-+ gpointer user_data);
-+ static gboolean map_event_cb(GtkWidget *widget, GdkEvent *event,
-+ gpointer user_data);
-+ void OnNameOwnerChanged();
-+ void OnProxyCreated(GDBusProxy *aProxy);
-+ void OnNativeMenuBarRegistered(nsMenuBar *aMenuBar,
-+ bool aSuccess);
-+ static void PrefChangedCallback(const char *aPref, void *aClosure);
-+ void PrefChanged();
-+
-+ GCancellable *mCreateProxyCancellable;
-+ GDBusProxy *mDbusProxy;
-+ bool mOnline;
-+ nsTArray<nsMenuBar *> mMenuBars;
-+ nsTHashMap<nsPtrHashKey<nsMenuBar>, GCancellable*> mMenuBarRegistrationCancellables;
-+
-+ static bool sShutdown;
-+ static nsNativeMenuService *sService;
-+};
-+
-+#endif /* __nsNativeMenuService_h__ */
-diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
-index e3a668faf2ad2b5dad6f2c5ec50bb90f12f68a52..b89027e1f02e764efa35f879f9f07f3e1867a2ee 100644
---- a/widget/gtk/nsWindow.cpp
-+++ b/widget/gtk/nsWindow.cpp
-@@ -7646,6 +7646,10 @@ void nsWindow::HideWindowChrome(bool aShouldHide) {
- SetWindowDecoration(aShouldHide ? BorderStyle::None : mBorderStyle);
- }
-
-+void nsWindow::SetMenuBar(UniquePtr<nsMenuBar> aMenuBar) {
-+ mMenuBar = std::move(aMenuBar);
-+}
-+
- bool nsWindow::CheckForRollup(gdouble aMouseX, gdouble aMouseY, bool aIsWheel,
- bool aAlwaysRollup) {
- LOG("nsWindow::CheckForRollup() aAlwaysRollup %d", aAlwaysRollup);
-diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h
-index 5c8ea783ba42b93e68e1699cd0ea8a34ea6e58e2..d9575241a04ec6cc3dfa3853d831728acb042df4 100644
---- a/widget/gtk/nsWindow.h
-+++ b/widget/gtk/nsWindow.h
-@@ -27,6 +27,8 @@
- #include "nsRefPtrHashtable.h"
- #include "IMContextWrapper.h"
-
-+#include "nsMenuBar.h"
-+
- #ifdef ACCESSIBILITY
- # include "mozilla/a11y/LocalAccessible.h"
- #endif
-@@ -208,6 +210,8 @@ class nsWindow final : public nsBaseWidget {
- nsresult MakeFullScreen(bool aFullScreen) override;
- void HideWindowChrome(bool aShouldHide) override;
-
-+ void SetMenuBar(mozilla::UniquePtr<nsMenuBar> aMenuBar);
-+
- /**
- * GetLastUserInputTime returns a timestamp for the most recent user input
- * event. This is intended for pointer grab requests (including drags).
-@@ -935,6 +939,8 @@ class nsWindow final : public nsBaseWidget {
-
- static bool sTransparentMainWindow;
-
-+ mozilla::UniquePtr<nsMenuBar> mMenuBar;
-+
- #ifdef ACCESSIBILITY
- RefPtr<mozilla::a11y::LocalAccessible> mRootAccessible;
-
-diff --git a/widget/moz.build b/widget/moz.build
-index 87f5362f3b70f81cac6376cd1b2e1fd09511816d..1fd8aa2b7ac5747f7654f5d071d1536770b2a7b7 100644
---- a/widget/moz.build
-+++ b/widget/moz.build
-@@ -164,6 +164,11 @@ EXPORTS += [
- "PuppetWidget.h",
- ]
-
-+if toolkit == "gtk":
-+ EXPORTS += [
-+ "nsINativeMenuService.h",
-+ ]
-+
- EXPORTS.mozilla += [
- "BasicEvents.h",
- "ClipboardReadRequestChild.h",
-diff --git a/widget/nsINativeMenuService.h b/widget/nsINativeMenuService.h
-new file mode 100644
-index 0000000000000000000000000000000000000000..e92d7a74a3bc508ee702a1699b9e484a6031c52a
---- /dev/null
-+++ b/widget/nsINativeMenuService.h
-@@ -0,0 +1,39 @@
-+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-+/* 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 nsINativeMenuService_h_
-+#define nsINativeMenuService_h_
-+
-+#include "nsISupports.h"
-+
-+class nsIWidget;
-+class nsIContent;
-+namespace mozilla {
-+namespace dom {
-+class Element;
-+}
-+} // namespace mozilla
-+
-+// {90DF88F9-F084-4EF3-829A-49496E636DED}
-+#define NS_INATIVEMENUSERVICE_IID \
-+ { \
-+ 0x90DF88F9, 0xF084, 0x4EF3, { \
-+ 0x82, 0x9A, 0x49, 0x49, 0x6E, 0x63, 0x6D, 0xED \
-+ } \
-+ }
-+
-+class nsINativeMenuService : public nsISupports {
-+ public:
-+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_INATIVEMENUSERVICE_IID)
-+ // Given a top-level window widget and a menu bar DOM node, sets up native
-+ // menus. Once created, native menus are controlled via the DOM, including
-+ // destruction.
-+ NS_IMETHOD CreateNativeMenuBar(nsIWidget* aParent,
-+ mozilla::dom::Element* aMenuBarNode) = 0;
-+};
-+
-+NS_DEFINE_STATIC_IID_ACCESSOR(nsINativeMenuService, NS_INATIVEMENUSERVICE_IID)
-+
-+#endif // nsINativeMenuService_h_
-diff --git a/widget/nsWidgetsCID.h b/widget/nsWidgetsCID.h
-index 8e0f67661414cbd7e8fe69c2ebdcffcdda4bdd44..911711e88a0e533989af05fcd383c6e1c81db2f6 100644
---- a/widget/nsWidgetsCID.h
-+++ b/widget/nsWidgetsCID.h
-@@ -66,6 +66,14 @@
- // Menus
- //-----------------------------------------------------------
-
-+// {0B3FE5AA-BC72-4303-85AE-76365DF1251D}
-+#define NS_NATIVEMENUSERVICE_CID \
-+ { \
-+ 0x0B3FE5AA, 0xBC72, 0x4303, { \
-+ 0x85, 0xAE, 0x76, 0x36, 0x5D, 0xF1, 0x25, 0x1D \
-+ } \
-+ }
-+
- // {F6CD4F21-53AF-11d2-8DC4-00609703C14E}
- #define NS_POPUPMENU_CID \
- { \
-diff --git a/xpcom/ds/NativeMenuAtoms.py b/xpcom/ds/NativeMenuAtoms.py
-new file mode 100644
-index 0000000000000000000000000000000000000000..488c8f49c0217890d2c5a12f57fdc194e08e49a7
---- /dev/null
-+++ b/xpcom/ds/NativeMenuAtoms.py
-@@ -0,0 +1,9 @@
-+from Atom import Atom
-+
-+NATIVE_MENU_ATOMS = [
-+ Atom("menuitem_with_favicon", "menuitem-with-favicon"),
-+ Atom("_moz_menubarkeeplocal", "_moz-menubarkeeplocal"),
-+ Atom("_moz_nativemenupopupstate", "_moz-nativemenupopupstate"),
-+ Atom("openedwithkey", "openedwithkey"),
-+ Atom("shellshowingmenubar", "shellshowingmenubar"),
-+]
-diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py
-index e8a59002999cefe22f15b7fc52ced21bcea2dd9f..4f8e982caabbd36e1198e0f275634ea7689e9838 100644
---- a/xpcom/ds/StaticAtoms.py
-+++ b/xpcom/ds/StaticAtoms.py
-@@ -13,6 +13,7 @@ from Atom import (
- PseudoElementAtom,
- )
- from HTMLAtoms import HTML_PARSER_ATOMS
-+from NativeMenuAtoms import NATIVE_MENU_ATOMS
-
- # Static atom definitions, used to generate nsGkAtomList.h.
- #
-@@ -2557,7 +2558,7 @@ STATIC_ATOMS = [
- InheritingAnonBoxAtom("AnonBox_mozSVGForeignContent", ":-moz-svg-foreign-content"),
- InheritingAnonBoxAtom("AnonBox_mozSVGText", ":-moz-svg-text"),
- # END ATOMS
--] + HTML_PARSER_ATOMS
-+] + HTML_PARSER_ATOMS + NATIVE_MENU_ATOMS
- # fmt: on
-
-
-diff --git a/xpfe/appshell/AppWindow.cpp b/xpfe/appshell/AppWindow.cpp
-index cf48d920a996c5e028b6ce24ccf694b7a01641e3..98a7f22da153f304b550c86fcc21487862fb1d4c 100644
---- a/xpfe/appshell/AppWindow.cpp
-+++ b/xpfe/appshell/AppWindow.cpp
-@@ -78,7 +78,7 @@
-
- #include "mozilla/dom/DocumentL10n.h"
-
--#ifdef XP_MACOSX
-+#if defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
- # include "mozilla/widget/NativeMenuSupport.h"
- # define USE_NATIVE_MENUS
- #endif
diff --git a/0024-Do-not-use-gconf-for-proxy-settings-if-not-running-w.patch b/0023-Do-not-use-gconf-for-proxy-settings-if-not-running-w.patch
index c1a6d30860a8..a6cb80ea420b 100644
--- a/0024-Do-not-use-gconf-for-proxy-settings-if-not-running-w.patch
+++ b/0023-Do-not-use-gconf-for-proxy-settings-if-not-running-w.patch
@@ -9,7 +9,7 @@ Subject: [PATCH] Do not use gconf for proxy settings if not running within
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp b/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
-index 982faf7d7968430cdf44928f2408847df55170d2..185dc1e22a903cec95b212d1713dddf764b9b198 100644
+index 4c84041ef379d9da77241ddd5bde01bfb1570791..ceba4f73cba051cea517a0988667de74d6b3172e 100644
--- a/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
+++ b/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
@@ -52,10 +52,14 @@ nsUnixSystemProxySettings::GetMainThreadOnly(bool* aMainThreadOnly) {
diff --git a/0025-Add-KDE-integration-to-Firefox-toolkit-parts.patch b/0024-Add-KDE-integration-to-Firefox-toolkit-parts.patch
index 1b113382f7c4..fec4b119d256 100644
--- a/0025-Add-KDE-integration-to-Firefox-toolkit-parts.patch
+++ b/0024-Add-KDE-integration-to-Firefox-toolkit-parts.patch
@@ -21,7 +21,7 @@ Co-authored-by: Björn Bidar <bjorn.bidar@thaodan.de>
python/mozbuild/mozpack/chrome/manifest.py | 1 +
toolkit/components/downloads/moz.build | 4 +
.../mozapps/downloads/HelperAppDlg.sys.mjs | 70 +++--
- .../unixproxy/nsUnixSystemProxySettings.cpp | 29 ++
+ .../unixproxy/nsUnixSystemProxySettings.cpp | 31 +-
toolkit/xre/moz.build | 2 +
toolkit/xre/nsKDEUtils.cpp | 286 ++++++++++++++++++
toolkit/xre/nsKDEUtils.h | 53 ++++
@@ -34,12 +34,12 @@ Co-authored-by: Björn Bidar <bjorn.bidar@thaodan.de>
uriloader/exthandler/unix/nsMIMEInfoUnix.cpp | 28 +-
.../exthandler/unix/nsOSHelperAppService.cpp | 10 +-
widget/gtk/moz.build | 1 +
- widget/gtk/nsFilePicker.cpp | 230 +++++++++++++-
+ widget/gtk/nsFilePicker.cpp | 225 +++++++++++++-
widget/gtk/nsFilePicker.h | 6 +
xpcom/components/ManifestParser.cpp | 10 +
xpcom/components/moz.build | 1 +
xpcom/io/nsLocalFileUnix.cpp | 20 +-
- 24 files changed, 910 insertions(+), 36 deletions(-)
+ 24 files changed, 905 insertions(+), 38 deletions(-)
create mode 100644 toolkit/xre/nsKDEUtils.cpp
create mode 100644 toolkit/xre/nsKDEUtils.h
create mode 100644 uriloader/exthandler/unix/nsCommonRegistry.cpp
@@ -48,10 +48,10 @@ Co-authored-by: Björn Bidar <bjorn.bidar@thaodan.de>
create mode 100644 uriloader/exthandler/unix/nsKDERegistry.h
diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp
-index 7860eaa60179d6e5e0952ad0ec75e38b37d8d1b7..a8358199720719f2d5aaff91e30307b752ca0d85 100644
+index 5b7df133cdeaacffaa1e8e208206589d5e92d574..dc66b1d0b47586a76555c509ac4abbad13739ea1 100644
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
-@@ -96,6 +96,7 @@
+@@ -97,6 +97,7 @@
#ifdef MOZ_BACKGROUNDTASKS
# include "mozilla/BackgroundTasks.h"
#endif
@@ -60,7 +60,7 @@ index 7860eaa60179d6e5e0952ad0ec75e38b37d8d1b7..a8358199720719f2d5aaff91e30307b7
#ifdef DEBUG
# include <map>
diff --git a/modules/libpref/moz.build b/modules/libpref/moz.build
-index 3e835d422cfdfb07410b01e834bee2973ae30c57..ce58aec8ef07acf971290174b9ee5c172b1fdccd 100644
+index 3a3751c7b85cb1126f56bab29633931d91d46f35..64f48563af0b53c24c3a0bd77f2ff41bbdf4c63e 100644
--- a/modules/libpref/moz.build
+++ b/modules/libpref/moz.build
@@ -126,6 +126,10 @@ UNIFIED_SOURCES += [
@@ -99,7 +99,7 @@ index 14c11d4c1daa8cbb03abf3cd2e1a7b60a981abc8..41b9969e7277fa2400f299863c831453
def __init__(self, base, *flags):
diff --git a/toolkit/components/downloads/moz.build b/toolkit/components/downloads/moz.build
-index 3818e8c0db1ed3cfc068d89b18b1fe2f1bf750a9..b70986db811191952919531cfb79e04b801491a2 100644
+index a6eea0a2d4448122dfd54e65d66d036871c32c11..34d419c6a3ce87131db0dda8c9173dabb0609fd0 100644
--- a/toolkit/components/downloads/moz.build
+++ b/toolkit/components/downloads/moz.build
@@ -51,5 +51,9 @@ if CONFIG["MOZ_PLACES"]:
@@ -113,10 +113,10 @@ index 3818e8c0db1ed3cfc068d89b18b1fe2f1bf750a9..b70986db811191952919531cfb79e04b
with Files("**"):
BUG_COMPONENT = ("Toolkit", "Downloads API")
diff --git a/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs b/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs
-index 66f77d38e4ed7b3802303194e8df675a5db81272..f8839c446683620d6df6c6eb2ea0a0ca3549af95 100644
+index 01d1a518d8e43fca1c5ea1b0d60e49d8c3a7b17b..8b08e363137d0cb5e17ba0e9cf072d6fbaf4a00c 100644
--- a/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs
+++ b/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs
-@@ -1246,26 +1246,56 @@ nsUnknownContentTypeDialog.prototype = {
+@@ -1232,26 +1232,56 @@ nsUnknownContentTypeDialog.prototype = {
this.chosenApp = params.handlerApp;
}
} else if ("@mozilla.org/applicationchooser;1" in Cc) {
@@ -194,7 +194,7 @@ index 66f77d38e4ed7b3802303194e8df675a5db81272..f8839c446683620d6df6c6eb2ea0a0ca
var nsIFilePicker = Ci.nsIFilePicker;
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
diff --git a/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp b/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
-index 185dc1e22a903cec95b212d1713dddf764b9b198..bdb4ed6f9f86583d02dd80278f858d064584f82a 100644
+index ceba4f73cba051cea517a0988667de74d6b3172e..730afcf34f800042ca43f21e58eeedc93b137066 100644
--- a/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
+++ b/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
@@ -16,6 +16,8 @@
@@ -215,7 +215,7 @@ index 185dc1e22a903cec95b212d1713dddf764b9b198..bdb4ed6f9f86583d02dd80278f858d06
};
NS_IMPL_ISUPPORTS(nsUnixSystemProxySettings, nsISystemProxySettings)
-@@ -397,6 +401,9 @@ nsresult nsUnixSystemProxySettings::GetProxyForURI(const nsACString& aSpec,
+@@ -394,6 +398,9 @@ nsresult nsUnixSystemProxySettings::GetProxyForURI(const nsACString& aSpec,
const nsACString& aHost,
const int32_t aPort,
nsACString& aResult) {
@@ -225,10 +225,13 @@ index 185dc1e22a903cec95b212d1713dddf764b9b198..bdb4ed6f9f86583d02dd80278f858d06
if (mProxySettings) {
nsresult rv = GetProxyFromGSettings(aScheme, aHost, aPort, aResult);
if (NS_SUCCEEDED(rv)) return rv;
-@@ -405,6 +412,28 @@ nsresult nsUnixSystemProxySettings::GetProxyForURI(const nsACString& aSpec,
- return GetProxyFromEnvironment(aScheme, aHost, aPort, aResult);
- }
-
+@@ -405,11 +412,31 @@ nsresult nsUnixSystemProxySettings::GetProxyForURI(const nsACString& aSpec,
+ NS_IMETHODIMP
+ nsUnixSystemProxySettings::GetSystemWPADSetting(bool* aSystemWPADSetting) {
+ *aSystemWPADSetting = false;
++ return NS_OK;
++}
++
+nsresult nsUnixSystemProxySettings::GetProxyFromKDE(const nsACString& aScheme,
+ const nsACString& aHost,
+ PRInt32 aPort,
@@ -248,14 +251,16 @@ index 185dc1e22a903cec95b212d1713dddf764b9b198..bdb4ed6f9f86583d02dd80278f858d06
+ if (!nsKDEUtils::command(command, &result) || result.Length() != 1)
+ return NS_ERROR_FAILURE;
+ aResult = result[0];
-+ return NS_OK;
-+}
-+
+ return NS_OK;
+ }
+
NS_IMPL_COMPONENT_FACTORY(nsUnixSystemProxySettings) {
auto result = MakeRefPtr<nsUnixSystemProxySettings>();
- result->Init();
+- result->Init();
+- return result.forget().downcast<nsISupports>();
+ }
diff --git a/toolkit/xre/moz.build b/toolkit/xre/moz.build
-index 9a76d1f580c08fafe6b3ab53669cb2ee6c289d12..80416ff1b4edeba2d90c934f2e8a5a519aaed041 100644
+index 778ea4415150708fc1f977283b4ace4aee2b7141..2370ad1581e3027613a4700229a9f94e93f6af0c 100644
--- a/toolkit/xre/moz.build
+++ b/toolkit/xre/moz.build
@@ -96,7 +96,9 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "uikit":
@@ -620,7 +625,7 @@ index 0000000000000000000000000000000000000000..7fa6eb8e83b32c8e2c62a0035d253e06
+
+#endif // nsKDEUtils
diff --git a/uriloader/exthandler/HandlerServiceParent.cpp b/uriloader/exthandler/HandlerServiceParent.cpp
-index ab77657dd5f378af0955c43ef958a8abea620134..18b4d85560699bbc3c69b82ee91dfb5cbe700e7b 100644
+index 1c83d9628f8ccbffd2d59f5f5b47f87935a4c46a..fc11218439b60048a7bd7919d003af21385013d7 100644
--- a/uriloader/exthandler/HandlerServiceParent.cpp
+++ b/uriloader/exthandler/HandlerServiceParent.cpp
@@ -18,7 +18,7 @@
@@ -632,7 +637,7 @@ index ab77657dd5f378af0955c43ef958a8abea620134..18b4d85560699bbc3c69b82ee91dfb5c
#endif
using mozilla::dom::ContentHandlerService;
-@@ -310,8 +310,8 @@ mozilla::ipc::IPCResult HandlerServiceParent::RecvExistsForProtocolOS(
+@@ -314,8 +314,8 @@ mozilla::ipc::IPCResult HandlerServiceParent::RecvExistsForProtocolOS(
}
#ifdef MOZ_WIDGET_GTK
// Check the GNOME registry for a protocol handler
@@ -644,7 +649,7 @@ index ab77657dd5f378af0955c43ef958a8abea620134..18b4d85560699bbc3c69b82ee91dfb5c
*aHandlerExists = false;
#endif
diff --git a/uriloader/exthandler/moz.build b/uriloader/exthandler/moz.build
-index cb96c690a69a87a95dc28cc4903cd84718c324af..164c06c8d186f7af445fa5bd5c08757b1c89e7fd 100644
+index e9009eb063c2a317beb72f3a8a0d6d2da4b52819..fd616bb3a0b5abb48f7f786ead53813b384ecbd9 100644
--- a/uriloader/exthandler/moz.build
+++ b/uriloader/exthandler/moz.build
@@ -86,7 +86,9 @@ else:
@@ -657,7 +662,7 @@ index cb96c690a69a87a95dc28cc4903cd84718c324af..164c06c8d186f7af445fa5bd5c08757b
"unix/nsMIMEInfoUnix.cpp",
]
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "android":
-@@ -134,6 +136,7 @@ LOCAL_INCLUDES += [
+@@ -135,6 +137,7 @@ LOCAL_INCLUDES += [
"/dom/ipc",
"/netwerk/base",
"/netwerk/protocol/http",
@@ -870,10 +875,10 @@ index 0000000000000000000000000000000000000000..c6a41b331b2b5ead6142171f08d8b8a7
+
+#endif // nsKDERegistry_h__
diff --git a/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp b/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
-index 330c4411597f1a19105601e256a2c3bc71c61780..c96c1f3ca5a05c3b6bce321d7a975aa040865fa8 100644
+index 038ba672d940bf897551618874dfa6fe52ac0c1c..265d7ef19e73c3b17357eedebda033e9ff04bf8f 100644
--- a/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
+++ b/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
-@@ -5,16 +5,19 @@
+@@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsMIMEInfoUnix.h"
@@ -882,6 +887,7 @@ index 330c4411597f1a19105601e256a2c3bc71c61780..c96c1f3ca5a05c3b6bce321d7a975aa0
#include "nsIGIOService.h"
#include "nsNetCID.h"
#include "nsIIOService.h"
+@@ -14,9 +14,12 @@
#ifdef MOZ_ENABLE_DBUS
# include "nsDBusHandlerApp.h"
#endif
@@ -894,8 +900,8 @@ index 330c4411597f1a19105601e256a2c3bc71c61780..c96c1f3ca5a05c3b6bce321d7a975aa0
+ return nsCommonRegistry::LoadURL(aURI);
}
- NS_IMETHODIMP
-@@ -29,15 +32,15 @@ nsMIMEInfoUnix::GetHasDefaultHandler(bool* _retval) {
+ NS_IMETHODIMP nsMIMEInfoUnix::GetDefaultExecutable(nsIFile** aExecutable) {
+@@ -42,15 +45,15 @@ nsMIMEInfoUnix::GetHasDefaultHandler(bool* _retval) {
*_retval = false;
if (mClass == eProtocolInfo) {
@@ -914,7 +920,7 @@ index 330c4411597f1a19105601e256a2c3bc71c61780..c96c1f3ca5a05c3b6bce321d7a975aa0
}
}
if (mimeInfo) *_retval = true;
-@@ -59,6 +62,21 @@ nsresult nsMIMEInfoUnix::LaunchDefaultWithFile(nsIFile* aFile) {
+@@ -72,6 +75,21 @@ nsresult nsMIMEInfoUnix::LaunchDefaultWithFile(nsIFile* aFile) {
nsAutoCString nativePath;
aFile->GetNativePath(nativePath);
@@ -937,7 +943,7 @@ index 330c4411597f1a19105601e256a2c3bc71c61780..c96c1f3ca5a05c3b6bce321d7a975aa0
if (!giovfs) {
return NS_ERROR_FAILURE;
diff --git a/uriloader/exthandler/unix/nsOSHelperAppService.cpp b/uriloader/exthandler/unix/nsOSHelperAppService.cpp
-index 7f6eaa46f2ee0d5155b83bfb07d8040584935772..f7627e790c47e1ae007b072b4bb47b18de1ae417 100644
+index fcc2e9f5aba3f76c0c3fea8349d388dc4a1da173..82a892672fd17a4691ee58d9eac3ca5674957d5b 100644
--- a/uriloader/exthandler/unix/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/unix/nsOSHelperAppService.cpp
@@ -10,7 +10,7 @@
@@ -986,10 +992,10 @@ index 7f6eaa46f2ee0d5155b83bfb07d8040584935772..f7627e790c47e1ae007b072b4bb47b18
LOG("Got MIMEInfo from GNOME registry without extensions; setting them "
"to %s\n",
diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build
-index a6ed6f7c8cd08853f4bf1e25eb658b8fb9a4cbb1..8362e17dee84e45c820ebf99397da914263bc1ef 100644
+index 87866b1a9b53c99663322bd536c4321deb539f9b..95be31d7bb7fb182321f449ac64f3341fffa5f17 100644
--- a/widget/gtk/moz.build
+++ b/widget/gtk/moz.build
-@@ -161,6 +161,7 @@ LOCAL_INCLUDES += [
+@@ -151,6 +151,7 @@ LOCAL_INCLUDES += [
"/layout/xul",
"/other-licenses/atk-1.0",
"/third_party/cups/include",
@@ -998,7 +1004,7 @@ index a6ed6f7c8cd08853f4bf1e25eb658b8fb9a4cbb1..8362e17dee84e45c820ebf99397da914
"/widget/headless",
"/widget/x11",
diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
-index d15c44d3a0bde1ae0b3c73ba6f35ace25a1c9a8b..987f23b4ea29ecfa943ce0b1646db669cd40de19 100644
+index 751da3dc6bc7ccfe58cfc9c00d7daa75ffc69894..7f5b1e96116cb6ac7b4fcfe74f247f7f6e54a6f6 100644
--- a/widget/gtk/nsFilePicker.cpp
+++ b/widget/gtk/nsFilePicker.cpp
@@ -5,6 +5,7 @@
@@ -1018,7 +1024,7 @@ index d15c44d3a0bde1ae0b3c73ba6f35ace25a1c9a8b..987f23b4ea29ecfa943ce0b1646db669
#undef LOG
#ifdef MOZ_LOGGING
-@@ -310,7 +313,8 @@ NS_IMETHODIMP
+@@ -307,7 +310,8 @@ NS_IMETHODIMP
nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter) {
if (aFilter.EqualsLiteral("..apps")) {
// No platform specific thing we can do here, really....
@@ -1028,14 +1034,13 @@ index d15c44d3a0bde1ae0b3c73ba6f35ace25a1c9a8b..987f23b4ea29ecfa943ce0b1646db669
}
nsAutoCString filter, name;
-@@ -420,6 +424,31 @@ nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
- // Can't show two dialogs concurrently with the same filepicker
- if (mRunning) return NS_ERROR_NOT_AVAILABLE;
-
+@@ -420,6 +424,26 @@ nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
+ if (MaybeBlockFilePicker(aCallback)) {
+ return NS_OK;
+ }
+ // KDE file picker is not handled via callback
+ if (nsKDEUtils::kdeSupport()) {
+ mCallback = aCallback;
-+ mRunning = true;
+ NS_ADDREF_THIS();
+ g_idle_add(
+ [](gpointer data) -> gboolean {
@@ -1048,19 +1053,15 @@ index d15c44d3a0bde1ae0b3c73ba6f35ace25a1c9a8b..987f23b4ea29ecfa943ce0b1646db669
+ } else {
+ queuedPicker->mResult = result;
+ }
-+ queuedPicker->mRunning = false;
+ NS_RELEASE(queuedPicker);
+ return G_SOURCE_REMOVE;
+ },
+ this);
-+
-+ return NS_OK;
+ }
-+
+
NS_ConvertUTF16toUTF8 title(mTitle);
- GtkWindow* parent_widget =
-@@ -701,6 +730,205 @@ void nsFilePicker::Done(void* file_chooser, gint response) {
+@@ -712,6 +736,205 @@ void nsFilePicker::Done(void* file_chooser, gint response) {
NS_RELEASE_THIS();
}
@@ -1267,7 +1268,7 @@ index d15c44d3a0bde1ae0b3c73ba6f35ace25a1c9a8b..987f23b4ea29ecfa943ce0b1646db669
void* nsFilePicker::GtkFileChooserNew(const gchar* title, GtkWindow* parent,
GtkFileChooserAction action,
diff --git a/widget/gtk/nsFilePicker.h b/widget/gtk/nsFilePicker.h
-index 7ec93a6694276b3622dbd2d5ba0ececa262b221c..c2571d314c59c3b6d8d70cd65534c9b5818ee86d 100644
+index f8fc22bc97fee7ca6da0bcb2ff13f6351270604e..38e963af0db65cb83b1f1b6b35155b8e7ac6dc58 100644
--- a/widget/gtk/nsFilePicker.h
+++ b/widget/gtk/nsFilePicker.h
@@ -76,6 +76,12 @@ class nsFilePicker : public nsBaseFilePicker {
@@ -1362,11 +1363,11 @@ index 88ee06d78db60a84343fd3d23c16e163aead37c3..834d6a2d353cc1bd11916de8a28f5d05
stTablet == eBad ||
#endif
diff --git a/xpcom/components/moz.build b/xpcom/components/moz.build
-index 4a58f46da3f610e9b2f55053939235c7350fedc5..7fb012af861f20932778c59da631f663def2db34 100644
+index e62b56b44a91a335cff20cfbf21e017aa85640af..2d7bd85bbf5c9d099d2b3f2d4d19641d350ffbd5 100644
--- a/xpcom/components/moz.build
+++ b/xpcom/components/moz.build
-@@ -71,6 +71,7 @@ LOCAL_INCLUDES += [
- "/js/xpconnect/loader",
+@@ -72,6 +72,7 @@ LOCAL_INCLUDES += [
+ "/js/xpconnect/src",
"/layout/build",
"/modules/libjar",
+ "/toolkit/xre",
diff --git a/0026-Add-KDE-integration-to-Firefox.patch b/0025-Add-KDE-integration-to-Firefox.patch
index 5ef29ba6353b..82a8e3396579 100644
--- a/0026-Add-KDE-integration-to-Firefox.patch
+++ b/0025-Add-KDE-integration-to-Firefox.patch
@@ -27,10 +27,10 @@ How to apply this patch:
create mode 100644 browser/components/shell/nsUnixShellService.h
diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js
-index 201d3c32da2ddb8356ff549c83cdcc608b959222..fd5cdeef683053c6888acd78b197c689b6c65b2f 100644
+index 22bd3fe174a9b1f457ccc8548d1ce9900ffb6c4c..b6909824b731f3106a19c2d955342bb9dc2ff8f5 100644
--- a/browser/components/preferences/main.js
+++ b/browser/components/preferences/main.js
-@@ -297,6 +297,13 @@ var gMainPane = {
+@@ -298,6 +298,13 @@ var gMainPane = {
}, backoffTimes[this._backoffIndex]);
}
@@ -44,10 +44,10 @@ index 201d3c32da2ddb8356ff549c83cdcc608b959222..fd5cdeef683053c6888acd78b197c689
this.initBrowserContainers();
this.buildContentProcessCountMenuList();
-@@ -1750,6 +1757,17 @@ var gMainPane = {
- }
+@@ -1765,6 +1772,17 @@ var gMainPane = {
+
try {
- shellSvc.setDefaultBrowser(false);
+ await shellSvc.setDefaultBrowser(false);
+ if (kde_session == 1) {
+ var shellObj = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsILocalFile);
@@ -63,7 +63,7 @@ index 201d3c32da2ddb8356ff549c83cdcc608b959222..fd5cdeef683053c6888acd78b197c689
console.error(ex);
return;
diff --git a/browser/components/shell/moz.build b/browser/components/shell/moz.build
-index fbcb6b9e1070040f682c8e89c0eace7b7658dddf..d68a08c67ec4c0c03e2eb7aba43e283795803118 100644
+index 82e5afade7ba82e720bc265de1b2d4ed10b7a243..98a2724b24a8a733f656382d2c0d2f53607500f7 100644
--- a/browser/components/shell/moz.build
+++ b/browser/components/shell/moz.build
@@ -36,6 +36,8 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
diff --git a/0027-Imported-patch-firefox-branded-icons.patch.patch b/0026-Imported-patch-firefox-branded-icons.patch.patch
index fa348dad2632..e8917fd59495 100644
--- a/0027-Imported-patch-firefox-branded-icons.patch.patch
+++ b/0026-Imported-patch-firefox-branded-icons.patch.patch
@@ -9,24 +9,24 @@ Subject: [PATCH] Imported patch firefox-branded-icons.patch
2 files changed, 6 insertions(+)
diff --git a/browser/branding/branding-common.mozbuild b/browser/branding/branding-common.mozbuild
-index 4e737310b37bc0bdbe4367e51c0f245eefbdbb50..0faf21fb931a0ed72495197d2152fd74bde6455e 100644
+index a38663a3dc1ebe0c0817945efc2f72018bc1b3c7..87a2340b828173d4bc0b5b32db3fde2011887d2b 100644
--- a/browser/branding/branding-common.mozbuild
+++ b/browser/branding/branding-common.mozbuild
-@@ -30,6 +30,9 @@ def FirefoxBranding():
+@@ -31,6 +31,9 @@ def FirefoxBranding():
FINAL_TARGET_FILES.chrome.icons.default += [
- 'default128.png',
- 'default16.png',
-+ 'default22.png',
-+ 'default24.png',
-+ 'default256.png',
- 'default32.png',
- 'default48.png',
- 'default64.png',
+ "default128.png",
+ "default16.png",
++ "default22.png",
++ "default24.png",
++ "default256.png",
+ "default32.png",
+ "default48.png",
+ "default64.png",
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
-index 359fcd671f0ebeba46e2556c99ec11ce067fe23e..93c0226117cbf72a8df46c08a569af5b7900c3dd 100644
+index b9950a85c2542de599f2d2bcb6eea20a658a5727..b736a26132105911f11e3e2bd08b6b3bc225b657 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
-@@ -223,10 +223,13 @@
+@@ -217,10 +217,13 @@
@RESPATH@/chrome/toolkit.manifest
#ifdef MOZ_GTK
@RESPATH@/browser/chrome/icons/default/default16.png
diff --git a/0028-Allow-Eme-for-arm-and-Aarch64.patch b/0027-Allow-Eme-for-arm-and-Aarch64.patch
index aa3b1288527c..7c045adefda0 100644
--- a/0028-Allow-Eme-for-arm-and-Aarch64.patch
+++ b/0027-Allow-Eme-for-arm-and-Aarch64.patch
@@ -12,10 +12,10 @@ Signed-off-by: Björn Bidar <bjorn.bidar@jolla.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
-index 527925bd8784e0dd33a79e0b7d80a53f424fcf48..c3ff4bd147689024b8a0c98fcfceaca7c87ae21e 100644
+index 9d691efbc37a08131a7ab0c87aa5c7521cd7112c..948e6442c2635de5248acf97559729aa645730d2 100644
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
-@@ -869,7 +869,7 @@ def eme_choices(target, wmf):
+@@ -876,7 +876,7 @@ def eme_choices(target, wmf):
if (
target.kernel in ("WINNT", "Linux")
and target.os != "Android"
diff --git a/0029-Shut-up-warnings-about-future-Rust-version-incompati.patch b/0028-Shut-up-warnings-about-future-Rust-version-incompati.patch
index cc8f33c20a65..cc1badf6f93c 100644
--- a/0029-Shut-up-warnings-about-future-Rust-version-incompati.patch
+++ b/0028-Shut-up-warnings-about-future-Rust-version-incompati.patch
@@ -12,13 +12,13 @@ Signed-off-by: Björn Bidar <bjorn.bidar@jolla.com>
1 file changed, 5 insertions(+)
diff --git a/Cargo.toml b/Cargo.toml
-index 27886bd8ff1ec0530f63498101d2fc33ce5c0cf4..7e1fb391e9fdff1b25ae20a0a249c9c7def6eb25 100644
+index 36341dd1aeb6ce372ad20c5e73830b8314eb03db..42228d5f3dfac3da24211eef6c000bdda3849dd6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
-@@ -228,3 +228,8 @@ uniffi_bindgen = "=0.24.3"
- uniffi_build = "=0.24.3"
- uniffi_macros = "=0.24.3"
- weedle2 = "=4.0.0"
+@@ -243,3 +243,8 @@ gpu-descriptor = { git = "https://github.com/zakarumych/gpu-descriptor", rev = "
+ # There is not going to be new version of mio 0.6, mio now being >= 0.7.11.
+ [patch.crates-io.mio]
+ path = "third_party/rust/mio-0.6.23"
+
+# Package code v0.1.4 uses code "that will be rejected by a future version of Rust"
+# Shut up such messages for now to make the build succeed
diff --git a/0030-Partially-revert-Bug-1768632-Make-EnumSet-compile-fo.patch b/0029-Partially-revert-Bug-1768632-Make-EnumSet-compile-fo.patch
index 9322a4f81c12..a7d91723a85b 100644
--- a/0030-Partially-revert-Bug-1768632-Make-EnumSet-compile-fo.patch
+++ b/0029-Partially-revert-Bug-1768632-Make-EnumSet-compile-fo.patch
@@ -15,10 +15,10 @@ Signed-off-by: Björn Bidar <bjorn.bidar@jolla.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mfbt/EnumSet.h b/mfbt/EnumSet.h
-index f7765c6f5c954f133f846ff27018c888a68f2284..7721d1d1facdebb2e78b63f58a56ac94357a6395 100644
+index 712e03d3f3d9b23ada1e77e422e193c31b16d598..024fa5fdeb203b1d1053a5c35881167dcba8b55f 100644
--- a/mfbt/EnumSet.h
+++ b/mfbt/EnumSet.h
-@@ -326,7 +326,7 @@ class EnumSet {
+@@ -336,7 +336,7 @@ class EnumSet {
}
}
diff --git a/0031-Bug-1796523-Workaround-source-locations-for-function.patch b/0030-Bug-1796523-Workaround-source-locations-for-function.patch
index b5bb0fe1b4e2..67c892f2ccd5 100644
--- a/0031-Bug-1796523-Workaround-source-locations-for-function.patch
+++ b/0030-Bug-1796523-Workaround-source-locations-for-function.patch
@@ -15,10 +15,10 @@ Signed-off-by: Björn Bidar <bjorn.bidar@jolla.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build/moz.configure/lto-pgo.configure b/build/moz.configure/lto-pgo.configure
-index 879e08e7c3b1a00f8bf13cf48bfc345fc80abdb0..922610c3de0e91ff97efc3e9588e323b22440089 100644
+index 422f7e65b6dc94d223705f954682abe2046522b1..cc13fb566d419898171176d0bc2476fce34d9dda 100644
--- a/build/moz.configure/lto-pgo.configure
+++ b/build/moz.configure/lto-pgo.configure
-@@ -87,7 +87,7 @@ def pgo_flags(compiler, profdata, target_is_windows):
+@@ -134,7 +134,7 @@ def pgo_flags(
return namespace(
gen_cflags=["-fprofile-generate"],
gen_ldflags=["-fprofile-generate"],
diff --git a/0032-Bug-1822730-Add-basic-blob-protocol-handling-for-blo.patch b/0031-Bug-1822730-Add-basic-blob-protocol-handling-for-blo.patch
index 76d06bba9029..c2a864754189 100644
--- a/0032-Bug-1822730-Add-basic-blob-protocol-handling-for-blo.patch
+++ b/0031-Bug-1822730-Add-basic-blob-protocol-handling-for-blo.patch
@@ -5,14 +5,14 @@ Subject: [PATCH] Bug 1822730 - Add basic blob protocol handling for blob URIs
that contain parsable http/s protocols
---
- .../mozapps/downloads/DownloadLastDir.sys.mjs | 17 +++++++++++++++--
- 1 file changed, 15 insertions(+), 2 deletions(-)
+ toolkit/mozapps/downloads/DownloadLastDir.sys.mjs | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/toolkit/mozapps/downloads/DownloadLastDir.sys.mjs b/toolkit/mozapps/downloads/DownloadLastDir.sys.mjs
-index 9fe90a0ecdc533593001d9a2763f8a21f393ce7d..2a2f524716c909dfa3f04b649b9f078fecd3d1f9 100644
+index dfd5d2cd26e7622bccc90e99e82a0c82e194376c..23e5deed63d8acb6cda0713ae6c371316a3e9879 100644
--- a/toolkit/mozapps/downloads/DownloadLastDir.sys.mjs
+++ b/toolkit/mozapps/downloads/DownloadLastDir.sys.mjs
-@@ -221,11 +221,13 @@ export class DownloadLastDir {
+@@ -221,8 +221,8 @@ export class DownloadLastDir {
/**
* Pre-processor to extract a domain name to be used with the content-prefs
@@ -23,12 +23,7 @@ index 9fe90a0ecdc533593001d9a2763f8a21f393ce7d..2a2f524716c909dfa3f04b649b9f078f
* - all file:/// URIs share the same folder
* - data: URIs share a folder per mime-type. If a mime-type is not
* specified text/plain is assumed.
-+ * - blob: blob URIs are tested for http/https and the blob protocol
-+ * is stripped.
- * In any other case the original URL is returned as a string and ContentPrefs
- * will do its usual parsing.
- *
-@@ -234,6 +236,9 @@ export class DownloadLastDir {
+@@ -236,6 +236,9 @@ export class DownloadLastDir {
*/
#cpsGroupFromURL(url) {
if (typeof url == "string") {
@@ -38,7 +33,7 @@ index 9fe90a0ecdc533593001d9a2763f8a21f393ce7d..2a2f524716c909dfa3f04b649b9f078f
url = new URL(url);
} else if (url instanceof Ci.nsIURI) {
url = URL.fromURI(url);
-@@ -241,6 +246,14 @@ export class DownloadLastDir {
+@@ -243,6 +246,14 @@ export class DownloadLastDir {
if (!URL.isInstance(url)) {
return url;
}
diff --git a/0032-Bug-1862601-Part-12-Add-new-line-break-classes.-r.patch b/0032-Bug-1862601-Part-12-Add-new-line-break-classes.-r.patch
new file mode 100644
index 000000000000..b8ca9f7d451f
--- /dev/null
+++ b/0032-Bug-1862601-Part-12-Add-new-line-break-classes.-r.patch
@@ -0,0 +1,28 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Andr=C3=A9=20Bargull?= <andre.bargull@gmail.com>
+Date: Mon, 16 Oct 2023 08:58:43 +0300
+Subject: [PATCH] Bug 1862601 - Part 12: Add new line break classes. r?
+
+---
+ intl/lwbrk/LineBreaker.cpp | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/intl/lwbrk/LineBreaker.cpp b/intl/lwbrk/LineBreaker.cpp
+index 6f73035f42cbb729f26a752d83349415257f113e..29bde665ce18c1a9aa907138ec167f65173769c8 100644
+--- a/intl/lwbrk/LineBreaker.cpp
++++ b/intl/lwbrk/LineBreaker.cpp
+@@ -448,7 +448,13 @@ static int8_t GetClass(uint32_t u, LineBreakRule aLevel,
+ /* REGIONAL_INDICATOR = 39, [RI] */ CLASS_CHARACTER,
+ /* E_BASE = 40, [EB] */ CLASS_BREAKABLE,
+ /* E_MODIFIER = 41, [EM] */ CLASS_CHARACTER,
+- /* ZWJ = 42, [ZWJ]*/ CLASS_CHARACTER};
++ /* ZWJ = 42, [ZWJ]*/ CLASS_CHARACTER,
++ /* AKSARA = 43, [AK] */ CLASS_CHARACTER,
++ /* AKSARA_PREBASE = 44, [AP] */ CLASS_CHARACTER,
++ /* AKSARA_START = 45, [AS] */ CLASS_CHARACTER,
++ /* VIRAMA_FINAL = 46, [VF] */ CLASS_CHARACTER,
++ /* VIRAMA = 47, [VI] */ CLASS_CHARACTER,
++ };
+
+ static_assert(U_LB_COUNT == mozilla::ArrayLength(sUnicodeLineBreakToClass),
+ "Gecko vs ICU LineBreak class mismatch");
diff --git a/PKGBUILD b/PKGBUILD
index d66b25f0e0ac..697959afb5cb 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -13,7 +13,7 @@ _pgo=true
_pkgname=firefox
pkgname=$_pkgname-kde-opensuse
-pkgver=121.0.1
+pkgver=127.0
pkgrel=1
pkgdesc="Standalone web browser from mozilla.org with OpenSUSE patch, integrate better with KDE"
arch=('i686' 'x86_64')
@@ -26,7 +26,7 @@ depends=('libxt' 'mime-types'
)
makedepends=('unzip' 'zip' 'diffutils' 'yasm' 'mesa' 'imake'
- 'xorg-server-xvfb' 'libpulse' 'inetutils' 'autoconf2.13'
+ 'xorg-server-xvfb' 'libpulse' 'inetutils'
'cargo' 'mercurial' 'llvm' 'clang' 'rust' 'jack'
'nodejs' 'cbindgen' 'nasm' 'xz'
'python' 'python-zstandard' 'dump_syms'
@@ -91,16 +91,16 @@ source=(https://archive.mozilla.org/pub/firefox/releases/$pkgver/source/firefox-
0020-Bug-847568-Support-system-harfbuzz.patch
0021-Bug-847568-Support-system-graphite2.patch
0022-Bug-1611386-Reenable-support-for-enable-system-sqlit.patch
- 0023-Bug-1419151-Add-Unity-menubar-support.patch
- 0024-Do-not-use-gconf-for-proxy-settings-if-not-running-w.patch
- 0025-Add-KDE-integration-to-Firefox-toolkit-parts.patch
- 0026-Add-KDE-integration-to-Firefox.patch
- 0027-Imported-patch-firefox-branded-icons.patch.patch
- 0028-Allow-Eme-for-arm-and-Aarch64.patch
- 0029-Shut-up-warnings-about-future-Rust-version-incompati.patch
- 0030-Partially-revert-Bug-1768632-Make-EnumSet-compile-fo.patch
- 0031-Bug-1796523-Workaround-source-locations-for-function.patch
- 0032-Bug-1822730-Add-basic-blob-protocol-handling-for-blo.patch
+ 0023-Do-not-use-gconf-for-proxy-settings-if-not-running-w.patch
+ 0024-Add-KDE-integration-to-Firefox-toolkit-parts.patch
+ 0025-Add-KDE-integration-to-Firefox.patch
+ 0026-Imported-patch-firefox-branded-icons.patch.patch
+ 0027-Allow-Eme-for-arm-and-Aarch64.patch
+ 0028-Shut-up-warnings-about-future-Rust-version-incompati.patch
+ 0029-Partially-revert-Bug-1768632-Make-EnumSet-compile-fo.patch
+ 0030-Bug-1796523-Workaround-source-locations-for-function.patch
+ 0031-Bug-1822730-Add-basic-blob-protocol-handling-for-blo.patch
+ 0032-Bug-1862601-Part-12-Add-new-line-break-classes.-r.patch
)
validpgpkeys=(
@@ -262,40 +262,40 @@ Version=2
END
}
-sha256sums=('b3a4216e01eaeb9a7c6ef4659d8dcd956fbd90a78a8279ee3a598881e63e49ce'
+sha256sums=('ea6b089ff046ca503978fdaf11ea123c64f66bbcdc4a968bed8f7c93e9994321'
'SKIP'
'be65b2421999ad5c8ffa363dc009ce2cd291badc422fbb456967616bad3e2e19'
'4c93b2e1f1675e033ed7910fe5f379626a92903a940697430985bcfdf94afceb'
'eaad0eee76f89e0a1a241742ec5c8ec9315b096f7b3e0ea302b253b926750aae'
- 'c3c785256e7497118e9e19de4c1748664e8df5930a436040f029023a1190a9a5'
+ 'c9fc92d2e91d853e91af8263d71960e6c23c9ff005e139e2fa13a255f16a9a64'
'eb19d9568e8d7705b2a0c4774d4f6a758a910c0e5cf427727feb5884a2a1ee98'
'4322124dc370ac56063837370a8107e85ca6e0d4037ff71ece5e7b0f55ed8053'
- 'a8aeb8b73abe711752ebf1a561fb4af736854be5c298441b8de7a1148a47a416'
- '111fa1040408cccf0ea52c59028ddd06bae52adc2d3387a8fc2ff89a8b6590f9'
+ '2bf113fa4eebe0177bb418c187a5d077c1760bb1b788059f444c483d79df8e4d'
+ '6b0c60632691f345969f0b6759428cc2d9fb8f7d7570e6d76141f6855b9bcbf4'
'999f0f5c198f00943894639d9dd4157f3e078a40e1f8a815aef2dacd5158a67c'
'bba76c5e13952ef45362f8e53a5c030e0f5d722f8f266228787136a5312330ea'
'f2fcd4ca82b833f5e5b7e991882e24f09463cd837242b18cf163bc751f2e21d5'
'766faefbd4898049e9913589962bf839da6785d50f0631b4eac7316f16bf2ea6'
'1cad951e7ff0073c9b5462fa9c4d8ead78d6d494286092b5d23a6fa5949259ef'
- '5109d3113dbf3e8e584ff2107be50bbb8d04927329b1dba3c7c08308e2ddc42e'
- '32d40630a010ee91d2c35c814ef2f567ad7faf859f8198735829958cb055f53b'
+ '385b77d458d02675ad791029fceb0d4168368f7aff68a7a8586f0a36d8a52c46'
+ '6145dc18238fca575dbbe65a3c244984cb132c0a08a02520af036bf77144b7c1'
'1ffdcff3d4e31c5cceddadfa0111c27a34480594238cdf85866ee1073d922910'
'3144c2f38c9e60ba00f231e7a8051ca41cdc5d9f542c0144f4549f525a8c129f'
'5ee703cddba6045a03ee882ff70423fe185d009e2c912fc49ef66f7703ea46fe'
- '2400173d2c84573194c6af9031663a5b2332ccb4929b246b216c61c97d8b0a54'
- '469065ad1535e0798f8e1a3dc3285cbbb003ed12c62af5d6b9e1184e9383b5f8'
- '72d30acbe1e8488c6bd3af2e0813223842a63b859d6e7aff66d2f23612b7ad8b'
- '2a54aedc86f72dfe070b8f7a609a09b20f44fb90cf6add94ac451067dbe379d1'
- '4f4f08bee921a1c0a78272cf08ff3e198895074e892aba8c172e7e12a97eaac6'
- '057f4c0dd6c0564438fecf909eb5365714f633416f438fb8b7a8e4b8356347ed'
- '6b2156bc3a0c8ae138a257dabe89ff6eac778f0230edb43b8f68eb659ae11ef3'
- 'ce4ebd0b0bf19a292c6d4f199e05878b67bc45ec040916bcc84c50bb87367243'
- 'dfb11575e7d43071c9046762408b7267507c645020678d57689d55d3f68c0c28'
- 'abfd58b5296c16642a99e0dba7f27366d6b532306e13458d7d9d1217344f7108'
- 'e6c33e08d0c839723a2379337251ab23bdb26a92edd9d5910986cf0301b3bd08'
- 'c264af7b086701e5c76b47e87e4cd79ddb424e4ec6e87f81592c7ea1a37ace3a'
- 'ce292fde34263f5dfd649b0b849c8f47cc5762acf8e5735e57ec8e453c2f14c1'
- '329bd252104fcfa21f68256dec589858fc63354c56dc57f7d4d84ee32c5310f1'
- '7038651e09bd1f1cf2561ee977e6fcc58f7295ce821f419288da6d0b2bcc8feb'
- '0d7a0f8bd7f0a8f1319d79a433d848a3eb43e81f4a14f29d5c8602be49d93cb9'
- 'ca63e1a8b93eed45fe1b6dc4da087d18b866570d99cfc6abfb8a7d3187d98e83')
+ '942c0f66b2ab1123760384accc056b54dab9467d3094d52c9f35b263ddfc4e11'
+ 'c898be9b4afa0f3fc4542efadd55a5947004a84cf3c8863a870f2ab1b4c7b056'
+ '54463246e5cfb36846907ea7924b3e43546ff55980de16517f4ff52e999765de'
+ '40302cef8ec83d12b95404ef3338e91a0166351462e4cccb14c192698198c88f'
+ 'b73389e1da6a8d8de3ebe1bf337c3777f6f815b2fd30102fb7a387d11f1d86f5'
+ '7da9a82f78fa3120c3dea8c1b7fe1889e62a3639412bf8b6aa646716e728bcf5'
+ '5f2bf078c4424271fb2ff999cf1bd7960faf9022e67f5f50ad0918b7216fb1e9'
+ 'a983f79d0a9c8b17ce3271250dd61e49a2ea9e70bf526f4f586fb5e17c01fcba'
+ '1d7a32f97d0bb54d6da48b5e858c119891888807c82a78146c78798269fb4307'
+ '1efc94925aa7ca4d46e94462cb9a1ca64d130209fff70cfe142647f3d20f16b9'
+ '6dd444248443d360dcc0d8821d65cd341f3026d44258c0149dbd4e63ea7617b0'
+ '8738417b180fcbc59c1314c1bd5da87b53e54851ef6f8e50c53ad597d5bd69d2'
+ 'faea2c6d22f755657a71996c41f92473015af57d5dee5600d0d2ec3096b49102'
+ 'c053fab26e784e081018254a875cc2656a34318075753c7c1e40bb2822c5bf53'
+ 'a3c56cf14d2e4d5f4872091bb5a9b765bcc60b3b1a301bef8e123af7a7182698'
+ '8531ed52332e4290b4c1c9552236689cc8b250855ae20365eac44e1cbc7a9504'
+ 'b08459d49f5fb22353e70f0c96a772ea9aa9e832b6ee9ecb02e564a858f9f52e')
diff --git a/firefox-kde-opensuse.changes b/firefox-kde-opensuse.changes
index c98cbe9dfc82..d81e39cf2d27 100644
--- a/firefox-kde-opensuse.changes
+++ b/firefox-kde-opensuse.changes
@@ -1,4 +1,461 @@
-------------------------------------------------------------------
+Tue Jun 11 09:21:24 UTC 2024 - Wolfgang Rosenauer <wr@rosenauer.org>
+
+- Mozilla Firefox 127.0
+ https://www.mozilla.org/en-US/firefox/127.0/releasenotes
+ MFSA 2024-25 (bsc#1226027)
+ * CVE-2024-5687 (bmo#1889066)
+ An incorrect principal could have been used when opening new tabs
+ * CVE-2024-5688 (bmo#1895086)
+ Use-after-free in JavaScript object transplant
+ * CVE-2024-5689 (bmo#1389707)
+ User confusion and possible phishing vector via Firefox Screenshots
+ * CVE-2024-5690 (bmo#1883693)
+ External protocol handlers leaked by timing attack
+ * CVE-2024-5691 (bmo#1888695)
+ Sandboxed iframes were able to bypass sandbox restrictions to
+ open a new window
+ * CVE-2024-5692 (bmo#1837514, bmo#1891234)
+ Bypass of file name restrictions during saving
+ * CVE-2024-5693 (bmo#1891319)
+ Cross-Origin Image leak via Offscreen Canvas
+ * CVE-2024-5694 (bmo#1895055)
+ Use-after-free in JavaScript Strings
+ * CVE-2024-5695 (bmo#1895579)
+ Memory Corruption using allocation using out-of-memory conditions
+ * CVE-2024-5696 (bmo#1896555)
+ Memory Corruption in Text Fragments
+ * CVE-2024-5697 (bmo#1414937)
+ Website was able to detect when Firefox was taking a
+ screenshot of them
+ * CVE-2024-5698 (bmo#1828259)
+ Data-list could have overlaid address bar
+ * CVE-2024-5699 (bmo#1891349)
+ Cookie prefixes not treated as case-sensitive
+ * CVE-2024-5700 (bmo#1862809, bmo#1889355, bmo#1893388, bmo#1895123)
+ Memory safety bugs fixed in Firefox 127, Firefox ESR 115.12,
+ and Thunderbird 115.12
+ * CVE-2024-5701 (bmo#1890909, bmo#1891422, bmo#1893915,
+ bmo#1894047, bmo#1896024)
+ Memory safety bugs fixed in Firefox 127
+- removed obsolete mozilla-bmo1886378.patch
+
+-------------------------------------------------------------------
+Wed May 29 06:05:07 UTC 2024 - Wolfgang Rosenauer <wr@rosenauer.org>
+
+- Mozilla Firefox 126.0.1
+ * Fixed an issue with reading tagged PDF documents in a screen reader
+ bmo#1894849
+ * Fixed not displaying localized text for non-en-US locales in the
+ Crash Reporter dialog box on macOS. (bmo#1896097)
+ * Fixed issues with drag-and-drop functionality on Linux. (bmo#1897115)
+ * Fixed an issue causing high GPU memory usage on certain versions
+ of AMD cards. (bmo#1897006)
+
+-------------------------------------------------------------------
+Tue May 28 15:05:14 UTC 2024 - Guillaume GARDET <guillaume.gardet@opensuse.org>
+
+- Backport upstream patches to fix build on aarch64 - boo#1225460
+ * mozilla-bmo1886378.patch
+
+-------------------------------------------------------------------
+Wed May 15 08:46:30 UTC 2024 - Wolfgang Rosenauer <wr@rosenauer.org>
+
+- Mozilla Firefox 126.0
+ https://www.mozilla.org/en-US/firefox/126.0/releasenotes
+ MFSA 2024-21 (bsc#1224056)
+ * CVE-2024-4764 (bmo#1879093)
+ Use-after-free when audio input connected with multiple consumers
+ * CVE-2024-4367 (bmo#1893645)
+ Arbitrary JavaScript execution in PDF.js
+ * CVE-2024-4765 (bmo#1871109)
+ Web application manifests could have been overwritten via
+ hash collision
+ * CVE-2024-4766 (bmo#1871214, bmo#1871217)
+ Fullscreen notification could have been obscured on Firefox
+ for Android
+ * CVE-2024-4767 (bmo#1878577)
+ IndexedDB files retained in private browsing mode
+ * CVE-2024-4768 (bmo#1886082)
+ Potential permissions request bypass via clickjacking
+ * CVE-2024-4769 (bmo#1886108)
+ Cross-origin responses could be distinguished between script
+ and non-script content-types
+ * CVE-2024-4770 (bmo#1893270)
+ Use-after-free could occur when printing to PDF
+ * CVE-2024-4771 (bmo#1893891)
+ Failed allocation could lead to use-after-free
+ * CVE-2024-4772 (bmo#1870579)
+ Use of insecure rand() function to generate nonce
+ * CVE-2024-4773 (bmo#1875248)
+ URL bar could be cleared after network error
+ * CVE-2024-4774 (bmo#1886598)
+ Undefined behavior in ShmemCharMapHashEntry()
+ * CVE-2024-4775 (bmo#1887332)
+ Invalid memory access in the built-in profiler
+ * CVE-2024-4776 (bmo#1887343)
+ Window may remain disabled after file dialog is shown in
+ full-screen
+ * CVE-2024-4777 (bmo#1878199, bmo#1893340)
+ Memory safety bugs fixed in Firefox 126, Firefox ESR 115.11,
+ and Thunderbird 115.11
+ * CVE-2024-4778 (bmo#1838834, bmo#1889291, bmo#1889595,
+ bmo#1890204, bmo#1891545)
+ Memory safety bugs fixed in Firefox 126
+- requires NSS 3.100
+- removed obsolete mozilla-libproxy-fix.patch
+
+-------------------------------------------------------------------
+Mon Apr 29 18:17:48 UTC 2024 - Andreas Stieger <andreas.stieger@gmx.de>
+
+- Mozilla Firefox 125.0.3
+ * Fixed: Fixed an extra blank tab with an address of
+ `https://0.0.0.1` sometimes appearing when attempting to
+ launch Firefox when it is already running (bmo#1892612).
+ * Fixed: Fixed an issue that could cause incorrect font
+ selection in some situations for users with the Japanese
+ locale set (bmo#1892363).
+ * Fixed: Fixed text corruption when dragging text containing
+ unicode characters on Linux systems (bmo#1888202).
+ * Fixed: Fixed a correctness error when checking
+ `arguments.length` (and not using arguments otherwise) inside
+ of a generator or async function (bmo#1892699).
+ * Fixed: Fixed an issue that could lead to inconsistent focus
+ handling of `<select>` elements when opened (bmo#1893177).
+
+-------------------------------------------------------------------
+Wed Apr 24 08:43:53 UTC 2024 - Manfred Hollstein <manfred.h@gmx.net>
+
+- Fix build on Leap by requiring gcc13 which has been made available
+ as an update.
+
+-------------------------------------------------------------------
+Sun Apr 21 04:49:23 UTC 2024 - Wolfgang Rosenauer <wr@rosenauer.org>
+
+- Mozilla Firefox 125.0.2
+ * The 125.0 and 125.0.1 releases were skipped due to problems
+ with a feature that proactively blocked downloads from
+ potentially untrustworthy URLs.
+ * New: Firefox now supports the AV1 codec for Encrypted Media
+ Extensions (EME), enabling higher-quality playback from video
+ streaming providers
+ * New: The Firefox PDF viewer now supports text highlighting.
+ * New: Firefox View now displays pinned tabs in the Open tabs
+ section. Tab indicators have also been added to Open tabs, so
+ users can do things like see which tabs are playing media and
+ quickly mute or unmute across windows. Indicators were also
+ added for bookmarks, tabs with notifications, and more!
+ their addresses upon submitting an address form, allowing
+ Firefox to autofill stored address information in the future.
+ * New: The URL Paste Suggestion feature provides a convenient
+ way for users to quickly visit URLs copied to the clipboard
+ in the address bar of Firefox. When the clipboard contains a
+ URL and the URL bar is focused, an autocomplete result
+ appears automatically. Activating the clipboard suggestion
+ will navigate the user to the URL with 1 click.
+ * New: Users of tab-specific Container add-ons can now search
+ in the Address Bar for tabs that are open in different
+ containers. Special thanks to volunteer contributor atararx
+ for kicking off the work on this feature!
+ * New: Firefox now provides an option to enable Web Proxy Auto-
+ Discovery (WPAD) while configured to use system proxy
+ settings.
+ * Changed: In a group of radio buttons where no option is
+ selected, the tab key now only reaches the first option
+ rather than cycling through all available options. The arrow
+ keys navigate between options as they do when there is a
+ selected option. This makes keyboard navigation more
+ efficient and consistent
+ * HTML5: Firefox now supports the `popover` global attribute
+ used for designating an element as a popover element. The
+ element won't be rendered until it is made visible, after
+ which it will appear on top of other page content.
+ * HTML5: WebAssembly multi-memory is now enabled by default.
+ Wasm multi-memory allows wasm modules to use and import
+ multiple independent linear memories. This enables more
+ efficient interoperability between modules and provides
+ better polyfills for upcoming wasm standards, such as the
+ component model.
+ * HTML5: Added support for Unicode Text Segmentation to
+ JavaScript.
+ * HTML5: Added support for `contextlost` and `contextrestored`
+ events on HTMLCanvasElement and OffscreenCanvas to allow user
+ code to recover from context loss with hardware accelerated
+ 2d canvas.
+ * HTML5: Firefox now supports the
+ `navigator.clipboard.readText()` web API. A paste context
+ menu will appear for the user to confirm when attempting to
+ read clipboard data not provided by the same-origin page.
+ * HTML5: Added support for the `content-box` and `stroke-box`
+ keywords of the `transform-box` CSS property.
+ * HTML5: The `align-content` property now works in block
+ layout, allowing block direction alignment without needing a
+ flex or grid container.
+ * HTML5: Support for `SVGAElement.text` was removed in favor of
+ the more widely-implemented `SVGAElement.textContent` method.
+ * Developer: Following several requests, we have reintroduced
+ the option to disable the Pause Debugger Overlay
+ (`devtools.debugger.features.overlay`). This overlay appears
+ over the page content when the debugger pauses JavaScript
+ execution. In certain scenarios, the overlay can be
+ intrusive, making it challenging to interact with the page,
+ for instance, evaluating shades of color underneath.
+ * Developer: We've added a new drop-down menu button at the
+ bottom of the source view in the Debugger panel, specifically
+ designed for Source Map related actions. Users can now easily
+ disable or enable Source Maps support, open the Source Map
+ file in a new tab, switch between the original source and the
+ generated bundle, toggle the "open original source by
+ default" option, and view the Source Map status such as
+ errors, loading status, etc.
+ MFSA 2024-18 (bsc#1221327)
+ * CVE-2024-3852 (bmo#1883542)
+ GetBoundName in the JIT returned the wrong object
+ * CVE-2024-3853 (bmo#1884427)
+ Use-after-free if garbage collection runs during realm
+ initialization
+ * CVE-2024-3854 (bmo#1884552)
+ Out-of-bounds-read after mis-optimized switch statement
+ * CVE-2024-3855 (bmo#1885828)
+ Incorrect JIT optimization of MSubstr leads to out-of-bounds
+ reads
+ * CVE-2024-3856 (bmo#1885829)
+ Use-after-free in WASM garbage collection
+ * CVE-2024-3857 (bmo#1886683)
+ Incorrect JITting of arguments led to use-after-free during
+ garbage collection
+ * CVE-2024-3858 (bmo#1888892)
+ Corrupt pointer dereference in
+ js::CheckTracedThing<js::Shape>
+ * CVE-2024-3859 (bmo#1874489)
+ Integer-overflow led to out-of-bounds-read in the OpenType
+ sanitizer
+ * CVE-2024-3860 (bmo#1881417)
+ Crash when tracing empty shape lists
+ * CVE-2024-3861 (bmo#1883158)
+ Potential use-after-free due to AlignedBuffer self-move
+ * CVE-2024-3862 (bmo#1884457)
+ Potential use of uninitialized memory in MarkStack assignment
+ operator on self-assignment
+ * CVE-2024-3863 (bmo#1885855)
+ Download Protections were bypassed by .xrm-ms files on
+ Windows
+ * CVE-2024-3302 (bmo#1881183,
+ bmo#https://kb.cert.org/vuls/id/421644)
+ Denial of Service using HTTP/2 CONTINUATION frames
+ * CVE-2024-3864 (bmo#1888333)
+ Memory safety bug fixed in Firefox 125, Firefox ESR 115.10,
+ and Thunderbird 115.10
+ * CVE-2024-3865 (bmo#1881076, bmo#1884887, bmo#1885359,
+ bmo#1889049)
+ Memory safety bugs fixed in Firefox 125
+- requires
+ NSS 3.99
+ rust 1.76
+- add mozilla-libproxy-fix.patch to fix with-libproxy build variant
+
+-------------------------------------------------------------------
+Wed Apr 3 12:50:27 UTC 2024 - Martin Sirringhaus <martin.sirringhaus@suse.com>
+
+- Mozilla Firefox 124.0.2
+ https://www.mozilla.org/en-US/firefox/124.0.2/releasenotes/
+ * Fixed an issue where users with a large amount of bookmarks would
+ be unable to restore a bookmarks backup. (bmo#1884308)
+ * Fixed an issue that would cause open Firefox windows
+ to go blank or crash during video playback on sites such as
+ Netflix. (bmo#1883932)
+ * Fixed a crash that affected Linux AArch64 builds. (bmo#1866396)
+ * Fixed an issue where some users experienced difficulties loading
+ webpages due to changes made to the default AppArmor configuration
+ shipping in Ubuntu 24.04. (bmo#1884347)
+
+-------------------------------------------------------------------
+Fri Mar 22 09:53:26 UTC 2024 - Wolfgang Rosenauer <wr@rosenauer.org>
+
+- Mozilla Firefox 124.0.1
+ https://www.mozilla.org/en-US/firefox/124.0.1/releasenotes/
+ MFSA 2024-15 (bsc#1221850)
+ * CVE-2024-29943 (bmo#1886849)
+ Out-of-bounds access via Range Analysis bypass
+ * CVE-2024-29944 (bmo#1886852)
+ Privileged JavaScript Execution via Event Handlers
+ Mozilla Firefox 124.0
+ https://www.mozilla.org/en-US/firefox/124.0/releasenotes/
+ MFSA 2024-12 (bsc#1221327)
+ * CVE-2024-2605 (bmo#1872920)
+ Windows Error Reporter could be used as a Sandbox escape vector
+ * CVE-2024-2606 (bmo#1879237)
+ Mishandling of WASM register values
+ * CVE-2024-2607 (bmo#1879939)
+ JIT code failed to save return registers on Armv7-A
+ * CVE-2024-2608 (bmo#1880692)
+ Integer overflow could have led to out of bounds write
+ * CVE-2023-5388 (bmo#1780432)
+ NSS susceptible to timing attack against RSA decryption
+ * CVE-2024-2609 (bmo#1866100)
+ Permission prompt input delay could expire when not in focus
+ * CVE-2024-2610 (bmo#1871112)
+ Improper handling of html and body tags enabled CSP nonce leakage
+ * CVE-2024-2611 (bmo#1876675)
+ Clickjacking vulnerability could have led to a user accidentally
+ granting permissions
+ * CVE-2024-2612 (bmo#1879444)
+ Self referencing object could have potentially led to a use-
+ after-free
+ * CVE-2024-2613 (bmo#1875701)
+ Improper handling of QUIC ACK frame data could have led to OOM
+ * CVE-2024-2614 (bmo#1685358, bmo#1861016, bmo#1880405, bmo#1881093)
+ Memory safety bugs fixed in Firefox 124, Firefox ESR 115.9,
+ and Thunderbird 115.9
+ * CVE-2024-2615 (bmo#1881074, bmo#1881650, bmo#1882438)
+ Memory safety bugs fixed in Firefox 124
+- requires
+ NSS = 3.98
+ rust-cbindgen >= 0.26
+
+-------------------------------------------------------------------
+Fri Mar 8 06:16:48 UTC 2024 - Andreas Stieger <andreas.stieger@gmx.de>
+
+- Mozilla Firefox 123.0.1
+ * Fixed the *Firefox Translation* language indicator in the
+ address bar displaying a colored square icon instead of the
+ language code icon. (bmo#1879415)
+ * Fixed a regression with the `onChange` event not firing when
+ clearing the value of a `textarea` HTML field.
+ (bmo#1881457)
+ * Fixed a regression in the JavaScript JIT engine incorrectly
+ inlining strings in some cases. (bmo#1882386)
+ * Fixed: Fixed low contrast of text when selecting rows in the
+ Developer tools' Storage panel. (bmo#1877090)
+
+-------------------------------------------------------------------
+Thu Feb 22 11:02:39 UTC 2024 - Wolfgang Rosenauer <wr@rosenauer.org>
+
+- Mozilla Firefox 123.0
+ https://www.mozilla.org/en-US/firefox/123.0/releasenotes/
+ MFSA 2024-05 (bsc#1220048)
+ * CVE-2024-1546 (bmo#1843752)
+ Out-of-bounds memory read in networking channels
+ * CVE-2024-1547 (bmo#1877879)
+ Alert dialog could have been spoofed on another site
+ * CVE-2024-1554 (bmo#1816390)
+ fetch could be used to effect cache poisoning
+ * CVE-2024-1548 (bmo#1832627)
+ Fullscreen Notification could have been hidden by select element
+ * CVE-2024-1549 (bmo#1833814)
+ Custom cursor could obscure the permission dialog
+ * CVE-2024-1550 (bmo#1860065)
+ Mouse cursor re-positioned unexpectedly could have led to
+ unintended permission grants
+ * CVE-2024-1551 (bmo#1864385)
+ Multipart HTTP Responses would accept the Set-Cookie header
+ in response parts
+ * CVE-2024-1555 (bmo#1873223)
+ SameSite cookies were not properly respected when opening a
+ website from an external browser
+ * CVE-2024-1556 (bmo#1870414)
+ Invalid memory access in the built-in profiler
+ * CVE-2024-1552 (bmo#1874502)
+ Incorrect code generation on 32-bit ARM devices
+ * CVE-2024-1553 (bmo#1855686, bmo#1867982, bmo#1871498, bmo#1872296,
+ bmo#1873521, bmo#1873577, bmo#1873597, bmo#1873866, bmo#1874080,
+ bmo#1874740, bmo#1875795, bmo#1875906, bmo#1876425, bmo#1878211,
+ bmo#1878286)
+ Memory safety bugs fixed in Firefox 123, Firefox ESR 115.8,
+ and Thunderbird 115.8
+ * CVE-2024-1557 (bmo#1746471, bmo#1848829, bmo#1864011, bmo#1869175,
+ bmo#1869455, bmo#1869938, bmo#1871606)
+ Memory safety bugs fixed in Firefox 123
+- requires NSS 3.97
+
+-------------------------------------------------------------------
+Tue Feb 13 21:21:15 UTC 2024 - Andreas Stieger <andreas.stieger@gmx.de>
+
+- Mozilla Firefox 122.0.1
+ https://www.mozilla.org/en-US/firefox/122.0.1/releasenotes/
+ * Fixed the Library and Sidebar context menus only displaying
+ Multi-Account Containers icons in the "Open in New Container
+ Tab" menu. (bmo#1876518)
+ * Fixed an issue when clicking the Dismiss button in
+ notification pop-ups on Windows causing a webpage in a new tab.
+ (bmo#1848801)
+ * Fixed the yaru-remix system theme not applying correctly on
+ Linux. (bmo#1877002)
+ * Fixed adding an extra new line to a rule in the Developer
+ Tools' Inspector when copying it to the clipboard.
+ (bmo#1876220)
+ * Rolled back a keyboard behavior change made to the Developer
+ Tools' Rules view when validating a property name or input with
+ the Enter key.
+ This moves the focus to the next input, as was the behavior
+ in Firefox 121. (bmo#1877457)
+
+-------------------------------------------------------------------
+Tue Jan 30 13:51:25 UTC 2024 - Martin Sirringhaus <martin.sirringhaus@suse.com>
+
+- Recommend libfido2-udev on codestreams that exist, in order to try
+ to get security keys (e.g. Yubikeys) work out of the box. (bsc#1184272)
+
+-------------------------------------------------------------------
+Sat Jan 27 23:12:05 UTC 2024 - Andreas Schwab <schwab@suse.de>
+
+- Fix file list
+
+-------------------------------------------------------------------
+Sun Jan 21 09:16:30 UTC 2024 - Wolfgang Rosenauer <wr@rosenauer.org>
+
+- Mozilla Firefox 122.0
+ https://www.mozilla.org/en-US/firefox/122.0/releasenotes/
+ MFSA 2024-01 (bsc#1218955)
+ * CVE-2024-0741 (bmo#1864587)
+ Out of bounds write in ANGLE
+ * CVE-2024-0742 (bmo#1867152)
+ Failure to update user input timestamp
+ * CVE-2024-0743 (bmo#1867408)
+ Crash in NSS TLS method
+ * CVE-2024-0744 (bmo#1871089)
+ Wild pointer dereference in JavaScript
+ * CVE-2024-0745 (bmo#1871838)
+ Stack buffer overflow in WebAudio
+ * CVE-2024-0746 (bmo#1660223)
+ Crash when listing printers on Linux
+ * CVE-2024-0747 (bmo#1764343)
+ Bypass of Content Security Policy when directive unsafe-inline was set
+ * CVE-2024-0748 (bmo#1783504)
+ Compromised content process could modify document URI
+ * CVE-2024-0749 (bmo#1813463)
+ Phishing site popup could show local origin in address bar
+ * CVE-2024-0750 (bmo#1863083)
+ Potential permissions request bypass via clickjacking
+ * CVE-2024-0751 (bmo#1865689)
+ Privilege escalation through devtools
+ * CVE-2024-0752 (bmo#1866840)
+ Use-after-free could occur when applying update on macOS
+ * CVE-2024-0753 (bmo#1870262)
+ HSTS policy on subdomain could bypass policy of upper domain
+ * CVE-2024-0754 (bmo#1871605)
+ Crash when using some WASM files in devtools
+ * CVE-2024-0755 (bmo#1868456, bmo#1871445, bmo#1873701)
+ Memory safety bugs fixed in Firefox 122, Firefox ESR 115.7,
+ and Thunderbird 115.7
+- requires NSS 3.96.1
+- rebased patches
+
+-------------------------------------------------------------------
+Tue Jan 9 20:36:26 UTC 2024 - Andreas Stieger <andreas.stieger@gmx.de>
+
+- Mozilla Firefox 121.0.1
+ * Fixed unexpected line wrapping in some CJK contexts caused by
+ changes in ideographic space handling. bmo#1870973)
+ * Fixed a hang when loading sites containing column-based
+ layouts under some circumstances. bmo#1867784)
+ * Fixed missing rounded corners for videos playing over another
+ video. bmo#1869994)
+ * Fixed Firefox not closing properly and other applications being
+ unable to use a USB security key after being previously used
+ during a Firefox session. bmo#1863135)
+
+-------------------------------------------------------------------
Wed Dec 20 12:59:57 UTC 2023 - Wolfgang Rosenauer <wr@rosenauer.org>
- Mozilla Firefox 121.0