mirror of
https://github.com/zen-browser/desktop.git
synced 2025-07-08 00:10:00 +02:00
feat: Improve contrast slider, b=no-bug, c=mods, workspaces
This commit is contained in:
parent
f27df1a5bd
commit
7c57254da7
6 changed files with 220 additions and 60 deletions
|
@ -5,20 +5,6 @@
|
|||
<panel flip="side" type="arrow" popupalign="center" orient="vertical" id="PanelUI-zen-gradient-generator" position="bottomright topright" mainview="true" side="left">
|
||||
<panelmultiview id="PanelUI-zen-gradient-generator-multiview" mainViewId="PanelUI-zen-gradient-generator-view">
|
||||
<panelview id="PanelUI-zen-gradient-generator-view" class="PanelUI-subView zen-theme-picker" role="document" mainview-with-header="true" has-custom-header="true">
|
||||
<hbox>
|
||||
<hbox id="PanelUI-zen-gradient-generator-predefined">
|
||||
<box data-lightness="00" data-algo="analogous" data-num-dots="3" data-position="219,99" style="background: linear-gradient(135deg, rgb(117, 255, 136), rgb(60, 66, 58));"></box>
|
||||
<box data-lightness="10" data-algo="analogous" data-num-dots="3" data-position="167,201" style="background: linear-gradient(135deg, #a03fe0, #382b5c);"></box>
|
||||
<box data-lightness="20" data-algo="analogous" data-num-dots="3" data-position="90,170" style="background: linear-gradient(135deg, #c57aa3, #af824f);"></box>
|
||||
<box data-lightness="30" data-algo="splitComplementary" data-num-dots="3" data-position="83,103" style="background: linear-gradient(135deg, #1e90ff, #968a4a);"></box>
|
||||
<box data-lightness="40" data-algo="analogous" data-num-dots="3" data-position="186,186" style="background: linear-gradient(135deg, #a07a48, #ab80e4);"></box>
|
||||
<box data-lightness="50" data-algo="float" data-num-dots="1" data-position="196,176" style="background: #7bcbda;"></box>
|
||||
<box data-lightness="60" data-algo="float" data-num-dots="1" data-position="116,167" style="background: #be9ac9;"></box>
|
||||
<box data-lightness="70" data-algo="float" data-num-dots="1" data-position="122,110" style="background: #cdcea1;"></box>
|
||||
<box data-lightness="80" data-algo="float" data-num-dots="1" data-position="181,83" style="background: #6ac593;"></box>
|
||||
<box data-lightness="150" data-algo="complementary" data-num-dots="2" data-position="82,112" style="background: linear-gradient(135deg, #1e90ff, #cfb179);"></box>
|
||||
</hbox>
|
||||
</hbox>
|
||||
<hbox class="zen-theme-picker-gradient">
|
||||
<hbox id="PanelUI-zen-gradient-generator-scheme">
|
||||
<button id="PanelUI-zen-gradient-generator-scheme-auto" class="subviewbutton"/>
|
||||
|
@ -36,10 +22,40 @@
|
|||
</hbox>
|
||||
<label data-l10n-id="zen-panel-ui-gradient-click-to-add" id="PanelUI-zen-gradient-generator-color-click-to-add"></label>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<hbox id="PanelUI-zen-gradient-generator-predefined">
|
||||
<box data-lightness="90" data-algo="float" data-num-dots="1" data-position="196,176" style="background: #7bcbda;"></box>
|
||||
<box data-lightness="80" data-algo="float" data-num-dots="1" data-position="116,167" style="background: #be9ac9;"></box>
|
||||
<box data-lightness="70" data-algo="float" data-num-dots="1" data-position="122,110" style="background: #cdcea1;"></box>
|
||||
<box data-lightness="60" data-algo="float" data-num-dots="1" data-position="181,83" style="background: #6ac593;"></box>
|
||||
<box data-lightness="50" data-algo="analogous" data-num-dots="3" data-position="219,99" style="background: linear-gradient(135deg, rgb(117, 255, 136), rgb(60, 66, 58));"></box>
|
||||
<box data-lightness="40" data-algo="analogous" data-num-dots="3" data-position="167,201" style="background: linear-gradient(135deg, #a03fe0, #382b5c);"></box>
|
||||
<box data-lightness="30" data-algo="analogous" data-num-dots="3" data-position="90,170" style="background: linear-gradient(135deg, #c57aa3, #af824f);"></box>
|
||||
<box data-lightness="20" data-algo="splitComplementary" data-num-dots="3" data-position="83,103" style="background: linear-gradient(135deg, #1e90ff, #968a4a);"></box>
|
||||
<box data-lightness="10" data-algo="analogous" data-num-dots="3" data-position="186,186" style="background: linear-gradient(135deg, #a07a48, #ab80e4);"></box>
|
||||
<box data-lightness="150" data-algo="complementary" data-num-dots="2" data-position="82,112" style="background: linear-gradient(135deg, #1e90ff, #cfb179);"></box>
|
||||
</hbox>
|
||||
</hbox>
|
||||
<hbox id="PanelUI-zen-gradient-generator-controls">
|
||||
<hbox id="PanelUI-zen-gradient-colors-wrapper">
|
||||
<vbox flex="1">
|
||||
<html:input type="range" min="0.15" max="0.85" value="0.5" step="0.05" id="PanelUI-zen-gradient-generator-opacity" />
|
||||
<vbox flex="1" id="PanelUI-zen-gradient-opacity-wrapper">
|
||||
<box id="PanelUI-zen-gradient-slider-wave">
|
||||
<svg viewBox="0 -2.5 455 70" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMid meet">
|
||||
<path d="M 51.373 27.395 L 419.634 27.395"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
style="stroke-width: 11px;"/>
|
||||
<defs>
|
||||
<linearGradient id="PanelUI-zen-gradient-generator-slider-wave-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="light-dark(rgb(77, 77, 77), rgb(161, 161, 161))"/>
|
||||
<stop offset="0%" stop-color="light-dark(rgba(77, 77, 77), rgba(161, 161, 161))"/>
|
||||
<stop offset="100%" stop-color="light-dark(rgba(77, 77, 77, 0.5), rgba(161, 161, 161, 0.5))"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</box>
|
||||
<html:input type="range" min="0.15" max="0.85" value="0.5" step="0.01" id="PanelUI-zen-gradient-generator-opacity" />
|
||||
</vbox>
|
||||
<vbox id="PanelUI-zen-gradient-generator-texture-wrapper">
|
||||
</vbox>
|
||||
|
|
|
@ -775,7 +775,10 @@
|
|||
|
||||
@media -moz-pref('zen.theme.window.scheme', 'auto') {
|
||||
#PanelUI-zen-gradient-generator-scheme-auto {
|
||||
background: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.2));
|
||||
/** Can't use rgba here because of the background image, provide a solid, gray
|
||||
* background for the auto scheme in dark mode.
|
||||
*/
|
||||
background: light-dark(#edebeb, rgb(106, 106, 106));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -785,7 +788,7 @@
|
|||
|
||||
@media -moz-pref('zen.theme.window.scheme', 'dark') {
|
||||
#PanelUI-zen-gradient-generator-scheme-dark {
|
||||
background: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.2));
|
||||
background: light-dark(#edebeb, rgb(106, 106, 106));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -795,6 +798,6 @@
|
|||
|
||||
@media -moz-pref('zen.theme.window.scheme', 'light') {
|
||||
#PanelUI-zen-gradient-generator-scheme-light {
|
||||
background: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.2));
|
||||
background: light-dark(#edebeb, rgb(106, 106, 106));
|
||||
}
|
||||
}
|
||||
|
|
13
src/widget/cocoa/nsCocoaWindow-mm.patch
Normal file
13
src/widget/cocoa/nsCocoaWindow-mm.patch
Normal file
|
@ -0,0 +1,13 @@
|
|||
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
index c4627621344d35081f11a7b0e03d02eca2097609..d2e5fe429aaac8b701a03380a67f4ea978d566b3 100644
|
||||
--- a/widget/cocoa/nsCocoaWindow.mm
|
||||
+++ b/widget/cocoa/nsCocoaWindow.mm
|
||||
@@ -7376,7 +7376,7 @@ - (id)initWithContentRect:(NSRect)aContentRect
|
||||
|
||||
// Returns an autoreleased NSImage.
|
||||
static NSImage* GetMenuMaskImage() {
|
||||
- const CGFloat radius = 6.0f;
|
||||
+ const CGFloat radius = 14.0f;
|
||||
const NSSize maskSize = {radius * 3.0f, radius * 3.0f};
|
||||
NSImage* maskImage = [NSImage imageWithSize:maskSize
|
||||
flipped:FALSE
|
|
@ -49,7 +49,11 @@
|
|||
}
|
||||
|
||||
async #insertStylesheet() {
|
||||
this.#modsBackend.rebuildModsStyles();
|
||||
try {
|
||||
this.#modsBackend.rebuildModsStyles();
|
||||
} catch (e) {
|
||||
console.warn('[ZenMods]: Error rebuilding mods styles:', e);
|
||||
}
|
||||
}
|
||||
|
||||
async #rebuildModsStylesheet() {
|
||||
|
|
|
@ -3,6 +3,43 @@
|
|||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
{
|
||||
function parseSinePath(pathStr) {
|
||||
const points = [];
|
||||
const commands = pathStr.match(/[MCL]\s*[\d\s\.\-,]+/g);
|
||||
if (!commands) return points;
|
||||
|
||||
commands.forEach((command) => {
|
||||
const type = command.charAt(0);
|
||||
const coordsStr = command.slice(1).trim();
|
||||
const coords = coordsStr.split(/[\s,]+/).map(Number);
|
||||
|
||||
switch (type) {
|
||||
case 'M':
|
||||
points.push({ x: coords[0], y: coords[1], type: 'M' });
|
||||
break;
|
||||
case 'C':
|
||||
if (coords.length >= 6 && coords.length % 6 === 0) {
|
||||
for (let i = 0; i < coords.length; i += 6) {
|
||||
points.push({
|
||||
x1: coords[i],
|
||||
y1: coords[i + 1],
|
||||
x2: coords[i + 2],
|
||||
y2: coords[i + 3],
|
||||
x: coords[i + 4],
|
||||
y: coords[i + 5],
|
||||
type: 'C',
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
points.push({ x: coords[0], y: coords[1], type: 'L' });
|
||||
break;
|
||||
}
|
||||
});
|
||||
return points;
|
||||
}
|
||||
|
||||
class nsZenThemePicker extends ZenMultiWindowFeature {
|
||||
static MAX_DOTS = 3;
|
||||
|
||||
|
@ -13,6 +50,11 @@
|
|||
|
||||
#allowTransparencyOnSidebar = Services.prefs.getBoolPref('zen.theme.acrylic-elements', false);
|
||||
|
||||
#linePath = `M 51.373 27.395 L 419.634 27.395`;
|
||||
#sinePath = `M 51.373 31.629 C 60.14 -4.265 68.906 -4.265 77.671 31.629 C 86.438 67.527 95.205 67.527 103.971 31.629 C 112.738 -4.265 121.504 -4.265 130.271 31.629 C 139.037 67.527 147.803 67.527 156.57 31.629 C 165.335 -4.265 174.101 -4.265 182.868 31.629 C 191.634 67.527 200.4 67.527 209.167 31.629 C 217.933 -4.265 226.7 -4.265 235.467 31.629 C 244.233 67.527 252.999 67.527 261.765 31.629 C 270.531 -4.265 279.297 -4.265 288.064 31.629 C 296.83 67.527 305.596 67.527 314.363 31.629 C 323.13 -4.265 331.896 -4.265 340.662 31.629 M 314.438 31.629 C 323.204 -4.265 331.97 -4.265 340.737 31.629 C 349.503 67.527 358.27 67.527 367.037 31.629 C 375.802 -4.265 384.568 -4.265 393.335 31.629 C 402.101 67.527 410.867 67.527 419.634 31.629`;
|
||||
|
||||
#sinePoints = parseSinePath(this.#sinePath);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
if (
|
||||
|
@ -38,6 +80,10 @@
|
|||
document.getElementById('PanelUI-zen-gradient-generator-custom-list')
|
||||
);
|
||||
|
||||
ChromeUtils.defineLazyGetter(this, 'sliderWavePath', () =>
|
||||
document.getElementById('PanelUI-zen-gradient-slider-wave').querySelector('path')
|
||||
);
|
||||
|
||||
this.panel.addEventListener('popupshowing', this.handlePanelOpen.bind(this));
|
||||
this.panel.addEventListener('popuphidden', this.handlePanelClose.bind(this));
|
||||
this.panel.addEventListener('command', this.handlePanelCommand.bind(this));
|
||||
|
@ -349,24 +395,11 @@
|
|||
const centerX = rect.width / 2;
|
||||
const centerY = rect.height / 2;
|
||||
const radius = (rect.width - padding) / 2;
|
||||
|
||||
// Convert RGB to HSL
|
||||
const [h, s, l] = this.rgbToHsl(r, g, b);
|
||||
|
||||
// We assume lightness is fixed; if not, add a warning or threshold check
|
||||
// const targetLightness = this.#currentLightness / 100;
|
||||
// if (Math.abs(l - targetLightness) > 0.01) return null;
|
||||
|
||||
// Convert hue (0-1) to angle in radians
|
||||
const angleRad = (h * 360 * Math.PI) / 180;
|
||||
|
||||
// Convert saturation to radial distance
|
||||
const distance = (1 - s) * radius;
|
||||
|
||||
// Convert polar to cartesian
|
||||
const x = centerX + Math.cos(angleRad) * distance;
|
||||
const y = centerY + Math.sin(angleRad) * distance;
|
||||
|
||||
const [hue, saturation] = this.rgbToHsl(r, g, b);
|
||||
const angle = (hue / 360) * 2 * Math.PI; // Convert to radians
|
||||
const normalizedSaturation = saturation / 100; // Convert to [0, 1]
|
||||
const x = centerX + radius * normalizedSaturation * Math.cos(angle) - padding;
|
||||
const y = centerY + radius * normalizedSaturation * Math.sin(angle) - padding;
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
|
@ -960,7 +993,7 @@
|
|||
onOpacityChange(event) {
|
||||
this.currentOpacity = parseFloat(event.target.value);
|
||||
// If we reached a whole number (e.g., 0.1, 0.2, etc.), send a haptic feedback
|
||||
if (Math.round(this.currentOpacity % 0.1) === 0) {
|
||||
if ((this.currentOpacity * 10) % 1 === 0) {
|
||||
Services.zen.playHapticFeedback();
|
||||
}
|
||||
this.updateCurrentWorkspace();
|
||||
|
@ -1324,6 +1357,39 @@
|
|||
browser.gZenThemePicker.currentOpacity = workspaceTheme.opacity ?? 0.5;
|
||||
browser.gZenThemePicker.currentTexture = workspaceTheme.texture ?? 0;
|
||||
|
||||
const opacitySlider = browser.document.getElementById(
|
||||
'PanelUI-zen-gradient-generator-opacity'
|
||||
);
|
||||
|
||||
{
|
||||
let opacity = browser.gZenThemePicker.currentOpacity;
|
||||
const svg = browser.gZenThemePicker.sliderWavePath;
|
||||
const stepSize = 0.05;
|
||||
opacity = Math.floor(opacity / stepSize) * stepSize;
|
||||
// Opacity can only be between 0.15 to 0.85. Make opacity relative to that range
|
||||
// So 0.15 becomes 0, and 0.85 becomes 1.
|
||||
if (opacity < 0.15) {
|
||||
opacity = 0;
|
||||
} else if (opacity > 0.85) {
|
||||
opacity = 1;
|
||||
} else {
|
||||
opacity = (opacity - 0.15) / (0.85 - 0.15);
|
||||
}
|
||||
svg.setAttribute('d', this.#interpolateWavePath(opacity));
|
||||
const [_, secondStop, thirdStop] = document.querySelectorAll(
|
||||
'#PanelUI-zen-gradient-generator-slider-wave-gradient stop'
|
||||
);
|
||||
opacity += 0.025; // add a little bit of opacity so it doesn't look clipped
|
||||
secondStop.setAttribute('offset', `${opacity * 100}%`);
|
||||
thirdStop.setAttribute('offset', `${opacity * 100}%`);
|
||||
svg.style.stroke =
|
||||
opacity < 0.1
|
||||
? thirdStop.getAttribute('stop-color')
|
||||
: 'url(#PanelUI-zen-gradient-generator-slider-wave-gradient)';
|
||||
opacitySlider.style.setProperty('--zen-thumb-height', `${40 + opacity * 10}px`);
|
||||
opacitySlider.style.setProperty('--zen-thumb-width', `${10 + opacity * 10}px`);
|
||||
}
|
||||
|
||||
for (const button of browser.document.querySelectorAll(
|
||||
'#PanelUI-zen-gradient-generator-color-actions button'
|
||||
)) {
|
||||
|
@ -1338,8 +1404,7 @@
|
|||
.getElementById('PanelUI-zen-gradient-generator-color-click-to-add')
|
||||
.toggleAttribute('hidden', workspaceTheme.gradientColors.length > 0);
|
||||
|
||||
browser.document.getElementById('PanelUI-zen-gradient-generator-opacity').value =
|
||||
browser.gZenThemePicker.currentOpacity;
|
||||
opacitySlider.value = browser.gZenThemePicker.currentOpacity;
|
||||
const textureSelectWrapper = browser.document.getElementById(
|
||||
'PanelUI-zen-gradient-generator-texture-wrapper'
|
||||
);
|
||||
|
@ -1528,6 +1593,37 @@
|
|||
this.updateCurrentWorkspace();
|
||||
}, 200);
|
||||
}
|
||||
|
||||
#interpolateWavePath(progress) {
|
||||
const linePath = this.#linePath;
|
||||
const sinePath = this.#sinePath;
|
||||
const referenceY = 27.3;
|
||||
if (this.#sinePoints.length === 0) {
|
||||
return progress < 0.5 ? linePath : sinePath;
|
||||
}
|
||||
if (progress <= 0.001) return linePath;
|
||||
if (progress >= 0.999) return sinePath;
|
||||
const t = progress;
|
||||
let newPathData = '';
|
||||
this.#sinePoints.forEach((p) => {
|
||||
switch (p.type) {
|
||||
case 'M':
|
||||
const interpolatedY = referenceY + (p.y - referenceY) * t;
|
||||
newPathData += `M ${p.x} ${interpolatedY} `;
|
||||
break;
|
||||
case 'C':
|
||||
const y1 = referenceY + (p.y1 - referenceY) * t;
|
||||
const y2 = referenceY + (p.y2 - referenceY) * t;
|
||||
const y = referenceY + (p.y - referenceY) * t;
|
||||
newPathData += `C ${p.x1} ${y1} ${p.x2} ${y2} ${p.x} ${y} `;
|
||||
break;
|
||||
case 'L':
|
||||
newPathData += `L ${p.x} ${p.y} `;
|
||||
break;
|
||||
}
|
||||
});
|
||||
return newPathData.trim();
|
||||
}
|
||||
}
|
||||
|
||||
window.nsZenThemePicker = nsZenThemePicker;
|
||||
|
|
|
@ -62,7 +62,11 @@
|
|||
padding: 0 var(--panel-padding);
|
||||
|
||||
@media (-moz-platform: macos) {
|
||||
gap: 3rem;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
#PanelUI-zen-gradient-opacity-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
& label {
|
||||
|
@ -80,7 +84,7 @@
|
|||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
margin: 5px auto 10px auto;
|
||||
margin: 0 auto 25px auto;
|
||||
width: 100%;
|
||||
|
||||
& > box {
|
||||
|
@ -164,31 +168,55 @@
|
|||
}
|
||||
}
|
||||
|
||||
#PanelUI-zen-gradient-generator-opacity,
|
||||
#PanelUI-zen-gradient-generator-texture {
|
||||
#PanelUI-zen-gradient-slider-wave {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: -3px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
scale: 1.2;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
background: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1));
|
||||
border-radius: 999px;
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
top: -2px;
|
||||
left: 4px;
|
||||
scale: 0.85;
|
||||
}
|
||||
}
|
||||
|
||||
#PanelUI-zen-gradient-generator-opacity {
|
||||
margin: 0 !important;
|
||||
margin-top: 5px !important;
|
||||
background: transparent;
|
||||
z-index: 2;
|
||||
|
||||
&::-moz-range-thumb {
|
||||
background: var(--zen-colors-tertiary);
|
||||
border: 2px solid var(--zen-colors-border);
|
||||
border-radius: 12px;
|
||||
height: 25px;
|
||||
width: 13px;
|
||||
background: light-dark(black, white);
|
||||
border-radius: 999px;
|
||||
height: var(--zen-thumb-height);
|
||||
width: var(--zen-thumb-width);
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
}
|
||||
|
||||
&::-moz-range-track {
|
||||
background: light-dark(rgba(0, 0, 0, 0.3), rgba(255, 255, 255, 0.3));
|
||||
border-radius: 999px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
&::-moz-range-progress {
|
||||
background: var(--zen-primary-color);
|
||||
border-radius: 999px;
|
||||
height: 8px;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,9 +301,9 @@
|
|||
min-width: fit-content !important;
|
||||
transition: background 0.2s;
|
||||
appearance: none;
|
||||
max-height: 28px;
|
||||
max-height: 26px;
|
||||
max-width: 26px;
|
||||
color: light-dark(rgba(0, 0, 0, 0.7), rgba(255, 255, 255, 0.9));
|
||||
backdrop-filter: blur(5px);
|
||||
|
||||
& .button-box {
|
||||
gap: 0.1rem;
|
||||
|
@ -304,6 +332,7 @@
|
|||
|
||||
#PanelUI-zen-gradient-generator-scheme {
|
||||
top: 10px;
|
||||
max-height: 32px;
|
||||
}
|
||||
|
||||
@media not -moz-pref('zen.theme.gradient.show-custom-colors') {
|
||||
|
@ -318,9 +347,8 @@
|
|||
position: relative;
|
||||
|
||||
@media (-moz-platform: macos) {
|
||||
width: 25%;
|
||||
aspect-ratio: 1;
|
||||
height: unset;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
}
|
||||
|
||||
&::after {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue