20110131

用键盘在双显示器间移动窗口 Ubuntu

用键盘在双显示器间移动窗口 Ubuntu

笔记本通常自己有个显示器,就在键盘上方,但是人心不足,总觉得太小,所以
通常还会外接一个。

窗口在两个显示器间移动,通常也很容易,用鼠标拖动就是,但是人心不足,总
觉得如果不用鼠标的话而使用快捷键的话,手指就可以不离开键盘。

这样的工作,早就有人做了。在win7中,它是默认支持的。在Ubuntu中,快捷键
只支持窗口在工作区间移动。

不过,这样的工作在Ubuntu下也早就有人做了, 见
[http://ubuntuforums.org/showthread.php?t=1045417]。有用wmctrl的,也有
用xdotool的。wmctrl是专门对窗口做操作的,xdotool是专门模拟鼠标键盘输入
的。

xdotool的作者是位牛人,他还有个作品,叫做keynav,能完全不用鼠标,而用
键盘移动鼠标。这样的工作看起来没啥希奇的,其牛之处在于keynav移动鼠标的
时候不是左键左移、右键右移,而是用了二分查找算法,把屏幕划成上下左右四
份,选择了鼠标的目标位置在哪个格子里,然后再把那个格式分成上下左右四分。
如是者…据说有的例子是最坏11次找到位置。考虑到精确定位的时候可能一直在
重复着向同一个方向,11次并不难做。至少在我的经验里,挺容易使用的。

于是我选择了xdotool这一方案。心理学上把这叫光环效应。比如这位牛人的名
字也叫乔丹。上了点岁数的人该知道这另一位乔丹挺牛的,为这名字倍添光彩。

可是基于xdotool的这个在屏幕间移窗口的工具有个不足之处,它默认显示器是
一左一右。而且需要用户手填显示器的分辨率地。人心不足,我把它改了。

显示器一左一右,曾导致大约一个月前,我的脊椎两侧轮着班疼。疼痛令我彻夜
难眠,轮俯卧撑都停了。直到有一天勉力恢复了一半俯卧撑,后背才不疼了。

这个切换当前焦点窗口的工具是个脚本,你得自己给它设置个快捷键。我定在
win+up 上了。这比win7那个还方便。win7下是这样的称动左边显示器要
Win+Shift+左,移到右边显示器要Win+Shift+右。移来和移去使用了不同的按键。
补充,win7这个显示器一上一下摆放也是可以的。

题外话1 我整了个显示器,22英寸,可以立起来,适合编码,可以横着,适合看
碟。特此显摆。

题外话2 发现白板上的笔道(用含酒精的白板笔写的)时间一长(24小时以上)
特别难以清除,用白猫洗洁精能去除大部分。用水彩笔(儿童用的水性笔)写
的,用水很容易就能擦掉;在干了以后,笔触略微变细和不连续,完全可以忍受。
且水性笔较细,白板上能写更多的东西了,字体也更能够容忍一些。

代码如下。这个小东西也起了个名字 swam,
Switch Window Actived between Monitors.

#!/bin/bash
#++++++++++++++++
# Monitor Switch
#
# Moves currently focused window from one monitor to the other.
# Designed for a system with two monitors.
# Script should be triggered using a keyboard shortcut.
# If the window is maximized it should remain maximized after being moved.
# If the window is not maximized it should retain its current size, unless
# height is too large for the destination monitor, when it will be trimmed.
#++++++++++++++++
# modified by Young <gift.young@gmail.com>
# based on chips617's work at
[http://ubuntuforums.org/showthread.php?t=1045417].

# bugs knonw:
# 1. If the left-top conner of the active window is out of your
monitors, we cannot determin which monitor is on, therefore we suppose
it is on monitor B.

# History:
# 2011-1-31 The monitors can be at any position, not only left and right.
# 2007-11 the original chips617's work

# resolution and position of monitors
count=0
while read line
do
keys[$((++count))]="${line}"
done <<EOF
$( xrandr -q | grep " connected" | awk '{print $3}' | awk -F'[x+]'
'{printf("%s\n%s\n%s\n%s\n",$1, $2, $3, $4)}' )
EOF
w_A_monitor=${keys[1]}
h_A_monitor=${keys[2]}
x_A_monitor=${keys[3]}
y_A_monitor=${keys[4]}
w_B_monitor=${keys[5]}
h_B_monitor=${keys[6]}
x_B_monitor=${keys[7]}
y_B_monitor=${keys[8]}

# # window title bar height (default title bar height in Gnome)
h_tbar=29
## todo

# # focus on active window
window=`xdotool getactivewindow`

# # get active window size and position
x=`xwininfo -id $window | grep "Absolute upper-left X" | awk '{print $4}'`
y=`xwininfo -id $window | grep "Absolute upper-left Y" | awk '{print $4}'`
w=`xwininfo -id $window | grep "Width" | awk '{print $2}'`
h=`xwininfo -id $window | grep "Height" | awk '{print $2}'`

# # window on A monitor
if [ "$x" -ge $x_A_monitor ] &&
[ "$x" -le $[$x_A_monitor + $w_A_monitor] ] &&
[ "$y" -ge $y_A_monitor ] &&
[ "$y" -le $[$y_A_monitor + $h_A_monitor ] ] ; then

new_x=$(($x-$x_A_monitor+$x_B_monitor))
new_y=$(($y-$y_A_monitor+$y_B_monitor-$h_tbar))
xdotool windowmove $window $new_x $new_y
# retain maximization
if [ "$w" -eq "$w_A_monitor" ]; then
xdotool windowsize $window 100% 100%
# adjust height
elif [ "$h" -gt $(($h_B_monitor-$h_tbar)) ]; then
xdotool windowsize $window $w $(($h_B_monitor-$h_tbar))
fi
# # window on B monitor
else
new_x=$(($x-$x_B_monitor+$x_A_monitor))
new_y=$(($y-$y_B_monitor+$y_A_monitor-$h_tbar))
xdotool windowmove $window $new_x $new_y
# retain maximization
if [ "$w" -eq "$w_B_monitor" ]; then
xdotool windowsize $window 100% 100%
# adjust height
elif [ "$h" -gt $(($h_A_monitor-$h_tbar)) ]; then
xdotool windowsize $window $w $(($h_A_monitor-$h_tbar))
fi

fi

2 comments:

Anonymous said...

Gooԁ info. Lucky me I came acrοss уour wеbsite
by chancе (stumbleupon). I hаve booκ-marked it for later!


Feel freе to surf to my web site - payday loans

Anonymous said...

achat cialis,
cialis achat,
cialis senza ricetta,
cialis.