🆕 Add macOS application packaging support with custom Dock icon integration and build documentation.

This commit is contained in:
2026-07-05 01:33:34 +08:00
parent 69f9b844ac
commit c78f4ac231
7 changed files with 153 additions and 1 deletions
+3
View File
@@ -1,5 +1,8 @@
README.md.tinyenc README.md.tinyenc
secure-editor-go secure-editor-go
secure-editor-go.app
logo.icns
logo.iconset
# ---> macOS # ---> macOS
# General # General
+28
View File
@@ -0,0 +1,28 @@
<?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>CFBundleName</key>
<string>Secure Editor</string>
<key>CFBundleDisplayName</key>
<string>Secure Editor</string>
<key>CFBundleIdentifier</key>
<string>ink.hatter.secure-editor-go</string>
<key>CFBundleVersion</key>
<string>0.1.1</string>
<key>CFBundleShortVersionString</key>
<string>0.1.1</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleExecutable</key>
<string>secure-editor-go</string>
<key>CFBundleIconFile</key>
<string>logo.icns</string>
<key>CFBundleIconName</key>
<string>logo</string>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
+22
View File
@@ -8,6 +8,28 @@ go mod tidy
go build go build
``` ```
## 打包为 macOS 应用(让 Dock 显示 LOGO
在 macOS 上,独立的命令行二进制在 Dock 中只会显示通用图标,`app.SetIcon` / `window.SetIcon` 无法改变 Dock 图标。要让 Dock 显示 `logo.jpeg`,需要将程序打包成 `.app` 应用包并附带 `.icns` 图标:
```shell
./build.sh # 编译并生成 secure-editor-go.app(含由 logo.jpeg 转换的 logo.icns
./build.sh --binary-only # 仅编译裸二进制
```
运行(仍以命令行参数方式调用包内可执行文件):
```shell
./secure-editor-go.app/Contents/MacOS/secure-editor-go <file> aes-256-gcm <key> <nonce>
```
`build.sh` 使用 macOS 自带的 `sips``iconutil``logo.jpeg` 生成多尺寸的 `logo.icns`,再按 `Info.plist` 组装 `.app` 包。重新打包后若 Dock 图标未刷新,可执行:
```shell
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f secure-editor-go.app
killall Dock
```
## 功能特性 ## 功能特性
- **AES-256-GCM 加解密**:以 `aes-256-gcm` 算法解密文件内容并在编辑器中展示,保存时重新加密写回(保留原文件权限位)。 - **AES-256-GCM 加解密**:以 `aes-256-gcm` 算法解密文件内容并在编辑器中展示,保存时重新加密写回(保留原文件权限位)。
Executable
+81
View File
@@ -0,0 +1,81 @@
#!/usr/bin/env bash
# Build secure-editor-go and package it as a macOS .app bundle so the
# Dock shows the bundled logo (iconutil/sips convert logo.jpeg -> logo.icns).
#
# Usage:
# ./build.sh # build binary + assemble .app bundle
# ./build.sh --binary-only # build only the plain binary, no bundle
#
# Run the app:
# ./secure-editor-go.app/Contents/MacOS/secure-editor-go <file> aes-256-gcm <key> <nonce>
set -euo pipefail
APP_NAME="secure-editor-go"
APP_BUNDLE="${APP_NAME}.app"
THIS_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$THIS_DIR"
BINARY_ONLY=0
if [ "${1-}" = "--binary-only" ]; then
BINARY_ONLY=1
fi
# 1. Build the Go binary.
echo "==> building binary"
go build -o "$APP_NAME" .
if [ "$BINARY_ONLY" -eq 1 ]; then
echo "==> done (binary only): $APP_NAME"
exit 0
fi
# 2. Generate logo.icns from logo.jpeg using macOS tooling.
if [ -f logo.jpeg ]; then
echo "==> generating logo.icns"
rm -rf logo.iconset logo.icns
mkdir -p logo.iconset
gen() {
# $1 = pixel size, $2 = iconset file name (without .png)
sips -s format png -z "$1" "$1" logo.jpeg --out "logo.iconset/$2.png" >/dev/null
}
gen 16 icon_16x16
gen 32 icon_16x16@2x
gen 32 icon_32x32
gen 64 icon_32x32@2x
gen 128 icon_128x128
gen 256 icon_128x128@2x
gen 256 icon_256x256
gen 512 icon_256x256@2x
gen 512 icon_512x512
gen 1024 icon_512x512@2x
iconutil -c icns logo.iconset -o logo.icns
rm -rf logo.iconset
else
echo "warning: logo.jpeg not found, bundle will have no icon" >&2
fi
# 3. Assemble the .app bundle.
echo "==> assembling $APP_BUNDLE"
rm -rf "$APP_BUNDLE"
mkdir -p "$APP_BUNDLE/Contents/MacOS"
mkdir -p "$APP_BUNDLE/Contents/Resources"
cp "$APP_NAME" "$APP_BUNDLE/Contents/MacOS/$APP_NAME"
[ -f logo.icns ] && cp logo.icns "$APP_BUNDLE/Contents/Resources/logo.icns"
cp Info.plist "$APP_BUNDLE/Contents/Info.plist"
# Refresh LaunchServices' view of the bundle so the icon takes effect.
touch "$APP_BUNDLE"
touch "$APP_BUNDLE/Contents/Info.plist"
# 4. (Optional) register with LaunchServices so the icon is picked up.
LSREGISTER="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister"
if [ -x "$LSREGISTER" ]; then
"$LSREGISTER" "$APP_BUNDLE" >/dev/null 2>&1 || true
fi
echo "==> done: $APP_BUNDLE"
echo " run: $APP_BUNDLE/Contents/MacOS/$APP_NAME <file> aes-256-gcm <key> <nonce>"
+16
View File
@@ -0,0 +1,16 @@
package main
import (
_ "embed"
"fyne.io/fyne/v2"
)
//go:embed logo.jpeg
var logoBytes []byte
// appIcon returns the bundled logo as a Fyne resource, used as the
// application/window icon shown while the editor loads.
func appIcon() fyne.Resource {
return fyne.NewStaticResource("logo.jpeg", logoBytes)
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

+2
View File
@@ -146,10 +146,12 @@ func main() {
isReadonly := isReadonly() isReadonly := isReadonly()
secureEditorApp := app.New() secureEditorApp := app.New()
secureEditorApp.SetIcon(appIcon())
if !isReadonly { if !isReadonly {
secureEditorApp.Settings().SetTheme(&lightEditorTheme{Theme: theme.DefaultTheme()}) secureEditorApp.Settings().SetTheme(&lightEditorTheme{Theme: theme.DefaultTheme()})
} }
window := secureEditorApp.NewWindow(Title) window := secureEditorApp.NewWindow(Title)
window.SetIcon(appIcon())
cfg := loadConfig() cfg := loadConfig()
window.Resize(clampToScreen(fyne.NewSize(cfg.Width, cfg.Height))) window.Resize(clampToScreen(fyne.NewSize(cfg.Width, cfg.Height)))