This commit is contained in:
2026-06-03 21:26:54 +02:00
parent 05e6b8d061
commit d21e5175d5
125 changed files with 41986 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env sh
# Check if animations are disabled (game mode is active)
check_gamemode() {
HYPRGAMEMODE=$(hyprctl getoption animations:enabled | awk 'NR==1{print $2}')
if [ "$HYPRGAMEMODE" = 0 ] ; then
echo "t"
return 0
else
echo "f"
return 1
fi
}
# Toggle game mode state
toggle_gamemode() {
HYPRGAMEMODE=$(hyprctl getoption animations:enabled | awk 'NR==1{print $2}')
if [ "$HYPRGAMEMODE" = 1 ] ; then
hyprctl --batch "\
keyword animations:enabled 0;\
keyword decoration:shadow:enabled 0;\
keyword decoration:blur:enabled 0;\
keyword general:gaps_in 0;\
keyword general:gaps_out 0;\
keyword general:border_size 1;\
keyword decoration:rounding 0"
exit
fi
hyprctl reload
}
# Main script logic
case "$1" in
check)
check_gamemode
;;
*)
toggle_gamemode
;;
esac
@@ -0,0 +1,71 @@
# Configuración de Hyprland para Multi-Monitor Support en Ax-Shell
# Configurar monitors
monitor=DP-1,1920x1080@60,0x0,1
monitor=HDMI-A-1,1920x1080@60,1920x0,1
# Configurar workspaces por monitor
# Monitor 0: Workspaces 1-10
workspace=1,monitor:DP-1
workspace=2,monitor:DP-1
workspace=3,monitor:DP-1
workspace=4,monitor:DP-1
workspace=5,monitor:DP-1
workspace=6,monitor:DP-1
workspace=7,monitor:DP-1
workspace=8,monitor:DP-1
workspace=9,monitor:DP-1
workspace=10,monitor:DP-1
# Monitor 1: Workspaces 11-20
workspace=11,monitor:HDMI-A-1
workspace=12,monitor:HDMI-A-1
workspace=13,monitor:HDMI-A-1
workspace=14,monitor:HDMI-A-1
workspace=15,monitor:HDMI-A-1
workspace=16,monitor:HDMI-A-1
workspace=17,monitor:HDMI-A-1
workspace=18,monitor:HDMI-A-1
workspace=19,monitor:HDMI-A-1
workspace=20,monitor:HDMI-A-1
# Keybinds globales para Ax-Shell multi-monitor
# Estos comandos se ejecutan en el monitor con foco actual
# Abrir launcher en monitor con foco
bind = SUPER, SPACE, exec, python ~/.config/Ax-Shell/scripts/toggle_launcher.py
# Abrir overview en monitor con foco
bind = SUPER, TAB, exec, python ~/.config/Ax-Shell/scripts/toggle_overview.py
# Navegar entre workspaces del monitor actual
bind = SUPER, 1, workspace, 1
bind = SUPER, 2, workspace, 2
bind = SUPER, 3, workspace, 3
bind = SUPER, 4, workspace, 4
bind = SUPER, 5, workspace, 5
bind = SUPER, 6, workspace, 6
bind = SUPER, 7, workspace, 7
bind = SUPER, 8, workspace, 8
bind = SUPER, 9, workspace, 9
bind = SUPER, 0, workspace, 10
# Mover ventanas a workspaces del monitor actual
bind = SUPER SHIFT, 1, movetoworkspacesilent, 1
bind = SUPER SHIFT, 2, movetoworkspacesilent, 2
bind = SUPER SHIFT, 3, movetoworkspacesilent, 3
bind = SUPER SHIFT, 4, movetoworkspacesilent, 4
bind = SUPER SHIFT, 5, movetoworkspacesilent, 5
bind = SUPER SHIFT, 6, movetoworkspacesilent, 6
bind = SUPER SHIFT, 7, movetoworkspacesilent, 7
bind = SUPER SHIFT, 8, movetoworkspacesilent, 8
bind = SUPER SHIFT, 9, movetoworkspacesilent, 9
bind = SUPER SHIFT, 0, movetoworkspacesilent, 10
# Cambiar entre monitores
bind = SUPER, bracketleft, focusmonitor, DP-1
bind = SUPER, bracketright, focusmonitor, HDMI-A-1
# Mover ventana al otro monitor
bind = SUPER SHIFT, bracketleft, movewindow, mon:DP-1
bind = SUPER SHIFT, bracketright, movewindow, mon:HDMI-A-1
+80
View File
@@ -0,0 +1,80 @@
#!/bin/bash
pick_rgb(){
# Execute hyprpicker with RGB format and save the output to a variable
hyprpicker -a -n -f rgb && sleep 0.1
# Create a temporal 64x64 PNG file with the color in /tmp using convert
magick -size 64x64 xc:"rgb($(wl-paste))" /tmp/color.png
# Send a notification using the file as an icon
notify-send "RGB color picked" "rgb($(wl-paste))" -i /tmp/color.png -a "Hyprpicker"
# Remove the temporal file
rm /tmp/color.png
# Exit
exit 0
}
pick_hex(){
# Execute hyprpicker and save the output to a variable
hyprpicker -a -n -f hex && sleep 0.1
# Create a temporal 64x64 PNG file with the color in /tmp using convert
magick -size 64x64 xc:"$(wl-paste)" /tmp/color.png
# Send a notification using the file as an icon
notify-send "HEX color picked" "$(wl-paste)" -i /tmp/color.png -a "Hyprpicker"
# Remove the temporal file
rm /tmp/color.png
# Exit
exit 0
}
pick_hsv(){
# Copy the color to the clipboard
echo -n "$(hyprpicker -n -f hsv)" | wl-copy -n
# Create a temporal 64x64 PNG file with the color in /tmp using convert
magick -size 64x64 xc:"hsv($(wl-paste))" /tmp/color.png
# Send a notification using the file as an icon
notify-send "HSV color picked" "hsv($(wl-paste))" -i /tmp/color.png -a "Hyprpicker"
# Remove the temporal file
rm /tmp/color.png
# Exit
exit 0
}
case "$1" in
-rgb)
pick_rgb
;;
-hsv)
pick_hsv
;;
-hex)
pick_hex
;;
*)
echo "Usage: $0 [-rgb|-hex|-hsv]"
exit 1
;;
esac
+83
View File
@@ -0,0 +1,83 @@
# From https://github.com/stwa/wayland-idle-inhibitor
# License: WTFPL Version 2
import sys
from dataclasses import dataclass
from signal import SIGINT, SIGTERM, signal
from threading import Event
import setproctitle
from pywayland.client.display import Display
from pywayland.protocol.idle_inhibit_unstable_v1.zwp_idle_inhibit_manager_v1 import \
ZwpIdleInhibitManagerV1
from pywayland.protocol.wayland.wl_compositor import WlCompositor
from pywayland.protocol.wayland.wl_registry import WlRegistryProxy
from pywayland.protocol.wayland.wl_surface import WlSurface
@dataclass
class GlobalRegistry:
surface: WlSurface | None = None
inhibit_manager: ZwpIdleInhibitManagerV1 | None = None
def handle_registry_global(
wl_registry: WlRegistryProxy, id_num: int, iface_name: str, version: int
) -> None:
global_registry: GlobalRegistry = wl_registry.user_data or GlobalRegistry()
if iface_name == "wl_compositor":
compositor = wl_registry.bind(id_num, WlCompositor, version)
global_registry.surface = compositor.create_surface() # type: ignore
elif iface_name == "zwp_idle_inhibit_manager_v1":
global_registry.inhibit_manager = wl_registry.bind(
id_num, ZwpIdleInhibitManagerV1, version
)
def main() -> None:
done = Event()
signal(SIGINT, lambda _, __: done.set())
signal(SIGTERM, lambda _, __: done.set())
global_registry = GlobalRegistry()
display = Display()
display.connect()
registry = display.get_registry() # type: ignore
registry.user_data = global_registry
registry.dispatcher["global"] = handle_registry_global
def shutdown() -> None:
display.dispatch()
display.roundtrip()
display.disconnect()
display.dispatch()
display.roundtrip()
if global_registry.surface is None or global_registry.inhibit_manager is None:
print("Wayland seems not to support idle_inhibit_unstable_v1 protocol.")
shutdown()
sys.exit(1)
inhibitor = global_registry.inhibit_manager.create_inhibitor( # type: ignore
global_registry.surface
)
display.dispatch()
display.roundtrip()
print("Inhibiting idle...")
done.wait()
print("Shutting down...")
inhibitor.destroy()
shutdown()
if __name__ == "__main__":
setproctitle.setproctitle("ax-inhibit")
main()
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# Captura con hyprshot (selección de región) y envía imagen RAW a stdout
ocr_text=$(hyprshot -m region -z -r -s | tesseract -l eng - - 2>/dev/null)
# Comprueba si Tesseract devolvió algo
if [[ -n "$ocr_text" ]]; then
# Copia el texto reconocido al portapapeles
echo -n "$ocr_text" | wl-copy
notify-send -a "Ax-Shell" "OCR Success" "Text Copied to Clipboard"
else
notify-send -a "Ax-Shell" "OCR Failed" "No text recognized or operation failed"
fi
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
WORK_MINUTES=25
BREAK_MINUTES=5
LONG_BREAK_MINUTES=15
POMODOROS_PER_LONG_BREAK=4
# Get the PID of this script (excluding the grep process itself)
MYPID=$$
if pgrep -f "pomodoro.sh" | grep -qv "$MYPID"; then
# Another instance is running - kill it
notify-send "Pomodoro Timer" "Timer stopped" -a "Pomodoro"
pkill -KILL -f "pomodoro.sh"
exit
fi
# Initialize counters
pomodoro_count=0
# Main loop
while true; do
# Work period
notify-send "Pomodoro Timer" "Work time! ($WORK_MINUTES minutes)" -a "Pomodoro"
sleep ${WORK_MINUTES}m
((pomodoro_count++))
if ((pomodoro_count % POMODOROS_PER_LONG_BREAK == 0)); then
notify-send "Pomodoro Timer" "Great job! Take a long break ($LONG_BREAK_MINUTES minutes)" -a "Pomodoro"
sleep ${LONG_BREAK_MINUTES}m
else
notify-send "Pomodoro Timer" "Good work! Take a short break ($BREAK_MINUTES minutes)" -a "Pomodoro"
sleep ${BREAK_MINUTES}m
fi
done
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
# Check if XDG_VIDEOS_DIR is not set
if [ -z "$XDG_VIDEOS_DIR" ]; then
XDG_VIDEOS_DIR="$HOME/Videos"
fi
# Directorio donde se guardarán las grabaciones
SAVE_DIR="$XDG_VIDEOS_DIR/Recordings"
mkdir -p "$SAVE_DIR"
# Si ya está corriendo gpu-screen-recorder, se envía SIGINT para detenerlo correctamente
if pgrep -f "gpu-screen-recorder" >/dev/null; then
pkill -SIGINT -f "gpu-screen-recorder"
# Espera un momento para asegurarse de que la grabación se haya detenido y el archivo esté listo
sleep 1
# Obtiene el último archivo grabado
LAST_VIDEO=$(ls -t "$SAVE_DIR"/*.mp4 2>/dev/null | head -n 1)
# Notificación con acciones: "View" abre el archivo, "Open folder" abre la carpeta
ACTION=$(notify-send -a "Ax-Shell" "⬜ Recording stopped" \
-A "view=View" -A "open=Open folder")
if [ "$ACTION" = "view" ] && [ -n "$LAST_VIDEO" ]; then
xdg-open "$LAST_VIDEO"
elif [ "$ACTION" = "open" ]; then
xdg-open "$SAVE_DIR"
fi
exit 0
fi
# Nombre del archivo de salida para la nueva grabación
OUTPUT_FILE="$SAVE_DIR/$(date +%Y-%m-%d-%H-%M-%S).mp4"
# Iniciar la grabación
notify-send -a "Ax-Shell" "🔴 Recording started"
gpu-screen-recorder -w screen -q ultra -a default_output -ac opus -cr full -f 60 -o "$OUTPUT_FILE"
+105
View File
@@ -0,0 +1,105 @@
#!/usr/bin/env sh
sleep 0.5
if [ -z "$XDG_PICTURES_DIR" ]; then
XDG_PICTURES_DIR="$HOME/Pictures"
fi
save_dir="${3:-$XDG_PICTURES_DIR/Screenshots}"
save_file=$(date +'%y%m%d_%Hh%Mm%Ss_screenshot.png')
full_path="$save_dir/$save_file"
mkdir -p "$save_dir"
mockup_mode="$2"
print_error() {
cat <<EOF
./screenshot.sh <action> [mockup]
...valid actions are...
p : print selected screen
s : snip selected region
w : snip focused window
EOF
}
case $1 in
p)
hyprshot -z -s -m output -o "$save_dir" -f "$save_file"
;;
s)
hyprshot -z -s -m region -o "$save_dir" -f "$save_file"
;;
w)
hyprshot -s -m window -o "$save_dir" -f "$save_file";
;;
*)
print_error
exit 1
;;
esac
if [ -f "$full_path" ]; then
# Copiar al portapapeles si no es mockup
if [ "$mockup_mode" != "mockup" ]; then
if command -v wl-copy >/dev/null 2>&1; then
wl-copy < "$full_path"
elif command -v xclip >/dev/null 2>&1; then
xclip -selection clipboard -t image/png < "$full_path"
fi
fi
# Procesar mockup
if [ "$mockup_mode" = "mockup" ]; then
temp_file="${full_path%.png}_temp.png"
mockup_file="${full_path%.png}_mockup.png"
mockup_success=true
# Redondear esquinas y transparencia
if [ "$mockup_success" = true ]; then
magick "$full_path" \
\( +clone -alpha extract -draw 'fill black polygon 0,0 0,20 20,0 fill white circle 20,20 20,0' \
\( +clone -flip \) -compose Multiply -composite \
\( +clone -flop \) -compose Multiply -composite \
\) -alpha off -compose CopyOpacity -composite "$temp_file" || mockup_success=false
fi
# Añadir sombra
if [ "$mockup_success" = true ]; then
magick "$temp_file" \
\( +clone -background black -shadow 60x20+0+10 -alpha set -channel A -evaluate multiply 1 +channel \) \
+swap -background none -layers merge +repage "$mockup_file" || mockup_success=false
fi
if [ "$mockup_success" = true ] && [ -f "$mockup_file" ]; then
rm "$temp_file"
mv "$mockup_file" "$full_path"
if command -v wl-copy >/dev/null 2>&1; then
wl-copy < "$full_path"
elif command -v xclip >/dev/null 2>&1; then
xclip -selection clipboard -t image/png < "$full_path"
fi
else
echo "Warning: Mockup processing failed, manteniendo original." >&2
rm -f "$temp_file" "$mockup_file"
if [ "$mockup_mode" = "mockup" ]; then
if command -v wl-copy >/dev/null 2>&1; then
wl-copy < "$full_path"
elif command -v xclip >/dev/null 2>&1; then
xclip -selection clipboard -t image/png < "$full_path"
fi
fi
fi
fi
ACTION=$(notify-send -a "Ax-Shell" -i "$full_path" "Screenshot saved" "in $full_path" \
-A "view=View" -A "edit=Edit" -A "open=Open Folder")
case "$ACTION" in
view) xdg-open "$full_path" ;;
edit) swappy -f "$full_path" ;;
open) xdg-open "$save_dir" ;;
esac
else
notify-send -a "Ax-Shell" "Screenshot Aborted"
fi
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env python3
"""
Example script for opening the launcher on the focused monitor.
This script uses the global keybind handler to open the launcher
on whichever monitor currently has focus.
"""
import sys
import os
# Add the Ax-Shell directory to Python path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
try:
from utils.global_keybinds import get_global_keybind_handler
handler = get_global_keybind_handler()
success = handler.open_launcher()
if success:
print("Launcher opened on focused monitor")
sys.exit(0)
else:
print("Failed to open launcher")
sys.exit(1)
except ImportError as e:
print(f"Error importing Ax-Shell modules: {e}")
sys.exit(1)
except Exception as e:
print(f"Error opening launcher: {e}")
sys.exit(1)
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env python3
"""
Example script for opening the overview on the focused monitor.
This script uses the global keybind handler to open the overview
on whichever monitor currently has focus.
"""
import sys
import os
# Add the Ax-Shell directory to Python path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
try:
from utils.global_keybinds import get_global_keybind_handler
handler = get_global_keybind_handler()
success = handler.open_overview()
if success:
print("Overview opened on focused monitor")
sys.exit(0)
else:
print("Failed to open overview")
sys.exit(1)
except ImportError as e:
print(f"Error importing Ax-Shell modules: {e}")
sys.exit(1)
except Exception as e:
print(f"Error opening overview: {e}")
sys.exit(1)