diff --git a/home/.local/bin/scripts/gui/dmenu b/home/.local/bin/scripts/gui/dmenu deleted file mode 100755 index f58a2e5..0000000 --- a/home/.local/bin/scripts/gui/dmenu +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# Compatibility executable script for applications running dmenu, which -# runs wofi in dmenu mode instead. Note: In many cases the arguments won't -# be compatible and this will fail, however the primary way scripts use -# dmenu is just for simple prompts, using the `-p` flag. and wofi does fully -# support this usage. - -cat | wofi --dmenu $@ diff --git a/home/.local/bin/scripts/gui/dmenu-scripts/dmenupass b/home/.local/bin/scripts/gui/dmenu-scripts/dmenupass deleted file mode 100755 index 8d5ce30..0000000 --- a/home/.local/bin/scripts/gui/dmenu-scripts/dmenupass +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# This script is the value for SUDO_ASKPASS variable, -# meaning that it will be used as a password prompt if needed. - -dmenu -P -p "$1" diff --git a/home/.local/bin/scripts/gui/dmenu-scripts/dmenuprompt b/home/.local/bin/scripts/gui/dmenu-scripts/dmenuprompt deleted file mode 100755 index 4d0adec..0000000 --- a/home/.local/bin/scripts/gui/dmenu-scripts/dmenuprompt +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -# Opens a basic yes/no prompt with dmenu -# This is useful for confirming whether an action should be taken - -# First try to run with restrict (-r) flag -# however not everyone has this patch applied, so if that fails, fall back -out="$(printf "No\nYes" | dmenu -i -r -p "$1" 2>/dev/null)" -if [ $? -ne 0 ]; then - out="$(printf "No\nYes" | dmenu -i -p "$1")" -fi - - -if [ "$out" == "Yes" ]; then - exit 0 -elif [ "$out" == "No" ]; then - exit 1 -else - # Dmenu allows invalid picks by explicitly typing in a different option - # when that happens, end with code 2 instead. - exit 2 -fi diff --git a/home/.local/bin/scripts/gui/hyprland/hypr-restart-portals b/home/.local/bin/scripts/gui/hyprland/hypr-restart-portals new file mode 100755 index 0000000..f58de91 --- /dev/null +++ b/home/.local/bin/scripts/gui/hyprland/hypr-restart-portals @@ -0,0 +1,8 @@ +#!/bin/sh + +sleep 4 +systemctl --user stop xdg-desktop-portal +systemctl --user stop xdg-desktop-portal-wlr +sleep 2 +systemctl --user start xdg-desktop-portal +systemctl --user start xdg-desktop-portal-wlr diff --git a/home/.local/bin/scripts/gui/hyprland/launch-hypr b/home/.local/bin/scripts/gui/hyprland/launch-hypr new file mode 100755 index 0000000..6e6ecf6 --- /dev/null +++ b/home/.local/bin/scripts/gui/hyprland/launch-hypr @@ -0,0 +1,11 @@ +#!/bin/sh + +# export SDL_VIDEODRIVER=wayland +# export _JAVA_AWT_WM_NONREPARENTING=1 +# export QT_QPA_PLATFORM=wayland +# export XDG_CURRENT_DESKTOP=sway +# export XDG_SESSION_DESKTOP=sway + +echo "---------- NEW RUN $(date) ----------" >> ~/.hyprlog.txt +Hyprland 2>&1 | awk '{ print strftime("%s: "), $0, fflush(); }' | tee -a "${XDG_CACHE_HOME:-$HOME/.cache}/.hyprlog.txt" +echo "---------- ENDED $(date) ----------" >> ~/.hyprlog.txt diff --git a/home/.local/bin/scripts/gui/dmenu-scripts/displayselect b/home/.local/bin/scripts/gui/prompt/dmenu-scripts/displayselect similarity index 100% rename from home/.local/bin/scripts/gui/dmenu-scripts/displayselect rename to home/.local/bin/scripts/gui/prompt/dmenu-scripts/displayselect diff --git a/home/.local/bin/scripts/gui/dmenu-scripts/dman b/home/.local/bin/scripts/gui/prompt/dmenu-scripts/dman similarity index 100% rename from home/.local/bin/scripts/gui/dmenu-scripts/dman rename to home/.local/bin/scripts/gui/prompt/dmenu-scripts/dman diff --git a/home/.local/bin/scripts/gui/dmenu-scripts/dmenumount b/home/.local/bin/scripts/gui/prompt/dmenu-scripts/dmenumount similarity index 100% rename from home/.local/bin/scripts/gui/dmenu-scripts/dmenumount rename to home/.local/bin/scripts/gui/prompt/dmenu-scripts/dmenumount diff --git a/home/.local/bin/scripts/gui/dmenu-scripts/dmenurecord b/home/.local/bin/scripts/gui/prompt/dmenu-scripts/dmenurecord similarity index 100% rename from home/.local/bin/scripts/gui/dmenu-scripts/dmenurecord rename to home/.local/bin/scripts/gui/prompt/dmenu-scripts/dmenurecord diff --git a/home/.local/bin/scripts/gui/dmenu-scripts/dmenuumount b/home/.local/bin/scripts/gui/prompt/dmenu-scripts/dmenuumount similarity index 100% rename from home/.local/bin/scripts/gui/dmenu-scripts/dmenuumount rename to home/.local/bin/scripts/gui/prompt/dmenu-scripts/dmenuumount diff --git a/home/.local/bin/scripts/gui/dmenu-scripts/pyrun b/home/.local/bin/scripts/gui/prompt/dmenu-scripts/pyrun similarity index 100% rename from home/.local/bin/scripts/gui/dmenu-scripts/pyrun rename to home/.local/bin/scripts/gui/prompt/dmenu-scripts/pyrun diff --git a/home/.local/bin/scripts/gui/dmenu-scripts/todo b/home/.local/bin/scripts/gui/prompt/dmenu-scripts/todo similarity index 100% rename from home/.local/bin/scripts/gui/dmenu-scripts/todo rename to home/.local/bin/scripts/gui/prompt/dmenu-scripts/todo diff --git a/home/.local/bin/scripts/gui/dmenu-scripts/website-link b/home/.local/bin/scripts/gui/prompt/dmenu-scripts/website-link similarity index 100% rename from home/.local/bin/scripts/gui/dmenu-scripts/website-link rename to home/.local/bin/scripts/gui/prompt/dmenu-scripts/website-link diff --git a/home/.local/bin/scripts/gui/prompt/menuman b/home/.local/bin/scripts/gui/prompt/menuman new file mode 100755 index 0000000..8ebbf5e --- /dev/null +++ b/home/.local/bin/scripts/gui/prompt/menuman @@ -0,0 +1,11 @@ +#!/bin/sh + +# Menu prompt to easily search for a man page to open + +page="$(apropos --long "$1" | menuprompt --choose -p "Pick man page" | awk '{print $2, $1}' | tr -d '()')" + +if tty -s; then + man "$page" +else + $TERMINAL -e man "$page" +fi diff --git a/home/.local/bin/scripts/gui/prompt/menupass b/home/.local/bin/scripts/gui/prompt/menupass new file mode 100755 index 0000000..7ca4b79 --- /dev/null +++ b/home/.local/bin/scripts/gui/prompt/menupass @@ -0,0 +1,20 @@ +#!/bin/sh + +# This script is the a wrapper around menuprompt automatically passing options +# to prompt for a password. This is necessary for SUDO_ASKPASS variable, as it +# expects a path to a single executable. +# +# SUDO_ASKPASS is an environment variable that can be set to a path of an executable, +# which will run if sudo can't obtain password from terminal (stdin), i.e. running in +# a graphical application. This script will use menuprompt to obtain the plaintext +# password and which sudo will then read and verify. +# +# This is as safe as any other SUDO_ASKPASS program, and it needs to return the final +# password in plaintext for sudo to read it, however pipes retain the same filesystem user +# permissions and shouldn't be accessible to other non-priviledged users, so it's not +# a huge security issue, but know that it will deal with plaintext passwords. +# +# You can test whether this worked by running sudo -A echo "test", making sudo use the +# SUDO_ASKPASS program to obtain the password. + +menuprompt -P -p "$1" 2>/dev/null diff --git a/home/.local/bin/scripts/gui/prompt/menuprompt b/home/.local/bin/scripts/gui/prompt/menuprompt new file mode 100755 index 0000000..19a429b --- /dev/null +++ b/home/.local/bin/scripts/gui/prompt/menuprompt @@ -0,0 +1,338 @@ +#!/bin/bash + +# Compatibility executable script for applications running dmenu, which +# runs wofi in dmenu mode instead. Note: In many cases the arguments won't +# be compatible and this will fail, however the primary way scripts use +# dmenu is just for simple prompts, using the `-p` flag. and wofi does fully +# support this usage. + +# Wrapper script for menu application independent prompts. This script will pick +# the appropriate installed prompt tool (dmenu/rofi/wofi) and use run it accordingly +# to picked usage option(s). + +help() { + cat << EOF +usage: menuprompt +Menuprompt is a wrapper script for menu application independent prompt (dmenu/rofi/wofi) + +options: + -h, --help show this help message and exit + -p, --prompt [MESSAGE] Prompt to be displayed in the menu + -a, --app [MENU_APP] Overrides the app picked by default, must be one of supported apps + -v, --verbose Show debug information (printed to stderr to retain pipeable stdout output) + -vv, --very-verbose Show even more debug information + --dry-run Don't actually run the final menu command (only useful with --verbose) + +actions: + -c, --choose + Basic pick prompt, picking from piped newline separated options + The picked option will be printed to stdout. + usage: printf 'No\nYes' | menuprompt -c -p 'Pick one: ' + -yn, --yesno + Essentially an alias for printf 'No\nYes' | menuprompt -p "\$1", however instead of printing the result + to stdout, this instead exits with code 0 on success, 1 on failure, or 2 on getting other input. This + allows for easily combining it with other applications through chaining. + example: menuprompt --yesno && poweroff or menuprompt -yn -p "Do you really want to quit?" && killall Hyprland + -P, --password + Password prompt - hides the input characters + example: menuprompt -P -p "Enter password:" | xargs -I {} echo "Hah, got your password: {}" + +supported menu applications and their actions: + dmenu: + - choose: supported + - yesno: supported + - password: supported, but requires password patch for -P argument + wofi: + - choose: supported + - yesno: supported + - password: supported, however setting --prompt won't have any effect + rofi: + - choose: supported + - yesno: supported + - password: not supported - no option for hidden input + + +passing custom arguments to menu app: + Note that when passing extra arguments, you should always explicity specify the menu application to use + as it's not guaranteed that all supported args will support given extra argument(s), nor that if they do + their support is consistent and the same argument does the same thing. + + examples: + Make dmenu run on the bottom of the screen: + printf "A\nB\nC" menuprompt --app dmenu --choose -- -b + + Run wofi with 20% width on the yesno prompt: + menuprompt --yesno -p "Do you really want to quit?" --app wofi -- --width=20% + + +exit codes: + 0: Menu app ran successfully, action completed + 1-2: Action specific + 3: User error - invalid usage + 4: Unable to pick menu app (no usable menu app installed?) + 5: Internal menuprompt error, report this! +EOF +} + +pick_menu_app() { + if [ -n "$MENU_APP" ]; then + if command -v "$MENU_APP" >/dev/null; then + echo "$MENU_APP" + return 0 + else + >&2 echo "Specified menu app by (set by \$MENU_APP) isn't a valid command \`$MENU_APP\`" + exit 3 + fi + fi + + if [ "$XDG_SESSION_TYPE" = "x11" ]; then + if command -v dmenu >/dev/null; then + echo "dmenu" + elif command -v rofi >/dev/null; then + echo "rofi" + else + >&2 echo "Menu application for x11 not found, neither dmenu nor rofi available." + exit 3 + fi + + elif [ "$XDG_SESSION_TYPE" = "wayland" ]; then + if command -v wofi >/dev/null; then + echo "wofi" + else + >&2 echo "Menu application for wayland not found, wofi not available." + exit 3 + fi + + else + >&2 echo "Unknown session type, expected \$XDG_SESSION_TYPE to be \`wayland\` or \`x11\`, got \`$XDG_SESSION_TYPE\`." + exit 3 + fi +} + +# Runs picked menu application with +# $1 pipe STDIN if set to "1", runs normally if "0" +# $2 app to use (result of pick_menu_app) +# $3 prompt to be shown (can be empty) +# $4- extra args to pass to given menu app +runmenu() { + pipe_stdin="$1" + app="$2" + prompt="$3" + shift 3 + + if [ "$VERBOSITY" -ge 2 ]; then + if [ $# -gt 0 ]; then + >&2 echo "Making menu command for app: \`$app\`, with prompt: \`$prompt\` and extra args: \`$*\`" + else + >&2 echo "Making menu command for app: \`$app\`, with prompt: \`$prompt\` (no extra args)" + fi + fi + + if [ "$app" = "dmenu" ] && [ "$pipe_stdin" -eq 0 ]; then + >&2 echo "Dmenu can only be used with piped STDIN (forgot --choose?)" + exit 3 + fi + + args=() + case "$app" in + dmenu) + args+=("-i") + ;; + wofi) + args+=("--dmenu") + ;; + rofi) + args+=("-dmenu") + ;; + *) + >&2 echo "Unsupported menu app: $app" + exit 4 + ;; + esac + + if [ -n "$prompt" ]; then + if [ "$app" = "wofi" ] && [ "$pipe_stdin" -eq 0 ]; then + >&2 echo "WARNING: wofi prompt can only be displayed with piped STDIN (forgot --choose?)" + fi + args+=("-p" "$prompt") + fi + + if [ "$VERBOSITY" -ge 1 ]; then + >&2 echo "Generated command: \`$app ${args[*]} $*\`" + fi + + if [ "$DRY_RUN" -ne 1 ]; then + if [ "$pipe_stdin" -eq 1 ]; then + cat | $app "${args[@]}" "$@" + elif [ "$pipe_stdin" -eq 0 ]; then + $app "${args[@]}" "$@" + return $? + else + >&2 echo "Internal error, pipe_stdin set to invalid value: \`$pipe_stdin\`" + exit 5 + fi + else + return 0 + fi +} + +# $1 app to use (result of pick_menu_app) +# $2 prompt to be shown (can be empty) +# $2- extra arguments to pass to given menu app +password() { + app="$1" + prompt="$2" + shift 2 + + if [ "$VERBOSITY" -ge 2 ]; then + >&2 echo "Prompting for password..." + fi + + if [ "$app" = "dmenu" ]; then + if ! runmenu "0" "$app" "$prompt" -P "$@"; then + >&2 echo "To use dmenu for passwords, you need to apply the password patch." + exit 3 + fi + elif [ "$app" = "wofi" ]; then + runmenu "0" "$app" "$prompt" -P "$@" + elif [ "$app" = "rofi" ]; then + >&2 echo "Rofi doesn't support password/hidden input." + exit 3 + else + >&2 echo "Unsupported menu application picked: \`$app\`" + exit 4 + fi +} + +# $1 app to use (result of pick_menu_app) +# $2 prompt to be shown (can be empty) +# $3- extra arguments to pass to the menu app +yesno() { + app="$1" + prompt="$2" + shift 2 + + if [ "$VERBOSITY" -ge 2 ]; then + >&2 echo "Prompting for yesno..." + fi + + temp="$(printf "No\nYes" | runmenu "1" "$app" "$prompt" "$@")" + + if [ "$VERBOSITY" -ge 2 ]; then + >&2 echo "Yesno prompt answer: \`$temp\`" + fi + + if [ "$temp" = "Yes" ]; then + return 0 + elif [ "$temp" = "No" ]; then + return 1 + else + return 2 + fi +} + +#@ - extra args to pass to picked menu app +run() { + app="$(pick_menu_app)" + + if [ "$VERBOSITY" -ge 2 ]; then + >&2 echo "ACTION: \`$ACTION\`" + >&2 echo "PROMPT_ARG: \`$PROMPT_ARG\`" + >&2 echo "picekd app: \`$app\`" + >&2 echo "Extra args: \`$*\`" + fi + + if [ -z "$ACTION" ]; then + runmenu "0" "$app" "$PROMPT_ARG" "$@" + return $? + elif [ "$ACTION" = "choose" ]; then + runmenu "1" "$app" "$PROMPT_ARG" "$@" + return $? + elif [ "$ACTION" = "yesno" ]; then + yesno "$app" "$PROMPT_ARG" "$@" + return $? + elif [ "$ACTION" = "password" ]; then + password "$app" "$PROMPT_ARG" "$@" + return $? + fi + + >&2 echo "Huh? How did you get here?" + >&2 echo "Rerun this command with the --verbose flag and submit a report with the captured output." + exit 5 +} + + +ACTION="" +PROMPT_ARG="" +MENU_APP="${MENU_APP-""}" +VERBOSITY=0 +DRY_RUN=0 +while [ "$1" ]; do + case "$1" in + # options + -h|--help) + help + exit 0 + ;; + -a|--app) + MENU_APP="$2" + shift 2 + ;; + -p|--prompt) + PROMPT_ARG="$2" + shift 2 + ;; + -v|--verbose) + VERBOSITY=1 + shift + ;; + -vv|--very-verbose) + VERBOSITY=2 + shift + ;; + --dry-run) + DRY_RUN=1 + shift + ;; + + # actions + -c|--choose) + if [ -n "$ACTION" ]; then + >&2 echo "Action already set, can't specify multiple actions" + exit 3 + fi + ACTION="choose" + shift + ;; + -yn|--yesno) + if [ -n "$ACTION" ]; then + >&2 echo "Action already set, can't specify multiple actions" + exit 3 + fi + ACTION="yesno" + shift + ;; + -P|--password) + if [ -n "$ACTION" ]; then + >&2 echo "Action already set, can't specify multiple actions" + exit 3 + fi + ACTION="password" + shift + ;; + --) + shift + run "$@" + exit $? + ;; + + # err + *) + >&2 echo "Unrecognized argument: $1" + >&2 echo "use -h or --help for help" + exit 4 + ;; + esac +done + +run diff --git a/home/.local/bin/scripts/gui/prompt/menutodo b/home/.local/bin/scripts/gui/prompt/menutodo new file mode 100644 index 0000000..4cf8c90 --- /dev/null +++ b/home/.local/bin/scripts/gui/prompt/menutodo @@ -0,0 +1,36 @@ +#!/bin/sh +# This is inspired by dmenu's todo script made by suckless +# +# Manage TODO tasks in dmenu by writing them, remove by selecting +# an existing entry +# +# Configurable variables +# --------------------------------------------------------------------- + +FILE="${XDG_DATA_HOME:-$HOME/.local/share}/todos" +PROMPT="Add/delete a task: " + +# Logic +# --------------------------------------------------------------------- +mkdir -p "$(dirname $FILE)" +touch "$FILE" + +height=$(wc -l "$FILE" | awk '{print $1}') + +# Run dmenu and keep restarting it until it returns an empty output +cmd=$(dmenu -l "$height" -p "$PROMPT" "$@" < "$FILE") +while [ -n "$cmd" ]; do + # If the output matched an existing TODO, remove it + if grep -q "^$cmd\$" "$FILE"; then + grep -v "^$cmd\$" "$FILE" > "$FILE.$$" + mv "$FILE.$$" "$FILE" + height=$(( height - 1 )) + # If the output didn't match an existing TODO, it's a new one, add it + else + echo "$cmd" >> "$FILE" + height=$(( height + 1 )) + fi + + # Keep restarting until empty output + cmd=$(dmenu -l "$height" -p "$PROMPT" "$@" < "$FILE") +done