diff options
Diffstat (limited to 'scripts/monitor-to-monitor.nix')
-rw-r--r-- | scripts/monitor-to-monitor.nix | 82 |
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 | |||
3 | let | ||
4 | name = "m2m"; | ||
5 | in | ||
6 | pkgs.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 | |||