Skip to content

Commit

Permalink
kernel: Fix terminal window resize events on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
garazdawi committed Oct 15, 2024
1 parent 2a45d46 commit 1e17298
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 30 deletions.
8 changes: 3 additions & 5 deletions erts/emulator/nifs/common/prim_tty_nif.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,12 +539,10 @@ static ERL_NIF_TERM tty_read_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
break;
case WINDOW_BUFFER_SIZE_EVENT:
enif_send(env, &tty->self, NULL,
enif_make_tuple2(env, argv[1],
enif_make_tuple2(
env, enif_make_atom(env, "resize"),
enif_make_tuple2(
env,
enif_make_int(env, inputs[i].Event.WindowBufferSizeEvent.dwSize.Y),
enif_make_int(env, inputs[i].Event.WindowBufferSizeEvent.dwSize.X))));
env, enif_make_atom(env, "signal"),
enif_make_atom(env, "resize"))));
break;
case MOUSE_EVENT:
/* We don't do anything with the mouse event */
Expand Down
48 changes: 23 additions & 25 deletions lib/kernel/src/prim_tty.erl
Original file line number Diff line number Diff line change
Expand Up @@ -310,37 +310,33 @@ init_term(State = #state{ tty = TTY, options = Options }) ->
DefaultReaderEncoding = if State#state.unicode -> utf8;
not State#state.unicode -> latin1
end,
{ok, Reader} = proc_lib:start_link(
?MODULE, reader,
[[State#state.tty, DefaultReaderEncoding, self()]]),
{ok, {_, ReaderRef} = Reader} =
proc_lib:start_link(
?MODULE, reader,
[[State#state.tty, DefaultReaderEncoding, self()]]),

case os:type() of
{unix, _} ->
%% `prim_tty' has signal handlers for SIGCONT and SIGWINCH.
%%
%% Historically, these signals were caught by `prim_tty_nif.c' and
%% forwarded to this process.
%%
%% After SIGCONT and SIGWINCH support was added, this module uses a
%% gen_event handler in `prim_tty_sighandler'.
ok = gen_event:add_handler(
erl_signal_server, prim_tty_sighandler,
#{parent => self(), reader => ReaderRef});
_ ->
ok
end,
WriterState#state{ reader = Reader };
{true, _} ->
WriterState;
{false, undefined} ->
WriterState
end,

%% `prim_tty' has signal handlers for SIGCONT and SIGWINCH.
%%
%% Historically, these signals were caught by `prim_tty_nif.c' and
%% forwarded to this process.
%%
%% After SIGCONT and SIGWINCH support was added, this module uses a
%% gen_event handler in `prim_tty_sighandler'.
case ReaderState#state.reader of
{_ReaderPid, ReaderRef} when is_reference(ReaderRef) ->
_ = gen_event:delete_handler(
erl_signal_server, prim_tty_sighandler,
undefined),
ok = gen_event:add_handler(
erl_signal_server, prim_tty_sighandler,
#{parent => self(), reader => ReaderRef}),
ok = os:set_signal(sigcont, handle),
ok = os:set_signal(sigwinch, handle);
_ ->
ok
end,

update_geometry(ReaderState).

-spec reinit(state(), options()) -> state().
Expand Down Expand Up @@ -490,9 +486,11 @@ reader_stop(#state{ reader = {ReaderPid, _} } = State) ->
{error, _} = call(ReaderPid, stop),
State#state{ reader = undefined }.

-spec handle_signal(state(), winch | cont) -> state().
-spec handle_signal(state(), winch | cont | resize) -> state().
handle_signal(State, winch) ->
update_geometry(State);
handle_signal(State, resize) ->
update_geometry(State);
handle_signal(State, cont) ->
tty_set(State#state.tty),
State.
Expand Down
2 changes: 2 additions & 0 deletions lib/kernel/src/prim_tty_sighandler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
-export([init/1, handle_event/2, handle_call/2, code_change/3]).

init(#{parent := _, reader := _} = State) ->
ok = os:set_signal(sigcont, handle),
ok = os:set_signal(sigwinch, handle),
{ok, State}.

handle_event(Signal, #{parent := Parent, reader := ReaderRef} = State)
Expand Down

0 comments on commit 1e17298

Please sign in to comment.