diff --git a/dotfiles/.config/ml4w/scripts/sidepad.sh b/dotfiles/.config/ml4w/scripts/sidepad.sh index 41618f136..6a48b84a2 100755 --- a/dotfiles/.config/ml4w/scripts/sidepad.sh +++ b/dotfiles/.config/ml4w/scripts/sidepad.sh @@ -14,17 +14,23 @@ launcher=$(cat $HOME/.config/ml4w/settings/launcher) # Configuration SIDEPAD_PATH="$HOME/.config/sidepad/sidepad" SIDEPAD_DATA="$HOME/.config/ml4w/settings/sidepad-active" +SIDEPAD_POS_FILE="$HOME/.config/ml4w/settings/sidepad-position" SIDEPAD_PADS_FOLDER="$HOME/.config/sidepad/pads" SIDEPAD_SELECT="$HOME/.config/sidepad/scripts/select.sh" # Load active sidepad SIDEPAD_OPTIONS="" SIDEPAD_ACTIVE=$(cat "$SIDEPAD_DATA") -source $SIDEPAD_PADS_FOLDER/$(cat "$SIDEPAD_DATA") +if [ -f "$SIDEPAD_POS_FILE" ]; then + SIDEPAD_POS=$(cat "$SIDEPAD_POS_FILE") +else + SIDEPAD_POS="left" +fi source $SIDEPAD_PADS_FOLDER/$SIDEPAD_ACTIVE echo ":: Current sidepad: $SIDEPAD_ACTIVE" echo ":: Current sidepad app: $SIDEPAD_APP" echo ":: Current sidepad class: $SIDEPAD_CLASS" +echo ":: Current sidepad position: $SIDEPAD_POS" # Select new sidepad with rofi select_sidepad() { @@ -40,7 +46,7 @@ select_sidepad() { echo ":: New sidepad: $pad" # Kill existing sidepad - eval "$SIDEPAD_PATH --class '$SIDEPAD_CLASS' --kill" + eval "$SIDEPAD_PATH --position '$SIDEPAD_POS' --class '$SIDEPAD_CLASS' --kill" # Write pad into active data file echo "$pad" > "$SIDEPAD_DATA" @@ -48,22 +54,32 @@ select_sidepad() { # Init sidepad source $SIDEPAD_PADS_FOLDER/$pad - eval "$SIDEPAD_PATH --class '$SIDEPAD_CLASS' --init '$SIDEPAD_APP'" + eval "$SIDEPAD_PATH --position '$SIDEPAD_POS' --class '$SIDEPAD_CLASS' --init '$SIDEPAD_APP'" echo ":: Sidepad switched" fi } # Dispatch parameters if [[ "$1" == "--init" ]]; then - eval "$SIDEPAD_PATH --class '$SIDEPAD_CLASS' --init '$SIDEPAD_APP'" + eval "$SIDEPAD_PATH --position '$SIDEPAD_POS' --class '$SIDEPAD_CLASS' --init '$SIDEPAD_APP'" elif [[ "$1" == "--hide" ]]; then - eval "$SIDEPAD_PATH --class '$SIDEPAD_CLASS' --hide" + if [[ "$SIDEPAD_POS" == "left" ]]; then + # Hide left sidepad + eval "$SIDEPAD_PATH --position '$SIDEPAD_POS' --class '$SIDEPAD_CLASS' --hide" + else + # Show right sidepad + eval "$SIDEPAD_PATH --position '$SIDEPAD_POS' --class '$SIDEPAD_CLASS' $SIDEPAD_OPTIONS" + fi elif [[ "$1" == "--test" ]]; then - eval "$SIDEPAD_PATH --class '$SIDEPAD_CLASS' --test" + eval "$SIDEPAD_PATH --position '$SIDEPAD_POS' --class '$SIDEPAD_CLASS' --test" elif [[ "$1" == "--kill" ]]; then - eval "$SIDEPAD_PATH --class '$SIDEPAD_CLASS' --kill" + eval "$SIDEPAD_PATH --position '$SIDEPAD_POS' --class '$SIDEPAD_CLASS' --kill" elif [[ "$1" == "--select" ]]; then select_sidepad else - eval "$SIDEPAD_PATH --class '$SIDEPAD_CLASS' $SIDEPAD_OPTIONS" + if [[ "$SIDEPAD_POS" == "left" ]]; then + eval "$SIDEPAD_PATH --position '$SIDEPAD_POS' --class '$SIDEPAD_CLASS' $SIDEPAD_OPTIONS" + else + eval "$SIDEPAD_PATH --position '$SIDEPAD_POS' --class '$SIDEPAD_CLASS' --hide" + fi fi diff --git a/dotfiles/.config/ml4w/settings/sidepad-position b/dotfiles/.config/ml4w/settings/sidepad-position new file mode 100644 index 000000000..d75e9e52b --- /dev/null +++ b/dotfiles/.config/ml4w/settings/sidepad-position @@ -0,0 +1 @@ +left \ No newline at end of file diff --git a/dotfiles/.config/sidepad/sidepad b/dotfiles/.config/sidepad/sidepad index c9deeefb6..861829fd3 100755 --- a/dotfiles/.config/sidepad/sidepad +++ b/dotfiles/.config/sidepad/sidepad @@ -8,12 +8,14 @@ # --- Configuration --- WINDOW_CLASS="dotfiles-sidepad" -HIDDEN_LEFT_GAP=10 -VISIBLE_LEFT_GAP=10 +POSITION="left" +HIDDEN_GAP=10 +VISIBLE_GAP=10 TARGET_WIDTH=700 TARGET_WIDTH_MAX=1000 TOP_GAP=100 BOTTOM_GAP=100 +PREV_FOCUS_FILE="/tmp/sidepad-prev-focus" # --- Script Variables --- HIDE_REQUESTED=0 @@ -26,8 +28,9 @@ show_help() { echo "" echo "Options:" echo " --class Override the window class (Default: $WINDOW_CLASS)" - echo " --hidden-gap Override the hidden left gap (Default: $HIDDEN_LEFT_GAP)" - echo " --visible-gap Override the visible left gap (Default: $VISIBLE_LEFT_GAP)" + echo " --position Override the position 'left' or 'right' (Default: $POSITION)" + echo " --hidden-gap Override the hidden gap (Default: $HIDDEN_GAP)" + echo " --visible-gap Override the visible gap (Default: $VISIBLE_GAP)" echo " --width Override the target width (Default: $TARGET_WIDTH)" echo " --width-max Override the maximum target width (Default: $TARGET_WIDTH_MAX)" echo " --top-gap Override the top gap (Default: $TOP_GAP)" @@ -88,13 +91,22 @@ while [[ $# -gt 0 ]]; do shift; shift ;; + --position) + if [[ "$2" != "left" && "$2" != "right" ]]; then + echo "Error: --position must be either 'left' or 'right' (got '$2')." >&2 + exit 1 + fi + POSITION="$2" + shift; shift + ;; + --hidden-gap) - HIDDEN_LEFT_GAP="$2" + HIDDEN_GAP="$2" shift; shift ;; --visible-gap) - VISIBLE_LEFT_GAP="$2" + VISIBLE_GAP="$2" shift; shift ;; @@ -152,33 +164,66 @@ done # --- Get Window and Monitor Info --- WINDOW_INFO=$(hyprctl clients -j | jq --arg class "$WINDOW_CLASS" '.[] | select(.class == $class)') -MONITOR_INFO=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true)') if [ -z "$WINDOW_INFO" ]; then echo "Error: Window with class '$WINDOW_CLASS' not found. Is the window open?" exit 1 fi +MONITOR_INFO=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true)') + WINDOW_ADDRESS=$(echo "$WINDOW_INFO" | jq -r '.address') WINDOW_WIDTH=$(echo "$WINDOW_INFO" | jq -r '.size[0]') WINDOW_HEIGHT=$(echo "$WINDOW_INFO" | jq -r '.size[1]') WINDOW_X=$(echo "$WINDOW_INFO" | jq -r '.at[0]') WINDOW_Y=$(echo "$WINDOW_INFO" | jq -r '.at[1]') MONITOR_HEIGHT=$(echo "$MONITOR_INFO" | jq -r '.height') +MONITOR_WIDTH=$(echo "$MONITOR_INFO" | jq -r '.width') +MONITOR_X=$(echo "$MONITOR_INFO" | jq -r '.x') +MONITOR_Y=$(echo "$MONITOR_INFO" | jq -r '.y') # --- Main Logic --- +# Determine if window is hidden +IS_HIDDEN=0 +if [[ "$POSITION" == "right" ]]; then + if (( WINDOW_X > MONITOR_X + MONITOR_WIDTH - TARGET_WIDTH || WINDOW_X < MONITOR_X )); then + IS_HIDDEN=1 + fi +else + if (( WINDOW_X < MONITOR_X || WINDOW_X > MONITOR_X + MONITOR_WIDTH )); then + IS_HIDDEN=1 + fi +fi + # Case 1: --hide flag is used, unconditionally hide the window. if [[ "$HIDE_REQUESTED" -eq 1 ]]; then - if (( WINDOW_X >= 0 )); then # Only act if it is not already hidden + if [[ "$IS_HIDDEN" -eq 0 ]]; then # Only act if it is not already hidden echo "--- Hiding window (--hide) ---" - PIXELS_TO_MOVE_X=$(( (WINDOW_X * -1) - TARGET_WIDTH + HIDDEN_LEFT_GAP )) + if [[ "$POSITION" == "right" ]]; then + TARGET_X=$(( MONITOR_X + MONITOR_WIDTH - HIDDEN_GAP )) + else + TARGET_X=$(( MONITOR_X - TARGET_WIDTH + HIDDEN_GAP )) + fi + PIXELS_TO_MOVE_X=$(( TARGET_X - WINDOW_X )) + WIDTH_CHANGE=$(( TARGET_WIDTH - WINDOW_WIDTH )) - PIXELS_TO_MOVE_Y=$(( TOP_GAP - WINDOW_Y )) + PIXELS_TO_MOVE_Y=$(( MONITOR_Y + TOP_GAP - WINDOW_Y )) TARGET_HEIGHT=$(( MONITOR_HEIGHT - TOP_GAP - BOTTOM_GAP )) HEIGHT_CHANGE=$(( TARGET_HEIGHT - WINDOW_HEIGHT )) hyprctl --batch "dispatch resizewindowpixel $WIDTH_CHANGE $HEIGHT_CHANGE,address:$WINDOW_ADDRESS; dispatch movewindowpixel $PIXELS_TO_MOVE_X $PIXELS_TO_MOVE_Y,address:$WINDOW_ADDRESS" + + # Restore focus + if [ -f "$PREV_FOCUS_FILE" ]; then + PREV_FOCUS=$(cat "$PREV_FOCUS_FILE") + if [[ -n "$PREV_FOCUS" ]]; then + # Suppress errors in case the previous window no longer exists or the address is invalid + hyprctl dispatch focuswindow address:"$PREV_FOCUS" 2>/dev/null || true + fi + rm "$PREV_FOCUS_FILE" + fi + echo "Operation completed." else echo "Window is already hidden." @@ -187,36 +232,59 @@ if [[ "$HIDE_REQUESTED" -eq 1 ]]; then fi # Case 2: Window is hidden, so show it. -if (( WINDOW_X < 0 )); then +if [[ "$IS_HIDDEN" -eq 1 ]]; then echo "--- Showing window ---" - PIXELS_TO_MOVE_X=$(( VISIBLE_LEFT_GAP - WINDOW_X )) + + # Save current focus + CURRENT_FOCUS=$(hyprctl activewindow -j | jq -r '.address') + if [[ "$CURRENT_FOCUS" != "$WINDOW_ADDRESS" ]]; then + echo "$CURRENT_FOCUS" > "$PREV_FOCUS_FILE" + fi + + if [[ "$POSITION" == "right" ]]; then + TARGET_X=$(( MONITOR_X + MONITOR_WIDTH - TARGET_WIDTH - VISIBLE_GAP )) + else + TARGET_X=$(( MONITOR_X + VISIBLE_GAP )) + fi + PIXELS_TO_MOVE_X=$(( TARGET_X - WINDOW_X )) + WIDTH_CHANGE=$(( TARGET_WIDTH - WINDOW_WIDTH )) - PIXELS_TO_MOVE_Y=$(( TOP_GAP - WINDOW_Y )) + PIXELS_TO_MOVE_Y=$(( MONITOR_Y + TOP_GAP - WINDOW_Y )) TARGET_HEIGHT=$(( MONITOR_HEIGHT - TOP_GAP - BOTTOM_GAP )) HEIGHT_CHANGE=$(( TARGET_HEIGHT - WINDOW_HEIGHT )) - hyprctl --batch "dispatch resizewindowpixel $WIDTH_CHANGE $HEIGHT_CHANGE,address:$WINDOW_ADDRESS; dispatch movewindowpixel $PIXELS_TO_MOVE_X $PIXELS_TO_MOVE_Y,address:$WINDOW_ADDRESS" + hyprctl --batch "dispatch resizewindowpixel $WIDTH_CHANGE $HEIGHT_CHANGE,address:$WINDOW_ADDRESS; dispatch movewindowpixel $PIXELS_TO_MOVE_X $PIXELS_TO_MOVE_Y,address:$WINDOW_ADDRESS; dispatch focuswindow address:$WINDOW_ADDRESS" echo "Operation completed." # Case 3: Window is visible, so toggle its width and correct its position. else # Ensure vertical position and height are correct - PIXELS_TO_MOVE_Y=$(( TOP_GAP - WINDOW_Y )) + PIXELS_TO_MOVE_Y=$(( MONITOR_Y + TOP_GAP - WINDOW_Y )) TARGET_HEIGHT=$(( MONITOR_HEIGHT - TOP_GAP - BOTTOM_GAP )) HEIGHT_CHANGE=$(( TARGET_HEIGHT - WINDOW_HEIGHT )) - # Don't move horizontally - PIXELS_TO_MOVE_X=0 - # Calculate width change if (( WINDOW_WIDTH == TARGET_WIDTH )); then echo "--- Expanding width to max ---" WIDTH_CHANGE=$(( TARGET_WIDTH_MAX - WINDOW_WIDTH )) + NEW_WIDTH=$TARGET_WIDTH_MAX else echo "--- Shrinking width to default ---" WIDTH_CHANGE=$(( TARGET_WIDTH - WINDOW_WIDTH )) + NEW_WIDTH=$TARGET_WIDTH + fi + + # Calculate horizontal move + if [[ "$POSITION" == "right" ]]; then + # If right aligned, we need to move X to keep right edge constant + TARGET_X=$(( MONITOR_X + MONITOR_WIDTH - NEW_WIDTH - VISIBLE_GAP )) + PIXELS_TO_MOVE_X=$(( TARGET_X - WINDOW_X )) + else + # If left aligned, X stays same (or we enforce VISIBLE_GAP) + TARGET_X=$(( MONITOR_X + VISIBLE_GAP )) + PIXELS_TO_MOVE_X=$(( TARGET_X - WINDOW_X )) fi - hyprctl --batch "dispatch resizewindowpixel $WIDTH_CHANGE $HEIGHT_CHANGE,address:$WINDOW_ADDRESS; dispatch movewindowpixel $PIXELS_TO_MOVE_X $PIXELS_TO_MOVE_Y,address:$WINDOW_ADDRESS" + hyprctl --batch "dispatch resizewindowpixel $WIDTH_CHANGE $HEIGHT_CHANGE,address:$WINDOW_ADDRESS; dispatch movewindowpixel $PIXELS_TO_MOVE_X $PIXELS_TO_MOVE_Y,address:$WINDOW_ADDRESS; dispatch focuswindow address:$WINDOW_ADDRESS" echo "Operation completed." fi \ No newline at end of file