<?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&#39;s Blog</title>
        <link>https://rebel1725.codeberg.page/blog/en/tags/kde/</link>
        <description>Recent content in KDE on Rebel Zhang&#39;s Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-GB</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/en/tags/kde/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Finding the Implementation of a Functionality in a QtWidgets Application Using GammaRay</title>
            <link>https://rebel1725.codeberg.page/blog/en/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/en/post/find-the-implementation-of-a-function-in-a-qtwidgets-application-using-gammaray/</guid>
            <description>&lt;p&gt;To exercise Freedom 1 and Freedom 3 of free software, and/or contribute to the free software community, we need to change the source code related to a functionality to make the software do something different. However, because we are not familiar with a project, we often do not know where the source code we need to change is. You may be lucky enough to find it by trying &lt;code&gt;grep -R &amp;lt;some-user-facing-string&amp;gt; .&lt;/code&gt;; however, sometimes that will not work (see &lt;a class=&#34;link&#34; href=&#34;../the-very-beginning-of-my-journey-contributing-to-the-free-software-community-existing-projects&#34; &gt;the previous post&lt;/a&gt;). In that case, we will need some advanced software introspection tools. For software developed with Qt, a powerful utility is &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;To use GammaRay, you first need to install it. If you want to introspect software installed from your distribution&amp;rsquo;s official repository, then install GammaRay from there too:&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;If you are using &lt;code&gt;kde-builder&lt;/code&gt; to develop KDE applications, add these lines to your &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;and build it into your working directory:&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;To use GammaRay, you need to have the application you want to introspect running. Then, fire up GammaRay and choose your application in the list.&lt;/p&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s take finding the slideshow logic in Gwenview as an example. Open Gwenview and then open an image, where you will see the &lt;code&gt;Start Slideshow&lt;/code&gt; option in the menu:&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;By going through the list of widgets one by one, you will see that &lt;code&gt;0x13bda470&lt;/code&gt; is the menu we want to introspect, which contains the &lt;code&gt;Start Slideshow&lt;/code&gt; option:&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;And we will see a &lt;code&gt;toggle_slideshow&lt;/code&gt; QAction in the Connections tab:&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; will tell us where such a QAction is:&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;Open the project in your favourite IDE, for example Qt Creator, and search for the string in &lt;code&gt;app/mainwindow.cpp&lt;/code&gt;. We will find &lt;code&gt;toggle_slideshow&lt;/code&gt; here:&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;Now let us search for &lt;code&gt;toggleSlideShow&lt;/code&gt; here, which will lead us to this function:&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;Continue searching for &lt;code&gt;mSlideShow&lt;/code&gt;, and you will land here:&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;We can now see that &lt;code&gt;d-&amp;gt;mSlideShow&lt;/code&gt; is of type &lt;code&gt;SlideShow *&lt;/code&gt;. Hovering over the &lt;code&gt;SlideShow&lt;/code&gt; name with the mouse will tell us that the type is provided by &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;Now open &lt;code&gt;lib/slideshow.cpp&lt;/code&gt; and &lt;code&gt;lib/slideshow.h&lt;/code&gt;, and you are ready to go.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>My Very First Steps Contributing to the Free Software Community (Existing Projects)</title>
            <link>https://rebel1725.codeberg.page/blog/en/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/en/post/the-very-beginning-of-my-journey-contributing-to-the-free-software-community-existing-projects/</guid>
            <description>&lt;p&gt;In recent days, I have contributed far less to the free software community than I have benefited from it, and what I have contributed has been limited to &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/rebel1725/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;small, simple personal projects&lt;/a&gt; and non-code contributions (such as some translations, uploading a few screenshots to &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;, and writing posts for the &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;). Over the past year, I have learned C/C++, Qt, assembly, and some Rust, and I think it is time to do something meaningful for the free software community and the free software movement.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;DISCLAIMER: This is not a guide! I am writing this post only to share my own experience. Please refer to the relevant documentation and consult experts to learn more about how to contribute to the free software community.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-i-chose-kde&#34;&gt;Why I chose KDE&#xA;&lt;/h2&gt;&lt;p&gt;Originally, I thought about contributing to postmarketOS. However, I felt that my skills fell far short of what was needed, and I decided to begin with something relatively simple. Since I am more familiar with C++ and Qt, I chose KDE for my first contribution to the community.&lt;/p&gt;&#xA;&lt;h2 id=&#34;feelings&#34;&gt;Feelings&#xA;&lt;/h2&gt;&lt;p&gt;My ability to read source code is poor. At around the beginning of 2025, I tried to read the source code of &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;, and I felt sick and overwhelmed.&lt;/p&gt;&#xA;&lt;p&gt;However, thanks to the experience of &lt;a class=&#34;link&#34; href=&#34;../a-brief-introduction-into-reverse-engineering&#34; &gt;learning reverse engineering&lt;/a&gt;, which requires reading assembly code, my ability to read high-level language source code has also improved. Therefore, I think I should try a real free software contribution in order to practise my skills in a real-world environment.&lt;/p&gt;&#xA;&lt;p&gt;Before opening the source tree, I was somewhat nervous, and I was afraid that I would be overwhelmed by the source code, just as I had been when reading the source of PDF Arranger. Thanks to my friend &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;&amp;rsquo;s encouragement, I found the courage to take that step.&lt;/p&gt;&#xA;&lt;h2 id=&#34;tools&#34;&gt;Tools&#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;One of KDE&amp;rsquo;s recommended development environments&lt;/a&gt; is the latest version of Fedora KDE. Because I use Qubes OS, it is very easy for me to quickly set up a standalone HVM and do all my work inside it.&lt;/p&gt;&#xA;&lt;p&gt;After that, I set up &lt;code&gt;kde-builder&lt;/code&gt; according to &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;the official documentation for KDE developers&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;working&#34;&gt;Working&#xA;&lt;/h2&gt;&lt;p&gt;I scanned through the &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;bug list&lt;/a&gt; hosted by &lt;a class=&#34;link&#34; href=&#34;https://bugs.kde.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;KDE&amp;rsquo;s official Bugzilla&lt;/a&gt;. I noticed &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;a bug that seemed very easy to fix&lt;/a&gt;, but after pulling the source code and building the binary, I found that the bug was not reproducible in my environment with the latest version of Ark.&lt;/p&gt;&#xA;&lt;p&gt;Then I went back to the bug list and spotted &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;another bug&lt;/a&gt; that seemed trivial. The system environment and software version in the bug report were the same as mine (Fedora KDE, 26.04), and the bug was reproducible in the application offered by Fedora&amp;rsquo;s official repository. After confirming this, I pulled the source code and built it.&lt;/p&gt;&#xA;&lt;p&gt;I fired up GDB on the binary &lt;code&gt;~/kde/build/konsole/bin/konsole&lt;/code&gt;. After pasting the string mentioned in the bug report (&lt;code&gt;calt,liga,ss03, ss07,ss09&lt;/code&gt;) into the field, I noticed this output in the console:&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;After several chats with an LLM, I found a way to locate the line printing this alert in the source code, using a GDB Python script:&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;After a GDB session, I confirmed that the alert was raised from the file &lt;code&gt;kfontchooser.cpp&lt;/code&gt; in &lt;code&gt;kwidgetsaddons&lt;/code&gt;. I also found the function that raises the alert:&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;I noticed that the split result was trimmed:&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;but the original, untrimmed string was still used as the 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;This seems to be a mistake made by the developer. To fix the issue, we only need to change the untrimmed string to the trimmed one:&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;After that, it was time to create a branch, commit the change to that branch, and submit a merge request. However, due to my limited experience with Git, I ran into a problem:&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;In the end, I submitted the change through the browser, since it was only a trivial change to a single file.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&#xA;&lt;/h2&gt;&lt;p&gt;Today, I made my very first contribution to the free software community, and I also became a brand-new free software contributor. In the future, I hope to contribute more and more, sharpen my skills, and become more beneficial to the community and the free software movement.&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
