add saturn
parent
aee37eed9a
commit
11f4b123bf
|
@ -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
|
|
@ -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
|
|
@ -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"
|
||||||
|
'';
|
||||||
|
}
|
|
@ -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)
|
|
@ -0,0 +1,7 @@
|
||||||
|
with import <nixpkgs> {} ;
|
||||||
|
(callPackage ./. {
|
||||||
|
}).overrideAttrs(o: {
|
||||||
|
GDK_PIXBUF_MODULE_FILE = "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache";
|
||||||
|
nativeBuildInputs = o.nativeBuildInputs ++
|
||||||
|
[ ] ;
|
||||||
|
})
|
Loading…
Reference in New Issue