WPS中的字体名

今天又被 fontconfig 坑到了……仔细想想,半年到一年前我还对 fontconfig 狗屁不通呢,而现在我已经被 fontconfit 坑了有几次了,这印证了一个真理:“只要你足够迟钝,世界就是美好的,一旦你有了某种能力,麻烦就会找到你”——这只是个玩笑,事实上不管你有没有能力,现实都不会让你好过 😈 在这些坑里面,有两个是跟今天主题相关的,也就是关于WPS中字体名称的两个问题: WPS 字体列表中中文字体在中文环境下不显示中文名(比如系统里面有宋体,列表里面显示 SimSun); WPS 设置段落字体(中文字体)后,工具栏显示的字体为英文名(比如你设置一段文字是宋体,但是标题栏显示的仍然是SimSun) 这两个问题有点像,但是却不是同一个问题(也不只是WPS有问题,而是WPS对字体的需求比较多): 第一个问题原先是 论坛用户报告 的(实际上刘老大也报过,不过被自动忽略了😂),论坛用户又报过来以后,大家看用户的报告太详细了,感动得一塌糊涂,顿时解决问题的动力都有了。我也折腾了大半天,不过脑袋里面一直有一个同事的声音:那是字体有问题!我也挺赞同的:盗版的字体,不靠谱很正常……所以,我就考虑能不能给字体做一些别名啥的,比如 SimSun 就叫 宋体……当然了最后就是玩了一下 fontconfig 的配置以后,默默就放弃了。 最后经过 @felixonmars 同学的排查,发现是上游的一个 bug ,而且已经修复,所以赶紧更了一波,解决了这个问题。 本以为皆大欢喜了,今天又有客户报过来 bug,说 Windows 上写好的文档,调整好的字体,跑到deepin下字体就不对了,废了老大的劲儿才又调好,其中就提到了选择方正字库里面的字体,显示的不是中文字体名称的问题。 怎么说呢,幸亏我脑子不好,不记得之前已经解决过中文字体名显示为英文的问题,要不然得跟客户和老板掰扯一会儿,我只记得字体的中英文名字好像是有点问题,所以默默赶紧去看了一下,还真真的有问题。 因为 DDE 并没有设置过多的 fontconfig 配置,所以我相信这不是 DDE 的问题,但是又觉得对于一个文字处理软件来说,如果这么重要的功能都有 BUG,我真不信 WPS 的人还能坐得住,所以就想试一下在 Ubuntu 下 WPS 的这个行为是否正确。刚好年前 ElementryOS 发新版的时候尝鲜装了一个在测试机器上,所以很快切进去下了一个 WPS 安装上,从一个正版的网站上下载了一个盗版的宋体,试了一下,果然踏马的是好的…… 理性的我用事实证明了感性的我是错误的,气氛一度很尴尬。 更让人尴尬的是,我也不知道这是怎么回事。但是,无巧不成书,就在这种尴尬氛围的笼罩下,我鬼使神差地在 ElementryOS (太长了,下面简称 EOS )上运行了 fc-match 宋体 这个命令,而且很神奇的发现输出的 simsun.ttf: "宋体" "Regular" 跟 deepin 下同样命令输出的 simsun.ttf: "SimSun" "Regular" 不太一样,这可把我乐坏了——要知道一个稍微复杂点的图形软件,打开 fontconfig 的调试以后,输出就是很可怕的,更别说 WPS!别问我是怎么知道的,回忆起来都是泪。但是现在使用 fc-match 就能重现的问题(我打心底认为这俩是同一个问题),调试起来就比较简单了。 Read On →

2018 年终总结

2018 年也不知道为啥过得这么快,似乎“嗖”的一下就过完了,但是仔细回想一下,还是有不少事、不少感想值得留存的,所以赶紧用文字记录下,不然以我的健忘性格,不用到明年的今天,我就不会再记得 2018 年我做了什么、经历了什么和有什么感悟了。惨痛的教训比如 2017, 没有总结,我看了 2016年终总结 甚至不知道我的 2017 相比 2016 是否有进步、有没有按照规划去做了对的事情。所以在这个时间点,就算是年终刚好出去参加同学的婚礼了,也在火车上抽了时间做了脑图,整理了一年下来的总结。 读书 总的来说18年读的书不算多,甚至可以用少来形容,不过总归还有些感悟,记录下来权做以后翻看旧书需要的介绍了。 《南渡北归》 拖拖拉拉终于几乎看完了全本,只是到国民党退到台湾以后,顿时有一种很丧的气氛在里面(不知道是书还是当时看的我),所以后面基本上就没怎么看了。 对于整本书的评价还是很高的,革命/战乱的年代,杂糅这知识分子的热忱、浪漫、坚毅、吃苦耐劳,沉入其中,感受每个人面对的挣扎和选择,对于一个人对人生和价值观的思考还是非常有促进作用的。 像《老残游记》和《浮生六记》一样,如果有机会,我还会再读几遍。 《技术管理之巅》 技术管理书,因为很贴近实际,所以显得比较接地气。 在看这本书的过程中想通了技术和管理其实是可以很好融合在一起,而不是互相对立的。 《把生命浪费在美好的事物上》 原以为是类似汪曾祺的哪些小散文的书,但是完全被吴晓波起的书字给骗了。把生命浪费在美好的事物上,你得先跟吴晓波一样有钱 :P 同上本书,这本书让我知道了“铜臭气”和“书呆子气”可以同时存在于一个人身上,并且很好地共存。 《曾国藩的正面与侧面》 青春期的时候,可能是热血漫画看多了,我总是喜欢认为自己是个“天才”,但是随着年龄增长,我越往后越发现我对于“天才”和“聪明”的需求越来越弱,反而是对“勤”和“恒”的需求越来越多。这本书并没有教会我做什么,而是加深了我早已有的很多想法,让我更知道如何为人和处事。 《原则》 忘记这本书是什么时候引起风潮的,似乎一时间所有的人都在看这本书。不过我还是因为懒没有看。等过了一段时间有次在火车上没事干,想找一本书看看就选择了这本书。 初看还是很有同感的,尤其是生活部分(其实就像作者说得,前面哪些他个人的经历,其实没有什么特别有意思的地方)的一些原则,我当时甚至想给深度的开发同事也弄一个 深度开发者行事原则 的,但是碍于这个东西实在不好讲,因为每个人本身的认知程度千差万别,想一下子拉齐到同一水平很不现实,所以一拖两拖,就废掉了。 不过我还是因此养成了一个把我在一些特殊时刻想到的一些感受和想法记录下来沉淀的习惯,收获也算不少吧。 《白夜行》 纯娱乐,读得相当快,好像是一两周之内读完的(这已经是我读书的最快水准)。读这本书是因为偶然一次机会在一个便利店看到一个《解忧杂货店》的舞台剧广告,上面写着“日本作家东野圭吾作品”,当时我就傻眼了——《解忧杂货店》不是村上春树的作品么???再三确认以后,我决定再读一本东野圭吾的作品,以示歉意,所以就选了《白夜行》。 书中的故事相当粗暴,但是很吸引人,就是那种“我已经猜到答案了,你快点告诉我是不是这样”一路走下去的感觉。 《见识》 吴军老师的书,都是干货的方法论合集。 按道理说一般说外企大佬写得书,多半是鸡汤(至少我认为是这样),但是吴军老师的书里面还是有很多大智慧。 《我们台湾这些年 I》(未完) 纯好奇,看着作者从小往大介绍,思绪慢慢从我的童年飘到现在,找回不少记忆。不过越往后看,越想借用《南渡北归》中蒋介石的一句话来送给自己和其他心心念互联网自由的人:“汝辈竟无革命精神若此!” 《奈飞文化手册》 得到APP里面买的,介绍奈飞公司文化的一本书,其实给我的感觉是跟《原则》这本书交相呼应的,书里面介绍的几个价值核心:“我们只招成年人”、“要让每个人都理解公司业务”、“绝对坦诚”、“只有事实才能捍卫观点”要么是有很多共鸣——比如“要让每个人理解公司业务”,我一直觉得公司很多东西该透明要积极去透明,也一直在努力让开发部内部所有的事情都清晰透明;要么就是对我启发比较大——比如“我们只招成年人”。其他章节不是不好,而是因为需要在公司更高层面去运作,所以我的认识相对较少。 旅行 全年两次旅游,一次在宜昌,一次在云南。 宜昌算是散心之旅,我和小崔两个人,游记见摆脱尘世繁杂——宜昌休闲4天游。 云南真的是一场说走就走的旅行,因为今年公司没有组织年度旅游,所以云南游算是全年的大游了,但是其实只是一时冲动陪朋友去云南探亲,结果他的探亲成假,我们旅游去成真了。无游记。 电视剧&纪录片 电影就不说了,跟着小崔看了好多电影。只说下对我印象还比较深刻的电视剧和纪录片。 《我们这一天》 家庭剧,这部剧让我对未来的家庭充满期待,也很感恩我后来不再是独生子女。 Read On →

深度滚动更新工作流程

背景 以前的系统发布模式为平均每3个月一次系统发布——开发周期2个月,测试周期1个月。这虽然保证了每次系统发布的状态都比较稳定,但是仍然避免不了在大量用户在不同场景下产生而发现新 BUG 的局面,而且因为这种发布模式缺少快速更新的机制,导致很多在内部已经得到修复的问题无法及时推送到外网,用户在这段时间内只能忍受一些 BUG 的干扰。所以,我们在 15.6 和 15.7 的时候引入了”发布后一个月“的概念,在这个时间段内,开发主要做问题修复工作,修复的内容可以快速推送到外网,而不用经过繁杂的测试,期望快速解决用户在使用新版本中遇到的问题,这就是深度滚动更新的原型。 15.8开发的过程中,我们又思考了一下这个过程,刚巧我们决定了要尝试”开放和透明“、拥抱社区,所以觉得目前这种把”大教堂“和”集市“两种开发模式揉在一起的方式不是特别明朗,对系统发布者和开发者都是一种负担,所以”从善如流“——从 15.9 开始,deepin 系统的发布开始遵循滚动更新的模式。 滚动更新流程 深度的滚动更新,需要参与系统发布的产品、开发和测试共同合作,所以制定了一套简单的工作流程作为大家协作的基础,从粗到细主要分为了以下几个范围: 1. 系统版本 系统版本的概念跟以前的 15.7、15.8 等没有不同,都会提前指定这 2 - 3 个月的一个工作计划,在阶段性工作完成之后,会有新版本的 ISO 发布。与之前不同的是,新功能不是等系统发布的时候一次性放出,而是在每周开发内容完成、测试通过以后就会放出;另外一个不同是,系统发布不再以完成所有开发内容为前提,而是在系统版本计划的时间点达到以后即发布,未完成的内容放入下个版本工作内容中。 工具使用: 系统版本规划的内容会展示在官网的“版本规划”中进行展示; 需求文档会邮件通知所有参与系统发布的同事。 2. 里程碑 由于前面所说的新版本不会要求计划内容都完成才发布,所以为了防止工作计划与实际工作产出相差过大,所以将每次系统版本发布做了阶段划分,也就是里程碑。举个例子来说,15.9 开发的阶段会划分为 15.8.1、15.8.2、 15.8.3、 15.8.4 等。 在每次里程碑开始之前,产品需要提前细化里程碑内的需求,在里程碑开始之前还未明确的需求,会被放入下个里程碑中。同样,在这个阶段,测试会根据产品需求编写测试用例。需求和测试用例都会经过一次评审。每个里程碑到达预定时间点之后,未完成的工作内容会按照优先级放入下个里程碑或者延后处理、放到其他里程碑中。 工具使用: 里程碑使用 github issues 中的 Milestone 工具来进行管理; 细化的需求文档以及需求变更会邮件通知所有参与系统发布的同事。 3. 工作周 每个里程碑由两个工作周组成。在每个工作周内,开发需要完成计划中的开发内容和上个工作周测试问题的修复工作,在每周结束的时候,开发对稳定的项目打 tag,并提交到 crp 平台进行打包、提供 changelog 供产品和测试在下个工作周进行验收。同样,在每个工作周内,产品和测试需要完成对上周开发内容的验收工作,保证在周三前完成功能验收、功能测试和 BUG 修复,周四时发布更新。 工具使用: 系统各个组件包版本控制、changlog 使用 crp 进行管理; 每周更新内容在 internal-discussion 中建相应里程碑发布任务的 issue 进行说明; 社区官网提供每次更新的更新注记。 目标 目前对滚动更新的期望主要有以下几点: Read On →

修理 FreeRDP

起因 头段时间入了一个大坑儿,大概被坑了有一个月之久,出来之后同事还不忘嘲讽一番:”这么个事情就搞了一个月,看吧,你果然是老了“。听了这句话,心里真是百般滋味,但转念一想,”我年轻的时候做事好像也不怎么快“,顿时也就释怀了 :) 这个坑就是”给 FreeRDP 的 RAIL 模式添加托盘支持“,当然,跟所有的需求一样,这么具有总结性而又直指根源的需求描述,绝对不是它最原始的模样——我刚接到这个坑的时候,它是这样的:FreeRDP 的 RAIL 模式下,应用的托盘在我们 DDE 下不显示。请注意这里说得是不显示,而不是后来发现的压根儿没有支持! FreeRDP 说到这,可能有读者还不了解 FreeRDP 和 RAIL,所以先简单介绍一下。 RDP 其实是一个协议名称,全称 Remote Desktop Protocol(远程桌面协议),是微软公司开发的一套用于远程桌面展示和操作的协议,FreeRDP 就是它在开源世界的实现咯。而 RAIL 的全称是 Remote Application Integrated Locally (远程应用本地集成),其实就是非常类似大家熟悉的虚拟机的”无缝模式“,通过将应用的显示跟本地环境相融合,让用户完全感受不到这个应用其实不在本机运行——就是这么一种技术。 问题也就出在这,我当时第一反应是这么老的技术实现肯定比较完整了,托盘没有显示出来应该是跟 DDE 的兼容性有点小问题,稍微修一下就完了,三下五除二的事情,所以满口答应了下来…… 经过 既然答应了,硬着头皮也要顶下去的。何况调 BUG 这种事情——不管是不是我们自己的问题——在深度都是家常便饭。慢慢地,调各种项目的 BUG 竟然成了我的一种乐趣——每次开始接手一个新的项目的时候,我都把自己当成了福尔摩斯或者胡八一,或者也可以是其他全世界最聪明的那类人 😜,在通过代码找寻问题线索的过程中,慢慢成为这个项目世界中的主宰,解开真相…… 额……不好意思,白日梦又发作了一会儿。总之,这次也不例外,而且刚好这次在调问题的过程中有记录几个关键环节,所以打算把中间的过程写成日记性质的记录,看看能不能有更好的阅读效果: 2018-11-14 从”沈老板“那收到需求,说 FreeRDP 在我们系统上有问题,应用的托盘显示不出来,QQ之类的程序关闭了窗口以后就没办法显示出来了,无法使用。这丫的又拿刘老大来压我……呵呵,想削他。不过看在他快要当爸爸的份上,还是算了。问了下时间要求,大概需要两周左右有初步的结果。不过我自己最近没有什么时间,先把锅丢给了印象中还比较熟悉网络协议的 @Blumia 同学。 2018-11-15 从 @Blumia 那收到反馈,可能 FreeRDP 没有实现托盘图标这部分的功能,我怕他一个人搞不定,简单翻了翻 FreeRDP 的项目 wiki 和 RDP 的一些介绍,给了他,让他先帮忙找一下需要补充实现部分的代码结构。 2018-11-16 没时间处理。 @Blumia 搭了测试环境。 中间几天两个人都没有时间处理 FreeRDP 的事情。 2018-11-22 留了少部分时间,看了 FreeRDP 的代码,大概找到了托盘图标相关处理应该在的位置。 Read On →

15.8研发心得

不早也不晚,2018年11月15日 deepin 15.8 如期发布。这虽然是个好消息,但是没有了延期的梗,我竟然不知道这篇研发心得应该如何开头……😓 开头这件事情总是很难,因为要做到一些以前没有做到的事情,就要求能将自己的水平提高哪怕那么一点点;同时,开头也不宜于高调,高调的开头太容易造成虎头蛇尾以致不能坚持的局面。在我的价值观里,与其浪费时间和精力在不能坚持的事情上,还不如什么都不做。所以很多事情我都不愿意开头,就像写这篇研发心得一样。 不过,幸运的是我们对发布系统这件事情倒是充满着热情,以至于我们能在每一次系统发布的“轮回”里,都无所畏惧地开头并且坚持如一。比如 15.4 的毛玻璃效果、15.5 的高分屏、15.6 的应用深色主题、15.7的性能优化等等等等……当然,这次的主角 15.8 也不输从前。 新特性介绍 15.8 中新的变动着实不少,但是从一个研发的角度来看,我觉得最重要的变化应该是组织系统开发和发布的人发生了变化。之所以说这个比较重要,是因为 deepin 的前辈们把接力棒交到我这里,我终于可以把它顺利地转交到合适的人手中了,这句话的言外之意是什么呢?就是大家以后如果遇到什么 bug,进门左转找 @zccrs 😂。 说明了以上信息,就可放心地介绍这次的新功能了。不过说实话,这次的新功能都相当直观,用不着我费什么口舌,再加上本次研发心得的重点不在此,所以大部分的新功能请看 系统发布新闻,这里只说两个我最喜欢的点吧。 第一个要说的,是15.8 的新功能里面最让人惊喜的 Dock时尚模式 的托盘插件 的设计调整: 为什么呢?这主要是因为以我的聪明才智,都一直认为时尚模式的托盘是一个无解的问题:系统托盘占用大量空间,应用托盘使用不方便……除非引入类似 macOS 的 topbar (估计很多人也是这么想的,所以都默默地在商店里面安装了 deepin-topbar吧)。事实上,当时我们讨论解决方案的时候也是差不多一样的状态,每个人都欲言又止,显然是还没说出口的方案就被自己推翻了,然而就在这个时候,设计师默默地上了一副设计图,把所有的应用托盘也放大成了与应用图标无异的大小。 我:!?!?!?(黑人脸 我刚要扔臭鸡蛋,设计师咔嚓又上传了一张图,仿佛在说 “蛋下留人~” 而转机就这样发生了,我看到设计图,就如大家在15.8看到的Dock时尚模式一样,托盘问题竟然被 almost 完美地解决了——在最后的关键时刻设计师保住了自己的颜面。 怎么说呢,这基本上是我在深度继看到一个开发同事用钥匙给电脑开机感到由衷地佩服以来,再一次罕见地(尤其是被设计师?😈)觉得世界观被刷新的一次体验了。 另外一个要提的是一个很小的点,不过现在想起来都会有一种吃了广告中的德芙的感觉——丝滑。是什么呢?如果你现在使用 deepin 浏览这篇文章,应该能看到我特地在文章开头、上一段和中间甩锅那一段,几乎到处都贴了 emoji 表情: 能正常显示,而不是豆腐块! 关键是它们是彩色的!!! 整篇文章不再有黑乎乎的表情——这简直是使用Linux写技术博客的 Blogger 的福音啊。如果你也想在文字编辑的时候输入开爱的 emoji 表情,可以打开 https://getemoji.com/ ,只需 copy&paste,瞬间让你拥有进入 21 世纪互联网的赶脚。 至于这个新特性为什么没有写到更新注记里面,是低调,是彩蛋,还是忘了写?咳咳,有点赶时间,继续往下写了 🙄🙄🙄 。 开放和透明 上面说了发系统的接力棒已经成功交(shuai)接(guo)给别人了,那我去干啥了呢?总得做点啥吧,要不被开了就不好玩儿了嘛😱。 我这段时间做得其实就是开放和透明。 在中国说起开源,应该没有人不知道深度作为“东半球最大的开源软件公司”的名头,如果有人不知道,那也让我们先姑且这么认为着 😜, 深度从出生的那一刻起就一直在开源——深度出品的软件产品中95%以上都是开源的,但是直到最近我才老有一种感觉就是深度一直在“开源”,但是并没有在“做开源”。 深度是很长于做产品的,每个产品都可以做得既小巧玲珑,又戳中用户痛点,所以积累了不少海内外用户。这些用户使用着我们的系统,时不时灵感来了还会提出一些宝贵的意见和建议,这本是极好的。但是作为开发者的我发现,其实这批用户里面有不少同行,他们也想为深度的开源事业做出自己的贡献,天天问我:How to contribute。我脑子飞速旋转,“这个功能貌似他可以加一下?不对,这个功能需要知道很多故事背景,说来话长……还是算了”,“那个bug他好像可以修一下,但是好像也不能按照常规的方式去修复……一两句话也说不清楚”。思来想去,最后只能以“你可以帮我们测试,测试也是一种贡献呀”、“你会德语呀,这么厉害,要不要帮我们加点翻译” 等等的回复搪塞过去,说完这些内疚到简直想出去哭一场。更有甚者,有些开发者克服了重重困难,终于提交了 CL (可以理解为补丁)想要一些功能,内部讨论半天给出一个决定和回复,对方回复,内部再讨论半天给一个回复……效率极低,还容易导致各种误解。更可惜的是,以后甚至还会有同样热心的开发者提交类似的补丁,然后重复前面的过程,及其浪费社会生产力。 Read On →

通过 Unix Domain Socket 传递文件描述符

Unix Domain Socket 是 Unix 系统下重要的本地进程间通信(IPC)机制之一,在 DDE、GNOME、KDE 等 Linux 桌面环境中常见的进程间通信方式 DBus 有一种实现方式就是基于 Unix Domain Socket 做的。虽然一直知道它的大名,也一直知道 Unix Domain Socket 可以用来传递文件描述符,但是碍于以前经验和眼界不足,加上没有深入去了解,完全不知道能传递文件描述符是多么强大的能力和必要性。 首先,我想着文件描述符不就是一个数字么,哪个 IPC 不能传递数字呢?完全没有思考到文件描述符是只在进程范围内有效,同样一个文件描述符放在不同的进程完全就不是一回事儿。这时候你肯定想,既然传递文件描述符这么麻烦,为啥非要传递文件描述符呢,使用文件名不也是一样的么?那么恭喜你,你也有更我一样在践行陶渊明老前辈看事物“不求甚解”的作风。传递文件描述符还是有它的必要性的,一方面,文件描述符代表的不只是一个文件,它还包含了文件打开的状态,比如 seek 的位置等,有点进程之于可执行程序的意思,拿到文件描述符也就拿到了这些动态的信息;另一方面,文件描述符不只对应于本地文件,它为了一众可读写对象提供了统一的读写接口,包含什么呢?本地文件、(匿名)管道、标准输入输出、甚至于 Socket 本身等……可以让你完全不关心文件描述符背后的实现是什么而方便实现自己的逻辑代码。 想通了以上道理,又有了以前似曾相识的感慨“古人诚不欺我”——前人留下的东西,必然有一定的合理性。这也是为什么我比较排斥看见一个软件不满意就立即重新造,尤其是能流传很广或者流程时间很长的软件,里面很多看起来不必要的东西,可能有其存在的合理性,最好的做法是尝试去改进,改进的过程了解其历史、学习其精髓,等自己胸有成竹的时候再下手重造不迟。额,跑题了…… 回到正题,之所以前段时间突然研究了一下 Socket 传递文件描述符的东西,是遇到这样一个需求:一个进程将自己的标准输入、标准输出和标准错误输出映射到另外一个进程相应的位置。带着对 Unix Domain Socket 的朦胧认识,写了一个简单的实现原型: // outlet.c #include <sys/socket.h> #include <sys/un.h> #include <string.h> #include <stdio.h> #include <errno.h> #include <unistd.h> #define SOCKET_NAME "/tmp/connection-uds-fd" int make_connection() { int fd; int connection_fd; int result; struct sockaddr_un sun; fd = socket(PF_UNIX, SOCK_STREAM, 0); sun.sun_family = AF_UNIX; strncpy(sun. Read On →

给 Doxygen 生成的文档中 Qt 的引用添加链接

额……这个标题怎么改读着都不怎么顺口,不过不用在意这些细节,问题不大 :) 上篇文章提到了 如何给DTK添加文档 ,给同事讲的时候有同事提出来最好能自动给对 Qt 的引用加上链接,我当时拍胸脯说文档里面 Qt 的类和方法随便引用,到时候一定让生成的文档可以链接到 Qt 的文档上。其实,到啥时候我也说不准……所以,还是研究了一下,翻了半天的 Stack Overflow 和 其他一些资料才搞清楚要怎么做到,这里记录一下。 如何在文档中添加外部文档的链接呢?官方文档 说得其实挺简单的: TAGFILES !最开始没有仔细看文档,理解歪了,以为 tags 文件是一个文档压缩包,添加到 TAGFILES 这项后面生成文档的时候自动下载,然后自动根据索引添加引用链接到文档中。所以,根据 doxygen generated documentation with auto-generated links to qt project 这篇文章,Doxyfile 配置文件写了: TAGFILES = qtcore.tags=http://doc.qt.io/qt-5/ \ qtgui.tags=http://doc.qt.io/qt-5/ \ qtwidgets.tags=http://doc.qt.io/qt-5/ \ qtxml.tags=http://doc.qt.io/qt-5/ \ qtnetwork.tags=http://doc.qt.io/qt-5/ 生成文档,怎么都不生效…… WTF ?! 继续 Google ,发现一个提交, 里面的 for i in core svg xmlpatterns; do curl -fsSLO "https://doc.qt.io/qt-5/qt$i.tags"; done; 引起了我的注意,恍然大悟: 原来这个 tags 文件就是索引文件,需要预先下载下来,之所以有 = 加上一个网址,是因为 tags 中只有类名到文档名的映射,并没有规定使用某种协议以及host。 Read On →

如何给 DTK 添加文档

背景 经过几年的摸爬滚打,DTK 作为构建 deepin 全家桶的基石,一直被说的主要有两个毛病: 内部人员觉得它不够稳; 外部人员觉得它无从下手; 第一个问题主要原因是 DTK 在最开始的时候缺失的东西太多,各种剧烈的变化同时进行,但是又没有比较好的版本控制和接口管理,所以经常是这个应用要用新版本,新版本删除了一个废弃的接口,用了旧接口的应用就崩了。由于最近 DTK 的变化日趋平稳,以及有了基本的版本控制,第一个问题渐渐淡出了人们的视野。 第二个问题外部人员无从下手的原因是 DTK 在开发过程中并没有留下接口文档,所以目前想使用 DTK,内部靠得是口口相传,外部靠的是阅读源码,完全的石器时代……甚至连社区的小伙伴都看不下去了,自己做了一个《Deepin开发指南》 。 是时候给DTK添加一下文档了! 工具选择 其实, DTK 之前是有写文档的,但是写得并不多,主要问题就是英文文档不好写。我也尝试写过,每个类、每个函数都只能憋出一句英文,这种文档跟没有是差不多的。所以,这里需要做一个艰难的决定:文档用中文来写,英文靠爱好者来翻译。 用什么文档工具呢? DTK 是基于 Qt 之上的开发库,最自然的想法是使用 QDoc,但是据使用 QDoc 搭建了 dde-file-manager 的 Github Pages 的 @BLumia 同学说 QDoc 对国际化的支持不是特别好,我们按道理是要支持中英双语文档的,遂放弃。除了 QDoc 以外,文档生成工具就是 Doxygen、还有一个KDE 项目自己的文档工具 KApiDox ,它们三者之间是什么关系呢?Doxygen 从 QDoc 上 fork 出来的,KApiDox 是基于 Doxygen 的封装……我没有怎么看 KApiDox ,所以就选择了 Doxygen 。 如何写 下面就是规则部分了。 1. 文档注释位置 为了保持头文件的清爽和干净,所有文档注释都要写在源文件中。 2. 多语言 按照 Doxygen 多语言处理的方式,需要在中文文档前添加 \~chinese 命令,在英文文档前添加 \~english 命令,这样设置 Doxyfile 中 OUTPUT_LANGUAGE=Chinese之后,就只会包含中文文档,而不会夹杂英文了,如: Read On →

关于 deepin-code-release 的一点新的思考

为什么要做 deepin-code-release 呢?其实我们在 deepin-code-release 的 README.md 中写得挺详细了: 从deepin项目启动开始,伴随着越来越多的deepin子项目产生,不同开源/商业定制版本的分割加剧,项目间的版本依赖问题、上游项目的patch丢失问题和系统环境无法恢复问题越来越严重,我们迫切需要一个统一的系统来帮助我们记录不同版本的ISO/软件仓库的状态,做各个子项目版本的版本控制和patch的版本控制,以达到快速恢复开发/系统环境,进而使针对不同系统版本的开发更加高效。 deepin release系统就是这样一个辅助系统,它的目标在于将它的每一个状态都对应到我们所有发布的ISO/软件仓库状态、每一个针对ISO/软件仓库的改动都能反映到这个仓库的改动上。 简而言之,deepin-code-release 是版本的版本控制管理工具,用来管理 deepin 众多“轮子”项目的版本号的,每次系统发布都需要进行一次记录,方便以后开发修问题的时候能找到当时的代码进行bug修复。 为了确保记录的准确,它的想法是这样的,每次(系统)发布前,深度的程序员各自检查一下自己负责的项目,如果需要跟随系统进行发布,就提交 CL 到 deepin-code-release 项目,这个 CL 会自动触发项目在对应仓库的打包,并且将打包结果反馈到 CL 的 Code Review 评分上,+1 分的就进行合并,反之闭门思过解决问题后再次提交,直到成功合并。 问题 以上需求还是听简单明确的,但是在目前的实现上却有一个问题:使用了 git-submodule 进行子项目的管理,再加上其他几个没有考虑的情况,这导致了好多小问题,以至于推行到现在还是阻碍重重: 1. 使用起来比较麻烦 deepin 的项目都是放在 gerrit 上的,它并没有一个统一的 git 用户(类似git@github.com中的git),所以同一个项目在不同开发人员的机器上的项目地址是不一样的,当成 submodule 放到 deepin-code-release 这个项目中以后,必须驱动项目地址中的用户名部分,再在 ~/.config/ssh 中添加一些额外的配置(参见 README.md )。 2. submodule 用起来比较别扭 最直接、也是抱怨最多的一点,是大家平常使用 git submodule 系列的命令并不多,所以对操作 git submodule 有不太习惯,而且就算是我比较熟练了,也总觉得 git submodule update 这个有点反直觉,感觉上应该是类似 git pull --recurse-submodules 的功能,但是实际上并不是这样。以至于很多人一不小心,把别个辛辛苦苦提交的更新又给退回去了。 3. 多了一个额外的仓库 原本的打算是每个开发都只需要克隆一个 deepin-code-release 项目,然后在其中 init 自己负责的项目并进行提交,需要关注多个项目的就按需 init 多个项目即可,但是实际推行的过程中还是发现大家并不是特别关注自己项目外的项目,deepin-code-release 里面就一个自己的项目初始化了,而且用着还挺别扭,还不如自己单独克隆一份,结果就每个开发上面既有一个自己项目的仓库,还要有一个包含了自己项目仓库的 deepin-code-release 项目,也是抱怨声颇多。 Read On →

15.7 研发心得——最好版本的台前幕后

15.7 终于如期地发布了……好吧,也就晚了2个工作日……毕竟这么好的版本,多等两天也可以的,对吧。需要多解释一句的是,我们之所以也没有按照往常的套路——拖到周五发,是因为周五刚好是情人节,毕竟程序员找个女朋友不容易,所以就拖了两天……这应该是个好借口吧 :P 发完系统第一件事情当然就是写《研发心得》咯,不知道从什么时候开始,《研发心得》成了发布标配,上午发系统,晚上就要《研发心得》,我只能微笑着说……嗯,挺好的!不过虽说是研发心得,但是别人看了我的心得以后都说像软文。我的想法是这样的:像软文就像软文嘛,让各位支持deepin的朋友看得舒舒服服的同时还能了解新功能,多好! 不过这次我准备换个风格,重点是真实。所以,这次的心得我准备说说 15.7 这个版本的台前幕后。 台前&幕后 “这是我用过的最好的deepin版本”。 我预测应该有很多用户会跟我有同样的想法,毕竟,对于发了这么多版本的我来说,15.7 是第一个版本让我有重新完整安装一次这样冲动的版本。三年多以来,每逢系统发布前,我都会挑一个良辰吉日加上一个好时间,这个时间其实主要取决于版本发布的延期情况而定,隆重地安装一下即将发布的新版本的ISO,说是为了测试一下其实是骗人的,毕竟我也测试不出什么bug来……主要是装一下心里面爽啊,你们要明天才能下载,我今天就用上了,呵呵呵…… 虽说每次的ISO我都安装过,但是我从来没有舍得把我现在在用的系统格式化掉重新安装,因为这个老家伙从deepin切换仓库到Debian我重新安装了一次系统开始就一直陪伴着我,没有必要的话,我是想一直让它继续往上升级的。直到这次15.7发布,我感觉它又是一次值得纪念的发布才想着来一次完整重装,不过冲动归冲动,我还是按捺住了心中那团火——还是没有重新安装,因为思来想去,升级上来的也是一样的嘛 :) 这次升级可以分为两大部分,一部分是DDE的优化,另一部分是仓库同步Debian上游。从一个用户的角度出发,我觉得吸引我的地方,或者说值得用户期待的地方主要有这么几个: 更快的启动速度 这个主要得益于“林姐”亲自操刀的文件预热技术warm-sched,它主要的原理是这样的,大家知道操作系统在启动的过程中,会进行大量的IO操作,这个在CPU性能不是问题的平台上就是启动慢的罪魁祸首了,大家还知道Linux内核其实本身是有文件缓存机制的,被缓存的文件访问会非常非常快,所以如果我们在系统加载的适当时候能进行一定的预热,那么系统加载的时间当然就会大大缩短了。 不过这个会导致的一个问题就是,用户登录的速度变得飞快(从原来的10s+变成3s),但是系统好像在deepin水波纹的时间似乎更长了,其实不用”似乎“,真的会这样,文件预热技术不是神话,它没办法吃掉那部分加载文件的时间,它能做到的只是在合适的时间点预热下一个阶段需要的文件。 ”这不是拆东墙补西墙么?“你可能会这么问,但是我要告诉你还真不是,如果没有预热,系统加载文件的过程是”乱序“的,这里的乱序是指文件存放不一定是顺序存放在磁道上的,乱序的文件访问会导致磁盘访问的过程中转来转去的,效率低下;相反,warm-sched不仅只是对文件预热,加载的过程可以保证磁盘的顺序访问,文件多了的话,这部分优化还是比较可观的…… 我记得以前有位同事总是喜欢开玩笑说”苍蝇也是肉啊“,当时在饭桌上没少让人倒胃口,但是这句话用在性能优化、以及上面这个例子上算是再合适不过了。 更少的资源占用 首先是电量,如果你是笔记本的话,应该能感受到笔记本续航的提升,deepin测试人员实测的数据是以前3小时续航能力的笔记本,待机会多出30分钟+的时间,也就是提升差不多有17%,跟使用powerstat这个工具测试的效果基本相差不大。那是不是原来待机4个小时的笔记本,也只会多出30分钟的续航时间呢?并不是的,因为这是一个功耗比例上的变化,这次优化以后理论上可以增加的待机时间就是 原来的待机时间x17% 了,如果你的电池健康程度够的话,应该能有更大的优化效果。 不过,这些都是在使用电池的情况下的数据,因为默认情况下deepin系统只有在拔掉电源的情况下才会自动进入节能模式,如果你想在连接电源的情况下也开启节能模式,我是说假如你真这么环保的话,你可以在控制中心的电源模块手动打开节能模式;相反,如果你像我一样不在乎耗电,只追求卓越的性能,你也可以随时把节能模式关掉,大丈夫就是这么帅,不怕编译的时候机器烫手;总之,由着你的性子来! 另外一个能明显感受到的变化是开机内存的减少,这里所说的开机内存是指在没有任何开机启动项的情况下,DDE达到稳定状态的一个内存值,由原来的 1.1G 占用降低到 830M 左右,在使用独显的情况下,内存占用会更低,简直令人发指!好处是什么呢?更低的内存占用意味着DDE变得更加轻量,应用程序可以占用更多的系统资源,例如你是chrome这个内存占用大户的用户,15.7 可以让你在系统不变卡的情况下多开十来个标签页呢,是不是很开心? 不过做这些优化的过程中最让我感到意外的是DDE对电量消耗的“助攻”竟然没有大家预想的那么多,进程抽风性地CPU占用高、间歇性地进程状态切换等居然连硬件功耗的零头都占不到,不过该改的地方一个都不少,所以,DDE 的CPU占用高的问题在15.7中也可以不用再见了。 更新的软件和驱动 这个就不用多说了,搭载了Debian上游最新的一波升级,你想要的“更新的软件”、“更新的驱动”统统都给你,就是这么大方!而且,这次你收到的不仅仅是一次更新带来的快感,更是deepin更新会变得更加快、准、狠的承诺。在15.7的需求中我们争论了好多次,一方说已经有太多用户吐槽我们软件不够新、基础库不够新,用户需要新的软件;另一方说更新太快容易导致用户环境不稳定,我们毕竟是一个面向普通用户的发行版;争论不休,都可以开一个深度辩论赛了……最后终于达成一致,我们希望能更快速的将软件更新推送给用户,不再一次性积累大批量的更新,同时保证一定的节奏,确保快速更新的同时不会挂挂挂。 另外,值得一提的是论坛用户和老板不停的要求、催促和威逼利诱下,我们终于——终于把PRIME方案引入到了深度显卡驱动管理工具中,现在如果你是双显卡(N+i)用户,你只要小手一点,就可以方便地在几个预设方案中轻松切换了……嗯,不辛苦,用户和老板高兴就好 :) 一点感悟 上面说了这么一大堆,其实当时为了准备这些优化的内容的时候,心里面还是比较慌的,因为系统优化这事儿做起来远没有听起来那么爽,尤其是在没有既定方法的情况下要定一个优化目标出来,还是相当无助的,而且一旦你陷入 盲目—烦躁—焦虑 的怪圈中,就很难再痛快地出来,这就是这次15.7所面临的第一个挣扎。 我跟几个程序员都交流过,程序员大多都有比较强的焦虑感,再加上程序员多有洁癖,动不动这不清真那不科学,更容易掉进上面这个怪圈,在这个怪圈里面,你要么有一天实在承受不了了,咔嚓——破罐子破摔,从此成为浩瀚宇宙中的一粒尘埃;要么有一天你想通了:“还想个毛,就是干”,然后挑一件事后跟别人扯淡都羞于提起的小事,慢悠悠地开始做,做完了你会发现你的心理负担变轻了不少,然后再挑一件小事,接着干……越干目标越近,焦虑感也越来越少……最终,完成发版大业。 所以,当时我们不知道到底优化目标定成什么样子,那就捡最笨的方法,跟其他几个操作系统:Ubuntu、Win7、Win10做一个横向对比,看看其他几家的情况,至少做到在单一侧面都不是最差的吧?(做到任一侧面都是最好的,就留作下次优化的目标吧,毕竟大家都等着咱们发版呢。)定完了就朝着目标开始研究怎么使用优化的工具:perf、valgrind、heaptrack、google-perftools等,大家都不怎么有经验?那就学一个培训一个,各自有任务去练习……等优化的patch都集成完了,对比下优化目标,不够或者还不满意就再来……所有15.7可见的优化都是这么一点点的“苍蝇肉”拼出来的。 刚好最近在Twitter上看到的一段话,可以把我上面想说的非常明白的表达了出来,把这段“心得”分享给大家: 真的,诸位,有什么难事千万别耗着,别等着,那只会让人在无尽的焦虑中煎熬,你就先大吼一句:“去你妈的。”然后两眼血丝地去推进,去做事,做着做着就有出路了。