diff options
Diffstat (limited to 'src/er_xdg_pipe_menu_cli.erl')
| -rw-r--r-- | src/er_xdg_pipe_menu_cli.erl | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/er_xdg_pipe_menu_cli.erl b/src/er_xdg_pipe_menu_cli.erl new file mode 100644 index 0000000..92ac715 --- /dev/null +++ b/src/er_xdg_pipe_menu_cli.erl @@ -0,0 +1,41 @@ +%%%------------------------------------------------------------------- +%% @doc Entry point invoked by Openbox as the pipe menu command. +%% +%% Tries the running daemon's Unix socket first for an instant, +%% pre-rendered response; if the daemon isn't reachable, falls back to +%% scanning, parsing and rendering inline so the menu still works. +%% @end +%%%------------------------------------------------------------------- + +-module(er_xdg_pipe_menu_cli). + +-export([main/1]). + +-define(CONNECT_TIMEOUT_MS, 200). +-define(RECV_TIMEOUT_MS, 1000). + +main(_Args) -> + Menu = + case from_daemon() of + {ok, Bin} -> Bin; + error -> er_xdg_pipe_menu_cache:build(er_xdg_pipe_menu_scanner:data_dirs()) + end, + io:put_chars(Menu). + +from_daemon() -> + Path = er_xdg_pipe_menu_socket:socket_path(), + case gen_tcp:connect({local, Path}, 0, [binary, {active, false}], ?CONNECT_TIMEOUT_MS) of + {ok, Socket} -> + Result = recv_all(Socket, []), + gen_tcp:close(Socket), + Result; + {error, _Reason} -> + error + end. + +recv_all(Socket, Acc) -> + case gen_tcp:recv(Socket, 0, ?RECV_TIMEOUT_MS) of + {ok, Data} -> recv_all(Socket, [Data | Acc]); + {error, closed} -> {ok, iolist_to_binary(lists:reverse(Acc))}; + {error, _Reason} -> error + end. |
