104 lines
4.1 KiB
OCaml
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"
|