Center TUI copy, shrink window to 520x400 via own app-id windowrule
.desktop now uses --app-id=omatether; install writes a marker-delimited float/center/size rule block into ~/.config/hypr/windows.conf (backed up once, removed on uninstall). Dropped udevadm trigger from install — it wedges an already-connected iPhone (device unconfigured); targeted usbmuxd restart instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
52c21e2467
commit
c48020f02d
2 changed files with 77 additions and 11 deletions
|
|
@ -7,7 +7,7 @@ the phone's Wi-Fi if it's on one, cellular otherwise. Works headless too.
|
|||
## TUI
|
||||
|
||||
Run `omatether.sh` with no arguments (or launch **iPhone Tether** from Walker —
|
||||
it opens as a floating window). The dashboard shows phone / tether / route
|
||||
it opens as a small floating window). The dashboard shows phone / tether / route
|
||||
state live and offers only the actions that make sense right now:
|
||||
|
||||
```
|
||||
|
|
|
|||
86
omatether.sh
86
omatether.sh
|
|
@ -12,6 +12,7 @@ set -euo pipefail
|
|||
|
||||
NETFILE="/etc/systemd/network/10-iphone-tether.network"
|
||||
DESKTOP_FILE="$HOME/.local/share/applications/omatether.desktop"
|
||||
WINDOWS_CONF="$HOME/.config/hypr/windows.conf"
|
||||
|
||||
# Route metrics: Omarchy ships ethernet=100, wifi=600, wwan=700.
|
||||
METRIC_FALLBACK=750 # tether used only when nothing better is up (default)
|
||||
|
|
@ -110,6 +111,31 @@ reload_networkd() {
|
|||
fi
|
||||
}
|
||||
|
||||
# Small centered floating window for the TUI (user-level Hyprland rule;
|
||||
# remove-then-append so re-installs stay idempotent).
|
||||
install_windowrules() {
|
||||
[[ -f $WINDOWS_CONF ]] || return 0 # not a Hyprland/Omarchy box — skip
|
||||
if ! grep -q 'omatether windowrules begin' "$WINDOWS_CONF"; then
|
||||
cp "$WINDOWS_CONF" "$WINDOWS_CONF.bak.$(date +%s)"
|
||||
fi
|
||||
sed -i '/>>> omatether windowrules begin/,/<<< omatether windowrules end/d' "$WINDOWS_CONF"
|
||||
cat >> "$WINDOWS_CONF" <<'EOF'
|
||||
# >>> omatether windowrules begin
|
||||
# omatether — small floating window, centered.
|
||||
windowrule = float on, match:class ^(omatether)$
|
||||
windowrule = center on, match:class ^(omatether)$
|
||||
windowrule = size 520 400, match:class ^(omatether)$
|
||||
# <<< omatether windowrules end
|
||||
EOF
|
||||
hyprctl reload >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
remove_windowrules() {
|
||||
[[ -f $WINDOWS_CONF ]] || return 0
|
||||
sed -i '/>>> omatether windowrules begin/,/<<< omatether windowrules end/d' "$WINDOWS_CONF"
|
||||
hyprctl reload >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
# --------------------------------------------------------- CLI commands ----
|
||||
|
||||
cmd_install() {
|
||||
|
|
@ -121,7 +147,8 @@ cmd_install() {
|
|||
reload_networkd
|
||||
ok "networkd profile written: $NETFILE (fallback priority, metric $METRIC_FALLBACK)"
|
||||
|
||||
# Floating TUI launcher for Walker (Omarchy TUI.float pattern).
|
||||
# Floating TUI launcher for Walker. Uses a dedicated app-id (rather than
|
||||
# Omarchy's generic TUI.float) so our own windowrule can size it smaller.
|
||||
local self
|
||||
self=$(realpath "$0")
|
||||
mkdir -p "$(dirname "$DESKTOP_FILE")"
|
||||
|
|
@ -129,17 +156,22 @@ cmd_install() {
|
|||
[Desktop Entry]
|
||||
Name=iPhone Tether
|
||||
Comment=Use an iPhone's internet over USB
|
||||
Exec=xdg-terminal-exec --app-id=TUI.float -e $self
|
||||
Exec=xdg-terminal-exec --app-id=omatether -e $self
|
||||
Icon=phone
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Network;
|
||||
EOF
|
||||
systemctl --user restart elephant.service 2>/dev/null || true
|
||||
ok "Walker launcher installed: 'iPhone Tether' (floating window)"
|
||||
install_windowrules
|
||||
ok "Walker launcher installed: 'iPhone Tether' (small floating window)"
|
||||
|
||||
# Nudge udev in case the phone was already plugged in before install.
|
||||
as_root udevadm trigger -s usb --action=add 2>/dev/null || true
|
||||
# If the phone was plugged in before usbmuxd existed it won't be seen yet;
|
||||
# restart usbmuxd to rescan. (Do NOT `udevadm trigger` — re-firing add
|
||||
# events on a connected iPhone wedges it: "device unconfigured".)
|
||||
if phone_on_usb && ! phone_visible; then
|
||||
revive_usbmuxd
|
||||
fi
|
||||
|
||||
say ""
|
||||
say "Run '$0' (no arguments) for the TUI, or '$0 pair' to pair now."
|
||||
|
|
@ -251,9 +283,10 @@ cmd_priority() {
|
|||
cmd_uninstall() {
|
||||
as_root rm -f "$NETFILE"
|
||||
rm -f "$DESKTOP_FILE"
|
||||
remove_windowrules
|
||||
as_root networkctl reload
|
||||
systemctl --user restart elephant.service 2>/dev/null || true
|
||||
ok "Removed $NETFILE and the Walker launcher (usbmuxd/libimobiledevice left installed)"
|
||||
ok "Removed $NETFILE, the Walker launcher and windowrules (usbmuxd/libimobiledevice left installed)"
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------- TUI -----
|
||||
|
|
@ -272,9 +305,29 @@ poll_terminal_size() {
|
|||
done
|
||||
}
|
||||
|
||||
# Visible length of a string (ANSI codes stripped; multibyte-aware).
|
||||
vis_len() {
|
||||
local s
|
||||
s=$(printf '%s' "$1" | sed 's/\x1b\[[0-9;]*m//g')
|
||||
printf '%s' "${#s}"
|
||||
}
|
||||
|
||||
# Print a line horizontally centered in the terminal. Uses $TW (measured
|
||||
# once per redraw) — tput inside redirected loops can misread the width.
|
||||
center_line() {
|
||||
local pad
|
||||
pad=$(( (${TW:-80} - $(vis_len "$1")) / 2 ))
|
||||
(( pad < 0 )) && pad=0
|
||||
printf '%*s%s\n' "$pad" '' "$1"
|
||||
}
|
||||
|
||||
tui_header() {
|
||||
gum style --border rounded --padding "0 2" --margin "0 0 1 0" \
|
||||
--border-foreground 212 --bold " OMATETHER" "${DIM}iPhone USB internet${RST}"
|
||||
local line
|
||||
while IFS= read -r line; do
|
||||
center_line "$line"
|
||||
done < <(gum style --border rounded --padding "0 2" --align center \
|
||||
--border-foreground 212 --bold " OMATETHER" "${DIM}iPhone USB internet${RST}")
|
||||
echo
|
||||
}
|
||||
|
||||
tui_connect() {
|
||||
|
|
@ -340,6 +393,7 @@ cmd_tui() {
|
|||
poll_terminal_size
|
||||
|
||||
while true; do
|
||||
TW=$(tput cols 2>/dev/null || echo 80)
|
||||
clear
|
||||
tui_header
|
||||
|
||||
|
|
@ -382,7 +436,10 @@ cmd_tui() {
|
|||
uplink_line="${RED}${RST} No internet route"
|
||||
fi
|
||||
|
||||
printf '%s\n%s\n%s\n\n' "$phone_line" "$tether_line" "$uplink_line"
|
||||
center_line "$phone_line"
|
||||
center_line "$tether_line"
|
||||
center_line "$uplink_line"
|
||||
echo
|
||||
|
||||
# --- context-aware menu ---
|
||||
local -a menu=()
|
||||
|
|
@ -398,8 +455,17 @@ cmd_tui() {
|
|||
fi
|
||||
menu+=("Status (full check)" "Refresh" "Quit")
|
||||
|
||||
# Center the menu as a block: pad every label by a common offset
|
||||
# (2 extra cols account for gum's cursor prefix).
|
||||
local maxlen=0 mpad m
|
||||
for m in "${menu[@]}"; do (( ${#m} > maxlen )) && maxlen=${#m}; done
|
||||
mpad=$(( (TW - maxlen) / 2 - 2 )); (( mpad < 0 )) && mpad=0
|
||||
local -a pmenu=()
|
||||
for m in "${menu[@]}"; do pmenu+=("$(printf '%*s%s' "$mpad" '' "$m")"); done
|
||||
|
||||
local choice
|
||||
choice=$(gum choose --header "What do you want to do?" "${menu[@]}") || break
|
||||
choice=$(gum choose --header "$(printf '%*s%s' "$((mpad + 2))" '' 'What do you want to do?')" "${pmenu[@]}") || break
|
||||
choice=${choice#"${choice%%[![:space:]]*}"} # trim the centering pad
|
||||
case $choice in
|
||||
"Install tethering support") cmd_install; gum input --placeholder "Press Enter…" >/dev/null || true ;;
|
||||
"Connect phone") tui_connect ;;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue