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
|
## TUI
|
||||||
|
|
||||||
Run `omatether.sh` with no arguments (or launch **iPhone Tether** from Walker —
|
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:
|
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"
|
NETFILE="/etc/systemd/network/10-iphone-tether.network"
|
||||||
DESKTOP_FILE="$HOME/.local/share/applications/omatether.desktop"
|
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.
|
# Route metrics: Omarchy ships ethernet=100, wifi=600, wwan=700.
|
||||||
METRIC_FALLBACK=750 # tether used only when nothing better is up (default)
|
METRIC_FALLBACK=750 # tether used only when nothing better is up (default)
|
||||||
|
|
@ -110,6 +111,31 @@ reload_networkd() {
|
||||||
fi
|
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 ----
|
# --------------------------------------------------------- CLI commands ----
|
||||||
|
|
||||||
cmd_install() {
|
cmd_install() {
|
||||||
|
|
@ -121,7 +147,8 @@ cmd_install() {
|
||||||
reload_networkd
|
reload_networkd
|
||||||
ok "networkd profile written: $NETFILE (fallback priority, metric $METRIC_FALLBACK)"
|
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
|
local self
|
||||||
self=$(realpath "$0")
|
self=$(realpath "$0")
|
||||||
mkdir -p "$(dirname "$DESKTOP_FILE")"
|
mkdir -p "$(dirname "$DESKTOP_FILE")"
|
||||||
|
|
@ -129,17 +156,22 @@ cmd_install() {
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Name=iPhone Tether
|
Name=iPhone Tether
|
||||||
Comment=Use an iPhone's internet over USB
|
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
|
Icon=phone
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Network;
|
Categories=Network;
|
||||||
EOF
|
EOF
|
||||||
systemctl --user restart elephant.service 2>/dev/null || true
|
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.
|
# If the phone was plugged in before usbmuxd existed it won't be seen yet;
|
||||||
as_root udevadm trigger -s usb --action=add 2>/dev/null || true
|
# 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 ""
|
||||||
say "Run '$0' (no arguments) for the TUI, or '$0 pair' to pair now."
|
say "Run '$0' (no arguments) for the TUI, or '$0 pair' to pair now."
|
||||||
|
|
@ -251,9 +283,10 @@ cmd_priority() {
|
||||||
cmd_uninstall() {
|
cmd_uninstall() {
|
||||||
as_root rm -f "$NETFILE"
|
as_root rm -f "$NETFILE"
|
||||||
rm -f "$DESKTOP_FILE"
|
rm -f "$DESKTOP_FILE"
|
||||||
|
remove_windowrules
|
||||||
as_root networkctl reload
|
as_root networkctl reload
|
||||||
systemctl --user restart elephant.service 2>/dev/null || true
|
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 -----
|
# ----------------------------------------------------------------- TUI -----
|
||||||
|
|
@ -272,9 +305,29 @@ poll_terminal_size() {
|
||||||
done
|
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() {
|
tui_header() {
|
||||||
gum style --border rounded --padding "0 2" --margin "0 0 1 0" \
|
local line
|
||||||
--border-foreground 212 --bold " OMATETHER" "${DIM}iPhone USB internet${RST}"
|
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() {
|
tui_connect() {
|
||||||
|
|
@ -340,6 +393,7 @@ cmd_tui() {
|
||||||
poll_terminal_size
|
poll_terminal_size
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
|
TW=$(tput cols 2>/dev/null || echo 80)
|
||||||
clear
|
clear
|
||||||
tui_header
|
tui_header
|
||||||
|
|
||||||
|
|
@ -382,7 +436,10 @@ cmd_tui() {
|
||||||
uplink_line="${RED}${RST} No internet route"
|
uplink_line="${RED}${RST} No internet route"
|
||||||
fi
|
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 ---
|
# --- context-aware menu ---
|
||||||
local -a menu=()
|
local -a menu=()
|
||||||
|
|
@ -398,8 +455,17 @@ cmd_tui() {
|
||||||
fi
|
fi
|
||||||
menu+=("Status (full check)" "Refresh" "Quit")
|
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
|
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
|
case $choice in
|
||||||
"Install tethering support") cmd_install; gum input --placeholder "Press Enter…" >/dev/null || true ;;
|
"Install tethering support") cmd_install; gum input --placeholder "Press Enter…" >/dev/null || true ;;
|
||||||
"Connect phone") tui_connect ;;
|
"Connect phone") tui_connect ;;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue