Odin window manager

This commit is contained in:
Joseph Ferano 2024-10-15 10:54:26 +07:00
parent 00be1d2e23
commit b2d8d37a60
4 changed files with 106 additions and 13 deletions

View File

@ -1,24 +1,36 @@
* Keymapping system * Keymapping system
** Keymap Stacking ** X11 Window Manager
- Run launcher
- Basic Window Management
- Buffer-or-x11win
** If only it had a good text editor...
- SDL2
** IMTUI Lib
- Autolayout system
** Custom Language VM
- LSP
- Treesitter
- Coroutines with the event loop
** Keymap System
*** Keymap Stacking
There shouldn't be modes, there would be keymaps and a stack. Insert mode would There shouldn't be modes, there would be keymaps and a stack. Insert mode would
be at the bottom of the stack. Adding a new mode means pushing onto the stack, be at the bottom of the stack. Adding a new mode means pushing onto the stack,
and when a keybinding event is raised, you iterate over the stack from top to and when a keybinding event is raised, you iterate over the stack from top to
bottom to find the correct keybinding. The vim nomenclature wouldn't work in bottom to find the correct keybinding. The vim nomenclature wouldn't work in
this case as you don't "leave insert mode". Rather, you pop the "normal mode" this case as you don't "leave insert mode". Rather, you pop the "normal mode"
keymap ontop of the "insert mode" keymap. keymap ontop of the "insert mode" keymap.
** Passthrough/Blocking *** Passthrough/Blocking
The keymap object should have additional settings that dictate its behavior when The keymap object should have additional settings that dictate its behavior when
a key is found and not found. a key is found and not found.
*** Found **** Found
**** Pop ***** Pop
The default could be to pop from the stack. The default could be to pop from the stack.
**** Keep ***** Keep
Keep the keymap on the stack. This is useful for both normal mode and transient Keep the keymap on the stack. This is useful for both normal mode and transient
like modes where you need to explicitly pop it from the stack. like modes where you need to explicitly pop it from the stack.
*** Not found **** Not found
**** Passthrough ***** Passthrough
Allow the loop to go to the next keymap Allow the loop to go to the next keymap
**** Block ***** Block
Ignore missing key, don't pop the keymap, maybe report an error Ignore missing key, don't pop the keymap, maybe report an error

View File

@ -13,6 +13,8 @@ using namespace std;
const int SCREEN_WIDTH = 1024; const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 768; const int SCREEN_HEIGHT = 768;
char *test_string = "This is a test string for fide";
enum KeyPressSurfaces enum KeyPressSurfaces
{ {
KEY_PRESS_SURFACE_DEFAULT, KEY_PRESS_SURFACE_DEFAULT,

View File

@ -84,7 +84,7 @@ sdl_init :: proc() -> (ok: bool) {
bt := new(BufferText) bt := new(BufferText)
bt.builder = strings.builder_make(0, 512) bt.builder = strings.builder_make(0, 512)
ctx.buffer_text = bt ctx.buffer_text = bt
append(&bt.builder.buf, "// Code goes here...\ntest more stuff ok") append(&bt.builder.buf, "// Code goes here...")
str := strings.to_cstring(&ctx.buffer_text.builder) str := strings.to_cstring(&ctx.buffer_text.builder)
color := sdl.Color{ 0, 0, 0, 255} color := sdl.Color{ 0, 0, 0, 255}
ctx.text_surface = ttf.RenderUTF8_Blended_Wrapped(ctx.font, str, color, 900); ctx.text_surface = ttf.RenderUTF8_Blended_Wrapped(ctx.font, str, color, 900);
@ -105,8 +105,10 @@ process_input :: proc() {
case .ESCAPE: case .ESCAPE:
ctx.should_close = true ctx.should_close = true
case .BACKSPACE: case .BACKSPACE:
if strings.builder_len(ctx.buffer_text.builder) > 0 {
strings.pop_rune(&ctx.buffer_text.builder) strings.pop_rune(&ctx.buffer_text.builder)
state.buffer_dirty = true state.buffer_dirty = true
}
case .RETURN: case .RETURN:
strings.write_rune(&ctx.buffer_text.builder, '\n') strings.write_rune(&ctx.buffer_text.builder, '\n')
state.buffer_dirty = true state.buffer_dirty = true
@ -124,7 +126,13 @@ update :: proc() {
color := sdl.Color{ 0, 0, 0, 255} color := sdl.Color{ 0, 0, 0, 255}
str := strings.to_cstring(&ctx.buffer_text.builder) str: cstring
if strings.builder_len(ctx.buffer_text.builder) > 0 {
str = strings.to_cstring(&ctx.buffer_text.builder)
} else {
str = cstring(" ")
}
ctx.text_surface = ttf.RenderUTF8_Blended_Wrapped(ctx.font, str, color, 900); ctx.text_surface = ttf.RenderUTF8_Blended_Wrapped(ctx.font, str, color, 900);
if (ctx.text_surface == nil) { if (ctx.text_surface == nil) {
log.errorf(sdl.GetErrorString()) log.errorf(sdl.GetErrorString())

71
odin-version/wm.odin Normal file
View File

@ -0,0 +1,71 @@
package wm
import fmt "core:fmt"
import "core:os"
import "core:log"
import "core:math"
import "core:strings"
import x "vendor:x11/xlib"
main :: proc () {
display: ^x.Display
root: x.Window
attr: x.XWindowAttributes
start: x.XButtonEvent
display = x.OpenDisplay(nil)
if display == nil {
fmt.println("Could not open display")
os.exit(1)
}
x.GrabKey(display, i32(x.KeysymToKeycode(display, x.StringToKeysym("F1"))), {.Mod1Mask},
x.DefaultRootWindow(display), true, .GrabModeAsync, .GrabModeAsync);
// x.GrabButton(display, 1, Mod1Mask, DefaultRootWindow(dpy), true,
// ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
// XGrabButton(display, 3, Mod1Mask, DefaultRootWindow(display), true,
// ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
// x.SelectInput
// display,
// root,
// {.SubstructureRedirect, .SubstructureNotify});
// x.Synchronize(display, false);
for {
e: x.XEvent
x.NextEvent(display, &e)
fmt.println("Received Event: ", e)
#partial switch e.type {
case .KeyPress:
x.RaiseWindow(display, e.xkey.subwindow)
case .ButtonPress:
x.GetWindowAttributes(display, e.xbutton.subwindow, &attr)
start = e.xbutton
case .MotionNotify:
xdiff := e.xbutton.x_root - start.x_root;
ydiff := e.xbutton.y_root - start.y_root;
xpos := attr.x + (start.button==.Button1 ? xdiff : 0)
ypos := attr.y + (start.button==.Button1 ? ydiff : 0)
width := u32(max(1, attr.width + (start.button==.Button2 ? xdiff : 0)))
height := u32(max(1, attr.height + (start.button==.Button2 ? ydiff : 0)))
x.MoveResizeWindow(display, start.subwindow, xpos, ypos, width, height)
case .ButtonRelease:
// start.subwindow = nil;
}
// else if(ev.xbutton.subwindow != None)
// else if(ev.type == MotionNotify && start.subwindow != None)
// {
// int xdiff = ev.xbutton.x_root - start.x_root;
// int ydiff = ev.xbutton.y_root - start.y_root;
// XMoveResizeWindow(dpy, start.subwindow,
// attr.x + (start.button==1 ? xdiff : 0),
// attr.y + (start.button==1 ? ydiff : 0),
// MAX(1, attr.width + (start.button==3 ? xdiff : 0)),
// MAX(1, attr.height + (start.button==3 ? ydiff : 0)));
// }
// else if(ev.type == ButtonRelease)
// start.subwindow = None;
}
}