fix: ctrl-q now properly exits
This commit is contained in:
@@ -13,8 +13,11 @@ defmodule BDS.Application do
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Local TUI: the headless server plus a TUI on the launching terminal, so
|
# Local TUI: the headless server plus a TUI on the launching terminal, so
|
||||||
# a GUI (via tunnel) and the local terminal can work in parallel.
|
# a GUI (via tunnel) and the local terminal can work in parallel. Quitting
|
||||||
def mode_children(:tui, env), do: mode_children(:server, env) ++ [{BDS.TUI, []}]
|
# this TUI stops the whole VM — the terminal is the app in this mode.
|
||||||
|
# SSH-served TUI sessions never get this flag and stay session-local.
|
||||||
|
def mode_children(:tui, env),
|
||||||
|
do: mode_children(:server, env) ++ [{BDS.TUI, [stop_vm_on_exit: true]}]
|
||||||
|
|
||||||
def mode_children(:desktop, env), do: desktop_children(env)
|
def mode_children(:desktop, env), do: desktop_children(env)
|
||||||
|
|
||||||
|
|||||||
@@ -37,13 +37,17 @@ defmodule BDS.TUI do
|
|||||||
# ── Mount ────────────────────────────────────────────────────────────────
|
# ── Mount ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_opts) do
|
def mount(opts) do
|
||||||
UILocale.put(BDS.Desktop.ShellData.ui_language())
|
UILocale.put(BDS.Desktop.ShellData.ui_language())
|
||||||
:ok = Events.subscribe()
|
:ok = Events.subscribe()
|
||||||
|
|
||||||
project_id = Projects.shell_snapshot().active_project_id
|
project_id = Projects.shell_snapshot().active_project_id
|
||||||
|
|
||||||
state = %{
|
state = %{
|
||||||
|
# Set only for the local BDS_MODE=tui child: quitting the TUI then
|
||||||
|
# shuts the VM down instead of leaving a headless server behind.
|
||||||
|
stop_vm_on_exit: Keyword.get(opts, :stop_vm_on_exit, false),
|
||||||
|
stop_fun: Keyword.get(opts, :stop_fun, &System.stop/0),
|
||||||
project_id: project_id,
|
project_id: project_id,
|
||||||
view: "posts",
|
view: "posts",
|
||||||
sidebar: nil,
|
sidebar: nil,
|
||||||
@@ -60,6 +64,14 @@ defmodule BDS.TUI do
|
|||||||
{:ok, load_sidebar(state)}
|
{:ok, load_sidebar(state)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def terminate(_reason, %{stop_vm_on_exit: true, stop_fun: stop_fun}) do
|
||||||
|
stop_fun.()
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def terminate(_reason, _state), do: :ok
|
||||||
|
|
||||||
# ── Events: global keys ──────────────────────────────────────────────────
|
# ── Events: global keys ──────────────────────────────────────────────────
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|||||||
@@ -107,9 +107,10 @@ defmodule BDS.ServerTest do
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "tui mode is the server plus a local TUI" do
|
test "tui mode is the server plus a local TUI that stops the VM on quit" do
|
||||||
assert BDS.Application.mode_children(:tui, :prod) ==
|
assert BDS.Application.mode_children(:tui, :prod) ==
|
||||||
BDS.Application.mode_children(:server, :prod) ++ [{BDS.TUI, []}]
|
BDS.Application.mode_children(:server, :prod) ++
|
||||||
|
[{BDS.TUI, [stop_vm_on_exit: true]}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "desktop mode delegates to desktop_children" do
|
test "desktop mode delegates to desktop_children" do
|
||||||
|
|||||||
@@ -132,4 +132,20 @@ defmodule BDS.TUITest do
|
|||||||
test "quit key stops the app" do
|
test "quit key stops the app" do
|
||||||
assert {:stop, _state} = BDS.TUI.handle_event(key("q", ["ctrl"]), mount!())
|
assert {:stop, _state} = BDS.TUI.handle_event(key("q", ["ctrl"]), mount!())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "local tui mode stops the VM when the app exits" do
|
||||||
|
parent = self()
|
||||||
|
state = mount!(stop_vm_on_exit: true, stop_fun: fn -> send(parent, :vm_stopped) end)
|
||||||
|
|
||||||
|
assert :ok = BDS.TUI.terminate(:normal, state)
|
||||||
|
assert_receive :vm_stopped
|
||||||
|
end
|
||||||
|
|
||||||
|
test "ssh-served sessions never stop the VM on exit" do
|
||||||
|
parent = self()
|
||||||
|
state = mount!(stop_fun: fn -> send(parent, :vm_stopped) end)
|
||||||
|
|
||||||
|
assert :ok = BDS.TUI.terminate(:normal, state)
|
||||||
|
refute_receive :vm_stopped, 100
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user