问题背景

联想小新 Pro 14 在 Windows 下可以选择 120Hz 刷新率,但 Ubuntu 下只有 60Hz,显示设置中没有 120Hz 选项。

环境

  • 机型:联想小新 Pro 14(XiaoXinPro-14)
  • GPU:Intel Alder Lake-P Iris Xe Graphics(i915 驱动)
  • 面板:CSOT MNE007ZA1-5,2880x1800,eDP
  • 系统:Ubuntu 25.04,内核 6.17

根本原因

面板的 EDID(显示器身份数据)中,120Hz 时序存放在 DisplayID 扩展块里,但这个扩展块的校验和是面板固件出厂就写错的

  • Linux DRM 子系统严格校验 DisplayID 校验和,校验失败直接丢弃整个扩展块,120Hz 模式不可见
  • Windows Intel 驱动对校验和更宽容,所以不受影响

可以用 dmesg / journalctl 确认:

1
journalctl -b -k | grep "DisplayID checksum"

如果看到 DisplayID checksum invalid, remainder is 248,就是这个问题。

修复思路

导出面板原始 EDID → 修正校验和 → 放入固件目录 → 让内核启动时加载修正后的 EDID。

修复步骤

1. 导出 EDID 并计算正确的校验和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
python3 -c "
with open('/sys/class/drm/card1-eDP-1/edid', 'rb') as f:
edid = bytearray(f.read())

# 修正 DisplayID 段校验和(字节 0xFE)
did_sum = sum(edid[0x81:0xFE])
edid[0xFE] = (256 - (did_sum % 256)) % 256

# 修正 EDID 扩展块校验和(字节 0xFF)
ext_sum = sum(edid[0x80:0xFF])
edid[0xFF] = (256 - (ext_sum % 256)) % 256

# 验证
assert sum(edid[0x81:0xFF]) % 256 == 0, 'DisplayID checksum failed'
assert sum(edid[0x80:0x100]) % 256 == 0, 'Extension block checksum failed'

with open('/tmp/edid_fixed.bin', 'wb') as f:
f.write(edid)
print('Fixed EDID saved to /tmp/edid_fixed.bin')
"

注意:不要直接用网上的 sed 's/f098$/f990/' 命令,那是针对特定版本面板的,不同批次面板 EDID 字节可能不同,必须用计算的方式得出正确校验和。

2. 安装修复后的 EDID

1
2
sudo mkdir -p /usr/lib/firmware/edid/
sudo cp /tmp/edid_fixed.bin /usr/lib/firmware/edid/edid.bin

3. 将 EDID 文件打包进 initramfs

i915 驱动在 initramfs 阶段就加载,此时根文件系统还没挂载,所以固件必须打包进 initramfs。

在 Ubuntu 25.04 上,initramfs-tools 的 hooks 机制可能不生效,直接追加 cpio 归档:

1
2
3
4
5
6
7
8
sudo bash -c '
TMPDIR=$(mktemp -d)
mkdir -p "$TMPDIR/usr/lib/firmware/edid"
cp /usr/lib/firmware/edid/edid.bin "$TMPDIR/usr/lib/firmware/edid/edid.bin"
cd "$TMPDIR"
find usr -print0 | cpio --null --create --format=newc >> /boot/initrd.img-$(uname -r)
rm -rf "$TMPDIR"
'

注意:固件路径是 usr/lib/firmware/(不是 lib/firmware/),Ubuntu 25.04 的 initramfs 内部使用 usr/lib/firmware/ 路径。

4. 添加内核启动参数

编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX_DEFAULT 中添加:

1
drm.edid_firmware=eDP-1:edid/edid.bin

例如:

1
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash drm.edid_firmware=eDP-1:edid/edid.bin"

然后更新 GRUB:

1
sudo update-grub

5. 重启并验证

重启后在「设置 → 显示器」中应该能看到 120Hz 选项。验证命令:

1
2
xrandr | grep eDP
# 应显示 119.99Hz

回滚方法

如果出问题,在 GRUB 菜单按 e,删掉 drm.edid_firmware=eDP-1:edid/edid.bin,按 Ctrl+X 启动即可恢复。

备注

  • Linux 6.19 内核已合并针对此面板的补丁(忽略错误校验和),届时升级内核后不再需要此 workaround
  • 此方法适用于所有因 DisplayID 校验和错误导致高刷不可用的 eDP 面板,不限于联想小新
  • eDP 连接器名称可能因机器不同而不同(eDP-1 / eDP-2),用 ls /sys/class/drm/ | grep eDP 确认

问题

GNOME 顶部栏右侧内容太多(网速监控 + 托盘图标 + 系统图标),和中间的时钟重叠。

原因

GNOME 顶部栏分三个区域:左、中(时钟)、右。默认扩展都挤在右边。

涉及的扩展:

  • netspeedsimplified - 网速/流量监控
  • ubuntu-appindicators - 应用托盘图标(微信、QQ 等)

解决方案

将部分扩展从右侧移到左侧,利用左侧的空闲空间。

1. 网速监控移到左边

1
dconf write /org/gnome/shell/extensions/netspeedsimplified/wpos 1

wpos 可选值:0 = 右,1 = 左,2 = 中

2. 托盘图标移到左边

1
dconf write /org/gnome/shell/extensions/appindicator/tray-pos "'left'"

可选值:'left''right'

其他可选优化

1
2
3
4
5
# 缩小托盘图标间距(默认 12)
dconf write /org/gnome/shell/extensions/appindicator/icon-spacing 6

# 网速监控竖排显示,节省横向空间
dconf write /org/gnome/shell/extensions/netspeedsimplified/isvertical true

恢复默认

1
2
dconf write /org/gnome/shell/extensions/netspeedsimplified/wpos 0
dconf write /org/gnome/shell/extensions/appindicator/tray-pos "'right'"

设置修改后即时生效,无需重启。也可以在”扩展”应用中点击对应扩展的齿轮图标进行图形化配置。

sudo免密

1
2
3
4
sudo visudo

# 文件末尾添加
YOUR_USERNAME ALL=(ALL) NOPASSWD: ALL

pkexec免密

要取消 pkexec 命令在 Linux 系统中的密码输入限制(实现免密执行特权命令),需要配置 PolicyKit 规则。这通常通过在 /etc/polkit-1/rules.d/ 目录中创建一个 .rules 文件来实现,允许特定用户免密执行特定命令

1
2
3
4
5
6
7
8
9
10
sudo nano /etc/polkit-1/rules.d/nopasswd.rules

# 添加如下代码
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.policykit.exec" && subject.user == "YOUR_USERNAME") {
return polkit.Result.YES;
}
});


问题背景

我在 Ubuntu 25 上想实现这件事:

  1. 截图后自动保存到文件
  2. 同时复制到剪贴板,方便直接粘贴

命令行手动执行 flameshot gui -p ~/Pictures/Screenshots -c 时可用,但绑定快捷键后执行却报错:

Flameshot Error: Unable to capture screen

另外,Ubuntu 25 默认 Wayland,会话里基本不再走 X11 方案

环境

  • 系统:Ubuntu 25
  • 显示会话:Wayland
  • 工具:Flameshot 12.1.0

结论

核心不是快捷键本身,而是 Wayland 截图通道(portal)和启动方式。

最终稳定方案:

  • 不使用 QT_QPA_PLATFORM=xcb
  • 使用脚本封装 Flameshot 命令
  • 快捷键绑定脚本路径
  • 重启 xdg-desktop-portal 相关服务

解决步骤

1. 安装/确认依赖

1
sudo apt install -y flameshot xdg-desktop-portal xdg-desktop-portal-gnome

2. 重启 portal 服务

1
2
pkill -x flameshot || true
systemctl --user restart xdg-desktop-portal xdg-desktop-portal-gnome

3. 创建截图脚本(Wayland)

1
2
3
4
5
6
mkdir -p ~/Pictures/Screenshots ~/bin
printf '%s\n' \
'#!/usr/bin/env bash' \
'/usr/bin/flameshot gui -p "$HOME/Pictures/Screenshots" -c' \
> ~/bin/flameshot-shot.sh
chmod +x ~/bin/flameshot-shot.sh

4. 先在终端验证脚本

1
~/bin/flameshot-shot.sh

如果这一步能正常截图,说明后端链路已通。

5. 绑定快捷键

设置 -> 键盘 -> 自定义快捷键 新增:

  • 名称:Flameshot
  • 命令:/home/zjz/bin/flameshot-shot.sh
  • 快捷键:Ctrl+Shift+Alt+S

今天需要将本地电脑A的虚拟机环境配置到电脑B上边,但是虚拟机很大,需要200G,在没有合适的硬盘下,使用网线进行传输

  1. 关闭电脑A和电脑B的防火墙

  2. 使用网线连接电脑A和电脑B(电脑B的WiFi关掉,只保留以太网)

  3. 配置共享文件夹

    1. 电脑C盘或者其它盘->属性->共享->高级共享->勾选共享此文件夹->点击权限->选择完全控制

      image-20260205163457476

    2. 配置网线传输速率,电脑B打开控制面板->网络与共享中心->更改适配器设置->双击以太网适配器->点击属性->点配置->点击高级->找到 连接速度和双工模式->配置为1G。注意,电脑B不要连接WiFi,否则速率可能会慢

      image-20260205163912560

    3. 然后电脑A也要配置,只不过电脑A选择 自动检测

  4. 传输速率配置完以后,我们还需要配置IP地址

    1. 电脑A 打开控制面板->网络与共享中心->更改适配器设置->双击以太网适配器->点击属性->Internet 协议版本 4 (TCP/IPv4),然后进行如下配置

      image-20260205164225233

      只需要配置IP地址和子网掩码,其它不需要,留空就行,这个主要是为了配置同一网段,最后保存即可

    2. 电脑B也需要配置IP地址,地址为192.168.10.2,子网掩码也是255.255.255.0,然后其它配置不变,保存即可

    3. 看一下两边能不能互相ping通,能ping通就下一步,ping不通就关闭防火墙

  5. 传输配置,为了以防万一,电脑A和电脑B都进行如下配置

    1. 打开控制面板->网络与共享中心->更改高级共享设置->打开公用文件夹共享和关闭密码保护共享

      image-20260205164828108

​ 如果电脑是win10,也差不多,只是名字不太一样,看着勾选就行

  1. 然后就可以查找电脑B了,电脑B之前我们已经共享了C盘或其它盘

    1. 电脑A 输入快捷键 win+r,输入 \\192.168.10.2

    2. 如果还是需要输入密码

      1. 用户名:192.168.10.2\用户名
      2. 密码:电脑B的登录密码
    3. 输入以后,资源管理中心的网络出现这样就表示成功了

      image-20260205170542613

    4. 然后将电脑A需要传输到电脑B的数据拖拽或者复制就对应的电脑B位置就好了

最后,如果是克隆虚拟机到新电脑,需要确保vmware版本相同,然后拷贝下面三个文件到新电脑即可

image-20260205170542613

ctypes封装C++接口给Python使用

一般步骤

  1. 设计 C API 边界,新增 *.h/*.cpp,用 extern "C" 暴露纯 C 接口。
  2. C API 只暴露基础类型与不透明句柄,避免直接暴露 C++ 类型。
  3. 约定错误处理,统一返回错误码,必要时提供 get_last_error
  4. 约定内存管理,C 层分配的内存由 C 层提供 free 释放函数。
  5. 生成动态库,Linux/macOS 需要 -fPIC-shared
  6. Python 侧用 ctypes 加载库,并为每个函数配置 argtypes/restype

最小示例
目标:封装一个 C++ Calculator,支持 add、返回字符串、回调通知。

文件 1:demo_c_api.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#ifndef DEMO_C_API_H
#define DEMO_C_API_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _WIN32
#ifdef DEMO_C_EXPORTS
#define DEMO_C_API __declspec(dllexport)
#else
#define DEMO_C_API __declspec(dllimport)
#endif
#else
#define DEMO_C_API __attribute__((visibility("default")))
#endif

typedef void* DemoHandle;
typedef void (*DemoMessageCallback)(const char* message, void* user_data);

DEMO_C_API DemoHandle demo_create(void);
DEMO_C_API void demo_destroy(DemoHandle handle);
DEMO_C_API int demo_add(DemoHandle handle, int a, int b);
DEMO_C_API char* demo_get_name(DemoHandle handle);
DEMO_C_API void demo_free_string(char* str);
DEMO_C_API void demo_set_callback(
DemoHandle handle,
DemoMessageCallback callback,
void* user_data
);

#ifdef __cplusplus
}
#endif

#endif

文件 2:demo_c_api.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "demo_c_api.h"

#include <cstdlib>
#include <cstring>
#include <string>

class Calculator {
public:
int add(int a, int b) {
return a + b;
}
};

static char* copy_string(const std::string& text) {
char* result = static_cast<char*>(std::malloc(text.size() + 1));
if (result) {
std::memcpy(result, text.c_str(), text.size() + 1);
}
return result;
}

struct DemoWrapper {
Calculator impl;
DemoMessageCallback callback = nullptr;
void* user_data = nullptr;
};

DemoHandle demo_create(void) {
return new DemoWrapper();
}

void demo_destroy(DemoHandle handle) {
if (!handle) {
return;
}
auto* wrapper = static_cast<DemoWrapper*>(handle);
delete wrapper;
}

int demo_add(DemoHandle handle, int a, int b) {
if (!handle) {
return 0;
}
auto* wrapper = static_cast<DemoWrapper*>(handle);
int result = wrapper->impl.add(a, b);
if (wrapper->callback) {
std::string message = "add called";
wrapper->callback(message.c_str(), wrapper->user_data);
}
return result;
}

char* demo_get_name(DemoHandle handle) {
if (!handle) {
return nullptr;
}
return copy_string("Calculator");
}

void demo_free_string(char* str) {
if (str) {
std::free(str);
}
}

void demo_set_callback(
DemoHandle handle,
DemoMessageCallback callback,
void* user_data
) {
if (!handle) {
return;
}
auto* wrapper = static_cast<DemoWrapper*>(handle);
wrapper->callback = callback;
wrapper->user_data = user_data;
}

编译动态库(Linux 示例)

1
g++ -std=c++17 -fPIC -shared demo_c_api.cpp -o libdemo.so

文件 3:demo.py(直接 ctypes 调用 + 再封装一层,仅提供接口)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import ctypes
from pathlib import Path

_CALLBACK = ctypes.CFUNCTYPE(None, ctypes.c_char_p, ctypes.c_void_p)

class Calculator:
def __init__(self):
lib_path = (Path(__file__).parent / "libdemo.so").resolve()
self._lib = ctypes.CDLL(str(lib_path))
self._lib.demo_create.argtypes = []
self._lib.demo_create.restype = ctypes.c_void_p
self._lib.demo_destroy.argtypes = [ctypes.c_void_p]
self._lib.demo_destroy.restype = None
self._lib.demo_add.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
self._lib.demo_add.restype = ctypes.c_int
self._lib.demo_get_name.argtypes = [ctypes.c_void_p]
self._lib.demo_get_name.restype = ctypes.c_void_p
self._lib.demo_free_string.argtypes = [ctypes.c_void_p]
self._lib.demo_free_string.restype = None
self._lib.demo_set_callback.argtypes = [
ctypes.c_void_p,
_CALLBACK,
ctypes.c_void_p,
]
self._lib.demo_set_callback.restype = None
self._handle = self._lib.demo_create()
self._callback = None

def add(self, a: int, b: int) -> int:
if not self._handle:
raise RuntimeError("Calculator 未初始化")
return int(self._lib.demo_add(self._handle, a, b))

def get_name(self) -> str:
if not self._handle:
raise RuntimeError("Calculator 未初始化")
ptr = self._lib.demo_get_name(self._handle)
if not ptr:
return ""
raw = ctypes.cast(ptr, ctypes.c_char_p).value or b""
self._lib.demo_free_string(ptr)
return raw.decode("utf-8", errors="ignore")

def set_callback(self, callback) -> None:
if not self._handle:
raise RuntimeError("Calculator 未初始化")
if callback is None:
raise RuntimeError("回调不能为空")

def _bridge(message_ptr, user_data):
text = message_ptr.decode("utf-8", errors="ignore") if message_ptr else ""
callback(text)

self._callback = _CALLBACK(_bridge)
self._lib.demo_set_callback(self._handle, self._callback, None)

def close(self) -> None:
if self._handle:
self._lib.demo_destroy(self._handle)
self._handle = None
self._callback = None

文件 4:test.py(使用 demo.py 提供的接口)

1
2
3
4
5
6
7
8
9
10
from demo import Calculator

def on_message(text: str) -> None:
print("callback:", text)

calc = Calculator()
print("name:", calc.get_name())
calc.set_callback(on_message)
print("1 + 2 =", calc.add(1, 2))
calc.close()

一、交换机

  • 工作层级:数据链路层(OSI第二层)
  • 核心功能:基于MAC地址在同一网络内转发数据帧
  • 特点
    • 用于扩展网络端口数量,实现多设备有线连接
    • 所有端口平等,不支持网络地址转换
    • 即插即用,无需配置即可工作
    • 不分配IP地址,不管理网络流量
  • 可以简单理解为做数据转发操作

二、路由器

  • 工作层级:网络层(OSI第三层)
  • 核心功能:基于IP地址在不同网络间路由数据包
  • 特点
    • 连接内网与互联网,是网络的出口网关
    • 执行NAT(网络地址转换),将内网IP转换为公网IP
    • 提供DHCP服务,为内网设备自动分配IP地址
    • 内置防火墙,提供基本网络安全防护
    • 通常集成WiFi功能(无线路由器)
  • 像小区的邮政局,负责处理对内和对外的信件收发

三、路由器接入

WiFi:现代路由器通常集成WiFi功能,但路由器本身的核心是路由和NAT,路由器能够提供网络服务,必须通过WAN口连接上行网络(如光猫、入户网线)

特性 网线接入 无线接入(WiFi)
速度 通常更快 受环境影响
稳定性 极高,不受干扰 受距离、障碍物、干扰影响
延迟 极低 较高
安全性 物理隔离更安全 需加密协议保护
适用场景 台式机、服务器、游戏主机 手机、笔记本、物联网设备

四、网络扩展

4.1、路由器桥接

当主路由器信号无法覆盖全部区域时,可通过桥接扩展网络

4.1.1、有线桥接(推荐)

配置方式:路由器B通过网线连接路由器A的LAN口
工作模式:将路由器B设置为AP模式(接入点模式)
优点

  • 性能无损,稳定性极高
  • 设备在同一局域网,互访方便

配置步骤

  1. 用网线连接路由器A的LAN口和路由器B的WAN口(或LAN口,需关闭DHCP)
  2. 登录路由器B管理界面,关闭DHCP功能
  3. 设置路由器B的LAN口IP为与路由器A同网段的不同地址
  4. 设置路由器B的WiFi名称和密码(可与路由器A相同或不同)
4.1.2、 无线桥接(中继模式)

配置方式:路由器B无线连接路由器A的信号
工作模式:WDS桥接或无线中继模式
优点:无需布线,灵活方便
缺点

  • 带宽减半(需接收和转发)
  • 稳定性受无线环境影响
  • 不同品牌兼容性可能有问题

配置步骤

  1. 将路由器B放在能稳定接收路由器A信号的位置
  2. 登录路由器B管理界面,开启WDS/中继功能
  3. 扫描并选择路由器A的WiFi信号,输入密码
  4. 设置路由器B的WiFi信息

4.2、电脑桥接

4.2.1、电脑网络共享

当台式机无法连接WiFi且无法连接主路由器时,可通过另一台已联网的电脑共享网络。

适用场景

  • 临时网络扩展,无多余路由器
  • 网络故障应急方案
  • 台式机无WiFi功能且无法布线

配置步骤

  1. 物理连接:用网线连接电脑A和电脑B的网口

  2. 电脑A设置(已连接WiFi的电脑):

    • 控制面板 → 网络和共享中心 → 更改适配器设置
    • 右键点击WiFi适配器 → 属性 → 共享选项卡
    • 勾选”允许其他网络用户通过此计算机的Internet连接来连接”
    • 选择连接电脑B的以太网适配器作为专用网络连接
    • 点击确定

    image-20260201221104233

  3. 电脑B设置

    • 确保以太网适配器设置为”自动获取IP地址”
    • 稍等片刻即可上网
  4. 网络变化

    • 电脑A的以太网适配器IP变为:192.168.137.1
    • 电脑B自动获取IP为:192.168.137.x
    • 电脑A充当临时路由器和DHCP服务器
  5. 注意事项

    • 电脑A需保持开机状态,电脑B才能上网
    • 共享后电脑A的防火墙可能阻止某些连接,需相应调整
    • Windows ICS默认不响应ping请求,这是正常安全设置

五、局域网通信原理

两个设备要直接通信,必须满足:

  1. 同一IP网段:IP地址的前三部分相同(如192.168.1.x)
  2. 同一子网掩码:通常为255.255.255.0
  3. 同一广播域:连接在同一交换机或路由器的同一VLAN内
1
2
3
4
5
6
[路由器] (IP: 192.168.1.1,DHCP服务器)
├──[交换机] (扩展更多端口)
│ ├──[电脑A] (自动获取IP: 192.168.1.100)
│ └──[电脑B] (自动获取IP: 192.168.1.101)
├──[手机] (通过WiFi连接,IP: 192.168.1.102)
└──[智能电视] (有线连接,IP: 192.168.1.103)

所有设备均在192.168.1.0/24网段,可以互相访问

现在有这么一个场景,电脑a要向电脑b的服务发送数据或请求,我们只有在同一个局域网且同一个网段才能发送数据,可以让电脑a和电脑b使用网线连接到同一个路由器或交换机上,这样就能处在同一个局域网,一个网段内了

六、虚拟机额外补充

虚拟机如VMware里边的网络桥接和我们上边的桥接不同,VMware中的网络模式一般有以下几种

  1. 桥接模式
  2. NAT模式
  3. 主机模式

在电脑A中运行虚拟机时,网络模式决定局域网其他设备能否访问虚拟机服务:

模式 虚拟机IP获取 电脑B能否访问虚拟机 适用场景
桥接模式 从主路由器获取,与电脑A同网段 可以直接访问 虚拟机需对外提供服务
NAT模式 从电脑A的虚拟网络获取私有IP 默认不能访问(需端口转发) 虚拟机仅需上网,不需被访问
仅主机模式 与电脑A的专用虚拟网络 不能访问 完全隔离的网络测试

  1. 减少虚拟机 cpu 核心数

  2. 减少内存分配

  3. 在C:\Users\username\Documents\Virtual Machines目录下,找到对应的虚拟机,修改.vmx文件,在末尾添加:

    1
    keyboard.vusb.enable = "TRUE"
  4. 关闭3D加速

安装GNOME 插件管理工具

1
sudo apt install gnome-shell-extension-manager

GNOME插件推荐

  1. Caffeine : 点击图标即可控制电脑不休眠

  2. Clipboard Indicator : 剪切板工具

  3. Compiz alike magic lamp effect : 最小化动画效果

  4. Dash to Dock : dock 栏工具

    • 让 Ubuntu Dock 支持点击最小化/恢复
    1
    gsettings set org.gnome.shell.extensions.dash-to-dock click-action 'minimize'
    • 回复原状
    1
    gsettings reset org.gnome.shell.extensions.dash-to-dock click-action
  5. Blur my shell 美化工具

Tweaks 工具

支持设置终端剧中显示,双击窗口放大或缩小

1
sudo apt install gnome-tweaks

方案一

安装中文语言包

1
2
sudo apt update
sudo apt install language-pack-zh-hans

安装 Fcitx5 输入法框架

1
sudo apt install fcitx5 fcitx5-chinese-addons fcitx5-config-qt fcitx5-configtool

手动启动:

1
fcitx5-configtool

手动创建 fcitx5 自启动文件

1
sudo nano /etc/xdg/autostart/fcitx5.desktop

写入

1
2
3
4
5
6
7
8
[Desktop Entry]
Type=Application
Exec=fcitx5
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name=Fcitx 5
Comment=Start Fcitx 5 input method framework

方案二

  1. 安装 IBus 和拼音引擎
1
2
3
4
sudo apt update
sudo apt install -y ibus ibus-libpinyin
im-config -n ibus
ibus restart
  1. 设置 -> 键盘 -> 输入源 -> + -> Chinese -> Intelligent Pinyin (libpinyin)

拓展-语音输入

开源项目

VocoType-linux:高性能 Linux 离线中文语音输入法,基于 Ali FunASR(VocoType-cli). ~0.1s 瞬时上屏,输入法级稳定性, 极高中文准确率、低资源占用(CPU Only).支持 IBus / Fcitx5

对着文档就能安装,只需要安装语音输入法就行,里边的中文输入法不太行

1
2
3
4
git clone https://github.com/LeonardNJU/VocoType-linux.git
cd vocotype-cli
./scripts/install-ibus.sh
ibus restart
0%