blobject / goose

tcl window manager
MIT License
6 stars 0 forks source link

Minimal start #12

Open blobject opened 8 months ago

blobject commented 8 months ago
blobject commented 8 months ago

@Eloitor Let's write the base in zig (watched an introductory video about the language yesterday :-p). What do you say?

Eloitor commented 8 months ago

I like Zig, but sadly it is not easy to set up, it is not available in many distros: https://repology.org/project/zig/versions

In void linux (what I use) it is stuck at 0.10.1 for some months... https://github.com/void-linux/void-packages/issues?q=Updating+Zig+to+0.11.0

The upgrade from 0.10.1 to 0.11.0 is not backward compatible. Further updates may not be as well..

Other options we can consider:

Do you have other suggestions? If not, for me the clear winner is C. But we can work with Zig 0.10.1 if you want, it is nice to learn.

Eloitor commented 8 months ago
  • [ ] Write a minimal config in tcl (maybe with stub external functions and api)

River can work with a tcl config!

https://gist.github.com/Eloitor/5b4b96311e0867057114b266245671b0

Maybe we can use river to get a prototype of the configuration that we wish to have

blobject commented 8 months ago

C: No problems

C it is then :-) I mean Haskell would be a dream, but also a bit too much work for me upfront.

use river to get a prototype of the configuration

Looks good, let's take a tiny subset of this. As a minimum, I'm thinking:

void linux (what I use)

Same here!

Eloitor commented 8 months ago

what about something like this?

#!/bin/env tclsh

proc bind {keys action args} {
    # TODO
    # exec riverctl map normal "modifier keys separated with +" "Main key" "translated action"
} 

bind {Super Shift Return} {exec foot}
bind {Super Q} {focused_window close}
bind {Super Shift E} {exit}
bind {Super J} {focus [focused_window next]}
bind {Super K} {focus [focused_window previous]}
bind {Super Space} {toogle-float}
bind {Super F} {toggle-fullscreen}
Eloitor commented 8 months ago

After thinking about it I think that adopting tk syntax is better:

# Keybindings
set Mod Mod4
bind . <$Mod-E> {exit}

https://www.tcl-lang.org/man/tcl/TkCmd/bind.htm

blobject commented 8 months ago

That's awesome. Yes, tk syntax for user events that call tcl procs.

We will need to work around the fact that bind is built for x and maybe implement our own library to support wayland events. Not sure how appropriate that would be for a minimal start.

At some point, though, I would love to do something like:

package require goose
set M Mod4
set S Shift
bind . <$M-Q> close [goose::get_current_window]
bind . <$M-$S-Q> close [goose::get_all_windows]
Eloitor commented 8 months ago

implement our own library to support wayland events.

Yes we'll have to do something like that. Maybe we can adapt something already done. It should be with "{" to avoid instant execution.

bind . <$M-Q> {close [goose::get_current_window]}

Maybe even better if it is a variable:

bind . <$M-Q> {close $goose::current_window}
bind . <$M-$S-Q> {close $goose::windows}
Eloitor commented 8 months ago

We can also use tk to prototype some possible configurations:

#!/bin/env wish

wm title . "Goose"

set bindings_help {Keybindings:}

rename bind original_bind
proc bind {path binding action description} {
    global bindings_help
    append bindings_help "\n $description"
    original_bind $path $binding $action
}

bind . <c> {spawn foobar}        "c: Create window"
bind . <d> {pack forget [focus]} "d: Delete window"
bind . <e> {exit}                "e: Exit"

label .keybindingsInfo -text $bindings_help -anchor n -justify left
pack .keybindingsInfo -side left -anchor w -fill both

namespace eval goose {
    variable window {}
    variable next_id 1
}

proc spawn {command} {
    set win_name [join ".textBox $goose::next_id" ""]
    append goose::windows $win_name
    text $win_name
    pack $win_name -fill both -expand true -side left
    $win_name insert 1.0 $win_name

    incr goose::next_id
}
Eloitor commented 8 months ago

We also need syntax for place a new window on coordinades X, Y. And move a window to coordinates X, Y (with optional configurable animation).

Eloitor commented 8 months ago

We can take ideas for window placement from

https://blog.teclado.com/side-values-in-tkinters-pack-geometry-manager/

blobject commented 8 months ago

Excellent stuff. I say we aim for https://github.com/blobject/goose/issues/12#issuecomment-1989607182 as a minimal config and polish the syntax as we go.

Maybe we can start with a tcl (without tk) syntax. Still need to look at how to make tk minimally support wayland, whether it would be better to roll our own or to adopt a third-party project.

Tried compiling tinywl but it fails due to a deprecated renderer initialisating step. And it builds against wlroots 0.15. So I'll hunt for a more up-to-date project to use as a guide.

Eloitor commented 8 months ago

how to make tk minimally support wayland

Maybe we can see what undroidwish did... https://stackoverflow.com/a/48026908

blobject commented 8 months ago

Yes, will need to do some source diving there and see the least amount of work needed to get tk running natively. That project seems to bundle a version of the entire tcl environment, so I'll need to parse out just the parts we want. Hopefully, what we're trying to achieve with tk isn't as daunting as it first appears.

Eloitor commented 8 months ago

What about using Critcl?

blobject commented 7 months ago

That would be really cool. Maybe not the super low-level stuff, but for all the "wm" logic, critcl would be fantastic.

Eloitor commented 7 months ago

I made a template for void:

# Template file for 'critcl'
pkgname=critcl
version=3.2
revision=1
hostmakedepends="tcl tcllib"
depends="tcl gcc"
short_desc="Compiled Runtime In Tcl"
maintainer="Eloi Torrents <eloitor@disroot.org>"
license="TCL"
homepage="https://andreas-kupries.github.io/critcl/"
distfiles="https://github.com/andreas-kupries/critcl/archive/refs/tags/${version}.tar.gz"
checksum=20061944e28dda4ab2098b8f77682cab77973f8961f6fa60b95bcc09a546789e

do_build() {
    DESTDIR=${PKGDESTDIR} tclsh build.tcl doc install
}

do_install() {
    DESTDIR=${PKGDESTDIR} tclsh build.tcl textdoc ${DESTDIR}/usr/share/doc/${pkgname}
    DESTDIR=${PKGDESTDIR} tclsh build.tcl install
}

do_check() {
    tclsh build.tcl test
}

I'm not adding it to void packages yet because critcl --help isn't working...

blobject commented 7 months ago

@Eloitor Got tinywl building, see sandbox branch. Critcl could be used to either "replace" or "wrap" tinywl, but either way I think this is a good place to start.

blobject commented 7 months ago

https://github.com/blobject/goose/commit/24619a69d10cc4418f44c49ae3e489aae55bd594:

╭╴0 22:48:28 gcritcl ~/src/goose
╰╴critcl -pkg -I ./wlroots/include -I /usr/include/pixman-1 -I /usr/local/include wlroots.tcl 
Config:   linux-x86_64-gcc
Build:    linux-x86_64-gcc
Target:   linux-x86_64
Source:   wlroots.tcl
  (tcl 8.6)
  (provide wlroots 1)
  (headers:     -I/usr/include)
  (libraries:   -L/usr/lib/x86_64-linux-gnu)
  (libraries:   -lwayland-server)
  (libraries:   -lwlroots)
  (include <wayland-server-core.h>)
  (include <wlr/backend.h>)
 Building ...
Library:  wlroots.so
  (tcl 8.6)
  (libraries:   -L/usr/lib/x86_64-linux-gnu)
  (libraries:   -lwayland-server)
  (libraries:   -lwlroots)
  Stubs:
    critcl3.2/critcl_c/tcl8.6/tclDecls.h:
      (tclStubsPtr     =>  const TclStubs *tclStubsPtr;)
    critcl3.2/critcl_c/tcl8.6/tclPlatDecls.h:
      (tclPlatStubsPtr =>  const TclPlatStubs *tclPlatStubsPtr;)

Package Placed Into: lib/wlroots
Done

╭╴0 22:54:50 gcritcl ~/src/goose
╰╴./tinywl.tcl 
(void*) 0x557022e61670
(void*) 0x557022e61760
(void*) 0x557022e61850

🔥