diff options
26 files changed, 817 insertions, 5759 deletions
@@ -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 && -+#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"); @@ -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 |