Packages
livebook
0.5.0
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook_app.ex
if Mix.target() == :app do
defmodule LivebookApp do
@moduledoc false
@behaviour :wx_object
# https://github.com/erlang/otp/blob/OTP-24.1.2/lib/wx/include/wx.hrl#L1314
@wx_id_exit 5006
def start_link(_) do
{:wx_ref, _, _, pid} = :wx_object.start_link(__MODULE__, [], [])
{:ok, pid}
end
def child_spec(init_arg) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [init_arg]},
restart: :transient
}
end
@impl true
def init(_) do
title = "Livebook"
wx = :wx.new()
frame = :wxFrame.new(wx, -1, title, size: {0, 0})
if macos?() do
fixup_macos_menubar(frame, title)
end
:wxFrame.show(frame)
:wxFrame.connect(frame, :command_menu_selected)
:wxFrame.connect(frame, :close_window, skip: true)
:wx.subscribe_events()
state = %{frame: frame}
Livebook.Utils.browser_open(LivebookWeb.Endpoint.access_url())
{frame, state}
end
@impl true
def handle_event({:wx, @wx_id_exit, _, _, _}, state) do
:init.stop()
{:stop, :normal, state}
end
@impl true
def handle_event({:wx, _, _, _, {:wxClose, :close_window}}, state) do
:init.stop()
{:stop, :normal, state}
end
# TODO: investigate "Universal Links" [1], that is, instead of livebook://foo, we have
# https://livebook.dev/foo, which means the link works with and without Livebook.app.
#
# [1] https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content
@impl true
def handle_info({:open_url, url}, state) do
'livebook://' ++ rest = url
import_livebook("https://#{rest}")
{:noreply, state}
end
@impl true
def handle_info({:open_file, path}, state) do
import_livebook("file://#{path}")
{:noreply, state}
end
# ignore other events
@impl true
def handle_info(_event, state) do
{:noreply, state}
end
defp import_livebook(url) do
%{
URI.parse(LivebookWeb.Endpoint.access_url())
| path: "/import"
}
|> append_query("url=#{URI.encode_www_form(url)}")
|> URI.to_string()
|> Livebook.Utils.browser_open()
end
defp fixup_macos_menubar(frame, title) do
menubar = :wxMenuBar.new()
:wxFrame.setMenuBar(frame, menubar)
# App Menu
menu = :wxMenuBar.oSXGetAppleMenu(menubar)
# Remove all items except for quit
for item <- :wxMenu.getMenuItems(menu) do
if :wxMenuItem.getId(item) == @wx_id_exit do
:wxMenuItem.setText(item, "Quit #{title}\tCtrl+Q")
else
:wxMenu.delete(menu, item)
end
end
end
defp macos?() do
:os.type() == {:unix, :darwin}
end
# TODO: On Elixir v1.14, use URI.append_query/2
defp append_query(%URI{query: query} = uri, query_to_add) when query in [nil, ""] do
%{uri | query: query_to_add}
end
defp append_query(%URI{} = uri, query) do
%{uri | query: uri.query <> "&" <> query}
end
end
end