I was running into the same issue and as others have pointed out Ubuntu sees your monitors looking something like this (maybe order is the other way around):
+----------++----------------+
| || |
| || |
+----------+| |
| |
+----------------+
In this example when your mouse is in the right monitor on the bottom and the mouse is moved straight left you hit a dead zone where you can't cross screens. I modified the bash file that cassm posted to have the mouse height be proportional when crossing so if you cross your mouse 3/4 the way up from the left monitor, the mouse appears 3/4 the way up on the right monitor.
To run the script I ran follow the instructions below:
1) Make sure to setup your monitors right with the picture in the script (ONE ABOVE IS DIFFERENT) in Ubuntu's Displays settings
2) Make a text file called "mousejumper.sh" or anything ending in .sh
3) Right click on file and change Properties to make it executable
4) Copy and paste the script into file
#! /bin/bash
# Cursor relocation script by Cass May <[email protected]>
# LEFTX and RIGHTX are the screen boundaries, which triggers cursor relocation
# LEFTMONHEIGHT and LEFTMONHEIGHT are the heights in pixels of the left and right monitor
# minus 1, because computers start counting at 0... so 1920 pixels heigh becomes 1919
LEFTX="1919"
LEFTMONHEIGHT="1080"
RIGHTX="1920"
RIGHTMONHEIGHT="2159"
# Size in pixels to jump over the screens with when you hit the boundary (ex: if 5, jumps from x = 1919 to x=1924)
BUFFER="5"
# In Ubuntu Displays settings window the two monitors must be setup to look like this:
# +----------------+
# | |
# +----------+| |
# | || |
# | || |
# +----------++----------------+
#
# If the monitor setup is in a different order (ex: larger screen on left side)
# or there are more than two monitors, then the script will need to be modified
# Tip: Set "Sticky Edges" to On in the Displays settings window because
# the script checks coordinates every 0.### seconds, and sticky edges
# keeps your mouse there longer
while true; do # keep loop going to run all the time, do a slight pause for performance
# grab cursor position, and extract x and y position
CURSORPOSITION="$(xdotool getmouselocation)"
XPOS="$(grep -o '[0-9]\+' <<< "$CURSORPOSITION" | awk 'NR==1{print $1}')"
YPOS="$(grep -o '[0-9]\+' <<< "$CURSORPOSITION" | awk 'NR==2{print $1}')"
#echo "Mouse position is: ($XPOS, $YPOS)"
# if XPOS is 1920 then on right 4k monitor
if [ $XPOS = $RIGHTX ]
then
#echo "Starting jump function"
# find % height then convert
# Input is 0-2159, Output is 1080-2159
NEWYPOS=$(echo "(($LEFTMONHEIGHT+$YPOS/$RIGHTMONHEIGHT*$LEFTMONHEIGHT))" | bc -l)
#echo "YPOS with floats is: $NEWYPOS"
NEWYPOS=$(echo "$NEWYPOS" | bc -l | xargs printf "%1.0f")
NEWXPOS=$(($RIGHTX-$BUFFER))
# Move Mouse to other screen with a few pixel buffer on the screen edge
#echo "Mouse jumped from right to left from: ($XPOS, $YPOS) to ($NEWXPOS, $NEWYPOS)"
xdotool mousemove "$NEWXPOS" "$NEWYPOS"
# if XPOS is 1919 then on left 1080 monitor
elif [ $XPOS = $LEFTX ]
then
#echo "Starting jump function"
# find % height then convert
# Input is 0-2159, Output is 1080-2159
NEWYPOS=$(echo "((($YPOS-$LEFTMONHEIGHT)/$LEFTMONHEIGHT*$RIGHTMONHEIGHT))" | bc -l)
#echo "YPOS with floats is: $NEWYPOS"
NEWYPOS=$(echo "$NEWYPOS" | bc -l | xargs printf "%1.0f")
NEWXPOS=$(($LEFTX+$BUFFER))
# Move Mouse to other screen with a few pixel buffer on the screen edge
#echo "Mouse jumped from left to right from: ($XPOS, $YPOS) to ($NEWXPOS, $NEWYPOS)"
xdotool mousemove "$NEWXPOS" "$NEWYPOS"
fi
sleep 0.05
done
5) Change these values in the script to match your monitor specs
LEFTX="1919"
LEFTMONHEIGHT="1080"
RIGHTX="1920"
RIGHTMONHEIGHT="2159"
My monitors were 1920x1080 on the left and 3840x2160 on the right.
If you need help finding your monitors values use this little bash script and move your mouse around:
#! /bin/bash
while true; do # keep loop going to run all the time, do a slight pause for performance
# grab cursor position, and extract x and y position
CURSORPOSITION="$(xdotool getmouselocation)"
XPOS="$(grep -o '[0-9]\+' <<< "$CURSORPOSITION" | awk 'NR==1{print $1}')"
YPOS="$(grep -o '[0-9]\+' <<< "$CURSORPOSITION" | awk 'NR==2{print $1}')"
echo "Mouse position is: ($XPOS, $YPOS)"
sleep 0.1
done
6) Run it in terminal with ./mousejumper.sh
I don't want to have this running all the time so I'm not going to have the system launch it on startup. I have a little utility I wrote to toggle scripts like this on and off manually.