作者: Zeeko

  • 摩托新手的天鹰 TS150 2023 特仕版磨合期体验

    之前没接触过摩托车,通勤用的都是小电驴,今年拿了摩托车驾照后就加钱买了第一辆摩托车。

    刚入手的第一感觉就是体积大、车身重,骑了一段时间后发现这是俩优点:

    • 体积大,坐垫空间也大,后座体验更好,不会觉得挤
    • 车身重,跑到 60 km/h 以上很稳定,不会像小电驴有种轻飘飘的感觉

    很多人在买车前都比较关心下面的几个问题,我用自己的体验来回答一下:

    关于震动:
    我没有骑过其他的摩托车,跟我之前的小电驴比起来肯定更抖,但在可接受的范围内。连续骑行超过 1 小时,稍微会感觉手麻。然后就是车头在低速震动的时候有“哒哒”的响声,没找出来是什么零件发出的声音,最后就只能装作自己听不见了。

    关于减震:
    不能说跟小电驴的减震没有区别,只能说减震的差距不明显,过减速带、坑洼路面还是尽量慢行吧。

    关于油耗:
    11 升的油箱,加满油 70 多块(2023 年 5 月),夏天极限续航保守估计 350 公里左右。我都是在市区、郊区骑行,感觉这点儿油耗不值得花时间记录,油耗记录 App 装上没多久就卸载了。

    因为没有骑过其他的摩托车,我说不出这车相较于其他车的优点,但是使用过程中印象深刻的槽点还是有一些的:

    • 自动起停:骑行过程中停止超过 3 秒,车辆就会自动熄火,非常适合等灯过路口的场景。如果发动机温度足够,可以直接拧油门重新点火。但是如果长时间熄火等待,发动机降温,就没法用油门启动了,什么时候会无法通过油门启动是无法预测的,所以还是得习惯通过点火开关启动。
    • 车机互联:因为有手机投屏功能,所以我没有安装手机支架,而是把手机放在车头包里面,但是 Moto Fun 的互联功能实在太脆弱了,经常会断开连接。往往想要看看导航路线的时候,车机上显示的就只有一个互联用的二维码。综合我这么长时间的使用体验,开启车机互联并用手机投屏导航,大概有 50% 的时间投屏可以正常工作,40% 的时间断开投屏显示自带的地图,10% 的时间连接完全断开。

    最后分享一下新手的改装,提车没多久就是 618 了,于是就上网整了一些改装配件,主要是为了增强舒适性,毕竟踏板主打的就是骑行舒适度:

    • 加高的风挡,顺便前移后视镜,原装后视镜空出来后可以装个 10 mm 正牙装饰螺丝
    • 护杠,除了防撞还可以提供更大的脚踏空间,另外还可以把背包通过护杠绑在油箱上,非常实用
    • 带靠背的尾箱,需要改装尾箱架,拆装尾箱架需要 13 mm 扳手
    • 带腰靠的坐垫,腰靠功能几乎感受不到,但是可以很好的分隔前后坐的座位空间
    • 180 度后视镜,补盲效果差强人意,正常的小汽车进入左右后视镜盲区之后就会出现在这块镜子的视野中。但是,如果旁边车道的是个五菱 mini 这类的小车,就会被我的肩膀挡住,反而不容易发现,接下来准备试试粘在左右后视镜上的补盲镜

    年轻人的第一次摩托车抛锚

    没想到不到半年时间,我就遇到了第一次摩托车抛锚 —— 无法点火。经过排查后发现是我下车熄火后忘了断电就着急忙慌地离开了,等三小时后回到车子面前的时候,车辆电池电量所剩无几,只能勉强维持屏幕亮起,无法点火。还好停车位置附近就有修理店,花了 40 人民币搭电才重新启动发动机。

    由于电池缺电,重新启动发动机后需要保持发动机持续工作,给电池充电。稳妥起见,我关掉自动起停功能,连着跑了 10 公里,确认熄火后能够正常启动才回了家。

    总结下来,要避免类似情况发生得养成肌肉记忆,熄火后记得断电。

  • 如何使用 Zerotier 连接你家中的设备

    我在家里的旧笔记本上使用 Open My Vault 建立了 NAS,不过我只能在家里连上 WiFi 才能访问它。在过年回老家、出门旅游或者外出办公的时候就没法使用了。虽然在这些场景经常用不上 NAS,不过,“我可以不用,但不能没有”。

    经过一番调研后,我发现我需要的是一个 VPN 软件,通过 VPN 安全地访问运行在家里的网络服务。基于部署难度上的考量,我选择了 zerotier,这是一款非常简单易用的 VPN 软件,免费版可以连接 25 个节点,对于我来说,完全够用了。但是,在国内的网络环境下,节点间的连接往往不太稳定,我在国内没有自己的公网 IP 服务器,所以借助一台香港服务器,来提高 zerotier 网络的稳定性。

    首先,在 my.zerotier.com 创建一个虚拟网络,我选择的私有网段是 10.2.2.0/24,因为这个网段不容易跟常见的家庭路由器内网撞车。

    家里的网络有全局透明代理,可以直接在运行 NAS 的服务器上使用官方的 zerotier 客户端加入 zerotier 网络。

    我没有在路由器上安装 zerotier:

    • 我的 OpenWRT 虚拟机系统版本太奇葩了,没法从官方源安装 zerotier
    • 我希望路由器的功能尽量少一些,毕竟 OpenWRT 跟日常使用的 Linux 系统有很大区别,对我而言有额外的维护负担

    我的 VPS 在香港,也需要加入 zerotier network,直接使用官方的 Linux 客户端就行,我并没有在 VPS 上建立 zerotier moon 服务,这跟我手机上的连接 zerotier 的方式有关。

    手机有时会出门,而且没法设置多个代理,所以就用 v2ray 客户端(SagerNet)将所有访问 10.2.2.0/24 的请求转发到 VPS 服务器。因为 VPS 已经加入了 zerotier 网络,所以手机上就不用安装 zerotier 客户端。笔记本电脑也是同理,这样做还可以避免 zerotier VPN 跟工作 VPN 冲突。

    不过这样的设置也带来了新的问题,对于手机而言,部署在家里的服务在不同网络环境下有不同的 IP 地址,虽然 zerotier 有 DNS 功能,但是我的手机本质上并没有加入 zerotier VPN,所以实际上也没办法使用 zerodns。还好我有自己的域名,在公网上,我把指向家里服务的域名都解析到 zerotier 的私有地址(10.2.2.0/24)。在家里的路由器上,将这些域名强制设置为局域网址(192.168.1.0/24)。

    至此,出门在外的时候,我终于可以随时访问部署在家里的 NAS 了,使用联通 5G 网络运行 iperf3 测试,能够跑到 60Mbps(对比通过 VPS 代理测速的 speedtest.net 结果 120Mbps),应急使用完全足够了。

  • 不花钱提升工作笔记本的电池续航

    我的工作电脑是一台安装 Arch Linux 的轻薄笔记本,虽说 Linux 比 Windows 更加节省资源,但是我的工作笔记本续航比较尿崩,出门必须带充电器,进店必找有插座的位置。看到同事的 mbp 的超长续航不可能不羡慕,但我也不奢望过多,只期望出门后,笔记本能够支撑一下午的正常办公就足够了。

    amd_pstate

    刚好最近注意到 Linux 6.1 内核中集成了 amd_pstate 模块,这是用来实现动态调节 Ryzen CPU 频率的驱动模块,相较于原先的 acpi_cpufreq 驱动, amd_pstate 支持 CPPC(Collaborative Processor Performance Control) 功能,简单来说,CPPC 可以根据系统对性能、功耗的需求,调节 CPU 的工作频率。

    支持 CPPC 的 CPU driver 需要跟合适的 CPU scaling governor 配合使用。后者是 Linux 系统中用来调节 CPU 频率的软件,不同的 gorvernor 实现了不同的 CPU 频率调整算法,跟 CPPC 最搭配的是下面两个 gorvernor:

    • ondemand:基于当前工作负载动态调节 CPU 频率
    • schedutil:基于调度器的反馈动态调节 CPU 频率

    这两种 gorvernor 都能根据操作系统的需要动态降低或提升 CPU 的工作频率,从而实现比较理想节能效果。

    对于运行 6.1 版本或者更新内核的 Linux ,可以参考这个链接启用 amd_pstate 驱动。

    检测 amd_pstate 生效的方式也比较简单,推荐安装 cpupower

    analyzing CPU 14:
      driver: amd-pstate
      CPUs which run at the same hardware frequency: 14
      CPUs which need to have their frequency coordinated by software: 14
      maximum transition latency: 20.0 us
      hardware limits: 400 MHz - 1.90 GHz
      available cpufreq governors: conservative ondemand userspace powersave performance schedutil
      current policy: frequency should be within 400 MHz and 1.90 GHz.
                      The governor "ondemand" may decide which speed to use
                      within this range.
      current CPU frequency: Unable to call hardware
      current CPU frequency: 1.11 GHz (asserted by call to kernel)
      boost state support:
        Supported: yes
        Active: no
        AMD PSTATE Highest Performance: 166. Maximum Frequency: 4.51 GHz.
        AMD PSTATE Nominal Performance: 70. Nominal Frequency: 1.90 GHz.
        AMD PSTATE Lowest Non-linear Performance: 41. Lowest Non-linear Frequency: 1.11 GHz.
        AMD PSTATE Lowest Performance: 15. Lowest Frequency: 400 MHz.
    

    对于笔记本来说,更常见的需求是根据电源状态自动设置性能偏好,这里推荐使用 TLP,为了方便使用,我还安装了 tlpui。TLP 允许我们配置电脑在不同电源状态的 CPU 调节参数:

    • gorvernor
    • 最低频率、最高频率
    • 自动超频开关

    不过 TLP 的自动超频开关有些死板,即使是出门在外使用电池的场景,我也希望偶尔开启 Boost 提高一下 IDE 分析代码的速度。解决这个问题很简单,有两个方法:

    1. 手动按需执行开关 CPU Boost 的命令
    2. 安装 auto-cpureq,这个软件会在后台监听当前的工作负载,会在必要的时候开关 Boost

    经过一段时间的观察与调试,为了尽量减少风扇噪音、提高电池续航,我的笔记本(HP EliteBook 845 G8 / Ryzen 5800U)配置如下:

    • 外部电源:schedutil gorvernor,启用自动超频,限定最低频率在标称频率的 68%(大概 1.1GHz)
    • 内置电池:ondemand gorvernor, 配合 auto-cpufreq 动态调整超频开关

    实际续航测试

    目前的电池状况,标称容量 45wh,电池健康度 76%,屏幕亮度 30% ~ 35%。工作时会使用的软件包括:

    • Webpack Dev Server
    • WebStorm(180kloc TypeScript 项目)
    • Vivaldi 浏览器(通常控制在 30 个标签以内)
    • Firefox 浏览器(通常控制在 3 个标签以内)
    • 飞书 Linux 客户端
    • Telegram

    acpi_cpufreq

    在 acpi_cprfreq 驱动下,我的笔记本电脑的最低运行频率是 1.9 GHz,最高可以达到 4.1 GHz,下面是我记录的两次续航时长。

    roundstart timeend timetime to 10%
    12023-02-06 13:322023-02-06 16:413:10
    22023-02-13 14:112023-02-13 17:353:24

    amd_pstate

    在 amd_pstate 驱动下,最低运行频率可以到 400 MHz,通常会在 900 MHz 徘徊,最高可以达到 4.1 GHz。

    roundstart timeend timetime to 10%
    12023-02-19 10:1514:474:32
    22023-02-20 9:3714:304:53
    32023-03-06 13:3117:314:00

    在 IDE 的使用体验上没有明显区别,小项目依然很流畅,巨型项目该卡的操作还是卡,但是续航的提升非常明显,至少出门重度办公一下午没有续航焦虑了。

    如何进一步改善续航?

    关于这点,我建议你看看 极客湾的观点

    • 尽量减少 Boost 时长
    • 减少 CPU 以外硬件的功耗

    普通消费者几乎没法做硬件上的改进(最多禁用独显以提高续航),只能从减少 Boost 时长上入手,毕竟是否开启 Boost、需要多长时间的 Boost,这些参数是可以通过软件调节的,上面提到的 auto-cpufreq 就是干这件事的,这个软件是用 python 编写,除了可以通过配置文件来设置之外,自己也可以根据实际体验和偏好来调节相关算法。

  • 如何解决米家设备在透明代理下无法联网的问题

    我在家里的一台旧笔记本上部署了透明代理服务,让连上家里网络的设备都能赛博漫游到国外,不过最近,在我的透明代理网络下,米家设备全部没法联网。我的透明代理工作机制如下:

    OpenWRT 强制启用 DHCP,给米家设备设置特定的 IP 地址,并把米家设备的网关设置为主路由;其他设备的网关设置为 OpenWRT。

    OpenWRT 会把所有需要转发(FORWARD,即目标地址非 OpenWRT 本身)的请求发送给透明代理端口(localhost:12345),接着运行在 OpenWRT 上的 v2ray 会对来自 12345 端口的请求分流,国内请求直接发送,国外请求通过代理协议发送到服务端。

    经过一番排查后,我发现在最近的一次主路由固件升级过后,OpenWRT 强制启动 DHCP 失效了,米家设备的网关被主路由设置成了 OpenWRT 。米家设备需要请求 https://:Mijia Cloud。而 Mijia Cloud 的 IP 地址是米家设备通过其他接口获取的,无法通过正常的 DNS 解析。这时,就引发了 v2ray 的一个问题:v2ray 在分流时会嗅探请求的域名以及域名解析后的 IP 地址,帮助判断请求是否需要被代理。因为 Mijia Cloud 无法被解析,导致嗅探功能出错,v2ray 无法进一步处理请求,导致请求被丢弃

    知道了问题的成因,解决方法就很简单,通过 OpenWRT 上的 iptables 分流,让来自米家设备的请求绕过代理:

    iptables -t mangle -A V2RAY -s 192.168.68.<mijia device ip> -j RETURN

    但是这样做,米家设备还是无法联网,通过 tcpdump 发现米家设备只能发送请求,无法接收响应。

    又是一番搜索,怀疑是一些路由器会校验请求来源设备 IP 跟数据包中来源 IP 的一致性,米家设备请求被 OpenWRT 转发到主路由网关,导致来源设备 IP 跟数据包中的来源 IP 不一致,最终请求被拦截在了主路由处。要解决这个问题,得在 OpenWRT 对应的网络接口上启用「动态 IP 伪装」,说白了就是 NAT 。

    其他设备也是被 OpenWRT 转发到主路由的,为什么它们没有出现这种问题呢?这时就需要进一步了解 Linux 的网络原理了:

    所有发往网关的请求应该都需要转发(FORWARD,因为请求的目标 IP 不是网关本身),但是所有基于这篇透明代理白话文设置的透明代理中,转发流量都被 iptables 发到了 12345 端口,变成了入站请求(INPUT),经过代理软件处理后,作为出站请求(OUTPUT)发出,这些流量就不再被认为是转发流量了,在主路由看来,这些被 v2ray 处理过的流量来源请求都是 OpenWRT ,所以不会触发来源请求校验失败。而被 iptables 分流的米家设备请求,从主路由看来,都是由 OpenWRT 发出但是来自米家设备 IP 的,导致校验失败。

    上面的根因分析完全是我半吊子的推测,可能不够准确、专业,但是启用 OpenWRT 的「动态 IP 伪装」之后,确实解决了米家设备无法联网的问题。


    参考链接

  • 给小新 Pad Pro 2021 刷入 GSI 镜像

    This entry is part 2 of 3 in the series 小新 Pad Pro 2021

    上回书说道,我成功解锁了小新 Pad Pro 2021,但解锁不是最终目的,让 Pad 用上不那么拉胯的原生安卓才算成功。

    准备工作

    • android-platform-tools
    • 一台已经解锁了 bootloader 的小新 Pad
      • 需要已经升级到 ZUI 14,否则自动旋转会有故障
    • 一个心仪的 GSI 镜像,你可以在这里挑选,我选择的是带有完整 GApps 的 LineageOS 19 GSI 镜像。
    • 原厂固件中解压得到的 vbmeta.img 跟 boot.img
    • 用来启用自动亮度调节的 Magisk 模块

    开搞

    下面的内容主要参考这篇帖子

    首先进入平板系统,启用开发者模式,允许 adb 调试,然后通过 USB 连接到电脑。接着在电脑上执行下面的命令:

    $ adb reboot bootloader
    $ fastboot --disable-verity --disable-verification flash vbmeta vbmeta.img
    $ fastboot reboot fastboot
    $ fastboot flash system your-gsi-system.img

    继续通过平板上的音量键,进入 Recovery 模式,然后选择清除数据(工厂模式重置),最后重启设备。

    第一次启动可能会比较慢,如果发现卡在联想 Logo 页面超过了 3 分钟了,可以长按电源键重启设备,一次不行,就多试几次,这种情况通常只会出现在第一次启动系统。

    提高使用体验

    在 LineageOS 19 中,以往小新 Pad Pro GSI 系统中会遇到的自动旋转失效问题已经不存在了。但是原生安卓缺少国产 ROM 的“平行视界”功能,运行不适配横屏模式的应用的体验跟 iPad OS 一样,会强制竖屏。所以还是得安装一个旋转管理器,强制部分应用横屏展示得忍受一下 UI 错位 ,我用的是这个 Xposed 模块 —— 自由屏幕旋转

    另一个提高不适配横屏应用使用体验的方法就是安装 米窗 ,可以用来替代 ZUI 自带的小窗功能,据说把它设置为系统应用体验会更好,但是因为 GSI 已经不会随便杀后台了,所以我也没有对它做特别地处理。

    自动亮度调节功能需要刷入启用自动亮度调节的 Magisk 模块,默认的自动亮度会偏暗,但是 Android 12 有自适应亮度调节功能,会根据用户手动调节亮度条的习惯调整自动亮度的明暗,经过几天体验下来,自动亮度调节功能基本正常。

    原生系统的后台管理机制比较宽松,为了能让垃圾应用退出后老实一些,我选择用 scene4 的“应用偏见”自动冻结垃圾国产应用(例如,淘宝、京东)。

    至于快充,由于我的手机充电速度是 Pad 的 6 倍,实在很难感受到是否存在快充变慢的情况。至少系统界面会在使用原装充电器的时候显示 “Charging Rapidly”的文字。

    关于续航,Lineage OS 系统设置中有一个默认启用的 Screen Saver 选项,这是一个类似“常亮显示”的功能,会在屏幕熄灭后在屏幕上显示一个时钟。小新 Pad Pro 虽然使用的是 A 屏,但是硬件设计上可能压根不支持“常量显示”,导致屏幕耗电量剧增。实测关掉 Screen Saver 后,待机续航可以提升一倍(从一天不到提升到两天),而且充电速度也会有明显的提升。

  • 不靠官方,自己动手解锁小新 Pad Pro

    This entry is part 1 of 3 in the series 小新 Pad Pro 2021

    联想小新 Pad 的 官方解锁页面下线了,客服也不回邮件,为了摆脱疯狂杀后台的 ZUI,我决定尝试自己动手为小新 Pad Pro 2021 解锁,刷入第三方 ROM。

    本文内容主要参考这篇帖子编写,并在原帖基础上补充了一些避免实操踩坑的细节。这个文章的方法对于小新 Pad 2022 可能同样有效?

    准备工作

    • 基础的计算机命令行操作能力
    • 认识 16 进制
    • Windows 电脑
    • 你的小新 Pad 的序列号,关机后按住音量 – 和电源键开机,进入 bootloader 模式后就可以看见序列号
    • 高通刷机工具 QPST
    • 小新 Pad Pro 2021(Lenovo P11 TB-J716F)原厂固件
    • android-platform-tool 这个都不知道在哪里下载还是建议不要刷机了
    • 一个二进制文件编辑器
    • 一个用来解锁 Bootloader 的 sn.img 文件,这个文件对应的设备序列号是 HAHAHAHA

    开搞

    1. 下载并安装 QPST 工具,也请一并安装附带的驱动程序。安装完成后从开始菜单找到 QFIL 工具并启动
    2. 解压原厂固件到文件夹,请确保文件夹的路径没有空格、中文等特殊字符
    3. 在 QFIL 选择 flat build 选项,选中刚刚解压出来的 prog_firehose_ddr.elf 作为 Programmer 文件
    4. 将 Pad 关机,等到完全息屏后按住音量 + ,再将 Pad 通过 USB 连接到电脑上,这时 Pad 会进入 EDL 模式。EDL 模式跟 fastboot 有一个很大的不同,如果一段时间内没有操作,EDL 模式会超时,这时 QFIL 工具虽然还能检测到连接上的设备,但是对设备的操作都会失败。
    5. 打开 QFIL 工具的 Tools 菜单,选择 Partition Manager,等待几秒,会弹出一个新的窗口
    6. 新窗口中选择 fpinfo 分区,右键点击,选择 Manage Partition
    7. 点击 Read Data,QFIL 从设备上下载数据并存放到  AppData\Roaming\Qualcomm\QFIL\COMPORT_xxx
    8. 备份刚刚下载的文件,文件名包含数据分区的地址 0x2208,这个文件里面存储了你设备的序列号,请务必小心保管
    9. 使用二进制编辑器编辑上述文件的一个副本,把文件开头的序列号替换为 HAHAHAHA
    10. 回到 QFIL,点击 Load Image 把刚刚编辑后的文件上传到设备上
    11. 接着用同样的办法下载 frp 分区文件,文件名包含数据分区的地址 0x2188,也请妥善备份这个文件
    12. 使用二进制编辑器编辑上述文件的一个副本,把文件末尾的最后一个字节从 00 改为 01,如果你的文件末尾已经是 01 了,可以直接跳转到第 14 步
    13. 回到 QFIL,点击 Load Image 把刚刚替换的文件上传到设备上
    14. 点击 Close,等待 EDL 模式重置完成后,拔出线缆
    15. 按住电源键跟音量 -,开机后进入 bootloader 模式,切记,此时千万不要进入 Android 系统,否则刚刚进行的修改会被还原。
    16. 进入 bootloader 后,屏幕上显示的序列号应该为 HAHAHAHA。如果发现修改没有生效,请重新执行上面 4 ~ 14 步的操作,注意自己的操作是否有遗漏。
    17. 执行命令: fastboot flash unlock sn.img
    18. 执行命令: fastboot oem unlock-go
    19. 恭喜你,你的设备已经成功解锁 bootloader
    20. 最后收尾,参考之前的步骤,使用 QFIL 工具还原 0x2208 以及 0x2188 分区。
  • 一款人体工学键盘,但是免费

    对于数字时代的打工人来说,人体工程学键盘更像是劳保用品,可以在一定程度上缓解长期使用键盘带来的手部不适。这篇文章中,我将向你介绍如何把手边的键盘变得更加“符合人体工学”。

    不标准的指法

    标准指法其实很不科学,按照标准指法摆放双手会让手腕呈现出一种非常怪异的姿势,我个人建议不要使用标准指法,除非你在使用类似 XBows 等专门为标准指法优化的人体工程学键盘。

    标准指法示例
    配合标准指法的手掌摆放示意

    下面的图片可能是很多人目前正在使用的指法,使用这种指法已经比标准指法要“人体工程学”很多了,至少在按键的时候不用扭曲左手手腕:

    每根手指负责按一种颜色的按键,食指分别放在 F 跟 J 上

    总之,我建议你不要迷信标准指法,可以根据自身条件在标准指法上改造,避免以扭曲的姿势使用键盘。

    用大拇指分担小拇指的功能

    如果你仔细观察,你会发现键盘的并非是按照字母区的中心对称排布的,这意味着我们的右手小拇指需要承担更多的功能,对于程序员来说更是如此,在代码中经常会用到的各种符号也更加集中在右手小拇指区:

    常见的 87 键键盘,很多笔记本电脑采用类似的布局

    同样的,如果我们经常要用到位于数字区的符号,也得让小拇指配合按住 Shift 键帮助输入。这样看来,力气最小的小拇指除了需要托住手机之外,还得频繁地用来打字,是时候给小拇指减负了。

    根据我的个人经验,大拇指力气很大,但用处很少(只用来痛快地敲击空格键),很适合用来为小拇指分担工作。如果你并非天赋异禀,那么你的大拇指能够轻松按到的按键应该是 alt 键跟空格键。空格键的主要用途是输入单个空格,或者把输入法的候选词提交到输入框中。alt 键通常用作修饰键,只在按组合键的时候才会用到,不过据我观察,大多数人只会用到一个 alt 键,另一个 alt 键往往常年吃灰。

    使用 Kmonad 打造免费人体工程学键盘

    把这两个按键利用起来,作为符号输入的组合键,就可以有效地把小拇指的工作分给有力的大拇指。想要完美地实现这个功能,通常需要依赖具有可编程功能的键盘。Kmonad 就是一款用来给“任意键盘”编程的开源软件,它支持 Windows、Linux、macOS 这些主流的操作系统,允许用户使用类似 Lisp 的配置语法给自己的键盘编程。你可以查看 Kmonad 的项目说明来学习如何使用这款软件,在这里我会分享我的“人体工程学”键盘配置思路。

    Kmonad 中最常用的功能是“层”,每一层下的键盘按键功能都可以自定义,每层中可以设置一些按键用来切换键盘当前所在层,只要你的键盘按键足够多,你可以为创建无限的按键层。要实现上面描述的字母区输入符号的功能,就需要单独创建一个符号层,然后通过空格键或者 alt 键切换。

    对于我个人而言,我几乎用不到长按空格键,所以我就把“按住空格超过 200 毫秒”作为临时切换到符号层的按键操作。

    按住空格键激活的符号输入层

    我的符号层除了安排了符号之外,还安排了一些功能键(回车键、退格键以及方向键)跟按键宏(在 F 键位上的 =>),主要是为了减少右手小拇指的移动距离,避免扭曲手腕。可以看到就算把方向键也挪到了字母区,还是留了不少空位,之后可以根据自己的习惯再把空位填满。

    其实除了空格键很少会被长按之外,数字区的按键也很少被长按,本着物尽其用的原则,我把长按数字区超过 300 ms 设置成了的对应的符号,这样既可以避免使用小拇指按住 Shift 键,又可以保留输入符号的按键位置习惯。

    添加快捷键层

    为了提高一些软件的使用效率,我们或多或少都会用到一些快捷键,但是一些快捷键的键位设计可能跟我们的生理结构相违背(你可以试试用一只手按 ctrl+shift+t)。这些快捷键在提高效率的同时,也在折磨我们的手指关节,因此,一些具有人体工程学结构的键盘,会把修饰键放在离大拇指比较近位置,以减少修饰键到字母区的平均距离,避免移动手掌造成手指关节的扭曲。

    上面提到,在普通的键盘上,空格键跟 alt 键都是大拇指容易触及的常用按键,我已经把长按空格键分配给了符号层,所以就用右侧的 alt 键作为新的“快捷键层”的切换入口。

    按住右侧 alt 键激活的快捷键层

    其他的小技巧

    我还搜集了一些其他的“键盘小妙招”,同样可以帮助你减少按键带来的手掌移动,保护你的手腕,这些功能经过我的验证都可以通过 Kmonad 实现。

    • 交换 Ctrl 跟 CapsLock
    • Auto Shift,长按字母键输入对应的大写字符,就跟手机上的虚拟键盘一样
    • Shift 粘滞键,单击 Shift 后按下其他按键就可以实现按住 Shift 的组合键输入
    • Tap Dance,给同一个按键设置“单击”、“双击”以及对应击键次数后长按的功能,例如,单击输入 Esc 双击输入 CapsLock、单击长按切换按键层。

    最后,其实我也不太确定按照这篇文章改造的键盘是否真的能够降低手部劳损的速度,至少在我个人的体验上,经过这样的一番改造的确减少了很多需要扭曲手腕的按键场景,对手部的疲劳有一定的缓解作用。如果你正被类似“键盘手” 、“鼠标手”的症状困扰,还是建议先去正规医院检查治疗,这篇文章介绍的方法最多只能作为一个低成本的辅助手段。


    我的 Kmonad 键盘配置

  • 2022 年,我的 Wayland 工作电脑设置

    Wayland 比 Xorg 要快很多,在没有独立显卡的笔记本电脑上对桌面动画性能提升还是很明显的,忍受不了卡顿掉帧的桌面动画,我决定切换到 Wayland 。

    DE

    试用了各种 DE、WM 后,我的最终选择是 KDE,KDE 支持为不同分辨率的屏幕设置不同的 DPI,并且能够清晰地在不同的屏幕上缩放 XWayland 应用,使之适配多个分辨率不同的显示器。

    只有真正去折腾的人才知道,让 Linux 桌面适配多个分辨率差异很大的屏幕有多痛苦,KDE Wayland 能够以最小的代价实现让人满意的效果。

    在 XOrg 下,为了实现为多块屏幕设置不同分数缩放,我使用的是全局设置两倍缩放,然后通过 xrandr 压缩到合适分辨率的做法,这种方式比较消耗性能,但还在可以勉强忍受的范围内。

    Wayland 下的 GNOME 虽然支持为不同显示器设置不用的缩放系数,但是分数缩放的支持比较差,使用 XWayland 渲染的软件会先按照 1 倍渲染,然后被系统强制放大到指定的倍率,其效果可想而知,满脸的马赛克锯齿。

    Wayland 下的 KDE 就厉害多了,可以直接在系统设置中针对不同的屏幕设置分数缩放,而且性能还很不错,最重要的是,KDE 会自动管理那些不支持 Wayland 的软件的缩放系数,最终可以让我们得到非常 Nice 的显示效果。

    左侧是笔记本内置屏幕(1920×1080, 14″,150%)上的 KDE 系统设置,使用原生 Wayland 渲染,右边是外接显示器上(3840×2160, 24″,200%)基于 Chromium 的 Obsidian,使用 XWayland 渲染。

    打工人必备

    飞书 XWayland

    Wayland 下的飞书跟 XOrg 下的使用体验没有太大区别,主要是 Wayland 下共享桌面需要一些额外的设置,可以参考下面的做法:

    1. 启用 Chromium 的一个 flag: enable-webrtc-pipewire-capturer
    2. 安装 xdg-desktop-portal-kde

    这种做法对于其他的基于 Chromium 的软件应该同样使用,其中的原理可以查看这篇文章

    截图与录屏

    截图工具用的是 Flameshot,虽然对多显示器的支持比较早期,但是用的顺手。KDE 自带的 spectacle 能用,但在我的电脑连接外置显示器的时候比较卡,而且不太符合我的使用习惯。

    录屏比较麻烦,我之前用的 SimpeScreenRecorder 并不支持 Wayland,找了一圈发现很多带图形界面的录屏软件在 KDE Wayland 下要么卡顿,要么功能上有 Bug。还有 Sway 用户推荐的各种命令行工具,感觉用起来会很不方便。最终我还是决定用 OBS 来录屏,属于是用牛刀来杀鸡了,但是至少稳定高效。

    输入法

    对于 KDE 用户来说,直接安装 fcitx5 应该就可以开箱即用了,如果发现输入法候选框没有在有些应用中出现,可以参考这里的说明试试。

    开发必备

    JetBrains 系列

    JetBrains 所有基于 Idea 的软件以及 Fleet 目前都只能在 XWayland 下运行,不过就我目前的使用体验来看,没有遇到任何阻断性的问题。

    WebStorm 2022
    Fleet

    KDE 会为 Fleet 设置 1.5 倍缩放(跟我设置的全局缩放一致),但实际上 Fleet 的 UI 库似乎会跟随全局缩放自动调整,所以得手动在 Fleet 中把缩放系数改为 75%,把 KDE 设置的缩放抵消掉。

    终端模拟器

    虽然用的 KDE,但是我没有选择使用 Konsole 作为终端模拟器,在我看来,响应更加迅速、跟 Shell 融和地更好的 kitty 更有吸引力。如果你发现无法在 kitty 窗口中调用 fcitx5,可以参考这里

    设置全局唤起 kitty 的快捷键需要一点 tricks,KDE Wayland 把设置自定义快捷键的设置面板换掉了,需要通过执行 QT_QPA_PLATFORM=xcb systemsettings 找回旧的快捷键设置面板。

  • 工欲善其事,如何利其器?CLI 篇

    工欲善其事,必先利其器,这篇文章将从 CLI 工具这个方面向你介绍“如何提高在 CLI 环境下的工作效率”。

    Shell

    Shell 是一个用来提供与操作系统内核(Kernel)交互的软件。

    常见的 Shell 分为两种:

    • Command Line Interface (CLI) 命令行界面
    • Graphic User Interface (GUI) 图形用户界面

    通常情况下,Shell 主要是指 CLI 程序,常见的 CLI shell 有 Bash、Zsh、Fish、PowerShell、Cmd 等。

    为什么会有 CLI Shell ?

    早期的计算机主机存放在专门的机房中,用户想要操作计算机需要通过终端(Terminal)连接,终端就是计算机的输入输出设备。最早的终端无法显示图像,只能通过屏幕跟键盘展示、输入字符,所以最早的 Shell 软件就以 CLI 的形式问世了。

    随着技术的进步发展,只能用来传输文本的终端设备几乎都被显示器替代了,GUI 取代了 CLI 的在人机交互方面的主要地位。

    CLI 优势

    CLI 最大的优势在于可编程,CLI shell 通常也是一个脚本语言解释器,可以通过编写 Shell 脚本来自动化完成一些复杂、重复的操作,这是 GUI 难以比拟的。

    在 GUI 成为主要人机交互界面的今天,终端模拟器(Terminal Emulator)是我们操作 CLI 的必备工具。一个优秀的终端模拟器通常会提供下面几个功能:

    • 多 Tab 切换
    • 窗口分屏
    • 搜索命令行输出(ScrollBack)
    • 自动识别链接

    这些功能也是提高 CLI 使用效率的必备功能,如果你的终端模拟器不支持这些功能,我推荐你使用下面的这些软件:

    • Windows
      • Windows Terminal
      • ConEmu
    • macOS
      • iTerm2
    • Linux
      • Konsole
      • Kitty

    我非常建议你设置 Tab 切换跟窗口分屏快捷键,这些操作可以极大地提升你使用 CLI 时的工作效率。

    设置一个用户友好的 CLI Shell

    Fish Shell 是一个智能的、用户友好的 Shell 程序。相比 Bash,它有如下优点:

    • 自动补全
    • 简单易学的脚本语法
    • 基于 Man 的智能提示与补全
    • 开箱即用,只要安装上就能够获得生产力的提升

    安装 Fish

    不建议将默认 Shell 修改为 Fish,因为 Fish 不遵循 POSIX Shell 规范,不一定跟其他的程序兼容,更好的做法是将兼容 POSIX 的 Shell 作为默认 Shell,然后在终端模拟器中将默认启动的 Shell 设置为 Fish。

    CLI 好伙伴

    • man CLI 程序说明书
    • bat 文本文件查看工具
    • tldr man 手册太长不看,就看 TLDR
    • fd 文件搜索工具
    • fuck 智能的命令行纠错工具
    • exa 更加友好的 ls 替代品

    进一步提升 Fish 的易用性

    • Fisher Fish 插件管理器
    • fzf fzf 命令行模糊搜索程序
    • z 智能的目录跳转工具
    • starship 高性能的 Shell 提示符

    fzf

    通过 fisher 安装 PatrickF1/fzf.fish

    • ctrl+r 搜索历史
    • ctrl+alt+f 从当前目录开始搜索文件,按 Tab 可以多选

    更多快捷键可以查看 GitHub Readme

    常用快捷键

    function fish_user_key_bindings
        # 使用 Ctrl + F 补全整行
        bind -M insert \cf accept-autosuggestion
        bind \cf accept-autosuggestion
    end
    • alt+. 将上个命令的最后一部分填到当前命令行末尾
    • alt+s 用 sudo 执行上条命令

    更多快捷键请查看文档

    私人订制,打造合适自己的 CLI 工具

    alias 给常用的命令设置别名,方便快速输入。

    funced/funcsave/function function 比 alias 更加完善,可以用来封装更加复杂的操作。

  • 如何使用 nx 缓存构建产物

    This entry is part 3 of 4 in the series Nx Monorepo Experience

    There are only two hard things in Computer Science: cache invalidation and naming things.

    Phil Karlton

    nx 的缓存机制如何工作

    How Caching Works 这篇文章中非常详细地说明了 nx 缓存构建结果的机制:
    nx 会计算当前执行的 target 的 Hash 作为 cache key,在 target 执行完成后把构建输出(包括终端输出、构建结果文件)作为缓存内容存储起来。

    通过配置 project.json 中 target 的 inputs 选项,我们可以调整能够让缓存失效的文件、环境变量,具体的配置方法可以查看这里

    在编写文件 glob 模式的时候,有两个特殊的变量:

    • {projectRoot} :当前项目的根目录
    • {workspaceRoot}:nx 工作区的根目录

    然而不管是在 inputs 还是 outputs 配置中,路径都是相对于 workspace root 的,所以 {workspaceRoot} 变量基本上没啥作用。

    如何为项目添加构建缓存

    缓存失效一直都是计算机领域的一个难题,在配置 nx 构建缓存的时候,我有以下两点建议:

    • inputs 配置应该宁滥毋缺,因为缓存不同步的严重性远大于缓存命中率低
    • outputs 配置必须不多不少,避免无关文件被错误地覆盖或者构建结果缺失

    要做到上面两点需要精确地控制 inputs 跟 outputs 的文件匹配模式,这里推荐几种帮你减少工作量方法:

    在拆分模块需要注意,尽量采用类似 Module Federation 或者 Webpack DLLPlugin 等机制,这种构建方式能够真正实现分模块打包。如果没有采用类似的机制,所有的模块都会在入口模块处被重新处理,所以除了入口模块之外,其他的模块没必要 minify ,这样可以加快打包速度。

    共享缓存执行结果

    nx 缓存默认存储在本地,独乐乐不如众乐乐,通过添加 nx-remotecache-minio,我们可以把 nx 缓存存储在任意与 S3 兼容的对象存储服务器上。如此,只要项目中的任意一位成员甚至 CI 服务器构建过某个模块,其他人都可以跳过构建直接从远程服务器拉取构建结果。

    需要注意的是,nx-remotecache-minio 没有处理访问对象存储超时的情况,所以一旦遇到对象存储服务器不可用的情况,记得及时终止构建,并将 NX_CACHE_MINIO_URL 环境变量设置成一个无法解析的地址,避免构建命令卡住。