142 lines
4.2 KiB
OCaml
142 lines
4.2 KiB
OCaml
let () =
|
|
let state = Kutu.State.new_state in
|
|
|
|
print_endline "Started Kutu WM";
|
|
|
|
Bindings.Core.register_callbacks state;
|
|
Mruby.Core.mrb_load_string state.mrb
|
|
{|#ruby
|
|
MOD_MAP = {
|
|
none: 0,
|
|
alt: 8,
|
|
super: 64
|
|
}
|
|
KEY_MAP = {
|
|
"tab" => 23,
|
|
"q" => 24,
|
|
"w" => 25,
|
|
"e" => 26,
|
|
"r" => 27,
|
|
"f" => 41,
|
|
|
|
"n" => 57,
|
|
"b" => 56,
|
|
"m" => 58,
|
|
"v" => 55,
|
|
}
|
|
def bind(key, mod = :alt, &block)
|
|
key = KEY_MAP[key]
|
|
mod = MOD_MAP[mod]
|
|
raise "unknown key" unless key
|
|
raise "unknown modifier" unless mod
|
|
_bind key, mod, &block
|
|
end
|
|
def unbind(key, mod = :alt)
|
|
key = KEY_MAP[key]
|
|
mod = MOD_MAP[mod]
|
|
raise "unknown key" unless key
|
|
raise "unknown modifier" unless mod
|
|
_unbind key, mod
|
|
end
|
|
|
|
bind "tab" do
|
|
system "firefox >/dev/null 2>&1 &"
|
|
end
|
|
bind ?q do |x|
|
|
kill x
|
|
end
|
|
bind ?w do
|
|
system "kitty >/dev/null 2>&1 &"
|
|
end
|
|
bind ?e do
|
|
exit
|
|
end
|
|
bind ?r do
|
|
unbind ?w
|
|
end
|
|
bind ?f do |x|
|
|
toggle_float x
|
|
end
|
|
|
|
bind ?v do |_, x|
|
|
remove_ws x
|
|
end
|
|
bind ?b do |_, x|
|
|
jump_ws ((x - 1 + ws_count) % ws_count)
|
|
end
|
|
bind ?n do |_, x|
|
|
jump_ws ((x + 1) % ws_count)
|
|
end
|
|
bind ?m do
|
|
new_ws
|
|
end
|
|
|};
|
|
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
|
|
(Unsigned.UInt32.of_int 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;
|
|
let ws = List.nth state.workspaces state.current in
|
|
ws.ws_root <-
|
|
Kutu.Layout.insert Kutu.Layout.Horizontal window ws.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 ws.ws_root)
|
|
| 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
|
|
let ws = List.nth state.workspaces state.current in
|
|
let new_root, removed = Kutu.Layout.remove window ws.ws_root in
|
|
if removed then ws.ws_root <- new_root
|
|
else
|
|
ws.ws_fwindows <- Kutu.Layout.remove_fwindow window ws.ws_fwindows;
|
|
Xcb.Window.focus state.conn state.root;
|
|
state.focus <- state.root;
|
|
List.iter
|
|
(fun { Kutu.Layout.fw_window = window; fw_rect = rect } ->
|
|
Xcb.Window.reshape state.conn window rect)
|
|
(Kutu.Layout.calculate state.screen ws.ws_root)
|
|
| _ -> ());
|
|
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"
|