Compare commits

..
2 Commits
Author SHA1 Message Date
syedm 3a273d1ee8 Little cleanup. 2026-09-10 18:41:54 +01:00
syedm 838773e153 Move initial ruby code out of line 2026-09-10 18:32:17 +01:00
5 changed files with 192 additions and 55 deletions
+4 -4
View File
@@ -103,24 +103,24 @@ end
end end
end end
bind 86 do |_, ws| bind 86, :none do |_, ws|
next unless in_project?(ws) next unless in_project?(ws)
n = (($current_project - 2) % MAX_PROJECTS) + 1 n = (($current_project - 2) % MAX_PROJECTS) + 1
go_project(n, $current_sub) go_project(n, $current_sub)
end end
bind 82 do |_, ws| bind 82, :none do |_, ws|
next unless in_project?(ws) next unless in_project?(ws)
n = ($current_project % MAX_PROJECTS) + 1 n = ($current_project % MAX_PROJECTS) + 1
go_project(n, $current_sub) go_project(n, $current_sub)
end end
bind 79 do |_, ws| bind 79, :none do |_, ws|
next unless in_project?(ws) next unless in_project?(ws)
go_project($current_project, ($current_sub + 1) % SUBS) go_project($current_project, ($current_sub + 1) % SUBS)
end end
bind 80 do |_, ws| bind 80, :none do |_, ws|
next unless in_project?(ws) next unless in_project?(ws)
go_project($current_project, ($current_sub - 1 + SUBS) % SUBS) go_project($current_project, ($current_sub - 1 + SUBS) % SUBS)
end end
View File
+5 -51
View File
@@ -1,62 +1,16 @@
let () = let () =
let startup_script = let startup_script =
if Array.length Sys.argv <> 2 then ( if Array.length Sys.argv <> 2 then None else Some Sys.argv.(1)
Printf.eprintf "usage: kutu <startup.rb>\n";
exit 1)
else Sys.argv.(1)
in in
let state = Kutu.State.new_state in let state = Kutu.State.new_state in
print_endline "Started Kutu WM"; print_endline "Started Kutu WM";
Bindings.Core.register_callbacks state; Bindings.Core.register_callbacks state;
Mruby.Core.mrb_load_string state.mrb Mruby.Core.mrb_load_string state.mrb Mruby.Initial.initial_code;
{|#ruby (match startup_script with
MOD_MAP = { | None -> ()
none: 0, | Some s -> Mruby.Core.mrb_load_file state.mrb s);
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,
"]" => 35,
"[" => 34,
"1" => 10,
"2" => 11,
"3" => 12,
"4" => 13,
"5" => 14,
"6" => 15,
"7" => 16,
"8" => 17,
"9" => 18,
"0" => 19
}
def bind(key, mod = :alt, &block)
key_ = key.is_a?(String) ? KEY_MAP[key] : key
mod = MOD_MAP[mod]
raise "unknown key #{key.to_s}" unless key_
raise "unknown modifier" unless mod
_bind key_, mod, &block
end
def unbind(key, mod = :alt)
key_ = key.is_a?(String) ? KEY_MAP[key] : key
mod = MOD_MAP[mod]
raise "unknown key #{key.to_s}" unless key_
raise "unknown modifier" unless mod
_unbind key_, mod
end
|};
Mruby.Core.mrb_load_file state.mrb startup_script;
Mruby.Core.error_check state.mrb; Mruby.Core.error_check state.mrb;
if Xcb.Connection.flush state.conn <= 0 then exit 1; if Xcb.Connection.flush state.conn <= 0 then exit 1;
+177
View File
@@ -0,0 +1,177 @@
let initial_code =
{|#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,
"]" => 35,
"[" => 34,
"1" => 10,
"2" => 11,
"3" => 12,
"4" => 13,
"5" => 14,
"6" => 15,
"7" => 16,
"8" => 17,
"9" => 18,
"0" => 19
}
def bind(key, mod = :super, &block)
key_ = key.is_a?(String) ? KEY_MAP[key] : key
mod = MOD_MAP[mod]
raise "unknown key #{key.to_s}" unless key_
raise "unknown modifier" unless mod
_bind key_, mod, &block
end
def unbind(key, mod = :super)
key_ = key.is_a?(String) ? KEY_MAP[key] : key
mod = MOD_MAP[mod]
raise "unknown key #{key.to_s}" unless key_
raise "unknown modifier" unless mod
_unbind key_, mod
end
# ==== State ====
MAX_PROJECTS = 9
SUBS = 2 # workspaces per project
$current_project = 1 # 1..MAX_PROJECTS
$current_sub = 0 # 0..SUBS-1
# For each special workspace, remembers which workspace you were on
# before you jumped into it -- so hitting the mode key again toggles back.
$special_origin = {}
SPECIAL = {
terminal: { cmd: "kitty" },
browser: { cmd: "firefox" },
music: { cmd: "spotify" },
misc: { cmd: nil }, # doesn't start anything
todo: { cmd: nil }, # doesn't start anything
}
# ==== Helpers ====
def project_ws(n, sub)
:"p#{n}_#{sub}"
end
def running?(process)
system("pgrep -x #{process} > /dev/null 2>&1")
end
def go_project(n, sub)
$current_project = n
$current_sub = sub
jump_ws project_ws(n, sub)
end
def in_project?(ws)
!SPECIAL.key?(ws)
end
# Toggle between a special-mode workspace (terminal/browser/music/misc/todo)
# and whatever workspace you were last on. Starts the associated app if
# it isn't already running. `ws` is the current workspace, passed in by
# the bind block (bind gives us (window, current_ws)).
def go_special(name, ws)
cfg = SPECIAL.fetch(name)
if ws == name
target = $special_origin[name] || project_ws($current_project, $current_sub)
jump_ws target
else
$special_origin[name] = ws
jump_ws name
system("#{cfg[:cmd]} >/dev/null 2>&1 &") if cfg[:cmd] && !running?(cfg[:cmd])
end
end
# ==== Untouched bindings ====
bind ?q do |x|
kill x
end
bind ?w do
system "kitty >/dev/null 2>&1 &"
end
bind ?e do
exit
end
bind ?f do |x|
toggle_float x
end
# ==== Mode switches ====
bind ?[ do |_, ws|
go_special :terminal, ws
end
bind ?] do |_, ws|
go_special :misc, ws
end
bind "tab" do |_, ws|
go_special :browser, ws
end
bind 89 do |_, ws|
go_special :music, ws
end
bind 81 do |_, ws|
go_special :todo, ws
end
# ==== Project navigation ====
(1..MAX_PROJECTS).each do |n|
bind n.to_s do
go_project(n, $current_sub)
end
end
bind 86, :none do |_, ws|
next unless in_project?(ws)
n = (($current_project - 2) % MAX_PROJECTS) + 1
go_project(n, $current_sub)
end
bind 82, :none do |_, ws|
next unless in_project?(ws)
n = ($current_project % MAX_PROJECTS) + 1
go_project(n, $current_sub)
end
bind 79, :none do |_, ws|
next unless in_project?(ws)
go_project($current_project, ($current_sub + 1) % SUBS)
end
bind 80, :none do |_, ws|
next unless in_project?(ws)
go_project($current_project, ($current_sub - 1 + SUBS) % SUBS)
end
# ==== Startup ====
go_project(1, 0)
|}
+6
View File
@@ -0,0 +1,6 @@
# Kutu WM
An X11 window manager written in ocaml.