From fbf20a4c1d88c7f47456e64faec9a1020401e5fd Mon Sep 17 00:00:00 2001 From: "Mr. M" Date: Tue, 14 Apr 2026 00:15:19 +0200 Subject: [PATCH] no-bug: Add invert floor values --- prefs/zen/boosts.yaml | 6 ++ src/zen/boosts/ZenBoostsEditor.mjs | 9 +-- src/zen/boosts/actors/ZenBoostsChild.sys.mjs | 5 +- src/zen/boosts/moz.build | 1 + src/zen/boosts/nsZenBCOverrides.cpp | 69 +++++++++++++++++++ src/zen/boosts/nsZenBoostsBackend.cpp | 71 +++++--------------- 6 files changed, 98 insertions(+), 63 deletions(-) create mode 100644 src/zen/boosts/nsZenBCOverrides.cpp diff --git a/prefs/zen/boosts.yaml b/prefs/zen/boosts.yaml index e7c6bcef8..1fd5c6bb4 100644 --- a/prefs/zen/boosts.yaml +++ b/prefs/zen/boosts.yaml @@ -7,3 +7,9 @@ - name: zen.boosts.dissolve-on-zap value: true + +- name: zen.boosts.invert-channel-floor + value: 15 + cpptype: uint32_t + mirror: once + type: static diff --git a/src/zen/boosts/ZenBoostsEditor.mjs b/src/zen/boosts/ZenBoostsEditor.mjs index af9afa9e1..8ecae5884 100644 --- a/src/zen/boosts/ZenBoostsEditor.mjs +++ b/src/zen/boosts/ZenBoostsEditor.mjs @@ -308,10 +308,6 @@ export class nsZenBoostEditor { fontButton.addEventListener("click", this.onFontButtonClick.bind(this)); fontButtonGroup.appendChild(fontButton); - - if (i === 0) { - fontButtonGroup.appendChild(this.doc.createElement("br")); - } } // Add default value @@ -319,6 +315,7 @@ export class nsZenBoostEditor { defaultOption.value = ""; // Use default font of site defaultOption.label = "Default"; fontList.appendChild(defaultOption); + fontList.appendChild(this.doc.createElement("hr")); for (let j = 0; j < fonts.length; j++) { const font = fonts[j]; @@ -466,12 +463,12 @@ ${cssSelector} { const actor = linkedBrowser.browsingContext.currentWindowGlobal.getActor("ZenBoosts"); const zapButton = this.doc.getElementById("zen-boost-zap"); - + const zapEnabled = await actor.sendQuery("ZenBoost:ZapModeEnabled"); // Checks if there are any zaps const zapAny = await actor.sendQuery("ZenBoost:ZapModeAny"); - zapButton.setAttribute("enabled", (zapEnabled || zapAny) ? "true" : "false"); + zapButton.setAttribute("enabled", zapEnabled || zapAny ? "true" : "false"); } async onUpdatePickerButtonVisual() { diff --git a/src/zen/boosts/actors/ZenBoostsChild.sys.mjs b/src/zen/boosts/actors/ZenBoostsChild.sys.mjs index d88b9596d..54c9ee0a3 100644 --- a/src/zen/boosts/actors/ZenBoostsChild.sys.mjs +++ b/src/zen/boosts/actors/ZenBoostsChild.sys.mjs @@ -262,9 +262,10 @@ export class ZenBoostsChild extends JSWindowActorChild { break; case "ZenBoost:ZapModeEnabled": return this.#currentState === ZenBoostsChild.STATES.ZAP; - case "ZenBoost:ZapModeAny": + case "ZenBoost:ZapModeAny": { const { boostData } = (await this.getWebsiteBoost()).boostEntry; - return boostData.zapSelectors.length > 0; + return !!boostData.zapSelectors.length; + } case "ZenBoost:SelectorPickerModeEnabled": return this.#currentState === ZenBoostsChild.STATES.PICKER; case "ZenBoost:OpenInspector": diff --git a/src/zen/boosts/moz.build b/src/zen/boosts/moz.build index 3c496f3ba..211d68fc2 100644 --- a/src/zen/boosts/moz.build +++ b/src/zen/boosts/moz.build @@ -21,6 +21,7 @@ EXPORTS.mozilla += [ ] SOURCES += [ + "nsZenBCOverrides.cpp", "nsZenBoostsBackend.cpp", ] diff --git a/src/zen/boosts/nsZenBCOverrides.cpp b/src/zen/boosts/nsZenBCOverrides.cpp new file mode 100644 index 000000000..52536ddac --- /dev/null +++ b/src/zen/boosts/nsZenBCOverrides.cpp @@ -0,0 +1,69 @@ +/* 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 "nsZenBoostsBackend.h" + +#include "nsIXULRuntime.h" +#include "nsPresContext.h" + +#include "mozilla/StaticPtr.h" + +#include "mozilla/MediaFeatureChange.h" + +#include "mozilla/dom/Document.h" +#include "mozilla/dom/DocumentInlines.h" +#include "mozilla/dom/BrowsingContext.h" + +#define MARK_MEDIA_FEATURE_CHANGED(_pc) \ + (_pc)->MediaFeatureValuesChanged( \ + {mozilla::RestyleHint::RecascadeSubtree(), NS_STYLE_HINT_VISUAL, \ + mozilla::MediaFeatureChangeReason::PreferenceChange}, \ + mozilla::MediaFeatureChangePropagation::All); + +#define TRIGGER_PRES_CONTEXT_RESTYLE() \ + WalkPresContexts( \ + [&](nsPresContext* aPc) { MARK_MEDIA_FEATURE_CHANGED(aPc); }); + +using BrowsingContext = mozilla::dom::BrowsingContext; + +template +void BrowsingContext::WalkPresContexts(Callback&& aCallback) { + PreOrderWalk([&](BrowsingContext* aContext) { + if (nsIDocShell* shell = aContext->GetDocShell()) { + if (RefPtr pc = shell->GetPresContext()) { + aCallback(pc.get()); + } + } + }); +} + +/** + * @brief Called when the ZenBoostsData field is set on a browsing context. + * Triggers a restyle if the boost data has changed. + * @param aOldValue The previous value of the boost data. + */ +void BrowsingContext::DidSet(FieldIndex, + ZenBoostData aOldValue) { + MOZ_ASSERT(IsTop()); + if (ZenBoostsData() == aOldValue) { + return; + } + PresContextAffectingFieldChanged(); + TRIGGER_PRES_CONTEXT_RESTYLE(); +} + +/** + * @brief Called when the IsZenBoostsInverted field is set on a browsing + * context. Triggers a restyle if the value has changed. + * @param aOldValue The previous value of the IsZenBoostsInverted flag. + */ +void BrowsingContext::DidSet(FieldIndex, + bool aOldValue) { + MOZ_ASSERT(IsTop()); + if (IsZenBoostsInverted() == aOldValue) { + return; + } + PresContextAffectingFieldChanged(); + TRIGGER_PRES_CONTEXT_RESTYLE(); +} diff --git a/src/zen/boosts/nsZenBoostsBackend.cpp b/src/zen/boosts/nsZenBoostsBackend.cpp index 109eb6b51..6c31bbd28 100644 --- a/src/zen/boosts/nsZenBoostsBackend.cpp +++ b/src/zen/boosts/nsZenBoostsBackend.cpp @@ -17,7 +17,12 @@ #include "mozilla/dom/DocumentInlines.h" #include "mozilla/dom/BrowsingContext.h" -#define COLOR_CHANNEL_MIDPOINT 128 +#include "mozilla/StaticPrefs_zen.h" + +// Lower bound applied to inverted channels so that pure white doesn't invert +// all the way to pure black, which makes inverted pages feel too dark. +#define INVERT_CHANNEL_FLOOR() \ + (mozilla::StaticPrefs::zen_boosts_invert_channel_floor_AtStartup()) #if defined(__clang__) || defined(__GNUC__) # define ZEN_HOT_FUNCTION __attribute__((hot)) @@ -31,59 +36,6 @@ // serialization/deserialization between parent and content processes. #define NS_GET_CONTRAST(_c) NS_GET_A(_c) -#define MARK_MEDIA_FEATURE_CHANGED(_pc) \ - (_pc)->MediaFeatureValuesChanged( \ - {mozilla::RestyleHint::RecascadeSubtree(), NS_STYLE_HINT_VISUAL, \ - mozilla::MediaFeatureChangeReason::PreferenceChange}, \ - mozilla::MediaFeatureChangePropagation::All); - -#define TRIGGER_PRES_CONTEXT_RESTYLE() \ - WalkPresContexts( \ - [&](nsPresContext* aPc) { MARK_MEDIA_FEATURE_CHANGED(aPc); }); - -using BrowsingContext = mozilla::dom::BrowsingContext; - -template -void BrowsingContext::WalkPresContexts(Callback&& aCallback) { - PreOrderWalk([&](BrowsingContext* aContext) { - if (nsIDocShell* shell = aContext->GetDocShell()) { - if (RefPtr pc = shell->GetPresContext()) { - aCallback(pc.get()); - } - } - }); -} - -/** - * @brief Called when the ZenBoostsData field is set on a browsing context. - * Triggers a restyle if the boost data has changed. - * @param aOldValue The previous value of the boost data. - */ -void BrowsingContext::DidSet(FieldIndex, - ZenBoostData aOldValue) { - MOZ_ASSERT(IsTop()); - if (ZenBoostsData() == aOldValue) { - return; - } - PresContextAffectingFieldChanged(); - TRIGGER_PRES_CONTEXT_RESTYLE(); -} - -/** - * @brief Called when the IsZenBoostsInverted field is set on a browsing - * context. Triggers a restyle if the value has changed. - * @param aOldValue The previous value of the IsZenBoostsInverted flag. - */ -void BrowsingContext::DidSet(FieldIndex, - bool aOldValue) { - MOZ_ASSERT(IsTop()); - if (IsZenBoostsInverted() == aOldValue) { - return; - } - PresContextAffectingFieldChanged(); - TRIGGER_PRES_CONTEXT_RESTYLE(); -} - namespace zen { nsZenAccentOklab nsZenBoostsBackend::mCachedAccent{0}; @@ -275,7 +227,16 @@ inline static nscolor zenInvertColorChannel(nscolor aColor) { const auto gShifted = sum - gInv; const auto bShifted = sum - bInv; - return NS_RGBA(rShifted, gShifted, bShifted, a); + // Compress the channel range into [FLOOR, 255] so dark inversions are + // lifted while light inversions are left untouched. This preserves hue + // since all three channels are scaled by the same factor. + const auto channelFloor = INVERT_CHANNEL_FLOOR(); + const uint32_t range = 255 - channelFloor; + const auto lift = [channelFloor, range](uint8_t c) -> uint8_t { + return static_cast(channelFloor + (c * range) / 255); + }; + + return NS_RGBA(lift(rShifted), lift(gShifted), lift(bShifted), a); } /**