3

[LINUX] 像电影里的黑客一样用 terminal 作为日常开发 - beautifulzzzz

 1 year ago
source link: https://www.cnblogs.com/zjutlitao/p/16426625.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

1、效果预览

博主平时用 terminal + vim 作为开发环境,有时候要同时打开多个窗口(如:coding、log、debug ...),这些窗口没有平铺效果,往往乱糟糟的。

本文带来一个脚本,可以一键启动炫酷的多个平铺的窗口,可供大家自行延展发展(因为不同系统的字体可能参数要微调),效果如下:

96604ae05811ce2ebe3ea599778294.png

2、具体实现

2.1 定位鼠标位置

考虑到多个显示器的情况,我们通过脚本读取鼠标箭头位置,然后在其所在窗口展开对应平铺窗口。

这里我们会用到 xdotool,例如,如下命令可以获取鼠标箭头位置:

➜  terminal xdotool getmouselocation                                              
x:1602 y:830 screen:0 window:79767574

我们用 sed 将上面返回的字符串中的 x\y 的值吸取出来:

# 获取鼠标位置
mouse_pos_x=`xdotool getmouselocation | sed "s:x\:\([0-9]*\) y\:\([0-9]*\) .*:\1:g"`
mouse_pos_y=`xdotool getmouselocation | sed "s:x\:\([0-9]*\) y\:\([0-9]*\) .*:\2:g"`

echo "mouse_pos_x = "$mouse_pos_x
echo "mouse_pos_y = "$mouse_pos_y

2.2 获取屏幕位置

上面我们定位了鼠标的位置,接下来我们要定位屏幕的位置,我们将要用到 xrandr 命令:

➜  terminal xrandr
Screen 0: minimum 320 x 200, current 3200 x 1080, maximum 8192 x 8192
HDMI-1 disconnected (normal left inverted right x axis y axis)
DVI-D-1 connected 1920x1080+1280+0 (normal left inverted right x axis y axis) 509mm x 286mm
   1920x1080     60.00*+  59.96    50.00    59.94    59.93  
   1920x1080i    60.00    50.00    59.94 
   ...
VGA-1 connected primary 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
   1280x1024     60.02*+  75.02  
   1280x960      60.00  
   1280x800      59.97    59.81    59.91  
   ...

我们用 sed1920x1080+1280+01280x1024+0+0 吸出来:

➜  terminal xrandr | grep " connected" | sed "s:.* connected.* \([0-9]*\)x\([0-9]*\)+\([0-9]*\)+\([0-9]*\).*:\1 \2 \3 \4:g"
1920 1080 1280 0
1280 1024 0 0

将吸取出来的值存起来:

# 通过下面逻辑,可以将所有屏幕的大小和位置全部算出来
# screen [x, y, x_start, y_start, x_end, y_end]
x_index=0
s_index=0
for x in `xrandr | grep " connected" | sed "s:.* connected.* \([0-9]*\)x\([0-9]*\)+\([0-9]*\)+\([0-9]*\).*:\1 \2 \3 \4:g"`
do
    echo $x
    screen[$s_index]=$x
    let x_index++
    let s_index++
    if [ $((x_index % 4)) -eq 0 ];then
        screen[$((s_index+0))]=$((screen[$((s_index-4))]+screen[$((s_index-2))]));
        screen[$((s_index+1))]=$((screen[$((s_index-3))]+screen[$((s_index-1))]));
        let s_index+=2
    fi
done

echo ${screen[@]}

2.3 计算鼠标在哪个窗口

上面两步已经获取了鼠标位置和窗口坐标,接下来就是一个简单的算法,来计算点在哪个矩形中的问题了(算法如下):

# 计算坐标 (x,y) 是否在某个屏幕中 (x_start,y_start,x_end,y_end)
function point_in_screen(){
    local x=$1
    local y=$2
    local x_start=$3
    local y_start=$4
    local x_end=$5
    local y_end=$6

    if (($x >= $x_start)) && (($x <= $x_end)) && (($y >= $y_start)) && (($y <= $y_end)) ; then
        return 1
    else
        return 0
    fi
}

这样,我们就能遍历鼠标的坐标点(x,y)在哪个屏幕中了:

screen_num=$((s_index/6))
index=0
while [ $index -le $screen_num ]
do
    point_in_screen $mouse_pos_x $mouse_pos_y ${screen[$((index*6+2))]} ${screen[$((index*6+3))]} ${screen[$((index*6+4))]} ${screen[$((index*6+5))]}
    if [ $? == 1 ];then
        echo 'the point in scree '$index
        create_terminal ${screen[$((index*6))]} ${screen[$((index*6+1))]} ${screen[$((index*6+2))]} ${screen[$((index*6+3))]}
        break
    fi
    let index++
done

我们在获取屏幕数据时,将一个屏幕的(w h x_start y_start x_end y_end)6 个数据作为一组存储,因此用 s_index/6 可以获取总的屏幕数。

2.4 1920x1080 平铺效果设计

我有两个屏幕:1920x1080 和 1280x1024,我的设计如下:

a70b760d9d7fc3f6afafa976c418c1.png
  • 在大屏幕中,展开 3 个窗口,就像我们常用的 IDE,有编码窗口,有输入交互命令的窗口,有看 log 的窗口;
  • 在小屏幕中,展开 3 个窗口,一个用来看文件,进行文件搜索,关键词搜索等,一个进行看天气,一个用来监控 CPU 和网速;

那么接下来就是用代码绘制了!

# 绘制 terminal
function create_terminal(){
    SCREEN_W=$1
    SCREEN_H=$2

    if (( $SCREEN_H == 1080)) && (($SCREEN_W == 1920)) ;then
        X_BOARD=15          #窗口与窗口之间的横向补偿(由于存在精度误差,该值是经验值)
        Y_BOARD=15

        LEFT_OFFSET=$3
        UP_OFFSET=$4

        H=50   #1080
        W=189  #1920

        win1_pos_x=$((LEFT_OFFSET+X_BOARD))
        win1_pos_y=$((UP_OFFSET+Y_BOARD))
        win1_size_w=$W
        win1_size_h=$((H*2/3))

        win2_pos_x=$win1_pos_x
        win2_pos_y=$((win1_pos_y + SCREEN_H*2/3 + Y_BOARD -22))
        win2_size_w=$((W/2-1))
        win2_size_h=$((H/3))

        win3_pos_x=$((win1_pos_x+SCREEN_W/2-8))
        win3_pos_y=$((win2_pos_y))
        win3_size_w=$win2_size_w
        win3_size_h=$((win2_size_h-2))

        xfce4-terminal --geometry $win1_size_w'x'$win1_size_h'+'$win1_pos_x'+'$win1_pos_y -Tcode -e'bash -c "vim ; bash"'
        xfce4-terminal --geometry $win2_size_w'x'$win2_size_h'+'$win2_pos_x'+'$win2_pos_y -Tcmd -e'bash -c "screenfetch ; bash"'
        xfce4-terminal --geometry $win3_size_w'x'$win3_size_h'+'$win3_pos_x'+'$win3_pos_y -Tlog -e'bash -c "xdotool key ctrl+shift+t; bash"'

        echo $win1_size_w'x'$win1_size_h'+'$win1_pos_x'+'$win1_pos_y
        echo $win2_size_w'x'$win2_size_h'+'$win2_pos_x'+'$win2_pos_y
        echo $win3_size_w'x'$win3_size_h'+'$win3_pos_x'+'$win3_pos_y
    elif (( $SCREEN_H == 1024)) && (($SCREEN_W == 1280)) ;then
        ...
    fi
}
  • X_BOARDY_BOARD 是窗口与窗口之间的留白,这样相比于窗口相互紧贴,显得更高端
  • HW 是个经验值,由于绘制窗口的函数 xfce4-terminal 传如的串口宽、高不是像素点,而是某种好像和字体相关的行、列,因此得根据自己电脑的情况微调
  • 我们有了窗口像素级起始位置,像素级大小,以及整个屏幕按照字体行列计算的大致行列数 H/W,我们就能计算出三个窗口的起始像素级位置,和窗口的行列级大小(这里有各种补偿,以达到最佳效果)
  • 最后调用 xfce4-terminal 进行绘制,在绘制的时候可以带一些默认执行的语句,例如:vimscreenfetch

2.5 1280x1024 平铺效果设计

同 1920x1080,绘制 1280x1024 的代码如下:

X_BOARD=30          #窗口与窗口之间的横向补偿(由于存在精度误差,该值是经验值)
Y_BOARD=30

LEFT_OFFSET=$3
UP_OFFSET=$4

H=48 #56   #1024
W=129 #142  #1280

win1_pos_x=$((LEFT_OFFSET+X_BOARD))
win1_pos_y=$((UP_OFFSET+Y_BOARD))
win1_size_w=$((W/2-4))
win1_size_h=$((H-2))

win2_pos_x=$((win1_pos_x + SCREEN_W/2 + X_BOARD - 48))
win2_pos_y=$win1_pos_y
win2_size_w=$win1_size_w
win2_size_h=$((win1_size_h/2))

win3_pos_x=$win2_pos_x
win3_pos_y=$((win1_pos_y + SCREEN_H/2 + Y_BOARD - 40))
win3_size_w=$win2_size_w
win3_size_h=$((win2_size_h-1))


# xwininfo
xfce4-terminal --geometry $win1_size_w'x'$win1_size_h'+'$win1_pos_x'+'$win1_pos_y -Tsys 
xfce4-terminal --geometry $win2_size_w'x'$win2_size_h'+'$win2_pos_x'+'$win2_pos_y -Tmem -e'bash -c "curl \"wttr.in/HangZhou?0\";bash"'
xfce4-terminal --geometry $win3_size_w'x'$win3_size_h'+'$win3_pos_x'+'$win3_pos_y -Tinfo -e'bash -c "sampler -c runchart.yml;bash"'
  • 天气用了一个 OpenAPI,这个属于 github 上一个超大项目,里面有各种开放 API
  • 系统性能,用了 sampler,大家可以进一步深入研究

本文代码在:https://github.com/nbtool/cool_terminal

➜  terminal tree
.
├── readme.md
├── runchart.yml
└── run.sh

0 directories, 3 files

[1]. 本文代码 GITHUB
[2]. xdotool 介绍
[3]. arch linux 社区 xrandr 介绍
[4]. arch linux 社区 xfce4-terminal 介绍


: ** 如果觉得不错,帮忙点个支持哈~**

24abbb1cf6f0bee204045d1f3bdb34.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK