mirror of
https://github.com/zen-browser/desktop.git
synced 2026-08-18 20:51:32 +00:00
gh-15005: Improve feel of theme colors (gh-15004)
This commit is contained in:
@@ -106,3 +106,6 @@
|
||||
- name: browser.referrals.enabled
|
||||
value: false
|
||||
locked: true
|
||||
|
||||
- name: browser.shell.customIcon.enabled
|
||||
value: false # For now?
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
value: 100
|
||||
|
||||
- name: zen.workspaces.switch-animation-duration
|
||||
value: 200
|
||||
value: 250
|
||||
|
||||
- name: zen.workspaces.wrap-around-navigation
|
||||
value: true
|
||||
|
||||
@@ -494,39 +494,49 @@ class nsZenMediaController {
|
||||
window.addEventListener("TabClose", onTabDiscardedOrClosed);
|
||||
window.addEventListener("TabBrowserDiscarded", onTabDiscardedOrClosed);
|
||||
|
||||
window.addEventListener("DOMAudioPlaybackStarted", event => {
|
||||
const browser = event.target;
|
||||
// The card is created right away (while the controller is fresh)
|
||||
// but only shown if the media is still playing a moment later, so
|
||||
// short sounds (e.g. notification pings) never reveal it.
|
||||
setTimeout(() => {
|
||||
const card = this.#cardForBrowser(browser);
|
||||
if (!card || card.isSharing) {
|
||||
return;
|
||||
}
|
||||
if (card.controller.isPlaying) {
|
||||
card.refreshVisibility();
|
||||
} else if (card.element.hidden) {
|
||||
// The sound was over before ever being shown (e.g. a
|
||||
// notification ping): drop the card instead of keeping a ghost
|
||||
// around.
|
||||
card.destroy();
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
this.activateMediaControls(
|
||||
browser.browsingContext.mediaController,
|
||||
browser
|
||||
);
|
||||
});
|
||||
|
||||
window.addEventListener("DOMAudioPlaybackStopped", () => {
|
||||
for (const card of this.#cards.values()) {
|
||||
card.updateMuteState();
|
||||
window.addEventListener("TabAttrModified", event => {
|
||||
if (!event.detail.changed.includes("soundplaying")) {
|
||||
return;
|
||||
}
|
||||
const tab = event.target;
|
||||
if (!tab.hasAttribute("soundplaying")) {
|
||||
this.onAudioPlaybackStopped();
|
||||
return;
|
||||
}
|
||||
this.onAudioPlaybackStarted(tab.linkedBrowser);
|
||||
});
|
||||
}
|
||||
|
||||
onAudioPlaybackStarted(browser) {
|
||||
// The card is created right away (while the controller is fresh) but
|
||||
// only shown if the media is still playing a moment later, so short
|
||||
// sounds (e.g. notification pings) never reveal it.
|
||||
setTimeout(() => {
|
||||
const card = this.#cardForBrowser(browser);
|
||||
if (!card || card.isSharing) {
|
||||
return;
|
||||
}
|
||||
if (card.controller.isPlaying) {
|
||||
card.refreshVisibility();
|
||||
} else if (card.element.hidden) {
|
||||
// The sound was over before ever being shown (e.g. a notification
|
||||
// ping): drop the card instead of keeping a ghost around.
|
||||
card.destroy();
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
this.activateMediaControls(
|
||||
browser.browsingContext?.mediaController,
|
||||
browser
|
||||
);
|
||||
}
|
||||
|
||||
onAudioPlaybackStopped() {
|
||||
for (const card of this.#cards.values()) {
|
||||
card.updateMuteState();
|
||||
}
|
||||
}
|
||||
|
||||
get frontCard() {
|
||||
return this.#orderedCards.find(card => !card.element.hidden) ?? null;
|
||||
}
|
||||
@@ -660,7 +670,7 @@ class nsZenMediaController {
|
||||
this.#cards.set(key, card);
|
||||
if (controller) {
|
||||
// Media cards start hidden and appear via the delayed check in
|
||||
// DOMAudioPlaybackStarted or on tab switch, like the original bar;
|
||||
// onAudioPlaybackStarted or on tab switch, like the original bar;
|
||||
// sharing cards show right away.
|
||||
card.element.hidden = true;
|
||||
} else {
|
||||
|
||||
@@ -138,6 +138,9 @@
|
||||
width: 100%;
|
||||
padding: 4px 6px;
|
||||
border-radius: var(--border-radius-medium);
|
||||
@media (-moz-platform: macos) {
|
||||
border-radius: calc(var(--border-radius-medium) - 2px);
|
||||
}
|
||||
outline: var(--zen-sidebar-notification-outline);
|
||||
outline-offset: -1.5px;
|
||||
box-shadow: var(--zen-sidebar-notification-shadow);
|
||||
|
||||
@@ -542,22 +542,22 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
|
||||
const centerX = rect.width / 2;
|
||||
const centerY = rect.height / 2;
|
||||
const radius = (rect.width - padding) / 2;
|
||||
const distance = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2);
|
||||
const distance = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2) - 0.2;
|
||||
let angle = Math.atan2(y - centerY, x - centerX);
|
||||
angle = (angle * 180) / Math.PI; // Convert to degrees
|
||||
angle = (angle * 180) / Math.PI;
|
||||
if (angle < 0) {
|
||||
angle += 360; // Normalize to [0, 360)
|
||||
angle += 360;
|
||||
}
|
||||
const normalizedDistance = 1 - Math.min(distance / radius, 1); // Normalize distance to [0, 1]
|
||||
let hue = (angle / 360) * 360; // Normalize angle to [0, 360)
|
||||
let saturation = normalizedDistance * 100; // stays high even in center
|
||||
const normalizedDistance = 1 - Math.min(distance / radius, 1);
|
||||
let hue = (angle / 360) * 360;
|
||||
let saturation = normalizedDistance * 100;
|
||||
if (type !== EXPLICIT_LIGHTNESS_TYPE) {
|
||||
saturation = 90 + (1 - normalizedDistance) * 10;
|
||||
// Set the current lightness to how far we are from the center of the circle
|
||||
// For example, moving the dot outside will have higher lightness, while moving it inside will have lower lightness
|
||||
this.#currentLightness = Math.round((1 - normalizedDistance) * 100);
|
||||
}
|
||||
let lightness = this.#currentLightness; // Fixed lightness for simplicity
|
||||
let lightness = this.#currentLightness;
|
||||
if (type === EXPLICIT_BLACKWHITE_TYPE) {
|
||||
// We can only get grayscales from white to black
|
||||
saturation = 0;
|
||||
@@ -1259,10 +1259,10 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
|
||||
let colorToBlendOpacity;
|
||||
if (this.isMica) {
|
||||
colorToBlend = this.isDarkMode ? [0, 0, 0] : [255, 255, 255];
|
||||
colorToBlendOpacity = 0.12;
|
||||
colorToBlendOpacity = 0.3;
|
||||
} else if (AppConstants.platform === "macosx") {
|
||||
colorToBlend = [255, 255, 255];
|
||||
colorToBlendOpacity = 0.18;
|
||||
colorToBlendOpacity = 0.6;
|
||||
}
|
||||
if (colorToBlend) {
|
||||
const blendedAlpha = Math.min(
|
||||
@@ -1495,9 +1495,17 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
|
||||
return color;
|
||||
}
|
||||
|
||||
getToolbarColor(isDarkMode = false) {
|
||||
getToolbarColor(isDarkMode = false, accentColor = undefined) {
|
||||
const opacity = 0.8;
|
||||
let baseColor = isDarkMode ? [255, 255, 255, opacity] : [0, 0, 0, opacity]; // Default toolbar
|
||||
if (accentColor && this.canBeTransparent) {
|
||||
// Blend a bit with the accent color to make it more visible
|
||||
baseColor = this.blendColors(
|
||||
accentColor,
|
||||
baseColor.slice(0, 3),
|
||||
10
|
||||
).concat(opacity);
|
||||
}
|
||||
return baseColor;
|
||||
}
|
||||
|
||||
@@ -1763,7 +1771,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
|
||||
docElement.style.setProperty("--zen-primary-color", primaryColor);
|
||||
|
||||
// Set `--toolbox-textcolor` to have a contrast with the primary color
|
||||
let textColor = this.getToolbarColor(isDarkMode);
|
||||
let textColor = this.getToolbarColor(isDarkMode, dominantColor);
|
||||
docElement.style.setProperty(
|
||||
"--toolbox-textcolor",
|
||||
`rgba(${textColor[0]}, ${textColor[1]}, ${textColor[2]}, ${textColor[3]})`
|
||||
@@ -2009,7 +2017,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
|
||||
grain: theme.texture ?? 0,
|
||||
isDarkMode,
|
||||
isExplicitMode,
|
||||
toolbarColor: this.getToolbarColor(isDarkMode),
|
||||
toolbarColor: this.getToolbarColor(isDarkMode, dominantColor),
|
||||
primaryColor: this.getAccentColorForUI(dominantColor, isDarkMode),
|
||||
};
|
||||
this.currentOpacity = previousOpacity;
|
||||
|
||||
@@ -321,7 +321,7 @@ zen-workspace {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
color: color-mix(in srgb, var(--toolbox-textcolor) 95%, var(--zen-primary-color));
|
||||
color: var(--toolbox-textcolor);
|
||||
|
||||
--tab-background-color-selected: color-mix(in srgb, light-dark(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.18)) 95%, var(--zen-primary-color)) !important;
|
||||
--tab-box-shadow-selected: 0 0.8px 1.5px 0px light-dark(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.05)) !important;
|
||||
|
||||
@@ -30,7 +30,7 @@ async function playVideoIn(tab) {
|
||||
}
|
||||
);
|
||||
// Wait for the browser to actually consider the tab "playing" — this is
|
||||
// what drives DOMAudioPlaybackStarted into the media controller.
|
||||
// what drives the soundplaying TabAttrModified into the media controller.
|
||||
await BrowserTestUtils.waitForCondition(
|
||||
() => tab.soundPlaying,
|
||||
"tab reports soundplaying"
|
||||
|
||||
Reference in New Issue
Block a user