aboutsummaryrefslogtreecommitdiff
path: root/scripts/monitor-to-monitor.nix
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/monitor-to-monitor.nix')
-rw-r--r--scripts/monitor-to-monitor.nix82
1 files changed, 82 insertions, 0 deletions
diff --git a/scripts/monitor-to-monitor.nix b/scripts/monitor-to-monitor.nix
new file mode 100644
index 0000000..fa03916
--- /dev/null
+++ b/scripts/monitor-to-monitor.nix
@@ -0,0 +1,82 @@
1{ pkgs, ... }:
2
3let
4 name = "m2m";
5in
6pkgs.writeShellScriptBin name ''
7 #
8 # Move the current window to the next monitor.
9 #
10 # Also works only on one X screen (which is the most common case).
11 #
12 # Props to
13 # http://icyrock.com/blog/2012/05/xubuntu-moving-windows-between-monitors/
14 #
15 # Unfortunately, both "xdotool getwindowgeometry --shell $window_id" and
16 # checking "-geometry" of "xwininfo -id $window_id" are not sufficient, as
17 # the first command does not respect panel/decoration offsets and the second
18 # will sometimes give a "-0-0" geometry. This is why we resort to "xwininfo".
19
20 screen_width=$(xdpyinfo | awk '/dimensions:/ { print $2; exit }' | cut -d"x" -f1)
21 screen_height=$(xdpyinfo | awk '/dimensions:/ { print $2; exit }' | cut -d"x" -f2)
22 display_width=$(xdotool getdisplaygeometry | cut -d" " -f1)
23 display_height=$(xdotool getdisplaygeometry | cut -d" " -f2)
24 window_id=$(xdotool getactivewindow)
25
26 # Remember if it was maximized.
27 window_horz_maxed=$(xprop -id "$window_id" _NET_WM_STATE | grep '_NET_WM_STATE_MAXIMIZED_HORZ')
28 window_vert_maxed=$(xprop -id "$window_id" _NET_WM_STATE | grep '_NET_WM_STATE_MAXIMIZED_VERT')
29
30 # Un-maximize current window so that we can move it
31 wmctrl -ir "$window_id" -b remove,maximized_vert,maximized_horz
32
33 # Read window position
34 x=$(xwininfo -id "$window_id" | awk '/Absolute upper-left X:/ { print $4 }')
35 y=$(xwininfo -id "$window_id" | awk '/Absolute upper-left Y:/ { print $4 }')
36
37 # Subtract any offsets caused by panels or window decorations
38 x_offset=$(xwininfo -id "$window_id" | awk '/Relative upper-left X:/ { print $4 }')
39 y_offset=$(xwininfo -id "$window_id" | awk '/Relative upper-left Y:/ { print $4 }')
40 x=$(( x - x_offset))
41 y=$(( y - y_offset))
42
43 # Compute new X position
44 new_x=$((x + display_width))
45 # Compute new Y position
46 new_y=$((y + display_height))
47
48 # If we would move off the right-most monitor, we set it to the left one.
49 # We also respect the window's width here: moving a window off more than half its width won't happen.
50 width=$(xdotool getwindowgeometry "$window_id" | awk '/Geometry:/ { print $2 }'|cut -d"x" -f1)
51 if [ "$(( new_x + width / 2))" -gt "$screen_width" ]; then
52 new_x=$((new_x - screen_width))
53 fi
54
55 height=$(xdotool getwindowgeometry "$window_id" | awk '/Geometry:/ { print $2 }'|cut -d"x" -f2)
56 if [ "$((new_y + height / 2))" -gt "$screen_height" ]; then
57 new_y=$((new_y - screen_height))
58 fi
59
60 # Don't move off the left side.
61 if [ "$new_x" -lt 0 ]; then
62 new_x=0
63 fi
64
65 # Don't move off the bottom
66 if [ "$new_y" -lt 0 ]; then
67 new_y=0
68 fi
69
70 # Move the window
71 xdotool windowmove "$window_id" "$new_x" "$new_y"
72
73 # Maximize window again, if it was before
74 if [ -n "''${window_horz_maxed}" ] && [ -n "''${window_vert_maxed}" ]; then
75 wmctrl -ir "$window_id" -b add,maximized_vert,maximized_horz
76 elif [ -n "''${window_horz_maxed}" ]; then
77 wmctrl -ir "$window_id" -b add,maximized_horz
78 elif [ -n "''${window_vert_maxed}" ]; then
79 wmctrl -ir "$window_id" -b add,maximized_vert
80 fi
81''
82