Files
kutu/src/main.ml
T
2026-11-11 17:10:01 +00:00

104 lines
4.1 KiB
OCaml

let () =
let startup_script =
if Array.length Sys.argv = 2 then Some Sys.argv.(1)
else
let default =
Filename.concat (Sys.getenv "HOME") ".config/kutu/config.rb"
in
if Sys.file_exists default then Some default else None
in
let state = Kutu.State.new_state in
print_endline "Started Kutu WM";
Bindings.Core.register_callbacks state;
(match startup_script with
| Some s ->
Mruby.Core.mrb_load_string state.mrb (Mruby.Initial.initial_code s)
| None -> Mruby.Core.mrb_load_string state.mrb (Mruby.Initial.initial_code ""));
Mruby.Core.error_check state.mrb;
if Xcb.Connection.flush state.conn <= 0 then exit 1;
while state.running do
(match Xcb.Event.next state.conn with
| None -> ()
| Some ev ->
(match Xcb.Event.rtype ev with
| KeyPress ->
let req = Xcb.Types.Events.Key.from ev in
let key = Xcb.Types.Events.Key.detail req in
let modifier = Xcb.Types.Events.Key.state req in
Bindings.Keybinds.dispatch_keybind state.mrb state.blocks key
modifier state.focus state.current
| MapRequest ->
let req = Xcb.Types.Events.Map_request.from ev in
let window = Xcb.Types.Events.Map_request.window req in
Xcb.Window.map state.conn window;
Xcb.Window.focus state.conn window;
Xcb.Window.move_to_bottom state.conn window;
state.focus <- window;
(* TODO: check if window wants to be floating and if so float it instead. *)
let ws =
match Hashtbl.find_opt state.workspaces state.current with
| Some ws -> ws
| None ->
let ws = { Kutu.Layout.ws_root = None; ws_fwindows = [] } in
Hashtbl.add state.workspaces state.current ws;
ws
in
ws.ws_root <-
Some (Kutu.Layout.insert Kutu.Layout.Horizontal window ws.ws_root);
List.iter
(fun { Kutu.Layout.wr_window = window; wr_rect = rect } ->
Xcb.Window.reshape state.conn window rect)
(Kutu.Layout.calculate state.screen ws.ws_root);
Hashtbl.replace state.window_workspace window state.current
| Create ->
let req = Xcb.Types.Events.Create.from ev in
let window = Xcb.Types.Events.Create.window req in
let override_ridirect =
Xcb.Types.Events.Create.override_redirect req
in
if override_ridirect == Unsigned.UInt8.of_int 0 then
Xcb.Window.setup_window state.conn window
| Enter ->
let req = Xcb.Types.Events.Enter.from ev in
let window = Xcb.Types.Events.Enter.window req in
state.focus <- window;
Xcb.Window.focus state.conn window
| Destroy ->
let req = Xcb.Types.Events.Destroy.from ev in
let window = Xcb.Types.Events.Destroy.window req in
begin match Hashtbl.find_opt state.window_workspace window with
| None -> ()
| Some ws_name ->
let ws = Hashtbl.find state.workspaces ws_name in
let new_root, tiled_removed =
Kutu.Layout.remove window ws.ws_root
in
if tiled_removed then ws.ws_root <- new_root
else
ws.ws_fwindows <-
Kutu.Layout.remove_fwindow window ws.ws_fwindows;
Hashtbl.remove state.window_workspace window;
if ws_name = state.current then
List.iter
(fun { Kutu.Layout.wr_window = window; wr_rect = rect } ->
Xcb.Window.reshape state.conn window rect)
(Kutu.Layout.calculate state.screen ws.ws_root)
end
| _ -> ());
Xcb.Utils.free ev);
Mruby.Core.error_check state.mrb;
if Xcb.Connection.flush state.conn <= 0 then exit 1;
Unix.sleepf 0.01
done;
Bindings.Keybinds.cleanup state.mrb state.blocks;
Mruby.Core.mrb_close state.mrb;
Xcb.Connection.disconnect state.conn;
print_endline "Closing up Kutu WM"