Skip to content

Commit 607076a

Browse files
committed
feat(icon): add support for custom application icons via --icon-uri option
1 parent 1cda2cc commit 607076a

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ Options:
141141
--[no-]relink-eln-files Enable/disable re-linking shared libraries in bundled *.eln files (default: enabled)
142142
--[no-]rsvg Enable/disable SVG image support via librsvg (default: enabled)
143143
--[no-]dbus Enable/disable dbus support (default: enabled)
144-
--[no-]alpha-background Enable/disable experimental alpha-background patch when building Emacs 30.x - 31.x (default: disabled)
144+
--alpha-background Apply experimental alpha-background patch when building Emacs 30.x - 31.x (default: disabled)
145145
--no-frame-refocus Apply no-frame-refocus patch when building Emacs 27.x - 31.x (default: disabled)
146146
--no-titlebar Apply no-titlebar patch when building Emacs 27.x - 28.x (default: disabled)
147147
--[no-]xwidgets Enable/disable XWidgets when building Emacs 27.x (default: disabled)
@@ -155,6 +155,7 @@ Options:
155155
-o, --output DIR Output directory for finished builds (default: <work-dir>/builds)
156156
--build-name NAME Override generated build name
157157
--dist-include x,y,z List of extra files to copy from Emacs source into build folder/archive (default: COPYING)
158+
--icon-uri URI Local path or URL to a .icns file to replace the default app icon
158159
--[no-]self-sign Enable/disable self-signing of Emacs.app (default: enabled)
159160
--[no-]archive Enable/disable creating *.tbz archive (default: enabled)
160161
--[no-]archive-keep-build-dir

build-emacs-for-macos

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ class Build
229229

230230
handle_native_lisp(app)
231231

232+
IconEmbedder.new(app, options[:icon_uri]).embed if options[:icon_uri]
232233
CLIHelperEmbedder.new(app).embed
233234
CSourcesEmbedder.new(app, @source_dir).embed
234235
LibEmbedder.new(
@@ -1413,6 +1414,59 @@ class CSourcesEmbedder < AbstractEmbedder
14131414
end
14141415
end
14151416

1417+
class IconEmbedder < AbstractEmbedder
1418+
include Helpers
1419+
1420+
def initialize(app, icon_uri)
1421+
super(app)
1422+
1423+
@icon_uri = icon_uri
1424+
end
1425+
1426+
def embed
1427+
return if @icon_uri.nil? || @icon_uri.strip.empty?
1428+
1429+
source = resolve_source(@icon_uri)
1430+
1431+
unless File.extname(source).downcase == '.icns'
1432+
fatal 'Icon must be a .icns file'
1433+
end
1434+
1435+
target = File.join(resources_dir, 'Emacs.icns')
1436+
info 'Replacing application icon...'
1437+
run_cmd('cp', '-pRL', source, target)
1438+
ensure
1439+
cleanup_download_tmpdir(source)
1440+
end
1441+
1442+
private
1443+
1444+
def resolve_source(uri)
1445+
if valid_url?(uri)
1446+
download_icon(uri)
1447+
else
1448+
path = File.expand_path(uri)
1449+
fatal "Icon file does not exist: #{path}" unless File.exist?(path)
1450+
path
1451+
end
1452+
end
1453+
1454+
def download_icon(url)
1455+
@download_tmpdir = Dir.mktmpdir(%w[emacs-icon .tmp])
1456+
path = File.join(@download_tmpdir, 'icon.icns')
1457+
info "Downloading icon from: #{url}"
1458+
run_cmd('curl', '-L#', url, '-o', path)
1459+
path
1460+
end
1461+
1462+
def cleanup_download_tmpdir(source)
1463+
return unless @download_tmpdir && source
1464+
return unless source.start_with?(@download_tmpdir)
1465+
1466+
FileUtils.rm_rf(@download_tmpdir)
1467+
end
1468+
end
1469+
14161470
class LibEmbedder < AbstractEmbedder
14171471
attr_reader :lib_sources
14181472
attr_reader :extra_libs
@@ -2127,6 +2181,7 @@ class CLIOptions
21272181
github_src_repo: nil,
21282182
github_auth: true,
21292183
dist_include: ['COPYING', 'configure_output.txt'],
2184+
icon_uri: nil,
21302185
self_sign: true,
21312186
archive: true,
21322187
archive_keep: false,
@@ -2323,6 +2378,11 @@ class CLIOptions
23232378
'folder/archive (default: COPYING)'
23242379
) { |v| options[:dist_include] = v }
23252380

2381+
opts.on(
2382+
'--icon-uri URI',
2383+
'Local path or URL to a .icns file to replace the default app icon'
2384+
) { |v| options[:icon_uri] = v }
2385+
23262386
opts.on(
23272387
'--[no-]self-sign',
23282388
'Enable/disable self-signing of Emacs.app (default: enabled)'

0 commit comments

Comments
 (0)