<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>KDE on Rebel Zhang 的博客</title>
        <link>https://rebel1725.codeberg.page/blog/zh/tags/kde/</link>
        <description>Recent content in KDE on Rebel Zhang 的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-CN</language>
        <managingEditor>rebel1725@tilde.club (Rebel Zhang)</managingEditor>
        <webMaster>rebel1725@tilde.club (Rebel Zhang)</webMaster>
        <lastBuildDate>Sun, 09 Aug 2026 20:49:33 +0800</lastBuildDate><atom:link href="https://rebel1725.codeberg.page/blog/zh/tags/kde/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>使用 GammaRay 在 QtWidgets 应用程序中找到某个功能的实现</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/find-the-implementation-of-a-function-in-a-qtwidgets-application-using-gammaray/</link>
            <pubDate>Sun, 09 Aug 2026 20:49:33 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/find-the-implementation-of-a-function-in-a-qtwidgets-application-using-gammaray/</guid>
            <description>&lt;p&gt;为了实践自由软件的自由 1 和自由 3，和/或为自由软件社区做出贡献，我们需要修改与某个功能相关的源代码，让软件做出不同的事情。然而，由于我们对某个项目并不熟悉，我们常常不知道需要修改的源代码在哪里。你可以试着运行 &lt;code&gt;grep -R &amp;lt;some-user-facing-string&amp;gt; .&lt;/code&gt;，不过有时这并不会奏效（见&lt;a class=&#34;link&#34; href=&#34;../the-very-beginning-of-my-journey-contributing-to-the-free-software-community-existing-projects&#34; &gt;上一篇文章&lt;/a&gt;）。在那种情况下，我们就需要一些高级的软件内省工具。对于使用 Qt 开发的软件，一个强大的工具是 &lt;a class=&#34;link&#34; href=&#34;https://www.kdab.com/software-technologies/developer-tools/gammaray/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;GammaRay&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;p&gt;要使用 GammaRay，你首先需要安装它。如果你想检查从发行版官方软件仓库安装的软件，那么也请从那里安装 GammaRay：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# apt install gammaray&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果你使用 &lt;code&gt;kde-builder&lt;/code&gt; 开发 KDE 应用程序，请将以下几行添加到你的 &lt;code&gt;~/.config/kde-builder.yaml&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;project gammaray:&#xA;  repository: https://github.com/KDAB/GammaRay.git&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后把它构建到你的工作目录中：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ kde-builder gammaray&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;要使用 GammaRay，你需要先让你想检查的应用程序运行起来。然后启动 GammaRay，并在列表中选择你的应用程序。&lt;/p&gt;&#xA;&lt;p&gt;我们以在 Gwenview 中查找幻灯片逻辑为例。打开 Gwenview，然后打开一张图片，你会在菜单中看到 &lt;code&gt;Start Slideshow&lt;/code&gt; 选项：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;a screenshot of Gwenview&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;390px&#34; data-flex-grow=&#34;162&#34; height=&#34;952&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://rebel1725.codeberg.page/images/pic_20260809_001.png&#34; srcset=&#34;https://rebel1725.codeberg.page/blog/pic_20260809_001_9260183633641420788_hu_365916c355e33157.png 800w, https://rebel1725.codeberg.page/images/pic_20260809_001.png 1548w&#34; width=&#34;1548&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;逐个浏览 Widgets 列表后，你会发现 &lt;code&gt;0x13bda470&lt;/code&gt; 就是我们想要检查的菜单，其中包含 &lt;code&gt;Start Slideshow&lt;/code&gt; 选项：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;GammaRay QtWidgets introspection&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;402px&#34; data-flex-grow=&#34;167&#34; height=&#34;1002&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://rebel1725.codeberg.page/images/pic_20260809_002.png&#34; srcset=&#34;https://rebel1725.codeberg.page/blog/pic_20260809_002_4293608996693979957_hu_43bd5ee0e43f111b.png 800w, https://rebel1725.codeberg.page/blog/pic_20260809_002_4293608996693979957_hu_c573a96130bd048e.png 1600w, https://rebel1725.codeberg.page/images/pic_20260809_002.png 1681w&#34; width=&#34;1681&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;而且我们会在 Connections 标签页中看到一个 &lt;code&gt;toggle_slideshow&lt;/code&gt; QAction：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;Connections&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;304px&#34; data-flex-grow=&#34;126&#34; height=&#34;604&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://rebel1725.codeberg.page/images/pic_20260809_003.png&#34; width=&#34;767&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;grep&lt;/code&gt; 会告诉我们这样的 QAction 位于哪里：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;~/kde/src/gwenview$ grep -R toggle_slideshow&#xA;app/fullscreencontent.cpp:    addAction(QStringLiteral(&amp;#34;toggle_slideshow&amp;#34;));&#xA;app/gwenviewui.rc:        &amp;lt;Action name=&amp;#34;toggle_slideshow&amp;#34; /&amp;gt;&#xA;app/mainwindow.cpp:        mToggleSlideShowAction = view-&amp;gt;addAction(QStringLiteral(&amp;#34;toggle_slideshow&amp;#34;), q, &amp;amp;MainWindow::toggleSlideShow);&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在你常用的 IDE 中打开该项目，例如 Qt Creator，然后在 &lt;code&gt;app/mainwindow.cpp&lt;/code&gt; 中搜索这个字符串。我们会在这里找到 &lt;code&gt;toggle_slideshow&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;        mToggleSlideShowAction = view-&amp;gt;addAction(QStringLiteral(&amp;#34;toggle_slideshow&amp;#34;), q, &amp;amp;MainWindow::toggleSlideShow);&#xA;        q-&amp;gt;updateSlideShowAction();&#xA;        connect(mSlideShow, &amp;amp;SlideShow::stateChanged, q, &amp;amp;MainWindow::updateSlideShowAction);&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在再搜索 &lt;code&gt;toggleSlideShow&lt;/code&gt;，它会带我们找到这个函数：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;void MainWindow::toggleSlideShow()&#xA;{&#xA;    if (d-&amp;gt;mSlideShow-&amp;gt;isRunning()) {&#xA;        d-&amp;gt;mSlideShow-&amp;gt;pause();&#xA;    } else {&#xA;        if (!d-&amp;gt;mViewAction-&amp;gt;isChecked()) {&#xA;            d-&amp;gt;mViewAction-&amp;gt;trigger();&#xA;        }&#xA;        if (!d-&amp;gt;mFullScreenAction-&amp;gt;isChecked()) {&#xA;            d-&amp;gt;mFullScreenAction-&amp;gt;trigger();&#xA;        }&#xA;        QList&amp;lt;QUrl&amp;gt; list;&#xA;        for (int pos = 0; pos &amp;lt; d-&amp;gt;mDirModel-&amp;gt;rowCount(); ++pos) {&#xA;            QModelIndex index = d-&amp;gt;mDirModel-&amp;gt;index(pos, 0);&#xA;            KFileItem item = d-&amp;gt;mDirModel-&amp;gt;itemForIndex(index);&#xA;            MimeTypeUtils::Kind kind = MimeTypeUtils::fileItemKind(item);&#xA;            switch (kind) {&#xA;            case MimeTypeUtils::KIND_SVG_IMAGE:&#xA;            case MimeTypeUtils::KIND_RASTER_IMAGE:&#xA;            case MimeTypeUtils::KIND_VIDEO:&#xA;                list &amp;lt;&amp;lt; item.url();&#xA;                break;&#xA;            default:&#xA;                break;&#xA;            }&#xA;        }&#xA;        d-&amp;gt;mSlideShow-&amp;gt;start(list);&#xA;    }&#xA;    updateSlideShowAction();&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;继续搜索 &lt;code&gt;mSlideShow&lt;/code&gt;，你会找到这里：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;struct MainWindow::Private {&#xA;    ...&#xA;    SlideShow *mSlideShow = nullptr;&#xA;    ...&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在我们知道 &lt;code&gt;d-&amp;gt;mSlideShow&lt;/code&gt; 的类型是 &lt;code&gt;SlideShow *&lt;/code&gt;。把鼠标悬停在 &lt;code&gt;SlideShow&lt;/code&gt; 这个字符串上，会告诉我们它的类型来自 &lt;code&gt;lib/slideshow.h&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;Qt Creator&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;271px&#34; data-flex-grow=&#34;112&#34; height=&#34;363&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://rebel1725.codeberg.page/images/pic_20260809_004.png&#34; width=&#34;410&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;现在打开 &lt;code&gt;lib/slideshow.cpp&lt;/code&gt; 和 &lt;code&gt;lib/slideshow.h&lt;/code&gt;，你就可以继续往下找了。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>我为自由软件社区贡献的最初几步（现有项目）</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/the-very-beginning-of-my-journey-contributing-to-the-free-software-community-existing-projects/</link>
            <pubDate>Sun, 02 Aug 2026 23:18:30 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/the-very-beginning-of-my-journey-contributing-to-the-free-software-community-existing-projects/</guid>
            <description>&lt;p&gt;近些天来，我对自由软件社区的贡献远远少于我从中受益的程度，而我所做出的贡献也仅限于&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/rebel1725/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;一些小而简单的个人项目&lt;/a&gt;以及非代码类贡献（例如一些翻译、向 &lt;a class=&#34;link&#34; href=&#34;https://screenshots.debian.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Debian Screenshots&lt;/a&gt; 上传几张截图，以及为 &lt;a class=&#34;link&#34; href=&#34;https://freeswzhcn.codeberg.page/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Free Software Chinese Site&lt;/a&gt; 撰写文章）。在过去的一年里，我学习了 C/C++、Qt、汇编，以及一些 Rust。我认为，现在是时候为自由软件社区和自由软件运动做一些有意义的事情了。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;免责声明：这不是一篇指南！我撰写这篇文章，只是为了分享我自己的经历。请参考相关文档，并向专家请教，以进一步了解如何为自由软件社区做出贡献。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;我为什么选择-kde&#34;&gt;我为什么选择 KDE&#xA;&lt;/h2&gt;&lt;p&gt;最初，我曾考虑为 postmarketOS 贡献。不过，我觉得自己的技能距离所需水平还差得很远，于是决定先从相对简单的事情开始。由于我对 C++ 和 Qt 更熟悉，所以我选择 KDE 作为我对社区的第一次贡献。&lt;/p&gt;&#xA;&lt;h2 id=&#34;感受&#34;&gt;感受&#xA;&lt;/h2&gt;&lt;p&gt;我阅读源代码的能力并不强。大约在 2025 年初，我尝试阅读 &lt;a class=&#34;link&#34; href=&#34;https://github.com/pdfarranger/pdfarranger&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;PDF Arranger&lt;/a&gt; 的源代码，当时我感到非常难受，也有些不知所措。&lt;/p&gt;&#xA;&lt;p&gt;不过，得益于&lt;a class=&#34;link&#34; href=&#34;../a-brief-introduction-into-reverse-engineering&#34; &gt;学习逆向工程&lt;/a&gt;的经历，而这恰好需要阅读汇编代码，我阅读高级语言源代码的能力也有所提升。因此，我认为自己应该尝试一次真正的自由软件贡献，在真实环境中练习自己的技能。&lt;/p&gt;&#xA;&lt;p&gt;在打开源码树之前，我有些紧张，担心自己会像读 PDF Arranger 的源代码时那样，被庞大的代码淹没。多亏了朋友 &lt;a class=&#34;link&#34; href=&#34;https://blog.i7arch.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Integral&lt;/a&gt; 的鼓励，我才鼓起勇气迈出那一步。&lt;/p&gt;&#xA;&lt;h2 id=&#34;工具&#34;&gt;工具&#xA;&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://develop.kde.org/docs/getting-started/building/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;KDE 推荐的开发环境之一&lt;/a&gt;是最新版的 Fedora KDE。由于我使用的是 Qubes OS，所以我可以很方便地快速搭建一个独立的 HVM，并在其中完成所有工作。&lt;/p&gt;&#xA;&lt;p&gt;随后，我按照 &lt;a class=&#34;link&#34; href=&#34;https://develop.kde.org/docs/getting-started/building/kde-builder-setup/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;KDE 开发者的官方文档&lt;/a&gt; 配置了 &lt;code&gt;kde-builder&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;工作过程&#34;&gt;工作过程&#xA;&lt;/h2&gt;&lt;p&gt;我浏览了 &lt;a class=&#34;link&#34; href=&#34;https://bugs.kde.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;KDE 官方 Bugzilla&lt;/a&gt; 上托管的&lt;a class=&#34;link&#34; href=&#34;https://bugs.kde.org/buglist.cgi?chfield=%5BBug%20creation%5D&amp;amp;chfieldfrom=7d&amp;amp;f1=product&amp;amp;o1=notequals&amp;amp;v1=Spam&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;漏洞列表&lt;/a&gt;。我注意到&lt;a class=&#34;link&#34; href=&#34;https://bugs.kde.org/show_bug.cgi?id=523617&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;一个看起来非常容易修复的漏洞&lt;/a&gt;，但在拉取源代码并构建二进制文件之后，我发现这个漏洞在我当前环境下，使用最新版本的 Ark 无法复现。&lt;/p&gt;&#xA;&lt;p&gt;随后我又回到漏洞列表，发现了&lt;a class=&#34;link&#34; href=&#34;https://bugs.kde.org/show_bug.cgi?id=523757&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;另一个看起来很简单的漏洞&lt;/a&gt;。该漏洞报告中的系统环境和软件版本与我的相同（Fedora KDE，26.04），而且在 Fedora 官方仓库提供的应用程序中可以复现。确认这一点之后，我拉取了源代码并进行了构建。&lt;/p&gt;&#xA;&lt;p&gt;我在二进制文件 &lt;code&gt;~/kde/build/konsole/bin/konsole&lt;/code&gt; 上启动了 GDB。把漏洞报告中提到的字符串（&lt;code&gt;calt,liga,ss03, ss07,ss09&lt;/code&gt;）粘贴到输入框后，我在终端里看到了如下输出：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;The tag name must be exactly 4 characters long!&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在与一个 LLM 进行了几轮交流之后，我找到了一种用 GDB Python 脚本定位源码中打印这条提示的代码行的方法：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;python&#xA;import gdb&#xA;&#xA;TARGET = b&amp;#34;The tag name must be exactly 4 characters long!&amp;#34;&#xA;&#xA;class FilteredWrite(gdb.Breakpoint):&#xA;    def stop(self):&#xA;        fd = int(gdb.parse_and_eval(&amp;#34;$rdi&amp;#34;))&#xA;        if fd not in (1, 2):&#xA;            return False&#xA;&#xA;        buf = int(gdb.parse_and_eval(&amp;#34;$rsi&amp;#34;))&#xA;        count = int(gdb.parse_and_eval(&amp;#34;$rdx&amp;#34;))&#xA;&#xA;        try:&#xA;            data = gdb.selected_inferior().read_memory(buf, count).tobytes()&#xA;        except gdb.MemoryError:&#xA;            return False&#xA;&#xA;        if TARGET in data:&#xA;            gdb.write(&amp;#34;\n=== matched output ===\n&amp;#34;)&#xA;            gdb.write(data.decode(&amp;#34;utf-8&amp;#34;, &amp;#34;replace&amp;#34;) + &amp;#34;\n&amp;#34;)&#xA;            gdb.execute(&amp;#34;bt full&amp;#34;)&#xA;            return True&#xA;&#xA;        return False&#xA;&#xA;FilteredWrite(&amp;#34;write&amp;#34;)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在一次 GDB 调试会话之后，我确认了这条警告是由 &lt;code&gt;kwidgetsaddons&lt;/code&gt; 中的 &lt;code&gt;kfontchooser.cpp&lt;/code&gt; 文件触发的。我还找到了触发这条警告的函数：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;void KFontChooserPrivate::slotFeaturesChanged(const QString &amp;amp;features)&#xA;{&#xA;    m_selectedFont.clearFeatures();&#xA;&#xA;    if (features.isEmpty()) {&#xA;        return;&#xA;    }&#xA;&#xA;    const QStringList rawFeaturesList = features.split(QLatin1Char(&amp;#39;,&amp;#39;), Qt::SkipEmptyParts);&#xA;    for (const QString &amp;amp;feature : rawFeaturesList) {&#xA;        auto f = QStringView(feature).trimmed();&#xA;        if (f.isEmpty()) {&#xA;            continue;&#xA;        }&#xA;        QList&amp;lt;QStringView&amp;gt; parts = f.split(QStringLiteral(&amp;#34;=&amp;#34;), Qt::SkipEmptyParts);&#xA;        if (parts.length() == 2) {&#xA;            const auto tag = QFont::Tag::fromString(parts[0]);&#xA;            bool ok = false;&#xA;            const int number = parts[1].toInt(&amp;amp;ok);&#xA;            if (tag.has_value() &amp;amp;&amp;amp; ok) {&#xA;                m_selectedFont.setFeature(tag.value(), number);&#xA;            }&#xA;        } else if (f.size() &amp;lt;= 4) {&#xA;            const auto tag = QFont::Tag::fromString(feature);&#xA;            if (tag.has_value()) {&#xA;                m_selectedFont.setFeature(tag.value(), 1);&#xA;            }&#xA;        }&#xA;    }&#xA;&#xA;    Q_EMIT q-&amp;gt;fontSelected(m_selectedFont);&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我注意到，拆分后的结果已经被去掉了首尾空白：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;auto f = QStringView(feature).trimmed();&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;但原始、未去空白的字符串却仍然被用作 tag：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;const auto tag = QFont::Tag::fromString(feature);&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这看起来是开发者写错了。要修复这个问题，我们只需要把未去空白的字符串改成去空白后的字符串：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;const auto tag = QFont::Tag::fromString(f);&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;接下来，就该创建一个分支，把改动提交到该分支，并提交合并请求了。不过，由于我对 Git 的经验有限，我遇到了一个问题：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;warning: redirecting to https://invent.kde.org/rebellfs/kwidgetsaddons.git/&#xA;Enumerating objects: 21973, done.&#xA;Counting objects: 100% (21973/21973), done.&#xA;Delta compression using up to 4 threads&#xA;Compressing objects: 100% (2790/2790), done.&#xA;Writing objects: 100% (21973/21973), 41.17 MiB | ... KiB/s, done.&#xA;Total 21973 (delta 13428), reused 21374 (delta 12884), pack-reused 0 (from 0)&#xA;remote: Resolving deltas: 100% (13428/13428), done.&#xA;remote: Audit failure - Commit 046e4bb16e60b66070ee4a00c368ca6924db3a08 - Email address has an invalid domain : [kde@randomguy3.me.uk](mailto:kde@randomguy3.me.uk)&#xA;remote: Audit failure - Commit 046e4bb16e60b66070ee4a00c368ca6924db3a08 - Email address has an invalid domain : [kde@randomguy3.me.uk](mailto:kde@randomguy3.me.uk)&#xA;remote: Audit failure - Commit c8c7ab3d0e7ca825bbb01d58de005d4d589b12cc - Email address has an invalid domain : [kde@randomguy3.me.uk](mailto:kde@randomguy3.me.uk)&#xA;remote: Audit failure - Commit c8c7ab3d0e7ca825bbb01d58de005d4d589b12cc - Email address has an invalid domain : [kde@randomguy3.me.uk](mailto:kde@randomguy3.me.uk)&#xA;remote: Audit failure - Commit 62e5736a1f4afc2d24ef2c4d643a98bc60e6d6cd - Email address has an invalid domain : [kde@randomguy3.me.uk](mailto:kde@randomguy3.me.uk)&#xA;remote: Audit failure - Commit 62e5736a1f4afc2d24ef2c4d643a98bc60e6d6cd - Email address has an invalid domain : [kde@randomguy3.me.uk](mailto:kde@randomguy3.me.uk)&#xA;remote: Audit failure - Commit f317243c63620acec15a46c412502e73b9a04e2a - Email address has an invalid domain : [kde@randomguy3.me.uk](mailto:kde@randomguy3.me.uk)&#xA;remote: Audit failure - Commit f317243c63620acec15a46c412502e73b9a04e2a - Email address has an invalid domain : [kde@randomguy3.me.uk](mailto:kde@randomguy3.me.uk)&#xA;remote: Push declined - commits failed audit&#xA;remote: Should the audit failures above mention issues regarding your name, please ensure that your Git username has been set to your full name.&#xA;remote: Please see https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup for more details on ensuring Git has been fully configured.&#xA;remote: In the event that your full name has been set and is shown above as being rejected, please file a Sysadmin ticket at https://go.kde.org/systickets&#xA;To https://invent.kde.org/rebellfs/kwidgetsaddons&#xA;! [remote rejected]     work/rebel1725/fix523757 -&amp;gt; work/rebel1725/fix523757 (pre-receive hook declined)&#xA;error: failed to push some refs to &amp;#39;https://invent.kde.org/rebellfs/kwidgetsaddons&amp;#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;最后，因为这只是对单个文件的一个小改动，我还是通过浏览器提交了这项修改。&lt;/p&gt;&#xA;&lt;h2 id=&#34;结论&#34;&gt;结论&#xA;&lt;/h2&gt;&lt;p&gt;今天，我完成了自己对自由软件社区的第一次贡献，也成为了一名全新的自由软件贡献者。今后，我希望能够贡献更多，不断磨练自己的技能，并且对社区和自由软件运动变得更加有帮助。&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
