Compare commits

..

4 Commits
main ... phoen

Author SHA1 Message Date
Daniel Barlow 521c004726 some generally (I hope) useful config for the Pinephone 2022-07-01 22:14:51 +00:00
Daniel Barlow 160ca21afd nixos module to start kiwmi at boot
this is here for my convenience, I make no claims of practicality
or beauty (it uses nix-shell and hardcodes pathnames)
2022-07-01 22:10:12 +00:00
Daniel Barlow 0e20e4d261 only resize output when using wayland backend
surprisingly enough, real hardware complains
2022-07-01 22:09:00 +00:00
Daniel Barlow 7db61a7af0 use output width/height instead of hardcoding 2022-07-01 22:08:15 +00:00
28 changed files with 155 additions and 1992 deletions

3
.gitignore vendored
View File

@ -1,3 +0,0 @@
*~
result*
*.img

View File

@ -1,11 +1,9 @@
# eufon
**Broken, not ready for use**
> *euphony*: _noun_ Harmonious arrangement of sounds in composition; a smooth and agreeable combination of articulate elements in any piece of writing.
A mostly Fennel-based graphical environment tailored for Linux-based
mobile devices. The principles we aspire to are
A mostly Fennel-based graphical environment tailored for the Pinephone
(other Linux-based mobile devices exist). The principles we aspire to are
* "habitable software" - build the system in such a way that a
technically competent user may change it to serve their needs,
@ -16,51 +14,24 @@ mobile devices. The principles we aspire to are
hardware buttons, let's play to its strengths instead of compensating for
its weaknesses
As of 2022 these principles are more aspirational than actual. _This
repo is basically in an advanced state of brokenness_
As of 2022 these principles are more aspirational than actual.
## Running the shell/apps locally
## Running it
$ nix-shell
nix-shell$ kiwmi -c init.lua
$ nix-shell --run "kiwmi -c init.lua"
This works on desktop or on mobile - Kiwmi is built on wlroots, which
will open a window on your existing Wayland or X11 desktop if you're
running one.
If you're connected over ssh and want to run Kiwmi on the console,
further contortions are required as you don't have the permissions
by default: run this before attempting to start Kiwmi
nix-shell -p seatd --run "sudo -b seatd -u $USER"
`shell.nix` sets `LUA_PATH` and `LUA_CPATH` settings appropriately -
if you want to write a real derivation (I'll get to it eventually)
you'll need to sort that out yourself. Nix generates a wrapper script
for the Lua interpreter itself, but it doesn't do the same for kiwmi.
## Connecting to the repl
By default Eufon opens a Unix socket to which you can connect to
interact with a Fennel REPL. The `eufonctl` script is a wrapper around
[socat](http://www.dest-unreach.org/socat/)
$ eufonctl $WAYLAND_DISPLAY
## Building for a device
Eufon can be installed as a [Mobile NixOS](https://github.com/NixOS/mobile-nixos/) module, by adding
`module.nix` to the `imports` in `your configuration.nix`. For example, on my development phone I
have
```nix
imports = [
(import <mobile-nixos/lib/configuration.nix> {
device = "motorola-potter";
})
/home/dan/src/phoen/eufon/module.nix
];
```
Instructions for using Mobile NixOS are currently outside the scope of
this README.
If you are using the example rc.fnl, it opens a Unix socket that you
can connect to and interact with a Fennel REPL. I use
[socat](http://www.dest-unreach.org/socat/) for this purpose:
$ socat - unix-connect:${XDG_RUNTIME_DIR}/kiwmi-repl.wayland-1.socket
# TODO
@ -79,7 +50,7 @@ this README.
- gestures to switch view
- gesture to launch terminal?
- some way to kill an app
- finish adding touch support to Kiwmi - https://github.com/buffet/kiwmi/pull/64
- kiwmi may or may not have touch support
- [ ] some way to add launcher shortcuts for Fennel functions
- [ ] hook up system to session bus, to handle incoming calls

View File

@ -1,2 +0,0 @@
#!/usr/bin/env bash
kiwmi -V -V -c init.lua

View File

@ -1,9 +0,0 @@
#!/usr/bin/env bash
SOCAT=socat
display=$1
test -n "$display" || display=$WAYLAND_DISPLAY
test -n "$display" || display=wayland-0
socket_name="${XDG_RUNTIME_DIR}/kiwmi-repl.${display}.socket"
${SOCAT} - unix-connect:$socket_name

View File

@ -8,7 +8,7 @@
(local Gtk lgi.Gtk)
(fn relpath [filename]
(.. (os.getenv "EUFON_PATH") "/crier/" filename))
(.. "crier/" filename))
(local dbus-service-attrs
{

View File

@ -10,10 +10,6 @@
, gtk3
, gtk-layer-shell
, lua5_3
, socat
, cpio
, makeWrapper
} :
let
lua = lua5_3;
@ -66,29 +62,6 @@ stdenv.mkDerivation {
gtk3
webkitgtk
];
nativeBuildInputs = [ cpio makeWrapper ];
installPhase = ''
export LUA_PATH="`lua -e 'print(package.path)'`"
export LUA_CPATH="`lua -e 'print(package.cpath)'`"
mkdir -p $out/bin
find . -name kiwmi -prune \
-o -type l -prune \
-o -name git -prune \
-o -print0 | cpio -0 -v --pass-through $out
substitute bin/eufonctl.sh $out/bin/eufonctl \
--replace SOCAT=socat SOCAT=${socat}/bin/socat
makeWrapper ${kiwmi}/bin/kiwmi $out/bin/eufon \
--set LUA_PATH "$out/?.lua;$LUA_PATH" \
--set LUA_CPATH "$LUA_CPATH" \
--prefix PATH : ${kiwmi}/bin:${luaWithPackages}/bin \
--set EUFON_PATH "$out" \
--set GIO_EXTRA_MODULES "${glib-networking}/lib/gio/modules" \
--set GI_TYPELIB_PATH "$GI_TYPELIB_PATH" \
--add-flags "-c $out/init.lua"
chmod +x $out/bin/eufon
'';
src = ./.;
}

200
eufon.fnl
View File

@ -1,200 +0,0 @@
;; -*- mode: Fennel;
(local { : view } (require :fennel))
(local texture (require :texture))
(local matrix (require :matrix))
(local socket-repl (require :socket-repl))
(local app-state
{
:in-overview false
:focus-view nil
:views []
})
(let [repl-socket-name
(..
(: (os.getenv "XDG_RUNTIME_DIR") :gsub "/$" "")
"/kiwmi-repl."
(os.getenv "WAYLAND_DISPLAY")
".socket"
)]
(socket-repl.start repl-socket-name))
(fn resize-wayland-backend [output]
(when (string.find (output:name) "^WL-")
(output:set_mode 360 720 0)))
(fn kill-window []
(print "DIE")
true)
(fn launch []
(print "WHOOSH")
true)
(fn eufon-path [f]
(.. (os.getenv "EUFON_PATH") "/" f))
(fn show-overview []
(let [facets 64
angle (/ (* 2 math.pi) facets)
scale 0.6
y-offset (+ (* 1 680)
(/ (* 360 facets) (* 2 math.pi)))
]
(each [i view (ipairs app-state.views)]
(doto view
(: :set_matrix
(-> matrix.identity
(matrix.scale scale scale)
(matrix.translate (* 2 180) (+ y-offset))
(matrix.rotate (/ (* (- i 2
) angle) 1))
(matrix.translate (* -2 180) (- y-offset))
(matrix.translate 120 150)
))
(: :show)))))
(fn hide-overview []
(each [k view (pairs app-state.views)]
(view:set_matrix matrix.identity)
(if (= (view:id) (app-state.focus-view:id))
(doto view
(: :show)
(: :focus))
(view:hide))))
(fn carousel []
(let [was app-state.in-overview]
(if was
(hide-overview)
(show-overview))
(: (kiwmi:active_output) :redraw)
(tset app-state :in-overview (not was))))
(fn placements [output]
(let [(width height) (output:size)
bar-height (/ height 15)]
{
:application {
:x 0
:y 0
:w width
:h (- height (* bar-height 1.1))
}
:bar {
:x 0
:y (- height (* bar-height 1.1))
:w width
:h (* bar-height 1.1)
}
:kill {
:x (- (* width 0.25) (/ bar-height 2))
:y (- height bar-height)
:w bar-height
:h bar-height
:on-press kill-window
}
:launch {
:x (- (* width 0.5) (/ bar-height 2))
:y (- height bar-height)
:w bar-height
:h bar-height
:on-press launch
}
:overview {
:x (- (* width 0.75) (/ bar-height 2))
:y (- height bar-height)
:w bar-height
:h bar-height
:on-press carousel
}
}))
(fn choose-view-at [x y]
(let [view (kiwmi:view_at x y)]
(tset app-state :focus-view view)
(tset app-state :in-overview false)
(hide-overview)
true))
(let [cursor (kiwmi:cursor)]
(cursor:on "button_up"
(fn [button-id]
(when app-state.in-overview
(let [geom (placements (kiwmi:active_output))
(x y) (cursor:pos)]
(if (< y geom.application.h)
(choose-view-at x y)
false))))))
(kiwmi:on
"output"
(fn [output]
(resize-wayland-backend output)
(let [(width height) (output:size)
r (output:renderer)
kill (texture.from-file r (eufon-path "close-window.png"))
launch (texture.from-file r (eufon-path "launcher.png"))
overview (texture.from-file r (eufon-path "carousel.png"))]
(output:on "render"
(fn [{: output : renderer}]
(let [buttons (placements output)]
(renderer:draw_rect :#77000077
buttons.bar.x buttons.bar.y
buttons.bar.w buttons.bar.h)
(renderer:draw_texture
kill
matrix.identity
buttons.kill.x buttons.kill.y
0.7)
(renderer:draw_texture
launch
matrix.identity
buttons.launch.x buttons.launch.y
0.7)
(renderer:draw_texture
overview
matrix.identity
buttons.overview.x buttons.overview.y
0.7)))))))
(let [cursor (kiwmi:cursor)]
(cursor:on "button_down"
(fn [button]
(let [(x y) (cursor:pos)]
(each [name attribs (pairs (placements (kiwmi:active_output)))]
(if (and
(<= attribs.x x)
(< x (+ attribs.x attribs.w))
(<= attribs.y y)
(< y (+ attribs.y attribs.h)))
(if attribs.on-press (attribs.on-press))))))))
(kiwmi:on "view"
(fn [view]
(let [geom (placements (kiwmi:active_output))]
(view:resize geom.application.w geom.application.h)
(view:move geom.application.x geom.application.y))
(view:focus)
(view:show)
(tset app-state :focus-view view)
(table.insert app-state.views view)
(view:on "request_move" #(view:imove))
(view:on "request_resize" (fn [ev] (view:iresize ev.edges)))))
(kiwmi:spawn "swaybg -c '#ff00ff'")
(kiwmi:spawn "lua -l fennelrun modeline")
;(kiwmi:spawn "lua -l fennelrun saturn")
(kiwmi:spawn "lua -l fennelrun crier")
(kiwmi:spawn "lua -l fennelrun just https://brvt.telent.net")
;(kiwmi:spawn "foot")
;; Local Variables:
;; inferior-lisp-program: "eufonctl"
;; End:

View File

@ -1,6 +1,4 @@
local fennel = require("fennel")
table.insert(package.loaders or package.searchers, fennel.searcher)
fennel.path = os.getenv("EUFON_PATH") .. "/?.fnl;" ..
os.getenv("EUFON_PATH") .. "/?/init.fnl;"
require(arg[0])
-- print(fennel.view(arg))
fennel.dofile(arg[0], { correlate = true })

View File

@ -3,5 +3,4 @@ print(os.getenv("LUA_CPATH"))
local fennel = require("fennel")
table.insert(package.loaders or package.searchers, fennel.searcher)
fennel.path = fennel.path .. ";" .. os.getenv("EUFON_PATH") .. "/?.fnl"
require("eufon")
fennel.dofile("rc.fnl")

View File

@ -39,10 +39,6 @@ struct kiwmi_cursor {
struct wl_listener cursor_button;
struct wl_listener cursor_axis;
struct wl_listener cursor_frame;
struct wl_listener cursor_touch_up;
struct wl_listener cursor_touch_down;
struct wl_listener cursor_touch_motion;
struct wl_listener cursor_touch_frame;
struct {
struct wl_signal button_down;
@ -50,7 +46,6 @@ struct kiwmi_cursor {
struct wl_signal destroy;
struct wl_signal motion;
struct wl_signal scroll;
struct wl_signal touch;
} events;
};
@ -66,14 +61,6 @@ struct kiwmi_cursor_motion_event {
double newy;
};
struct kiwmi_cursor_touch_event {
char *event;
int id;
double x;
double y;
bool handled;
};
struct kiwmi_cursor_scroll_event {
const char *device_name;
bool is_vertical;

View File

@ -15,7 +15,6 @@ struct kiwmi_input {
struct wl_listener new_input;
struct kiwmi_cursor *cursor;
struct kiwmi_seat *seat;
int touchpads;
struct {
struct wl_signal keyboard_new;

File diff suppressed because it is too large Load Diff

View File

@ -15,8 +15,6 @@
#include "input/seat.h"
#include "server.h"
#include "vvector.h"
void
view_close(struct kiwmi_view *view)
{
@ -184,30 +182,13 @@ view_at(
double *sx,
double *sy)
{
float xy[2] = { lx, ly };
float xy_[2];
float transform[3][3];
float inv_transform[3][3];
float det;
struct kiwmi_view *view;
wl_list_for_each (view, &desktop->views, link) {
if (view->hidden || !view->mapped) {
continue;
}
/*
The view may have transformation matrix, so we need to map
lx, ly into the view co-ordinate space before calling
surface_at. Or possibly vice versa. This stuff makes my head
hurt.
*/
memcpy(transform, view->matrix, sizeof transform);
INVERT_3X3(inv_transform, det, transform);
MAT_DOT_VEC_2X3(xy_, inv_transform, xy);
if (surface_at(view, surface, xy_[0], xy_[1], sx, sy)) {
if (surface_at(view, surface, lx, ly, sx, sy)) {
return view;
}
}

View File

@ -14,7 +14,6 @@
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_touch.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/util/log.h>
@ -120,130 +119,6 @@ cursor_motion_notify(struct wl_listener *listener, void *data)
process_cursor_motion(server, event->time_msec);
}
static void
cursor_touch_down_notify(struct wl_listener *listener, void *data)
{
struct kiwmi_cursor *cursor =
wl_container_of(listener, cursor, cursor_touch_down);
struct kiwmi_server *server = cursor->server;
struct kiwmi_desktop *desktop = &server->desktop;
struct wlr_event_touch_down *event = data;
struct kiwmi_input *input = &server->input;
struct wlr_seat *seat = input->seat->seat;
struct wlr_surface *surface = NULL;
/* FIXME figure out what scaling should be done here.
* Does the touch co-ordinate system map onto a single output
* (e.g. phone screen) or onto the entire layout (tablet,
* maybe?)
*/
double lx = 720 * event->x;
double ly = 1440 * event->y;
double sx, sy;
struct kiwmi_view *view = view_at(
desktop,
lx, ly,
&surface,
&sx, &sy);
wlr_log(WLR_DEBUG, "view %x surface %x %f,%f %f,%f\n",
view, surface, lx, ly, sx, sy);
/* we send the event to lua with 0..1 co-ordinates, because
* it may not be over any surface
*/
struct kiwmi_cursor_touch_event new_event = {
.event = "down",
.id = event->touch_id,
.x = event->x,
.y = event->y,
};
wl_signal_emit(&cursor->events.touch, &new_event);
if(!new_event.handled &&
surface &&
wlr_surface_accepts_touch(seat, surface)) {
wlr_log(WLR_DEBUG, "surface %x %f %f\n",
surface, sx, sy);
wlr_seat_touch_notify_down(seat, surface, event->time_msec,
event->touch_id, sx, sy);
}
}
static void
cursor_touch_up_notify(struct wl_listener *listener, void *data)
{
struct kiwmi_cursor *cursor =
wl_container_of(listener, cursor, cursor_touch_up);
struct kiwmi_server *server = cursor->server;
struct wlr_event_touch_up *event = data;
struct kiwmi_input *input = &server->input;
struct wlr_seat *seat = input->seat->seat;
struct kiwmi_cursor_touch_event new_event = {
.event = "up",
.id = event->touch_id,
};
wl_signal_emit(&cursor->events.touch, &new_event);
if(!new_event.handled) {
wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id);
}
}
static void
cursor_touch_motion_notify(struct wl_listener *listener, void *data)
{
struct kiwmi_cursor *cursor =
wl_container_of(listener, cursor, cursor_touch_motion);
struct kiwmi_server *server = cursor->server;
struct wlr_event_touch_motion *event = data;
struct kiwmi_input *input = &server->input;
struct wlr_seat *seat = input->seat->seat;
struct kiwmi_cursor_touch_event new_event = {
.event = "motion",
.id = event->touch_id,
.x = event->x,
.y = event->y,
};
wl_signal_emit(&cursor->events.touch, &new_event);
if(!new_event.handled) {
/* UNSURE: should we still send this even if the touch_down
* didn't get sent because the surface doesn't accept
* touch? */
wlr_seat_touch_notify_motion(seat, event->time_msec,
event->touch_id, event->x, event->y);
}
}
static void
cursor_touch_frame_notify(struct wl_listener *listener, void *data)
{
struct kiwmi_cursor *cursor =
wl_container_of(listener, cursor, cursor_touch_frame);
struct kiwmi_server *server = cursor->server;
struct kiwmi_input *input = &server->input;
struct wlr_seat *seat = input->seat->seat;
struct kiwmi_cursor_touch_event new_event = {
.event = "frame",
};
wl_signal_emit(&cursor->events.touch, &new_event);
if(!new_event.handled) {
wlr_seat_touch_notify_frame(seat);
}
}
static void
cursor_motion_absolute_notify(struct wl_listener *listener, void *data)
{
@ -377,23 +252,10 @@ cursor_create(
cursor->cursor_frame.notify = cursor_frame_notify;
wl_signal_add(&cursor->cursor->events.frame, &cursor->cursor_frame);
cursor->cursor_touch_down.notify = cursor_touch_down_notify;
wl_signal_add(&cursor->cursor->events.touch_down, &cursor->cursor_touch_down);
cursor->cursor_touch_up.notify = cursor_touch_up_notify;
wl_signal_add(&cursor->cursor->events.touch_up, &cursor->cursor_touch_up);
cursor->cursor_touch_motion.notify = cursor_touch_motion_notify;
wl_signal_add(&cursor->cursor->events.touch_motion, &cursor->cursor_touch_motion);
cursor->cursor_touch_frame.notify = cursor_touch_frame_notify;
wl_signal_add(&cursor->cursor->events.touch_frame, &cursor->cursor_touch_frame);
wl_signal_init(&cursor->events.button_down);
wl_signal_init(&cursor->events.button_up);
wl_signal_init(&cursor->events.destroy);
wl_signal_init(&cursor->events.motion);
wl_signal_init(&cursor->events.touch);
wl_signal_init(&cursor->events.scroll);
return cursor;

View File

@ -28,13 +28,6 @@ new_pointer(struct kiwmi_input *input, struct wlr_input_device *device)
wlr_cursor_attach_input_device(input->cursor->cursor, device);
}
static void
new_touch(struct kiwmi_input *input, struct wlr_input_device *device)
{
wlr_cursor_attach_input_device(input->cursor->cursor, device);
input->touchpads++;
}
static void
new_keyboard(struct kiwmi_input *input, struct wlr_input_device *device)
{
@ -60,9 +53,6 @@ new_input_notify(struct wl_listener *listener, void *data)
case WLR_INPUT_DEVICE_POINTER:
new_pointer(input, device);
break;
case WLR_INPUT_DEVICE_TOUCH:
new_touch(input, device);
break;
case WLR_INPUT_DEVICE_KEYBOARD:
new_keyboard(input, device);
break;
@ -75,9 +65,6 @@ new_input_notify(struct wl_listener *listener, void *data)
if (!wl_list_empty(&input->keyboards)) {
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
}
if(input->touchpads) {
caps |= WL_SEAT_CAPABILITY_TOUCH;
}
wlr_seat_set_capabilities(input->seat->seat, caps);
}

View File

@ -162,36 +162,6 @@ kiwmi_cursor_on_motion_notify(struct wl_listener *listener, void *data)
}
}
static void
kiwmi_cursor_on_touch_notify(struct wl_listener *listener, void *data)
{
struct kiwmi_lua_callback *lc = wl_container_of(listener, lc, listener);
struct kiwmi_server *server = lc->server;
lua_State *L = server->lua->L;
struct kiwmi_cursor_touch_event *event = data;
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
lua_newtable(L);
lua_pushnumber(L, event->x);
lua_setfield(L, -2, "x");
lua_pushnumber(L, event->y);
lua_setfield(L, -2, "y");
lua_pushnumber(L, event->id);
lua_setfield(L, -2, "id");
lua_pushstring(L, event->event);
lua_setfield(L, -2, "name");
if (lua_pcall(L, 1, 0, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
}
static void
kiwmi_cursor_on_scroll_notify(struct wl_listener *listener, void *data)
{
@ -297,31 +267,6 @@ l_kiwmi_cursor_on_motion(lua_State *L)
return 0;
}
static int
l_kiwmi_cursor_on_touch(lua_State *L)
{
struct kiwmi_object *obj =
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_cursor");
luaL_checktype(L, 2, LUA_TFUNCTION);
struct kiwmi_cursor *cursor = obj->object;
struct kiwmi_server *server = cursor->server;
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
lua_pushlightuserdata(L, server);
lua_pushvalue(L, 2);
lua_pushlightuserdata(L, kiwmi_cursor_on_touch_notify);
lua_pushlightuserdata(L, &cursor->events.touch);
lua_pushlightuserdata(L, obj);
if (lua_pcall(L, 5, 0, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
return 0;
}
return 0;
}
static int
l_kiwmi_cursor_on_scroll(lua_State *L)
{
@ -351,7 +296,6 @@ static const luaL_Reg kiwmi_cursor_events[] = {
{"button_down", l_kiwmi_cursor_on_button_down},
{"button_up", l_kiwmi_cursor_on_button_up},
{"motion", l_kiwmi_cursor_on_motion},
{"touch", l_kiwmi_cursor_on_touch},
{"scroll", l_kiwmi_cursor_on_scroll},
{NULL, NULL},
};

View File

@ -216,21 +216,20 @@ kiwmi_server_event_loop_fd_handler(int fd, uint32_t mask, void *data)
lua_State *L = lc->server->lua->L;
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
lua_pushvalue(L, -1);
lua_pushinteger(L, fd);
lua_pushinteger(L, mask);
if (lua_pcall(L, 2, 1, 0)) {
if (lua_pcall(L, 2, 0, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
}
/* if callback returns false/nil, remove the handler */
if (! lua_toboolean(L, -1)) {
wl_event_source_remove(lc->event_source);
/*
FIXME we need to call
luaL_unref(L, LUA_REGISTRYINDEX, lc->callback_ref);
free(lc);
}
lua_pop(L, -1);
when the file is closed, but probably not before then
*/
return true;
}
@ -243,6 +242,7 @@ l_kiwmi_server_event_loop_add_fd(lua_State *L)
struct kiwmi_server *server = obj->object;
int fd = lua_tonumber(L, 2);
int mode = lua_tonumber(L, 3);
luaL_checktype(L, 4, LUA_TFUNCTION); // callback
@ -265,14 +265,12 @@ l_kiwmi_server_event_loop_add_fd(lua_State *L)
/* luaL_ref pops last parameter (callback) from stack */
lc->callback_ref = luaL_ref(L, LUA_REGISTRYINDEX);
lc->event_source =
wl_event_loop_add_fd(server->wl_event_loop,
fd,
event_types,
kiwmi_server_event_loop_fd_handler,
lc);
return 0;
wl_event_loop_add_fd(server->wl_event_loop,
fd,
event_types,
kiwmi_server_event_loop_fd_handler,
lc);
return true;
}

View File

@ -40,9 +40,6 @@ whenever there is activity on the file descriptor `fd`. The `mode` parameter
is one of `O_RDWR`, `O_RDONLY`, `O_WRONLY` as defined in luaposix
`posix.fcntl` module.
If `callback` returns false or nil, the handler will be unregistered
from the event loop and not called again.
#### kiwmi:focused_view()
Returns the currently focused view.

View File

@ -1,55 +0,0 @@
;; homogeneous matrix operations for 2d graphics
(local identity
[
1 0 0
0 1 0
0 0 1
])
(fn multiply-matrix [a b]
[
(+ (* (. a 1) (. b 1)) (* (. a 2) (. b 4)) (* (. a 3) (. b 7)))
(+ (* (. a 1) (. b 2)) (* (. a 2) (. b 5)) (* (. a 3) (. b 8)))
(+ (* (. a 1) (. b 3)) (* (. a 2) (. b 6)) (* (. a 3) (. b 9)))
(+ (* (. a 4) (. b 1)) (* (. a 5) (. b 4)) (* (. a 6) (. b 7)))
(+ (* (. a 4) (. b 2)) (* (. a 5) (. b 5)) (* (. a 6) (. b 8)))
(+ (* (. a 4) (. b 3)) (* (. a 5) (. b 6)) (* (. a 6) (. b 9)))
(+ (* (. a 7) (. b 1)) (* (. a 8) (. b 4)) (* (. a 9) (. b 7)))
(+ (* (. a 7) (. b 2)) (* (. a 8) (. b 5)) (* (. a 9) (. b 8)))
(+ (* (. a 7) (. b 3)) (* (. a 8) (. b 6)) (* (. a 9) (. b 9)))
])
(fn scale [matrix x y]
(let [scale [
x 0 0
0 y 0
0 0 1]]
(multiply-matrix matrix scale)))
(fn translate [matrix x y]
(let [translation [
1 0 x
0 1 y
0 0 1]]
(multiply-matrix matrix translation)))
(fn rotate [matrix rad]
(let [sin (math.sin rad)
cos (math.cos rad)
rotation [
cos (- sin) 0
sin cos 0
0 0 1
]]
(multiply-matrix matrix rotation)))
{
: identity
: scale
: translate
: rotate
}

View File

@ -9,7 +9,7 @@
;(local battery (require :blinkenlicht.metric.battery))
(local cpustat (require :blinkenlicht.metric.cpustat))
(stylesheet (.. (os.getenv "EUFON_PATH") "/modeline.css"))
(stylesheet "modeline.css")
(fn battery-icon-codepoint [status percent]
(if (= status "Charging") 0xf0e7

View File

@ -1,5 +1,4 @@
{ config, lib, pkgs, ... }:
let eufon = pkgs.callPackage ./default.nix {}; in
{
systemd.services."eufon" = {
wants = [
@ -20,7 +19,6 @@ let eufon = pkgs.callPackage ./default.nix {}; in
"systemd-udev-settle.service"
];
conflicts = [
"getty@tty1.service" # not sure if needed
"getty@tty2.service"
"plymouth-quit.service"
];
@ -29,11 +27,11 @@ let eufon = pkgs.callPackage ./default.nix {}; in
let run-eufon = pkgs.writeScript "run-eufon" ''
#!${pkgs.bash}/bin/bash
source ${config.system.build.setEnvironment}
${pkgs.dbus}/bin/dbus-run-session ${eufon}/bin/eufon
${pkgs.dbus}/bin/dbus-run-session /home/dan/src/eufon/run.sh
systemd-cat echo "dbus-run-session $?"
'';
in {
WorkingDirectory = "${eufon}";
WorkingDirectory = "/home/dan/src/eufon";
TTYPath = "/dev/tty2";
TTYReset = "yes";
TTYVHangup = "yes";
@ -42,7 +40,6 @@ let eufon = pkgs.callPackage ./default.nix {}; in
StandardInput = "tty";
StandardError = "journal";
StandardOutput = "journal";
SyslogIdentifier = "eufon";
User = "dan";
ExecStart = run-eufon;
Restart = "always";
@ -52,15 +49,9 @@ let eufon = pkgs.callPackage ./default.nix {}; in
};
};
environment.systemPackages = with pkgs; [
git eufon
git
];
boot.postBootCommands = lib.mkOrder (-1) ''
brightness=4000
echo "Setting brightness to $brightness"
echo $brightness > /sys/class/backlight/wled/brightness
'';
networking.networkmanager.enable = true;
services.logind.extraConfig = ''
HandlePowerKey=ignore
'';

108
rc.fnl Normal file
View File

@ -0,0 +1,108 @@
(local { : GdkPixbuf } (require :lgi))
(local { : view } (require :fennel))
(local socket-repl (require :socket-repl))
(let [repl-socket-name
(..
(: (os.getenv "XDG_RUNTIME_DIR") :gsub "/$" "")
"/kiwmi-repl."
(os.getenv "WAYLAND_DISPLAY")
".socket"
)]
(socket-repl.start repl-socket-name))
(fn texture-from-file [renderer filename]
(let [pixels
(let [(buf err) (GdkPixbuf.Pixbuf.new_from_file filename)]
(if (not buf) (print :err err))
buf)]
(renderer:texture_from_pixels
pixels.rowstride
pixels.width
pixels.height
(pixels:get_pixels))))
(fn resize-wayland-backend [output]
(when (string.find (output:name) "^WL-")
(output:set_mode 360 720 0)))
(kiwmi:on
"output"
(fn [output]
(resize-wayland-backend output)
(let [[width height] (output:size)
r (output:renderer)
kill (texture-from-file r "close-window.png")
launch (texture-from-file r "launcher.png")
spinner (texture-from-file r "carousel.png")]
(output:on "render"
(fn [{: output : renderer}]
(let [bar-height (/ height 15)
matrix [1 0 0
0 1 0
0 0 1]]
(renderer:draw_rect :#00000077
0 (- height bar-height)
width bar-height)
(renderer:draw_texture
kill
matrix
30 (- height bar-height)
0.7)
(renderer:draw_texture
launch
matrix
(- (/ width 2) (/ bar-height 2)) (- height bar-height)
0.7)
(renderer:draw_texture
spinner
matrix
(- width 30 bar-height) (- height bar-height)
0.7)))))))
(fn kill-window []
(print "DIE")
true)
(fn launch []
(print "WHOOSH")
true)
(fn carousel []
(print "spin spin sugar")
true)
(let [cursor (kiwmi:cursor)]
(cursor:on "button_down"
(fn [button]
(let [(x y) (cursor:pos)]
(if (> y 680)
(if (< x 70)
(kill-window)
(and (< 150 x) (< x 190))
(launch)
(and (< 285 x) (< x 330))
(carousel)
false))))))
(kiwmi:on "view"
(fn [view]
(let [(w h) (: (kiwmi:active_output) :size)]
(view:resize w h)
(view:move 0 0))
(view:focus)
(view:show)
(view:on "request_move" #(view:imove))
(view:on "request_resize" (fn [ev] (view:iresize ev.edges)))))
;(kiwmi:spawn "swaybg -c '#ff00ff'")
(kiwmi:spawn "lua -l fennelrun modeline.fnl")
(kiwmi:spawn "lua -l fennelrun saturn/main.fnl")
(kiwmi:spawn "lua -l fennelrun crier/crier.fnl")
(kiwmi:spawn "lua -l fennelrun just/just.fnl")
;(kiwmi:spawn "foot")

0
run.sh Executable file → Normal file
View File

View File

@ -5,6 +5,11 @@ in (p.overrideAttrs (o:{
shellHook = ''
export LUA_PATH=`lua -e 'print(package.path)'`
export LUA_CPATH=`lua -e 'print(package.cpath)'`
export EUFON_PATH=`pwd`
# this is a shell function mostly so that I can comment it out
# to experiment with starting sway or tinywl or something else
# to see how they behave if kiwmi is being weird
start_eufon(){
kiwmi -c init.lua;
}
'';
})).override { debug = true; }

View File

@ -20,29 +20,17 @@
(on-connected connected-fd)))
))
(fn get-input [fd]
(let [buf (unistd.read fd 1024)]
(if (and buf (> (# buf) 0))
buf
"\n,exit")))
(fn start [pathname]
(print pathname)
(unistd.unlink pathname)
(unix-socket-listener
pathname
(fn [fd]
(let [sock (fdopen fd "w+")
repl-coro (coroutine.create repl)]
(print :fd fd :sock sock)
(watch-fd fd fcntl.O_RDONLY
(fn [fd]
(coroutine.resume repl-coro (get-input fd))
(if (= (coroutine.status repl-coro) :dead)
(do
(sock:write "bye!\n")
(sock:close)
false)
true
)))
#(coroutine.resume repl-coro (unistd.read $1 1024)))
(coroutine.resume repl-coro
{:readChunk
(fn [{: stack-size}]

View File

@ -1,14 +0,0 @@
(local { : GdkPixbuf } (require :lgi))
(fn from-file [renderer filename]
(let [pixels
(let [(buf err) (GdkPixbuf.Pixbuf.new_from_file filename)]
(if (not buf) (print :err err))
buf)]
(renderer:texture_from_pixels
pixels.rowstride
pixels.width
pixels.height
(pixels:get_pixels))))
{ : from-file }