Compare commits
2
Commits
945ff0a6d3
...
3a273d1ee8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a273d1ee8
|
||
|
|
838773e153
|
@@ -103,24 +103,24 @@ end
|
||||
end
|
||||
end
|
||||
|
||||
bind 86 do |_, ws|
|
||||
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 do |_, ws|
|
||||
bind 82, :none do |_, ws|
|
||||
next unless in_project?(ws)
|
||||
n = ($current_project % MAX_PROJECTS) + 1
|
||||
go_project(n, $current_sub)
|
||||
end
|
||||
|
||||
bind 79 do |_, ws|
|
||||
bind 79, :none do |_, ws|
|
||||
next unless in_project?(ws)
|
||||
go_project($current_project, ($current_sub + 1) % SUBS)
|
||||
end
|
||||
|
||||
bind 80 do |_, ws|
|
||||
bind 80, :none do |_, ws|
|
||||
next unless in_project?(ws)
|
||||
go_project($current_project, ($current_sub - 1 + SUBS) % SUBS)
|
||||
end
|
||||
|
||||
+5
-51
@@ -1,62 +1,16 @@
|
||||
let () =
|
||||
let startup_script =
|
||||
if Array.length Sys.argv <> 2 then (
|
||||
Printf.eprintf "usage: kutu <startup.rb>\n";
|
||||
exit 1)
|
||||
else Sys.argv.(1)
|
||||
if Array.length Sys.argv <> 2 then None else Some Sys.argv.(1)
|
||||
in
|
||||
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,
|
||||
"]" => 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.mrb_load_string state.mrb Mruby.Initial.initial_code;
|
||||
(match startup_script with
|
||||
| None -> ()
|
||||
| Some s -> Mruby.Core.mrb_load_file state.mrb s);
|
||||
Mruby.Core.error_check state.mrb;
|
||||
|
||||
if Xcb.Connection.flush state.conn <= 0 then exit 1;
|
||||
|
||||
@@ -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)
|
||||
|}
|
||||
@@ -0,0 +1,6 @@
|
||||
# Kutu WM
|
||||
|
||||
An X11 window manager written in ocaml.
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user