🆕 Add macOS application packaging support with custom Dock icon integration and build documentation.
This commit is contained in:
+4
-1
@@ -1,5 +1,8 @@
|
||||
README.md.tinyenc
|
||||
secure-editor-go
|
||||
secure-editor-go.app
|
||||
logo.icns
|
||||
logo.iconset
|
||||
|
||||
# ---> macOS
|
||||
# General
|
||||
@@ -8,7 +11,7 @@ secure-editor-go
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
+28
@@ -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>
|
||||
@@ -8,6 +8,28 @@ go mod tidy
|
||||
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` 算法解密文件内容并在编辑器中展示,保存时重新加密写回(保留原文件权限位)。
|
||||
|
||||
@@ -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>"
|
||||
@@ -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)
|
||||
}
|
||||
@@ -146,10 +146,12 @@ func main() {
|
||||
isReadonly := isReadonly()
|
||||
|
||||
secureEditorApp := app.New()
|
||||
secureEditorApp.SetIcon(appIcon())
|
||||
if !isReadonly {
|
||||
secureEditorApp.Settings().SetTheme(&lightEditorTheme{Theme: theme.DefaultTheme()})
|
||||
}
|
||||
window := secureEditorApp.NewWindow(Title)
|
||||
window.SetIcon(appIcon())
|
||||
|
||||
cfg := loadConfig()
|
||||
window.Resize(clampToScreen(fyne.NewSize(cfg.Width, cfg.Height)))
|
||||
|
||||
Reference in New Issue
Block a user