You are not logged in.
Pages: 1
I began using dual monitors and this quickly became a problem with Xfce because the shared workspaces Xfce uses is the worst possible setup for multiple monitors. If each monitor had their own workspaces or the second monitor had a single workspace it would be fine, but shared workspaces is not usable. Is there a way to make windows in the second monitor automatically become visible in all workspaces and stop this if they are moved to the primary monitor? Idk if there is already a script for this out there.
My second problem is not unique to Xfce because I think other DEs also have this problem. Some applications do not open in the right display. Most Xfce apps do, but some apps like MPV or qimgv don't. Is there a way to fix this and make all apps open where they were launched?
Last edited by espas (2022-01-08 15:51:06)
Offline
Is there a way to make windows in the second monitor automatically become visible in all workspaces and stop this if they are moved to the primary monitor? Idk if there is already a script for this out there.
Challenge accepted!
Here is a script I've quickly thrown together. Give it a go and see if it works. You need to change the first 4 variables (EXTx, EXTy, EXTw, EXTh) to suit your system. This will be the xrandr dimensions of what you consider an external monitor. So for example, if your primary monitor dimensions are 0,0,1366,768 and the external monitor is to the right and also sized 1366x768, then as per xrandr the dimensions would be 1367,0,2732,768. It is currently coded only to deal with side by side monitors.
#!/bin/bash
# requires wmctrl
# x,y,width,height of "external" monitor - based on xrandr
EXTx=0
EXTy=0
EXTw=1920
EXTh=1080
# make sure that only one instance of this script is running per user
lockfile=/tmp/.emsa.$USER.lockfile
if ( set -o noclobber; echo "locked" > "$lockfile") 2> /dev/null; then
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
echo "emsaDEBUG: Locking succeeded" >&2
while true
do
# get a list of visible windows and put it in an array
readarray -t windows < <(wmctrl -lG | grep -v "\-1")
# walk the list of windows to see if the top corner of any window is in the monitor range
for x in "${windows[@]}"
do
if [ $(echo $x | awk '{print $3}') -ge $EXTx -a $(echo $x | awk '{print $3}') -le $EXTw ]
then
# save the windowID
WIN=$(echo $x | awk '{print $1}')
# sticky the window
wmctrl -i -r $(echo $x|awk '{print $1}') -b add,sticky
# wait until window no longer exists or is no longer in the monitor range
while :
do
# get stickied windows new info
tWIN=$(wmctrl -lG | grep $WIN)
# if window no longer exists, break
if [ $? -eq 1 ]; then break; fi
# get windows current x value
tWINx=$(echo $tWIN | awk '{print $3}')
# if no longer in the range....
if ! [ $tWINx -ge $EXTx -a $tWINx -le $EXTw ]
then
# remove stick bit and break out
wmctrl -i -r $(echo $x|awk '{print $1}') -b remove,sticky
break
fi
sleep 1
done
fi
done
# pause for next cycle
sleep 1
done
# can't create lockfile - notify user and quit
else
echo "emsaDEBUG: Lock failed, check for existing process and/or lock file and delete - exiting." >&2
exit 1
fi
exit 0
My second problem is not unique to Xfce because I think other DEs also have this problem. Some applications do not open in the right display. Most Xfce apps do, but some apps like MPV or qimgv don't. Is there a way to fix this and make all apps open where they were launched?
Because this is controlled by the app, there is nothing that Xfce can do, but you can use a tool like devilspie to force placement of application windows.
Edit: fixed code formatting
Last edited by ToZ (2022-01-07 21:24:35)
Please remember to mark your thread [SOLVED] to make it easier for others to find
--- How To Ask For Help | FAQ | Developer Wiki | Community | Contribute ---
Offline
Thanks. I tried this script and it makes one window visible in all workspace but not all windows in the monitor. Maybe I'm not using it correctly, but it made a single window visible on all workspace and it wasn't in the monitor I wanted (probably because I didn't use the variables correctly) but it seems like even if I did it would only work for 1 window.
Offline
Yes, it was coded for just one window. I misread. Here is a version of the script that will sticky all windows whose top left corner sits in the boundary of the external monitor:
#!/bin/bash
# requires wmctrl
# x1, y1, x2, y2 of "external" monitor - based on xrandr
EXTx=0
EXTy=0
EXTw=1920
EXTh=1080
# make sure that only one instance of this script is running per user
lockfile=/tmp/.emsa.$USER.lockfile
if ( set -o noclobber; echo "locked" > "$lockfile") 2> /dev/null; then
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
echo "emsaDEBUG: Locking succeeded" >&2
# variable to hold stickied windows
STICKS=""
while true
do
# get a list of visible windows and put it in an array
readarray -t windows < <(wmctrl -lG | grep -v "\-1")
# walk the list of visible windows to see if the top corner of any window is in the monitor range and sticky it
for x in "${windows[@]}"
do
if [ $(echo $x | awk '{print $3}') -ge $EXTx -a $(echo $x | awk '{print $3}') -le $EXTw ]
then
# sticky the window
WINID=$(echo $x | awk '{print $1}')
wmctrl -i -r $WINID -b add,sticky
# save the window ID
STICKS=$(echo "$STICKS $WINID" | awk '{for (i=1;i<=NF;i++) if (!a[$i]++) printf("%s%s",$i,FS)}{printf("\n")}')
fi
done
# convert list of stickied window IDs to an array
IFS=' ' read -a stickies <<< "$STICKS"
# walk the list of stickied windows to make sure they still need to be sticky
for y in "${stickies[@]}"
do
yx=$(wmctrl -lG | grep $y)
if ! [ $(echo $yx | awk '{print $3}') -ge $EXTx -a $(echo $yx | awk '{print $3}') -le $EXTw ]
then
# remove the sticky bit
wmctrl -i -r $y -b remove,sticky
STICKS=$(echo $STICKS | sed "s/ $y//g")
fi
done
unset windows stickies
# pause for next cycle
sleep 1
done
# can't create lockfile - notify user and quit
else
echo "emsaDEBUG: Lock failed, check for existing process and/or lock file and delete - exiting." >&2
exit 1
fi
exit 0
Post back the results of "xrandr" and I'll tell you what settings you need to use for the first 4 variables.
Please remember to mark your thread [SOLVED] to make it easier for others to find
--- How To Ask For Help | FAQ | Developer Wiki | Community | Contribute ---
Offline
This one is working, but I can't make it work on the right monitor.
This is the xrandr output:
Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767
DVI-D-0 disconnected (normal left inverted right x axis y axis)
HDMI-0 disconnected (normal left inverted right x axis y axis)
DP-0 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 527mm x 296mm
1920x1080 60.00 + 144.00* 119.98 119.88 99.93 74.97 59.94 50.00
1280x1024 75.02 60.02
1280x720 59.94 50.00
1024x768 119.99 99.97 75.03 70.07 60.00
800x600 119.97 99.66 75.00 72.19 60.32 56.25
720x576 50.00
720x480 59.94
640x480 119.52 99.77 75.00 72.81 59.94 59.93
DP-1 disconnected (normal left inverted right x axis y axis)
DP-2 disconnected (normal left inverted right x axis y axis)
DP-3 disconnected (normal left inverted right x axis y axis)
DP-4 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 527mm x 296mm
1920x1080 60.00 + 144.00* 119.98 119.88 99.93 59.94 50.00
1680x1050 59.88
1440x900 59.90
1280x1024 75.02 60.02
1280x720 60.00 59.94 50.00
1024x768 119.99 99.97 75.03 70.07 60.00
800x600 119.97 99.66 75.00 72.19 60.32 56.25
720x576 50.00
720x480 59.94
640x480 119.52 99.77 75.00 72.81 59.94 59.93
DP-5 disconnected (normal left inverted right x axis y axis)
Offline
Try these settings:
EXTx=1921
EXTy=0
EXTw=1919
EXTh=1080
Please remember to mark your thread [SOLVED] to make it easier for others to find
--- How To Ask For Help | FAQ | Developer Wiki | Community | Contribute ---
Offline
Try these settings:
EXTx=1921 EXTy=0 EXTw=1919 EXTh=1080
Doesn't work. Nothing happens.
Offline
Am I correct in assuming that DP-4 is your primary monitor and that DP-0 is to the right of it?
I see what I did wrong. Try the following:
EXTx=1921
EXTy=0
EXTw=3840
EXTh=1080
Last edited by ToZ (2022-01-08 12:18:56)
Please remember to mark your thread [SOLVED] to make it easier for others to find
--- How To Ask For Help | FAQ | Developer Wiki | Community | Contribute ---
Offline
Am I correct in assuming that DP-4 is your primary monitor and that DP-0 is to the right of it?
I see what I did wrong. Try the following:EXTx=1921 EXTy=0 EXTw=3840 EXTh=1080
It's working perfectly now. Thank you very much!
Offline
Updated version:
- Found a bug around the logic of managing windows IDs that resulted in unnecessary unstickying and eventually an error if no windows in target area
- Optimized so that sticky action is only applied when needed (not every time as before)
- tweaked so it works for both side-by-side and above-and-below monitor layouts
#!/bin/bash
# requires wmctrl
# x1,y1,x2,y2 bounding box of "external" monitor - based on xrandr
# --- horizontal example ---
EXTx=1921
EXTy=0
EXTw=3840
EXTh=1080
ORIENTATION=horizontal
# --- vertical example ---
#EXTx=0
#EXTy=0
#EXTw=1920
#EXTh=1080
#ORIENTATION=vertical
### don't change anything below #####################################################################################3
# make sure that only one instance of this script is running per user
lockfile=/tmp/.emsa.$USER.lockfile
if ( set -o noclobber; echo "locked" > "$lockfile") 2> /dev/null; then
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
echo "emsaDEBUG: Locking succeeded" >&2
# variable to hold stickied windows
STICKS=""
while true
do
# get a list of visible windows and put it in an array
readarray -t windows < <(wmctrl -lG | grep -v "\-1")
# walk the list of visible windows to see if the top corner of any window is in the monitor range and sticky it
for x in "${windows[@]}"
do
case $ORIENTATION in
horizontal)
if [ $(echo $x | awk '{print $3}') -ge $EXTx -a $(echo $x | awk '{print $3}') -le $EXTw ]
then
WINID=$(echo $x | awk '{print $1}')
if ! [ $(echo $STICKS | grep $WINID) ]
then
# sticky the window
wmctrl -i -r $WINID -b add,sticky
fi
fi
;;
vertical)
if [ $(echo $x | awk '{print $4}') -ge $EXTy -a $(echo $x | awk '{print $4}') -le $EXTh ]
then
WINID=$(echo $x | awk '{print $1}')
if ! [ $(echo $STICKS | grep $WINID) ]
then
# sticky the window
wmctrl -i -r $WINID -b add,sticky
fi
fi
;;
*) echo "Error: ORIENTATION not defined"
exit 1
;;
esac
# save the window ID ensuring no duplicates
STICKS=$(echo "$STICKS $WINID" | awk '{for (i=1;i<=NF;i++) if (!a[$i]++) printf("%s%s",$i,FS)}{printf("\n")}')
done
# convert list of stickied window IDs to an array
IFS=' ' read -a stickies <<< "$STICKS"
# walk the list of stickied windows to make sure they still need to be sticky
for y in "${stickies[@]}"
do
yx=$(wmctrl -lG | grep $y)
case $ORIENTATION in
horizontal)
if ! [ $(echo $yx | awk '{print $3}') -ge $EXTx -a $(echo $yx | awk '{print $3}') -le $EXTw ]
then
# remove the sticky bit
wmctrl -i -r $y -b remove,sticky
STICKS=$(echo $STICKS | sed "s/ $y//g")
fi
;;
vertical)
if ! [ $(echo $yx | awk '{print $4}') -ge $EXTy -a $(echo $yx | awk '{print $4}') -le $EXTh ]
then
# remove the sticky bit
wmctrl -i -r $y -b remove,sticky
STICKS=$(echo $STICKS | sed "s/$y//g")
fi
;;
*) echo "Error: ORIENTATION not defined properly"
exit 1
;;
esac
done
unset windows stickies WINID y
# pause before next cycle
sleep 1
done
# can't create lockfile - notify user and quit
else
echo "emsaDEBUG: Lock failed, check for existing process and/or lock file and delete - exiting." >&2
exit 1
fi
exit 0
Please remember to mark your thread [SOLVED] to make it easier for others to find
--- How To Ask For Help | FAQ | Developer Wiki | Community | Contribute ---
Offline
Updated version:
- Found a bug around the logic of managing windows IDs that resulted in unnecessary unstickying and eventually an error if no windows in target area
- Optimized so that sticky action is only applied when needed (not every time as before)
- tweaked so it works for both side-by-side and above-and-below monitor layouts
I noticed both versions do not work for maximized or full screen apps. When you maximize a window or make it full screen it doesn't stick to all workspace anymore.
Also, the script outputs "line 78: [: too many arguments" very frequently.
Offline
Also, the script outputs "line 78: [: too many arguments" very frequently.
That's probably because POSIX doesn't specify the results for when there are more than four arguments to the [ utility. It also prefers using "&&" in place of the -a primary and splitting up the whole expression to separate parts like so:
[ $(echo $yx | awk '{print $4}') -ge $EXTy ] && [ $(echo $yx | awk '{print $4}') -le $EXTh ]
As you can see, there are now two expressions each with 3 arguments (the command substitution is performed by the shell before the whole line is executed), which follows the standard.
Last edited by KBar (2022-02-04 20:50:31)
Remember to edit the subject of your topic to include the [SOLVED] tag once you're satisfied with the answers or have found a solution (in which case, don't forget to share it as well), so that other members of the community can quickly refer to it and save their time. Pretty please!
Offline
I noticed both versions do not work for maximized or full screen apps. When you maximize a window or make it full screen it doesn't stick to all workspace anymore.
The test is done based on the top-left corner of the window. The external x coordinate is set to 1921:
EXTx=1921
...that should probably be set to 1920 (as counting starts at 0). First screen would be 0-1919 and second one starting at 1920.
Please remember to mark your thread [SOLVED] to make it easier for others to find
--- How To Ask For Help | FAQ | Developer Wiki | Community | Contribute ---
Offline
Pages: 1
[ Generated in 0.016 seconds, 8 queries executed - Memory usage: 624.43 KiB (Peak: 657.27 KiB) ]