From 11f4b123bf2c5da2ccfb76f6f212345f761f0db2 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Sun, 16 Jan 2022 14:49:54 +0000 Subject: [PATCH] add saturn --- saturn/Makefile | 15 ++++++++ saturn/README.md | 9 +++++ saturn/default.nix | 60 +++++++++++++++++++++++++++++ saturn/main.fnl | 94 ++++++++++++++++++++++++++++++++++++++++++++++ saturn/shell.nix | 7 ++++ 5 files changed, 185 insertions(+) create mode 100644 saturn/Makefile create mode 100644 saturn/README.md create mode 100644 saturn/default.nix create mode 100644 saturn/main.fnl create mode 100644 saturn/shell.nix diff --git a/saturn/Makefile b/saturn/Makefile new file mode 100644 index 0000000..852d14e --- /dev/null +++ b/saturn/Makefile @@ -0,0 +1,15 @@ +FENNEL?=$(fennel) +PREFIX?=/usr/local + +MODULES=main.fnl + +%.lua : %.fnl + lua $(FENNEL) --compile $< > $@ + +saturn: $(patsubst %.fnl,%.lua,$(MODULES)) Makefile + (echo -e "#!/usr/bin/lua\n" ; cat main.lua ) > $@ + chmod +x $@ + +install: + mkdir -p $(PREFIX)/bin + cp saturn $(PREFIX)/bin diff --git a/saturn/README.md b/saturn/README.md new file mode 100644 index 0000000..956bc26 --- /dev/null +++ b/saturn/README.md @@ -0,0 +1,9 @@ +# Saturn + +> Saturn 5, you really were the greatest sight + +A very simple launcher app for the Pinephone, written using Fennel and +the LGI bindings to gobject-introspection. + +I may someday separate this from the rest of Slab but for the moment +it's more convenient to keep it all together diff --git a/saturn/default.nix b/saturn/default.nix new file mode 100644 index 0000000..1ae008f --- /dev/null +++ b/saturn/default.nix @@ -0,0 +1,60 @@ +{ stdenv +, callPackage +, fetchFromGitHub +, fetchurl +, gobject-introspection +, gtk3 +, lib +, librsvg +, lua53Packages +, lua5_3 +, makeWrapper +}: +let fennel = fetchurl { + name = "fennel.lua"; + url = "https://fennel-lang.org/downloads/fennel-1.0.0"; + hash = "sha256:1nha32yilzagfwrs44hc763jgwxd700kaik1is7x7lsjjvkgapw7"; + }; + inifile = let lua = lua5_3; in lua53Packages.buildLuaPackage rec { + pname = "inifile"; + name = "${pname}-${version}"; + version = "1.0.2"; + src = fetchFromGitHub { + owner = "bartbes"; + repo = "inifile"; + rev = "f0b41a8a927f3413310510121c5767021957a4e0"; + sha256 = "1ry0q238vbp8wxwy4qp1aychh687lvbckcf647pmc03rwkakxm4r"; + }; + buildPhase = ":"; + installPhase = '' + mkdir -p "$out/share/lua/${lua.luaversion}" + cp inifile.lua "$out/share/lua/${lua.luaversion}/" + ''; + }; + lua = lua5_3.withPackages (ps: with ps; [ + inifile + inspect + lgi + luafilesystem + luaposix + readline + ]); +in stdenv.mkDerivation { + pname = "saturn"; + version = "0.4.9"; # nearly Saturn 0.5 + src =./.; + inherit fennel; + + buildInputs = [ lua gtk3 gobject-introspection.dev ]; + nativeBuildInputs = [ lua makeWrapper ]; + + makeFlags = [ "PREFIX=${placeholder "out"}" ]; + # GDK_PIXBUF_MODULE_FILE setting is to support SVG icons without + # their having been transformed to bitmaps. + # This makes a big difference to how many icons are displayed on + # my machine + postInstall = '' + echo $GI_TYPELIB_PATH + wrapProgram $out/bin/saturn --prefix GDK_PIXBUF_MODULE_FILE : ${librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache --prefix GI_TYPELIB_PATH : "$GI_TYPELIB_PATH" + ''; +} diff --git a/saturn/main.fnl b/saturn/main.fnl new file mode 100644 index 0000000..0e28c5f --- /dev/null +++ b/saturn/main.fnl @@ -0,0 +1,94 @@ + +(local lfs (require :lfs)) +(local inifile (require :inifile)) +(local inspect (require :inspect)) +(local posix (require :posix)) + +(local lgi (require :lgi)) +(local Gtk lgi.Gtk) +(local Pango lgi.Pango) + +(local icon-theme (Gtk.IconTheme.get_default)) + +(fn find-icon [name] + (var found false) + (if (= (name.sub 1 1) "/") + (Gtk.Image.new_from_file name) + (let [sizes (icon-theme:get_icon_sizes name)] + + (each [_ res (pairs [64 48]) :until found] + (set found (icon-theme:load_icon + name res + (+ Gtk.IconLookupFlags.FORCE_SVG Gtk.IconLookupFlags.USE_BUILTIN)))) + (Gtk.Image.new_from_pixbuf found)))) + +(fn read-desktop-file [f] + (let [parsed (inifile.parse f) + vals (. parsed "Desktop Entry")] + (when vals.Icon (tset vals "IconImage" (find-icon vals.Icon))) + vals)) + +(fn all-apps [] + (var apps-table []) + ;; for i in ${XDG_DATA_DIRS//:/ /} ; do ls $i/applications/*.desktop ;done + (each [path (string.gmatch (os.getenv "XDG_DATA_DIRS") "[^:]*")] + (let [apps (.. path "/applications/")] + (when (lfs.attributes apps) + (each [f (lfs.dir apps)] + (when (= (f:sub -8) ".desktop") + (let [attrs (read-desktop-file (.. apps f))] + (when (not attrs.NoDisplay) + (table.insert apps-table attrs)))))))) + apps-table) + +;; Exec entries in desktop files may contain %u %f and other characters +;; in which the launcheris supposed to interpolate filenames/urls etc. +;; We don't +(fn parse-percents [str] + (str:gsub "%%(.)" (fn [c] (if (= c "%") "%" "")))) + +(fn spawn-async [vec] + (let [pid (posix.unistd.fork)] + (if (> pid 0) + true + (< pid 0) + (assert (= "can't spawn" nil)) + (posix.spawn vec)))) + +(fn launch [app] +; (print (if app.DBusActivatable "dbus" "not dbus")) + (let [cmd (parse-percents app.Exec)] + (if app.Terminal + (spawn-async ["/usr/bin/env" "kitty" cmd]) + (spawn-async ["/usr/bin/env" "sh" "-c" cmd])) + (os.exit))) + +(fn button-for [app] + (doto (Gtk.Button + { + :label app.Name + :image-position Gtk.PositionType.TOP + :relief Gtk.ReliefStyle.NONE + :on_clicked #(launch app) }) + (: :set_image app.IconImage))) + +(let [grid (Gtk.Grid { +; :orientation "vertical" + :column_spacing 8 + :row_spacing 8 + }) + scrolled-window (Gtk.ScrolledWindow {}) + window (Gtk.Window { + :title "Saturn V" + :default_width 720 + :default_height 800 + })] + (each [i app (ipairs (all-apps))] + (let [x (% (- i 1) 8) + y (// (- i 1) 8)] + (grid:attach (button-for app) x y 1 1))) + (scrolled-window:add grid) + (window:add scrolled-window) + (window:show_all)) + +(Gtk:main) diff --git a/saturn/shell.nix b/saturn/shell.nix new file mode 100644 index 0000000..63b5737 --- /dev/null +++ b/saturn/shell.nix @@ -0,0 +1,7 @@ +with import {} ; +(callPackage ./. { +}).overrideAttrs(o: { + GDK_PIXBUF_MODULE_FILE = "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"; + nativeBuildInputs = o.nativeBuildInputs ++ + [ ] ; +})