From a9f2e864912e3ed8187c1e8367803a46148806ec Mon Sep 17 00:00:00 2001 From: kenji Date: Fri, 26 Dec 2025 09:01:49 -0600 Subject: [PATCH] Revert "this one works" This reverts commit 8ac3c212286659152dba5244b62a5320d13de402. --- apps/ghostty/home.nix | 1 - apps/hyprland/hypr/rules.nix | 3 + apps/waybar/home.nix | 6 +- scripts/hakase-scripts.nix | 123 +++++++++++++---------------------- 4 files changed, 50 insertions(+), 83 deletions(-) diff --git a/apps/ghostty/home.nix b/apps/ghostty/home.nix index 1171e6a..2407c1c 100644 --- a/apps/ghostty/home.nix +++ b/apps/ghostty/home.nix @@ -12,7 +12,6 @@ enableFishIntegration = true; settings = { - confirm-close-surface = false; window-padding-x = 15; window-padding-y = 15; window-padding-balance = true; diff --git a/apps/hyprland/hypr/rules.nix b/apps/hyprland/hypr/rules.nix index b9bbadc..99ab9c2 100644 --- a/apps/hyprland/hypr/rules.nix +++ b/apps/hyprland/hypr/rules.nix @@ -5,7 +5,10 @@ # "center, class:^(org\.hakase\..*)$" # "size 80% 70%, class:^(org\.hakase\..*)$" # Example using percentages # --- POPUP RULES (Wifi, BT, Audio) --- + "size 602 478, class:^(org\.hakase\.popup\..*)$" + "move 1312 32, class:^(org\.hakase\.popup\..*)$" "float, class:^(org\.hakase\.popup\..*)$" + "pin, class:^(org\.hakase\.popup\..*)$" "animation slide right, class:^(org\.hakase\.popup\..*)$" "dimaround, class:^(org\.hakase\.popup\..*)$" ]; diff --git a/apps/waybar/home.nix b/apps/waybar/home.nix index 5b59ae6..9160c37 100644 --- a/apps/waybar/home.nix +++ b/apps/waybar/home.nix @@ -95,7 +95,7 @@ tooltip-format-disconnected = "Disconnected"; interval = 3; spacing = 1; - on-click = "hakase-popup-wifi"; + on-click = "hakase-launch-wifi"; }; "battery" = { @@ -124,12 +124,12 @@ format-connected = "󰂱"; format-no-controller = ""; tooltip-format = "Devices connected: {num_connections}"; - on-click = "hakase-popup-bluetooth"; + on-click = "hakase-launch-bluetooth"; }; "pulseaudio" = { format = "{icon}"; - on-click = "hakase-popup-volume"; + on-click = "hakase-focus-wrapper wiremix"; on-click-right = "pamixer -t"; tooltip-format = "Playing at {volume}%"; scroll-step = 5; diff --git a/scripts/hakase-scripts.nix b/scripts/hakase-scripts.nix index 48ae9ed..1109f5d 100644 --- a/scripts/hakase-scripts.nix +++ b/scripts/hakase-scripts.nix @@ -53,105 +53,71 @@ ''; hakase-launch-popup = pkgs.writeShellScriptBin "hakase-launch-popup" '' - if (($# < 3)); then - echo "Usage: hakase-launch-popup [width] [height] [command...]" + if (($# == 0)); then + echo "Usage: hakase-launch-popup [command]" exit 1 fi - # --- ARGS & CONFIG --- - WIN_WIDTH="$1" - WIN_HEIGHT="$2" - shift 2 - - MARGIN=10 - BAR_HEIGHT=40 - # --------------------- - CMD_NAME=$(basename "$1") - TARGET_CLASS="org.hakase.popup.$CMD_NAME" + # Define a specific class for popups so Hyprland rules can catch them + CLASS_NAME="org.hakase.popup.$CMD_NAME" - # 1. SINGLETON: Close any existing hakase popups first - # This ensures only one popup is ever open at a time. - EXISTING_JSON=$(${pkgs.hyprland}/bin/hyprctl clients -j | ${pkgs.jq}/bin/jq -r '.[] | select(.class | startswith("org.hakase.popup."))') + # Check if already running; if so, toggle/close it + EXISTING_ADDR=$(${pkgs.hyprland}/bin/hyprctl clients -j | ${pkgs.jq}/bin/jq -r --arg c "$CLASS_NAME" '.[] | select(.class == $c) | .address') - if [[ -n "$EXISTING_JSON" ]]; then - OLD_ADDR=$(echo "$EXISTING_JSON" | ${pkgs.jq}/bin/jq -r '.address') - OLD_CLASS=$(echo "$EXISTING_JSON" | ${pkgs.jq}/bin/jq -r '.class') - - ${pkgs.hyprland}/bin/hyprctl dispatch closewindow "address:$OLD_ADDR" - - # Toggle behavior: If we clicked the same button again, just close and exit. - if [[ "$OLD_CLASS" == "$TARGET_CLASS" ]]; then - exit 0 - fi - sleep 0.15 + if [[ -n "$EXISTING_ADDR" ]]; then + ${pkgs.hyprland}/bin/hyprctl dispatch closewindow "address:$EXISTING_ADDR" + exit 0 fi - # 2. POSITIONING - MONITOR_INFO=$(${pkgs.hyprland}/bin/hyprctl monitors -j | ${pkgs.jq}/bin/jq '.[] | select(.focused == true)') - MON_X=$(echo "$MONITOR_INFO" | ${pkgs.jq}/bin/jq '.x') - MON_Y=$(echo "$MONITOR_INFO" | ${pkgs.jq}/bin/jq '.y') - MON_WIDTH=$(echo "$MONITOR_INFO" | ${pkgs.jq}/bin/jq '.width') + # Launch the application + # We use setsid to detach, but keep the PID to kill it later + xdg-terminal-exec --app-id="$CLASS_NAME" -e "$@" & + APP_PID=$! - # Defaults to 0 if jq fails - MON_X=''${MON_X:-0} - MON_Y=''${MON_Y:-0} - MON_WIDTH=''${MON_WIDTH:-1920} + # Wait for the window to appear and grab its address + TIMEOUT=0 + WINDOW_ADDR="" + while [[ -z "$WINDOW_ADDR" && $TIMEOUT -lt 20 ]]; do + sleep 0.1 + WINDOW_ADDR=$(${pkgs.hyprland}/bin/hyprctl clients -j | ${pkgs.jq}/bin/jq -r --arg c "$CLASS_NAME" '.[] | select(.class == $c) | .address') + ((TIMEOUT++)) + done - TARGET_X=$((MON_X + MON_WIDTH - WIN_WIDTH - MARGIN)) - TARGET_Y=$((MON_Y + BAR_HEIGHT + MARGIN)) + if [[ -z "$WINDOW_ADDR" ]]; then + echo "Failed to find window for $CLASS_NAME" + exit 1 + fi - # 3. LAUNCH - RULE="[float;pin;size $WIN_WIDTH $WIN_HEIGHT;move $TARGET_X $TARGET_Y]" - ${pkgs.hyprland}/bin/hyprctl dispatch exec "$RULE xdg-terminal-exec --app-id=$TARGET_CLASS -e $@" + # Monitor Hyprland socket for focus changes + # We use socat to stream events. If activewindow changes to something else, kill the app. + ${pkgs.socat}/bin/socat -U - UNIX-CONNECT:"$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" | while read -r line; do + if [[ "$line" == "activewindow>>"* ]]; then + # Extract the new focused address + NEW_FOCUS="0x$(echo "$line" | cut -d '>' -f3 | cut -d ',' -f1)" - # 4. BACKGROUND: Close on "Click Outside" (Blur) - ( - # Wait for the window to actually appear - TIMEOUT=0 - WINDOW_ADDR="" - while [[ -z "$WINDOW_ADDR" && $TIMEOUT -lt 20 ]]; do - sleep 0.1 - WINDOW_ADDR=$(${pkgs.hyprland}/bin/hyprctl clients -j | ${pkgs.jq}/bin/jq -r --arg c "$TARGET_CLASS" '.[] | select(.class == $c) | .address') - ((TIMEOUT++)) - done - - if [[ -n "$WINDOW_ADDR" ]]; then - # Listen to socket for focus changes - ${pkgs.socat}/bin/socat -U - UNIX-CONNECT:"$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" | while read -r line; do - if [[ "$line" == "activewindow>>"* ]]; then - # Extract address from event: activewindow>>1234abcd,title - NEW_FOCUS=$(echo "$line" | cut -d '>' -f3 | cut -d ',' -f1) - - # Normalize to 0x format to match hyprctl - if [[ "$NEW_FOCUS" != 0x* ]]; then - NEW_FOCUS="0x$NEW_FOCUS" - fi - - # If the focused window is NOT our popup, kill the popup - if [[ "$WINDOW_ADDR" != "$NEW_FOCUS" ]]; then - ${pkgs.hyprland}/bin/hyprctl dispatch closewindow "address:$WINDOW_ADDR" - break - fi - fi - done + # If the new focus is NOT our popup window, kill the popup + if [[ "$WINDOW_ADDR" != "$NEW_FOCUS" ]]; then + kill "$APP_PID" 2>/dev/null + # Also force close in Hyprland to be sure + ${pkgs.hyprland}/bin/hyprctl dispatch closewindow "address:$WINDOW_ADDR" + break + fi fi - ) & + done + ''; - exit 0 - ''; # 1. WiFi (Impala) - Requires a larger view + # 2. Specific Launchers using the Popup logic hakase-popup-wifi = pkgs.writeShellScriptBin "hakase-popup-wifi" '' - exec hakase-launch-popup 800 500 impala + exec hakase-launch-popup impala ''; - # 2. Bluetooth (Bluetui) - Fits your specific test size hakase-popup-bluetooth = pkgs.writeShellScriptBin "hakase-popup-bluetooth" '' - exec hakase-launch-popup 602 478 bluetui + exec hakase-launch-popup bluetui ''; - # 3. Volume (Wiremix) - Can be smaller hakase-popup-volume = pkgs.writeShellScriptBin "hakase-popup-volume" '' - exec hakase-launch-popup 800 300 wiremix + exec hakase-launch-popup wiremix ''; in { environment.systemPackages = [ @@ -162,7 +128,6 @@ in { pkgs.impala pkgs.wiremix pkgs.pamixer - pkgs.yad hakase-launch-popup hakase-popup-wifi