抄代码,可以抄到什么程度
最近,老是有同学跟我提到 "不会写代码,只会从网上抄",在加上前两天提到
的本科毕业论文同学"做"过的微博系统,觉得有必要说一下
1. 什么是可以从网上抄的.最粗暴简单的回答是:一个字母也不能复制粘贴.
2. 抄到什么程度你仍然可以说那是你的程序.这是个老大的哲学问题了,不过咱
们不讨论那么深.
故事开始.
前一段时间写的程序--把窗口由一个显示器切到另一个显示器的工具--有个缺
点,如果窗口已经在大显示器上最大化了,或者很长,怎么也不移动了小显示器
上。
虽然我可以快捷键先把它整小,然后再移。终究不爽得很。
忍了很久,而且前一段时间已经找到问题的症结。今天改了下程序。
因为我的程序信赖的一个工具 xdotool,不能移动最大化的窗口。而且,如果窗
口比目标显示器还大,也不能移动。
首先想到的是可以先把窗口缩小,然后移走,再恢复原来的大小。奈何,我没有
找到 xdotool 改变最大化窗口大小的方法。所以,此路不通。
想起来另一个工具可以信赖,wmctrl,倒是可以操作。不过,它不能找到当前的
激活窗口。而这,正是我们要移动的东西,得知道。
在网上找到一德国兄弟的作品
[http://my.opera.com/raphman/blog/show.dml/302528?cid=56972962#comment56972962],
我改吧改吧抄吧抄吧,把关于xprop得到当前激活窗口的那段放我的代码里了。
顺手,把用同一工具判定当前窗口是不是最大化啥的一段代码抄过来。因为窗口
系统不太一样,他用KDE,我用GNOME,又改了一下。
终于,我的程序能够工作了。放在
[https://github.com/younggift/argus/blob/master/monitor_switch.sh]里了。
现在,我们可以回过头来回答先前的问题了.
1. 什么是可以从网上抄的.
事实上,我们通常会抄一下 某种实现机制(比如怎么调用printf,它的参数)
的代码示例, 从MSDN或者 code project 这样的站点中.
当然,应该通读一下文档,而不是简单的抄代码.没有看懂的情况下就抄代码,
实践证明,后患无穷.
不读说明书就使用工具或者设备,是极其危险的.API也是一样.
不过,如果已经了解原理,抄一段别人的实现,改吧改吧...似乎可以容忍.
2. 抄到什么程度你仍然可以说那是你的程序.
业务逻辑必须是你手写的,因为那是你的工作唯一区别于别人的东西.让你的需
求适应用户的要求,而不是服从你能找到的资源的下限,即不能因为你手儿不行
就降低要求,除非你明确知道你不行,别人也不能实现.
如果我抄了德国哥们的整休代码,把其中KDE那部分换成了GNOME的,那就是大
抄.我原来的代码是把适用于 左右显示器布局 的代码改成了 适用于 任何布局
的双显示器, 这是加入了一部分功能, 有贡献,不过,整体的代码仍然是人家
的.现在,我改成了用wmctrl,改动就又多了一些.
郭小四同学抄了整体的人物设定和故事情节,那就是抄.如果只是引用一两句主
席语录,那叫时尚.或者叫致敬.
=======================
#!/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.
#---------------------------------------------
# dependence on xrandr, wmctrl, xprop, xwininfo, awk
#
# modified by Young <gift.young@gmail.com>
# based on chips617's work at
[http://ubuntuforums.org/showthread.php?t=1045417].
# based on Raphael Wimmer's work at
[http://my.opera.com/raphman/blog/show.dml/302528]
# History:
# 2011-3-19 bug fixed: we don't depend on xdotool any more, because we
can't find the function by it to manipulate the maximized window.
# 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.
# 2. if one of the monitor is rotated left, the shortcut will be disabled.
# 2011-1-31 The monitors can be at any position, not only left and right.
# 2007-11 the original chips617's work
# bugs knonw:
# empty now.
# 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]}
# get active window
# window=`xdotool getactivewindow`
activeWinLine=$(xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)")
window="${activeWinLine:40}"
# window title bar height
# h_tbar=29
xWinDecorLine=$(xprop -id $window | grep "_NET_FRAME_EXTENTS(CARDINAL)")
h_tbar=${xWinDecorLine:37 :2}
# 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}'`
# calculate the new position of the window ...
## if the window was 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
x_target_monitor=$x_B_monitor
y_target_monitor=$y_B_monitor
w_target_monitor=$w_B_monitor
h_target_monitor=$h_B_monitor
x_source_monitor=$x_A_monitor
y_source_monitor=$y_A_monitor
## if the window was on B monitor
else
x_target_monitor=$x_A_monitor
y_target_monitor=$y_A_monitor
w_target_monitor=$w_A_monitor
h_target_monitor=$h_A_monitor
x_source_monitor=$x_B_monitor
y_source_monitor=$y_B_monitor
fi
new_x=$(($x-$x_source_monitor+$x_target_monitor))
new_y=$(($y-$y_source_monitor+$y_target_monitor-$h_tbar))
# ... and the width or the height up to the edge of the target monitor
if (($w > $w_target_monitor))
then
w=$w_target_monitor
fi
if (($h > $h_target_monitor))
then
h=$h_target_monitor
fi
# move the window to another monitor
# if maximized store info and de-maximize
winState=$(xprop -id $window | grep "_NET_WM_STATE(ATOM)" )
if [[ `echo ${winState} | grep "_NET_WM_STATE_MAXIMIZED_HORZ"` != "" ]]
then
maxH=1
wmctrl -i -r $window -b remove,maximized_horz
fi
if [[ `echo ${winState} | grep "_NET_WM_STATE_MAXIMIZED_VERT"` != "" ]]
then
maxV=1
wmctrl -i -r $window -b remove,maximized_vert
fi
# do move
wmctrl -i -r $window -e 0,$new_x,$new_y,$w,$h
# the following lines are for debug.
# echo x x_source_monitor x_target_monitor
# echo $x $x_source_monitor $x_target_monitor
# echo y y_source_monitor y_target_monitor
# echo $y $y_source_monitor $y_target_monitor
# echo h $h w $w
# echo new_x $new_x
# echo new_y $new_y
# restore maximization
((${maxV})) && wmctrl -i -r $window -b add,maximized_vert
((${maxH})) && wmctrl -i -r $window -b add,maximized_horz
# raise window (seems to be necessary sometimes)
#wmctrl -i -a $window
# and bye
exit 0