1

I'm using my laptop in different configurations. Sometimes i'm using only laptop, with LVDS1 output. Sometimes i've one monitor(DP1) on right of LVDS. Sometimes on left. Sometimes i have two monitors(DP2/DP3) - one on left, and one on right of LVDS

I would like to setup my desktop for this environment. I want xfce panel always on LVDS, web browser - always on external monitor(and if are 2 monitors - on right), communicator(pidgin) on left (DP2) or LVDS if there is no left monitor.

I've prepared set of script to configurue xserver using xrandr - for all configurations. position of panel i'm setting by xfconf-query.

But - how to move specific application to specific monitor? For example - how to run all pidgin applications to DP2? I don't want do it by mouse - i want to move all filtered xwindow clients to specific display. It's possible?

1
  • Possible with wmctrl program. I could write a script for two monitors but i don't have a third monitor so cannot do anything there Oct 8, 2015 at 2:07

2 Answers 2

4

If your main objective is to avoid using the mouse, this script allows for a keyboard shortcut to move the windows between monitors. It works great for me on my triple monitor setup. Then you can assign a keyboard shortcut to tile after moving to a new monitor.

  1. Download the script below. Save under ~/bin/
  2. Make it executable: chmod +x ~/bin/move-to-next-monitor

Source: https://github.com/jc00ke/bin/blob/master/move-to-next-monitor. Thanks to jc00ke!

#!/bin/sh
#
# Move the current window to the next monitor.
#
# Also works only on one X screen (which is the most common case).
#
# Props to
# http://icyrock.com/blog/2012/05/xubuntu-moving-windows-between-monitors/
#
# Unfortunately, both "xdotool getwindowgeometry --shell $window_id" and
# checking "-geometry" of "xwininfo -id $window_id" are not sufficient, as
# the first command does not respect panel/decoration offsets and the second
# will sometimes give a "-0-0" geometry. This is why we resort to "xwininfo".
# Make sure your largest monitor is set to Primary display.

screen_width=`xdpyinfo | awk '/dimensions:/ { print $2; exit }' | cut -d"x" -f1`
screen_height=`xdpyinfo | awk '/dimensions:/ { print $2; exit }' | cut -d"x" -f2`
display_width=`xdotool getdisplaygeometry | cut -d" " -f1`
display_height=`xdotool getdisplaygeometry | cut -d" " -f2`
window_id=`xdotool getactivewindow`

# Remember if it was maximized.
window_state=`xprop -id $window_id _NET_WM_STATE | awk '{ print $3 }'`

# Un-maximize current window so that we can move it
wmctrl -ir $window_id -b remove,maximized_vert,maximized_horz

# Read window position
x=`xwininfo -id $window_id | awk '/Absolute upper-left X:/ { print $4 }'`
y=`xwininfo -id $window_id | awk '/Absolute upper-left Y:/ { print $4 }'`

# Subtract any offsets caused by panels or window decorations
x_offset=`xwininfo -id $window_id | awk '/Relative upper-left X:/ { print $4 }'`
y_offset=`xwininfo -id $window_id | awk '/Relative upper-left Y:/ { print $4 }'`
x=`expr $x - $x_offset`
y=`expr $y - $y_offset`

# Compute new X position
new_x=`expr $x + $display_width`
# Compute new Y position
new_y=`expr $y + $display_height`

# If we would move off the right-most monitor, we set it to the left one.
# We also respect the window's width here: moving a window off more than half its width won't happen.
width=`xdotool getwindowgeometry $window_id | awk '/Geometry:/ { print $2 }'|cut -d"x" -f1`
if [ `expr $new_x + $width / 2` -gt $screen_width ]; then
  new_x=`expr $new_x - $screen_width`
fi

height=`xdotool getwindowgeometry $window_id | awk '/Geometry:/ { print $2 }'|cut -d"x" -f2`
if [ `expr $new_y + $height / 2` -gt $screen_height ]; then
  new_y=`expr $new_y - $screen_height`
fi

# Don't move off the left side.
if [ $new_x -lt 0 ]; then
  new_x=0
fi

# Don't move off the bottom
if [ $new_y -lt 0 ]; then
  new_y=0
fi

# Move the window
xdotool windowmove $window_id $new_x $new_y

# Maintain if window was maximized or not
if [ "${window_state}" = "_NET_WM_STATE_MAXIMIZED_HORZ," ]; then
    wmctrl -ir $window_id -b add,maximized_vert,maximized_horz
fi
  1. If not already installed, install xdotool and wmctrl: sudo apt-get install xdotool wmctrl
  2. Next assign a keyboard shortcut for the script under Keyboard > Application Shortcuts. (I use Alt+Right. Then to tile right I use Ctrl+Alt+Right and to tile left Ctrl+Alt+Left. Window tiling keyboard shortcuts are under Window Manager.)
    Source: http://makandracards.com/makandra/12447-how-to-move-a-window-to-the-next-monitor-on-xfce-xubuntu

For different size monitors
I have a 1920x1080 center monitor and two 1440x900 side monitors.

display_width=`xdotool getdisplaygeometry | cut -d" " -f1`
display_height=`xdotool getdisplaygeometry | cut -d" " -f2`

The above two commands output the dimensions of my largest monitor even if the window happens to be on a side monitor. Therefore the script always moved the window according to these dimensions. This caused the script to not always move to the next monitor, but sometimes it would move to the previous monitor. I took my overall screen width (4800) and divided it by three. Now it always moves to the next monitor.

display_width="1600"
display_height=`xdotool getdisplaygeometry | cut -d" " -f2`
2
  • Although your answer is 100% correct, it might also become 100% useless if that link is moved, changed, merged into another one or the main site just disappears... :-( Therefore, please edit your answer, and copy the relevant steps from the link into your answer, thereby guaranteeing your answer for 100% of the lifetime of this site! ;-) You can always leave the link in at the bottom of your answer as a source for your material...
    – Fabby
    Oct 7, 2015 at 23:49
  • 1
    Good point. (That should have occurred to me.) Thank you for that input.
    – jbrock
    Oct 8, 2015 at 2:04
1

For some reason I can add an answer but cannot comment on jbrock's answer above...

on my rig (Fedora 22), xprop -id $window_id _NET_WM_STATE returns "_NET_WM_STATE_FOCUSED" rather than nothing at all for non-maximised windows, so the script as-is always maximises the window after moving it.

Also it is possible for a window to be maximised in only one direction, but the script always applies both directions back in at the end.

To restore the window to exactly the state of maximized-ness it was in before, test for the two flags explicitly and add them back individually. Replace last 3 lines of original script with this:

if [[ $window_state = *MAXIMIZED_HORZ* ]]; then
  wmctrl -ir $window_id -b add,maximized_horz
fi
if [[ $window_state = *MAXIMIZED_VERT* ]]; then
  wmctrl -ir $window_id -b add,maximized_vert
fi
2
  • I'm just now seeing your answer here. Mine also returns "_NET_WM_STATE_FOCUSED" when it is not maximized. I don't quite understand why the original script has the -n argument (saying if it returns nothing). A few days ago I looked at the script and fixed it from always maximizing. I just tried your solution, but it did not preserve the maximized state. However, my changes to the above script (last three lines) work great for me on my setup.
    – jbrock
    Feb 20, 2016 at 23:59
  • I've also added information on my answer about different size monitors. By the way you need 50 reputation to comment. askubuntu.com/help/privileges/comment
    – jbrock
    Feb 21, 2016 at 0:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.