Reputation: 2566
I am trying to create a script in KDE (Plasma) that allows me to resize a window by holding down the Shift key and left-clicking, and dragging with the mouse. The resizing should be centered around the initial mouse position (the position of the mouse when the Shift key and left mouse button are first pressed). The goal is to have a smooth, damped resizing effect that works regardless of where I click within the window, not just on the edges. The default KDE window resizing behavior doesn't allow for this level of control.
Current Approach:
I am using a bash
script to achieve this, using xdotool
for window management and xinput
for keyboard monitoring. The script is designed to:
xdotool
to resize and move the window.Result at the moment:
sudo ~/scripts/dynamic-resize.sh
Setting up watches.
Watches established.
Code:
#!/bin/bash
# xinput must be installed:
# Debian: sudo apt-get install xinput
# Fedora: sudo dnf install xorg-x11-utils oder sudo yum install xorg-x11-utils
# Arch: sudo pacman -S inotify-tools
# Configuration
modifier_key="Shift" # or "Alt", "Control", etc.
mouse_button_code="1" #Code for the leftmouse click.
resize_button="3" # 1=links, 2=mitte, 3=rechts #We aren't using this anymore.
damping_factor="0.2" # Damping factor
threshold="400" # Threshold for dynamic damping
sleep_time="0.02" # Sleep time after each movement (in seconds)
event_mouse="3"
event_keyboard="2"
# Function: Dynamically resize window
resize_window() {
# 1. Get active window ID
active_window_id=$(xdotool getactivewindow)
# 2. Get initial window geometry
initial_x=$(xdotool getwindowgeometry $active_window_id | awk '{print $4}' | cut -d, -f1)
initial_y=$(xdotool getwindowgeometry $active_window_id | awk '{print $4}' | cut -d, -f2)
initial_width=$(xdotool getwindowgeometry $active_window_id | awk '{print $5}' | cut -d, -f1)
initial_height=$(xdotool getwindowgeometry $active_window_id | awk '{print $5}' | cut -d, -f2)
# 3. Get initial mouse position
initial_mouse_x=$(xdotool getmouselocation | awk -F ":" '{print $2}' | awk '{print $1}')
initial_mouse_y=$(xdotool getmouselocation | awk -F ":" '{print $4}' | awk '{print $1}')
# 4. Loop: As long as the mouse button is pressed
while is_mouse_button_pressed; do
# 5. Get current mouse position
current_mouse_x=$(xdotool getmouselocation | awk -F ":" '{print $2}' | awk '{print $1}')
current_mouse_y=$(xdotool getmouselocation | awk -F ":" '{print $4}' | awk '{print $1}')
# 6. Calculate difference
diff_x=$((current_mouse_x - initial_mouse_x))
diff_y=$((current_mouse_y - initial_mouse_y))
# 7. Calculate dynamic damping factor
if [ $(abs $diff_x) -lt $threshold ]; then
damping_factor_x=$((damping_factor * (abs $diff_x) / $threshold + 0.1))
else
damping_factor_x=$damping_factor
fi
if [ $(abs $diff_y) -lt $threshold ]; then
damping_factor_y=$((damping_factor * (abs $diff_y) / $threshold + 0.1))
else
damping_factor_y=$damping_factor
fi
# 8. Calculate new size and position
new_width=$((initial_width + diff_x * damping_factor_x))
new_height=$((initial_height + diff_y * damping_factor_y))
new_x=$((initial_x - diff_x * damping_factor_x / 2))
new_y=$((initial_y - diff_y * damping_factor_y / 2))
# 9. Size restrictions (minimum, maximum, etc.)
new_width=$((new_width < 100 ? 100 : new_width))
new_height=$((new_height < 100 ? 100 : new_height))
# 10. Change window size and position
xdotool windowsize $active_window_id $new_width $new_height
xdotool windowmove $active_window_id $new_x $new_y
# 11. Short pause to reduce CPU load
sleep $sleep_time
done
}
# Returns 0 if mouse is not being left-clicked, and 1 if it is.
is_mouse_button_pressed() {
#Returns 0 if shift is not pressed
if ! is_shift_pressed; then
#echo "shift is not pressed"
return 1;
fi
#echo "shift is pressed, now checking mouse"
xinput test $event_mouse | grep -q "button\[$mouse_button_code\]=down"
mouse_result=$?
#echo "mouse_result=$mouse_result"
return $mouse_result
}
# Return 0 if shift is not pressed.
is_shift_pressed() {
xinput query-state "HID 045e:000b" | grep -q "key\[62\]=down"
}
# Hauptteil des Skripts
while true; do
# Überprüfen, ob die Super-Taste gedrückt ist
if is_shift_pressed; then
# Funktion aufrufen
resize_window
fi
done
What I've Tried:
xinput
and xev
: I've used xinput list
and xev
to identify the correct device names and keycodes for my keyboard and mouse.xinput query-state
: This works great except that it cannot work in the background. It cannot monitor when there has been changes.input
group.inotifywait
to monitor changes on /dev/input/event*
, but this did not trigger the script.Specific Questions:
xinput test
and xinput query-state
is not working.Upvotes: 0
Views: 27