napcok
April 13, 2025, 12:36pm
1
Automatically exported from code.google.com/p/fittstool
This little tool has incredible potential… especially if wrapped in scripts in something more user-friendly. I have never heard of it before.
Name comes from Fitts Law:
Fitts's law (often cited as Fitts' law) is a predictive model of human movement primarily used in human–computer interaction and ergonomics. The law predicts that the time required to rapidly move to a target area is a function of the ratio between the distance to the target and the width of the target. Fitts's law is used to model the act of pointing, either by physically touching an object with a hand or finger, or virtually, by pointing to an object on a computer monitor using a pointing de Fi...
Available positions:
Left, TopLeft, etc, TopCenter, BottomCenter, Right, TopRight, BottomRight, etc…
Available events:
LeftButton, RightButton, MiddleButton, WheelUp, WheelDown, WheelUpOnce, WheelDownOnce, Enter, Leave
Available in AUR:
yay fittstool
I’d love to look closer into this once I find some time to experiment.
1 Like
muzqs
April 13, 2025, 7:10pm
2
16 years old tool… .
It works nice and simple config.
Quick test [TopCenter] volume level.
muzqs
April 13, 2025, 8:44pm
3
update test… when i turn off second display all corners and sides seems to work. But with second display one side not reacting.
edit :
i see now., when both display on.
The second display takes the corners and side.
muzqs
April 13, 2025, 9:40pm
4
Not fancy: Fittstool GUI for quick settings and testing if things are working.
Running fittstool for the first time will create a config file.
After that change config with this one.
~/.config/fittstool/fittstoolrc
#fittstoolrc template
#volume control in the top right corner:
[BottomLeft]
WheelUp=
WheelDown=
WheelUpOnce=
WheelDownOnce=
MiddleButton=
RightButton=
LeftButoon=
Enter=
Leave=
[Left]
WheelUp=amixer -D pulse set Master 5%+
WheelDown=amixer -D pulse set Master 5%-
WheelUpOnce=
WheelDownOnce=
MiddleButton=terminator
RightButton=
LeftButton=
Enter=
Leave=
[TopCenter]
WheelUp=amixer -D pulse set Master 5%+
WheelDown=amixer -D pulse set Master 5%-
WheelUpOnce=
WheelDownOnce=
MiddleButton=
RightButton=pactl set-sink-mute @DEFAULT_SINK@ toggle
LeftButton=
Enter=
Leave=
[BottomCenter]
WheelUp=
WheelDown=
WheelUpOnce=
WheelDownOnce=
MiddleButton=terminator
RightButton=
LeftButton=
Enter=
Leave=
[BottomRight]
WheelUp=
WheelDown=
WheelUpOnce=
WheelDownOnce=
MiddleButton=terminator
RightButton=
LeftButton=
Enter=
Leave=
[TopLeft]
WheelUp=
WheelDown=
WheelUpOnce=
WheelDownOnce=
MiddleButton=terminator
RightButton=
LeftButton=
Enter=
Leave=
[Right]
WheelUp=
WheelDown=
WheelUpOnce=terminator
WheelDownOnce=
MiddleButton=
RightButton=terminator
LeftButton=
Enter=
Leave=
[TopRight]
WheelUp=
WheelDown=
WheelUpOnce=terminator
WheelDownOnce=
MiddleButton=
RightButton=terminator
LeftButton=
Enter=
Leave=
./fittstool-settings.sh
#!/bin/bash
me="fittstool-settings.sh"
CONFIG_FILE="$HOME/.config/fittstool/fittstoolrc"
[ -d "$(dirname "$CONFIG_FILE")" ] || mkdir -p "$(dirname "$CONFIG_FILE")"
POSITIONS="Left|TopLeft|TopCenter|TopRight|Right|BottomRight|BottomCenter|BottomLeft"
EVENTS=("WheelUp" "WheelDown" "WheelUpOnce" "WheelDownOnce" "MiddleButton" "RightButton" "LeftButton" "Enter" "Leave")
# Step 1: Choose Position
POSITION=$(yad --title="Choose Position" --width=300 --height=400 --center \
--list --column="Position" --separator="" \
$(echo $POSITIONS | tr "|" " "))
[ -z "$POSITION" ] && exit 1
# Step 2: Get existing values if present
declare -A CURRENT_VALUES
if grep -q "^\[$POSITION\]" "$CONFIG_FILE"; then
in_section=0
while IFS= read -r line; do
[[ "$line" =~ ^\[$POSITION\] ]] && in_section=1 && continue
[[ "$line" =~ ^\[.*\] ]] && [[ $in_section -eq 1 ]] && break
[[ $in_section -eq 1 && "$line" =~ = ]] && {
key="${line%%=*}"
val="${line#*=}"
CURRENT_VALUES["$key"]="$val"
}
done < "$CONFIG_FILE"
fi
# Step 3: Show form with pre-filled fields
FIELDS=()
for EVENT in "${EVENTS[@]}"; do
FIELDS+=(--field="$EVENT":TXT "${CURRENT_VALUES[$EVENT]}")
done
VALUES=$(yad --title="Set Commands for $POSITION" --width=600 --form "${FIELDS[@]}" --center)
[ $? -ne 0 ] && exit 1
IFS="|" read -r "${EVENTS[@]}" <<< "$VALUES"
# Step 4: Update config file
# Remove existing section if present
sed -i "/^\[$POSITION\]/,/^\[/ {/^\[.*\]/!d}" "$CONFIG_FILE"
sed -i "/^\[$POSITION\]/d" "$CONFIG_FILE"
{
echo "[$POSITION]"
for EVENT in "${EVENTS[@]}"; do
eval val=\$$EVENT
echo "$EVENT=$val"
done
echo
} >> "$CONFIG_FILE"
# Step 5: Reload fittstool safely
# Get all fittstool PIDs except this script's parent
for pid in $(pgrep -f fittstool); do
if [ "$pid" != "$PPID" ] && [ "$pid" != "$$" ]; then
kill "$pid"
fi
done
fittstool &
# Step 6: Confirmation
yad --center --title="Done" --text="Configuration for [$POSITION] saved!\n\nfittstool reloaded." --button=OK
# restart menu
$me;
exit 0
1 Like
napcok
April 14, 2025, 12:01pm
5
I forked the repo to make some - mostly cosmetic changes.
(as my knowledge of C programming is close to absolute zero)
updated README
fix misplaced width and height (command output)
allow longer commands (200 chars instead 100)
Forked repo:
A tool for binding mouse events at the screen corners to commands
fittstool package is now available from Mabox repo.
yay
yay fittstool
Notes for future consideration
Things to think about…
If we decide to implement it in Mabox in a more user-friendly way.
Enter and Leave events seem perfect for showing hints to the user
Just a quick notify-send.sh
example:
Enter=notify-send.sh -u critical -R /tmp/rID "TopRight" "Hello from <b>fittstool</b>"
Leave=notify-send.sh -s $(cat /tmp/rID)
Something Yad based will be better here, as yad allows controlling window (hints) position.
Hint must off course show configured actions for entered corner(area).
User readeable command descriptions can be defined in config file after #.
Like:
LeftButton=mabox-terminal #Quick terminal (F12)
So…
mb-fittstool wrapper script
mb-fittstool start | stop | restart
Redirects fittstool command output to file, parse it and prepare hints (config file can also be parsed off course for that).
autostart
.desktop file for GUI autostart tool
If implemented, this will make other Mabox tools obsolete: mcorners
(hot-corners) and released few days ago areaclick
.
Also something similar must be implemented for W-A-KP_1..9 (currently areaclick actions are spawned).
1 Like
muzqs
April 14, 2025, 12:45pm
6
Hi @napcok ,
I have been looking at fittstool.c too.
Is this the same as …
What i wanted to do is looking if i could change the screen dimentions.
When there is connected more than one monitor, always use the default ‘primary’ monitor specs.
C is completly new to me too.
#include "monitor.h" /* if you have get_primary_monitor_geometry() */
#include "options.h" /* if init_options() is declared there */
int pw, ph, px, py;
if (get_primary_monitor_geometry(&px, &py, &pw, &ph)) {
init_options(pw, ph);
}
// function to get primary display width and height
int get_primary_monitor_geometry(int *x, int *y, int *w, int *h) {
FILE *fp = popen("xrandr --query | awk '/ primary / { print $3 }'", "r");
if (!fp) return 0;
char geom[32];
if (fgets(geom, sizeof(geom), fp)) {
sscanf(geom, "%dx%d+%d+%d", w, h, x, y);
pclose(fp);
return 1;
}
pclose(fp);
return 0;
}
napcok
April 14, 2025, 1:20pm
7
muzqs:
Is this the same as …
What i wanted to do is looking if i could change the screen dimentions.
When there is connected more than one monitor, always use the default ‘primary’ monitor specs.
No, I just fixed some bad reporting, a trivial bug. It has nothing to do with the geometry calculations in the program - which seem to be done by XCB library .
1 Like
muzqs
April 14, 2025, 2:35pm
8
Indeed that is the proper way to do it from what i read.
muzqs
April 18, 2025, 12:16pm
9
Testing Fork of FITTSTOOL
.
I am calling the project FITTSMON
.
Areaclick turned off. (using events with fittsmon)
New feature. (working)
always use primairy display dimensions when multiple display’s are connected.
Todo/want to add function.
option to add multiple display’s with $ fittsmon DP-0 DP-1 etc
.
for each display custom mouse events possible.
possible to set area click margins.
to be continued…
muzqs
April 18, 2025, 10:19pm
11
Created gitlab. Forked from @napcok .
Ready for some testing on other machines…
1 Like
muzqs
April 18, 2025, 11:17pm
12
Handy fittsmonrc
for testing…
Change DP-0 for your display.
# Default configuration for all enabled monitors
[TopCenter]
WheelUp=amixer -D pulse set Master 5%+
WheelDown=amixer -D pulse set Master 5%-
WheelUpOnce=notify-send "Default: Wheel Up Once"
WheelDownOnce=notify-send "Default: Wheel Down Once"
MiddleButton=notify-send "Default: Middle Button"
RightButton=pactl set-sink-mute @DEFAULT_SINK@ toggle
LeftButton=notify-send "Default: Left Button"
Enter=
Leave=
[BottomLeft]
WheelUp=notify-send "Default: BottomLeft Wheel Up"
WheelDown=notify-send "Default: BottomLeft Wheel Down"
WheelUpOnce=notify-send "Default: BottomLeft Wheel Up Once"
WheelDownOnce=notify-send "Default: BottomLeft Wheel Down Once"
MiddleButton=notify-send "Default: BottomLeft Middle Button"
RightButton=notify-send "Default: BottomLeft Right Button"
LeftButton=notify-send "Default: BottomLeft Left Button"
Enter=
Leave=
[Left ]
WheelUp=notify-send "Default: Left Wheel Up"
WheelDown=notify-send "Default: Left Wheel Down"
WheelUpOnce=notify-send "Default: Left Wheel Up Once"
WheelDownOnce=notify-send "Default: Left Wheel Down Once"
MiddleButton=notify-send "Default: Left Middle Button"
RightButton=notify-send "Default: Left Right Button"
LeftButton=notify-send "Default: Left Left Button"
Enter=
Leave=
[BottomCenter]
WheelUp=notify-send "Default: BottomCenter Wheel Up"
WheelDown=notify-send "Default: BottomCenter Wheel Down"
WheelUpOnce=notify-send "Default: BottomCenter Wheel Up Once"
WheelDownOnce=notify-send "Default: BottomCenter Wheel Down Once"
MiddleButton=notify-send "Default: BottomCenter Middle Button"
RightButton=notify-send "Default: BottomCenter Right Button"
LeftButton=notify-send "Default: BottomCenter Left Button"
Enter=
Leave=
[TopLeft]
WheelUp=notify-send "Default: TopLeft Wheel Up"
WheelDown=notify-send "Default: TopLeft Wheel Down"
WheelUpOnce=notify-send "Default: TopLeft Wheel Up Once"
WheelDownOnce=notify-send "Default: TopLeft Wheel Down Once"
MiddleButton=notify-send "Default: TopLeft Middle Button"
RightButton=notify-send "Default: TopLeft Right Button"
LeftButton=notify-send "Default: TopLeft Left Button"
Enter=
Leave=
[BottomRight]
WheelUp=notify-send "Default: BottomRight Wheel Up"
WheelDown=notify-send "Default: BottomRight Wheel Down"
WheelUpOnce=notify-send "Default: BottomRight Wheel Up Once"
WheelDownOnce=notify-send "Default: BottomRight Wheel Down Once"
MiddleButton=notify-send "Default: BottomRight Middle Button"
RightButton=notify-send "Default: BottomRight Right Button"
LeftButton=notify-send "Default: BottomRight Left Button"
Enter=
Leave=
[Right]
WheelUp=notify-send "Default: Right Wheel Up"
WheelDown=notify-send "Default: Right Wheel Down"
WheelUpOnce=notify-send "Default: Right Wheel Up Once"
WheelDownOnce=notify-send "Default: Right Wheel Down Once"
MiddleButton=terminator
RightButton=notify-send "Default: Right Right Button"
LeftButton=notify-send "Default: Right Left Button"
Enter=
Leave=
[TopRight]
WheelUp=notify-send "Default: TopRight Wheel Up"
WheelDown=notify-send "Default: TopRight Wheel Down"
WheelUpOnce=notify-send "Default: TopRight Wheel Up Once"
WheelDownOnce=notify-send "Default: TopRight Wheel Down Once"
MiddleButton=terminator
RightButton=notify-send "Default: TopRight Right Button"
LeftButton=notify-send "Default: TopRight Left Button"
Enter=
Leave=
[Left]
WheelUp=amixer -D pulse set Master 5%+
WheelDown=amixer -D pulse set Master 5%-
WheelUpOnce=notify-send "Default: Left Wheel Up Once"
WheelDownOnce=notify-send "Default: Left Wheel Down Once"
MiddleButton=notify-send "Default: Left Middle Button"
RightButton=notify-send "Default: Left Right Button"
LeftButton=notify-send "Default: Left Left Button"
Enter=
Leave=
## Monitor-specific configuration for DP-0
[DP-0-TopCenter]
WheelUp=amixer -D pulse set Master 5%+
WheelDown=amixer -D pulse set Master 5%-
WheelUpOnce=notify-send "DP-0: TopCenter Wheel Up Once"
WheelDownOnce=notify-send "DP-0: TopCenter Wheel Down Once"
MiddleButton=notify-send "DP-0: TopCenter Middle Button"
RightButton=pactl set-sink-mute @DEFAULT_SINK@ toggle
LeftButton=notify-send "DP-0: TopCenter Left Button"
Enter=
Leave=
[DP-0-BottomLeft]
WheelUp=notify-send "DP-0: BottomLeft Wheel Up"
WheelDown=notify-send "DP-0: BottomLeft Wheel Down"
WheelUpOnce=notify-send "DP-0: BottomLeft Wheel Up Once"
WheelDownOnce=notify-send "DP-0: BottomLeft Wheel Down Once"
MiddleButton=notify-send "DP-0: BottomLeft Middle Button"
RightButton=notify-send "DP-0: BottomLeft Right Button"
LeftButton=notify-send "DP-0: BottomLeft Left Button"
Enter=
Leave=
[DP-0-Left ]
WheelUp=notify-send "DP-0: Left Wheel Up"
WheelDown=notify-send "DP-0: Left Wheel Down"
WheelUpOnce=notify-send "DP-0: Left Wheel Up Once"
WheelDownOnce=notify-send "DP-0: Left Wheel Down Once"
MiddleButton=notify-send "DP-0: Left Middle Button"
RightButton=notify-send "DP-0: Left Right Button"
LeftButton=notify-send "DP-0: Left Left Button"
Enter=
Leave=
[DP-0-BottomCenter]
WheelUp=notify-send "DP-0: BottomCenter Wheel Up"
WheelDown=notify-send "DP-0: BottomCenter Wheel Down"
WheelUpOnce=skippy-xd --paging
WheelDownOnce=skippy-xd --expose
MiddleButton=skippy-xd --expose
RightButton=notify-send "DP-0: BottomCenter Right Button"
LeftButton=notify-send "DP-0: BottomCenter Left Button"
Enter=
Leave=
[DP-0-TopLeft]
WheelUp=notify-send "DP-0: TopLeft Wheel Up"
WheelDown=notify-send "DP-0: TopLeft Wheel Down"
WheelUpOnce=notify-send "DP-0: TopLeft Wheel Up Once"
WheelDownOnce=notify-send "DP-0: TopLeft Wheel Down Once"
MiddleButton=notify-send "DP-0: TopLeft Middle Button"
RightButton=notify-send "DP-0: TopLeft Right Button"
LeftButton=notify-send "DP-0: TopLeft Left Button"
Enter=
Leave=
[DP-0-BottomRight]
WheelUp=notify-send "DP-0: BottomRight Wheel Up"
WheelDown=notify-send "DP-0: BottomRight Wheel Down"
WheelUpOnce=notify-send "DP-0: BottomRight Wheel Up Once"
WheelDownOnce=notify-send "DP-0: BottomRight Wheel Down Once"
MiddleButton=notify-send "DP-0: BottomRight Middle Button"
RightButton=notify-send "DP-0: BottomRight Right Button"
LeftButton=notify-send "DP-0: BottomRight Left Button"
Enter=
Leave=
[DP-0-Right]
WheelUp=notify-send "DP-0: Right Wheel Up"
WheelDown=notify-send "DP-0: Right Wheel Down"
WheelUpOnce=notify-send "DP-0: Right Wheel Up Once"
WheelDownOnce=notify-send "DP-0: Right Wheel Down Once"
MiddleButton=terminator
RightButton=notify-send "DP-0: Right Right Button"
LeftButton=notify-send "DP-0: Right Left Button"
Enter=
Leave=
[DP-0-TopRight]
WheelUp=notify-send "DP-0: TopRight Wheel Up"
WheelDown=notify-send "DP-0: TopRight Wheel Down"
WheelUpOnce=notify-send "DP-0: TopRight Wheel Up Once"
WheelDownOnce=notify-send "DP-0: TopRight Wheel Down Once"
MiddleButton=terminator
RightButton=notify-send "DP-0: TopRight Right Button"
LeftButton=notify-send "DP-0: TopRight Left Button"
Enter=
Leave=
[DP-0-Left]
WheelUp=amixer -D pulse set Master 5%+
WheelDown=amixer -D pulse set Master 5%-
WheelUpOnce=notify-send "DP-0: Left Wheel Up Once"
WheelDownOnce=notify-send "DP-0: Left Wheel Down Once"
MiddleButton=notify-send "DP-0: Left Middle Button"
RightButton=notify-send "DP-0: Left Right Button"
LeftButton=notify-send "DP-0: Left Left Button"
Enter=
Leave=
## Monitor-specific configuration for DP-X or HDMI-X
1 Like