mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-10-18 17:35:55 +08:00
Desktop icon improvements (#1201)
This commit is contained in:
parent
2fdcc60dd2
commit
fc82b55dab
9 changed files with 66 additions and 41 deletions
|
@ -4,4 +4,11 @@ defmodule AppBuilder do
|
|||
defdelegate build_mac_app_dmg(release, options), to: AppBuilder.MacOS
|
||||
|
||||
defdelegate build_windows_installer(release, options), to: AppBuilder.Windows
|
||||
|
||||
def os do
|
||||
case :os.type() do
|
||||
{:unix, :darwin} -> :macos
|
||||
{:win32, _} -> :windows
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -94,7 +94,7 @@ defmodule AppBuilder.MacOS do
|
|||
Keyword.validate!(options, [
|
||||
:name,
|
||||
:version,
|
||||
:logo_path,
|
||||
:icon_path,
|
||||
:info_plist,
|
||||
:url_schemes,
|
||||
:document_types,
|
||||
|
@ -125,8 +125,16 @@ defmodule AppBuilder.MacOS do
|
|||
launcher_src_path
|
||||
])
|
||||
|
||||
logo_path = options[:logo_path] || Application.app_dir(:wx, "examples/demo/erlang.png")
|
||||
create_logo(app_bundle_path, logo_path)
|
||||
icon_path = options[:icon_path] || Application.app_dir(:wx, "examples/demo/erlang.png")
|
||||
dest_path = Path.join([app_bundle_path, "Contents", "Resources", "AppIcon.icns"])
|
||||
create_icon(icon_path, dest_path)
|
||||
|
||||
for type <- options[:document_types] || [] do
|
||||
if src_path = type[:icon_path] do
|
||||
dest_path = Path.join([app_bundle_path, "Contents", "Resources", "#{type.name}Icon.icns"])
|
||||
create_icon(src_path, dest_path)
|
||||
end
|
||||
end
|
||||
|
||||
info_plist = options[:info_plist] || info_plist(options)
|
||||
File.write!(Path.join([app_bundle_path, "Contents", "Info.plist"]), info_plist)
|
||||
|
@ -180,15 +188,16 @@ defmodule AppBuilder.MacOS do
|
|||
"""
|
||||
end
|
||||
|
||||
defp create_logo(app_bundle_path, logo_source_path) do
|
||||
logo_dest_path = Path.join([app_bundle_path, "Contents", "Resources", "AppIcon.icns"])
|
||||
defp create_icon(src_path, dest_path) do
|
||||
src_path = normalize_icon_path(src_path)
|
||||
|
||||
if Path.extname(logo_source_path) == ".icns" do
|
||||
File.cp!(logo_source_path, logo_dest_path)
|
||||
if Path.extname(src_path) == ".icns" do
|
||||
File.cp!(src_path, dest_path)
|
||||
else
|
||||
logo_dest_tmp_path = "tmp/AppIcon.iconset"
|
||||
File.rm_rf!(logo_dest_tmp_path)
|
||||
File.mkdir_p!(logo_dest_tmp_path)
|
||||
name = Path.basename(dest_path, ".icns")
|
||||
dest_tmp_path = "tmp/#{name}.iconset"
|
||||
File.rm_rf!(dest_tmp_path)
|
||||
File.mkdir_p!(dest_tmp_path)
|
||||
|
||||
sizes = for(i <- [16, 32, 64, 128], j <- [1, 2], do: {i, j}) ++ [{512, 1}]
|
||||
|
||||
|
@ -200,12 +209,12 @@ defmodule AppBuilder.MacOS do
|
|||
end
|
||||
|
||||
size = size * scale
|
||||
out = "#{logo_dest_tmp_path}/icon_#{size}x#{size}#{suffix}.png"
|
||||
cmd!("sips", ~w(-z #{size} #{size} #{logo_source_path} --out #{out}))
|
||||
out = "#{dest_tmp_path}/icon_#{size}x#{size}#{suffix}.png"
|
||||
cmd!("sips", ~w(-z #{size} #{size} #{src_path} --out #{out}))
|
||||
end
|
||||
|
||||
cmd!("iconutil", ~w(-c icns #{logo_dest_tmp_path} -o #{logo_dest_path}))
|
||||
File.rm_rf!(logo_dest_tmp_path)
|
||||
cmd!("iconutil", ~w(-c icns #{dest_tmp_path} -o #{dest_path}))
|
||||
File.rm_rf!(dest_tmp_path)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -297,6 +306,10 @@ defmodule AppBuilder.MacOS do
|
|||
<string><%= ext %></string>
|
||||
<% end %>
|
||||
</array>
|
||||
<%= if type[:icon_path] do %>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string><%= type.name %>Icon</string>
|
||||
<% end %>
|
||||
</dict>
|
||||
<% end %>
|
||||
</array>
|
||||
|
|
|
@ -66,4 +66,12 @@ defmodule AppBuilder.Utils do
|
|||
"""
|
||||
end
|
||||
end
|
||||
|
||||
def normalize_icon_path(path) when is_binary(path) do
|
||||
path
|
||||
end
|
||||
|
||||
def normalize_icon_path(path_per_os) when is_list(path_per_os) do
|
||||
Keyword.fetch!(path_per_os, AppBuilder.os())
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ defmodule AppBuilder.Windows do
|
|||
:version,
|
||||
:url_schemes,
|
||||
:document_types,
|
||||
:logo_path,
|
||||
:icon_path,
|
||||
:module
|
||||
])
|
||||
|
||||
|
@ -52,9 +52,9 @@ defmodule AppBuilder.Windows do
|
|||
vcredist_path = ensure_vcredistx64()
|
||||
File.cp!(vcredist_path, Path.join(tmp_dir, "vcredist_x64.exe"))
|
||||
|
||||
logo_path = options[:logo_path] || Application.app_dir(:wx, "examples/demo/erlang.png")
|
||||
icon_path = options[:icon_path] || Application.app_dir(:wx, "examples/demo/erlang.png")
|
||||
app_icon_path = Path.join(tmp_dir, "app_icon.ico")
|
||||
copy_image(logo_path, app_icon_path)
|
||||
create_icon(icon_path, app_icon_path)
|
||||
|
||||
erl_exe = Path.join([tmp_dir, "rel", "erts-#{release.erts_version}", "bin", "erl.exe"])
|
||||
rcedit_path = ensure_rcedit()
|
||||
|
@ -254,14 +254,13 @@ defmodule AppBuilder.Windows do
|
|||
end
|
||||
|
||||
defp ensure_magick do
|
||||
url =
|
||||
"https://download.imagemagick.org/ImageMagick/download/binaries/ImageMagick-7.1.0-portable-Q16-x64.zip"
|
||||
|
||||
sha256 = "b61a726cea1e3bf395b9aeb323fca062f574fbf8f11f4067f88a0e6b984a1391"
|
||||
AppBuilder.Utils.ensure_executable(url, sha256, "magick.exe")
|
||||
System.find_executable("magick.exe") ||
|
||||
raise "couldn't find magick.exe in PATH to automatically convert images to .ico"
|
||||
end
|
||||
|
||||
defp copy_image(src_path, dest_path) do
|
||||
defp create_icon(src_path, dest_path) do
|
||||
src_path = normalize_icon_path(src_path)
|
||||
|
||||
if Path.extname(src_path) == ".ico" do
|
||||
File.cp!(src_path, dest_path)
|
||||
else
|
||||
|
|
|
@ -8,16 +8,10 @@ if Mix.target() == :app do
|
|||
defmacro wxID_OSX_HIDE, do: 5250
|
||||
defmacro wxBITMAP_TYPE_PNG, do: 15
|
||||
|
||||
def os do
|
||||
case :os.type() do
|
||||
{:unix, :darwin} -> :macos
|
||||
{:win32, _} -> :windows
|
||||
end
|
||||
end
|
||||
|
||||
def taskbar(title, icon, menu_items) do
|
||||
pid = self()
|
||||
options = if os() == :macos, do: [iconType: 1], else: []
|
||||
os = AppBuilder.os()
|
||||
options = if os == :macos, do: [iconType: 1], else: []
|
||||
|
||||
# skip keyboard shortcuts
|
||||
menu_items =
|
||||
|
@ -35,7 +29,7 @@ if Mix.target() == :app do
|
|||
|
||||
# For some reason, on macOS the menu event must be handled in another process
|
||||
# but on Windows it must be either the same process OR we use the callback.
|
||||
case os() do
|
||||
case os do
|
||||
:macos ->
|
||||
env = :wx.get_env()
|
||||
|
||||
|
@ -92,7 +86,7 @@ if Mix.target() == :app do
|
|||
def menubar(app_name, menus) do
|
||||
menubar = :wxMenuBar.new()
|
||||
|
||||
if os() == :macos, do: fixup_macos_menubar(menubar, app_name)
|
||||
if AppBuilder.os() == :macos, do: fixup_macos_menubar(menubar, app_name)
|
||||
|
||||
for {title, menu_items} <- menus do
|
||||
true = :wxMenuBar.append(menubar, menu(menu_items), title)
|
||||
|
@ -125,13 +119,13 @@ if Mix.target() == :app do
|
|||
GenServer.start_link(__MODULE__, arg, name: @name)
|
||||
end
|
||||
|
||||
taskbar_icon_path = "rel/app/taskbar_icon.png"
|
||||
taskbar_icon_path = "rel/app/icon.png"
|
||||
@external_resource taskbar_icon_path
|
||||
@taskbar_icon File.read!(taskbar_icon_path)
|
||||
|
||||
@impl true
|
||||
def init(_) do
|
||||
os = os()
|
||||
os = AppBuilder.os()
|
||||
wx = :wx.new()
|
||||
AppBuilder.Wx.subscribe_to_app_events(@name)
|
||||
|
||||
|
@ -161,7 +155,7 @@ if Mix.target() == :app do
|
|||
# 1. MIX_TARGET=app mix phx.server
|
||||
# 2. mix app
|
||||
# 3. mix release app
|
||||
taskbar_icon_path = Path.join(System.tmp_dir!(), "taskbar_icon.png")
|
||||
taskbar_icon_path = Path.join(System.tmp_dir!(), "icon.png")
|
||||
File.write!(taskbar_icon_path, @taskbar_icon)
|
||||
icon = :wxIcon.new(taskbar_icon_path, type: wxBITMAP_TYPE_PNG())
|
||||
|
||||
|
|
14
mix.exs
14
mix.exs
|
@ -175,7 +175,10 @@ defmodule Livebook.MixProject do
|
|||
@app_options [
|
||||
name: "Livebook",
|
||||
version: @version,
|
||||
logo_path: "rel/app/mac-icon.png",
|
||||
icon_path: [
|
||||
macos: "rel/app/icon-macos.png",
|
||||
windows: "rel/app/icon.ico"
|
||||
],
|
||||
additional_paths: [
|
||||
"/rel/erts-#{:erlang.system_info(:version)}/bin",
|
||||
"/rel/vendor/elixir/bin"
|
||||
|
@ -185,6 +188,10 @@ defmodule Livebook.MixProject do
|
|||
%{
|
||||
name: "LiveMarkdown",
|
||||
extensions: ["livemd"],
|
||||
icon_path: [
|
||||
macos: "rel/app/icon.png",
|
||||
windows: "rel/app/icon.ico"
|
||||
],
|
||||
# macos specific
|
||||
role: "Editor"
|
||||
}
|
||||
|
@ -218,10 +225,7 @@ defmodule Livebook.MixProject do
|
|||
end
|
||||
|
||||
defp build_windows_installer(release) do
|
||||
options =
|
||||
Keyword.take(@app_options, [:name, :version, :url_schemes, :document_types]) ++
|
||||
[module: LivebookApp, logo_path: "static/images/logo.png"]
|
||||
|
||||
options = Keyword.drop(@app_options, [:additional_paths]) ++ [module: LivebookApp]
|
||||
AppBuilder.build_windows_installer(release, options)
|
||||
end
|
||||
end
|
||||
|
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
BIN
rel/app/icon.ico
Normal file
BIN
rel/app/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Loading…
Add table
Reference in a new issue