Merge branch 'dev' into window-sync

This commit is contained in:
mr. m
2025-12-07 18:36:06 +01:00
committed by GitHub
16 changed files with 352 additions and 58 deletions

37
package-lock.json generated
View File

@@ -9,7 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"license": "MPL-2.0", "license": "MPL-2.0",
"dependencies": { "dependencies": {
"@zen-browser/surfer": "^1.11.26" "@zen-browser/surfer": "^1.12.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-typescript": "^7.27.0", "@babel/preset-typescript": "^7.27.0",
@@ -35,6 +35,7 @@
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.24" "@jridgewell/trace-mapping": "^0.3.24"
@@ -64,6 +65,7 @@
"integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
} }
@@ -106,6 +108,7 @@
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"peer": true,
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
@@ -146,6 +149,7 @@
"integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@babel/compat-data": "^7.26.8", "@babel/compat-data": "^7.26.8",
"@babel/helper-validator-option": "^7.25.9", "@babel/helper-validator-option": "^7.25.9",
@@ -163,6 +167,7 @@
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"peer": true,
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
@@ -336,6 +341,7 @@
"integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@babel/template": "^7.27.0", "@babel/template": "^7.27.0",
"@babel/types": "^7.27.0" "@babel/types": "^7.27.0"
@@ -1109,9 +1115,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@zen-browser/surfer": { "node_modules/@zen-browser/surfer": {
"version": "1.11.26", "version": "1.12.0",
"resolved": "https://registry.npmjs.org/@zen-browser/surfer/-/surfer-1.11.26.tgz", "resolved": "https://registry.npmjs.org/@zen-browser/surfer/-/surfer-1.12.0.tgz",
"integrity": "sha512-NZcFZ4a/HWvEJlEr5IlQto/xHLOr6tZjkZALue2qHg+rjRKR5v2BEV4hV5mfAo85gKhyM2Ism0sD+0+/VQIESg==", "integrity": "sha512-I5nxDgGpFGtdOAC9DZkoQp9GJ4cAqCW+0p0DoQRjW/jdnQJUH20ygvPyPr+sgjXISPFclYX+KrVoT2kJqTdlTw==",
"license": "MPL-2.0", "license": "MPL-2.0",
"dependencies": { "dependencies": {
"@resvg/resvg-js": "^1.4.0", "@resvg/resvg-js": "^1.4.0",
@@ -1147,7 +1153,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
}, },
@@ -1819,7 +1824,8 @@
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
], ],
"license": "CC-BY-4.0" "license": "CC-BY-4.0",
"peer": true
}, },
"node_modules/chalk": { "node_modules/chalk": {
"version": "4.1.2", "version": "4.1.2",
@@ -2006,7 +2012,8 @@
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"peer": true
}, },
"node_modules/core-js-pure": { "node_modules/core-js-pure": {
"version": "3.41.0", "version": "3.41.0",
@@ -2326,7 +2333,8 @@
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.139.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.139.tgz",
"integrity": "sha512-GGnRYOTdN5LYpwbIr0rwP/ZHOQSvAF6TG0LSzp28uCBb9JiXHJGmaaKw29qjNJc5bGnnp6kXJqRnGMQoELwi5w==", "integrity": "sha512-GGnRYOTdN5LYpwbIr0rwP/ZHOQSvAF6TG0LSzp28uCBb9JiXHJGmaaKw29qjNJc5bGnnp6kXJqRnGMQoELwi5w==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC",
"peer": true
}, },
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
@@ -2562,6 +2570,7 @@
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
@@ -2585,7 +2594,6 @@
"integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1", "@eslint-community/regexpp": "^4.12.1",
@@ -3433,6 +3441,7 @@
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
} }
@@ -4430,6 +4439,7 @@
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"bin": { "bin": {
"json5": "lib/cli.js" "json5": "lib/cli.js"
}, },
@@ -4864,6 +4874,7 @@
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"peer": true,
"dependencies": { "dependencies": {
"yallist": "^3.0.2" "yallist": "^3.0.2"
} }
@@ -5078,7 +5089,8 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"peer": true
}, },
"node_modules/normalize-path": { "node_modules/normalize-path": {
"version": "3.0.0", "version": "3.0.0",
@@ -5534,7 +5546,6 @@
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"bin": { "bin": {
"prettier": "bin/prettier.cjs" "prettier": "bin/prettier.cjs"
}, },
@@ -6949,6 +6960,7 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"escalade": "^3.2.0", "escalade": "^3.2.0",
"picocolors": "^1.1.1" "picocolors": "^1.1.1"
@@ -7252,7 +7264,8 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC",
"peer": true
}, },
"node_modules/yaml": { "node_modules/yaml": {
"version": "2.7.0", "version": "2.7.0",

View File

@@ -49,7 +49,7 @@
}, },
"homepage": "https://github.com/zen-browser/desktop#readme", "homepage": "https://github.com/zen-browser/desktop#readme",
"dependencies": { "dependencies": {
"@zen-browser/surfer": "^1.11.26" "@zen-browser/surfer": "^1.12.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-typescript": "^7.27.0", "@babel/preset-typescript": "^7.27.0",

View File

@@ -12,10 +12,9 @@
<button id="PanelUI-zen-gradient-generator-scheme-dark" class="subviewbutton"/> <button id="PanelUI-zen-gradient-generator-scheme-dark" class="subviewbutton"/>
</hbox> </hbox>
<hbox id="PanelUI-zen-gradient-generator-color-actions"> <hbox id="PanelUI-zen-gradient-generator-color-actions">
<button id="PanelUI-zen-gradient-generator-color-add" class="subviewbutton"> <button id="PanelUI-zen-gradient-generator-color-add" class="subviewbutton" />
</button> <button id="PanelUI-zen-gradient-generator-color-remove" class="subviewbutton" />
<button id="PanelUI-zen-gradient-generator-color-remove" class="subviewbutton"> <button id="PanelUI-zen-gradient-generator-color-toggle-algo" class="subviewbutton" />
</button>
</hbox> </hbox>
<label data-l10n-id="zen-panel-ui-gradient-click-to-add" id="PanelUI-zen-gradient-generator-color-click-to-add"></label> <label data-l10n-id="zen-panel-ui-gradient-click-to-add" id="PanelUI-zen-gradient-generator-color-click-to-add"></label>
</hbox> </hbox>
@@ -78,6 +77,27 @@
<box data-lightness="20" data-algo="analogous" data-num-dots="3" data-position="118,215" <box data-lightness="20" data-algo="analogous" data-num-dots="3" data-position="118,215"
style="--c1: rgb(22, 80, 61); --c2: rgb(26, 60, 76); --c3: rgb(27, 87, 15);" /> style="--c1: rgb(22, 80, 61); --c2: rgb(26, 60, 76); --c3: rgb(27, 87, 15);" />
</hbox> </hbox>
<hbox>
# Start from black to white in a span on 8 steps and.
# They must all go from the middle to the right side. They must always stay verically centered.
# And reach to 180 on the right side, meaning we must divide the width in 16 segments.
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="180,180" style="background: rgb(0, 0, 0);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="202.5,180" style="background: rgb(32, 32, 32);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="225,180" style="background: rgb(64, 64, 64);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="247.5,180" style="background: rgb(96, 96, 96);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="270,180" style="background: rgb(128, 128, 128);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="292.5,180" style="background: rgb(160, 160, 160);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="315,180" style="background: rgb(192, 192, 192);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="337.5,180" style="background: rgb(224, 224, 224);"></box>
</hbox>
</hbox> </hbox>
<toolbarbutton id="PanelUI-zen-gradient-generator-color-page-right" class="toolbarbutton-1" /> <toolbarbutton id="PanelUI-zen-gradient-generator-color-page-right" class="toolbarbutton-1" />
</hbox> </hbox>

View File

@@ -692,6 +692,10 @@
list-style-image: url('container-tab.svg') !important; list-style-image: url('container-tab.svg') !important;
} }
#PanelUI-zen-gradient-generator-color-toggle-algo {
list-style-image: url('algorithm.svg');
}
#appMenuClearRecentHistory { #appMenuClearRecentHistory {
list-style-image: url('edit-delete.svg') !important; list-style-image: url('edit-delete.svg') !important;
} }

View File

@@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifdef XP_WIN #ifdef XP_WIN
* skin/classic/browser/zen-icons/algorithm.svg (../shared/zen-icons/lin/algorithm.svg)
* skin/classic/browser/zen-icons/arrow-down.svg (../shared/zen-icons/lin/arrow-down.svg) * skin/classic/browser/zen-icons/arrow-down.svg (../shared/zen-icons/lin/arrow-down.svg)
* skin/classic/browser/zen-icons/arrow-left.svg (../shared/zen-icons/lin/arrow-left.svg) * skin/classic/browser/zen-icons/arrow-left.svg (../shared/zen-icons/lin/arrow-left.svg)
* skin/classic/browser/zen-icons/arrow-right.svg (../shared/zen-icons/lin/arrow-right.svg) * skin/classic/browser/zen-icons/arrow-right.svg (../shared/zen-icons/lin/arrow-right.svg)
@@ -131,6 +132,7 @@
* skin/classic/browser/zen-icons/zoom-out.svg (../shared/zen-icons/lin/zoom-out.svg) * skin/classic/browser/zen-icons/zoom-out.svg (../shared/zen-icons/lin/zoom-out.svg)
#endif #endif
#ifdef XP_MACOSX #ifdef XP_MACOSX
* skin/classic/browser/zen-icons/algorithm.svg (../shared/zen-icons/lin/algorithm.svg)
* skin/classic/browser/zen-icons/arrow-down.svg (../shared/zen-icons/lin/arrow-down.svg) * skin/classic/browser/zen-icons/arrow-down.svg (../shared/zen-icons/lin/arrow-down.svg)
* skin/classic/browser/zen-icons/arrow-left.svg (../shared/zen-icons/lin/arrow-left.svg) * skin/classic/browser/zen-icons/arrow-left.svg (../shared/zen-icons/lin/arrow-left.svg)
* skin/classic/browser/zen-icons/arrow-right.svg (../shared/zen-icons/lin/arrow-right.svg) * skin/classic/browser/zen-icons/arrow-right.svg (../shared/zen-icons/lin/arrow-right.svg)
@@ -259,6 +261,7 @@
* skin/classic/browser/zen-icons/zoom-out.svg (../shared/zen-icons/lin/zoom-out.svg) * skin/classic/browser/zen-icons/zoom-out.svg (../shared/zen-icons/lin/zoom-out.svg)
#endif #endif
#ifdef XP_LINUX #ifdef XP_LINUX
* skin/classic/browser/zen-icons/algorithm.svg (../shared/zen-icons/lin/algorithm.svg)
* skin/classic/browser/zen-icons/arrow-down.svg (../shared/zen-icons/lin/arrow-down.svg) * skin/classic/browser/zen-icons/arrow-down.svg (../shared/zen-icons/lin/arrow-down.svg)
* skin/classic/browser/zen-icons/arrow-left.svg (../shared/zen-icons/lin/arrow-left.svg) * skin/classic/browser/zen-icons/arrow-left.svg (../shared/zen-icons/lin/arrow-left.svg)
* skin/classic/browser/zen-icons/arrow-right.svg (../shared/zen-icons/lin/arrow-right.svg) * skin/classic/browser/zen-icons/arrow-right.svg (../shared/zen-icons/lin/arrow-right.svg)

View File

@@ -0,0 +1,5 @@
#filter dumbComments emptyLines substitution
# 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/.
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"><g stroke-linecap="round" stroke-width="1.5" fill="none" stroke="context-fill" stroke-opacity="context-fill-opacity" stroke-linejoin="round" class="nc-icon-wrapper"><path d="M4.75 15.25C5.99264 15.25 7 14.2426 7 13C7 11.7574 5.99264 10.75 4.75 10.75C3.50736 10.75 2.5 11.7574 2.5 13C2.5 14.2426 3.50736 15.25 4.75 15.25Z"/><path d="M13.25 15.25C14.4926 15.25 15.5 14.2426 15.5 13C15.5 11.7574 14.4926 10.75 13.25 10.75C12.0074 10.75 11 11.7574 11 13C11 14.2426 12.0074 15.25 13.25 15.25Z"/><path d="M9 7.25C10.2426 7.25 11.25 6.24264 11.25 5C11.25 3.75736 10.2426 2.75 9 2.75C7.75736 2.75 6.75 3.75736 6.75 5C6.75 6.24264 7.75736 7.25 9 7.25Z"/></g></svg>

View File

@@ -2,4 +2,4 @@
# This Source Code Form is subject to the terms of the Mozilla Public # 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 # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="18px" height="18px" viewBox="0 0 18 18"><path d="M17.25,8.25h-1.292c-.146-1.369-.69-2.619-1.512-3.637l1.583-1.583c.293-.293,.293-.768,0-1.061s-.767-.294-1.061,0l-1.583,1.583c-1.018-.821-2.268-1.365-3.636-1.511V.75c0-.414-.336-.75-.75-.75s-.75,.336-.75,.75v1.292c-1.368,.146-2.618,.69-3.636,1.511l-1.583-1.583c-.293-.293-.768-.293-1.061,0s-.293,.768,0,1.061l1.583,1.583c-.821,1.018-1.365,2.268-1.511,3.637H.75c-.414,0-.75,.336-.75,.75s.336,.75,.75,.75h1.292c.146,1.369,.69,2.619,1.511,3.637l-1.583,1.583c-.293,.293-.293,.768,0,1.061,.146,.146,.338,.22,.53,.22,.191,0,.384-.073,.53-.22l1.583-1.583c1.018,.821,2.268,1.365,3.636,1.511v1.292c0,.414,.336,.75,.75,.75s.75-.336,.75-.75v-1.292c1.368-.146,2.618-.69,3.636-1.511l1.583,1.583c.146,.146,.338,.22,.53,.22s.384-.073,.53-.22c.293-.293,.293-.768,0-1.061l-1.583-1.583c.821-1.018,1.365-2.268,1.512-3.637h1.292c.414,0,.75-.336,.75-.75s-.336-.75-.75-.75Zm-11.25,1.75c-.552,0-1-.448-1-1s.448-1,1-1,1,.448,1,1-.448,1-1,1Zm3,2c-.828,0-1.5-.672-1.5-1.5,0-.276,.224-.5,.5-.5h2c.276,0,.5,.224,.5,.5,0,.828-.672,1.5-1.5,1.5Zm2-3c0-.552,.448-1,1-1s1,.448,1,1-.448,1-1,1-1-.448-1-1Z" fill="currentColor"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="18px" height="18px" viewBox="0 0 18 18"><path d="M17.25,8.25h-1.292c-.146-1.369-.69-2.619-1.512-3.637l1.583-1.583c.293-.293,.293-.768,0-1.061s-.767-.294-1.061,0l-1.583,1.583c-1.018-.821-2.268-1.365-3.636-1.511V.75c0-.414-.336-.75-.75-.75s-.75,.336-.75,.75v1.292c-1.368,.146-2.618,.69-3.636,1.511l-1.583-1.583c-.293-.293-.768-.293-1.061,0s-.293,.768,0,1.061l1.583,1.583c-.821,1.018-1.365,2.268-1.511,3.637H.75c-.414,0-.75,.336-.75,.75s.336,.75,.75,.75h1.292c.146,1.369,.69,2.619,1.511,3.637l-1.583,1.583c-.293,.293-.293,.768,0,1.061,.146,.146,.338,.22,.53,.22,.191,0,.384-.073,.53-.22l1.583-1.583c1.018,.821,2.268,1.365,3.636,1.511v1.292c0,.414,.336,.75,.75,.75s.75-.336,.75-.75v-1.292c1.368-.146,2.618-.69,3.636-1.511l1.583,1.583c.146,.146,.338,.22,.53,.22s.384-.073,.53-.22c.293-.293,.293-.768,0-1.061l-1.583-1.583c.821-1.018,1.365-2.268,1.512-3.637h1.292c.414,0,.75-.336,.75-.75s-.336-.75-.75-.75Zm-11.25,1.75c-.552,0-1-.448-1-1s.448-1,1-1,1,.448,1,1-.448,1-1,1Zm3,2c-.828,0-1.5-.672-1.5-1.5,0-.276,.224-.5,.5-.5h2c.276,0,.5,.224,.5,.5,0,.828-.672,1.5-1.5,1.5Zm2-3c0-.552,.448-1,1-1s1,.448,1,1-.448,1-1,1-1-.448-1-1Z" fill="context-fill"></path></svg>

View File

@@ -2,4 +2,4 @@
# This Source Code Form is subject to the terms of the Mozilla Public # 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 # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="18px" height="18px" viewBox="0 0 18 18"><path d="M16.705,10.223c-.246-.183-.578-.197-.838-.037-.868,.532-1.859,.813-2.867,.813-3.033,0-5.5-2.467-5.5-5.5,0-1.146,.354-2.247,1.023-3.186,.177-.249,.186-.581,.021-.839-.164-.258-.467-.386-.77-.334C3.994,1.847,1.25,5.152,1.25,9c0,4.411,3.589,8,8,8,3.638,0,6.819-2.461,7.735-5.986,.077-.296-.034-.609-.28-.791Z" fill="currentColor"></path><path d="M12.743,4.492l-.946-.315-.316-.947c-.102-.306-.609-.306-.711,0l-.316,.947-.946,.315c-.153,.051-.257,.194-.257,.356s.104,.305,.257,.356l.946,.315,.316,.947c.051,.153,.194,.256,.355,.256s.305-.104,.355-.256l.316-.947,.946-.315c.153-.051,.257-.194,.257-.356s-.104-.305-.257-.356Z" fill="currentColor" data-color="color-2"></path><circle cx="14.25" cy="7.75" r=".75" fill="currentColor" data-color="color-2"></circle></svg> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="18px" height="18px" viewBox="0 0 18 18"><path d="M16.705,10.223c-.246-.183-.578-.197-.838-.037-.868,.532-1.859,.813-2.867,.813-3.033,0-5.5-2.467-5.5-5.5,0-1.146,.354-2.247,1.023-3.186,.177-.249,.186-.581,.021-.839-.164-.258-.467-.386-.77-.334C3.994,1.847,1.25,5.152,1.25,9c0,4.411,3.589,8,8,8,3.638,0,6.819-2.461,7.735-5.986,.077-.296-.034-.609-.28-.791Z" fill="context-fill"></path><path d="M12.743,4.492l-.946-.315-.316-.947c-.102-.306-.609-.306-.711,0l-.316,.947-.946,.315c-.153,.051-.257,.194-.257,.356s.104,.305,.257,.356l.946,.315,.316,.947c.051,.153,.194,.256,.355,.256s.305-.104,.355-.256l.316-.947,.946-.315c.153-.051,.257-.194,.257-.356s-.104-.305-.257-.356Z" fill="currentColor" data-color="color-2"></path><circle cx="14.25" cy="7.75" r=".75" fill="currentColor" data-color="color-2"></circle></svg>

View File

@@ -2,4 +2,4 @@
# This Source Code Form is subject to the terms of the Mozilla Public # 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 # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="18px" height="18px" viewBox="0 0 18 18"><path d="M3.025,5.623c.068,.204,.26,.342,.475,.342s.406-.138,.475-.342l.421-1.263,1.263-.421c.204-.068,.342-.259,.342-.474s-.138-.406-.342-.474l-1.263-.421-.421-1.263c-.137-.408-.812-.408-.949,0l-.421,1.263-1.263,.421c-.204,.068-.342,.259-.342,.474s.138,.406,.342,.474l1.263,.421,.421,1.263Z" fill="currentColor" data-color="color-2"></path><path d="M16.525,8.803l-4.535-1.793-1.793-4.535c-.227-.572-1.168-.572-1.395,0l-1.793,4.535-4.535,1.793c-.286,.113-.475,.39-.475,.697s.188,.584,.475,.697l4.535,1.793,1.793,4.535c.113,.286,.39,.474,.697,.474s.584-.188,.697-.474l1.793-4.535,4.535-1.793c.286-.113,.475-.39,.475-.697s-.188-.584-.475-.697Z" fill="currentColor"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="18px" height="18px" viewBox="0 0 18 18"><path d="M3.025,5.623c.068,.204,.26,.342,.475,.342s.406-.138,.475-.342l.421-1.263,1.263-.421c.204-.068,.342-.259,.342-.474s-.138-.406-.342-.474l-1.263-.421-.421-1.263c-.137-.408-.812-.408-.949,0l-.421,1.263-1.263,.421c-.204,.068-.342,.259-.342,.474s.138,.406,.342,.474l1.263,.421,.421,1.263Z" fill="context-fill" data-color="color-2"></path><path d="M16.525,8.803l-4.535-1.793-1.793-4.535c-.227-.572-1.168-.572-1.395,0l-1.793,4.535-4.535,1.793c-.286,.113-.475,.39-.475,.697s.188,.584,.475,.697l4.535,1.793,1.793,4.535c.113,.286,.39,.474,.697,.474s.584-.188,.697-.474l1.793-4.535,4.535-1.793c.286-.113,.475-.39,.475-.697s-.188-.584-.475-.697Z" fill="currentColor"></path></svg>

View File

@@ -0,0 +1,91 @@
From 433cc8224790300fdabe76bd225b644c1812da34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Thu, 27 Nov 2025 15:28:12 +0000
Subject: [PATCH] Bug 1993474 - Ensure our WNDPROC has precedence over
WinAppSDK's. r=gstoll,win-reviewers
See the comment for reasoning. WM_NCCALCSIZE wasn't getting called, and
we rely on that to get the right client area on things like maximized
windows.
Differential Revision: https://phabricator.services.mozilla.com/D274281
---
widget/windows/nsWindow.cpp | 32 ++++++++++++++++++++++----------
widget/windows/nsWindow.h | 2 ++
2 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp
index 0b98d157097da..b357df236cfcd 100644
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -1520,12 +1520,31 @@ DWORD nsWindow::WindowExStyle() {
*
**************************************************************/
+bool nsWindow::ShouldAssociateWithWinAppSDK() const {
+ // We currently don't need any SDK functionality for for PiP windows,
+ // and using the SDK on these windows causes them to go under the
+ // taskbar (bug 1995838).
+ //
+ // TODO(emilio): That might not be true anymore after bug 1993474,
+ // consider re-testing and removing that special-case.
+ return IsTopLevelWidget() && !mIsPIPWindow;
+}
+
bool nsWindow::AssociateWithNativeWindow() {
if (!mWnd || !IsWindow(mWnd)) {
NS_ERROR("Invalid window handle");
return false;
}
+ if (ShouldAssociateWithWinAppSDK()) {
+ // Make sure to call this here to associate our window with the
+ // Windows App SDK _before_ setting our WNDPROC, if needed.
+ // This is important because the SDKs WNDPROC might handle messages like
+ // WM_NCCALCSIZE without calling into us, and that can cause sizing issues,
+ // see bug 1993474.
+ WindowsUIUtils::SetIsTitlebarCollapsed(mWnd, mCustomNonClient);
+ }
+
// Connect the this pointer to the native window handle.
// This should be done before SetWindowLongPtrW, because nsWindow::WindowProc
// uses WinUtils::GetNSWindowPtr internally.
@@ -1552,12 +1571,7 @@ void nsWindow::DissociateFromNativeWindow() {
DebugOnly<WNDPROC> wndProcBeforeDissociate =
reinterpret_cast<WNDPROC>(::SetWindowLongPtrW(
mWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(*mPrevWndProc)));
- // If we've used the Windows App SDK to remove the minimize/maximize/close
- // entries from the titlebar, then the Windows App SDK sets its own WNDPROC
- // own the window, so this assertion would fail. But we only do this if
- // Mica is available.
- NS_ASSERTION(WinUtils::MicaAvailable() ||
- wndProcBeforeDissociate == nsWindow::WindowProc,
+ NS_ASSERTION(wndProcBeforeDissociate == nsWindow::WindowProc,
"Unstacked an unexpected native window procedure");
WinUtils::SetNSWindowPtr(mWnd, nullptr);
@@ -2835,9 +2849,7 @@ void nsWindow::SetCustomTitlebar(bool aCustomTitlebar) {
mCustomNonClientMetrics = {};
ResetLayout();
}
- // Not needed for PiP windows, and using the Windows App SDK on
- // these windows causes them to go under the taskbar (bug 1995838)
- if (!mPIPWindow) {
+ if (ShouldAssociateWithWinAppSDK()) {
WindowsUIUtils::SetIsTitlebarCollapsed(mWnd, mCustomNonClient);
}
}
diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h
index 20f016757dfee..2756b248368a3 100644
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -335,6 +335,8 @@ class nsWindow final : public nsIWidget {
bool IsRTL() const { return mIsRTL; }
+ bool ShouldAssociateWithWinAppSDK() const;
+
/**
* AssociateDefaultIMC() associates or disassociates the default IMC for
* the window.

View File

@@ -0,0 +1,58 @@
diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -850,13 +850,10 @@
bool mHasTaskbarIconBeenCreated = false;
// Whether we're in the process of sending a WM_SETTEXT ourselves
bool mSendingSetText = false;
- // Whether we're a PIP window.
- bool mPIPWindow : 1;
-
// Whether we are asked to render a mica backdrop.
bool mMicaBackdrop : 1;
int32_t mCachedHitTestResult = 0;
diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -815,11 +815,10 @@
**************************************************************/
nsWindow::nsWindow()
: nsIWidget(BorderStyle::Default),
mFrameState(std::in_place, this),
- mPIPWindow(false),
mMicaBackdrop(false),
mLastPaintEndTime(TimeStamp::Now()),
mCachedHitTestTime(TimeStamp::Now()),
mSizeConstraintsScale(GetDefaultScale().scale) {
if (!gInitializedVirtualDesktopManager) {
@@ -1026,11 +1025,10 @@
HWND parent =
aParent ? (HWND)aParent->GetNativeData(NS_NATIVE_WINDOW) : nullptr;
mIsRTL = aInitData.mRTL;
- mPIPWindow = aInitData.mPIPWindow;
mOpeningAnimationSuppressed = aInitData.mIsAnimationSuppressed;
mAlwaysOnTop = aInitData.mAlwaysOnTop;
mIsAlert = aInitData.mIsAlert;
mResizable = aInitData.mResizable;
@@ -2805,11 +2803,11 @@
} else if (sizeMode == nsSizeMode_Maximized) {
// We make the entire frame part of the client area. We leave the default
// frame sizes for left, right and bottom since Windows will automagically
// position the edges "offscreen" for maximized windows.
metrics.mOffset.top = metrics.mCaptionHeight;
- } else if (mPIPWindow &&
+ } else if (mIsPIPWindow &&
!StaticPrefs::widget_windows_pip_decorations_enabled()) {
metrics.mOffset = metrics.DefaultMargins();
} else {
metrics.mOffset = NormalWindowNonClientOffset();
}

View File

@@ -0,0 +1,34 @@
From dd4460727998a53e9fa7372afba2a93a9546cec3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Fri, 28 Nov 2025 15:06:26 +0000
Subject: [PATCH] Bug 2002986 - Use IAppWindowTitlebar::ResetToDefault() for
non-collapsed titlebar. r=win-reviewers,gstoll
This seems to actually go to the default DWM stuff and is the documented
way of doing so:
https://learn.microsoft.com/en-us/windows/apps/develop/title-bar#reset-the-title-bar
Differential Revision: https://phabricator.services.mozilla.com/D274413
---
widget/windows/WindowsUIUtils.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/widget/windows/WindowsUIUtils.cpp b/widget/windows/WindowsUIUtils.cpp
index a5a6c893e7056..abaabfba69dfa 100644
--- a/widget/windows/WindowsUIUtils.cpp
+++ b/widget/windows/WindowsUIUtils.cpp
@@ -1394,7 +1394,11 @@ void WindowsUIUtils::SetIsTitlebarCollapsed(HWND aWnd, bool aIsCollapsed) {
MOZ_ASSERT_UNREACHABLE("IAppWindowTitleBar could not be acquired");
return;
}
- hr = titleBar->put_ExtendsContentIntoTitleBar(aIsCollapsed);
+ if (aIsCollapsed) {
+ hr = titleBar->put_ExtendsContentIntoTitleBar(aIsCollapsed);
+ } else {
+ hr = titleBar->ResetToDefault();
+ }
if (FAILED(hr)) {
MOZ_LOG(gWindowsLog, LogLevel::Error,
("Skipping SetIsTitlebarCollapsed() because "

View File

@@ -0,0 +1,34 @@
From dd4460727998a53e9fa7372afba2a93a9546cec3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Fri, 28 Nov 2025 15:06:26 +0000
Subject: [PATCH] Bug 2002986 - Use IAppWindowTitlebar::ResetToDefault() for
non-collapsed titlebar. r=win-reviewers,gstoll
This seems to actually go to the default DWM stuff and is the documented
way of doing so:
https://learn.microsoft.com/en-us/windows/apps/develop/title-bar#reset-the-title-bar
Differential Revision: https://phabricator.services.mozilla.com/D274413
---
widget/windows/WindowsUIUtils.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/widget/windows/WindowsUIUtils.cpp b/widget/windows/WindowsUIUtils.cpp
index a5a6c893e7056..abaabfba69dfa 100644
--- a/widget/windows/WindowsUIUtils.cpp
+++ b/widget/windows/WindowsUIUtils.cpp
@@ -1394,7 +1394,11 @@ void WindowsUIUtils::SetIsTitlebarCollapsed(HWND aWnd, bool aIsCollapsed) {
MOZ_ASSERT_UNREACHABLE("IAppWindowTitleBar could not be acquired");
return;
}
- hr = titleBar->put_ExtendsContentIntoTitleBar(aIsCollapsed);
+ if (aIsCollapsed) {
+ hr = titleBar->put_ExtendsContentIntoTitleBar(aIsCollapsed);
+ } else {
+ hr = titleBar->ResetToDefault();
+ }
if (FAILED(hr)) {
MOZ_LOG(gWindowsLog, LogLevel::Error,
("Skipping SetIsTitlebarCollapsed() because "

View File

@@ -18,13 +18,13 @@
@keyframes zen-theme-picker-dot-animation { @keyframes zen-theme-picker-dot-animation {
from { from {
transform: scale(0.8) translate(-50%, -50%); transform: scale(0.8) translate(-25%, -25%);
} }
50% { 50% {
transform: scale(1.2) translate(-50%, -50%); transform: scale(1.2) translate(-25%, -25%);
} }
to { to {
transform: scale(1) translate(-50%, -50%); transform: scale(1) translate(-25%, -25%);
} }
} }

View File

@@ -45,6 +45,7 @@ const MAX_OPACITY = 0.9;
const MIN_OPACITY = AppConstants.platform === 'macosx' ? 0.25 : 0.35; const MIN_OPACITY = AppConstants.platform === 'macosx' ? 0.25 : 0.35;
const EXPLICIT_LIGHTNESS_TYPE = 'explicit-lightness'; const EXPLICIT_LIGHTNESS_TYPE = 'explicit-lightness';
const EXPLICIT_BLACKWHITE_TYPE = 'explicit-black-white';
export class nsZenThemePicker extends nsZenMultiWindowFeature { export class nsZenThemePicker extends nsZenMultiWindowFeature {
static MAX_DOTS = 3; static MAX_DOTS = 3;
@@ -146,6 +147,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
get colorHarmonies() { get colorHarmonies() {
return [ return [
{ type: 'complementary', angles: [180] }, { type: 'complementary', angles: [180] },
{ type: 'singleAnalogous', angles: [310] },
{ type: 'splitComplementary', angles: [150, 210] }, { type: 'splitComplementary', angles: [150, 210] },
{ type: 'analogous', angles: [50, 310] }, { type: 'analogous', angles: [50, 310] },
{ type: 'triadic', angles: [120, 240] }, { type: 'triadic', angles: [120, 240] },
@@ -198,6 +200,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
} }
this.dots = this.dots.slice(0, numDots); this.dots = this.dots.slice(0, numDots);
} }
const type = target.getAttribute('data-type') || EXPLICIT_LIGHTNESS_TYPE;
// Generate new gradient from the single color given // Generate new gradient from the single color given
const [x, y] = rawPosition.split(',').map((pos) => parseInt(pos)); const [x, y] = rawPosition.split(',').map((pos) => parseInt(pos));
let dots = [ let dots = [
@@ -205,18 +208,18 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
ID: 0, ID: 0,
position: { x, y }, position: { x, y },
isPrimary: true, isPrimary: true,
type: EXPLICIT_LIGHTNESS_TYPE, type,
}, },
]; ];
for (let i = 1; i < numDots; i++) { for (let i = 1; i < numDots; i++) {
dots.push({ dots.push({
ID: i, ID: i,
position: { x: 0, y: 0 }, position: { x: 0, y: 0 },
type: EXPLICIT_LIGHTNESS_TYPE, type,
}); });
} }
this.useAlgo = algo; this.useAlgo = algo;
this.#currentLightness = lightness; if (lightness !== null) this.#currentLightness = lightness;
dots = this.calculateCompliments(dots, 'update', this.useAlgo); dots = this.calculateCompliments(dots, 'update', this.useAlgo);
this.handleColorPositions(dots, true); this.handleColorPositions(dots, true);
this.updateCurrentWorkspace(); this.updateCurrentWorkspace();
@@ -416,10 +419,10 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
calculateInitialPosition([r, g, b]) { calculateInitialPosition([r, g, b]) {
// This function is called before the picker is even rendered, so we hard code the dimensions // This function is called before the picker is even rendered, so we hard code the dimensions
// important: If any sort of sizing is changed, make sure changes are reflected here // important: If any sort of sizing is changed, make sure changes are reflected here
const padding = 30; const padding = 0;
const rect = { const rect = {
width: 338, width: 380 + padding * 2,
height: 338, height: 380 + padding * 2,
}; };
const centerX = rect.width / 2; const centerX = rect.width / 2;
const centerY = rect.height / 2; const centerY = rect.height / 2;
@@ -437,7 +440,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
const gradient = this.panel.querySelector('.zen-theme-picker-gradient'); const gradient = this.panel.querySelector('.zen-theme-picker-gradient');
const rect = gradient.getBoundingClientRect(); const rect = gradient.getBoundingClientRect();
const padding = 30; // each side const padding = 30; // each side
const dotHalfSize = 36 / 2; // half the size of the dot const dotHalfSize = 38 / 2; // half the size of the dot
x += dotHalfSize; x += dotHalfSize;
y += dotHalfSize; y += dotHalfSize;
rect.width += padding * 2; // Adjust width and height for padding rect.width += padding * 2; // Adjust width and height for padding
@@ -452,7 +455,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
angle += 360; // Normalize to [0, 360) angle += 360; // Normalize to [0, 360)
} }
const normalizedDistance = 1 - Math.min(distance / radius, 1); // Normalize distance to [0, 1] const normalizedDistance = 1 - Math.min(distance / radius, 1); // Normalize distance to [0, 1]
const hue = (angle / 360) * 360; // Normalize angle to [0, 360) let hue = (angle / 360) * 360; // Normalize angle to [0, 360)
let saturation = normalizedDistance * 100; // stays high even in center let saturation = normalizedDistance * 100; // stays high even in center
if (type !== EXPLICIT_LIGHTNESS_TYPE) { if (type !== EXPLICIT_LIGHTNESS_TYPE) {
saturation = 80 + (1 - normalizedDistance) * 20; saturation = 80 + (1 - normalizedDistance) * 20;
@@ -460,7 +463,12 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
// For example, moving the dot outside will have higher lightness, while moving it inside will have lower lightness // 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); this.#currentLightness = Math.round((1 - normalizedDistance) * 100);
} }
const lightness = this.#currentLightness; // Fixed lightness for simplicity let lightness = this.#currentLightness; // Fixed lightness for simplicity
if (type === EXPLICIT_BLACKWHITE_TYPE) {
// We can only get grayscales from white to black
saturation = 0;
lightness = Math.round((1 - normalizedDistance) * 100);
}
const [r, g, b] = this.hslToRgb(hue / 360, saturation / 100, lightness / 100); const [r, g, b] = this.hslToRgb(hue / 360, saturation / 100, lightness / 100);
return [ return [
Math.min(255, Math.max(0, r)), Math.min(255, Math.max(0, r)),
@@ -675,7 +683,13 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
} }
if (action === 'remove') { if (action === 'remove') {
return colorHarmonies.find((harmony) => harmony.angles.length === numDots); let harmony = colorHarmonies.find((harmony) => harmony.angles.length === numDots);
// If we are coming from 3 analogous dots, we should now go to singleAnalogous if
// there are 2 dots left
if (harmony.type === 'analogous' && numDots === 1) {
harmony = colorHarmonies.find((harmony) => harmony.type === 'singleAnalogous');
}
return harmony;
} }
if (action === 'add') { if (action === 'add') {
return colorHarmonies.find((harmony) => harmony.angles.length + 1 === numDots); return colorHarmonies.find((harmony) => harmony.angles.length + 1 === numDots);
@@ -700,7 +714,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
const dotPad = this.panel.querySelector('.zen-theme-picker-gradient'); const dotPad = this.panel.querySelector('.zen-theme-picker-gradient');
const rect = dotPad.getBoundingClientRect(); const rect = dotPad.getBoundingClientRect();
const padding = 30; const padding = 0;
let updatedDots = [...dots]; let updatedDots = [...dots];
const centerPosition = { x: rect.width / 2, y: rect.height / 2 }; const centerPosition = { x: rect.width / 2, y: rect.height / 2 };
@@ -843,16 +857,30 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
this.handleColorPositions(colorPositions); this.handleColorPositions(colorPositions);
this.updateCurrentWorkspace(); this.updateCurrentWorkspace();
return; return;
} else if (target.id === 'PanelUI-zen-gradient-generator-color-toggle-algo') {
const applicableHarmonies = this.colorHarmonies.filter(
(harmony) => harmony.angles.length + 1 === this.dots.length
);
let currentIndex = applicableHarmonies.findIndex((harmony) => harmony.type === this.useAlgo);
const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % applicableHarmonies.length;
this.useAlgo = applicableHarmonies[nextIndex].type;
let colorPositions = this.calculateCompliments(this.dots, 'update', this.useAlgo);
this.handleColorPositions(colorPositions);
this.updateCurrentWorkspace();
return;
} }
if (event.button !== 0 || this.dragging || this.recentlyDragged) return; if (event.button !== 0 || this.dragging || this.recentlyDragged) return;
const gradient = this.panel.querySelector('.zen-theme-picker-gradient'); const gradient = this.panel.querySelector('.zen-theme-picker-gradient');
const rect = gradient.getBoundingClientRect(); const rect = gradient.getBoundingClientRect();
const padding = 30; const padding = 0;
const centerX = rect.left + rect.width / 2; const centerX = rect.left + rect.width / 2 - padding;
const centerY = rect.top + rect.height / 2; const centerY = rect.top + rect.height / 2 - padding;
const radius = (rect.width - padding) / 2; const radius = (rect.width - padding) / 2;
let pixelX = event.clientX; let pixelX = event.clientX;
let pixelY = event.clientY; let pixelY = event.clientY;
@@ -982,7 +1010,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
if (this.dragging) { if (this.dragging) {
event.preventDefault(); event.preventDefault();
const rect = this.panel.querySelector('.zen-theme-picker-gradient').getBoundingClientRect(); const rect = this.panel.querySelector('.zen-theme-picker-gradient').getBoundingClientRect();
const padding = 30; // each side const padding = 0; // each side
// do NOT let the ball be draged outside of an imaginary circle. You can drag it anywhere inside the circle // do NOT let the ball be draged outside of an imaginary circle. You can drag it anywhere inside the circle
// if the distance between the center of the circle and the dragged ball is bigger than the radius, then the ball // if the distance between the center of the circle and the dragged ball is bigger than the radius, then the ball
// should be placed on the edge of the circle. If it's inside the circle, then the ball just follows the mouse // should be placed on the edge of the circle. If it's inside the circle, then the ball just follows the mouse
@@ -1164,7 +1192,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
if (!forToolbar) { if (!forToolbar) {
return [ return [
`linear-gradient(${rotation}deg, ${this.getSingleRGBColor(themedColors[1], forToolbar)} 0%, transparent 100%)`, `linear-gradient(${rotation}deg, ${this.getSingleRGBColor(themedColors[1], forToolbar)} 0%, transparent 100%)`,
`linear-gradient(${rotation + 180}deg, ${this.getSingleRGBColor(themedColors[0], forToolbar)} 0%, transparent 80%)`, `linear-gradient(${rotation + 180}deg, ${this.getSingleRGBColor(themedColors[0], forToolbar)} 0%, transparent 100%)`,
] ]
.reverse() .reverse()
.join(', '); .join(', ');
@@ -1175,8 +1203,8 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
let color2 = this.getSingleRGBColor(themedColors[0], forToolbar); let color2 = this.getSingleRGBColor(themedColors[0], forToolbar);
let color3 = this.getSingleRGBColor(themedColors[1], forToolbar); let color3 = this.getSingleRGBColor(themedColors[1], forToolbar);
return [ return [
`radial-gradient(circle at 0% 0%, ${color2} -10%, transparent 100%)`,
`linear-gradient(to top, ${color1} -50%, transparent 125%)`, `linear-gradient(to top, ${color1} -50%, transparent 125%)`,
`radial-gradient(circle at 0% 0%, ${color2} 10%, transparent 80%)`,
`radial-gradient(circle at 100% -100%, ${color3} -100%, transparent 400%)`, `radial-gradient(circle at 100% -100%, ${color3} -100%, transparent 400%)`,
].join(', '); ].join(', ');
} }
@@ -1389,6 +1417,9 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
workspaceTheme.gradientColors.length === 0 || workspaceTheme.gradientColors.length === 0 ||
(button.id === 'PanelUI-zen-gradient-generator-color-add' (button.id === 'PanelUI-zen-gradient-generator-color-add'
? workspaceTheme.gradientColors.length >= nsZenThemePicker.MAX_DOTS ? workspaceTheme.gradientColors.length >= nsZenThemePicker.MAX_DOTS
: false) ||
(button.id === 'PanelUI-zen-gradient-generator-color-toggle-algo'
? workspaceTheme.gradientColors.length < 2
: false); : false);
} }
const clickToAdd = browser.document.getElementById( const clickToAdd = browser.document.getElementById(

View File

@@ -5,7 +5,7 @@
*/ */
#PanelUI-zen-gradient-generator { #PanelUI-zen-gradient-generator {
--panel-width: 360px; --panel-width: 380px;
--panel-padding: 10px; --panel-padding: 10px;
min-width: var(--panel-width); min-width: var(--panel-width);
} }
@@ -102,15 +102,16 @@
overflow: auto; overflow: auto;
scrollbar-width: none; scrollbar-width: none;
scroll-behavior: smooth; scroll-behavior: smooth;
mask-image: linear-gradient(to right, transparent 0%, black 2.5%, black 97.5%, transparent 100%);
& > hbox { & > hbox {
justify-content: space-around; justify-content: space-between;
min-width: 100%; min-width: 100%;
padding: 0 1px;
& > box { & > box {
width: 22px; width: 26px;
height: 22px; height: 26px;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
border-radius: 50%; border-radius: 50%;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
@@ -251,17 +252,17 @@
min-height: calc(var(--panel-width) - var(--panel-padding) * 2 - 2px); min-height: calc(var(--panel-width) - var(--panel-padding) * 2 - 2px);
background: light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.03)); background: light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.03));
background-image: radial-gradient( background-image: radial-gradient(
light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.1)) 1px, light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.1)) 0.5px,
transparent 0 transparent 0
); );
background-position: -23px -23px; background-position: -23px -23px;
background-size: 6px 6px; background-size: 6px 6px;
& .zen-theme-picker-dot { & .zen-theme-picker-dot {
position: absolute; position: fixed;
z-index: 2; z-index: 2;
width: 18px; width: 20px;
height: 18px; height: 20px;
border-radius: 50%; border-radius: 50%;
background: var(--zen-theme-picker-dot-color); background: var(--zen-theme-picker-dot-color);
@media (-prefers-color-scheme: dark) { @media (-prefers-color-scheme: dark) {
@@ -270,25 +271,25 @@
cursor: pointer; cursor: pointer;
border: 3px solid #ffffff; border: 3px solid #ffffff;
animation: zen-theme-picker-dot-animation 0.5s; animation: zen-theme-picker-dot-animation 0.5s;
transform: translate(-50%, -50%); transform: translate(-25%, -25%);
pointer-events: none; pointer-events: none;
transform-origin: center center; transform-origin: center center;
&:first-of-type { &:first-of-type {
width: 36px; width: 38px;
height: 36px; height: 38px;
border-width: 4px; border-width: 4px;
z-index: 2; z-index: 2;
pointer-events: all; pointer-events: all;
transition: transform 0.2s; transition: transform 0.2s;
z-index: 999; z-index: 999;
&:hover { &:hover {
transform: scale(1.05) translate(-50%, -50%); transform: scale(1.05) translate(-25%, -25%);
} }
} }
&[dragging='true'] { &[dragging='true'] {
transform: scale(1.2) translate(-50%, -50%) !important; transform: scale(1.2) translate(-25%, -25%) !important;
} }
} }
} }
@@ -329,10 +330,10 @@
min-width: fit-content !important; min-width: fit-content !important;
transition: background 0.2s; transition: background 0.2s;
appearance: none; appearance: none;
max-height: 26px; max-height: 30px;
max-width: 26px; max-width: 30px;
min-height: 26px; min-height: 30px;
min-width: 26px !important; min-width: 30px !important;
color: light-dark(rgba(0, 0, 0, 0.7), rgba(255, 255, 255, 0.9)); color: light-dark(rgba(0, 0, 0, 0.7), rgba(255, 255, 255, 0.9));
& .button-box { & .button-box {