20110320

抄代码,可以抄到什么程度

抄代码,可以抄到什么程度

最近,老是有同学跟我提到 "不会写代码,只会从网上抄",在加上前两天提到

的本科毕业论文同学"做"过的微博系统,觉得有必要说一下

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

No comments: