Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ zen-look-and-feel-compact-view-top-toolbar =
zen-look-and-feel-compact-toolbar-flash-popup =
.label = Briefly make the toolbar popup when switching or opening new tabs in compact mode

zen-look-and-feel-app-icon-header = App Icon
zen-look-and-feel-app-icon-description = Change the icon used by the running app on macOS
zen-look-and-feel-app-icon-label = Variant
zen-look-and-feel-app-icon-default =
.label = Default
zen-look-and-feel-app-icon-alternate =
.label = Alternative

pane-zen-tabs-title = Tab Management
category-zen-workspaces =
.tooltiptext = { pane-zen-tabs-title }
Expand Down Expand Up @@ -357,4 +365,4 @@ zen-devtools-toggle-dom-shortcut = Toggle DOM
zen-devtools-toggle-accessibility-shortcut = Toggle Accessibility
zen-close-all-unpinned-tabs-shortcut = Close All Unpinned Tabs
zen-new-unsynced-window-shortcut = New Blank Window
zen-duplicate-tab-shortcut = Duplicate Tab
zen-duplicate-tab-shortcut = Duplicate Tab
49 changes: 46 additions & 3 deletions src/browser/components/preferences/zen-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,16 @@ var gZenMarketplaceManager = {

const kZenExtendedSidebar = "zen.view.sidebar-expanded";
const kZenSingleToolbar = "zen.view.use-single-toolbar";
const kZenMacOSAppIconVariant = "zen.widget.macos.app-icon-variant";
const kZenMacOSAppIconPreviewSrcByVariant = {
default: "chrome://branding/content/icon48.png",
alternate: "chrome://browser/content/zen-images/app-icons/alternate-preview.png",
};

function getZenMacOSAppIconVariant() {
const variant = Services.prefs.getStringPref(kZenMacOSAppIconVariant, "default");
return kZenMacOSAppIconPreviewSrcByVariant[variant] ? variant : "default";
}

var gZenLooksAndFeel = {
init() {
Expand All @@ -652,18 +662,25 @@ var gZenLooksAndFeel = {
}
this.__hasInitialized = true;
gZenMarketplaceManager.init();
for (const pref of [kZenExtendedSidebar, kZenSingleToolbar]) {
for (const pref of [kZenExtendedSidebar, kZenSingleToolbar, kZenMacOSAppIconVariant]) {
Services.prefs.addObserver(pref, this);
}
window.addEventListener("unload", () => {
for (const pref of [kZenExtendedSidebar, kZenSingleToolbar]) {
for (const pref of [kZenExtendedSidebar, kZenSingleToolbar, kZenMacOSAppIconVariant]) {
Services.prefs.removeObserver(pref, this);
}
});
this.applySidebarLayout();
this.initMacOSAppIconVariantControl();
this.applyMacOSAppIconPreview();
},

observe() {
observe(_subject, _topic, data) {
if (data == kZenMacOSAppIconVariant) {
this.applyMacOSAppIconPreview();
return;
}

this.applySidebarLayout();
},

Expand Down Expand Up @@ -708,6 +725,27 @@ var gZenLooksAndFeel = {
});
}
},

applyMacOSAppIconPreview() {
const preview = document.getElementById("zenLooksAndFeelMacOSAppIconPreview");
if (!preview) {
return;
}

preview.setAttribute(
"src",
kZenMacOSAppIconPreviewSrcByVariant[getZenMacOSAppIconVariant()]
);
},

initMacOSAppIconVariantControl() {
const variantControl = document.getElementById("zenLooksAndFeelMacOSAppIconVariant");
if (!variantControl) {
return;
}

Preferences.addSyncFromPrefListener(variantControl, getZenMacOSAppIconVariant);
},
};

var gZenWorkspacesSettings = {
Expand Down Expand Up @@ -1135,6 +1173,11 @@ Preferences.addAll([
type: "bool",
default: true,
},
{
id: "zen.widget.macos.app-icon-variant",
type: "string",
default: "default",
},
{
id: "zen.workspaces.hide-default-container-indicator",
type: "bool",
Expand Down
27 changes: 27 additions & 0 deletions src/browser/components/preferences/zenLooksAndFeel.inc.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,33 @@
data-l10n-id="zen-look-and-feel-compact-toolbar-flash-popup"
preference="zen.view.compact.toolbar-flash-popup"/>
</vbox>

#ifdef XP_MACOSX
<label><html:h2 data-l10n-id="zen-look-and-feel-app-icon-header"/></label>
<description class="description-deemphasized" data-l10n-id="zen-look-and-feel-app-icon-description" />

<hbox id="zenMacOSAppIconSetting" align="center">
<html:div class="zenAppIconPreviewFrame">
<html:img id="zenLooksAndFeelMacOSAppIconPreview"
src="chrome://branding/content/icon48.png" />
</html:div>

<vbox flex="1">
<label data-l10n-id="zen-look-and-feel-app-icon-label"/>
<menulist id="zenLooksAndFeelMacOSAppIconVariant"
preference="zen.widget.macos.app-icon-variant">
<menupopup>
<menuitem data-l10n-id="zen-look-and-feel-app-icon-default"
label="Default"
value="default"/>
<menuitem data-l10n-id="zen-look-and-feel-app-icon-alternate"
label="Alternative"
value="alternate"/>
</menupopup>
</menulist>
</vbox>
</hbox>
#endif
</groupbox>

<hbox id="zenGlanceCategory"
Expand Down
24 changes: 24 additions & 0 deletions src/browser/themes/shared/preferences/zen-preferences.css
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,30 @@ groupbox h2 {
margin-top: 15px;
}

#zenMacOSAppIconSetting {
gap: 16px;
margin-block: 10px 14px;

& .zenAppIconPreviewFrame {
display: flex;
align-items: center;
justify-content: center;
width: 80px;
min-width: 80px;
height: 80px;
border: 1px solid var(--zen-colors-border);
border-radius: 18px;
background: color-mix(in srgb, var(--zen-colors-tertiary) 70%, transparent);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}

& #zenLooksAndFeelMacOSAppIconPreview {
width: 64px;
height: 64px;
border-radius: 18px;
}
}

.zen-compact-mode-styles-browser-wrapper {
width: 55%;
height: 60px;
Expand Down
1 change: 1 addition & 0 deletions src/zen/@types/lib.gecko.xpcom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19519,6 +19519,7 @@ declare global {
): void;
canShare(): boolean;
playHapticFeedback(): void;
setMacOSAppIcon(iconBundlePath: string, iconName: string): void;
}

// https://searchfox.org/mozilla-central/source/zen/drag-and-drop/nsIZenDragAndDrop.idl
Expand Down
2 changes: 2 additions & 0 deletions src/zen/common/Components.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

category browser-before-ui-startup resource:///modules/ZenActorsManager.sys.mjs gZenActorsManager.init
category browser-before-ui-startup resource:///modules/ZenAppIcon.sys.mjs ZenAppIcon.init
category browser-quit-application-granted resource:///modules/ZenAppIcon.sys.mjs ZenAppIcon.uninit
10 changes: 10 additions & 0 deletions src/zen/common/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

EXTRA_JS_MODULES += [
"sys/ZenActorsManager.sys.mjs",
"sys/ZenAppIcon.sys.mjs",
"sys/ZenCustomizableUI.sys.mjs",
"sys/ZenUIMigration.sys.mjs",
]
Expand All @@ -12,3 +13,12 @@ EXTRA_JS_MODULES.zen.ui += [
"sys/ui/ZenProgressBar.sys.mjs",
"sys/ui/ZenUIComponent.sys.mjs",
]

FINAL_TARGET_FILES["zen-app-icons"]["alternate.bundle"]["Contents"] += [
"../images/app-icons/alternate.bundle/Contents/Info.plist",
]

FINAL_TARGET_FILES["zen-app-icons"]["alternate.bundle"]["Contents"]["Resources"] += [
"../images/app-icons/alternate-preview.png",
"../images/app-icons/alternate.bundle/Contents/Resources/Assets.car",
]
76 changes: 76 additions & 0 deletions src/zen/common/sys/ZenAppIcon.sys.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// 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/.

const ZEN_MACOS_APP_ICON_VARIANT_PREF = "zen.widget.macos.app-icon-variant";
const ZEN_MACOS_APP_ICON_RESOURCES = {
alternate: {
bundlePath: "zen-app-icons/alternate.bundle",
iconName: "AppIcon",
},
};

class nsZenAppIcon {
#initialized = false;
#hasAppliedAfterStartup = false;
#observingStartup = false;

init() {
if (this.#initialized || Services.appinfo.OS != "Darwin") {
return;
}

this.#initialized = true;
this.#hasAppliedAfterStartup = false;
Services.prefs.addObserver(ZEN_MACOS_APP_ICON_VARIANT_PREF, this);
Services.obs.addObserver(this, "browser-delayed-startup-finished");
this.#observingStartup = true;
void this.#applyMacOSAppIconVariant();
}

uninit() {
if (!this.#initialized) {
return;
}

this.#initialized = false;
Services.prefs.removeObserver(ZEN_MACOS_APP_ICON_VARIANT_PREF, this);
if (this.#observingStartup) {
Services.obs.removeObserver(this, "browser-delayed-startup-finished");
this.#observingStartup = false;
}
}

observe(_subject, topic, data) {
if (topic == "nsPref:changed" && data == ZEN_MACOS_APP_ICON_VARIANT_PREF) {
void this.#applyMacOSAppIconVariant();
return;
}

if (topic == "browser-delayed-startup-finished" && !this.#hasAppliedAfterStartup) {
this.#hasAppliedAfterStartup = true;
Services.obs.removeObserver(this, "browser-delayed-startup-finished");
this.#observingStartup = false;
void this.#applyMacOSAppIconVariant();
}
}

#applyMacOSAppIconVariant() {
const variant = Services.prefs.getStringPref(
ZEN_MACOS_APP_ICON_VARIANT_PREF,
"default"
);
const iconResource = ZEN_MACOS_APP_ICON_RESOURCES[variant];

try {
Services.zen.setMacOSAppIcon(
iconResource?.bundlePath ?? "",
iconResource?.iconName ?? ""
);
} catch (error) {
console.error("ZenAppIcon: failed to apply macOS app icon variant", error);
}
}
}

export const ZenAppIcon = new nsZenAppIcon();
Binary file added src/zen/images/app-icons/alternate-preview.png
Comment thread
yordis marked this conversation as resolved.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/zen/images/app-icons/alternate.bundle/Contents/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>app.zen-browser.icons.alternate</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
</dict>
</plist>
Binary file not shown.
1 change: 1 addition & 0 deletions src/zen/images/jar.inc.mn
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
content/browser/zen-images/layouts/collapsed.png (../../zen/images/layouts/collapsed.png)
content/browser/zen-images/layouts/multiple-toolbar.png (../../zen/images/layouts/multiple-toolbar.png)
content/browser/zen-images/layouts/single-toolbar.png (../../zen/images/layouts/single-toolbar.png)
content/browser/zen-images/app-icons/alternate-preview.png (../../zen/images/app-icons/alternate-preview.png)
content/browser/zen-images/grain-bg.png (../../zen/images/grain-bg.png)
content/browser/zen-images/note-indicator.svg (../../zen/images/note-indicator.svg)

Expand Down
6 changes: 6 additions & 0 deletions src/zen/toolkit/common/ZenCommonUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ ZenCommonUtils::PlayHapticFeedback() {
return PlayHapticFeedbackInternal();
}

NS_IMETHODIMP
ZenCommonUtils::SetMacOSAppIcon(const nsAString& aIconBundlePath,
const nsAString& aIconName) {
return SetMacOSAppIconInternal(aIconBundlePath, aIconName);
}

NS_IMETHODIMP
ZenCommonUtils::CanShare(bool* canShare) {
auto aWindow = GetMostRecentWindow();
Expand Down
7 changes: 7 additions & 0 deletions src/zen/toolkit/common/ZenCommonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,15 @@ class ZenCommonUtils final : public nsIZenCommonUtils {
// No-op on non-macOS platforms
return NS_OK;
}
static auto SetMacOSAppIconInternal(const nsAString& aIconBundlePath,
const nsAString& aIconName) -> nsresult {
// No-op on non-macOS platforms
return NS_OK;
}
#else
static auto PlayHapticFeedbackInternal() -> nsresult;
static auto SetMacOSAppIconInternal(const nsAString& aIconBundlePath,
const nsAString& aIconName) -> nsresult;
#endif
};

Expand Down
Loading