open Ctypes open Foreign let register_kill (state : Kutu.State.wm_state) = let mrb_get_args = foreign "mrb_get_args" (ptr Mruby.Types.Mrb_state.typ @-> string @-> ptr int64_t @-> returning int) in let kill_window (mrb : Mruby.Types.Mrb_state.t structure ptr) (self : Mruby.Types.Mrb_value.t structure) = let win_id = allocate int64_t 0L in ignore (mrb_get_args mrb "i" win_id); let id = Unsigned.UInt32.of_int64 !@win_id in if id != state.root then Xcb.Window.kill state.conn id; self in Mruby.Bindings.mrb_define_method state.mrb (Mruby.Types.Mrb_state.get_object_class state.mrb) "kill" kill_window (Mruby.Bindings.mrb_args_req 1) let register_toggle_float (state : Kutu.State.wm_state) = let mrb_get_args = foreign "mrb_get_args" (ptr Mruby.Types.Mrb_state.typ @-> string @-> ptr int64_t @-> returning int) in let toggle_float (mrb : Mruby.Types.Mrb_state.t structure ptr) (self : Mruby.Types.Mrb_value.t structure) = let win_id = allocate int64_t 0L in ignore (mrb_get_args mrb "i" win_id); let window = Unsigned.UInt32.of_int64 !@win_id in let windows = Kutu.Layout.calculate state.screen state.workspaces.(state.current).ws_root in (match Kutu.Layout.find_fwindow window windows with | Some { fw_rect; _ } -> begin match Kutu.Layout.find_fwindow window state.workspaces.(state.current).ws_fwindows with | Some _ -> print_endline "Error: window already floating" | None -> let new_root, _ = Kutu.Layout.remove window state.workspaces.(state.current).ws_root in state.workspaces.(state.current).ws_root <- new_root; state.workspaces.(state.current).ws_fwindows <- { fw_rect; fw_window = window } :: state.workspaces.(state.current).ws_fwindows; Xcb.Window.move_to_top state.conn window; List.iter (fun { Kutu.Layout.fw_window = window; fw_rect = rect } -> Xcb.Window.reshape state.conn window rect) (Kutu.Layout.calculate state.screen state.workspaces.(state.current).ws_root) end | None -> begin match Kutu.Layout.find_fwindow window state.workspaces.(state.current).ws_fwindows with | Some _ -> state.workspaces.(state.current).ws_fwindows <- Kutu.Layout.remove_fwindow window state.workspaces.(state.current).ws_fwindows; Xcb.Window.move_to_bottom state.conn window; state.workspaces.(state.current).ws_root <- Kutu.Layout.insert Kutu.Layout.Horizontal window state.workspaces.(state.current).ws_root; List.iter (fun { Kutu.Layout.fw_window = window; fw_rect = rect } -> Xcb.Window.reshape state.conn window rect) (Kutu.Layout.calculate state.screen state.workspaces.(state.current).ws_root) | None -> print_endline "Error: window is neither tiled nor floating" end); self in Mruby.Bindings.mrb_define_method state.mrb (Mruby.Types.Mrb_state.get_object_class state.mrb) "toggle_float" toggle_float (Mruby.Bindings.mrb_args_req 1)