This commit is contained in:
2026-11-11 17:10:01 +00:00
parent e89a101be5
commit 06bc5e9a48
8 changed files with 180 additions and 44 deletions
+13 -20
View File
@@ -1,20 +1,24 @@
system 'bash ~/main/ocaml/epq/scripts/startup.sh >/dev/null 2>&1 &'
tmp_src = '@src@'
SRC = if tmp_src == '@src@'
'~/main/ocaml/epq/scripts'
else
tmp_src
end
MAX_PROJECTS = 3
SPECIAL = {
term1: { cmd: 'kitty' },
term2: { cmd: 'kitty' },
terminal: { cmd: 'kitty' },
browser: { cmd: 'firefox' },
misc: { cmd: nil }
}
$current = 0
$p_sub = Array.new(9, 0)
system "bash #{SRC}/startup.sh >/dev/null 2>&1 &"
def project_ws(n)
:"p#{n}_#{$p_sub[$current]}"
:"p#{n}"
end
def go_project(n)
@@ -47,11 +51,11 @@ bind 'w' do
end
bind 'e' do
system 'bash ~/main/ocaml/epq/scripts/power.sh >/dev/null 2>&1 &'
system "bash #{SRC}/power.sh >/dev/null 2>&1 &"
end
bind 'd' do
system 'bash ~/main/ocaml/epq/scripts/run.sh >/dev/null 2>&1 &'
system "bash #{SRC}/run.sh >/dev/null 2>&1 &"
end
bind 'v' do
@@ -123,12 +127,8 @@ bind 'f' do
system 'kitty -e fish -c "btop" >/dev/null 2>&1 &'
end
bind '[' do |_, ws|
go_special :term1, ws
end
bind ']' do |_, ws|
go_special :term2, ws
bind 80, :none do |_, ws|
go_special :terminal, ws
end
bind 79, :none do |_, ws|
@@ -164,11 +164,4 @@ bind 82, :none do |_, ws|
go_project(n)
end
bind 80, :none do |_, ws|
next unless in_project?(ws)
$p_sub[$current] = $p_sub[$current] == 1 ? 0 : 1
go_project($current)
end
go_project(0)
+11 -6
View File
@@ -34,18 +34,21 @@ let register_toggle_float (state : Kutu.State.wm_state) =
begin match Hashtbl.find_opt state.workspaces state.current with
| Some ws -> (
let windows = Kutu.Layout.calculate state.screen ws.ws_root in
match Kutu.Layout.find_fwindow window windows with
| Some { fw_rect; _ } ->
match
List.find_opt
(fun { Kutu.Layout.wr_window = w; wr_rect } -> w = window)
windows
with
| Some _ ->
begin match Kutu.Layout.find_fwindow window ws.ws_fwindows with
| Some _ -> print_endline "Error: window already floating"
| None ->
let new_root, _ = Kutu.Layout.remove window ws.ws_root in
ws.ws_root <- new_root;
ws.ws_fwindows <-
{ fw_rect; fw_window = window } :: ws.ws_fwindows;
ws.ws_fwindows <- window :: ws.ws_fwindows;
Xcb.Window.move_to_top state.conn window;
List.iter
(fun { Kutu.Layout.fw_window = window; fw_rect = rect } ->
(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
@@ -59,7 +62,7 @@ let register_toggle_float (state : Kutu.State.wm_state) =
Some
(Kutu.Layout.insert Kutu.Layout.Horizontal window ws.ws_root);
List.iter
(fun { Kutu.Layout.fw_window = window; fw_rect = rect } ->
(fun { Kutu.Layout.wr_window = window; wr_rect = rect } ->
Xcb.Window.reshape state.conn window rect)
(Kutu.Layout.calculate state.screen ws.ws_root)
| None ->
@@ -73,3 +76,5 @@ let register_toggle_float (state : Kutu.State.wm_state) =
(Mruby.Types.Mrb_state.get_object_class state.mrb)
"toggle_float" toggle_float
(Mruby.Bindings.mrb_args_req 1)
(* Add a window moving operation to move between workspaces. *)
+4 -6
View File
@@ -26,24 +26,22 @@ let register_jump (state : Kutu.State.wm_state) =
begin match Hashtbl.find_opt state.workspaces state.current with
| Some old_ws ->
List.iter
(fun { Kutu.Layout.fw_window = window; fw_rect } ->
(fun { Kutu.Layout.wr_window = window; wr_rect } ->
Xcb.Window.unmap state.conn window)
(Kutu.Layout.calculate state.screen old_ws.ws_root);
List.iter
(fun { Kutu.Layout.fw_window = window; fw_rect } ->
Xcb.Window.unmap state.conn window)
(fun window -> Xcb.Window.unmap state.conn window)
old_ws.ws_fwindows
| None -> ()
end;
state.current <- name;
List.iter
(fun { Kutu.Layout.fw_window = window; fw_rect = rect } ->
(fun { Kutu.Layout.wr_window = window; wr_rect = rect } ->
Xcb.Window.map state.conn window;
Xcb.Window.reshape state.conn window rect)
(Kutu.Layout.calculate state.screen new_ws.ws_root);
List.iter
(fun { Kutu.Layout.fw_window = window; fw_rect } ->
Xcb.Window.map state.conn window)
(fun window -> Xcb.Window.map state.conn window)
new_ws.ws_fwindows);
self
in
+8 -5
View File
@@ -9,21 +9,24 @@ type layout =
layout_r : layout;
}
type fwindow = { fw_rect : Decl.Types.rect; fw_window : Xcb.Types.Window.t }
type window_result = {
wr_rect : Decl.Types.rect;
wr_window : Xcb.Types.Window.t;
}
type workspace = {
mutable ws_root : layout option;
mutable ws_fwindows : fwindow list;
mutable ws_fwindows : Xcb.Types.Window.t list;
}
let empty_workspace () = { ws_root = None; ws_fwindows = [] }
let is_empty_workspace ws = ws.ws_root = None && ws.ws_fwindows = []
let find_fwindow window fwindows =
List.find_opt (fun fw -> fw.fw_window = window) fwindows
List.find_opt (fun fw -> fw = window) fwindows
let remove_fwindow window fwindows =
List.filter (fun fw -> fw.fw_window <> window) fwindows
List.filter (fun fw -> fw <> window) fwindows
let flip_direction = function Horizontal -> Vertical | Vertical -> Horizontal
@@ -122,7 +125,7 @@ let rec calculate rect = function
| Some l -> (
match l with
| Leaf { layout_window } ->
[ { fw_rect = rect; fw_window = layout_window } ]
[ { wr_rect = rect; wr_window = layout_window } ]
| Split { layout_direction; layout_ratio; layout_l; layout_r } ->
let left_rect, right_rect =
split_rect rect layout_direction layout_ratio
+4 -7
View File
@@ -16,12 +16,8 @@ let () =
(match startup_script with
| Some s ->
print_string s;
print_endline " : Have something";
Mruby.Core.mrb_load_string state.mrb (Mruby.Initial.initial_code s)
| None ->
print_endline "Nothing";
Mruby.Core.mrb_load_string state.mrb (Mruby.Initial.initial_code ""));
| 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;
@@ -44,6 +40,7 @@ let () =
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
@@ -55,7 +52,7 @@ let () =
ws.ws_root <-
Some (Kutu.Layout.insert Kutu.Layout.Horizontal window ws.ws_root);
List.iter
(fun { Kutu.Layout.fw_window = window; fw_rect = rect } ->
(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
@@ -89,7 +86,7 @@ let () =
Hashtbl.remove state.window_workspace window;
if ws_name = state.current then
List.iter
(fun { Kutu.Layout.fw_window = window; fw_rect = rect } ->
(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
+44
View File
@@ -4,6 +4,8 @@
#include <mruby/value.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb_icccm.h>
mrb_value kutu_mrb_int_value(mrb_state *mrb, uint32_t value) {
return mrb_int_value(mrb, (mrb_int)value);
@@ -22,3 +24,45 @@ void kutu_mrb_load_file(mrb_state *mrb, const char *filename) {
mrb_load_file(mrb, file);
fclose(file);
}
xcb_size_hints_t kutu_wm_n_hints(xcb_connection_t *conn, xcb_window_t win) {
xcb_size_hints_t hints;
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_normal_hints(conn, win);
if (!xcb_icccm_get_wm_normal_hints_reply(conn, cookie, &hints, NULL))
return (xcb_size_hints_t){0};
return hints;
}
xcb_icccm_wm_hints_t kutu_wm_hints(xcb_connection_t *conn, xcb_window_t win) {
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints(conn, win);
xcb_icccm_wm_hints_t hints;
xcb_icccm_get_wm_hints_reply(conn, cookie, &hints, NULL);
return hints;
}
char *kutu_wm_name(xcb_connection_t *conn, xcb_window_t win) {
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_name(conn, win);
xcb_icccm_get_text_property_reply_t reply;
xcb_icccm_get_wm_name_reply(conn, cookie, &reply, NULL);
return reply.name;
}
uint8_t kutu_wm_transient_for(xcb_connection_t *conn, xcb_window_t win) {
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_transient_for(conn, win);
return xcb_icccm_get_wm_transient_for_reply(conn, cookie, &win, NULL);
}
void kutu_set_wm_state(xcb_connection_t *conn, xcb_window_t win, int state) {
xcb_intern_atom_cookie_t cookie =
xcb_intern_atom(conn, 0, strlen("WM_STATE"), "WM_STATE");
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, cookie, NULL);
if (!reply)
return;
xcb_atom_t WM_STATE = reply->atom;
free(reply);
uint32_t data[2];
data[0] = state;
data[1] = XCB_WINDOW_NONE;
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, WM_STATE, WM_STATE, 32,
2, data);
}
+25
View File
@@ -228,6 +228,31 @@ module Screen_iterator = struct
let screen ptr = !@(getf ptr data)
end
module Size_hints = struct
type t
let typ : t structure typ = structure "xcb_size_hints_t"
let flags = field typ "flags" uint32_t
let x = field typ "x" int32_t
let y = field typ "y" int32_t
let width = field typ "width" int32_t
let height = field typ "height" int32_t
let min_width = field typ "min_width" int32_t
let min_height = field typ "min_height" int32_t
let max_width = field typ "max_width" int32_t
let max_height = field typ "max_height" int32_t
let width_inc = field typ "width_inc" int32_t
let height_inc = field typ "height_inc" int32_t
let min_aspect_num = field typ "min_aspect_num" int32_t
let min_aspect_den = field typ "min_aspect_den" int32_t
let max_aspect_num = field typ "max_aspect_num" int32_t
let max_aspect_den = field typ "max_aspect_den" int32_t
let base_width = field typ "base_width" int32_t
let base_height = field typ "base_height" int32_t
let win_gravity = field typ "win_gravity" uint32_t
let () = seal typ
end
(* TODO: convert all these:
/* Opcode for xcb_create_notify. */
/**
+71
View File
@@ -132,6 +132,77 @@ let focus conn window =
in
Error.check conn cookie
let _xcb_wm_n_hints =
foreign "kutu_wm_n_hints"
(ptr Types.Connection.typ @-> Types.Window.typ
@-> returning Types.Size_hints.typ)
let has_flag flags flag =
Unsigned.UInt32.logand flags (Unsigned.UInt32.of_int flag)
<> Unsigned.UInt32.zero
let p_size = 1 lsl 3
let p_min_size = 1 lsl 4
let p_max_size = 1 lsl 5
let p_resize_inc = 1 lsl 6
let p_aspect = 1 lsl 7
let make_window conn window =
let hints = _xcb_wm_n_hints conn window in
let flags = getf hints Types.Size_hints.flags in
let has_min = has_flag flags p_min_size in
let has_size = has_flag flags p_size in
let has_max = has_flag flags p_max_size in
let has_aspect = has_flag flags p_aspect in
let size =
if has_size then
Some
(getf hints Types.Size_hints.width, getf hints Types.Size_hints.height)
else None
in
let min =
if has_min then
Some
( getf hints Types.Size_hints.min_width,
getf hints Types.Size_hints.min_height )
else None
in
let max =
if has_max then
Some
( getf hints Types.Size_hints.max_width,
getf hints Types.Size_hints.max_height )
else None
in
let fixed_size =
match (size, min, max) with
| Some size, _, _ -> Some size
| _, Some min, _ -> Some min
| _, _, Some max -> Some max
| _ -> None
in
let fixed_aspect =
if has_aspect then
let min_num = getf hints Types.Size_hints.min_aspect_num in
let min_den = getf hints Types.Size_hints.min_aspect_den in
let max_num = getf hints Types.Size_hints.max_aspect_num in
let max_den = getf hints Types.Size_hints.max_aspect_den in
if min_den <> Int32.zero then
Some
( Int32.div (Int32.mul (Int32.of_int 100) min_num) min_den,
Int32.of_int 100 )
else if max_den <> Int32.zero then
Some
( Int32.div (Int32.mul (Int32.of_int 100) max_num) max_den,
Int32.of_int 100 )
else None
else None
in
match (fixed_size, fixed_aspect) with
| Some (x, y), _ -> Some (x, y)
| _, Some (x, y) -> Some (x, y)
| _ -> None
let _xcb_kill_client =
foreign "xcb_kill_client"
(ptr Types.Connection.typ @-> Types.Window.typ