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




    1、效果预览

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

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


    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,我的设计如下:

    • 在大屏幕中,展开 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,大家可以进一步深入研究

    3 代码

    本文代码在: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 介绍



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

  • 相关阅读:
    网络安全(黑客)自学
    QLabel类常用方法
    自学嵌入式,已经会用stm32做各种小东西了
    k8s入门到实战--跨服务调用
    基于kubernetes平台微服务的部署
    PHP安装dbase扩展,2024最新安装日志,注意PHP版本、扩展目录路径、文件权限3个大坑
    数量关系 --- 方程
    Pridwen: Universally Hardening SGX Programs via Load-Time Synthesis【ATC`22】
    《ClickHouse原理解析与应用实践》读书笔记(3)
    UTONMOS:中国区块链专利申请数量占全球总量的84%
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/16426625.html