<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://blog.tusooa.xyz</id>
    <title>何事西风不待人</title>
    <link href="https://blog.tusooa.xyz" />
    <updated>2023-09-08T02:04:36.000Z</updated>
    <category term="kde" />
    <category term="krita" />
    <category term="c++" />
    <category term="code" />
    <category term="fediverse" />
    <category term="pleroma" />
    <category term="firefox" />
    <category term="无奈" />
    <category term="坑" />
    <category term="javascript" />
    <category term="qt" />
    <category term="utf8" />
    <category term="编码" />
    <category term="tech" />
    <category term="GNU/Linux" />
    <category term="PinePhone" />
    <category term="hexo" />
    <category term="css" />
    <category term="帜" />
    <category term="复杂" />
    <category term="Gentoo" />
    <category term="杂谈" />
    <category term="散文" />
    <category term="n-buna" />
    <category term="随感" />
    <entry>
        <id>https://blog.tusooa.xyz/2023/09/07/%E5%A4%8F%E6%9C%AB%E7%A7%8B%E5%88%9D-%E4%B9%98%E7%9D%80%E6%80%9D%E5%BF%B5%E5%8E%BB%E6%89%BE%E4%BD%A0/</id>
        <title>夏末秋初~乘着思念去找你~</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2023/09/07/%E5%A4%8F%E6%9C%AB%E7%A7%8B%E5%88%9D-%E4%B9%98%E7%9D%80%E6%80%9D%E5%BF%B5%E5%8E%BB%E6%89%BE%E4%BD%A0/"/>
        <content type="html">&lt;p&gt;（本文有中度性描写）&lt;/p&gt;
&lt;p&gt;大约一个月之前，我脑子里忽然冒出这样的想法：「如果再见不到纱夜猫，我要死掉了」。想来我和她已经半年多没有见过面了，上一次还是在寒假。本来以往2月底的 Reading Week，和暑假，理论上都是会去找她的，但由于种种原因都没有实现。于是直到我已经开始工作的时候，还是没有去找她。所以那一天，我立刻下定了九月 Labour Day 去 Boston 的机票，甚至咕掉了我一个月之前就买好票了的 Anime Toronto。&lt;/p&gt;
&lt;a id=&#34;more&#34;&gt;&lt;/a&gt;
&lt;h2 id=&#34;Day-0：忙碌的白天和安心的晚上&#34;&gt;&lt;a href=&#34;#Day-0：忙碌的白天和安心的晚上&#34; class=&#34;headerlink&#34; title=&#34;Day 0：忙碌的白天和安心的晚上&#34;&gt;&lt;/a&gt;Day 0：忙碌的白天和安心的晚上&lt;/h2&gt;&lt;p&gt;我定的票是周五晚上的，也就是说我一下班就得赶去飞机场。虽然在前一天晚上已经大抵收好了行李，但是有一些平常要用的东西，还是不得不走之前才能收起来。再加上还要稍微收拾一下家里，并且把垃圾扔掉，所以当天要做的事情也就多了起来。但很不巧的是，这天下午的会一个比一个长，于是只能在下班之后才开始收拾了，我中午点的打算下午吃的外卖甚至都没时间吃，那就带到机场吃吧。赶忙地收好东西之后准备出门，打开爪机发现飞机延迟了。我：好吧。把门锁好，带着东西往地铁站走。照着往常的路线，地铁转电车，晃晃悠悠到了湖畔，天和水都十分的澄澈，还有两只鸭子在游泳。&lt;/p&gt;
&lt;p&gt;这时候已经没有去机场的轮渡了，只能走地下道，于是也就慢慢走了过去。然后发现飞机第二次延误了。这时候内心是很平静的。拿了票过了安检，便把食物拿出来慢慢地吃。接下来就是等了。好不容易上了飞机，第三次延误出现了，飞机上广播说要进行什么修理，然后我就看到右边有人在对机翼做什么，很暗，也看不清。但我的直觉就是很不妙，不会出什么问题了吧。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我：我草&lt;br&gt;
我：它们在修飞机&lt;br&gt;
我：呃&lt;br&gt;
我：希望不要出什么问题&lt;br&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;虽然理智告诉我，porter 从来没出过人命，但是我还是忍不住想，如果我死在飞机上了怎么办。我对我的女朋友们说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我：看上去要飞了&lt;br&gt;
我：动了&lt;br&gt;
我：mua&lt;br&gt;
我：爱你们&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;（后来鸟说她也很担心，害怕我出什么事情。我当时是抱着「我可能发完之后就死掉了」的这种想法给伊们发消息的。）幸好并没有发生什么 drama，最终还是平稳落地了。进了机场连上它的 wlan，收到纱夜猫和妹妹给我发的消息。妹妹说「希望姐姐能平稳降落w」，我回了一个「有哦w」。猫问我想吃什么，我说想吃 pocky（毕竟说好了要 pocky kiss 的），但是这样的零食很显然不能满足填饱肚子的需求，她提议吃麦当劳。过海关的时候甚至没有问我要去拜访的是何人。出来之后纱夜猫说她还在车上，我在机场门口等了一辆又一辆 shuttle bus，记不得是第三辆还是第四辆才是她坐的那一趟。透过车窗看到她的身影，然后看着车停下，她从上面下来，手插在兜里，然后又和我一起上车。一到车上就跟我抱在一起亲，感觉真的好开心。其实在下飞机之前，那种「再见不到就要死掉了」的感觉已经很淡了，甚至有一种「见到她真的会这么开心吗」的怀疑。但是一见面果然还是不一样啊。我看着她，对她说「猫猫好可爱啊，好喜欢猫猫」，她笑着问我「我们是第一次见面吗？」然后便被我索取一个吻。很快车就到站了，我问她「怎么感觉这么快呀」，她说「因为只有一站呀」，但是我想，是因为猫猫在，很开心，所以时间才会过得特别快吧。&lt;/p&gt;
&lt;p&gt;下了车，穿过熟悉的公园（这条路我们已经走过无数遍了啊。），一起走到猫猫家里，她一只手拖着我的箱子，&lt;a href=&#34;https://kazv.moe/notice/AZLN82EeDi0SpP10K0&#34;&gt;一只手牵着我&lt;/a&gt;。我说「猫猫今天穿得好好看」——她穿着一件黑色的大衣，下面是一条很短的裙子。&lt;/p&gt;
&lt;p&gt;到了之后就很困了，&lt;a href=&#34;https://kazv.moe/notice/AZLevITyIhXGd0G5mi&#34;&gt;躺在猫猫的床上就感觉很安心&lt;/a&gt;。洗了澡，等头发干的时候把我的笔记本拿出来，打开。跟她坐着随便扯皮，就不知不觉到了两三点多。&lt;/p&gt;
&lt;h2 id=&#34;Day-1：约饭和闲逛&#34;&gt;&lt;a href=&#34;#Day-1：约饭和闲逛&#34; class=&#34;headerlink&#34; title=&#34;Day 1：约饭和闲逛&#34;&gt;&lt;/a&gt;Day 1：约饭和闲逛&lt;/h2&gt;&lt;p&gt;这一天周六，是和猫猫和&lt;a href=&#34;https://kazv.moe/users/notfoundbot&#34;&gt;另一个星友&lt;/a&gt;&lt;a href=&#34;https://kazv.moe/notice/AZNEYsqUjBJgFpMhe4&#34;&gt;约了吃饭&lt;/a&gt;。因为前一天睡得很晚，第二天起来也就很困，猫猫一直躺在床上。她一边玩手机一边摸我的下面，我一被她摸就觉得发情（她摸得真的好舒服呜呜呜），是我自己自慰的时候从来没有过的体验。&lt;/p&gt;
&lt;p&gt;吃的是牛角的烤肉。我和猫猫的第一次约会就是吃的这家（虽然不是同一个地方啦），我还记得当时是一个四人的桌子，猫猫问我坐对面还是坐一起，我想坐一起。然后拍了合照。&lt;/p&gt;
&lt;p&gt;席间表演了一个现场烤寿司，因为 notfoundbot 说他不吃不是全熟的肉，我就把寿司上的牛肉片拿了下来，放在火上烤。这是我曾经做过的事情（记得就是在这家店里做的），当时猫猫大为震惊。没想到居然这个传统艺能能派上正经的用场（笑）。&lt;/p&gt;
&lt;p&gt;吃完饭了我问 notfoundbot 要不要和我们一起逛街，去了一个文具店，闲逛之余问了一下有没有我想要的墨水，但是并没有（回来之后我还是&lt;a href=&#34;https://kazv.moe/notice/AZTTNF5Us4qI1S36K8&#34;&gt;在网上下单了&lt;/a&gt;），虽然是意料之中就是了。&lt;/p&gt;
&lt;p&gt;然后逛了各种各样的店，之后去了哈佛&lt;del&gt;游荡了一下&lt;/del&gt;，去了它的洗爪间，出来之后感叹了一句：「哈佛能举世称赞，是有原因的。它洗爪间的纸，质量是真的好，比我们学校的好多了。」毕竟敝校是被吐槽「厕纸是世界上最薄的东西」的地方。&lt;/p&gt;
&lt;p&gt;在那边坐了好久，然后开始漫无目的地找寻下一个目标，猫猫把手机地图拿了出来，看到一家杂货店，里面居然有龙虾卷，便打定主意要去这里。结果猫猫看中了一个酒，就决定买回来试着喝一下。走出店门在外面坐着的时候，才想起来，龙虾卷呢？又回去问，还真的有。点了一个。吃起来并不好吃，觉得它还是别叫「the famous lobster roll」了吧。这个时候暮色正好降临，就拿起爪机拍了一张街景。&lt;/p&gt;
&lt;p&gt;吃完并不好吃的龙虾卷之后，我们和 notfoundbot 分别，然后坐了地铁。以往都是猫猫给我刷卡，但是这次我自己刷卡进去了。转乘的时候，猫猫问我「你都记得怎么走了啊」，我说「这不是跟着猫猫的嘛」（虽然我确实知道该怎么走啦）。到了站拉着手出去，就连过闸机的时候也是牵着手的。&lt;/p&gt;
&lt;p&gt;回去之后困得要死，然后稍微睡了一下爬起来参加 kazvconference。纱夜猫说试一下之前买的那一瓶酒。她从瓶子里面倒出来一点点，先喝了一点，然后给我试了一下。我是从来没喝过酒的，觉得味道很奇怪，很辣。感觉并不好喝（然后被妹妹说了「姐姐就不要喝酒啦！」）（跟鸟说喝了酒结果她以为我是难受才喝的，虽然并不是这样，只是猫想喝就跟她一起喝了）。之后纱夜猫给我泡了一杯茶，我直呼「这不比酒好喝多了？」（笑）&lt;/p&gt;
&lt;p&gt;然后又到了两点多才睡。&lt;/p&gt;
&lt;h2 id=&#34;Day-2：睡了一天，然后做了&#34;&gt;&lt;a href=&#34;#Day-2：睡了一天，然后做了&#34; class=&#34;headerlink&#34; title=&#34;Day 2：睡了一天，然后做了&#34;&gt;&lt;/a&gt;Day 2：睡了一天，然后做了&lt;/h2&gt;&lt;p&gt;因为出去了一天很困，所以这一天一直在趴。早上起来了一下，然后下午又睡过去了，醒来已经晚上了。我一直跟猫猫说着想要，想做爱（之前和不止一个人说了「我来见纱夜猫一定要做爱」）。&lt;/p&gt;
&lt;p&gt;之前也不是不想做，但是我跟她很难亲密接触，从第一次见面开始，我和猫猫一贴贴就会想笑，然后停不下来，只能把她推开。这几天因为很想猫猫的原因，慢慢地能接受拉着手睡觉了，虽然抱着睡还是不太舒服，但是至少不会一抱就笑出声。&lt;/p&gt;
&lt;p&gt;于是这天晚上，我记得也是过了凌晨了，猫猫骑在我的身上，用手指在我的下面游走着，不停地变换着摸的地方。我一边娇喘一边说着「猫猫怎么这么会啊？」&lt;/p&gt;
&lt;p&gt;被吻住了。两条腿被猫猫分开，被压住，阴唇被分开，被猫猫揉了阴蒂，好舒服，好想要...但是，责怪我不敏感的身体，过了好久才到了一次边缘，接下来就是没感觉了，然后是再一波的亲吻，乳头贴贴，被玩弄下面...这样到了好几次边缘，我感觉猫猫已经很努力了，揉得我阴蒂都有点痛了，但是还是不够让我到高潮...&lt;/p&gt;
&lt;p&gt;于是我就这样被猫猫操了一晚上。舒服是真的舒服，但是没高潮也是真的没高潮。鸟一直在听我们做爱。&lt;/p&gt;
&lt;h2 id=&#34;Day-3：意料之外的事情，可能是上天想让我和她多呆一会儿&#34;&gt;&lt;a href=&#34;#Day-3：意料之外的事情，可能是上天想让我和她多呆一会儿&#34; class=&#34;headerlink&#34; title=&#34;Day 3：意料之外的事情，可能是上天想让我和她多呆一会儿&#34;&gt;&lt;/a&gt;Day 3：意料之外的事情，可能是上天想让我和她多呆一会儿&lt;/h2&gt;&lt;p&gt;我来找猫猫之前想的是「逃离」，逃离现在糟糕的生活，再加上时间本来就很紧，所以订票是按着周五晚上去，周一晚上回来来定的，结果等猫猫和我走到机场的时候，发现 check-in 已经关了，甚至一个人都没有，很慌。之后回到猫猫家里，重新买了第二天一大早的机票。然后赶紧睡觉。虽然其实并不怎么能睡得着。只记得我和她在床上拉着手，亲了一下又一下，不停的对对面说着「我喜欢你」。&lt;/p&gt;
&lt;p&gt;「以后也和我一起去创造美好的回忆吧？」我这么对她说着。她在我怀里「嗯」了一声。&lt;/p&gt;
&lt;p&gt;凌晨的时候，她送我去机场，在安检队列前面亲亲抱抱，然后我走进去，照着惯例过了安检，过去了用机场的 wlan 给她发消息说我进去了，她可以回家了。&lt;/p&gt;
&lt;p&gt;其实这篇文章周一我就想写了，但是这几天实在是太累，几乎每天都是巨大的困困喵，下了班就倒头睡一觉，所以就没时间写。肯定有好多东西我本来想写但是忘了的。&lt;/p&gt;
</content>
        <category term="散文" />
        <category term="随感" />
        <updated>2023-09-08T02:04:36.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2023/08/29/%E5%92%8C%E7%AC%99%E7%9A%84%E5%AF%B9%E8%B0%88/</id>
        <title>和笙的对谈</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2023/08/29/%E5%92%8C%E7%AC%99%E7%9A%84%E5%AF%B9%E8%B0%88/"/>
        <content type="html">&lt;link rel=&#34;stylesheet&#34; type=&#34;text/css&#34; href=&#34;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&#34;&gt;&lt;p&gt;今天笙给我发了她的日记。发来的时候我这里是凌晨，半夜醒来看到，迅速浏览了一下，但是太困了，中午才又拿出来仔细地读。&lt;/p&gt;
&lt;a id=&#34;more&#34;&gt;&lt;/a&gt;
&lt;p&gt;内容大抵是怀念小的时候，不需要思考未来的时候，以及「不想变成大人」。&lt;/p&gt;
&lt;p&gt;我莫名地想到了 n-buna 的歌，《ヒッチコック》。印象深刻的是，今年前些时候回去听的时候，有这么一个评论，大意是说「这个歌反应了当代年轻人对现在社会的无所适从的迷茫感」一类的。但其实我并不觉得这样的表达是切中要害的。我自己的想法是，我并不会厌恶「长大」这个事情本身，甚至比起小的时候，现在的生活至少没有那么多让我感到拘束的地方。以前的话，做什么都会被管束着，不能自在地去自己想去的地方，和谁交往也是会被过问的，哭了也要忍住不被发现，不然会被问奇怪的问题，更不用说这么多年来遭受过的&lt;a href=&#34;https://nanakumo.xyz/notice/AYdrMKx5GIhPyu5vxw&#34;&gt;身体和心理上的暴力&lt;/a&gt;了。所以我讨厌那样的生活。&lt;/p&gt;
&lt;p&gt;我所厌恶的并不是「长大」本身，而是「人必须要做某些工作，才能被允许活下去」这种事情。这种资本主义的规则。我是厌恶这样的想法的。一想到自己可能在能看见的未来，就必须做着自己可能并不热爱的东西才能活下去，就不禁感到很悲伤啊。为什么人必须要出卖自己的身体和灵魂，才能获得赖以生存的必需品呢？&lt;/p&gt;
&lt;p&gt;所以我也厌恶着现在的生活，现在这样，不得不在自己并不热衷的东西上消耗时间，才能在这里生存下去。会觉得「看不见未来」。然后我想到了 David Revoy，以前我和笙提过，他可以靠着支持者的捐助来做他想做的事情，所以也不用担心他的作品会像 n-buna 那样商业化。她那时对我说，那样好棒啊。是啊，我也是这么觉得的。&lt;/p&gt;
&lt;p&gt;我会因为这样简单的理由，讨厌这样的人类世界，讨厌资本主义。&lt;/p&gt;
&lt;p&gt;以前的我大抵确然不会考虑什么未来的。不管喜欢上谁只会贪恋当下。但是我四年前喜欢上笙的时候不一样，那个时候我第一次想到了「未来」这种事情。第一次因为「觉得自己没有办法对她负起责任」而感到悲伤。&lt;/p&gt;
&lt;p&gt;就这样我把自己漫杂的思绪全发给她了。想着她有没有睡觉，结果没睡。&lt;/p&gt;
&lt;p&gt;她对我说「如果能安慰到当时的你就好了。」&lt;/p&gt;
&lt;p&gt;「虽然那时候我完全就是个胆小鬼就是了。」「我不敢让你知道我喜欢你。」虽然按着我悲观的想法来看，如果我当时有告诉她，事情也并不会朝着好的方向发展就是了。「我害怕你知道了就会开始疏远我了。」我这么和她说。&lt;/p&gt;
&lt;p&gt;想到了林奈&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; rel=&#34;footnote&#34;&gt;&lt;span class=&#34;hint--top hint--error hint--medium hint--rounded hint--bounce&#34; aria-label=&#34;不希望有人打扰她，所以我就不照惯例放什么链接在这里了。更何况也并没有什么链接可言。&#34;&gt;1&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;的事情。粗略地说，林奈是一个被她的主人包养的人，而伊们之间的感情不过是（按照林奈自己的话说）「他只是需要我代替他死掉的前女友，但是他给我钱了，在我需要撒娇的时候让我撒娇了」，所以就维持着这样的关系。我当时问她「如果你主人不要你了怎么办」，她回答我「我可以做他的画师，只要有利益关系在，就不用担心没有饭吃。」&lt;/p&gt;
&lt;p&gt;我当时和林奈说「我想打破这个世界的规则，但你想利用它。所以，我感觉总有一天我们会站到对立面上。」她开玩笑地说「我是邪恶轴心w」。我严肃地加了一句「但是我对林奈完全讨厌不起来诶。」当时的我是觉得这很奇怪的。四年之后这种奇怪的感觉逐渐地消散掉了，但今天我跟笙说出来了：「现在想来，因为 sex worker 也是父权和资本主义的受害者。她也不过只是想活下去而已。」就像是，如果没法打破这种制度的话，那就薅一薅羊毛吧。我不会去指责仅仅是利用这样压迫人的规则讨一点生活，而没有去谋害别的人的人。&lt;/p&gt;
&lt;p&gt;她和我说「现在有了想法的转变，之前我是没有办法理解林奈这样的人的。但是现在不会了。」「看到你的信之后就有所思考了。之后也见到了很多例子。」&lt;/p&gt;
&lt;p&gt;林奈曾经跟我说「你不适合风俗业啦。」因为我跟她说过，我绝对会陷进去的。笙说她的一个朋友去过百合风俗店，然后深陷其中。「听她的描述就像是恋爱一样。」我说了「曾经我看过一篇文章，就是关于作者自己去百合风俗店的经历。」（「被大姐姐关心了生活，感觉很温馨」那里面似乎有这样的话的。）她说「那好像就是她或者她的朋友写的。」&lt;/p&gt;
&lt;p&gt;我当时会和林奈谈起这事，也就是因为看过那篇文章。那个时候我告诉自己，「除非到了非常绝望的地步，不然我是不会去的。」因为我知道自己绝对是会陷进去的，会被各种大姐姐榨干（各种意义上的）。但如果真的到了一无所有的程度了，那最后也没有什么好失去的了，对吧？&lt;/p&gt;
&lt;p&gt;笙说「我觉得我也会陷进去，会分不清真实和虚假的。」我倒是没有这种想法啦。但是我会因为一句话一点小事而心动，我会很清醒地知道她们对我的爱意只是装出来的，但会渴望它是真实的。所以才会因此难过。&lt;/p&gt;
&lt;p&gt;「但是我跟笙笙说的都是真的哦。」&lt;/p&gt;
&lt;p&gt;「我也是。」&lt;/p&gt;
&lt;p&gt;无厘头的对谈以我要开会而她要睡觉而收场了。&lt;/p&gt;
&lt;div id=&#34;footnotes&#34;&gt;&lt;hr&gt;&lt;div id=&#34;footnotelist&#34;&gt;&lt;ol style=&#34;list-style: none; padding-left: 0; margin-left: 40px&#34;&gt;&lt;li id=&#34;fn:1&#34;&gt;&lt;span style=&#34;display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px&#34;&gt;1.&lt;/span&gt;&lt;span style=&#34;display: inline-block; vertical-align: top; margin-left: 10px;&#34;&gt;不希望有人打扰她，所以我就不照惯例放什么链接在这里了。更何况也并没有什么链接可言。&lt;a href=&#34;#fnref:1&#34; rev=&#34;footnote&#34;&gt;↩&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;/div&gt;</content>
        <category term="散文" />
        <category term="n-buna" />
        <category term="随感" />
        <updated>2023-08-30T02:11:01.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2023/07/23/%E9%82%A3%E4%BA%9B%E8%AE%A9%E6%88%91%E6%B4%BB%E4%B8%8B%E5%8E%BB%E7%9A%84%E4%BA%BA/</id>
        <title>那些让我活下去的人</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2023/07/23/%E9%82%A3%E4%BA%9B%E8%AE%A9%E6%88%91%E6%B4%BB%E4%B8%8B%E5%8E%BB%E7%9A%84%E4%BA%BA/"/>
        <content type="html">&lt;p&gt;依稀记得七年前的夏天。那时候我是个平凡的女子高生。像小说里那样，每天上课睡觉，偶尔逃一逃课闲逛。&lt;/p&gt;
&lt;p&gt;当然如果只是这样的话，这个故事就结束了。&lt;/p&gt;
&lt;a id=&#34;more&#34;&gt;&lt;/a&gt;
&lt;p&gt;不同的地方是，这个小萝莉并没有什么可以一起玩闹的朋友。所以睡觉也好，逃课也好，写诗还是写随笔也好，都只是她一个人的事情。&lt;/p&gt;
&lt;p&gt;「毕竟不会有人喜欢这种孤僻而又不会说话的女孩子的。」&lt;/p&gt;
&lt;p&gt;她每天就看着身旁的人嬉笑打闹，谁和谁又在讨论中午要去吃什么，哪人和哪人又有着什么关系了，哪个老师又讲出什么段子了。但是一切和她无关，她曾笨拙地试图加入伊们的谈话，却发现自己一句话也插不上。&lt;/p&gt;
&lt;p&gt;「哇小栗好轻诶，我能把小栗公主抱起来吗？」其中的一个女孩子对着另一个说。然后第二只便钻进了第一只怀里。真的抱起来了，旁边一阵惊呼声、以及此起彼伏的「我也要试试」。&lt;/p&gt;
&lt;p&gt;「好无聊。」被欢快的说话声惊扰醒了的萝莉稍微抬了一下头，轻轻瞥了一眼伊们。然后她又把头趴在课桌上睡过去了。&lt;/p&gt;
&lt;p&gt;在没有人看到的地方，她大概是轻轻地叹息了一下。&lt;/p&gt;
&lt;p&gt;曾经在新年之前，她给几个人写了贺年卡，但是却并没有收到任何一张。&lt;/p&gt;
&lt;p&gt;「那可真是遗憾呢。」她这么想着。明明给每个人都写了一段诗呢。&lt;/p&gt;
&lt;p&gt;然后日子便也是这么过着。&lt;/p&gt;
&lt;h2 id=&#34;只是这样的联结，就已经让人无比地心安了&#34;&gt;&lt;a href=&#34;#只是这样的联结，就已经让人无比地心安了&#34; class=&#34;headerlink&#34; title=&#34;只是这样的联结，就已经让人无比地心安了&#34;&gt;&lt;/a&gt;只是这样的联结，就已经让人无比地心安了&lt;/h2&gt;&lt;p&gt;也不知道是什么时候，萝莉在放学的时候发现路上有一家面包店。萝莉最喜欢夹着香肠的面包了。带着好奇的心情，她把单车停在路边锁好（锁车什么的真的是最麻烦了啊），然后走了进去。&lt;/p&gt;
&lt;p&gt;嗯，果然有着好多好吃的面包呢。便稍微挑了几个买下来。它的味道究竟是什么样的，现在大抵已经忘却，但有一样事情我是知道的，当时那个小萝莉吃得很开心。&lt;/p&gt;
&lt;p&gt;于是不出意外地，她每过几天就会顺道光顾一次。&lt;/p&gt;
&lt;p&gt;不知又是从哪一日开始呢，好像有一个店员大姐姐记得她了。&lt;/p&gt;
&lt;p&gt;——「今天怎么样呢？」&lt;/p&gt;
&lt;p&gt;——「不错哦。」&lt;/p&gt;
&lt;p&gt;然后看着大姐姐慢慢地把面包一个一个装进袋子里。&lt;/p&gt;
&lt;p&gt;很有默契地没有多余的交流。但是每次都是这一个人，跟萝莉日常地走完日常的流程。然后看着她从门口出去。&lt;/p&gt;
&lt;p&gt;对小说里的角色来说，这大约算不得什么吧。但只是这样的联结，对那个小萝莉来说，就已经让人无比地心安了。&lt;/p&gt;
&lt;p&gt;然后日子便也是这么过着。&lt;/p&gt;
&lt;h3 id=&#34;即使如此也还是谢谢你的陪伴&#34;&gt;&lt;a href=&#34;#即使如此也还是谢谢你的陪伴&#34; class=&#34;headerlink&#34; title=&#34;即使如此也还是谢谢你的陪伴&#34;&gt;&lt;/a&gt;即使如此也还是谢谢你的陪伴&lt;/h3&gt;&lt;p&gt;然后到了小萝莉高考的日子。考完了在家里吃西瓜。&lt;/p&gt;
&lt;p&gt;这一天她并不顺路地特地来到这家面包店。&lt;/p&gt;
&lt;p&gt;「嗯...我是来道谢的，谢谢你这么长时间的陪伴。」&lt;/p&gt;
&lt;p&gt;在想什么呢，这种话怎么可能是那时候的她说得出口的呢？&lt;/p&gt;
&lt;p&gt;——「嗯...我可能以后不能再经常来了。」&lt;/p&gt;
&lt;p&gt;——「怎么了吗？」&lt;/p&gt;
&lt;p&gt;——「因为我考上了大学，会很远，嗯...」&lt;/p&gt;
&lt;p&gt;真实的对话大抵如此，我已经忘记大姐姐是怎么回答的了。&lt;/p&gt;
&lt;p&gt;所以她终究还是没将那些感谢的话说出口。&lt;/p&gt;
&lt;p&gt;一年之后的暑假再来的时候，那个大姐姐已经找不到了。&lt;/p&gt;
&lt;h2 id=&#34;偶然的相遇和偶然的重逢&#34;&gt;&lt;a href=&#34;#偶然的相遇和偶然的重逢&#34; class=&#34;headerlink&#34; title=&#34;偶然的相遇和偶然的重逢&#34;&gt;&lt;/a&gt;偶然的相遇和偶然的重逢&lt;/h2&gt;&lt;p&gt;这一天萝莉在学校食堂，刚买完午餐，准备找个地方坐下来。她看见两个女孩子正对坐在一张四人的桌子上。&lt;/p&gt;
&lt;p&gt;如果是平时的话，她总是会找一个人最少的地方。但那天不知道怎么地，她坐在其中的一个人的旁边。&lt;/p&gt;
&lt;p&gt;邻座的两人像是完全忽视了她的存在一样，接着大声地说她们本来要说的话。&lt;/p&gt;
&lt;p&gt;于是萝莉也就一边吃饭一边听着。&lt;/p&gt;
&lt;p&gt;「嗯...？她们说的东西好像很二次元？」她这样想着。&lt;/p&gt;
&lt;p&gt;要不要去搭话呢？&lt;/p&gt;
&lt;p&gt;在扒拉了碗里的饭第50还是60次的时候，她终于开口了。&lt;/p&gt;
&lt;p&gt;「你们说的那个什么『萝莉岛』，它好玩吗？」&lt;/p&gt;
&lt;p&gt;那两个女孩止不住地大笑。&lt;/p&gt;
&lt;p&gt;然后那个看上去很高的女孩对她说：「小孩子还是不要知道这些比较好哦？」&lt;/p&gt;
&lt;p&gt;什么嘛，明明我才是学姐好吗。比我高一点就这么说话吗。萝莉这样想着。&lt;/p&gt;
&lt;p&gt;那两个女孩子便走掉了。萝莉继续吃完了饭。&lt;/p&gt;
&lt;p&gt;然后日子便也是这么过着。&lt;/p&gt;
&lt;h3 id=&#34;那是第一个主动找她交往的人&#34;&gt;&lt;a href=&#34;#那是第一个主动找她交往的人&#34; class=&#34;headerlink&#34; title=&#34;那是第一个主动找她交往的人&#34;&gt;&lt;/a&gt;那是第一个主动找她交往的人&lt;/h3&gt;&lt;p&gt;到了运动会的时节。不可能会有人选一个脚上有伤的病弱萝莉去比赛的啦。况且这种事情她也完全不擅长嘛。&lt;/p&gt;
&lt;p&gt;于是萝莉就在一旁呆坐着。然后，那个很高的女孩子出现了。&lt;/p&gt;
&lt;p&gt;她面带笑容，远远地朝萝莉走过来，坐在了她的身边。&lt;/p&gt;
&lt;p&gt;然后就是闲聊啦。我早已忘记那天她们究竟是怎么打开话题的，可能是死宅特有的什么方式吧。但总之，萝莉知道了这个人是高二的学妹（真是的，那还管我叫小孩子）。那个女孩知道了萝莉是个破画画的。然后萝莉拿出了自己画画的本子，那个女孩子在本子上写下了自己的联系方式。&lt;/p&gt;
&lt;p&gt;再之后的事情也记不真切，大抵是偶尔会聊一会儿天的程度吧。在学校里也甚少碰面。但那是她身边第一个主动找她交往的人呢。&lt;/p&gt;
&lt;h2 id=&#34;即使是痛苦的过去，也会有着如明星般闪耀的存在&#34;&gt;&lt;a href=&#34;#即使是痛苦的过去，也会有着如明星般闪耀的存在&#34; class=&#34;headerlink&#34; title=&#34;即使是痛苦的过去，也会有着如明星般闪耀的存在&#34;&gt;&lt;/a&gt;即使是痛苦的过去，也会有着如明星般闪耀的存在&lt;/h2&gt;&lt;p&gt;现在的我回看起过去的那个小萝莉，果然是会心疼的吧？她从没感受到过爱，于是也特别容易满足。&lt;/p&gt;
&lt;p&gt;如果是现在的我回到过去的话，大概会说一句「只是如此吗？」吧。&lt;/p&gt;
&lt;p&gt;正是因为过去那个小萝莉承受了那么多她本不该承受的，我才站到现在的位置上来。&lt;/p&gt;
&lt;p&gt;而在那样痛苦的过去里，我还是翻出了些许如明星般闪耀的存在。&lt;/p&gt;
&lt;p&gt;她们大约就是让她活下去的人吧。&lt;/p&gt;
&lt;p&gt;然后日子便也是这么过着。&lt;/p&gt;
&lt;p&gt;现在的我拼命地记下当下的美好。&lt;/p&gt;
&lt;p&gt;而那也终将成为闪耀的回忆。&lt;/p&gt;
&lt;h2 id=&#34;日后谈&#34;&gt;&lt;a href=&#34;#日后谈&#34; class=&#34;headerlink&#34; title=&#34;日后谈&#34;&gt;&lt;/a&gt;日后谈&lt;/h2&gt;&lt;p&gt;把这篇文章给我四年之前暗恋过的女孩子看了。&lt;/p&gt;
&lt;p&gt;她说「能带入到你的心情呢。」&lt;/p&gt;
&lt;p&gt;我说「是因为你也曾经历过类似的事情吗？」&lt;/p&gt;
&lt;p&gt;她说「是这样的。」&lt;/p&gt;
&lt;p&gt;我说「然后那个时候是因为有我在吗？」&lt;/p&gt;
&lt;p&gt;她说「是这样的。」&lt;/p&gt;
&lt;p&gt;啊啊，原来我也成为过那样闪耀的存在呢。&lt;/p&gt;
&lt;p&gt;「之后也要陪你一起走下去啊。」当时的我这么对她说着。&lt;/p&gt;
&lt;p&gt;「好哦。」现在的她回应了我这句穿越了四年的话。&lt;/p&gt;
</content>
        <category term="杂谈" />
        <category term="散文" />
        <updated>2023-07-23T19:54:30.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2023/07/13/Fediverse-the-two-years/</id>
        <title>&lt;span class=&#39;ts-langs-group&#39;&gt; &lt;span class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt; Fediverse: the two years &lt;/span&gt; &lt;span class=&#39;ts-lang-zh-CN ts-langs ts-langs-show ts-langs-block&#39;&gt; 联邦宇宙：这两年来 &lt;/span&gt; &lt;/span&gt;</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2023/07/13/Fediverse-the-two-years/"/>
        <content type="html">&lt;style type=&#34;text/css&#34;&gt;.ts-langs:not(.ts-langs-show) { display: none; }&lt;/style&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;It&amp;#39;s more than two years I have been here, maybe almost three.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;我呆这块儿两年有余了，可能几乎有三年了。&lt;/div&gt;

&lt;a id=&#34;more&#34;&gt;&lt;/a&gt;
&lt;h1 id=&#34;1-y-hitorino&#34;&gt;&lt;a href=&#34;#1-y-hitorino&#34; class=&#34;headerlink&#34; title=&#34;-1+y: hitorino&#34;&gt;&lt;/a&gt;-1+y: hitorino&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;This is the actual beginning of me in the fediverse though I did not realize it then.
Someone invited me to &lt;a href=&#34;https://m.hitorino.moe&#34;&gt;hitorino&lt;/a&gt;, a then-functioning Mastodon server. And they suggested
an app to me, maybe it&amp;#39;s Pawoo or something, but I cannot remember. No one told me anything
about the fediverse, not even Mastodon. They just gave me a link, and that&amp;#39;s it. So I just
registered, and that&amp;#39;s it.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;这是我在联邦宇宙里的实际开始，虽然我那时没得意识到。
有人邀请我去 &lt;a href=&#34;https://m.hitorino.moe&#34;&gt;hitorino&lt;/a&gt;，当时还在运作的一个 Mastodon 服务器。
对面还推荐了一个 app 给我，可能是 Pawoo 或者什么玩意儿吧，但是我记不得了。
没得人告诉我关于联邦宇宙的任何东西，甚至没得讲 Mastodon。伊就给了我一个链接，
然后就没得了。所以我也就注册了，然后就没得了。&lt;/div&gt;

&lt;h1 id=&#34;0-t-tusooa-xyz&#34;&gt;&lt;a href=&#34;#0-t-tusooa-xyz&#34; class=&#34;headerlink&#34; title=&#34;0: t.tusooa.xyz&#34;&gt;&lt;/a&gt;0: t.tusooa.xyz&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;It was the end of 2020 I remember. I was browsing through some old archives on #archlinux-cn.
There were many interesting people, including those I&amp;#39;ve been known for a decade or so.
Some got a blog, and they put their link to their Mastodon
account on it. I followed that link, and got (re-)introduced to that little simple interface.
&amp;quot;Oh, it&amp;#39;s a microblog.&amp;quot; I was like. I was already using Matrix for a long time, and my feeling
was, &amp;quot;So I can self-host this as well?&amp;quot; So I did, and that was &lt;a href=&#34;https://t.tusooa.xyz&#34;&gt;https://t.tusooa.xyz&lt;/a&gt; .
I began posting poems, posting some daily life, and it turns out that I have already been interacting
with those who later became my lovers.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;我记得那是 2020 的末尾。我在浏览 #archlinux-cn 高头的一些老档案。
那块有好多有意思的人，包括那些我晓得了有十年多了的人。
有人有个博客，而把伊的 Mastodon 账号链接放在上面了。
我追随了那个链接，被（重新）带到了那个小小的简单的界面高头。
「哦，这是个微博啊。」我这么想到。我已经用了 Matrix 蛮长时间的了，我的感受就是，
「所以我也能自己 host 这个玩意儿？」那我就干了，就成了 &lt;a href=&#34;https://t.tusooa.xyz&#34;&gt;https://t.tusooa.xyz&lt;/a&gt; 。
我开始发诗，发点儿日常生活，我还发觉在那个时候我就开始跟那些后来成为我的恋人的人们互动了。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Good life was short. I got burned out by my internship. Covid was there. I wasn&amp;#39;t able
to see my girlfriend. I tried to participate in discussions peacefully, there were always
people who spread hatred, discrimination, and especially transphobia. Since the beginning,
I tried to give constructive feedback, but those just won&amp;#39;t listen and will just violently
push you back against a rock. And the more I use Mastodon, the more I feel it was really
uncustomizable. The text limit can&amp;#39;t be changed without changing the code. The requirement
for email upon registration is constantly bothering me because it is inherently unnecessary
information collected against users&amp;#39; privacy, and Eugen refused to make it optional.
I never actually opened up registration on the server.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;美好生活是短暂的。我被实习搞得精疲力竭。Covid 在那块。我见不到女朋友。我试到和平地参与讨论，
总有人散播仇恨，歧视，而尤其是恐跨。从最开始来讲，我试到给出建设性的反馈，但是伊们就不听，
还粗暴地把你推到石头高头。而且啊，我越是用 Mastodon，就越觉得它真的不可定制。文字上限不改代码就改不了。
要求注册时填邮箱真的是让我很苦恼，因为是原本不必要的信息被收集起来，损害用户的隐私，而 Eugen
拒绝让它变成可选的。我从来没得在那个服务器高头开过注册。&lt;/div&gt;

&lt;h1 id=&#34;Watching-for-Pleroma注视到-Pleroma&#34;&gt;&lt;a href=&#34;#Watching-for-Pleroma注视到-Pleroma&#34; class=&#34;headerlink&#34; title=&#34;Watching for Pleroma注视到 Pleroma&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;Watching for Pleroma&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;注视到 Pleroma&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;It was no surprise I began searching for alternative microblogging software. And somehow I found out about Pleroma.
It looks so nice, so customizable, and is so friendly towards those who do not register (Mastodon requires you
to register to perform most read-only actions). Immediately I was amazed about that. Only one thing though: Mastodon
allows you to take all (&amp;quot;conditions apply&amp;quot;!) your followers with you when you jump ships. Pleroma had no such feature.
The good side was, I found out about &lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/2773&#34;&gt;one merge request&lt;/a&gt; on their GitLab, which allows you to move from
Mastodon to Pleroma, by adding an alias referring the old account to the new account.
I was never thinking of going back, so that was enough for me. I looked at it and that gave me hope
of using some other software than Mastodon. But after a month or so, there was literally no progress on that MR, so
I decided to shout out in the dev channel and ask what was going on. One of them, maybe rinpatch, told me that if no one
cared about it then it was probably going to be ignored, and suggested that I comment on the MR. I ended up testing it and
reported my results -- initially it did not work. It went the wrong way as the original method added it to the WebFinger
profile, but Mastodon expects the alias in the Actor object. After the problem was fixed, I was able to open up a Pleroma
server for my own use.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;我开始搜索替代的微博软件就不值得惊讶了。然后我不知怎么的就找到了 Pleroma。它看上去很棒，
很可定制，而且对不注册的人非常友好（Mastodon要你注册才能完成大部分的只读操作）。
我立刻就为之惊叹了。但有一事：Mastodon允许你跳船的时候把所有的关注者带走（「要符合条件的才行」！）。
Pleroma 还没得这个功能。好的一面就是，我在伊们的 GitLab 高头找到了&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/2773&#34;&gt;一个合并请求&lt;/a&gt;，
能让你从 Mastodon 移动到 Pleroma。原理是在新账号上加一个指向旧账号的别名。
我从来没得想过回去，所以那对我来讲就足够了。我看到它，就觉有希望能用 Mastodon 意外的什么软件了。
但过了一个月吧，那个 MR 高头完全没得任何进度，所以我决定去开发者频道高头吼一嗓子问问到底怎么样了。
其中一个，可能是 rinpatch 吧，告诉我如果没得人关心，那可能就会被忽略了，然后建议我去那个 MR 高头评论。
我最终还是自己测试了，汇报了我的结果——一开始是不能用的。它走错了道路，之前的方法是把它加到 WebFinger
profile 高头，但是 Mastodon 想要别名在 Actor 对象里头。这个问题修好了之后，我就能开一个自己用的 Pleroma 服务器了。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;And that was the beginning of &lt;a href=&#34;https://kazv.moe&#34;&gt;kazv.moe&lt;/a&gt;, somewhere April in 2021.
It started out as a tiny little server.
I invited my girlfriend and some friends there. Some people who I have known when I was on Mastodon
registered alt accounts on it. Even though registration was completely open without any verification,
there was not a lot of people.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;而那便是 &lt;a href=&#34;https://kazv.moe&#34;&gt;kazv.moe&lt;/a&gt; 的开端了，2021年4月的某日。
它开始是一个微小的服务器。我把我的女朋友和一些朋友邀请了过来。
一些我在 Mastodon 高头认识的人在上面注册了小号。
尽管完全开放注册，没得任何验证机制，它也还是没得多少人。&lt;/div&gt;

&lt;h1 id=&#34;Hacking-Pleroma&#34;&gt;&lt;a href=&#34;#Hacking-Pleroma&#34; class=&#34;headerlink&#34; title=&#34;Hacking Pleroma&#34;&gt;&lt;/a&gt;Hacking Pleroma&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;As time goes, I feel that I want more features for Pleroma. First of all, I want account migration
to fully work. A lot of people are posting really long images and I could not zoom in conveniently.
I really liked Misskey&amp;#39;s tree-style thread display and nice mention links. The emoji picker was a
disaster to use because it was really slow to load, and everything was mixed together, there being only
two groups: &amp;quot;custom&amp;quot; and &amp;quot;unicode,&amp;quot; effectively making emoji packs useless.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;时光流逝，我感觉我想要 Pleroma 有更多功能。首先，我想要账号迁移能完全工作。
好多人在发巨长的图，我没得办法方便地放大。
我真的很喜欢 Misskey 的树状线索显示和好看的艾特链接。
表情选择器用起来简直是灾难，因为它加载起来真的真的慢，所有的东西都糊在一起，只有两个分组：
「自定义」和「unicode」，让表情包完全无用。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;So I started to write code, for the features I want, and deployed them to kazv.moe .
At the beginning, I just touched the frontend. It was relatively easy. It&amp;#39;s JavaScript,
and I knew JavaScript since 2017, when I joined &lt;a href=&#34;https://rikumi.dev&#34;&gt;Rikumi&lt;/a&gt;&amp;#39;s project and started
writing server-side JavaScript. It took me some time to figure out how Vue works, but
since I knew React, it wasn&amp;#39;t that much of a problem.
Then, &lt;a href=&#34;https://suicablog.cobaltkiss.blue&#34;&gt;suica&lt;/a&gt; asked me why search
on Pleroma was broken. And debula found out the cause of it. To fix that took me a couple
of hours -- that was &lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3519&#34;&gt;the first time I touched Pleroma&amp;#39;s backend code&lt;/a&gt;. I was never exposed
to any Elixir or Erlang before, and all I read was Elixir&amp;#39;s official tutorial. I did not get
to read the OTP part -- it could have saved a huge part of my time if I did, because I did not
know how to run individual test cases and wasted a lot of time on running the whole &lt;code&gt;coveralls&lt;/code&gt;
process.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;所以我开始给我想要的特性写代码，然后把它部署到 kazv.moe 去。一开始，我只是动动前端。
还是比较简单的。它是 JavaScript 的，而我从 2017年加入 &lt;a href=&#34;https://rikumi.dev&#34;&gt;Rikumi&lt;/a&gt; 的项目开始写服务端
JavaScript 的时候就懂得 JavaScript 了。弄清楚 Vue 怎么工作花了点时间，但是我懂 React，
所以问题不大。
然后，&lt;a href=&#34;https://suicablog.cobaltkiss.blue&#34;&gt;suica&lt;/a&gt; 问我为什么 Pleroma 的搜索是坏的。debula 找到了问题的原因。修它花了我几个小时——
那是&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3519&#34;&gt;我第一次去动 Pleroma 的后端代码&lt;/a&gt;。我之前从来没得接触过任何 Elixir 或者 Erlang，
我当时就读了 Elixir 的官方教程。没得读 OTP 的那部分——要是看了的话，那能节省我一大半的时间了，
因为我不晓得怎么运行单个的测试案例，在运行整个 &lt;code&gt;coveralls&lt;/code&gt; 过程里浪费了好多时间。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;And so I continued adding new features: &lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1408&#34;&gt;grouped emoji picker&lt;/a&gt;, &lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1419&#34;&gt;remote interaction&lt;/a&gt;,
&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1424&#34;&gt;misskeyish mention links&lt;/a&gt;, &lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1431&#34;&gt;confirmation dialogs&lt;/a&gt;, &lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3524&#34;&gt;account migration&lt;/a&gt;,
&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3634&#34;&gt;translations for backend-rendered pages&lt;/a&gt;, &lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3643&#34;&gt;server announcements&lt;/a&gt;, &lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3678&#34;&gt;editing&lt;/a&gt;.
Those are all things wanted by people, and they really love to see it. However, Pleroma at that time was on the
verge of collapsing: AG was using his power to push all his changes into Pleroma in any way he could, while
caring little if nothing about other people&amp;#39;s work and especially Pleroma-FE, as Soapbox was the frontend of
&lt;em&gt;his&lt;/em&gt; legacy. There were not a lot of people who can review my code, so it got stuck in the process for
a very long time. My very first MR took half a year to get merged.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;然后我就继续加新功能：&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1408&#34;&gt;分组的表情选择器&lt;/a&gt;，&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1419&#34;&gt;远端互动&lt;/a&gt;，
&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1424&#34;&gt;misskey 式的艾特链接&lt;/a&gt;，&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1431&#34;&gt;确认对话框&lt;/a&gt;，&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3524&#34;&gt;账号迁移&lt;/a&gt;，
&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3634&#34;&gt;后端渲染的页面的翻译&lt;/a&gt;，&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3643&#34;&gt;服务器公告&lt;/a&gt;，&lt;a href=&#34;https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3678&#34;&gt;编辑&lt;/a&gt;。
这些都是人们想要的功能，伊们真的很想看到的。但是，Pleroma 在那个时候处在崩溃的边缘：
AG 在用他的权力以任何可以的方法把他的修改推进 Pleroma 里头，但是对别人的工作，尤其是 Pleroma-FE
（毕竟 Soapbox 是&lt;em&gt;他&lt;/em&gt;的遗迹前端嘛）的关注微乎其微，如果不是完全没得的话。没得什么人能审阅我的代码，
所以它卡在过程里就卡了好久。我第一个 MR 用了半年才被合并。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;In the meantime, hj organized a meeting for Pleroma developers and users to reunionize the
community and rethink about the next steps. AG was stripped off the maintainer title, and
later got kicked out. He then became really abusive on the fediverse, calling names towards
me and Hélène, the other girl at that time on our team. I wonder whether it is due to this
that she ended up quitting developing Pleroma. I ended up banned both of his instance from
kazv.moe . Reflecting on that, I would say, &amp;quot;&lt;strong&gt;&lt;em&gt;A self-claimed feminist, and all he does is...
harassing women? What a shame?&lt;/em&gt;&lt;/strong&gt;&amp;quot; By the end of the year of 2022, I was named
a new maintainer through the consensus of the current devs on the IRC channel. And we released
2.5.0, the one with many of the long-longed features I wrote. The Akkoma folks forked away
from us and advertised their software with the features I wrote, claiming credits just because
they released earlier than us. I really can&amp;#39;t say I like how this works.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;在同时，hj 给 Pleroma 的开发者和用户组织了一个会议，为了重组社群，再思考下一步怎么办。
AG 被削除了维护者的头衔，之后被开除出去了。他之后在联邦宇宙上面变得非常粗暴，咒骂我跟
Hélène，当时我们团队里头的另一个女孩。我不晓得是不是因为这个，她才从 Pleroma 的开发里退出的。
我最后在 kazv.moe 高头把他的两个实例都给封得了。
现在回想起来，我就要讲了：「&lt;strong&gt;&lt;em&gt;一个自称的女权主义者，而他做的事情都是在...伤害女性？多么可耻啊？&lt;/em&gt;&lt;/strong&gt;」
2022年底，IRC 频道高头的现任开发者们一致同意授予我新的维护者的职位。然后我们释出了 2.5.0，
这个有很多我写的，大家都期盼已久的特性的版本。Akkoma 那一帮人从我们这边 fork 走了，
拿着我写的那些特性来宣传伊们的软件，只因为伊们释出的早，便抢了名头。我真的没得办法讲我喜欢这事的。&lt;/div&gt;

&lt;h1 id=&#34;My-personal-life我的个人生活&#34;&gt;&lt;a href=&#34;#My-personal-life我的个人生活&#34; class=&#34;headerlink&#34; title=&#34;My personal life我的个人生活&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;My personal life&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;我的个人生活&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;&lt;strong&gt;From here on there might be depiction of sex. You have been warned.&lt;/strong&gt;&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;&lt;strong&gt;从这里开始可能有性描写。你已经被警告过了。&lt;/strong&gt;&lt;/div&gt;


&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;That&amp;#39;s not as much dramatic as the Pleroma drama, no? I still posted my poems (2021 was the year when I wrote the
most poems till then). I occasionally posted the food I cooked, and I posted my political viewpoints.
Definitely a lot of people hate me for my views, but I do not care any more. I created an &lt;a href=&#34;https://kazv.moe/users/SWwind&#34;&gt;alt account&lt;/a&gt; for
more intimate relationships, and I started to flirt with &lt;a href=&#34;https://kazv.moe/users/Murasaki&#34;&gt;Reiki&lt;/a&gt;. We used paired avatars, expressed our feelings
to each other, and maybe after half a year, I asked them to be my girlfriend. They agreed.
Since that time I realized I was not a &amp;quot;pure lesbian&amp;quot; but rather can be attracted to non-binary people as well, which
is a type of Bi+. I use the term yuri to represent my sexual orientation now.
And later I got to be girlfriends with &lt;a href=&#34;https://m.cmx.im/@StarKiller&#34;&gt;two&lt;/a&gt; &lt;a href=&#34;https://nya.one/@Orca&#34;&gt;other&lt;/a&gt; cute people.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;那远不如 Pleroma 的戏剧那么戏剧化，不是吗？我仍然发诗（2021是我在以往年份里写过最多诗的一年）。
我偶尔发点自己做的食物，我还发我的政治观点。肯定有很多人因为我的观点而恨我的，但我不再在意了。
我创了一个&lt;a href=&#34;https://kazv.moe/users/SWwind&#34;&gt;小号&lt;/a&gt;给更加亲密的关系，并且开始和&lt;a href=&#34;https://kazv.moe/users/Murasaki&#34;&gt;蕾姬&lt;/a&gt;调情。我们用一对的头像，
向对方表达自己的感情，可能有半年之后吧，我让伊做我的女朋友。伊答应了。
从那个时候起，我意识到我不是一个「纯女同」，我其实也可以对非二元的人产生吸引的，这是一种 Bi+。
我现在用百合这个词来表达我的性取向。再之后我又和&lt;a href=&#34;https://m.cmx.im/@StarKiller&#34;&gt;另外&lt;/a&gt;&lt;a href=&#34;https://nya.one/@Orca&#34;&gt;两个&lt;/a&gt;可爱的人成为了女朋友。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;After covid I have been able to see Saya more often, but only during my school breaks.
She masturbated me and I think that counts as sex.
I hate it that I have to cross the border. At school it&amp;#39;s still busy, and I have encountered
a couple of small problems, but luckily they were resolved promptly.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;covid 过后我能更频繁地见 Saya 了，但是也只有学校放假的时候。
她给我自慰了，我觉得这算是性交。
我讨厌必须穿越边境这事。
在学校还是很忙，碰到了好多小问题，但还好能妥善解决。&lt;/div&gt;


&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Revealing my political views isn&amp;#39;t necessarily a bad thing right? &lt;a href=&#34;https://nanakumo.github.io&#34;&gt;Someone&lt;/a&gt; came to kazv.moe
because she love my views, and I ended up having a crush on her. Unfortunately she doesn&amp;#39;t
love me back so we are just being friends and sisters. I guess that&amp;#39;s the bitterness of life, huh.
(Oh have I told you that she now has a Pleroma instance with the exact same setup as mine?)
I finally actually used my Funkwhale, and please, look forward to our new song, ok?&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;揭示我的政治观点不一定是坏事，对吧？&lt;a href=&#34;https://nanakumo.github.io&#34;&gt;有人&lt;/a&gt;就是因为喜欢我的观点才来到 kazv.moe，再后来我爱上了她。
但不凑巧，她并不也爱我，所以我们只是在做朋友和姐妹啦。我想这就是人生的酸涩吧，嘛。
（哦，我啊讲过啊，她现在有一个 Pleroma 实例了，用的是跟我一模一样的配置诶？）
我终于把我的 Funkwhale 真的用起来了，请期待一下我们的新歌吧？&lt;/div&gt;


</content>
        <category term="code" />
        <category term="fediverse" />
        <category term="pleroma" />
        <updated>2023-07-13T18:19:25.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2021/10/01/systemd-openRC/</id>
        <title>systemd -&gt; openRC</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2021/10/01/systemd-openRC/"/>
        <content type="html">&lt;style type=&#34;text/css&#34;&gt;.ts-langs:not(.ts-langs-show) { display: none; }&lt;/style&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Recently I switched from systemd to openRC on my Gentoo laptop.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;最近我把我践兔的笔记本高头的 systemd 换到了 openRC。&lt;/div&gt;

&lt;a id=&#34;more&#34;&gt;&lt;/a&gt;
&lt;h1 id=&#34;Why-为什么啊？&#34;&gt;&lt;a href=&#34;#Why-为什么啊？&#34; class=&#34;headerlink&#34; title=&#34;Why?为什么啊？&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;Why?&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;为什么啊？&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Contrast to what you might think, this article would not do a comparison between systemd and openRC.
I switched purely for fun.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;没得想到吧，这篇文章不搞 systemd 跟 openRC 的对比。我纯粹为了好玩。&lt;/div&gt;

&lt;h1 id=&#34;Steps步骤&#34;&gt;&lt;a href=&#34;#Steps步骤&#34; class=&#34;headerlink&#34; title=&#34;Steps步骤&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;Steps&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;步骤&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;First update the whole system, as it is a good practice before doing any invasive change.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;首先更新整个系统。在搞任何侵入性的修改之前，这么搞总是好的。&lt;/div&gt;

&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;eix-sync&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;emerge -av1uUD --with-bdeps=y world&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Then switch to a non-systemd profile.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;然后切到一个不是 systemd 的 profile。&lt;/div&gt;

&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;eselect profile list&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;eselect profile &lt;span class=&#34;built_in&#34;&gt;set&lt;/span&gt; X&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Change &lt;code&gt;USE=&amp;quot;elogind -systemd&amp;quot;&lt;/code&gt; in make.conf.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;在 make.conf 里头，改个 &lt;code&gt;USE=&amp;quot;elogind -systemd&amp;quot;&lt;/code&gt;。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;I first tried to do the same as updating the system, but it still does not rid me of the systemd dependencies.
So check now what packages still have a hard-dependency on systemd.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;我先试到搞跟更新系统的时候一样的事情，但是它还是没得办法把我从 systemd 依赖里头解脱出来。
所以现在检查一下哪些包还对 systemd 有硬依赖的。&lt;/div&gt;

&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;40&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;] equery d systemd&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt; * These packages depend on systemd:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;app-crypt&amp;#x2F;p11-kit-0.23.22 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;app-editors&amp;#x2F;emacs-27.2-r5 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;app-i18n&amp;#x2F;fcitx5-5.0.1 (sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;dev-db&amp;#x2F;mariadb-10.5.10-r2 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;dev-db&amp;#x2F;postgresql-13.3 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;dev-lang&amp;#x2F;erlang-24.0.2 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;dev-libs&amp;#x2F;libratbag-0.16 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;dev-libs&amp;#x2F;weston-9.0.0-r1 (systemd ? &amp;gt;&amp;#x3D;sys-apps&amp;#x2F;systemd-209[pam])&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;dev-qt&amp;#x2F;qtcore-5.15.2-r3 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;gnome-base&amp;#x2F;gnome-desktop-40.3 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;kde-plasma&amp;#x2F;plasma-meta-5.22.5 (systemd ? sys-apps&amp;#x2F;systemd[pam])&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;media-sound&amp;#x2F;pulseaudio-13.0-r1 (systemd ? sys-apps&amp;#x2F;systemd:0[abi_x86_32(-)?,abi_x86_64(-)?,abi_x86_x32(-)?,abi_mips_n32(-)?,abi_mips_n64(-)?,abi_mips_o32(-)?,abi_s390_32(-)?,abi_s390_64(-)?])&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;net-libs&amp;#x2F;webkit-gtk-2.32.4 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;net-misc&amp;#x2F;modemmanager-1.16.8 (systemd ? &amp;gt;&amp;#x3D;sys-apps&amp;#x2F;systemd-209)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;net-misc&amp;#x2F;networkmanager-1.32.4-r1 (systemd ? &amp;gt;&amp;#x3D;sys-apps&amp;#x2F;systemd-209:0)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;net-print&amp;#x2F;cups-2.3.3_p2-r2 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;net-wireless&amp;#x2F;bluez-5.61 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-apps&amp;#x2F;accountsservice-0.6.55-r1 (systemd ? &amp;gt;&amp;#x3D;sys-apps&amp;#x2F;systemd-186:0)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-apps&amp;#x2F;dbus-1.12.20-r3 (systemd ? sys-apps&amp;#x2F;systemd:0)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-apps&amp;#x2F;gentoo-systemd-integration-8 (&amp;gt;&amp;#x3D;sys-apps&amp;#x2F;systemd-207)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-apps&amp;#x2F;hwids-20210613-r1 (systemd ? sys-apps&amp;#x2F;systemd[hwdb])&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-apps&amp;#x2F;smartmontools-7.2 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-apps&amp;#x2F;util-linux-2.37.2-r1 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-auth&amp;#x2F;pambase-20210201.1 (homed ? sys-apps&amp;#x2F;systemd[homed])&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;                            (systemd ? sys-apps&amp;#x2F;systemd[pam])&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-auth&amp;#x2F;polkit-0.119-r2 (systemd ? sys-apps&amp;#x2F;systemd:0[policykit])&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-auth&amp;#x2F;rtkit-0.13-r1 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-fs&amp;#x2F;lvm2-2.02.188-r2 (systemd ? &amp;gt;&amp;#x3D;sys-apps&amp;#x2F;systemd-205:0)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-fs&amp;#x2F;udisks-2.9.3 (systemd ? &amp;gt;&amp;#x3D;sys-apps&amp;#x2F;systemd-209)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-kernel&amp;#x2F;dracut-053-r1 (sys-apps&amp;#x2F;systemd[sysv-utils])&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;sys-process&amp;#x2F;procps-3.3.17-r1 (systemd ? sys-apps&amp;#x2F;systemd[abi_x86_32(-)?,abi_x86_64(-)?,abi_x86_x32(-)?,abi_mips_n32(-)?,abi_mips_n64(-)?,abi_mips_o32(-)?,abi_s390_32(-)?,abi_s390_64(-)?])&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;virtual&amp;#x2F;libudev-232-r5 (systemd ? &amp;gt;&amp;#x3D;sys-apps&amp;#x2F;systemd-232:0&amp;#x2F;2[abi_x86_32(-)?,abi_x86_64(-)?,abi_x86_x32(-)?,abi_mips_n32(-)?,abi_mips_n64(-)?,abi_mips_o32(-)?,abi_s390_32(-)?,abi_s390_64(-)?])&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;virtual&amp;#x2F;logger-0-r1 (&amp;gt;&amp;#x3D;sys-apps&amp;#x2F;systemd-38)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;virtual&amp;#x2F;service-manager-1 (kernel_linux ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;virtual&amp;#x2F;tmpfiles-0-r1 (!prefix-guest ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;virtual&amp;#x2F;udev-217-r3 (&amp;gt;&amp;#x3D;sys-apps&amp;#x2F;systemd-217)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;x11-base&amp;#x2F;xorg-server-1.20.13-r1 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;x11-misc&amp;#x2F;sddm-0.18.1-r5 (systemd ? sys-apps&amp;#x2F;systemd)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;It turns out that &lt;code&gt;virtual/logger&lt;/code&gt;, &lt;code&gt;virtual/service-manager&lt;/code&gt;, &lt;code&gt;virtual/tmpfiles&lt;/code&gt; have dependencies on systemd, and
they are not willing to switch to another provider. I had to pull them in manually. Here, I chose &lt;code&gt;openrc&lt;/code&gt; for &lt;code&gt;service-manager&lt;/code&gt;
(obviously), &lt;code&gt;systemd-tmpfiles&lt;/code&gt; for &lt;code&gt;tmpfiles&lt;/code&gt; (only other sensible package to provide this), and &lt;code&gt;syslog-ng&lt;/code&gt; for &lt;code&gt;logger&lt;/code&gt;
(this one has many choices).&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;看样子 &lt;code&gt;virtual/logger&lt;/code&gt;、&lt;code&gt;virtual/service-manager&lt;/code&gt;、&lt;code&gt;virtual/tmpfiles&lt;/code&gt; 有 systemd 的依赖，而且这些都不愿意切换到另一个
提供者的。我就得把这些手动拉进来了。在这块，我选了 &lt;code&gt;openrc&lt;/code&gt; 来提供 &lt;code&gt;service-manager&lt;/code&gt;（显然），&lt;code&gt;systemd-tmpfiles&lt;/code&gt; 来提供
&lt;code&gt;tmpfiles&lt;/code&gt;（唯一的别的提供这玩意儿的理智的包），然后是 &lt;code&gt;syslog-ng&lt;/code&gt; 来提供 &lt;code&gt;logger&lt;/code&gt;（这个就有蛮多选择的了）。&lt;/div&gt;

&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;emerge -av1uUD --with-bdeps=y openrc systemd-tmpfiles sysvinit syslog-ng world&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;In the meantime, prepare other parts of the system for openRC.
First backup the current kernel (bzImage, System.map and initramfs), and check the kernel config
to make sure we supported openRC.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;与此同时，把系统的别的地方给 openRC 准备一下子。
首先备份一下当前的内核（bzImage、System.map 跟 initramfs），然后检查一下内核配置，确保支持了 openRC。&lt;/div&gt;

&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;Gentoo Linux  ---&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  Support for init systems, system and service managers  ---&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    [*] OpenRC, runit and other script based systems and managers&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Bid farewell to systemd and express gratitude:&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;跟 systemd 讲再见，表达一下感谢：&lt;/div&gt;

&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;] systemd-analyze&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;Startup finished in 6.575s (firmware) + 2.132s (loader) + 2.835s (kernel) + 2.130s (userspace) &amp;#x3D; 13.674s&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;graphical.target reached after 2.087s in userspace&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Always good to have some root ttys and sessions:&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;有几个 root 的 tty 跟会话总是好的：&lt;/div&gt;

&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;sudo su -&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Install a busybox in case of misfortune.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;装个 busybox 以防不测。&lt;/div&gt;

&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;euse -E static -p sys-apps&amp;#x2F;busybox&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;euse -D pam -p sys-apps&amp;#x2F;busybox&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;emerge -av busybox&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;After the &lt;code&gt;emerge&lt;/code&gt; finished, I was prompted to run &lt;code&gt;emerge @preserved-rebuild&lt;/code&gt; so just ran it.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;&lt;code&gt;emerge&lt;/code&gt; 结束之后，它提示我要运行 &lt;code&gt;emerge @preserved-rebuild&lt;/code&gt;，那就运行吧。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Update the initramfs to pickup any changes. This may not be needed; I ran it just to be safe.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;更新 initramfs 来捡起来任何更改。这个可能不需要，为了保险起见我还是执行了。&lt;/div&gt;

&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;genkernel --no-clean initramfs&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&#34;Configuration配置&#34;&gt;&lt;a href=&#34;#Configuration配置&#34; class=&#34;headerlink&#34; title=&#34;Configuration配置&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;Configuration&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;配置&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Reference: &lt;a href=&#34;https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Base&#34;&gt;https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Base&lt;/a&gt;&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;参考： &lt;a href=&#34;https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Base&#34;&gt;https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Base&lt;/a&gt;&lt;/div&gt;

&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;# cat &amp;#x2F;etc&amp;#x2F;timezone&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;# echo &amp;quot;.......&amp;quot; &amp;gt; &amp;#x2F;etc&amp;#x2F;timezone&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;# emerge --config sys-libs&amp;#x2F;timezone-data&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;# cat &amp;#x2F;etc&amp;#x2F;locale.gen&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;# eselect locale list&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;emerge -av app-admin&amp;#x2F;logrotate&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;# cat &amp;#x2F;etc&amp;#x2F;conf.d&amp;#x2F;hwclock&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;# cat &amp;#x2F;etc&amp;#x2F;conf.d&amp;#x2F;hostname&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;# cat &amp;#x2F;etc&amp;#x2F;hostname&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;NetworkManager&#34;&gt;&lt;a href=&#34;#NetworkManager&#34; class=&#34;headerlink&#34; title=&#34;NetworkManager&#34;&gt;&lt;/a&gt;&lt;a href=&#34;https://wiki.gentoo.org/wiki/NetworkManager#Service&#34;&gt;NetworkManager&lt;/a&gt;&lt;/h3&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;rc-update add NetworkManager default&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;Display-manager显示管理器&#34;&gt;&lt;a href=&#34;#Display-manager显示管理器&#34; class=&#34;headerlink&#34; title=&#34;Display manager显示管理器&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;Display manager&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;显示管理器&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;rc-update add display-manager default&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;nano -w &amp;#x2F;etc&amp;#x2F;conf.d&amp;#x2F;display-manager&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;keymaps-replacement-for-localectl-keymaps（localectl的替代）&#34;&gt;&lt;a href=&#34;#keymaps-replacement-for-localectl-keymaps（localectl的替代）&#34; class=&#34;headerlink&#34; title=&#34;keymaps (replacement for localectl)keymaps（localectl的替代）&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;keymaps (replacement for localectl)&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;keymaps（localectl的替代）&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Reference: &lt;a href=&#34;https://wiki.gentoo.org/wiki/Keyboard_layout_switching&#34;&gt;https://wiki.gentoo.org/wiki/Keyboard_layout_switching&lt;/a&gt;&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;参考： &lt;a href=&#34;https://wiki.gentoo.org/wiki/Keyboard_layout_switching&#34;&gt;https://wiki.gentoo.org/wiki/Keyboard_layout_switching&lt;/a&gt;&lt;/div&gt;


&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;nano -w &amp;#x2F;etc&amp;#x2F;conf.d&amp;#x2F;keymaps&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;rc-update add keymaps boot&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;# cat &amp;#x2F;etc&amp;#x2F;X11&amp;#x2F;xorg.conf.d&amp;#x2F;00-keyboard.conf&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;lvm&#34;&gt;&lt;a href=&#34;#lvm&#34; class=&#34;headerlink&#34; title=&#34;lvm&#34;&gt;&lt;/a&gt;lvm&lt;/h3&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Reference: &lt;a href=&#34;https://wiki.gentoo.org/wiki/LVM#openrc&#34;&gt;https://wiki.gentoo.org/wiki/LVM#openrc&lt;/a&gt;&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;参考： &lt;a href=&#34;https://wiki.gentoo.org/wiki/LVM#openrc&#34;&gt;https://wiki.gentoo.org/wiki/LVM#openrc&lt;/a&gt;&lt;/div&gt;

&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;rc-update add lvm boot&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;tmpfs-on-tmp-systemd-auto-mount-在-tmp-高头的-tmpfs（systemd-自动挂载的）&#34;&gt;&lt;a href=&#34;#tmpfs-on-tmp-systemd-auto-mount-在-tmp-高头的-tmpfs（systemd-自动挂载的）&#34; class=&#34;headerlink&#34; title=&#34;tmpfs on /tmp (systemd auto-mount)在 /tmp 高头的 tmpfs（systemd 自动挂载的）&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;tmpfs on /tmp (systemd auto-mount)&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;在 /tmp 高头的 tmpfs（systemd 自动挂载的）&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;# nano -w &amp;#x2F;etc&amp;#x2F;fstab&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;tmpfs &amp;#x2F;tmp tmpfs rw,nosuid,noatime,nodev,size&amp;#x3D;4G,mode&amp;#x3D;1777 0 0&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;backlight-replacement-for-systemd-backlight-backlight（systemd-backlight-的替代）&#34;&gt;&lt;a href=&#34;#backlight-replacement-for-systemd-backlight-backlight（systemd-backlight-的替代）&#34; class=&#34;headerlink&#34; title=&#34;backlight (replacement for systemd-backlight)backlight（systemd-backlight 的替代）&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;backlight (replacement for systemd-backlight)&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;backlight（systemd-backlight 的替代）&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;eselect repository enable beatussum-overlay&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;emaint sync --repo beatussum-overlay&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;echo &amp;#39;*&amp;#x2F;*::beatussum-overlay&amp;#39; |sudo tee &amp;#x2F;etc&amp;#x2F;portage&amp;#x2F;package.mask&amp;#x2F;beatussum-overlay&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;echo &amp;#39;sys-apps&amp;#x2F;save-backlight::beatussum-overlay&amp;#39; |sudo tee &amp;#x2F;etc&amp;#x2F;portage&amp;#x2F;package.unmask&amp;#x2F;save-backlight&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;emerge -av save-backlight&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;rc-update add save-backlight default&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;alsa&#34;&gt;&lt;a href=&#34;#alsa&#34; class=&#34;headerlink&#34; title=&#34;alsa&#34;&gt;&lt;/a&gt;alsa&lt;/h3&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Note that the alsasound service only saves and loads mixer state. You will still be able to use sound without this service.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;注意 alsasound 服务只是保存跟读取混音器的状态。就算不用这个服务，也可以用声音的。&lt;/div&gt;


&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;rc-update add alsasound default&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;rc-update add alsasound nonetwork&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;cron&#34;&gt;&lt;a href=&#34;#cron&#34; class=&#34;headerlink&#34; title=&#34;cron&#34;&gt;&lt;/a&gt;cron&lt;/h3&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;rc-update add cronie boot&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;time-sync-replacement-for-systemd-timesync-时间同步（systemd-timesync-的替代）&#34;&gt;&lt;a href=&#34;#time-sync-replacement-for-systemd-timesync-时间同步（systemd-timesync-的替代）&#34; class=&#34;headerlink&#34; title=&#34;time sync (replacement for systemd-timesync)时间同步（systemd-timesync 的替代）&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;time sync (replacement for systemd-timesync)&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;时间同步（systemd-timesync 的替代）&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;emerge -av ntp&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;rc-update add ntp-client default&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;rc-update add ntpd default&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;https://wiki.gentoo.org/wiki/Ntp#Ntpd&lt;/p&gt;
&lt;h3 id=&#34;ufw&#34;&gt;&lt;a href=&#34;#ufw&#34; class=&#34;headerlink&#34; title=&#34;ufw&#34;&gt;&lt;/a&gt;ufw&lt;/h3&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;rc-update add ufw default&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;bluetooth蓝牙&#34;&gt;&lt;a href=&#34;#bluetooth蓝牙&#34; class=&#34;headerlink&#34; title=&#34;bluetooth蓝牙&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;bluetooth&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;蓝牙&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;rc-update add bluetooth&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&#34;Finalize完成&#34;&gt;&lt;a href=&#34;#Finalize完成&#34; class=&#34;headerlink&#34; title=&#34;Finalize完成&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;Finalize&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;完成&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;# emerge -avuUD world&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;# reboot&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;But in fact after the reboot command it just hangs indefinitely. I ended up rebooting via sysrq.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;但是实际上重启命令之后它就一直卡到那块了。我最后用 sysrq 重启的。&lt;/div&gt;

&lt;h1 id=&#34;What-39-s-next-然后呢？&#34;&gt;&lt;a href=&#34;#What-39-s-next-然后呢？&#34; class=&#34;headerlink&#34; title=&#34;What&amp;#39;s next?然后呢？&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;What&amp;#39;s next?&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;然后呢？&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Nothing. What are you expecting?&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;没得唻。你在期待什么呢？&lt;/div&gt;


</content>
        <category term="坑" />
        <category term="GNU/Linux" />
        <category term="Gentoo" />
        <updated>2021-10-01T22:25:15.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2021/03/28/Notes-on-PinePhone-and-mobile-GNU-Linux-systems/</id>
        <title>&lt;span class=&#39;ts-langs-group&#39;&gt; &lt;span class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt; Notes on PinePhone and mobile GNU/Linux systems &lt;/span&gt; &lt;span class=&#39;ts-lang-zh-CN ts-langs ts-langs-show ts-langs-block&#39;&gt; 关于 PinePhone 和移动端 GNU/Linux 系统的笔记 &lt;/span&gt; &lt;/span&gt;</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2021/03/28/Notes-on-PinePhone-and-mobile-GNU-Linux-systems/"/>
        <content type="html">&lt;style type=&#34;text/css&#34;&gt;.ts-langs:not(.ts-langs-show) { display: none; }&lt;/style&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;At the end of last year, I bought the PinePhone KDE Community Edition; but due to me being too lazy,
I had not tried it out until several months later. I used a few distributions, namely (1) the manjaro
with Plasma Mobile it comes with, (2) Plasma Mobile development version, also based on Manjaro, and
(3) openSUSE Tumbleweed with Plasma Mobile. The first two are not really usable, as I got blackscreens
after a few reboots -((.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;去年底，我买了 PinePhone KDE 社区版；然而因为我太懒，好几个月都没得好好试试。用了几个发行版，分别是 (1)
PinePhone 自带的 Manjaro，(2) Plasma Mobile 的开发版本，也是基于 Manjaro 的，和 (3) 带了 Plasma Mobile
的 openSUSE Tumbleweed。前两个都用不起来，重启几次之后就黑屏了 -((。&lt;/div&gt;

&lt;a id=&#34;more&#34;&gt;&lt;/a&gt;
&lt;h1 id=&#34;Experience-with-openSUSEopenSUSE-的体验&#34;&gt;&lt;a href=&#34;#Experience-with-openSUSEopenSUSE-的体验&#34; class=&#34;headerlink&#34; title=&#34;Experience with openSUSEopenSUSE 的体验&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;Experience with openSUSE&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;openSUSE 的体验&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;h2 id=&#34;What-39-s-working什么能用&#34;&gt;&lt;a href=&#34;#What-39-s-working什么能用&#34; class=&#34;headerlink&#34; title=&#34;What&amp;#39;s working什么能用&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;What&amp;#39;s working&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;什么能用&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;1.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Messaging and calls. Had a call with my girlfriend for about 30mins without interruption. Although she said my voice is a bit strange.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;短信和通话。给女朋友打了三十分的电话，没得中断过的。虽然她说我的声音有一点奇怪。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;2.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;NeoChat.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;NeoChat。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;3.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Web browser.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;网络浏览器。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;4.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Setting locales. I see some translations in Mandarin as Simplified Chinese are there already, but
there are a lot of places without translations (namely those specific to Plasma Mobile).&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;设置 locale。我看到有的简体中文的官话翻译已经在那块了，但是还是有好多地方没得个翻译的（就那些只在
Plasma Mobile 里头有的）。&lt;/div&gt;&lt;/p&gt;
&lt;h2 id=&#34;Problems问题&#34;&gt;&lt;a href=&#34;#Problems问题&#34; class=&#34;headerlink&#34; title=&#34;Problems问题&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;Problems&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;问题&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;1.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Data does not work. Plasma Mobile does not give me an option to &lt;a href=&#34;https://wiki.pine64.org/wiki/PinePhone_APN_Settings#Setting_the_APN&#34;&gt;change network settings&lt;/a&gt; either.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;流量没得办法用。Plasma Mobile 也没得给我个&lt;a href=&#34;https://wiki.pine64.org/wiki/PinePhone_APN_Settings#Setting_the_APN&#34;&gt;改网络设置&lt;/a&gt;的地方哎。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;2.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Sometimes laggy.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;有的时候卡。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;3.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Due to 2, pushing the power button does not always immediately wake up the phone.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;因为 2，按电源键了，也不一定能立刻唤醒手机。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;4.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Input method does not work. At least for the openSUSE distribution, it (maliit) does not come with Chinese input.
Even after I installed &lt;code&gt;maliit-keyboard2-lang&lt;/code&gt;. The screen keyboard is implemented using IM modules.
Setting &lt;code&gt;QT_IM_MODULE=fcitx&lt;/code&gt; will just prevent the screen keyboard from showing up.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;输入法没得办法用。至少在 openSUSE 发行版高头，丫 (maliit) 没得个中文输入的。就算我装了 &lt;code&gt;maliit-keyboard2-lang&lt;/code&gt;，
也不行。屏幕键盘用输入法模块实现的。设个 &lt;code&gt;QT_IM_MODULE=fcitx&lt;/code&gt;，屏幕键盘就不能显示了。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;5.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;With earphones there are electrical current sounds from time to time.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;耳机有的时候会有电流声。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;6.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;If I click an app, and switch to another app, or the desktop, before that app window
shows up, the app window will pop up afterwards instead of being pushed to the background.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;要是我按一个应用，再在那个应用的窗口显示之前，切到另一个应用，或者是桌面，那那个窗口会弹出来，
而不是摁到后台去。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;7.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Privacytools search reports &amp;quot;Rate limit exceeded1&amp;quot; [sic] when I search in Angelfish.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;我在 Angelfish 里搜索的时候，Privacytools 的搜索跟我讲「Rate limit exceeded1」[原文如此]。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;8.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;The screen keyboard sometimes responds to key pressing with word suggestions, which can
be never inputed to the input box desired.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;屏幕键盘有的时候会把我的按键转成单词建议，但那玩意儿又从来没得办法输到输入框里去。&lt;/div&gt;&lt;/p&gt;
&lt;h1 id=&#34;Other-notes别的笔记&#34;&gt;&lt;a href=&#34;#Other-notes别的笔记&#34; class=&#34;headerlink&#34; title=&#34;Other notes别的笔记&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;Other notes&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;别的笔记&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;p&gt;1.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;I have a nano sim card and it will need the adapter that comes with PinePhone to install it properly. I
pushed it in without the adapter, and had to disassemble the phone to push it back out from the inside.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;我有个 nano sim card，那玩意儿要用 PinePhone 自带的转接器才能好好装上。之前没得用转接器就摁进去了，结果
只能把手机拆的了然后从里头给它推出来。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;2.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;The Manjaro distribution the PinePhone comes with has Telegram installed by default. Telegram can only
connect to a non-free server, and forces users to provide a phone number in order to use services that
does not need one. This is a serious privacy concern.
I strongly oppose to the use of Telegram in any cases, and suggest everyone uninstall
it upon receiving your PinePhone.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;PinePhone 自带的 Manjaro 发行版默认安装了 Telegram。Telegram 只能连接到一个不自由的服务器，而且强迫用户
提供手机号以使用并不需要手机号的服务。这是一个严重的隐私隐患。
我强烈反对任何情况下使用 Telegram，并推荐所有人收到 PinePhone 之后立刻卸载它。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;3.
  &lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;The Manjaro distribution the PinePhone comes with cannot be waken up by an alarm clock. I have not yet
tried with openSUSE.&lt;/div&gt;
  &lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;PinePhone 自带的 Manjaro 发行版没得办法被闹钟唤醒。openSUSE 我还没得试过。&lt;/div&gt;&lt;/p&gt;

</content>
        <category term="坑" />
        <category term="GNU/Linux" />
        <category term="PinePhone" />
        <updated>2021-03-28T23:07:52.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2021/02/04/From-a-weird-Dolphin-bug/</id>
        <title>&lt;span class=&#39;ts-langs-group&#39;&gt; &lt;span class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt; From a weird Dolphin bug &lt;/span&gt; &lt;span class=&#39;ts-lang-zh-CN ts-langs ts-langs-show ts-langs-block&#39;&gt; 从一个奇怪的 Dolphin bug 说起 &lt;/span&gt; &lt;/span&gt;</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2021/02/04/From-a-weird-Dolphin-bug/"/>
        <content type="html">&lt;style type=&#34;text/css&#34;&gt;.ts-langs:not(.ts-langs-show) { display: none; }&lt;/style&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;One day when I opened Dolphin I found that it is reporting the file does
not exist when I tried to open one with a Chinese file name. &amp;quot;Well, that&amp;#39;s
bad,&amp;quot; I thought, and instead opened it in the terminal. Recently I went
through the bug list for Dolphin and KIO and saw that encoding-related
bugs are all mentioning that file cannot be trashed. Which is not the case
for me. So I opened a &lt;a href=&#34;https://bugs.kde.org/show_bug.cgi?id=432406&#34;&gt;new bug&lt;/a&gt; and started investigating it.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;某日我打开 Dolphin，发觉它在我试图打开一个文件名带中文的文件的时候告诉我那文件不存在。
「行吧，太差了。」我想着，然后在终端里打开了那个文件。最近我遍览了 Dolphin 和 KIO 的
bug 列表，看着编码相关的 bug 全在说文件不能被扔垃圾桶。而我这里却不然。所以我开了个
&lt;a href=&#34;https://bugs.kde.org/show_bug.cgi?id=432406&#34;&gt;新 bug&lt;/a&gt; 开始钻研它。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;A note: if your Qt is not configured to use icu, then this does
not apply to you.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;提示：如果您的 Qt 没有被配置为使用 icu，那么这事对您便不适用。&lt;/div&gt;

&lt;a id=&#34;more&#34;&gt;&lt;/a&gt;
&lt;h1 id=&#34;From-Dolphin-to-KIO从-Dolphin-到-KIO&#34;&gt;&lt;a href=&#34;#From-Dolphin-to-KIO从-Dolphin-到-KIO&#34; class=&#34;headerlink&#34; title=&#34;From Dolphin to KIO从 Dolphin 到 KIO&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;From Dolphin to KIO&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;从 Dolphin 到 KIO&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;So I checked Dolphin&amp;#39;s code, found that the actual code for opening a file
&lt;a href=&#34;https://invent.kde.org/system/dolphin/-/blob/24f04d75e17010ff50fcacaf2a602f4a08222449/src/dolphincontextmenu.cpp#L498&#34;&gt;is with KIO&lt;/a&gt;. The implementation
&lt;a href=&#34;https://invent.kde.org/frameworks/kio/-/blob/726cfd722a20ec6afdfcbc045621c1f67564c391/src/widgets/kfileitemactions.cpp#L422&#34;&gt;is in &lt;code&gt;KFileItemActions&lt;/code&gt;&lt;/a&gt;. However, that seems not to
be the real source of error. The KFileItemList there is already wrong,
with all non-ascii characters turned into question marks. Further I looked
into the logic of obtaining the content of a directory: KIO invokes a
plugin called &lt;code&gt;file.so&lt;/code&gt;, for local filesystem, and that, which is actually
a kdeinit program, run as another process, does the real work. Then the
data is transferred back to Dolphin using a QDataStream. And in &lt;code&gt;file.so&lt;/code&gt;
it seems that everything looks correct.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;所以啊我就查了查 Dolphin 的代码，发觉真正打开文件的代码
&lt;a href=&#34;https://invent.kde.org/system/dolphin/-/blob/24f04d75e17010ff50fcacaf2a602f4a08222449/src/dolphincontextmenu.cpp#L498&#34;&gt;在 KIO 里&lt;/a&gt;。实现
&lt;a href=&#34;https://invent.kde.org/frameworks/kio/-/blob/726cfd722a20ec6afdfcbc045621c1f67564c391/src/widgets/kfileitemactions.cpp#L422&#34;&gt;在 &lt;code&gt;KFileItemActions&lt;/code&gt; 里&lt;/a&gt;。然而，那好像并不是
真的错因。那里的 KFileItemList 已经错了，非 ascii 的字符全变问号了。再往下，我
看了看获取目录内容的逻辑：对于本地文件系统，KIO 调用了一个唤作 &lt;code&gt;file.so&lt;/code&gt; 的插件，
而那插件实际上是个 kdeinit 程序，作为另一个进程，做了实事的了。然后数据通过一个
QDataStream 传到 Dolphin 里。在 &lt;code&gt;file.so&lt;/code&gt; 里，一切看着都很对。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Why is that? Is it the QDataStream is bad? I looked into the
code for how QDataStream transfers strings and, no, it cannot be.
Also I noticed that the filename is displaying correctly in
Dolphin, just I cannot open it. I got some support on the #kde-devel
channel, and someone reminded me of the &lt;code&gt;LegacyCodec&lt;/code&gt; in &lt;code&gt;file.so&lt;/code&gt;.
That is not the cause of the problem, of cource, as in there it is
nothing wrong. But it reminded me of the &lt;code&gt;QTextCodec&lt;/code&gt; problem. There
is something Qt used to convert its UTF-16 representation into other
encodings. And that is called &lt;code&gt;QTextCodec::codecForLocale()&lt;/code&gt;. An
observation is that in &lt;code&gt;file.so&lt;/code&gt;, the codec name is called &lt;code&gt;UTF-8&lt;/code&gt;;
while in Dolphin, it is called &lt;code&gt;US-ASCII&lt;/code&gt;, unless I set &lt;code&gt;LC_ALL&lt;/code&gt;
to a UTF-8 locale.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;为啥啊？QDataStream 坏了吗？我看了下 QDataStream 是怎么传字串的，啊这，
不可能错的。又注意到文件名在 Dolphin 里显示啥问题都没有，只是我打不开。
在 #kde-devel 上得到了些帮助，有人提醒我 &lt;code&gt;file.so&lt;/code&gt; 里有一 &lt;code&gt;LegacyCodec&lt;/code&gt;。
当然这不是真的错因，因为那边没啥问题啊。但是这教我注意到 &lt;code&gt;QTextCodec&lt;/code&gt; 的问题了。
有个玩意儿是 Qt 用来把它自己的 UTF-16 表示法转成别的编码的。那玩意儿叫
&lt;code&gt;QTextCodec::codecForLocale()&lt;/code&gt;。观察到 &lt;code&gt;file.so&lt;/code&gt; 里的 codec 名字叫
&lt;code&gt;UTF-8&lt;/code&gt;；跑 Dolphin 里它变成 &lt;code&gt;US-ASCII&lt;/code&gt; 了，除非我把 &lt;code&gt;LC_ALL&lt;/code&gt; 设成一个
UTF-8 的 locale。&lt;/div&gt;

&lt;h1 id=&#34;icu-and-Qt-bugsicu-和-Qt-的-bug-们&#34;&gt;&lt;a href=&#34;#icu-and-Qt-bugsicu-和-Qt-的-bug-们&#34; class=&#34;headerlink&#34; title=&#34;icu and Qt bugsicu 和 Qt 的 bug 们&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;icu and Qt bugs&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;icu 和 Qt 的 bug 们&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;I digged
into the code for that, and it turns out that it ultimately uses
&lt;code&gt;ucnv_getDefaultName()&lt;/code&gt; to obtain the name of the encoding.
That function is from &lt;a href=&#34;http://site.icu-project.org/&#34;&gt;icu&lt;/a&gt;. In their bug tracker, I found
&lt;a href=&#34;https://unicode-org.atlassian.net/browse/ICU-12789?jql=text%20~%20%22ucnv_getDefaultName%22&#34;&gt;one&lt;/a&gt; that says:

&lt;blockquote&gt;&lt;p&gt;You may need to call &lt;code&gt;setlocale(LC_ALL, &amp;quot;&amp;quot;);&lt;/code&gt; from your own code before ICU.&lt;/p&gt;
&lt;/blockquote&gt;&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;我钻进代码里一看，它用了个叫 &lt;code&gt;ucnv_getDefaultName()&lt;/code&gt; 的去获取编码的名字。
这函数 &lt;a href=&#34;http://site.icu-project.org/&#34;&gt;icu&lt;/a&gt; 里的。在伊们的 bug 追踪器上，我看到&lt;a href=&#34;https://unicode-org.atlassian.net/browse/ICU-12789?jql=text%20~%20%22ucnv_getDefaultName%22&#34;&gt;一个&lt;/a&gt;说：

&lt;blockquote&gt;&lt;p&gt;在 ICU 之前，您可能得从您自己的代码里调用 &lt;code&gt;setlocale(LC_ALL, &amp;quot;&amp;quot;);&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;And that reminds me. Does Qt call it for us? I searched on Qt&amp;#39;s
bug tracker and got &lt;a href=&#34;https://bugreports.qt.io/browse/QTBUG-57522&#34;&gt;this&lt;/a&gt;:

&lt;blockquote&gt;&lt;p&gt;When using ICU, Qt may call &lt;code&gt;ucnv_getDefaultName()&lt;/code&gt; without calling &lt;code&gt;setlocale(.., &amp;quot;&amp;quot;)&lt;/code&gt; first, which is required before calling &lt;code&gt;ucnv_getDefaultName()&lt;/code&gt;.
One such possible path is:
&lt;code&gt;QString::fromLocal8Bit() -&amp;gt; QTextCodec::codecForLocale() -&amp;gt; QIcuCodec::defaultCodecUnlocked() -&amp;gt; ucnv_getDefaultName()&lt;/code&gt;
&lt;code&gt;setlocale()&lt;/code&gt; is called in &lt;code&gt;QCoreApplicationPrivate::initLocale()&lt;/code&gt;, which may not have been called.&lt;/p&gt;
&lt;/blockquote&gt;

But unfortunately, it seems the Qt person does not want to fix it.
Ok, I guess, then what is calling &lt;code&gt;ucnv_getDefaultName()&lt;/code&gt;? At least,
if they do not fix it, I &lt;em&gt;must&lt;/em&gt; fix it.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;这又给我提了个醒了。Qt 给咱们调用这玩意儿了吗？我搜搜 Qt 的 bug 追踪器，看到&lt;a href=&#34;https://bugreports.qt.io/browse/QTBUG-57522&#34;&gt;这&lt;/a&gt;：

&lt;blockquote&gt;&lt;p&gt;用 ICU 时，Qt 可能会调用 &lt;code&gt;ucnv_getDefaultName()&lt;/code&gt; 而先前却没有调用过 &lt;code&gt;setlocale(.., &amp;quot;&amp;quot;)&lt;/code&gt;。后者则是在调用 &lt;code&gt;ucnv_getDefaultName()&lt;/code&gt; 之前必须得调用的.
一个可能的途径是：
&lt;code&gt;QString::fromLocal8Bit() -&amp;gt; QTextCodec::codecForLocale() -&amp;gt; QIcuCodec::defaultCodecUnlocked() -&amp;gt; ucnv_getDefaultName()&lt;/code&gt;
&lt;code&gt;setlocale()&lt;/code&gt; 是在 &lt;code&gt;QCoreApplicationPrivate::initLocale()&lt;/code&gt; 里调用的。但这玩意儿可能还没被调用呢。&lt;/p&gt;
&lt;/blockquote&gt;&lt;/div&gt;

&lt;h1 id=&#34;How-to-track-down-a-function-call怎么追踪一个函数调用&#34;&gt;&lt;a href=&#34;#How-to-track-down-a-function-call怎么追踪一个函数调用&#34; class=&#34;headerlink&#34; title=&#34;How to track down a function call怎么追踪一个函数调用&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;How to track down a function call&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;怎么追踪一个函数调用&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;I did not know. First intuition was to search for &lt;code&gt;fromLocal8Bit&lt;/code&gt; in the KIO source.
Yields nothing useful. Then it occurred to me that I could use &lt;code&gt;LD_PRELOAD&lt;/code&gt; trick.
From &lt;code&gt;proxychains&lt;/code&gt; to &lt;code&gt;valgrind&lt;/code&gt;, they all use &lt;code&gt;LD_PRELOAD&lt;/code&gt; to override an existing
function. If I override &lt;code&gt;ucnv_getDefaultName()&lt;/code&gt; to have it call &lt;code&gt;std::terminate()&lt;/code&gt;,
I could get a backtrace using gdb. So here it is:&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;我不知道啊。第一个直觉是在 KIO 源码里搜 &lt;code&gt;fromLocal8Bit&lt;/code&gt;。并没有用。然后我突然想起来
&lt;code&gt;LD_PRELOAD&lt;/code&gt; 的伎俩了。从 &lt;code&gt;proxychains&lt;/code&gt; 到 &lt;code&gt;valgrind&lt;/code&gt;，都用了 &lt;code&gt;LD_PRELOAD&lt;/code&gt; 去覆盖
一个已有的函数。如果我把 &lt;code&gt;ucnv_getDefaultName()&lt;/code&gt; 覆盖了，让它调用 &lt;code&gt;std::terminate()&lt;/code&gt;，
我便能用 gdb 整个 backtrace 出来。所以就这样了：&lt;/div&gt;

&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;meta&#34;&gt;#&lt;span class=&#34;meta-keyword&#34;&gt;include&lt;/span&gt; &lt;span class=&#34;meta-string&#34;&gt;&amp;lt;exception&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;string&#34;&gt;&amp;quot;C&amp;quot;&lt;/span&gt; &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;char&lt;/span&gt; *&lt;span class=&#34;title&#34;&gt;ucnv_getDefaultName&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(&lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    std::&lt;span class=&#34;built_in&#34;&gt;terminate&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;string&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;Compile that file with &lt;code&gt;g++ ucnv-override.cpp -shared -fPIC -o ucnv-override.so&lt;/code&gt;
and set &lt;code&gt;LD_PRELOAD=/path/to/ucnv-override.so&lt;/code&gt;. Use gdb to invoke dolphin.
Got &lt;a href=&#34;https://bugsfiles.kde.org/attachment.cgi?id=135421&#34;&gt;a backtrace&lt;/a&gt;. And it&amp;#39;s there:&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;用 &lt;code&gt;g++ ucnv-override.cpp -shared -fPIC -o ucnv-override.so&lt;/code&gt; 编译那文件，
设下 &lt;code&gt;LD_PRELOAD=/path/to/ucnv-override.so&lt;/code&gt;。用 gdb 启动 dolphin。
弄出&lt;a href=&#34;https://bugsfiles.kde.org/attachment.cgi?id=135421&#34;&gt;一个 backtrace&lt;/a&gt;。搁这儿呢：&lt;/div&gt;

&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;#26 0x00007ffff582370b in QLoggingCategory::init(char const*, QtMsgType) () from &amp;#x2F;usr&amp;#x2F;lib64&amp;#x2F;libQt5Core.so.5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;#27 0x00007ffff772d29b in __static_initialization_and_destruction_0 (__initialize_p&amp;#x3D;1, __priority&amp;#x3D;65535)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    at &amp;#x2F;home&amp;#x2F;tusooa&amp;#x2F;Code&amp;#x2F;kio&amp;#x2F;src&amp;#x2F;widgets&amp;#x2F;kdirmodel.cpp:39&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;#28 0x00007ffff772d2ce in _GLOBAL__sub_I_kdirmodel.cpp(void) ()&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    at &amp;#x2F;home&amp;#x2F;tusooa&amp;#x2F;Code&amp;#x2F;kio&amp;#x2F;build&amp;#x2F;src&amp;#x2F;widgets&amp;#x2F;KF5KIOWidgets_autogen&amp;#x2F;include&amp;#x2F;moc_kdirmodel.cpp:155&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;#29 0x00007ffff7fe1c1e in ?? () from &amp;#x2F;lib64&amp;#x2F;ld-linux-x86-64.so.2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;No statement from &lt;code&gt;main&lt;/code&gt;, no statement from Dolphin. It is in the
initialization of a global variable. And that is:&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;没有 &lt;code&gt;main&lt;/code&gt; 的语句。没有 Dolphin 的语句。这玩意是在初始化全局变量的。
呐看：&lt;/div&gt;

&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;static&lt;/span&gt; QLoggingCategory &lt;span class=&#34;title&#34;&gt;category&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(&lt;span class=&#34;string&#34;&gt;&amp;quot;kf.kio.widgets.kdirmodel&amp;quot;&lt;/span&gt;, QtInfoMsg)&lt;/span&gt;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;The &lt;code&gt;QLoggingCategory&lt;/code&gt;. But Krita uses that for debug too, while I
do not have any issues dealing with Chinese file names? It turns out
that we have been using the &lt;code&gt;Q_LOGGING_CATEGORY&lt;/code&gt; macro, and &amp;quot;The
implicitly-defined QLoggingCategory object is created on first use,
in a thread-safe manner.&amp;quot; (from &lt;a href=&#34;https://doc.qt.io/qt-5/qloggingcategory.html#Q_LOGGING_CATEGORY-1&#34;&gt;Qt doc&lt;/a&gt;) So in that case,
the initialization is always run after entering &lt;code&gt;main()&lt;/code&gt;, where
&lt;code&gt;setlocale()&lt;/code&gt; has been called already.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;这 &lt;code&gt;QLoggingCategory&lt;/code&gt;。但 Krita 也用它做调试啊，我也没发现处理中文文件名有
啥问题啊？原来是我们用的是 &lt;code&gt;Q_LOGGING_CATEGORY&lt;/code&gt; 宏，而「这隐式定义的
QLoggingCategory 对象在初次使用时给创建的，这过程还线程安全。」（来自
&lt;a href=&#34;https://doc.qt.io/qt-5/qloggingcategory.html#Q_LOGGING_CATEGORY-1&#34;&gt;Qt 文档&lt;/a&gt;）所以那情况下，初始化肯定在进了 &lt;code&gt;main()&lt;/code&gt;，&lt;code&gt;setlocale()&lt;/code&gt;
被调用过了的时候才运行了的。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;So, replace that with &lt;code&gt;Q_LOGGING_CATEGORY(category, &amp;quot;kf.kio.widgets.kdirmodel&amp;quot;, QtInfoMsg)&lt;/code&gt;,
and everything went back to normal. &lt;del&gt;200 IQ.&lt;/del&gt;&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;所以啊，把那换成 &lt;code&gt;Q_LOGGING_CATEGORY(category, &amp;quot;kf.kio.widgets.kdirmodel&amp;quot;, QtInfoMsg)&lt;/code&gt;，
啥东西都正常了。&lt;del&gt;智商 200。&lt;/del&gt;&lt;/div&gt;

</content>
        <category term="坑" />
        <category term="qt" />
        <category term="utf8" />
        <category term="编码" />
        <updated>2021-02-05T00:38:47.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2020/10/10/Some-multilingual-hacks-on-Hexo/</id>
        <title>&lt;span class=&#39;ts-langs-group&#39;&gt; &lt;span class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt; Some multilingual hacks on Hexo &lt;/span&gt; &lt;span class=&#39;ts-lang-zh-CN ts-langs ts-langs-show ts-langs-block&#39;&gt; 瞎折腾Hexo的多语言 &lt;/span&gt; &lt;/span&gt;</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2020/10/10/Some-multilingual-hacks-on-Hexo/"/>
        <content type="html">&lt;style type=&#34;text/css&#34;&gt;.ts-langs:not(.ts-langs-show) { display: none; }&lt;/style&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;I do not know why exactly I am so stubborn to insist on making this
site multilingual, and in a way that you may see multiple languages
at the same time. But it is something.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;我自己也不明白为什么我执拗得一定要把这网站做成多语言的，还是叫人
能同时看到多种语言的那种。但聊胜于无吧。&lt;/div&gt;

&lt;a id=&#34;more&#34;&gt;&lt;/a&gt;
&lt;h1 id=&#34;A-weird-thing-about-HexoHexo-的诡异事件&#34;&gt;&lt;a href=&#34;#A-weird-thing-about-HexoHexo-的诡异事件&#34; class=&#34;headerlink&#34; title=&#34;A weird thing about HexoHexo 的诡异事件&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;A weird thing about Hexo&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;Hexo 的诡异事件&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;The &lt;em&gt;first&lt;/em&gt; weird thing I got, when I was trying to figure out
&lt;a href=&#34;https://github.com/next-theme/hexo-theme-next&#34;&gt;hexo-theme-next&lt;/a&gt;: sometimes &lt;code&gt;hexo server&lt;/code&gt; gives
the perfect result, but when I &lt;code&gt;hexo generate&lt;/code&gt; or &lt;code&gt;hexo deploy&lt;/code&gt;,
nothing will be correct. Everything is just malformed, and it
does not change even if I &lt;code&gt;hexo clean&lt;/code&gt;.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;我在折腾 &lt;a href=&#34;https://github.com/next-theme/hexo-theme-next&#34;&gt;hexo-theme-next&lt;/a&gt; 的时候碰到的第一个诡异事件是：
有时候 &lt;code&gt;hexo server&lt;/code&gt; 给出了个无懈可击的结果，但只要一 &lt;code&gt;hexo generate&lt;/code&gt;
或者 &lt;code&gt;hexo deploy&lt;/code&gt;，全完蛋。整个网站看着都非常诡异，甚至我
&lt;code&gt;hexo clean&lt;/code&gt; 了之后也没有丝毫变化。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;After digging a lot into the source code, and enabling &lt;code&gt;--debug&lt;/code&gt;,
I finally found that there are some backup files that are also
processed. And the content of those files &lt;em&gt;does&lt;/em&gt; correspond to
the wrong contents on the site. &amp;quot;Okay,&amp;quot; hereby I say, &amp;quot;this
behaviour is indeed ridiculous.&amp;quot;&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;钻进源码里东张西望了好久，再合着 &lt;code&gt;--debug&lt;/code&gt; 的加成，我终于看到了一些备份文件
也被处理了。而其内容&lt;strong&gt;确然&lt;/strong&gt;是应了网站上有问题的东西。「行吧，」如是我说，
「是事直令人齿冷。」&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;And thus I added the ignore rules to ignore all such files,
and everything is hopefully back in place.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;所以我加了忽略规则来忽略这种文件，世界终于清净了，谢天谢地。&lt;/div&gt;

&lt;figure class=&#34;highlight yaml&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;attr&#34;&gt;ignore:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;bullet&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;string&#34;&gt;&amp;quot;**/*~&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;bullet&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;string&#34;&gt;&amp;quot;**/#*&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;bullet&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;string&#34;&gt;&amp;quot;**/.#*&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h1 id=&#34;NexT-39-s-language-switcherNexT-的语言切换器&#34;&gt;&lt;a href=&#34;#NexT-39-s-language-switcherNexT-的语言切换器&#34; class=&#34;headerlink&#34; title=&#34;NexT&amp;#39;s language switcherNexT 的语言切换器&#34;&gt;&lt;/a&gt;&lt;span class=&#39;ts-langs-group&#39;&gt;&lt;span class=&#39;ts-lang-en ts-langs ts-langs-show&#39;&gt;NexT&amp;#39;s language switcher&lt;/span&gt;&lt;span class=&#39;ts-lang-zh-CN ts-langs&#39;&gt;NexT 的语言切换器&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;That is an even more terrible part that comes in. Yes,
&lt;a href=&#34;https://github.com/next-theme/hexo-theme-next&#34;&gt;NexT&lt;/a&gt; comes with such a thing called a
&amp;quot;language switcher,&amp;quot; but it never takes you to a right
place. I cannot even get Hexo generate pages for
different languages, no matter how I change the &lt;code&gt;language&lt;/code&gt;
parameter in &lt;code&gt;_config.yml&lt;/code&gt;. So whenever I click on the
language switcher, I got a 404. And it is hidden at the very
bottom of the page --- How should one expect their visitor
to dig into the deepest hole before they can switch languages?&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;这玩意儿甚至更可怕了。是是是，&lt;a href=&#34;https://github.com/next-theme/hexo-theme-next&#34;&gt;NexT&lt;/a&gt; 有个叫「语言切换器」
的东西，但是它总把人引入歧途。让 Hexo 给不同的语言分别生成页面，这我
怎么改 &lt;code&gt;_config.yml&lt;/code&gt; 里的 &lt;code&gt;language&lt;/code&gt; 参数，也弄不成。所以呢，每次
按下这语言切换器的时候，404 就浮现在我眼前了。而且这切换器给藏在了页面
最底下——让访客钻进最深的洞里才许其切换语言，这能成吗？&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;So, well, since NexT&amp;#39;s language switcher sucks, and multi-page
style multi-language implementation is not feasible, why not just
put everything all together? NexT at least provides a way to
customize what texts are shown... in &lt;code&gt;languages.yml&lt;/code&gt;.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;啊啊，行吧，NexT 这语言切换器是糟透了，多页面显示多语言也办不到，那么把
所有东西全放一起，这又如何呢？NexT 至少给了个用 &lt;code&gt;languages.yml&lt;/code&gt; 来控制
显示什么文字的方法呀......&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;The main idea is to merge NexT&amp;#39;s default translations into one.
I made a Perl script for this. The text for every language is a
&lt;code&gt;span&lt;/code&gt;, and they are next to each other. Use css to put a divider
between every visible &lt;code&gt;span&lt;/code&gt;. Whether a language is shown is controlled
by a JavaScript program that adds or removes classes from the elements.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;大意就是把 NexT 的默认翻译全整一起去。这事我写了个 Perl 脚本去做。每种语言的文字
装在一个 &lt;code&gt;span&lt;/code&gt; 里，并并排。用 css 在每个显示了的 &lt;code&gt;span&lt;/code&gt; 之间，摆一个分割线。
至于某种语言是显示呢是隐藏呢，这让 JavaScript 程序来控制，就从元素里加上或是减去
些 class 就好。&lt;/div&gt;

&lt;div class=&#39;ts-lang-en ts-langs ts-langs-show ts-langs-block&#39;&gt;As I am too lazy, the code is all &lt;a href=&#34;https://lily-is.land/tusooa/blog&#34;&gt;on GitLab&lt;/a&gt;.
Whether this is a viable implementation is left as an exercise
for the reader.&lt;/div&gt;
&lt;div class=&#39;ts-lang-zh-CN ts-langs ts-langs-block&#39;&gt;因为我太懒了，代码都在 &lt;a href=&#34;https://lily-is.land/tusooa/blog&#34;&gt;GitLab 上&lt;/a&gt;。这东西到底可行不，
留给读者作练习。&lt;/div&gt;


</content>
        <category term="坑" />
        <category term="javascript" />
        <category term="hexo" />
        <category term="css" />
        <updated>2020-10-10T20:55:15.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2020/10/01/Fix-firefox-address-bar-clickSelectsAll-bug/</id>
        <title>Fix firefox address bar clickSelectsAll bug (Spoiler: no re-compilation required.)</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2020/10/01/Fix-firefox-address-bar-clickSelectsAll-bug/"/>
        <content type="html">&lt;p&gt;A couple of months ago, I opened my Firefox as usual, I found out that
when I click on the address bar, it dared to select everything in it
as if any creepy browser would do! The first thing I did is to check
the &lt;code&gt;clickSelectsAll&lt;/code&gt; pref -- what I always do first after getting a
new install of Firefox on Windows is setting this pref to &lt;code&gt;false&lt;/code&gt;,
and setting &lt;code&gt;doubleClickSelectsAll&lt;/code&gt; pref to &lt;code&gt;true&lt;/code&gt;: that is the default
behaviour for Firefox on GNU/Linux... that time at least...&lt;/p&gt;
&lt;p&gt;Much to my disappointment, the pref are setting correctly, but nothing
works. I tried to search for this, but without success, maybe since
this bug was so new, or I was to silly to apply the right keywords
(huh, maybe the latter one?). So I created an account on Mozilla&amp;#39;s
bugtracker just to open &lt;a href=&#34;https://bugzilla.mozilla.org/show_bug.cgi?id=1629135&#34;&gt;a bug&lt;/a&gt;. At the same time I switched
back to the ESR version of Firefox, which rid me (till recently) of
this stupid address bar but still granted me security updates. A
few days ago, however, Firefox ESR was unfortunately eventually shipped
with this bug, calling for a solution.&lt;/p&gt;
&lt;a id=&#34;more&#34;&gt;&lt;/a&gt;
&lt;h1 id=&#34;Some-more-background&#34;&gt;&lt;a href=&#34;#Some-more-background&#34; class=&#34;headerlink&#34; title=&#34;Some more background&#34;&gt;&lt;/a&gt;Some more background&lt;/h1&gt;&lt;p&gt;Here I will add more background because I need to complain a lot (&amp;gt;w&amp;lt;).
If you would like to see the solution directly, &lt;a href=&#34;#The-solution&#34;&gt;jump there&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Someone on bugzilla pointed out that the bug had been
&lt;a href=&#34;https://bugzilla.mozilla.org/show_bug.cgi?id=1621570&#34;&gt;raised by someone else&lt;/a&gt;. Following that bug, I saw that
the developer was being pretty toxic and just marked it as &lt;code&gt;WONTFIX&lt;/code&gt;,
despite many people criticized the buggy behaviour and regarded
the original behaviour as signature of Firefox. I finally switched
from Ubuntu to Gentoo after the new ESR, as I would like to have more
control of my software.&lt;/p&gt;
&lt;p&gt;Yesterday I &lt;a href=&#34;https://matrix.to/#/!NREUQXSZzhWoQFQpTe:matrix.org/$16014845914171808dKKcm:matrix.org?via=matrix.org&amp;amp;via=tusooa.xyz&#34;&gt;talked&lt;/a&gt; to &lt;a href=&#34;https://outsideofinfinity.wordpress.com/&#34;&gt;tiar&lt;/a&gt; about the freedom
of users to make software behave the way they want, without necessarily
being a developer. I complained that many free/libre software does not
excel in this aspect, using Firefox &gt;=75 as an example.&lt;/p&gt;
&lt;p&gt;The thing Firefox developers does, by removing the &lt;code&gt;clickSelectsAll&lt;/code&gt;
prefs, is actually somewhat limiting users&amp;#39; freedom, as customization
becomes harder and harder. This kind of freedom has been brought up
by a KDE person as &lt;a href=&#34;https://phabricator.kde.org/T11091&#34;&gt;a goal&lt;/a&gt; called &amp;quot;freedom out of the box.&amp;quot;
In short, it aims to make changing the behaviour of a program
as easy as just using it, probably unifying the interface where a program
is used and where a program is customized.&lt;/p&gt;
&lt;p&gt;And that is reasonable: no one should have to spend quite a long time
reading an extraordinarily large code base just to make a tiny little
change that would significantly improve their lives. We will simply not
have that much time. I know tweaking system is fun... (should I say
addictive?) but still, instant result is always a good-to-have.&lt;/p&gt;
&lt;h1 id=&#34;The-solution&#34;&gt;&lt;a href=&#34;#The-solution&#34; class=&#34;headerlink&#34; title=&#34;The solution&#34;&gt;&lt;/a&gt;The solution&lt;/h1&gt;&lt;p&gt;For Firefox, we do have a &lt;a href=&#34;https://superuser.com/questions/540851/go-back-to-not-selecting-the-whole-url-when-i-click-the-address-bar&#34;&gt;solution&lt;/a&gt; without needing to
recompile. That is, to change the &lt;code&gt;omni.ja&lt;/code&gt; pack in the Firefox
distribution. Based on that I managed to restore the old good
urlbar behaviour.&lt;/p&gt;
&lt;p&gt;For my &lt;code&gt;firefox-bin&lt;/code&gt; on Gentoo, the relevant file is at
&lt;code&gt;/opt/firefox/browser/omni.ja&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;First make a copy of that file:&lt;/p&gt;
&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;cp -v /opt/firefox/browser/omni.ja omni.ja.orig&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Then unzip the file:&lt;/p&gt;
&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;mkdir omni &amp;amp;&amp;amp; unzip -d omni /opt/firefox/browser/omni.ja&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;It may return 2, but does not matter.&lt;/p&gt;
&lt;p&gt;Then edit the &lt;code&gt;modules/UrlbarInput.jsm&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Change&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;built_in&#34;&gt;this&lt;/span&gt;._preventClickSelectsAll = &lt;span class=&#34;built_in&#34;&gt;this&lt;/span&gt;.focused;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;built_in&#34;&gt;this&lt;/span&gt;._preventClickSelectsAll = &lt;span class=&#34;literal&#34;&gt;true&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;to get the &lt;code&gt;clickSelectsAll&lt;/code&gt; behaviour.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; (event.target.id == SEARCH_BUTTON_ID) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; (event.detail == &lt;span class=&#34;number&#34;&gt;2&lt;/span&gt;) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;built_in&#34;&gt;this&lt;/span&gt;.select();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  event.preventDefault();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125; &lt;span class=&#34;keyword&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; (event.target.id == SEARCH_BUTTON_ID) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;to get the &lt;code&gt;doubleClickSelectsAll&lt;/code&gt; behaviour.&lt;/p&gt;
&lt;p&gt;Note that this will &lt;em&gt;not&lt;/em&gt; put the url into primary selection
upon double click. This can be useful sometimes, if you just
would like to replace the current url with the one currently
in primary selection.
If you would like to put the url into primary selection
upon double click, which completely restores the original
behaviour, change it to&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; (event.detail == &lt;span class=&#34;number&#34;&gt;2&lt;/span&gt;) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;built_in&#34;&gt;this&lt;/span&gt;.inputField.select();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  event.preventDefault();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125; &lt;span class=&#34;keyword&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; (event.target.id == SEARCH_BUTTON_ID) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;instead.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I have also made a patch:
&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;] diff -Naur omni-old omni&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;diff -Naur omni-old/modules/UrlbarInput.jsm omni/modules/UrlbarInput.jsm&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;--- omni-old/modules/UrlbarInput.jsm    2010-01-01 00:00:00.000000000 -0500&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;+++ omni/modules/UrlbarInput.jsm        2020-10-01 19:50:41.925266392 -0400&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;@@ -2225,7 +2225,7 @@&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;         &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;         this.focusedViaMousedown = !this.focused;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;-        this._preventClickSelectsAll = this.focused;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;+        this._preventClickSelectsAll = &lt;span class=&#34;literal&#34;&gt;true&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;         &lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; (event.target != this.inputField) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;           this.focus();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;@@ -2242,7 +2242,11 @@&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;           this.selectionStart = this.selectionEnd = 0;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;         &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;-        &lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; (event.target.id == SEARCH_BUTTON_ID) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;+        // doubleClickSelectsAll&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;+        &lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; (event.detail == 2) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;+          this.select();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;+          event.preventDefault();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;+        &amp;#125; &lt;span class=&#34;keyword&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; (event.target.id == SEARCH_BUTTON_ID) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;           this._preventClickSelectsAll = &lt;span class=&#34;literal&#34;&gt;true&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;           this.search(UrlbarTokenizer.RESTRICT.SEARCH);&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;         &amp;#125; &lt;span class=&#34;keyword&#34;&gt;else&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;There is also the search bar to change. The original Superuser answer
suggests this, but as I do not use the search bar, I have not
tried it out, nor do I know what the original behaviour of it was.
&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;sed -i &lt;span class=&#34;string&#34;&gt;&amp;#x27;s/this\._preventClickSelectsAll = this\._textbox\.focused;/this._preventClickSelectsAll = true;/&amp;#x27;&lt;/span&gt;  omni/chrome/browser/content/browser/search/searchbar.js&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;After editing, we need to re-pack the files:
&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;built_in&#34;&gt;cd&lt;/span&gt; omni &amp;amp;&amp;amp; zip -0DXqr ../omni.ja * &amp;amp;&amp;amp; &lt;span class=&#34;built_in&#34;&gt;cd&lt;/span&gt; -&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;And replace the original one:
&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;cp -v omni.ja /opt/firefox/browser/omni.ja&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;You may need to change the ownership of the newly-created archive:
&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;chown [U]:[G] /opt/firefox/browser/omni.ja&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
where &lt;code&gt;[U]&lt;/code&gt; and &lt;code&gt;[G]&lt;/code&gt; refers to the owner and group of the original
file (we made a backup at &lt;code&gt;omni.ja.orig&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;To ensure everything takes effect, make a file called &lt;code&gt;.purgecaches&lt;/code&gt;
to make Firefox aware of the changes:
&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;touch /opt/firefox/browser/.purgecaches&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Okay, from now on, we shall no longer suffer from the &lt;code&gt;clickSelectsAll&lt;/code&gt;
bug.&lt;/p&gt;
&lt;p&gt;Also, you may want to have additional configurations, such as
&lt;a href=&#34;https://www.userchrome.org/megabar-styling-firefox-address-bar.html&#34;&gt;disabling the pop-up list upon clicking address bar&lt;/a&gt;
or &lt;a href=&#34;https://github.com/WesleyBranton/Remove-Firefox-Megabar/blob/master/remove_megabar.css&#34;&gt;gettind rid of the address bar expanding effect&lt;/a&gt;
when clicked upon.&lt;/p&gt;
</content>
        <category term="firefox" />
        <category term="无奈" />
        <category term="坑" />
        <category term="javascript" />
        <updated>2020-10-02T00:15:56.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2019/08/24/Pay-another-respect-to-kritacommand-which-we-are-going-beyond/</id>
        <title>Pay another respect to kritacommand--which we are going beyond</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2019/08/24/Pay-another-respect-to-kritacommand-which-we-are-going-beyond/"/>
        <content type="html">&lt;blockquote&gt;
&lt;p&gt;Your work is gonna make Krita significantly different.
-- &lt;a href=&#34;https://invent.kde.org/woltherav&#34;&gt;Wolthera&lt;/a&gt;, Krita developer and digital artist&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Krita&amp;#39;s undo system, namely &lt;code&gt;kritacommand&lt;/code&gt;, was &lt;a href=&#34;https://invent.kde.org/kde/krita/commit/76fc48a7ce15afb93c072d4faa77da831517ee52&#34;&gt;added&lt;/a&gt; 8 years ago to Calligra under the name of &lt;code&gt;kundo2&lt;/code&gt;, as a fork of Qt&amp;#39;s undo framework. The use of undo commands, however, might have an even longer history. Undo commands provide a way to revert individual actions. Up to now, most (&lt;a href=&#34;https://invent.kde.org/kde/krita/merge_requests/32/diffs&#34;&gt;though not all&lt;/a&gt;) undo commands do it by providing two sets of code that do and undo the actions, respectively. Drawbacks of this system includes (1) it is not very easy to manage; (2) it may introduce duplicated code; and (3) it makes it hard to access a previous document state without actually going back to that state. What I do is to start getting rid of such situation.&lt;/p&gt;
&lt;p&gt;The plan for a new system is to use shallow copies to store documents at different states. Dmitry said &amp;quot;it was something we really want to do and allows us to make historical brushes (fetch content from earlier document states).&amp;quot; And according to him, he spent years to implement copy-on-write on paint layers. He suggested me to start from vector layers which he thought would be easier since it does not need to be very thread-safe. &lt;/p&gt;
&lt;p&gt;I completely understood that was a challenge, but did not realize where the difficult part was until I come here. Copy-on-write is not the challenging part. We have &lt;code&gt;QSharedDataPointer&lt;/code&gt; and almost all the work is to routinely replace the same code. Porting tools is more difficult. The old flake tools are running under the GUI thread, which makes no requirement on thread-safety. Technically we do not need to run it in a stroke / in image thread but with no multithreading the tools runs too slowly on some computers (read as &amp;quot;my Thinkpad laptop&amp;quot;) so I am not unwilling to take this extra challenge. In previous posts I described how the strokes work and the problems I encountered. Besides that there are still some problems I need to face.&lt;/p&gt;
&lt;h2 id=&#34;the-HACK-code-in-the-stroke-strategy&#34;&gt;&lt;a href=&#34;#the-HACK-code-in-the-stroke-strategy&#34; class=&#34;headerlink&#34; title=&#34;the HACK code in the stroke strategy&#34;&gt;&lt;/a&gt;the HACK code in the stroke strategy&lt;/h2&gt;&lt;p&gt;At the last of the strokes post, I proposed a fix to the crash when deleting &lt;code&gt;KisNode&lt;/code&gt;, which is messy. After testing with Dmitry at the sprint, we discovered that the real problems lies in &lt;code&gt;KoShapeManager&lt;/code&gt;&amp;#39;s &lt;code&gt;updateTreeCompressor&lt;/code&gt;. It is used to schedule updates of its R-tree. However, it is run at the beginning of every other operation so Dmitry says it is no longer needed. After the compressor was removed we are safe to delete the node normally so there would be no need for such hack code.&lt;/p&gt;
&lt;h2 id=&#34;Path-tool-crashing-when-editing-calligraphic-shapes&#34;&gt;&lt;a href=&#34;#Path-tool-crashing-when-editing-calligraphic-shapes&#34; class=&#34;headerlink&#34; title=&#34;Path tool crashing when editing calligraphic shapes&#34;&gt;&lt;/a&gt;Path tool crashing when editing calligraphic shapes&lt;/h2&gt;&lt;p&gt;Calligraphic shapes, coming from Karbon, is a shape created by hand-drawing. It has many path points and editing it using path tool usually leads to a crash. Dmitry tested it with ASan and discovered the problem occurs because the path points, which is fetched in the GUI thread to paint the canvas, could be deleted when editing the shape. He suggests to apply a lock to the canvas, not allowing the image and GUI threads to access the shapes concurrently.&lt;/p&gt;
&lt;h2 id=&#34;Keeping-selections-after-undo-redoing&#34;&gt;&lt;a href=&#34;#Keeping-selections-after-undo-redoing&#34; class=&#34;headerlink&#34; title=&#34;Keeping selections after undo/redoing&#34;&gt;&lt;/a&gt;Keeping selections after undo/redoing&lt;/h2&gt;&lt;p&gt;This challenge is a smaller one. The shape selections were not kept, since they are not part of the layer. It was owned by the layer&amp;#39;s shape manager, though, but a cloned layer would take a brand-new shape manager. In addition &lt;code&gt;undo()&lt;/code&gt; and &lt;code&gt;redo()&lt;/code&gt; will now replace the whole layer, so pointers to original shapes are no longer valid. This means merely keeping the selections from the shape manager would not work. The solution is to map the selected shapes to the cloned layer, which would be kept in the undo command. The strategy I use is similar to what we have done for layers: go through the whole heirarchy of the old layer and push everything into a queue; go through the heirarchy of the cloned layer in the same order and each time take the first shape in the queue; if the popped shape is in the selection, we add its counterpart in the cloned layer to our new selection.&lt;/p&gt;
&lt;p&gt;For now the tools should be working and the merge request is prepared for final review. Hopefully it would make its way to &lt;code&gt;master&lt;/code&gt; soon.&lt;/p&gt;
</content>
        <category term="kde" />
        <category term="krita" />
        <category term="c++" />
        <category term="tech" />
        <updated>2019-08-24T23:51:09.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2019/08/21/The-Sprint/</id>
        <title>The Sprint</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2019/08/21/The-Sprint/"/>
        <content type="html">&lt;p&gt;Hi -)) haven&amp;#39;t posted for some time, because I was busy travelling and coding for the first half of the month. From Aug 5 to Aug 9, I went to the Krita Sprint in Deventer, Netherlands.&lt;/p&gt;
&lt;p&gt;According to Halla, I was the first person to arrive. My flight took a transit via Hong Kong where some flights were affected due to natural and social factors, but fortunately mine was not one of them. Upon arrival in Amsterdam I got a ticket for the Intercity to Deventer. Railway constructions made me take a transfer via Utrecht Centraal, but that was not a problem at all: the station has escalators going both up to the hall, and down to the platforms (in China you can only go to the hall by stairs or elevator (which is often crowded after you get off)). When I got out of Deventer Station, Halla immediately recognized me (how?!). It was early in the morning, and the street&amp;#39;s quietness was broken by the sound of me dragging my suitcase. Halla led me through Deventer&amp;#39;s crooked streets and alleys to his house.&lt;/p&gt;
&lt;p&gt;For the next two days people gradually arrived. I met my main mentor &lt;a href=&#34;https://invent.kde.org/dkazakov&#34;&gt;Dmitry&lt;/a&gt; (magician!) and his tiger, Sagoskatt, which I (and many others) have mistaken for a giraffe. He was even the voice actor for Sago. He had got quite a lot of insights into the code base (according to Halla, &amp;quot;80%&amp;quot;) and solved a number of bugs in Krita (but he said he introduced a lot of bugs, ha!). Also I met David Revoy (my favourite painter!), the author of &lt;a href=&#34;https://peppercarrot.com&#34;&gt;Pepper and Carrot&lt;/a&gt;. And Tiar, our developer who started to work full-time on Krita this year; she had always been volunteering to support other Krita users and always on the IRC and Reddit. And two of other three GSoC students for the year: &lt;a href=&#34;https://invent.kde.org/albertofl&#34;&gt;Blackbeard&lt;/a&gt; (just as his face) and &lt;a href=&#34;https://invent.kde.org/kuntalmajumder&#34;&gt;Hellozee&lt;/a&gt;. &lt;a href=&#34;https://invent.kde.org/szaman&#34;&gt;Sh_zam&lt;/a&gt; could not come and lost communications due to political issues, which was really unfortunate (eh at least now he can be connected). It is feels so good to be able to see so many people in the community -- they are so nice! And it is such an experience to hack in a basement church.&lt;/p&gt;
&lt;p&gt;On Aug 7 we went to the Open Air Museum. It displays a large extent of the history in the Netherlands, how their people lived. After a really delicious lunch we went out and started to do paintings. I was to paint on my Surface using Krita, but unfortunately it went out of battery so I had to gave up and painted on a postcard. The tram in the museum is my favourite one (I am always fond of transit) and they even have a carhouse where stood lots of old vehicles. Except for my head which hit the ceiling of the coach three times, everything that day was wonderful.&lt;/p&gt;
&lt;p&gt;The next day was the main meeting. In the morning we discussed the development plans for Krita. Bugs. Stability. New features. David Revoy came up again with the &lt;a href=&#34;https://bugs.kde.org/show_bug.cgi?id=407851&#34;&gt;docker size problem&lt;/a&gt;, which Halla simply called it &amp;quot;a Qt problem.&amp;quot; He said, &amp;quot;Yes I do know what to do with that, but new users probably don&amp;#39;t and thus we gotta address it and not solely blame Qt.&amp;quot; (Yeah it troubled me a lot as well!) Another thing closely related to me was &lt;a href=&#34;https://invent.kde.org/websites/docs-krita-org/merge_requests/57&#34;&gt;building on Windows&lt;/a&gt;, which was largely neglected by KDE. In the afternoon the focus shifted to marketing. I did not know much about it, but it is a fact that we cannot produce electricity out of love. We spent quite a lot of time on the painting competition for Krita. Where it should be held. How to collect the paintings. How to filter out good pictures. Krita promotes new artists. They promote our software.&lt;/p&gt;
&lt;p&gt;For the next two days people started leaving. I left on the 10th, and then slept for a whole day when I got to Nanjing (so tired...). On Aug 14th I left again for Toronto, and then restarted to write code and debug. I finally got the time to write this post today, as I finally fixed a crash in my project. It is almost finished, and soon another post would be made on it.&lt;/p&gt;
</content>
        <category term="kde" />
        <category term="krita" />
        <updated>2019-08-22T03:16:54.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2019/07/26/Strokes-are-Working-Now/</id>
        <title>Strokes are Working Now</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2019/07/26/Strokes-are-Working-Now/"/>
        <content type="html">&lt;p&gt;Okay, good news today. I have been porting DefaultTool to the new node-replacing system and 
it is working now, finally, at least for the part I have already done.&lt;/p&gt;
&lt;p&gt;The work involves combining a number of different modules in Krita: the stroke system,
KoInteractionTool and its interaction strategies, and, well, the COW mechanism in Flake.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;KoInteractionTool&lt;/code&gt; is the class used to manage the interaction with vector shapes, and 
is subclassed by &lt;code&gt;DefaultTool&lt;/code&gt;. The behaviours of &lt;code&gt;KoInteractionTool&lt;/code&gt; (and thus &lt;code&gt;DefaultTool&lt;/code&gt;) 
are defined by &lt;code&gt;KoInteractionStrategy&lt;/code&gt;s. Upon the press of the mouse button, &lt;code&gt;DefaultTool&lt;/code&gt; 
creates an instance of some subclass of &lt;code&gt;KoInteractionStrategy&lt;/code&gt;, say, &lt;code&gt;ShapeMoveStrategy&lt;/code&gt;, 
according to the point of the click as well as keyboard modifiers. Mouse move events after that 
are all handled by the interaction strategy. When the mouse is released, the interaction strategy&amp;#39;s 
&lt;code&gt;finishInteraction()&lt;/code&gt; is called, and then &lt;code&gt;createCommand()&lt;/code&gt;. If the latter returns some 
&lt;code&gt;KUndo2Command&lt;/code&gt;, the command is added to the undo history. Till now it sounds simple.&lt;/p&gt;
&lt;p&gt;So how does the stroke system come in? I have experimented the interaction strategy 
without the stroke system (&lt;a href=&#34;commit&#34;&gt;https://invent.kde.org/tusooaw/krita/commit/638bfcd84c622d3cfefda1e5132380439dd3fdc2&lt;/a&gt;), 
but it is really slow and even freezes Krita for a while sometimes. The stroke system 
allows the modification of the shapes to run in the image thread, instead of the GUI thread. 
A stroke is a set of jobs scheduled and run by a &lt;code&gt;KisStrokesFacade&lt;/code&gt; (here, &lt;code&gt;KisImage&lt;/code&gt;). 
One creates the stroke in a strokes facade using a stroke strategy, which defines the behaviour 
of the stroke. After creation, jobs can be added to the stroke and then executed at some later 
time (it is asynchronous). &lt;/p&gt;
&lt;p&gt;So combining these two, we have an interaction strategy and a stroke strategy -- 
when the interaction strategy is created, we start the stroke in the image; 
when there is mouse move, we add individual jobs that change the shapes to the stroke; 
when the mouse released, we end the stroke. 
My discussion with Dmitry firstly tended to make the interaction strategy inherit 
the stroke strategy but later it proves not a viable solution since the interaction 
strategy is owned and deleted by &lt;code&gt;KoInteractionTool&lt;/code&gt; while the stroke strategy is owned 
by the stroke --- which will lead to double deletion. So we divide it into two classes 
instead: the interaction strategy starts the stroke, and the stroke strategy takes a copy 
of the current active layer upon creation; when handling mouse move events, a job is added 
to the stroke to modify the current layer; finally when the interaction finishes, 
the interaction strategy ends the stroke and creates an undo command if the layer has been 
changed.&lt;/p&gt;
&lt;p&gt;A problem I found lies in the final stage--if the mouse is released as soon as being pressed 
and no undo command is created, Krita will simply crash. It does not happen when I use &lt;code&gt;gdb&lt;/code&gt; 
to start Krita so it seems to be a timing issue though it leads to difficulty for debugging as 
well. Dmitry used a self-modified version of Qt to produce a backtrace, indicating the problem 
probably lies in &lt;code&gt;KisCanvas2&lt;/code&gt;&amp;#39;s &lt;code&gt;canvasUpdateCompressor&lt;/code&gt;, which is not thread-safe. However, 
after I changed it to &lt;code&gt;KisThreadSafeSignalCompressor&lt;/code&gt;, the crash still happens, unfortunately. &lt;/p&gt;
&lt;p&gt;The final inspiration comes from the comments in &lt;code&gt;KisThreadSafeSignalCompressor&lt;/code&gt;, though. It 
indicates we cannot delete the compressor from other threads --- we have to use &lt;code&gt;obj-&amp;gt;deleteLater()&lt;/code&gt; 
instead, since it lies in the gui thread. And aha, that is the problem. The stroke strategy&amp;#39;s destructor 
is executed in the image thread; if the undo command is not created, there is only one reference to 
our copied &lt;code&gt;KisNode&lt;/code&gt;, namely in our stroke strategy, so it has to be destructed there. However, upon 
the creation of the &lt;code&gt;KisNode&lt;/code&gt;, it is moved into the gui thread. So it simply means we cannot let it 
be deleted in the image thread. The solution looks a little bit messy, but it works:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;KisNode *node = m_d-&amp;gt;originalState.&lt;span class=&#34;built_in&#34;&gt;data&lt;/span&gt;(); &lt;span class=&#34;comment&#34;&gt;// take the address from KisSharedPtr&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;node-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;ref&lt;/span&gt;(); &lt;span class=&#34;comment&#34;&gt;// prevent KisSharedPtr from deleting the node&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;m_d-&amp;gt;originalState.&lt;span class=&#34;built_in&#34;&gt;clear&lt;/span&gt;(); &lt;span class=&#34;comment&#34;&gt;// now node is not being referenced by any KisSharedPtr&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;node-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;deref&lt;/span&gt;(); &lt;span class=&#34;comment&#34;&gt;// the reference count is now zero again&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;node-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;deleteLater&lt;/span&gt;(); &lt;span class=&#34;comment&#34;&gt;// it will be deleted by the event loop, later&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
</content>
        <category term="kde" />
        <category term="krita" />
        <category term="c++" />
        <category term="tech" />
        <updated>2019-07-26T15:40:29.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2019/07/09/make-j5-kritaflake/</id>
        <title>`make -j5 kritaflake`</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2019/07/09/make-j5-kritaflake/"/>
        <content type="html">&lt;p&gt;At the end of June I finished copy-on-write vector layers. From the very beginning, I have been 
&lt;a href=&#34;https://tusooa.github.io/2019/05/18/Polymorphism-and-Implicit-Sharing/&#34;&gt;researching into&lt;/a&gt; 
possibilities to make &lt;code&gt;kritaflake&lt;/code&gt; implicitly sharable. In that post I mentioned the way 
Sean Parent uses for Photoshop, and adapted it for the derived d-pointers in Flake. &lt;/p&gt;
&lt;h2 id=&#34;Derived-d-pointers&#34;&gt;&lt;a href=&#34;#Derived-d-pointers&#34; class=&#34;headerlink&#34; title=&#34;Derived d-pointers&#34;&gt;&lt;/a&gt;Derived d-pointers&lt;/h2&gt;&lt;p&gt;TL;DR: We got rid of it.&lt;/p&gt;
&lt;p&gt;As I mentioned in the &lt;a href=&#34;https://phabricator.kde.org/T10901&#34;&gt;task page&lt;/a&gt;, derived d-pointers originally 
in Flake are a barrier to implicit sharing. One of the reasons is that we need to write more code (either 
&lt;code&gt;KisSharedDescendent&lt;/code&gt; wrapper class, or repeated code for virtual clone functions). Also, derived 
d-pointers do not actually encapsulate the data in the parent classes -- for example, the members in 
&lt;code&gt;KoShapePrivate&lt;/code&gt; are all accessible by descendents of &lt;code&gt;KoShape&lt;/code&gt;, say, &lt;code&gt;KoShapeContainer&lt;/code&gt;. That is probably 
not how encapsulating should work. So in the end we decided to get rid of derived d-pointers in Flake.&lt;/p&gt;
&lt;p&gt;This leads to one problem, however, in the class &lt;code&gt;KoShapeGroup&lt;/code&gt;. &lt;code&gt;KoShapeGroup&lt;/code&gt; is a descendent of &lt;code&gt;KoShapeContainer&lt;/code&gt;, 
which owns a &lt;code&gt;KoShapeContainerModel&lt;/code&gt; that can be subclassed to control the behaviour when a child is added to or 
removed from the container. &lt;code&gt;KoShapeGroup&lt;/code&gt; uses &lt;code&gt;ShapeGroupContainerModel&lt;/code&gt; which performs additional operations 
specific to &lt;code&gt;KoShapeGroup&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After I merged my branch into master, it was said that Flake tests failed under address sanitizer (ASan). I 
took a look and discovered that there was use after free in the class &lt;code&gt;KoShapeGroup&lt;/code&gt;, namely the use of its 
d-pointer. The use is called by the destructor of &lt;code&gt;KoShapeContainer&lt;/code&gt;, which calls 
&lt;code&gt;KoShapeContainerModel::deleteOwnedShapes()&lt;/code&gt;, which removes individual shapes 
from the container, which then calls &lt;code&gt;KoShapeGroup::invalidateSizeCache()&lt;/code&gt;. The original situation was:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;destructor of &lt;code&gt;KoShapeGroup&lt;/code&gt; was called; &lt;/li&gt;
&lt;li&gt;members defined in &lt;code&gt;KoShapeGroup&lt;/code&gt; got deleted (nothing, because 
everything is in the derived d-pointer which is defined in &lt;code&gt;KoShape&lt;/code&gt;); &lt;/li&gt;
&lt;li&gt;destructor of &lt;code&gt;KoShapeContainer&lt;/code&gt; 
was called, which calls &lt;code&gt;d-&amp;gt;model-&amp;gt;deleteOwnedShapes()&lt;/code&gt;; &lt;/li&gt;
&lt;li&gt;then that of &lt;code&gt;KoShape&lt;/code&gt;, which deletes all the private members. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But after the derived d-pointers are converted to normal ones, the calling sequence upon destruction 
becomes: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;destructor of &lt;code&gt;KoShapeGroup&lt;/code&gt; was called; &lt;/li&gt;
&lt;li&gt;members defined in &lt;code&gt;KoShapeGroup&lt;/code&gt; got deleted (its own d-pointer); &lt;/li&gt;
&lt;li&gt;destructor of &lt;code&gt;KoShapeContainer&lt;/code&gt; was called, which calls &lt;code&gt;d-&amp;gt;model-&amp;gt;deleteOwnedShapes()&lt;/code&gt;; &lt;/li&gt;
&lt;li&gt;&lt;code&gt;d-&amp;gt;model&lt;/code&gt; is a &lt;code&gt;ShapeGroupContainerModel&lt;/code&gt;, which will call &lt;code&gt;KoShapeGroup::invalidateSizeCache()&lt;/code&gt;; &lt;/li&gt;
&lt;li&gt;that last function accesses the d-pointer of &lt;code&gt;KoShapeGroup&lt;/code&gt;, USE AFTER FREE. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In order to solve this problem we have to manually call &lt;code&gt;model()-&amp;gt;deleteOwnedShapes()&lt;/code&gt; in the destructor 
of &lt;code&gt;KoShapeGroup&lt;/code&gt;, at which time the d-pointer is still accessible.&lt;/p&gt;
&lt;h2 id=&#34;q-pointers&#34;&gt;&lt;a href=&#34;#q-pointers&#34; class=&#34;headerlink&#34; title=&#34;q-pointers&#34;&gt;&lt;/a&gt;q-pointers&lt;/h2&gt;&lt;p&gt;TL;DR: We also got rid of it. &lt;/p&gt;
&lt;p&gt;q-pointers are a method used in Qt to hide private methods from the header files, in order to improve 
binary compatibility. q-pointers are stored in *Private classes (&lt;code&gt;d&lt;/code&gt;s), indicating the object that owns 
this private instance. But this is, of course, conflicting with the principle of &amp;quot;sharing&amp;quot; because 
the situation now is that multiple objects can own the same data. The q-pointers in flake is rather confusing 
under such circumstances, since the private data cannot know which object is the caller. &lt;/p&gt;
&lt;p&gt;To avoid this confusion, there are multiple ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;to move all the functions regarding q-pointers to the public classes; &lt;/li&gt;
&lt;li&gt;to pass the q-pointer every time when calling those functions in private classes; or &lt;/li&gt;
&lt;li&gt;to add another layer of &amp;quot;shared data&amp;quot; in the d-pointer and keep the q-pointers in the unshared part. &lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;implicit-sharing&#34;&gt;&lt;a href=&#34;#implicit-sharing&#34; class=&#34;headerlink&#34; title=&#34;implicit sharing&#34;&gt;&lt;/a&gt;implicit sharing&lt;/h2&gt;&lt;p&gt;To enable implicit sharing for the &lt;code&gt;KoShape&lt;/code&gt; hierarchy, the only thing left to be done is to 
change the &lt;code&gt;QScopedPointer&amp;lt;Private&amp;gt; d;&lt;/code&gt; in the header file to &lt;code&gt;QSharedDataPointer&amp;lt;Private&amp;gt; d;&lt;/code&gt; 
and make the private classes inherit &lt;code&gt;QSharedData&lt;/code&gt;. This step is rather easy and then just run the 
tests to make sure it does not break anything. Horray! &lt;/p&gt;
</content>
        <category term="kde" />
        <category term="krita" />
        <category term="c++" />
        <category term="tech" />
        <updated>2019-07-09T17:37:14.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2019/06/21/Snapshot-Docker/</id>
        <title>Snapshot Docker</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2019/06/21/Snapshot-Docker/"/>
        <content type="html">&lt;p&gt;Over the past few weeks I have been working on the &lt;a href=&#34;https://phabricator.kde.org/T10991&#34;&gt;Snapshot Docker&lt;/a&gt;, 
and now it is finished already. -))&lt;/p&gt;
&lt;p&gt;The idea of snapshots is to make copies of the current document and allow users to return to them at a later 
time. This is a part of my whole Google Summer of Code project, which aims to bring Krita a better undo/redo 
system. When fully implemented, it will fully replace the current mechanism that stores actions with one that 
stores different states. That is to say, Krita will create a snapshot of the document for every undoable step.&lt;/p&gt;
&lt;p&gt;Snapshot Docker is not only a feature requested by artists but also a experimental implementation of the 
clone-replace mechanism. It has the following key parts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cloning the document, which is provided by &lt;code&gt;KisDocument::lockAndCloneForSaving()&lt;/code&gt;, which is already implemented 
in master.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace the current document by another one, which is previously cloned.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Part (1) is already implemented so the work falls mainly on Part (2). My original approach is to replace the 
document and image pointers in &lt;code&gt;KisView&lt;/code&gt; and &lt;code&gt;KisCanvas&lt;/code&gt;, but it is not viable since other parts of the program 
have signal/slot connections on the &lt;code&gt;KisDocument&lt;/code&gt; and &lt;code&gt;KisImage&lt;/code&gt;, and directly replacing the two pointers will 
not only fail to work but also cause weird crashes. After discussing with &lt;a href=&#34;https://invent.kde.org/dkazakov&#34;&gt;Dmitry&lt;/a&gt;, 
we find out that it is probably better not to touch these two pointers, but to replace the content within
&lt;code&gt;KisDocument&lt;/code&gt; and &lt;code&gt;KisImage&lt;/code&gt;. It is therefore suggested that two member functions be made, namely 
&lt;code&gt;KisDocument::copyFromDocument&lt;/code&gt; and &lt;code&gt;KisImage::copyFromImage&lt;/code&gt;. These functions copies data from another document/image 
to the current one, avoiding the changes to the pointers inside the original instance. Eh, except for the nodes, 
since we have to reset and refresh the nodes in the image. &lt;/p&gt;
&lt;p&gt;It is also important to notify other parts of Krita about the change in the document. One important thing is 
tell the layer docker about the changes in the nodes (they are completely different), which is done using the 
&lt;code&gt;KisImage::sigLayersChangedAsync()&lt;/code&gt; signal. The current activated node is also stored and restored, by using 
the strategy of linearizing the layer tree using a queue, and then finding the corresponding node in the cloned 
image. Note that when restoring, we are unable to find layer by uuid, since they should change when copied to 
the current image (the comments in &lt;code&gt;KisImage&lt;/code&gt; says the only situation where we should keep the uuids is for saving).&lt;/p&gt;
&lt;p&gt;Another interesting thing is the palettes. Krita 4.2.0 allows documents to store their own, local palettes. 
The palette list is but a &lt;code&gt;QList&amp;lt;KoColorSet *&amp;gt;&lt;/code&gt;, meaning that only creating a new &lt;code&gt;QList&lt;/code&gt; of the same pointers 
will not work. This is because, the palettes are controlled by canvas resource manager, which takes the responsibility 
to delete them. Therefore, when taking snapshots, we had better take deep copies of the &lt;code&gt;KoColorSet&lt;/code&gt;s. And then 
another problem comes: the snapshots own their &lt;code&gt;KoColorSet&lt;/code&gt;s because they are not controlled by the resource manager 
in any way; but the &lt;code&gt;KisDocument&lt;/code&gt; in the view does not. So we have to set up another flag, &lt;code&gt;ownsPaletteList&lt;/code&gt;, to 
tell the document whether it should delete the palettes in the destructor.&lt;/p&gt;
&lt;p&gt;And now the work has shifted to the refactoring of &lt;code&gt;kritaflake&lt;/code&gt;, the library that mainly handles vector layers and 
shapes. I converted the whole &lt;code&gt;KoShape&lt;/code&gt; hierarchy to implicit sharing where possible, but some tests are broken. I 
am now on Windows, where unit tests do not run. I will continue the development of flake as soon as I get access to 
my Linux laptop.&lt;/p&gt;
</content>
        <category term="kde" />
        <category term="krita" />
        <updated>2019-06-21T15:40:38.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2019/06/16/New-Style-Signal-Slot-Connection/</id>
        <title>New Style Signal/Slot Connection</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2019/06/16/New-Style-Signal-Slot-Connection/"/>
        <content type="html">&lt;p&gt;Yes, I know. The last post on the assistants is rather boring. And yet these days I have been 
working on the &lt;a href=&#34;https://invent.kde.org/kde/krita/merge_requests/41&#34;&gt;snapshot docker&lt;/a&gt;, though 
it still seems a little (just a little, you see) unfinished as Dmitry is said to experience 
a relatively high delay when switching between snapshots. However this is not what I can reproduce 
on my older laptop, so I am really waiting for his test results in order to further investigate 
the problem.&lt;/p&gt;
&lt;p&gt;But there &lt;em&gt;is&lt;/em&gt; something interesting happening just when I am randomly testing things. From
Krita&amp;#39;s debug output, I saw &lt;code&gt;QObject::connect()&lt;/code&gt; complaining about the arguments I passed, 
saying it is expecting parenthesis. &amp;quot;Okay,&amp;quot; I thought, &amp;quot;then there have to be something wrong 
with the &lt;a href=&#34;https://invent.kde.org/kde/krita/merge_requests/41/diffs?commit_id=8c465f12139318e86ab36d343e1db8bbbb141e06&#34;&gt;code I wrote&lt;/a&gt;.&amp;quot; 
And that was quite confusing. I remember having used member function pointers in those places, 
got a compile-time error since &lt;code&gt;KisSignalAutoConnectionsStore&lt;/code&gt; did not support the new syntax,
then switched back to the &lt;code&gt;SINGAL()&lt;/code&gt; and &lt;code&gt;SLOT()&lt;/code&gt; macros. &lt;code&gt;KisSignalAutoConnectionsStore&lt;/code&gt; is 
a helper class to quickly (dis)connect a group of connections. One can use the &lt;code&gt;addConnection()&lt;/code&gt; 
method to add a connection, and use &lt;code&gt;clear()&lt;/code&gt; to remove all connections made before. &lt;/p&gt;
&lt;p&gt;Well, everything good, apart from the fact that I missed the parenthesis, which I did not 
discover until I looked into the debug output. So I asked Dmitry why not add the new syntax 
to &lt;code&gt;KisSignalAutoConnectionsStore&lt;/code&gt;, and he said we should. &lt;/p&gt;
&lt;p&gt;What is good about the new syntax is compile-time checking. We probably do not want our connections
to fail to be made only when you run the program, just because there is a typo in the signature. 
That is definitely tiring and hard to catch (hmm, I did not notice the problem until today I 
randomly glanced at the command line; it might be worse if I shipped the snapshot docker together 
with those careless bugs).&lt;/p&gt;
&lt;p&gt;The modification to the code seems straightforward. All what happens is in the &lt;code&gt;KisSignalAutoConnection&lt;/code&gt; 
class. In its constructor, the connection is made using &lt;code&gt;QObject::connect()&lt;/code&gt;; in its destructor, 
the connection is removed by passing the same sets of arguments to &lt;code&gt;QObject::disconnect()&lt;/code&gt; currently 
in &lt;code&gt;master&lt;/code&gt;. The signature is just &lt;code&gt;KisSignalAutoConnection(const QObject *, const char *, const QObject *, const char *)&lt;/code&gt;, 
as &lt;code&gt;SIGNAL()&lt;/code&gt; and &lt;code&gt;SLOT()&lt;/code&gt; macros are but to append their arguments to the string &lt;code&gt;&amp;quot;1&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;2&amp;quot;&lt;/code&gt; respectively. &lt;/p&gt;
&lt;p&gt;So the problem we have is we do not want the arguments that specify the signals and/or slots 
to be just strings. We want them to be pointers to member functions, or maybe lambdas. 
According to QObject document, the signature for new-style &lt;code&gt;connect()&lt;/code&gt; is:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;QMetaObject::Connection &lt;span class=&#34;title&#34;&gt;QObject::connect&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; QObject *sender, PointerToMemberFunction signal, &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Okay, so we know that &lt;code&gt;sender&lt;/code&gt; and &lt;code&gt;receiver&lt;/code&gt; should be pointers to &lt;code&gt;QObject&lt;/code&gt;s, and 
either the type of &lt;code&gt;signal&lt;/code&gt; or &lt;code&gt;functor&lt;/code&gt; we do not know. 
Now let&amp;#39;s make our &lt;code&gt;KisSignalAutoConnection&lt;/code&gt; constructor a template function: &lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;template&lt;/span&gt;&amp;lt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Signal&lt;/span&gt;, &lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Method&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;inline&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;KisSignalAutoConnection&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; QObject *sender, Signal signal,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;params&#34;&gt;                               &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; QObject *receiver, Method method&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;params&#34;&gt;                               Qt::ConnectionType type = Qt::AutoConnection)&lt;/span&gt;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;But when these parameters are passed to &lt;code&gt;QObject::connect()&lt;/code&gt;, we get a compile-time error, saying 
there is no matching overload for &lt;code&gt;connect()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;p&gt;The answer is the Qt documentation is simplifying, if not hiding, the truth. The real definition 
for &lt;code&gt;connect()&lt;/code&gt; is found in Line 227 of &lt;code&gt;qobject.h&lt;/code&gt;:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;template&lt;/span&gt; &amp;lt;&lt;span class=&#34;keyword&#34;&gt;typename&lt;/span&gt; Func1, &lt;span class=&#34;keyword&#34;&gt;typename&lt;/span&gt; Func2&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;inline&lt;/span&gt; QMetaObject::Connection &lt;span class=&#34;title&#34;&gt;connect&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;typename&lt;/span&gt; QtPrivate::FunctionPointer&amp;lt;Func1&amp;gt;::Object *sender, Func1 signal,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;params&#34;&gt;                                 &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;typename&lt;/span&gt; QtPrivate::FunctionPointer&amp;lt;Func2&amp;gt;::Object *receiver, Func2 slot,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;params&#34;&gt;                                 Qt::ConnectionType type = Qt::AutoConnection)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;And tracking down the definition of &lt;code&gt;QtPrivate::FunctionPointer&lt;/code&gt;, we get it in &lt;code&gt;qobjectdefs_impl.h&lt;/code&gt;:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;template&lt;/span&gt;&amp;lt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Obj&lt;/span&gt;, &lt;span class=&#34;title&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Ret&lt;/span&gt;, &lt;span class=&#34;title&#34;&gt;typename&lt;/span&gt;... &lt;span class=&#34;title&#34;&gt;Args&lt;/span&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;FunctionPointer&lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;built_in&#34;&gt;Ret&lt;/span&gt; (Obj::*) (Args...)&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;typedef&lt;/span&gt; Obj Object;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ...&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;And seeing what we have passed to &lt;code&gt;KisSignalAutoConnection&lt;/code&gt; (in the &lt;a href=&#34;https://invent.kde.org/kde/krita/merge_requests/41/diffs?commit_id=39262a9385fb933ab428f4a72939a692994e0f21#dbe442eaf45dc765d904fe6d9922b309d19f1d5a&#34;&gt;test code&lt;/a&gt;):&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;KisSignalAutoConnectionsStore conn;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;conn.&lt;span class=&#34;built_in&#34;&gt;addConnection&lt;/span&gt;(test1.&lt;span class=&#34;built_in&#34;&gt;data&lt;/span&gt;(), &amp;amp;TestClass::sigTest1, test2.&lt;span class=&#34;built_in&#34;&gt;data&lt;/span&gt;(), &amp;amp;TestClass::slotTest1);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;We can see that &lt;code&gt;Func1&lt;/code&gt; is a member function of &lt;code&gt;TestClass&lt;/code&gt;, so &lt;code&gt;QtPrivate::FunctionPointer&amp;lt;Func1&amp;gt;::Object&lt;/code&gt; 
is just &lt;code&gt;TestClass&lt;/code&gt;. But the constructor of &lt;code&gt;KisSignalAutoConnection&lt;/code&gt; receives a &lt;code&gt;const QObject *&lt;/code&gt;. 
The problem here is that &lt;code&gt;connect()&lt;/code&gt; is expecting a &lt;code&gt;const TestClass *&lt;/code&gt;, but we give them a &lt;code&gt;const QObject *&lt;/code&gt;. 
A base class pointer cannot be implicitly converted to a derived class pointer, so we have that error. &lt;/p&gt;
&lt;p&gt;The resolution seems pretty simple, as we only need to include the types of &lt;code&gt;sender&lt;/code&gt; and &lt;code&gt;receiver&lt;/code&gt; 
into the template, and pass everything as-is to &lt;code&gt;QObject::connect()&lt;/code&gt;: &lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;template&lt;/span&gt;&amp;lt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Sender&lt;/span&gt;, &lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Signal&lt;/span&gt;, &lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Receiver&lt;/span&gt;, &lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Method&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;inline&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;KisSignalAutoConnection&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(Sender sender, Signal signal, Receiver receiver, Method method,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;params&#34;&gt;                               Qt::ConnectionType type = Qt::AutoConnection)&lt;/span&gt;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Sounds viable. But how can we store the four parameters? It might be intuitive to make another base class, 
say, &lt;code&gt;KisSignalAutoConnectionBase()&lt;/code&gt;, and make &lt;code&gt;KisSignalAutoConnection&lt;/code&gt; a template class, so we can 
store &lt;code&gt;sender&lt;/code&gt;, &lt;code&gt;receiver&lt;/code&gt;, etc.&lt;/p&gt;
&lt;p&gt;But wait, isn&amp;#39;t this just too complex? First of all, we do not have any overridden functions 
except for the destructor. What is more, we do not seem to have any valuable things in that base 
class -- it would be an empty class. The use of inheritance here is ugly and useless. &lt;/p&gt;
&lt;p&gt;And, we do not need to store the four parameters at all. &lt;code&gt;QObject::connect()&lt;/code&gt; returns a 
&lt;code&gt;QMetaObject::Connection&lt;/code&gt;, which can be used later to &lt;code&gt;disconnect()&lt;/code&gt; it. So instead of 
the parameters passed to &lt;code&gt;connect()&lt;/code&gt;, we just store the &lt;code&gt;Connection&lt;/code&gt; object. And that is not 
part of the template:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;template&lt;/span&gt;&amp;lt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Sender&lt;/span&gt;, &lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Signal&lt;/span&gt;, &lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Receiver&lt;/span&gt;, &lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Method&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;inline&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;KisSignalAutoConnection&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(Sender sender, Signal signal, Receiver receiver, Method method,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;params&#34;&gt;                                   Qt::ConnectionType type = Qt::AutoConnection)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;        : m_connection(QObject::connect(sender, signal, receiver, method, type))&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;    &amp;#123;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;inline&lt;/span&gt; ~&lt;span class=&#34;built_in&#34;&gt;KisSignalAutoConnection&lt;/span&gt;()&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        QObject::&lt;span class=&#34;built_in&#34;&gt;disconnect&lt;/span&gt;(m_connection);&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;private&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    QMetaObject::Connection m_connection;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;And with the &lt;a href=&#34;https://invent.kde.org/kde/krita/merge_requests/41/diffs?commit_id=39262a9385fb933ab428f4a72939a692994e0f21#dbe442eaf45dc765d904fe6d9922b309d19f1d5a&#34;&gt;test code&lt;/a&gt; mentioned above, 
we do make sure that the new implementation works well with both syntaxes. &lt;/p&gt;
&lt;p&gt;So, great, krita developers, we can use the new syntax for auto connections as well. &lt;/p&gt;
&lt;p&gt;PS: There will soon be another post on my work of the snapshot docker -- it&amp;#39;s almost finished!&lt;/p&gt;
</content>
        <category term="kde" />
        <category term="krita" />
        <category term="c++" />
        <category term="tech" />
        <updated>2019-06-17T00:12:56.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2019/05/30/Assistants-copy-share-assignment/</id>
        <title>Assistants -- copy, share, assignment</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2019/05/30/Assistants-copy-share-assignment/"/>
        <content type="html">&lt;p&gt;Over the last week I have been investigating into &lt;a href=&#34;https://bugs.kde.org/show_bug.cgi?id=361012&#34;&gt;Bug 361012&lt;/a&gt;, 
on the undo history of the modification of guides. But from the very beginning I mixed up the two terms 
&amp;quot;guides&amp;quot; and &amp;quot;assistants,&amp;quot; so I decided to &lt;a href=&#34;https://invent.kde.org/kde/krita/merge_requests/32&#34;&gt;work on both&lt;/a&gt;. 
The work with guides is a lot simpler and will not be covered here, though. &lt;/p&gt;
&lt;p&gt;As I write this post, the &lt;a href=&#34;https://invent.kde.org/kde/krita/tree/master&#34;&gt;master branch of Krita&lt;/a&gt; 
does not create any undo commands for the document. I first &lt;a href=&#34;https://invent.kde.org/kde/krita/merge_requests/32/diffs?commit_id=12bc1d0730f04321c5ec304ce09f6670ef14c576&#34;&gt;added undo commands&lt;/a&gt; for adding and removing 
assistants, which seems the easiest. The editing of them is a bit more difficult, as the dragging 
operations involve the movement of many &amp;quot;handles,&amp;quot; the movable round buttons that define the position 
of one or more assistants. The source code on master for implementing such actions is quite complicated 
and involves a great number of cases. It would be another great endeavour to put all these bunches of 
code into a &lt;code&gt;KUndo2Command&lt;/code&gt;. But, another thing I have experimented with and I will be working on 
will immediately clear the clouds.&lt;/p&gt;
&lt;p&gt;So I just thought of the copy-on-write mechanism, and yes, why not? Though COW itself is not 
actually implemented for the guides, it does seem inspiring. I mean, we can just save a copy 
of all assistants and, when needed, restore that. &lt;/p&gt;
&lt;p&gt;The main problem here is the handles. They are represented as shared pointers in individual 
assistants and may be shared between different ones (e.g. two perspectives share two corner 
handles and one side handles). When we take a clone of the list of assistants it will be 
necessary to keep this kind of relationship. My solution is to use a &lt;code&gt;QMap&lt;/code&gt; of pointers, 
which seems to coincide with the logic of exporting to xml, but I had yet to read that part
of the code when writing mine so I did not know about that. The logic is to check, for 
every handle, whether there is a mapping relationship in the map. If there is, we reuse that 
handle, and if not, we create a new one with the same position and record that relationship 
in our &lt;code&gt;QMap&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But some display properties are not to be recorded into the undo history. Such properties 
include the changing of color, visibility, etc. To resolve this problem, I put these data into 
a shared pointer and, when we are cloning an assistant for undo/redo, we will reuse that pointer.
When we replace the assistant list with the one recorded, all the display properties will remain 
since the data are shared. &lt;/p&gt;
&lt;p&gt;And for the next several weeks I will move onto the &lt;a href=&#34;https://phabricator.kde.org/T10991&#34;&gt;Snapshot Docker&lt;/a&gt;.&lt;/p&gt;
</content>
        <category term="kde" />
        <category term="krita" />
        <category term="c++" />
        <category term="code" />
        <updated>2019-05-30T18:20:53.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2019/05/18/Polymorphism-and-Implicit-Sharing/</id>
        <title>Polymorphism and Implicit Sharing</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2019/05/18/Polymorphism-and-Implicit-Sharing/"/>
        <content type="html">&lt;p&gt;Recently I have been researching into possibilities to make members of &lt;code&gt;KoShape&lt;/code&gt; copy-on-write. 
At first glance, it seems enough to declare d-pointers as some subclass of &lt;code&gt;QSharedDataPointer&lt;/code&gt; 
(see Qt&amp;#39;s &lt;a href=&#34;https://doc.qt.io/qt-5/implicit-sharing.html&#34;&gt;implicit sharing&lt;/a&gt;) and then replace 
pointers with instances. However, there remain a number of problems to be solved, one of them 
being polymorphism.&lt;/p&gt;
&lt;h2 id=&#34;polymorphism-and-value-semantics&#34;&gt;&lt;a href=&#34;#polymorphism-and-value-semantics&#34; class=&#34;headerlink&#34; title=&#34;polymorphism and value semantics&#34;&gt;&lt;/a&gt;polymorphism and value semantics&lt;/h2&gt;&lt;p&gt;In the &lt;a href=&#34;https://invent.kde.org/kde/krita/blob/aeb8a1097ad58eaff91aa34c40b18e82428b0a3a/libs/flake/KoShape_p.h#L65&#34;&gt;definition&lt;/a&gt; 
of &lt;code&gt;KoShapePrivate&lt;/code&gt; class, the member &lt;code&gt;fill&lt;/code&gt; is stored as a &lt;code&gt;QSharedPointer&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;QSharedPointer&amp;lt;KoShapeBackground&amp;gt; fill;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are a number of subclasses of &lt;code&gt;KoShapeBackground&lt;/code&gt;, including &lt;code&gt;KoColorBackground&lt;/code&gt;, 
&lt;code&gt;KoGradientBackground&lt;/code&gt;, to name just a few. We cannot store an instance of &lt;code&gt;KoShapeBackground&lt;/code&gt; 
directly since we want polymorphism. But, well, making &lt;code&gt;KoShapeBackground&lt;/code&gt; copy-on-write seems to have 
nothing to do with whether we store it as a pointer or instance. So let&amp;#39;s just put it here -- 
I will come back to this question at the end of this post.&lt;/p&gt;
&lt;h2 id=&#34;d-pointers-and-QSharedData&#34;&gt;&lt;a href=&#34;#d-pointers-and-QSharedData&#34; class=&#34;headerlink&#34; title=&#34;d-pointers and QSharedData&#34;&gt;&lt;/a&gt;d-pointers and &lt;code&gt;QSharedData&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;KoShapeBackground&lt;/code&gt; heirarchy (similar to the &lt;code&gt;KoShape&lt;/code&gt; one) uses derived d-pointers
for storing private data. To make things easier, I will here use a small example to 
elaborate on its use. &lt;/p&gt;
&lt;h3 id=&#34;derived-d-pointer&#34;&gt;&lt;a href=&#34;#derived-d-pointer&#34; class=&#34;headerlink&#34; title=&#34;derived d-pointer&#34;&gt;&lt;/a&gt;derived d-pointer&lt;/h3&gt;&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;42&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;43&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;44&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;45&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;46&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;47&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;48&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;49&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;50&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;AbstractPrivate&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&amp;#123;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;AbstractPrivate&lt;/span&gt;() : &lt;span class=&#34;built_in&#34;&gt;var&lt;/span&gt;(&lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; ~&lt;span class=&#34;built_in&#34;&gt;AbstractPrivate&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; var;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Abstract&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&amp;#123;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;comment&#34;&gt;// it is not yet copy-constructable; we will come back to this later&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;comment&#34;&gt;// Abstract(const Abstract &amp;amp;other) = default;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ~&lt;span class=&#34;built_in&#34;&gt;Abstract&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;protected&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;explicit&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Abstract&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(AbstractPrivate &amp;amp;dd)&lt;/span&gt; : d_ptr(&amp;amp;dd) &amp;#123;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;/span&gt;= &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;modifyVar&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;/span&gt;= &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;protected&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    QScopedPointer&amp;lt;AbstractPrivate&amp;gt; d_ptr;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;private&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Q_DECLARE_PRIVATE&lt;/span&gt;(Abstract)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;DerivedPrivate&lt;/span&gt; :&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt; AbstractPrivate&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;DerivedPrivate&lt;/span&gt;() : &lt;span class=&#34;built_in&#34;&gt;AbstractPrivate&lt;/span&gt;(), &lt;span class=&#34;built_in&#34;&gt;bar&lt;/span&gt;(&lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; ~&lt;span class=&#34;built_in&#34;&gt;DerivedPrivate&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; bar;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Derived&lt;/span&gt; :&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt; Abstract&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Derived&lt;/span&gt;() : &lt;span class=&#34;built_in&#34;&gt;Abstract&lt;/span&gt;(*(&lt;span class=&#34;keyword&#34;&gt;new&lt;/span&gt; DerivedPrivate)) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;comment&#34;&gt;// it is not yet copy-constructable&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;comment&#34;&gt;// Derived(const Derived &amp;amp;other) = default;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ~&lt;span class=&#34;built_in&#34;&gt;Derived&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;protected&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;explicit&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Derived&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(AbstractPrivate &amp;amp;dd)&lt;/span&gt; : Abstract(dd) &amp;#123;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;override&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;built_in&#34;&gt;Q_D&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; Derived); cout &amp;lt;&amp;lt; &lt;span class=&#34;string&#34;&gt;&amp;quot;foo &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; d-&amp;gt;var &amp;lt;&amp;lt; &lt;span class=&#34;string&#34;&gt;&amp;quot; &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; d-&amp;gt;bar &amp;lt;&amp;lt; endl; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;modifyVar&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;override&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;built_in&#34;&gt;Q_D&lt;/span&gt;(Derived); d-&amp;gt;var++; d-&amp;gt;bar++; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;private&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Q_DECLARE_PRIVATE&lt;/span&gt;(Derived)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;The main goal of making &lt;code&gt;DerivedPrivate&lt;/code&gt; a subclass of &lt;code&gt;AbstractPrivate&lt;/code&gt; is to avoid multiple 
d-pointers in the structure. Note that there are constructors taking a reference to the 
private data object. These are to make it possible for a &lt;code&gt;Derived&lt;/code&gt; object to use the same
d-pointer as its &lt;code&gt;Abstract&lt;/code&gt; parent. The &lt;code&gt;Q_D()&lt;/code&gt; macro is used to convert the &lt;code&gt;d_ptr&lt;/code&gt;, which is a 
pointer to &lt;code&gt;AbstractPrivate&lt;/code&gt; to another pointer, named &lt;code&gt;d&lt;/code&gt;, of some of its descendent type; 
here, it is a &lt;code&gt;DerivedPrivate&lt;/code&gt;. It is used together with the &lt;code&gt;Q_DECLARE_PRIVATE()&lt;/code&gt; macro 
in the class definition 
and has a rather complicated implementation in the Qt headers. But for simplicity, it does 
not hurt for now to understand it as the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#define Q_D(Class) Class##Private *const d = reinterpret_cast&amp;lt;Class##Private *&amp;gt;(d_ptr.data())
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;Class##Private&lt;/code&gt; means simply to append string &lt;code&gt;Private&lt;/code&gt; to (the macro argument) &lt;code&gt;Class&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Now let&amp;#39;s test it by creating a pointer to &lt;code&gt;Abstract&lt;/code&gt; and give it a &lt;code&gt;Derived&lt;/code&gt; object:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;QScopedPointer&amp;lt;Abstract&amp;gt; &lt;span class=&#34;title&#34;&gt;ins&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(&lt;span class=&#34;keyword&#34;&gt;new&lt;/span&gt; Derived())&lt;/span&gt;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;foo&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;modifyVar&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;foo&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foo 0 0
foo 1 1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Looks pretty viable -- everything&amp;#39;s working well! -- What if we use Qt&amp;#39;s implicit sharing? Just 
make &lt;code&gt;AbstractPrivate&lt;/code&gt; a subclass of &lt;code&gt;QSharedData&lt;/code&gt; and replace &lt;code&gt;QScopedPointer&lt;/code&gt; with &lt;code&gt;QSharedDataPointer&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;making-d-pointer-QSharedDataPointer&#34;&gt;&lt;a href=&#34;#making-d-pointer-QSharedDataPointer&#34; class=&#34;headerlink&#34; title=&#34;making d-pointer QSharedDataPointer&#34;&gt;&lt;/a&gt;making d-pointer &lt;code&gt;QSharedDataPointer&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;In the last section, we commented out the copy constructors since &lt;code&gt;QScopedPointer&lt;/code&gt; is not copy-constructable,
but here &lt;code&gt;QSharedDataPointer&lt;/code&gt; is copy-constructable, so we add them back:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;42&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;43&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;44&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;45&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;46&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;47&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;48&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;AbstractPrivate&lt;/span&gt; :&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt; QSharedData&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;AbstractPrivate&lt;/span&gt;() : &lt;span class=&#34;built_in&#34;&gt;var&lt;/span&gt;(&lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; ~&lt;span class=&#34;built_in&#34;&gt;AbstractPrivate&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; var;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Abstract&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&amp;#123;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Abstract&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; Abstract &amp;amp;other) = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ~&lt;span class=&#34;built_in&#34;&gt;Abstract&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;protected&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;explicit&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Abstract&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(AbstractPrivate &amp;amp;dd)&lt;/span&gt; : d_ptr(&amp;amp;dd) &amp;#123;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;/span&gt;= &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;modifyVar&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;/span&gt;= &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;protected&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    QSharedDataPointer&amp;lt;AbstractPrivate&amp;gt; d_ptr;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;private&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Q_DECLARE_PRIVATE&lt;/span&gt;(Abstract)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;DerivedPrivate&lt;/span&gt; :&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt; AbstractPrivate&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;DerivedPrivate&lt;/span&gt;() : &lt;span class=&#34;built_in&#34;&gt;AbstractPrivate&lt;/span&gt;(), &lt;span class=&#34;built_in&#34;&gt;bar&lt;/span&gt;(&lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; ~&lt;span class=&#34;built_in&#34;&gt;DerivedPrivate&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; bar;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Derived&lt;/span&gt; :&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt; Abstract&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Derived&lt;/span&gt;() : &lt;span class=&#34;built_in&#34;&gt;Abstract&lt;/span&gt;(*(&lt;span class=&#34;keyword&#34;&gt;new&lt;/span&gt; DerivedPrivate)) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Derived&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; Derived &amp;amp;other) = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ~&lt;span class=&#34;built_in&#34;&gt;Derived&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;protected&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;explicit&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Derived&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(AbstractPrivate &amp;amp;dd)&lt;/span&gt; : Abstract(dd) &amp;#123;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;override&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;built_in&#34;&gt;Q_D&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; Derived); cout &amp;lt;&amp;lt; &lt;span class=&#34;string&#34;&gt;&amp;quot;foo &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; d-&amp;gt;var &amp;lt;&amp;lt; &lt;span class=&#34;string&#34;&gt;&amp;quot; &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; d-&amp;gt;bar &amp;lt;&amp;lt; endl; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;modifyVar&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;override&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;built_in&#34;&gt;Q_D&lt;/span&gt;(Derived); d-&amp;gt;var++; d-&amp;gt;bar++; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;private&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Q_DECLARE_PRIVATE&lt;/span&gt;(Derived)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;And testing the copy-on-write mechanism:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;QScopedPointer&amp;lt;Derived&amp;gt; &lt;span class=&#34;title&#34;&gt;ins&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(&lt;span class=&#34;keyword&#34;&gt;new&lt;/span&gt; Derived())&lt;/span&gt;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;QScopedPointer&amp;lt;Derived&amp;gt; &lt;span class=&#34;title&#34;&gt;ins2&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(&lt;span class=&#34;keyword&#34;&gt;new&lt;/span&gt; Derived(*ins))&lt;/span&gt;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;foo&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;modifyVar&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;foo&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins2-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;foo&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;But, eh, it&amp;#39;s a compile-time error.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;error: reinterpret_cast from type &amp;apos;const AbstractPrivate*&amp;apos; to type &amp;apos;AbstractPrivate*&amp;apos; casts away qualifiers
 Q_DECLARE_PRIVATE(Abstract)
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;Q-D-revisited&#34;&gt;&lt;a href=&#34;#Q-D-revisited&#34; class=&#34;headerlink&#34; title=&#34;Q_D, revisited&#34;&gt;&lt;/a&gt;&lt;code&gt;Q_D&lt;/code&gt;, revisited&lt;/h3&gt;&lt;p&gt;So, where does the &lt;code&gt;const&lt;/code&gt; removal come from? In &lt;code&gt;qglobal.h&lt;/code&gt;, the code related to &lt;code&gt;Q_D&lt;/code&gt; is as follows:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;template&lt;/span&gt; &amp;lt;&lt;span class=&#34;keyword&#34;&gt;typename&lt;/span&gt; T&amp;gt; &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;inline&lt;/span&gt; T *&lt;span class=&#34;title&#34;&gt;qGetPtrHelper&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(T *ptr)&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; ptr; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;template &amp;lt;typename Ptr&amp;gt; inline auto qGetPtrHelper(const Ptr &amp;amp;ptr) -&amp;gt; decltype(ptr.operator-&amp;gt;()) &amp;#123; return ptr.operator-&amp;gt;(); &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;comment&#34;&gt;// The body must be a statement:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;meta&#34;&gt;#&lt;span class=&#34;meta-keyword&#34;&gt;define&lt;/span&gt; Q_CAST_IGNORE_ALIGN(body) QT_WARNING_PUSH QT_WARNING_DISABLE_GCC(&lt;span class=&#34;meta-string&#34;&gt;&amp;quot;-Wcast-align&amp;quot;&lt;/span&gt;) body QT_WARNING_POP&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;meta&#34;&gt;#&lt;span class=&#34;meta-keyword&#34;&gt;define&lt;/span&gt; Q_DECLARE_PRIVATE(Class) \&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    inline Class##Private* d_func() \&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &amp;#123; &lt;span class=&#34;built_in&#34;&gt;Q_CAST_IGNORE_ALIGN&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;reinterpret_cast&lt;/span&gt;&amp;lt;Class##Private *&amp;gt;(&lt;span class=&#34;built_in&#34;&gt;qGetPtrHelper&lt;/span&gt;(d_ptr));) &amp;#125; \&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    inline const Class##Private* d_func() const \&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &amp;#123; &lt;span class=&#34;built_in&#34;&gt;Q_CAST_IGNORE_ALIGN&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;reinterpret_cast&lt;/span&gt;&amp;lt;&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; Class##Private *&amp;gt;(&lt;span class=&#34;built_in&#34;&gt;qGetPtrHelper&lt;/span&gt;(d_ptr));) &amp;#125; \&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;friend&lt;/span&gt; &lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Class&lt;/span&gt;##&lt;span class=&#34;title&#34;&gt;Private&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;meta&#34;&gt;#&lt;span class=&#34;meta-keyword&#34;&gt;define&lt;/span&gt; Q_D(Class) Class##Private * const d = d_func()&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;It turns out that &lt;code&gt;Q_D&lt;/code&gt; will call &lt;code&gt;d_func()&lt;/code&gt; which then calls an overload of &lt;code&gt;qGetPtrHelper()&lt;/code&gt; 
that takes &lt;code&gt;const Ptr &amp;amp;ptr&lt;/code&gt;. What does &lt;code&gt;ptr.operator-&amp;gt;()&lt;/code&gt; return? What is the difference between 
&lt;code&gt;QScopedPointer&lt;/code&gt; and &lt;code&gt;QSharedDataPointer&lt;/code&gt; here?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://doc.qt.io/qt-5/qscopedpointer.html#operator--gt&#34;&gt;&lt;code&gt;QScopedPointer&lt;/code&gt;&lt;/a&gt;&amp;#39;s &lt;code&gt;operator-&amp;gt;()&lt;/code&gt; is a 
&lt;code&gt;const&lt;/code&gt; method that returns a non-&lt;code&gt;const&lt;/code&gt; pointer to &lt;code&gt;T&lt;/code&gt;; however, 
&lt;a href=&#34;https://doc.qt.io/qt-5/qshareddatapointer.html#operator--gt&#34;&gt;&lt;code&gt;QSharedDataPointer&lt;/code&gt;&lt;/a&gt; has two 
&lt;code&gt;operator-&amp;gt;()&lt;/code&gt;s, one being &lt;code&gt;const T* operator-&amp;gt;() const&lt;/code&gt;, the other &lt;code&gt;T* operator-&amp;gt;()&lt;/code&gt;, and they
have quite different behaviours -- the non-&lt;code&gt;const&lt;/code&gt; variant calls &lt;code&gt;detach()&lt;/code&gt; (where copy-on-write 
is implemented), but the other one does not.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;qGetPtrHelper()&lt;/code&gt; here can only take &lt;code&gt;d_ptr&lt;/code&gt; as a &lt;code&gt;const QSharedDataPointer&lt;/code&gt;, not a non-&lt;code&gt;const&lt;/code&gt; 
one; so, no matter which &lt;code&gt;d_func()&lt;/code&gt; we are calling, we can only get a &lt;code&gt;const AbstractPrivate *&lt;/code&gt;. 
That is just the problem here. &lt;/p&gt;
&lt;p&gt;To resolve this problem, let&amp;#39;s replace the &lt;code&gt;Q_D&lt;/code&gt; macros with the ones we define ourselves:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#define CONST_SHARED_D(Class) const Class##Private *const d = reinterpret_cast&amp;lt;const Class##Private *&amp;gt;(d_ptr.constData())
#define SHARED_D(Class) Class##Private *const d = reinterpret_cast&amp;lt;Class##Private *&amp;gt;(d_ptr.data())
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We will then use &lt;code&gt;SHARED_D(Class)&lt;/code&gt; in place of &lt;code&gt;Q_D(Class)&lt;/code&gt; and &lt;code&gt;CONST_SHARED_D(Class)&lt;/code&gt; for 
&lt;code&gt;Q_D(const Class)&lt;/code&gt;. Since the &lt;code&gt;const&lt;/code&gt; and non-&lt;code&gt;const&lt;/code&gt; variant really behaves differently, 
it should help to differentiate these two uses. Also, delete &lt;code&gt;Q_DECLARE_PRIVATE&lt;/code&gt; since we 
do not need them any more:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;42&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;43&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;44&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;AbstractPrivate&lt;/span&gt; :&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt; QSharedData&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;AbstractPrivate&lt;/span&gt;() : &lt;span class=&#34;built_in&#34;&gt;var&lt;/span&gt;(&lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; ~&lt;span class=&#34;built_in&#34;&gt;AbstractPrivate&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; var;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Abstract&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&amp;#123;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Abstract&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; Abstract &amp;amp;other) = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ~&lt;span class=&#34;built_in&#34;&gt;Abstract&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;protected&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;explicit&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Abstract&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(AbstractPrivate &amp;amp;dd)&lt;/span&gt; : d_ptr(&amp;amp;dd) &amp;#123;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;/span&gt;= &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;modifyVar&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;/span&gt;= &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;protected&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    QSharedDataPointer&amp;lt;AbstractPrivate&amp;gt; d_ptr;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;DerivedPrivate&lt;/span&gt; :&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt; AbstractPrivate&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;DerivedPrivate&lt;/span&gt;() : &lt;span class=&#34;built_in&#34;&gt;AbstractPrivate&lt;/span&gt;(), &lt;span class=&#34;built_in&#34;&gt;bar&lt;/span&gt;(&lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; ~&lt;span class=&#34;built_in&#34;&gt;DerivedPrivate&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; bar;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Derived&lt;/span&gt; :&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt; Abstract&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Derived&lt;/span&gt;() : &lt;span class=&#34;built_in&#34;&gt;Abstract&lt;/span&gt;(*(&lt;span class=&#34;keyword&#34;&gt;new&lt;/span&gt; DerivedPrivate)) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Derived&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; Derived &amp;amp;other) = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ~&lt;span class=&#34;built_in&#34;&gt;Derived&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;protected&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;explicit&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Derived&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;(AbstractPrivate &amp;amp;dd)&lt;/span&gt; : Abstract(dd) &amp;#123;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;override&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;built_in&#34;&gt;CONST_SHARED_D&lt;/span&gt;(Derived); cout &amp;lt;&amp;lt; &lt;span class=&#34;string&#34;&gt;&amp;quot;foo &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; d-&amp;gt;var &amp;lt;&amp;lt; &lt;span class=&#34;string&#34;&gt;&amp;quot; &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; d-&amp;gt;bar &amp;lt;&amp;lt; endl; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;modifyVar&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;override&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;built_in&#34;&gt;SHARED_D&lt;/span&gt;(Derived); d-&amp;gt;var++; d-&amp;gt;bar++; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;With the same &lt;code&gt;main()&lt;/code&gt; code, what&amp;#39;s the result?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foo 0 0
foo 1 16606417
foo 0 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;... big whoops, what is that random thing there? Well, if we use &lt;code&gt;dynamic_cast&lt;/code&gt; in place of 
&lt;code&gt;reinterpret_cast&lt;/code&gt;, the program simply crashes after &lt;code&gt;ins-&amp;gt;modifyVar();&lt;/code&gt;, indicating that 
&lt;code&gt;ins&lt;/code&gt;&amp;#39;s &lt;code&gt;d_ptr.data()&lt;/code&gt; is not at all a &lt;code&gt;DerivedPrivate&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;virtual-clones&#34;&gt;&lt;a href=&#34;#virtual-clones&#34; class=&#34;headerlink&#34; title=&#34;virtual clones&#34;&gt;&lt;/a&gt;virtual clones&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;detach()&lt;/code&gt; method of &lt;code&gt;QSharedDataPointer&lt;/code&gt; will by default create an instance of &lt;code&gt;AbstractPrivate&lt;/code&gt; 
regardless of what the instance really is. Fortunately, it is possible to change that behaviour 
through &lt;a href=&#34;https://doc.qt.io/qt-5/qshareddatapointer.html#clone&#34;&gt;specifying the &lt;code&gt;clone()&lt;/code&gt; method&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, we need to make a virtual function in &lt;code&gt;AbstractPrivate&lt;/code&gt; class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;virtual AbstractPrivate *clone() const = 0;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(make it pure virtual just to force all subclasses to re-implement it; if your base class is 
not abstract you probably want to implement the &lt;code&gt;clone()&lt;/code&gt; method) and then override it 
in &lt;code&gt;DerivedPrivate&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;virtual DerivedPrivate *clone() const &amp;#123; return new DerivedPrivate(*this); &amp;#125;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then, specify the template method for &lt;code&gt;QSharedDataPointer::clone()&lt;/code&gt;. As we will re-use it multiple
times (for different base classes), it is better to define a macro:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;meta&#34;&gt;#&lt;span class=&#34;meta-keyword&#34;&gt;define&lt;/span&gt; DATA_CLONE_VIRTUAL(Class) template&lt;span class=&#34;meta-string&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;                      \&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    Class##Private *QSharedDataPointer&amp;lt;Class##Private&amp;gt;::&lt;span class=&#34;built_in&#34;&gt;clone&lt;/span&gt;()   \&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &amp;#123;                                                             \&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; d-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;clone&lt;/span&gt;();                                        \&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;comment&#34;&gt;// after the definition of Abstract&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;built_in&#34;&gt;DATA_CLONE_VIRTUAL&lt;/span&gt;(Abstract)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;It is not necessary to write &lt;code&gt;DATA_CLONE_VIRTUAL(Derived)&lt;/code&gt; as we are never storing a 
&lt;code&gt;QSharedDataPointer&amp;lt;DerivedPrivate&amp;gt;&lt;/code&gt; throughout the heirarchy.&lt;/p&gt;
&lt;p&gt;Then test the code again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foo 0 0
foo 1 1
foo 0 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;-- Just as expected! It continues to work if we replace &lt;code&gt;Derived&lt;/code&gt; with &lt;code&gt;Abstract&lt;/code&gt; in &lt;code&gt;QScopedPointer&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;QScopedPointer&amp;lt;Abstract&amp;gt; ins(new Derived());
QScopedPointer&amp;lt;Abstract&amp;gt; ins2(new Derived(* dynamic_cast&amp;lt;const Derived *&amp;gt;(ins.data())));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well, another problem comes, that the constructor for &lt;code&gt;ins2&lt;/code&gt; seems too ugly, and messy. We could, like 
the private classes, implement a virtual function &lt;code&gt;clone()&lt;/code&gt; for these kinds of things, but it is 
still not gentle enough, and we cannot use a default copy constructor for any class that contains 
such &lt;code&gt;QScopedPointer&lt;/code&gt;s.&lt;/p&gt;
&lt;p&gt;What about &lt;code&gt;QSharedPointer&lt;/code&gt; that is copy-constructable? Well, then these copies actually point to 
the same data structures and no copy-on-write is performed at all. This still not wanted. &lt;/p&gt;
&lt;h2 id=&#34;the-Descendents-of&#34;&gt;&lt;a href=&#34;#the-Descendents-of&#34; class=&#34;headerlink&#34; title=&#34;the Descendents of ...&#34;&gt;&lt;/a&gt;the &lt;code&gt;Descendent&lt;/code&gt;s of ...&lt;/h2&gt;&lt;p&gt;Inspired by &lt;a href=&#34;https://www.youtube.com/watch?v=QGcVXgEVMJg&#34;&gt;Sean Parent&amp;#39;s video&lt;/a&gt;, 
I finally come up with the following implementation:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;38&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;template&lt;/span&gt;&amp;lt;&lt;span class=&#34;keyword&#34;&gt;typename&lt;/span&gt; T&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;Descendent&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;&amp;#123;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;concept&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;class&#34;&gt;    &amp;#123;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; ~&lt;span class=&#34;built_in&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;concept&lt;/span&gt;&lt;/span&gt;() = &lt;span class=&#34;keyword&#34;&gt;default&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; T *&lt;span class=&#34;title&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;/span&gt;= &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; T *&lt;span class=&#34;title&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;/span&gt;= &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;virtual&lt;/span&gt; unique_ptr&amp;lt;&lt;span class=&#34;keyword&#34;&gt;concept&lt;/span&gt;&amp;gt; &lt;span class=&#34;title&#34;&gt;clone&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;/span&gt;= &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;template&lt;/span&gt;&amp;lt;&lt;span class=&#34;keyword&#34;&gt;typename&lt;/span&gt; U&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;class&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;model&lt;/span&gt; :&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;concept&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;built_in&#34;&gt;model&lt;/span&gt;(U x) : &lt;span class=&#34;built_in&#34;&gt;instance&lt;/span&gt;(&lt;span class=&#34;built_in&#34;&gt;move&lt;/span&gt;(x)) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; T *&lt;span class=&#34;title&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &amp;amp;instance; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;function&#34;&gt;T *&lt;span class=&#34;title&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &amp;amp;instance; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;comment&#34;&gt;// or unique_ptr&amp;lt;model&amp;lt;U&amp;gt; &amp;gt;(new model&amp;lt;U&amp;gt;(U(instance))) if you do not have C++14&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;function&#34;&gt;unique_ptr&amp;lt;&lt;span class=&#34;keyword&#34;&gt;concept&lt;/span&gt;&amp;gt; &lt;span class=&#34;title&#34;&gt;clone&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; make_unique&amp;lt;model&amp;lt;U&amp;gt; &amp;gt;(&lt;span class=&#34;built_in&#34;&gt;U&lt;/span&gt;(instance)); &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        U instance;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    unique_ptr&amp;lt;&lt;span class=&#34;keyword&#34;&gt;concept&lt;/span&gt;&amp;gt; m_d;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;public&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;template&lt;/span&gt;&amp;lt;&lt;span class=&#34;keyword&#34;&gt;typename&lt;/span&gt; U&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Descendent&lt;/span&gt;(U x) : &lt;span class=&#34;built_in&#34;&gt;m_d&lt;/span&gt;(make_unique&amp;lt;model&amp;lt;U&amp;gt; &amp;gt;(&lt;span class=&#34;built_in&#34;&gt;move&lt;/span&gt;(x))) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Descendent&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; Descendent &amp;amp; that) : &lt;span class=&#34;built_in&#34;&gt;m_d&lt;/span&gt;(&lt;span class=&#34;built_in&#34;&gt;move&lt;/span&gt;(that.m_d-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;clone&lt;/span&gt;())) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;Descendent&lt;/span&gt;(Descendent &amp;amp;&amp;amp; that) : &lt;span class=&#34;built_in&#34;&gt;m_d&lt;/span&gt;(&lt;span class=&#34;built_in&#34;&gt;move&lt;/span&gt;(that.m_d)) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    Descendent &amp;amp; &lt;span class=&#34;keyword&#34;&gt;operator&lt;/span&gt;=(&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; Descendent &amp;amp;that) &amp;#123; Descendent &lt;span class=&#34;built_in&#34;&gt;t&lt;/span&gt;(that); *&lt;span class=&#34;keyword&#34;&gt;this&lt;/span&gt; = &lt;span class=&#34;built_in&#34;&gt;move&lt;/span&gt;(t); &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; *&lt;span class=&#34;keyword&#34;&gt;this&lt;/span&gt;; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    Descendent &amp;amp; &lt;span class=&#34;keyword&#34;&gt;operator&lt;/span&gt;=(Descendent &amp;amp;&amp;amp; that) &amp;#123; m_d = &lt;span class=&#34;built_in&#34;&gt;move&lt;/span&gt;(that.m_d); &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; *&lt;span class=&#34;keyword&#34;&gt;this&lt;/span&gt;; &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; T *&lt;span class=&#34;title&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; m_d-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;ptr&lt;/span&gt;(); &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; T *&lt;span class=&#34;title&#34;&gt;constData&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; m_d-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;ptr&lt;/span&gt;(); &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;function&#34;&gt;T *&lt;span class=&#34;title&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;/span&gt;&amp;#123; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; m_d-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;ptr&lt;/span&gt;(); &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; T *&lt;span class=&#34;keyword&#34;&gt;operator&lt;/span&gt;-&amp;gt;() &lt;span class=&#34;keyword&#34;&gt;const&lt;/span&gt; &amp;#123; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; m_d-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;ptr&lt;/span&gt;(); &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    T *&lt;span class=&#34;keyword&#34;&gt;operator&lt;/span&gt;-&amp;gt;() &amp;#123; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; m_d-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;ptr&lt;/span&gt;(); &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;This class allows you to use &lt;code&gt;Descendent&amp;lt;T&amp;gt;&lt;/code&gt; (read as &amp;quot;descendent of &lt;code&gt;T&lt;/code&gt;&amp;quot;) to represent any instance 
of any subclass of &lt;code&gt;T&lt;/code&gt;. It is copy-constructable, move-constructable, copy-assignable, and move-assignable. &lt;/p&gt;
&lt;p&gt;Test code:&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    Descendent&amp;lt;Abstract&amp;gt; ins = &lt;span class=&#34;built_in&#34;&gt;Derived&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    Descendent&amp;lt;Abstract&amp;gt; ins2 = ins;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;foo&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;modifyVar&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;foo&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    ins2-&amp;gt;&lt;span class=&#34;built_in&#34;&gt;foo&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;It gives just the same results as before, but much neater and nicer -- How does it work?&lt;/p&gt;
&lt;p&gt;First we define a class &lt;code&gt;concept&lt;/code&gt;. We put here what we want our instance to satisfy. We would like to 
access it as &lt;code&gt;const&lt;/code&gt; and non-&lt;code&gt;const&lt;/code&gt;, and to clone it as-is. Then we define a template class &lt;code&gt;model&amp;lt;U&amp;gt;&lt;/code&gt; 
where &lt;code&gt;U&lt;/code&gt; is a subclass of &lt;code&gt;T&lt;/code&gt;, and implement these functionalities.&lt;/p&gt;
&lt;p&gt;Next, we store a &lt;code&gt;unique_ptr&amp;lt;concept&amp;gt;&lt;/code&gt;. The reason for not using &lt;code&gt;QScopedPointer&lt;/code&gt; is &lt;code&gt;QScopedPointer&lt;/code&gt; is not 
movable, but movability is a feature we actually will want (in sink arguments and return values).&lt;/p&gt;
&lt;p&gt;Finally it&amp;#39;s just the constructor, moving and copying operations, and ways to access the wrapped object.&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;Descendent&amp;lt;Abstract&amp;gt; ins2 = ins;&lt;/code&gt; is called, we will go through the copy constructor of &lt;code&gt;Descendent&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Descendent(const Descendent &amp;amp; that) : m_d(move(that.m_d-&amp;gt;clone())) &amp;#123;&amp;#125;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which will then call &lt;code&gt;ins.m_d-&amp;gt;clone()&lt;/code&gt;. But remember that &lt;code&gt;ins.m_d&lt;/code&gt; actually contains a pointer to 
&lt;code&gt;model&amp;lt;Derived&amp;gt;&lt;/code&gt;, whose &lt;code&gt;clone()&lt;/code&gt; is &lt;code&gt;return make_unique&amp;lt;model&amp;lt;Derived&amp;gt; &amp;gt;(Derived(instance));&lt;/code&gt;. This expression 
will call the copy constructor of &lt;code&gt;Derived&lt;/code&gt;, then make a &lt;code&gt;unique_ptr&amp;lt;model&amp;lt;Derived&amp;gt; &amp;gt;&lt;/code&gt;, which calls the 
constructor of &lt;code&gt;model&amp;lt;Derived&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;model(Derived x) : instance(move(x)) &amp;#123;&amp;#125;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which move-constructs &lt;code&gt;instance&lt;/code&gt;. Finally the &lt;code&gt;unique_ptr&amp;lt;model&amp;lt;Derived&amp;gt; &amp;gt;&lt;/code&gt; is implicitly converted to 
&lt;code&gt;unique_ptr&amp;lt;concept&amp;gt;&lt;/code&gt;, as per the &lt;a href=&#34;https://en.cppreference.com/w/cpp/memory/unique_ptr&#34;&gt;conversion rule&lt;/a&gt;. 
&amp;quot;If &lt;code&gt;T&lt;/code&gt; is a derived class of some base &lt;code&gt;B&lt;/code&gt;, then &lt;code&gt;std::unique_ptr&amp;lt;T&amp;gt;&lt;/code&gt; is implicitly convertible to 
&lt;code&gt;std::unique_ptr&amp;lt;B&amp;gt;&lt;/code&gt;.&amp;quot;&lt;/p&gt;
&lt;p&gt;And from now on, happy hacking --- (.&amp;gt;w&amp;lt;.)&lt;/p&gt;
</content>
        <category term="kde" />
        <category term="krita" />
        <category term="c++" />
        <category term="tech" />
        <updated>2019-05-18T18:18:41.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2019/05/13/GSoC-2019/</id>
        <title>GSoC 2019</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2019/05/13/GSoC-2019/"/>
        <content type="html">&lt;p&gt;This summer will be a little bit interesting as I joined the
&lt;a href=&#34;https://summerofcode.withgoogle.com/&#34;&gt;Google Summer of Code&lt;/a&gt; (GSoC).
The software I will be working on is &lt;a href=&#34;https://krita.org/&#34;&gt;Krita&lt;/a&gt;.
Krita is a painting software I have been using for more than one year.
Since the (pre)release of Krita 4.0, I use it to &lt;a href=&#34;https://www.deviantart.com/thistusooa&#34;&gt;paint all my works&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Before using Krita, I used to use PaintToolSAI, and there are quite a lot of concepts
and functionalities in it that I find really useful; after getting involved in the
Krita community I am pretty lucky to be able to introduce these little shiny stars
to our community, and even &lt;a href=&#34;https://github.com/tusooa/krita-docker-color-slider&#34;&gt;implement some of them&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://phabricator.kde.org/T10901&#34;&gt;My project for GSoC&lt;/a&gt; is on
&lt;a href=&#34;https://invent.kde.org/kde/krita/tree/master/libs/command&#34;&gt;the undo/redo system in Krita&lt;/a&gt;. 
The system currently works using an undo stack to storage individual changes to the document,
and invoking these commands to perform undos and redos. This system is complex and not easy
to maintain. As &lt;a href=&#34;https://invent.kde.org/dkazakov&#34;&gt;Dmitry&lt;/a&gt; suggests, a better solution would
be &lt;a href=&#34;https://www.youtube.com/watch?v=QGcVXgEVMJg&#34;&gt;storing the states of the document as shallow copies&lt;/a&gt;, 
since it simplifies the system and make history brushes possible. It would be a rather huge
and fundamental change in the code, and he recommends me to experiment with vector layers first.&lt;/p&gt;
&lt;p&gt;Another part of the project, which is not a research, is the snapshot docker that would allow
users to temporarily save some states of the document and return to them quickly at a later time.
This is an enhancement on the GUI level, as the tile data in paint layers are shallow copied, making
it possible to make a clone of the document relatively fast. &lt;/p&gt;
&lt;p&gt;I will make more posts on KDE and Krita in the near future. Let&amp;#39;s keep in touch! (.w.)&lt;/p&gt;
</content>
        <category term="kde" />
        <category term="krita" />
        <updated>2019-05-13T15:16:48.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2018/04/29/short-code/</id>
        <title>短代码(一个马后炮)</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2018/04/29/short-code/"/>
        <content type="html">&lt;p&gt;没赶上报名截止日期，一直 &lt;code&gt;not invited&lt;/code&gt;。就很难过。&lt;/p&gt;
&lt;p&gt;E 的题目描述是这样的。&lt;/p&gt;
&lt;h1 id=&#34;Description&#34;&gt;&lt;a href=&#34;#Description&#34; class=&#34;headerlink&#34; title=&#34;Description&#34;&gt;&lt;/a&gt;Description&lt;/h1&gt;&lt;p&gt;tz学姐做题很忙，有一些简单的问题需要你帮忙解决：给定三个序列A,B,C和一个整数X, 现在需要找到三个数Ai，Bj，Ck，满足Ai+Bj+Ck = X.&lt;/p&gt;
&lt;h1 id=&#34;Input&#34;&gt;&lt;a href=&#34;#Input&#34; class=&#34;headerlink&#34; title=&#34;Input&#34;&gt;&lt;/a&gt;Input&lt;/h1&gt;&lt;p&gt;第1行三个整数 L, N, M；&lt;/p&gt;
&lt;p&gt;第2行L个整数代表序列A&lt;/p&gt;
&lt;p&gt;第3行M个整数代表序列B&lt;/p&gt;
&lt;p&gt;第4行N个整数代表序列C&lt;/p&gt;
&lt;p&gt;第5行1个整数S代表有S个X。&lt;/p&gt;
&lt;p&gt;接下来的S行每行一个整数X&lt;/p&gt;
&lt;p&gt;1&amp;lt;=L, N, M&amp;lt;=500, 1&amp;lt;=S&amp;lt;=1000. 所有整数均在32位整数范围内&lt;/p&gt;
&lt;h1 id=&#34;Output&#34;&gt;&lt;a href=&#34;#Output&#34; class=&#34;headerlink&#34; title=&#34;Output&#34;&gt;&lt;/a&gt;Output&lt;/h1&gt;&lt;p&gt;对于S个询问计算X对应的公式是否能被满足。 如能满足，输出 &amp;quot;YES&amp;quot;, 否则输出 &amp;quot;NO&amp;quot;。&lt;/p&gt;
&lt;h1 id=&#34;Sample-Input&#34;&gt;&lt;a href=&#34;#Sample-Input&#34; class=&#34;headerlink&#34; title=&#34;Sample Input&#34;&gt;&lt;/a&gt;Sample Input&lt;/h1&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;3 3 3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;1 2 3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;1 2 3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;1 2 3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h1 id=&#34;Sample-Output&#34;&gt;&lt;a href=&#34;#Sample-Output&#34; class=&#34;headerlink&#34; title=&#34;Sample Output&#34;&gt;&lt;/a&gt;Sample Output&lt;/h1&gt;&lt;figure class=&#34;highlight plain&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;NO&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;YES&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;NO&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h1 id=&#34;喵&#34;&gt;&lt;a href=&#34;#喵&#34; class=&#34;headerlink&#34; title=&#34;喵&#34;&gt;&lt;/a&gt;喵&lt;/h1&gt;&lt;p&gt;我当时给出的代码是这样的。&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;meta&#34;&gt;#&lt;span class=&#34;meta-keyword&#34;&gt;include&lt;/span&gt; &lt;span class=&#34;meta-string&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;meta&#34;&gt;#&lt;span class=&#34;meta-keyword&#34;&gt;include&lt;/span&gt; &lt;span class=&#34;meta-string&#34;&gt;&amp;lt;algorithm&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;namespace&lt;/span&gt; std;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; l,m,n;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  cin&amp;gt;&amp;gt;l&amp;gt;&amp;gt;m&amp;gt;&amp;gt;n;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; a[l],b[m],c[n];&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt;&amp;amp;p:a)cin&amp;gt;&amp;gt;p;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt;&amp;amp;p:b)cin&amp;gt;&amp;gt;p;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt;&amp;amp;p:c)cin&amp;gt;&amp;gt;p;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;built_in&#34;&gt;sort&lt;/span&gt;(c,c+n);&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  cin&amp;gt;&amp;gt;n;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; p;cin&amp;gt;&amp;gt;p;)&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; q:a)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;      &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; r:b)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt;(&lt;span class=&#34;built_in&#34;&gt;binary_search&lt;/span&gt;(c,c+n,p-q-r)) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;          cout&amp;lt;&amp;lt;&lt;span class=&#34;string&#34;&gt;&amp;quot;YES\n&amp;quot;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;          &lt;span class=&#34;keyword&#34;&gt;goto&lt;/span&gt; l;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    cout&amp;lt;&amp;lt;&lt;span class=&#34;string&#34;&gt;&amp;quot;NO\n&amp;quot;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  l:&lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;comment&#34;&gt;//292&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;由于我不能提交，无法判断它是否超时了。查了一下网上的做法，是把 &lt;code&gt;a&lt;/code&gt; 和 &lt;code&gt;b&lt;/code&gt; 加起来存到另一个数组里，然后对这个新的数组排序查找。&lt;/p&gt;
&lt;p&gt;仔细分析一下就是：&lt;/p&gt;
&lt;p&gt;我的方法，排序用了 &lt;code&gt;O(n*log n)&lt;/code&gt;，查找 &lt;code&gt;O(n**2*log n)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;另一个做法，排序 &lt;code&gt;O(n**2*log n)&lt;/code&gt;，查找 &lt;code&gt;O(n*log n)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;看上去好像正好抵消了没什么区别。问题在于查找是&lt;strong&gt;多次&lt;/strong&gt;查找，我们希望每次查找的时间尽量短。&lt;/p&gt;
&lt;p&gt;所以改过的代码是这样的：&lt;/p&gt;
&lt;figure class=&#34;highlight c++&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;meta&#34;&gt;#&lt;span class=&#34;meta-keyword&#34;&gt;include&lt;/span&gt; &lt;span class=&#34;meta-string&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;meta&#34;&gt;#&lt;span class=&#34;meta-keyword&#34;&gt;include&lt;/span&gt; &lt;span class=&#34;meta-string&#34;&gt;&amp;lt;algorithm&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;namespace&lt;/span&gt; std;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;function&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;title&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;params&#34;&gt;()&lt;/span&gt; &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; l,m,n,r=&lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  cin&amp;gt;&amp;gt;l&amp;gt;&amp;gt;m&amp;gt;&amp;gt;n;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; a[l],b[m],c[n],S[l*m]; &lt;span class=&#34;comment&#34;&gt;// GNU 扩展的变长数组&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt;&amp;amp;p:a)cin&amp;gt;&amp;gt;p;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;comment&#34;&gt;// range-for 输入第二组数据，同时将输入的数据和第一组的每一个数字相累加，结果存到 `S` 里。&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt;&amp;amp;p:b) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    cin&amp;gt;&amp;gt;p;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt;&amp;amp;q:a)S[r++]=p+q;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt;&amp;amp;p:c)cin&amp;gt;&amp;gt;p;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;built_in&#34;&gt;sort&lt;/span&gt;(S,S+r);&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  cin&amp;gt;&amp;gt;n; &lt;span class=&#34;comment&#34;&gt;// 丢弃个数信息，因为不需要&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; p;cin&amp;gt;&amp;gt;p;)&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt;(&lt;span class=&#34;keyword&#34;&gt;int&lt;/span&gt; q:c)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;      &lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt;(&lt;span class=&#34;built_in&#34;&gt;binary_search&lt;/span&gt;(S,S+r,p-q))&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;built_in&#34;&gt;puts&lt;/span&gt;(&lt;span class=&#34;string&#34;&gt;&amp;quot;YES&amp;quot;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;        &lt;span class=&#34;keyword&#34;&gt;goto&lt;/span&gt; l; &lt;span class=&#34;comment&#34;&gt;// 直接跳到下次输入，不输出 NO&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;      &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;    &lt;span class=&#34;built_in&#34;&gt;puts&lt;/span&gt;(&lt;span class=&#34;string&#34;&gt;&amp;quot;NO&amp;quot;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  l:&lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;  &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;comment&#34;&gt;//311&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;排名表上最短是345。&lt;/p&gt;
&lt;p&gt;但是有什么用呢。我又不能提交(以后一定要提前关注一下)。&lt;/p&gt;
</content>
        <category term="无奈" />
        <category term="坑" />
        <category term="复杂" />
        <updated>2018-04-29T10:58:57.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.tusooa.xyz/2018/01/25/dig-a-hole/</id>
        <title>开个坑。。。。</title>
        <link rel="alternate" href="https://blog.tusooa.xyz/2018/01/25/dig-a-hole/"/>
        <content type="html">&lt;p&gt;嗯大约就是这样0 0。&lt;/p&gt;
</content>
        <category term="坑" />
        <category term="帜" />
        <updated>2018-01-26T02:08:32.000Z</updated>
    </entry>
</feed>
