Lenovo Legion Toolkit 技术深度剖析:开源硬件控制架构解析与实战指南
Lenovo Legion Toolkit 技术深度剖析开源硬件控制架构解析与实战指南【免费下载链接】LenovoLegionToolkitLightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops.项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionToolkitLenovo Legion ToolkitLLT作为一款专为联想拯救者系列笔记本设计的开源硬件控制工具通过轻量级架构设计实现了对笔记本性能模式、键盘背光、电池健康等核心功能的精细控制。本文将从技术架构、模块实现、扩展开发等多个维度深入剖析这一项目的技术价值为技术爱好者和进阶用户提供深度技术解析和实战指导。技术价值定位开源硬件控制的专业解决方案在当前的笔记本硬件控制领域Lenovo Legion Toolkit 代表了开源社区对专有软件生态的突破性回应。传统笔记本厂商提供的控制软件往往存在资源占用高、功能分散、隐私风险等问题而 LLT 通过模块化架构和开源透明的方式为技术用户提供了完整的硬件管理解决方案。核心优势内存占用极低仅占用不到10MB内存CPU使用率趋近于零无后台服务所有功能实时响应无需等待开源透明代码完全公开无隐私风险功能整合将所有硬件控制功能集中在一个简洁界面中项目采用 C#/.NET 8 技术栈构建充分利用了 Windows 平台的底层 API 调用能力同时保持了良好的跨平台兼容性设计思想。通过抽象层设计将硬件操作与业务逻辑分离为后续的功能扩展和维护提供了坚实基础。架构深度解析模块化设计与事件驱动模型核心架构设计模式Lenovo Legion Toolkit 采用了典型的分层架构设计主要分为以下几个核心层次1. 硬件抽象层HAL位于LenovoLegionToolkit.Lib/System/目录包含了对底层硬件的直接访问接口。通过 WMIWindows Management Instrumentation、NVAPI 等系统级 API实现对笔记本硬件的精细控制。// 示例电源管理核心接口 namespace LenovoLegionToolkit.Lib.System { public class Power { public static async Task SetPowerModeAsync(PowerModeState state) { // 通过 WMI 调用 Lenovo 专有接口 await WMI.CallAsync(root\\WMI, $SELECT * FROM LENOVO_GAMEZONE_DATA, SetSmartFanMode, new { Data (int)state }); } } }2. 功能特性层位于LenovoLegionToolkit.Lib/Features/目录定义了各种硬件功能的抽象接口。每个功能都继承自AbstractFeature基类实现了统一的启用/禁用、获取/设置接口。// 示例性能模式特性实现 public class PowerModeFeature : AbstractDriverFeaturePowerModeState { protected override uint ControlId 0x02020000; protected override uint FunctionId 0x2; protected override TaskPowerModeState GetStateInternalAsync() { // 硬件状态读取逻辑 } protected override Task SetStateInternalAsync(PowerModeState state) { // 硬件状态设置逻辑 } }3. 控制器层位于LenovoLegionToolkit.Lib/Controllers/目录负责协调多个相关功能的协同工作。例如AIController负责智能性能调度GPUController管理显卡工作模式切换。4. 自动化系统位于LenovoLegionToolkit.Lib.Automation/目录实现了基于事件驱动的自动化规则引擎。支持多种触发器类型电源状态、应用启动、时间等和执行动作的组合。事件驱动与观察者模式项目大量使用了观察者模式来实现硬件状态变化的实时响应// 自动监听器基类设计 public abstract class AbstractAutoListenerT : IAutoListenerT where T : EventArgs { private readonly ListEventHandlerT _handlers []; public event EventHandlerT? Changed { add _handlers.Add(value); remove _handlers.Remove(value); } protected void RaiseChanged(T args) { foreach (var handler in _handlers) handler?.Invoke(this, args); } }这种设计使得系统能够实时响应硬件状态变化如电源连接状态、游戏启动事件等并触发相应的自动化动作。核心模块实战代码示例与配置详解性能模式控制实现性能模式控制是 LLT 的核心功能之一支持安静模式、平衡模式、野兽模式和自定义模式。实现位于LenovoLegionToolkit.Lib/Features/PowerModeFeature.cspublic enum PowerModeState { Quiet 1, // 安静模式CPU功率限制15W Balance 2, // 平衡模式CPU功率25-35W Performance 3, // 野兽模式CPU功率解锁至45W Custom 255 // 自定义模式支持风扇曲线和功率限制调整 } // 通过命令行接口控制 llt feature get PowerMode // 查询当前性能模式 llt feature set PowerMode 3 // 切换到野兽模式显卡工作模式优化显卡模式管理支持混合模式、独显直连和禁用独立显卡三种工作状态位于LenovoLegionToolkit.Lib/Features/Hybrid/目录英文版界面展示GPU工作模式切换和独立显卡状态监控public enum GPUWorkingMode { Unknown 0, Hybrid 1, // 混合模式日常使用最佳选择 Discrete 2, // 独显直连游戏性能提升5-15% HybridAuto 3, // 自动混合根据电源状态自动切换 HybridIGPUOnly 4 // 集成显卡模式最大化电池续航 } // 显卡模式切换示例 llt feature get GPUWorkingMode // 查询当前显卡模式 llt feature set GPUWorkingMode Hybrid // 切换到混合模式自动化规则配置自动化系统支持复杂的条件判断和动作执行链配置示例{ trigger: { type: PowerStateChanged, parameters: { powerState: ACConnected } }, actions: [ { type: PowerMode, parameters: { mode: Performance } }, { type: Delay, parameters: { delay: 5000 } }, { type: RGBKeyboard, parameters: { preset: GameProfile } } ] }扩展开发指南二次开发与功能定制添加新的硬件控制器要扩展 LLT 支持新的硬件功能需要遵循以下步骤1. 创建特性类继承AbstractFeatureT基类实现硬件特定的控制逻辑public class NewHardwareFeature : AbstractDriverFeatureNewHardwareState { protected override uint ControlId 0x03010000; // 硬件控制ID protected override uint FunctionId 0x1; // 功能ID protected override async TaskNewHardwareState GetStateInternalAsync() { // 实现硬件状态读取逻辑 var result await WMI.CallAsync(...); return ParseState(result); } protected override async Task SetStateInternalAsync(NewHardwareState state) { // 实现硬件状态设置逻辑 await WMI.CallAsync(..., new { Data (int)state }); } }2. 注册到依赖注入容器在LenovoLegionToolkit.Lib/IoCModule.cs中添加注册代码builder.RegisterTypeNewHardwareFeature() .AsIFeatureNewHardwareState() .SingleInstance();3. 添加用户界面控件在 WPF 项目中创建相应的用户控件并集成到主界面中。创建自定义自动化步骤自动化系统支持自定义步骤类型扩展方法如下1. 实现自动化步骤接口public class CustomAutomationStep : IAutomationStepCustomParameters { public string DisplayName 自定义步骤; public string Description 执行自定义操作; public Taskbool ExecuteAsync(CustomParameters parameters) { // 实现步骤逻辑 return Task.FromResult(true); } public TaskValidationResult ValidateAsync(CustomParameters parameters) { // 实现参数验证逻辑 return Task.FromResult(ValidationResult.Ok()); } }2. 注册自动化步骤工厂在LenovoLegionToolkit.Lib.Automation/Pipeline/Triggers/目录中添加相应的工厂类。扩展命令行接口CLI 接口基于 IPC进程间通信架构扩展方法1. 添加新的 CLI 命令在LenovoLegionToolkit.CLI/Program.cs中添加命令处理var newCommand new Command(newFeature, 控制新功能) { new Optionstring(--mode, 设置模式) }; newCommand.SetHandler(async (mode) { var client new IpcClient(); await client.ConnectAsync(); await client.SendAsync(new IpcRequest(newFeature, mode)); await client.DisconnectAsync(); }); rootCommand.AddCommand(newCommand);2. 实现 IPC 服务端处理在LenovoLegionToolkit.WPF/CLI/IpcServer.cs中添加对应的请求处理逻辑。性能优化策略高级调优技巧内存使用优化LLT 通过以下策略实现极低的内存占用1. 延迟加载设计public class LazyFeatureLoader { private readonly LazyIFeaturePowerModeState _powerModeFeature; public LazyFeatureLoader() { _powerModeFeature new LazyIFeaturePowerModeState( () container.ResolveIFeaturePowerModeState()); } public IFeaturePowerModeState PowerModeFeature _powerModeFeature.Value; }2. 对象池技术对于频繁创建销毁的对象使用对象池减少GC压力public class HardwareCommandPool { private readonly ConcurrentBagHardwareCommand _pool new(); public HardwareCommand Rent() { if (_pool.TryTake(out var command)) return command; return new HardwareCommand(); } public void Return(HardwareCommand command) { command.Reset(); _pool.Add(command); } }响应时间优化1. 异步操作链所有硬件操作都采用异步模式避免阻塞UI线程public async TaskPowerModeState GetPowerModeAsync() { try { return await _powerModeFeature.GetStateAsync() .ConfigureAwait(false); } catch (Exception ex) { Log.Instance.Error(获取性能模式失败, ex); return PowerModeState.Unknown; } }2. 批量操作优化多个相关操作合并执行减少硬件通信次数public async Task ApplyPowerProfileAsync(PowerProfile profile) { var tasks new ListTask { _powerModeFeature.SetStateAsync(profile.Mode), _gpuModeFeature.SetStateAsync(profile.GpuMode), _fanController.SetCurveAsync(profile.FanCurve) }; await Task.WhenAll(tasks).ConfigureAwait(false); }电源效率优化电池使用场景优化配置{ batteryProfile: { powerMode: Quiet, gpuMode: HybridIGPUOnly, screenBrightness: 50, keyboardBacklight: Off, usbPower: Disabled } }插电高性能配置{ performanceProfile: { powerMode: Performance, gpuMode: Discrete, fanCurve: Aggressive, overclock: Enabled } }社区生态分析技术发展趋势与分支维护项目现状与分支策略重要提示本项目已于2025年7月24日归档不再主动维护。但所有代码仍然可用社区分支仍在积极开发。虽然原项目已归档但社区仍在积极维护多个分支版本活跃分支推荐功能增强分支添加新硬件支持优化现有功能Bug修复分支专注于稳定性修复和兼容性改进实验性分支尝试新特性如AI优化、云同步等技术架构扩展点工具箱采用模块化设计便于功能扩展硬件控制器扩展接口public interface IHardwareController { bool IsSupported { get; } Task InitializeAsync(); TaskHardwareInfo GetInfoAsync(); Task ApplySettingsAsync(HardwareSettings settings); }插件系统设计 项目预留了插件接口允许第三方开发者扩展功能自定义硬件监控指标新增自动化触发器类型集成第三方服务如云配置同步贡献指南与开发流程代码贡献流程Fork项目仓库创建个人分支进行开发创建功能分支基于主分支创建开发分支编写单元测试确保功能正确性和稳定性提交Pull Request详细描述变更内容和测试结果参与代码审查与社区成员讨论改进方案测试策略[TestFixture] public class PowerModeFeatureTests { [Test] public async Task SetPowerMode_ShouldSucceed() { // 模拟硬件接口 var mockHardware new MockIHardwareInterface(); var feature new PowerModeFeature(mockHardware.Object); // 执行测试 await feature.SetStateAsync(PowerModeState.Performance); // 验证结果 mockHardware.Verify(h h.SendCommand(It.IsAnybyte[]()), Times.Once); } }技术总结展望未来发展方向与最佳实践架构演进方向短期技术目标支持更多联想笔记本型号的硬件接口优化现有功能的性能和稳定性完善自动化规则的调试工具中长期技术规划跨平台支持Linux/macOS的架构设计云配置同步和备份功能AI驱动的智能性能优化算法插件系统标准化和扩展接口性能基准测试建议建立系统的性能基准测试套件public class PerformanceBenchmark { [Benchmark] public async Task PowerModeSwitchLatency() { var stopwatch Stopwatch.StartNew(); await _powerModeFeature.SetStateAsync(PowerModeState.Performance); return stopwatch.ElapsedMilliseconds; } [Benchmark] public async Task AutomationRuleExecutionTime() { // 测试自动化规则执行性能 } [Benchmark] public void MemoryUsageUnderLoad() { // 测试高负载下的内存使用情况 } }安全与稳定性最佳实践硬件操作安全双重验证机制重要硬件设置变更前进行二次确认回滚策略自动检测异常并恢复到安全状态操作日志记录所有硬件操作记录详细日志便于问题追踪错误处理策略public async Task SafeHardwareOperationAsync(FuncTask operation) { try { await operation(); } catch (HardwareException ex) when (ex.IsRecoverable) { // 可恢复错误尝试重试 await RetryHelper.RetryAsync(operation, maxAttempts: 3); } catch (HardwareException ex) when (ex.IsCritical) { // 关键错误记录并通知用户 Log.Instance.Error(硬件操作失败, ex); await ShowCriticalErrorNotificationAsync(ex); } }配置管理最佳实践配置文件结构优化{ version: 2.0, profiles: { gaming: { powerMode: Performance, gpuMode: Discrete, fanCurve: aggressive, rgbProfile: game }, battery: { powerMode: Quiet, gpuMode: HybridIGPUOnly, screenBrightness: 40 } }, automation: { rules: [ { name: 游戏模式切换, trigger: GameStarted, actions: [applyProfile:gaming] } ] } }技术决策权衡分析架构设计权衡性能 vs 内存采用延迟加载和对象池平衡实时性 vs 稳定性异步操作链配合错误恢复机制功能完整性 vs 代码复杂度模块化设计保持核心简洁硬件兼容性策略动态检测硬件能力避免不支持的功能优雅降级机制确保基本功能可用详细的兼容性报告帮助用户理解限制中文版界面展示电源管理、显示设置和性能监控等核心功能更符合国内用户习惯结语开源硬件控制的技术价值Lenovo Legion Toolkit 不仅是一个功能强大的硬件控制工具更是开源社区在硬件逆向工程和系统级编程方面的优秀实践。通过精细的架构设计和高效的技术实现项目展示了如何在不依赖厂商专有软件的情况下实现对笔记本硬件的全面控制。技术贡献总结硬件抽象层设计为后续类似项目提供了可参考的架构模式事件驱动自动化系统展示了复杂状态机在桌面应用中的应用跨进程通信机制实现了轻量级的 CLI 与 GUI 交互方案社区协作模式建立了开源硬件控制项目的开发范式对于技术爱好者而言LLT 的源码是学习 Windows 硬件编程、WMI 接口调用、.NET 桌面应用开发的宝贵资源。对于进阶用户项目提供的扩展接口和自动化系统为个性化硬件管理提供了无限可能。通过合理配置和使用 Lenovo Legion Toolkit用户可以充分发挥拯救者笔记本的硬件潜力获得更加流畅、高效的使用体验。这款工具不仅是官方软件的轻量替代品更是技术爱好者探索硬件控制的绝佳平台。技术提示硬件控制涉及底层操作在进行深度定制前请充分理解相关风险建议在测试环境中验证配置后再应用到生产环境。【免费下载链接】LenovoLegionToolkitLightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops.项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionToolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

高效漫画下载革命:揭秘picacomic-downloader如何重塑你的漫画收藏体验

高效漫画下载革命:揭秘picacomic-downloader如何重塑你的漫画收藏体验

高效漫画下载革命:揭秘picacomic-downloader如何重塑你的漫画收藏体验 在数字漫画阅读时代,你是否曾为网络不稳定而烦恼?是否因为手动保存漫画效率低下而放弃收藏?picacomic-downloader作为一款专为漫画爱好者设计的专业下载工具…

2026/10/14 18:58:50 阅读更多 →
职场社交技巧:如何应对‘明天有空吗‘的陷阱提问

职场社交技巧:如何应对‘明天有空吗‘的陷阱提问

1. 为什么"明天有事吗"是个陷阱问题 "明天有事吗"这句话表面看是普通询问,实则暗藏社交玄机。我在职场和生活中遇到过太多次类似场景——对方抛出这个看似无害的问题时,往往背后隐藏着真实意图。可能是想临时安排工作、请求帮忙、甚…

2026/10/15 2:14:53 阅读更多 →
【YOLO26多模态涨点改进】TGRS 2026 | 独家创新首发、特征融合改进篇| 引入SSFRM语义空间特征优化模块,利用深层语义特征指导浅层细节特征,助力遥感目标检测、小目标检测有效涨点

【YOLO26多模态涨点改进】TGRS 2026 | 独家创新首发、特征融合改进篇| 引入SSFRM语义空间特征优化模块,利用深层语义特征指导浅层细节特征,助力遥感目标检测、小目标检测有效涨点

一、本文介绍 🔥本文给大家介绍使用 SSFRM语义空间特征优化模块 改进YOLO26多模态网络模型。 为了提升YOLO26多模态融合目标检测的跨层特征质量,本文引入SSFRM语义空间特征优化模块,利用深层语义信息从通道与空间两个维度引导浅层特征筛选,强化目标边缘、纹理和位置线索…

2026/10/13 12:52:18 阅读更多 →

最新新闻

AI Agent智能面积手册:从0到1搭建可扩展Agent系统的工程实践

AI Agent智能面积手册:从0到1搭建可扩展Agent系统的工程实践

1. 从“智能面积”说起:这份手册到底想解决什么问题“智能面积”这个词第一次出现在我视野里的时候,我盯着屏幕愣了几秒。做了这么多年技术方案,见过“技术债”“算力密度”“数据飞轮”这类概念,但把“面积”和“智能”放在一起&…

2026/10/15 6:16:43 阅读更多 →
个人AI智能体内容下载与导出:从剪贴板到API的完整实现指南

个人AI智能体内容下载与导出:从剪贴板到API的完整实现指南

1. 从“生成完就丢”到“内容资产化”:为什么下载能力是个人AI智能体的分水岭很多人用个人AI智能体(AI Agent)时都有过这种体验:让它写一篇周报、生成一段产品文案、整理一份会议纪要,屏幕上文字哗啦啦地出来&#xff…

2026/10/15 6:16:43 阅读更多 →
智能面积:AI Agent系统能力覆盖与工程实践手册

智能面积:AI Agent系统能力覆盖与工程实践手册

1. 从“智能面积”说起:这份手册到底想解决什么问题第一次看到“智能面积”这个词,我愣了几秒。做了这么多年技术,面积这个词通常跟机房、存储、带宽挂钩,什么时候跟“智能”绑在一起了?翻完这份手册的公开内容之后&am…

2026/10/15 6:16:43 阅读更多 →
大数据集群批量分发脚本实战:从手敲scp到xsync高效同步

大数据集群批量分发脚本实战:从手敲scp到xsync高效同步

大数据集群批量分发脚本:从手敲 scp 到一套体面的 xsync先说一个我踩过的坑。某次业务上线前,需要临时把一份配置文件同步到集群里所有节点。当时集群才六台机器,我图省事,一台一台 scp,敲到第五台的时候,第…

2026/10/15 6:16:43 阅读更多 →
Natron 在 GNU/Linux 上从源码编译安装完整指南:qmake 与 CMake 双构建路径详解

Natron 在 GNU/Linux 上从源码编译安装完整指南:qmake 与 CMake 双构建路径详解

音视频视频处理图形学桌面应用 【免费下载链接】Natron Open-source video compositing software. Node-graph based. Similar in functionalities to Adobe After Effects and Nuke by The Foundry. 项目地址: https://gitcode.com/gh_mirrors/na/Natron 点击查看 …

2026/10/15 6:16:43 阅读更多 →
MCP协议实战:从零构建大模型工具调用标准化方案

MCP协议实战:从零构建大模型工具调用标准化方案

大模型再聪明,也有一件事干不了:它不知道你公司数据库里昨天新增了多少订单,不知道你本地那台服务器上某个服务的实时状态,更没法直接帮你把一条消息发到团队协作工具里。这不是模型能力不行,而是它的“活动范围”被锁…

2026/10/15 6:15:42 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →