Capture mesh-catalog at feat/r4g (2246ccc4) with the templates its manifests name and its predefined.json, and lay the copy out as a repository's root
The catalogue's manifests moved their content into template files and fall back to predefined keys, so a copy of module.json alone no longer passes the catalogue's own check; the bus's Dockerfile is gone from the catalogue.
This commit is contained in:
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
# dmenu, as this node's launcher answers it (module rofi, novox/hq ADR 0208). The node-launcher
|
||||
# seat's dmenu-compatible command: choices on standard input, the chosen one on standard output,
|
||||
# exit 1 when nothing was chosen. A script calls `dmenu` and works whichever module holds the seat.
|
||||
#
|
||||
# rofi understands dmenu's -p, -l and -i. dmenu's look options (-fn, -nb, -nf, -sb, -sf, -m, -w)
|
||||
# take a value rofi would misread, so they are dropped with it; -b and -f are dropped alone. The
|
||||
# look is the launcher's theme.
|
||||
set -u
|
||||
n=$#
|
||||
while [ "$n" -gt 0 ]; do
|
||||
arg=$1
|
||||
shift
|
||||
n=$((n - 1))
|
||||
case $arg in
|
||||
-fn | -nb | -nf | -sb | -sf | -m | -w)
|
||||
if [ "$n" -gt 0 ]; then
|
||||
shift
|
||||
n=$((n - 1))
|
||||
fi
|
||||
;;
|
||||
-b | -f) ;;
|
||||
*) set -- "$@" "$arg" ;;
|
||||
esac
|
||||
done
|
||||
exec rofi -dmenu "$@"
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
# rofi-launch drun|run|window|filebrowser|sudo (module rofi, novox/hq ADR 0208): what the launcher's
|
||||
# key bindings run.
|
||||
#
|
||||
# After a resume the keyboard grab can fail for a moment, and rofi then exits at once: a key press
|
||||
# that opens nothing. So a failure within half a second is tried again, up to five times. A person
|
||||
# closing the menu takes longer than that, and is never shown it a second time.
|
||||
set -u
|
||||
mode=${1:-drun}
|
||||
|
||||
now_ms() { date +%s%3N; }
|
||||
|
||||
attempt() {
|
||||
i=0
|
||||
while [ "$i" -lt 5 ]; do
|
||||
start=$(now_ms)
|
||||
"$@" && return 0
|
||||
[ $(($(now_ms) - start)) -ge 500 ] && return 1
|
||||
i=$((i + 1))
|
||||
sleep 0.1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
case $mode in
|
||||
drun | run | window | filebrowser)
|
||||
attempt rofi -show "$mode"
|
||||
;;
|
||||
sudo)
|
||||
# A command line, run with sudo in the node's terminal.
|
||||
command=$(attempt rofi -dmenu -p sudo </dev/null) || exit 0
|
||||
[ -n "$command" ] || exit 0
|
||||
exec rofi-sensible-terminal -e sudo sh -c "$command"
|
||||
;;
|
||||
*)
|
||||
echo "rofi-launch: no mode $mode (drun, run, window, filebrowser, sudo)" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
# rofi-powermenu (module rofi, novox/hq ADR 0208): lock, suspend, log out, reboot, shut down.
|
||||
#
|
||||
# It belongs to the session, and it is the launcher's: its whole face is rofi's. Every action is a
|
||||
# verb of logind or the service manager, so nothing here names a window manager or a locker:
|
||||
# - lock asks logind to lock the session, which the holder of node-lock-screen answers;
|
||||
# - log out ends this login session, whichever window manager runs in it.
|
||||
# Adopted from the workstations' power menu of 2026-10-04 (after adi1090x's powermenu type-2).
|
||||
set -u
|
||||
|
||||
theme=mesh-powermenu
|
||||
uptime="$(uptime -p | sed -e 's/^up //')"
|
||||
|
||||
shutdown=''
|
||||
reboot=''
|
||||
lock=''
|
||||
suspend=''
|
||||
logout=''
|
||||
yes=''
|
||||
no=''
|
||||
|
||||
menu() {
|
||||
rofi -dmenu -p "Uptime: $uptime" -mesg "Uptime: $uptime" -theme "$theme"
|
||||
}
|
||||
|
||||
confirm() {
|
||||
printf '%s\n%s\n' "$yes" "$no" | rofi -dmenu -p 'Confirmation' -mesg 'Are you sure?' -theme "$theme" \
|
||||
-theme-str 'window {location: center; anchor: center; fullscreen: false; width: 350px;}' \
|
||||
-theme-str 'mainbox {children: [ "message", "listview" ];}' \
|
||||
-theme-str 'listview {columns: 2; lines: 1;}' \
|
||||
-theme-str 'element-text {horizontal-align: 0.5;}' \
|
||||
-theme-str 'textbox {horizontal-align: 0.5;}'
|
||||
}
|
||||
|
||||
session() {
|
||||
# The login session this menu runs in: the session's own id, else logind's answer for this process.
|
||||
if [ -n "${XDG_SESSION_ID:-}" ]; then
|
||||
echo "$XDG_SESSION_ID"
|
||||
else
|
||||
loginctl show-session auto -p Id --value 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
confirmed() { [ "$(confirm)" = "$yes" ]; }
|
||||
|
||||
chosen="$(printf '%s\n' "$lock" "$suspend" "$logout" "$reboot" "$shutdown" | menu)" || exit 0
|
||||
case $chosen in
|
||||
"$lock") loginctl lock-session "$(session)" ;;
|
||||
"$suspend") confirmed && systemctl suspend ;;
|
||||
"$logout") confirmed && loginctl terminate-session "$(session)" ;;
|
||||
"$reboot") confirmed && systemctl reboot ;;
|
||||
"$shutdown") confirmed && systemctl poweroff ;;
|
||||
esac
|
||||
exit 0
|
||||
@@ -0,0 +1,54 @@
|
||||
/* rofi, the launcher (module rofi, novox/hq ADR 0208). Owned by the mesh: this file is replaced at
|
||||
* every push. Adopted from the two workstations' file of 2026-10-04: the settings that differ from
|
||||
* rofi's defaults, nothing else. Its look is the theme "mesh", in themes/ beside this file. */
|
||||
|
||||
configuration {
|
||||
modi: "drun,run,window,filebrowser";
|
||||
show-icons: true;
|
||||
case-sensitive: false;
|
||||
normalize-match: true;
|
||||
matching: "normal";
|
||||
tokenize: true;
|
||||
cycle: true;
|
||||
steal-focus: false;
|
||||
click-to-exit: true;
|
||||
sort: false;
|
||||
|
||||
/* Applications: the user's and the system's desktop entries, read fresh each time so a
|
||||
* program installed a minute ago is there. */
|
||||
drun-match-fields: "name,generic,exec,categories,keywords";
|
||||
drun-display-format: "{name} [<span weight='light' size='small'><i>({generic})</i></span>]";
|
||||
drun-show-actions: false;
|
||||
drun-url-launcher: "xdg-open";
|
||||
drun-use-desktop-cache: false;
|
||||
drun-reload-desktop-cache: false;
|
||||
run,drun {
|
||||
fallback-icon: "application-x-addon";
|
||||
}
|
||||
|
||||
/* A command run from `run` opens in the node's terminal when it asks for one. */
|
||||
terminal: "rofi-sensible-terminal";
|
||||
run-shell-command: "{terminal} -e {cmd}";
|
||||
ssh-command: "{terminal} -e {ssh-client} {host} [-p {port}]";
|
||||
parse-hosts: true;
|
||||
parse-known-hosts: true;
|
||||
|
||||
window-match-fields: "title,class,role,name,desktop";
|
||||
window-format: "{w} - {c} - {t:0}";
|
||||
|
||||
disable-history: false;
|
||||
max-history-size: 25;
|
||||
|
||||
filebrowser {
|
||||
directories-first: true;
|
||||
sorting-method: "name";
|
||||
}
|
||||
|
||||
display-window: "Windows";
|
||||
display-run: "Run";
|
||||
display-ssh: "SSH";
|
||||
display-drun: "Apps";
|
||||
display-filebrowser: "Files";
|
||||
}
|
||||
|
||||
@theme "mesh"
|
||||
@@ -0,0 +1,8 @@
|
||||
# The launcher's key bindings (module rofi, novox/hq ADR 0208). Owned by the mesh: replaced at every
|
||||
# push. i3 reads this file through its configuration's `include ~/.config/i3/config.d/*.conf`, after
|
||||
# the variables it sets, so $mod is i3's.
|
||||
bindsym $mod+d exec --no-startup-id ~/.local/bin/rofi-launch drun
|
||||
bindsym $mod+t exec --no-startup-id ~/.local/bin/rofi-launch run
|
||||
bindsym $mod+Shift+t exec --no-startup-id ~/.local/bin/rofi-launch sudo
|
||||
bindsym $mod+Shift+w exec --no-startup-id ~/.local/bin/rofi-launch window
|
||||
bindsym $mod+Escape exec --no-startup-id ~/.local/bin/rofi-powermenu
|
||||
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* The theme "mesh-powermenu" (module rofi, novox/hq ADR 0208): the power menu's five buttons.
|
||||
* Owned by the mesh; replaced at every push. Adopted from the workstations' power menu theme of
|
||||
* 2026-10-04 (after adi1090x's powermenu type-2, style-1), its colours inlined.
|
||||
**/
|
||||
|
||||
/*****----- Configuration -----*****/
|
||||
configuration {
|
||||
show-icons: false;
|
||||
}
|
||||
|
||||
/*****----- Global Properties -----*****/
|
||||
* {
|
||||
background: #000000FF;
|
||||
background-alt: #282B31FF;
|
||||
foreground: #FFFFFFFF;
|
||||
selected: #DE5200FF;
|
||||
active: #DE5200FF;
|
||||
urgent: #CC0000FF;
|
||||
|
||||
font: "JetBrainsMono Nerd Font 11";
|
||||
}
|
||||
|
||||
|
||||
/*****----- Main Window -----*****/
|
||||
window {
|
||||
/* properties for window widget */
|
||||
transparency: "real";
|
||||
location: center;
|
||||
anchor: center;
|
||||
fullscreen: false;
|
||||
width: 800px;
|
||||
x-offset: 0px;
|
||||
y-offset: 0px;
|
||||
|
||||
/* properties for all widgets */
|
||||
enabled: true;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
cursor: "default";
|
||||
background-color: @background;
|
||||
}
|
||||
|
||||
/*****----- Main Box -----*****/
|
||||
mainbox {
|
||||
enabled: true;
|
||||
spacing: 15px;
|
||||
margin: 0px;
|
||||
padding: 30px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: transparent;
|
||||
children: [ "inputbar", "listview" ];
|
||||
}
|
||||
|
||||
/*****----- Inputbar -----*****/
|
||||
inputbar {
|
||||
enabled: true;
|
||||
spacing: 15px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: transparent;
|
||||
text-color: @foreground;
|
||||
children: [ "textbox-prompt-colon", "prompt"];
|
||||
}
|
||||
|
||||
dummy {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
textbox-prompt-colon {
|
||||
enabled: true;
|
||||
expand: false;
|
||||
str: "";
|
||||
padding: 12px 16px;
|
||||
border-radius: 0px;
|
||||
background-color: @urgent;
|
||||
text-color: @background;
|
||||
}
|
||||
prompt {
|
||||
enabled: true;
|
||||
padding: 12px;
|
||||
border-radius: 0px;
|
||||
background-color: @active;
|
||||
text-color: @background;
|
||||
}
|
||||
|
||||
/*****----- Message -----*****/
|
||||
message {
|
||||
enabled: true;
|
||||
margin: 0px;
|
||||
padding: 12px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: @background-alt;
|
||||
text-color: @foreground;
|
||||
}
|
||||
textbox {
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.5;
|
||||
placeholder-color: @foreground;
|
||||
blink: true;
|
||||
markup: true;
|
||||
}
|
||||
error-message {
|
||||
padding: 12px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: @background;
|
||||
text-color: @foreground;
|
||||
}
|
||||
|
||||
/*****----- Listview -----*****/
|
||||
listview {
|
||||
enabled: true;
|
||||
columns: 5;
|
||||
lines: 1;
|
||||
cycle: true;
|
||||
dynamic: true;
|
||||
scrollbar: false;
|
||||
layout: vertical;
|
||||
reverse: false;
|
||||
fixed-height: true;
|
||||
fixed-columns: true;
|
||||
|
||||
spacing: 15px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: transparent;
|
||||
text-color: @foreground;
|
||||
cursor: "default";
|
||||
}
|
||||
|
||||
/*****----- Elements -----*****/
|
||||
element {
|
||||
enabled: true;
|
||||
spacing: 0px;
|
||||
margin: 0px;
|
||||
padding: 40px 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: @background-alt;
|
||||
text-color: @foreground;
|
||||
cursor: pointer;
|
||||
}
|
||||
element-text {
|
||||
font: "JetBrainsMono Nerd Font Bold 32";
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
cursor: inherit;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.5;
|
||||
}
|
||||
element selected.normal {
|
||||
background-color: var(selected);
|
||||
text-color: var(background);
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* The theme "mesh" (module rofi, novox/hq ADR 0208): every rofi window unless a caller names
|
||||
* another. Owned by the mesh; replaced at every push. Adopted from the workstations' theme of
|
||||
* 2026-10-04 (after adi1090x's launcher type-4, style-1), its colour file inlined so the theme is
|
||||
* one file, and its face the monospace one every desktop module names.
|
||||
**/
|
||||
|
||||
/*****----- Global Properties -----*****/
|
||||
* {
|
||||
background: #000000FF;
|
||||
background-alt: #282B31FF;
|
||||
foreground: #FFFFFFFF;
|
||||
selected: #DE5200FF;
|
||||
active: #DE5200FF;
|
||||
urgent: #CC0000FF;
|
||||
|
||||
font: "JetBrainsMono Nerd Font 11";
|
||||
|
||||
border-colour: var(selected);
|
||||
handle-colour: var(selected);
|
||||
background-colour: var(background);
|
||||
foreground-colour: var(foreground);
|
||||
alternate-background: var(background-alt);
|
||||
normal-background: var(background);
|
||||
normal-foreground: var(foreground);
|
||||
urgent-background: var(urgent);
|
||||
urgent-foreground: var(background);
|
||||
active-background: var(active);
|
||||
active-foreground: var(background);
|
||||
selected-normal-background: var(selected);
|
||||
selected-normal-foreground: var(background);
|
||||
selected-urgent-background: var(active);
|
||||
selected-urgent-foreground: var(background);
|
||||
selected-active-background: var(urgent);
|
||||
selected-active-foreground: var(background);
|
||||
alternate-normal-background: var(background);
|
||||
alternate-normal-foreground: var(foreground);
|
||||
alternate-urgent-background: var(urgent);
|
||||
alternate-urgent-foreground: var(background);
|
||||
alternate-active-background: var(active);
|
||||
alternate-active-foreground: var(background);
|
||||
}
|
||||
|
||||
/*****----- Main Window -----*****/
|
||||
window {
|
||||
transparency: "real";
|
||||
location: center;
|
||||
anchor: center;
|
||||
fullscreen: false;
|
||||
width: 600px;
|
||||
x-offset: 0px;
|
||||
y-offset: 0px;
|
||||
enabled: true;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 1px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
cursor: "default";
|
||||
background-color: @background-colour;
|
||||
}
|
||||
|
||||
/*****----- Main Box -----*****/
|
||||
mainbox {
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
children: [ "inputbar", "message", "listview", "mode-switcher" ];
|
||||
}
|
||||
|
||||
/*****----- Inputbar -----*****/
|
||||
inputbar {
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: 0px 0px 1px 0px;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: @alternate-background;
|
||||
text-color: @foreground-colour;
|
||||
children: [ "prompt", "entry" ];
|
||||
}
|
||||
|
||||
prompt {
|
||||
enabled: true;
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
textbox-prompt-colon {
|
||||
enabled: true;
|
||||
expand: false;
|
||||
str: "::";
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
entry {
|
||||
enabled: true;
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
cursor: text;
|
||||
placeholder: "Search...";
|
||||
placeholder-color: inherit;
|
||||
}
|
||||
|
||||
/*****----- Listview -----*****/
|
||||
listview {
|
||||
enabled: true;
|
||||
columns: 1;
|
||||
lines: 8;
|
||||
cycle: true;
|
||||
dynamic: true;
|
||||
scrollbar: false;
|
||||
layout: vertical;
|
||||
reverse: false;
|
||||
fixed-height: true;
|
||||
fixed-columns: true;
|
||||
spacing: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
cursor: "default";
|
||||
}
|
||||
scrollbar {
|
||||
handle-width: 5px;
|
||||
handle-color: @handle-colour;
|
||||
border-radius: 0px;
|
||||
background-color: @alternate-background;
|
||||
}
|
||||
|
||||
/*****----- Elements -----*****/
|
||||
element {
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
cursor: pointer;
|
||||
}
|
||||
element normal.normal {
|
||||
background-color: var(normal-background);
|
||||
text-color: var(normal-foreground);
|
||||
}
|
||||
element normal.urgent {
|
||||
background-color: var(urgent-background);
|
||||
text-color: var(urgent-foreground);
|
||||
}
|
||||
element normal.active {
|
||||
background-color: var(active-background);
|
||||
text-color: var(active-foreground);
|
||||
}
|
||||
element selected.normal {
|
||||
background-color: var(selected-normal-background);
|
||||
text-color: var(selected-normal-foreground);
|
||||
}
|
||||
element selected.urgent {
|
||||
background-color: var(selected-urgent-background);
|
||||
text-color: var(selected-urgent-foreground);
|
||||
}
|
||||
element selected.active {
|
||||
background-color: var(selected-active-background);
|
||||
text-color: var(selected-active-foreground);
|
||||
}
|
||||
element alternate.normal {
|
||||
background-color: var(alternate-normal-background);
|
||||
text-color: var(alternate-normal-foreground);
|
||||
}
|
||||
element alternate.urgent {
|
||||
background-color: var(alternate-urgent-background);
|
||||
text-color: var(alternate-urgent-foreground);
|
||||
}
|
||||
element alternate.active {
|
||||
background-color: var(alternate-active-background);
|
||||
text-color: var(alternate-active-foreground);
|
||||
}
|
||||
element-icon {
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
size: 24px;
|
||||
cursor: inherit;
|
||||
}
|
||||
element-text {
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
highlight: inherit;
|
||||
cursor: inherit;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.0;
|
||||
}
|
||||
|
||||
/*****----- Mode Switcher -----*****/
|
||||
mode-switcher {
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
}
|
||||
button {
|
||||
padding: 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: @alternate-background;
|
||||
text-color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
button selected {
|
||||
background-color: var(selected-normal-background);
|
||||
text-color: var(selected-normal-foreground);
|
||||
}
|
||||
|
||||
/*****----- Message -----*****/
|
||||
message {
|
||||
enabled: true;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
}
|
||||
textbox {
|
||||
font: "Inter 11";
|
||||
padding: 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: @alternate-background;
|
||||
text-color: @foreground-colour;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.0;
|
||||
highlight: none;
|
||||
placeholder-color: @foreground-colour;
|
||||
blink: true;
|
||||
markup: true;
|
||||
}
|
||||
error-message {
|
||||
padding: 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: @background-colour;
|
||||
text-color: @foreground-colour;
|
||||
}
|
||||
+20
-12
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user