<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Cassidy James Blaede</title>
    <description>Building useful, usable, delightful products that respect privacy.</description>
    <link>https://cassidyjames.com/</link>
    <atom:link href="https://cassidyjames.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 26 Feb 2024 23:05:56 +0000</pubDate>
    <lastBuildDate>Mon, 26 Feb 2024 23:05:56 +0000</lastBuildDate>
    <generator>Jekyll v3.9.5</generator>
    
      
        <item>
          <title>How and Why to Get Verified on Mastodon</title>

          <description>
            
              
              
              
              
                &lt;img src=&quot;https://cassidyjames.com/images/blog/mastodon-verification/verified.png&quot; /&gt;
              
            

            &lt;p&gt;I run a little family Mastodon server so that I can have &lt;a href=&quot;https://mastodon.blaede.family/@cassidy&quot;&gt;@cassidy@blaede.family&lt;/a&gt; and feel comfortable sharing random photos of my kids with people while remaining in control of how they’re shared. Part of running a Mastodon server is that the admin can curate what hashtags, posts, and links are allowed to trend; e.g. if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#furryNSFW&lt;/code&gt; is popular across your server’s corner of the Internet, you &lt;em&gt;might&lt;/em&gt; not want that to be recommended to your mom on the trending page (true story!). So admins can explicitly allow or disallow each trend before it’s shown to their users. Once a trend is allowed, it will be able to trend again at any point in the future, cutting down on work for seasonal or naturally recurring trends (like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#SilentSunday&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#SuperbOwl&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;This also works for individual links and posts, but a more powerful feature is that &lt;strong&gt;admins can explicitly allow (or disallow) certain &lt;em&gt;accounts&lt;/em&gt; or &lt;em&gt;publishers&lt;/em&gt; to trend&lt;/strong&gt;. This can greatly cut down on moderation work, as admins can allow-list reputable news sites or people they know are generally good people who stick to the rules and are unlikely to post something they don’t want trending; I personally use this for virtually anyone I actually know in real life or from various open source projects. However, I’ve started becoming a bit more lenient than that, as for my small instance there’s a pretty low risk of abuse: &lt;strong&gt;I allow-list anyone with a verified account that looks decent at a glance.&lt;/strong&gt; I check in on the trends regularly and can always revoke that, but if someone has proven they are who they say they are and aren’t regularly posting things I wouldn’t want to trend, I don’t want to have to go approve every post that might trend!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/mastodon-verification/verified.png&quot; alt=&quot;Example of verified accounts on Mastodon&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So my call to anyone and everyone on Mastodon—but especially journalists and well-known personalities—is: &lt;strong&gt;get verified!&lt;/strong&gt; It greatly helps people like me and mods of larger servers know you’re you, and makes it more likely that people will find you in search, follow you, and see you on trending page in their Mastodon app or server.&lt;/p&gt;

&lt;h3 id=&quot;okay-but-how&quot;&gt;Okay, but how?&lt;/h3&gt;

&lt;p&gt;If you’re coming from X (the social network formerly known as Twitter and still available at twitter.com) or a Meta network like Instagram, you might think being verified is some process requiring payment, government ID verification, bribery, etc. With Mastodon, that’s not so! Verification is built on web standards and proves one thing: your account is associated with a specific page on the Internet. That might seem like less of a guarantee (it doesn’t explicitly prove your real &lt;em&gt;human identity&lt;/em&gt;), it’s powerful. Here are some recommended ways to use verification to prove you’re, well, &lt;em&gt;you:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Personal website&lt;/strong&gt;: this is the most flexible and in your control; if you have a website where you direct people, use that for verification! It proves that your Mastodon account belongs to the same person as the website.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;GitHub account&lt;/strong&gt;: GitHub supports Mastodon links on profiles and will add the right markup to support verification. For open source people, this is a great way to associate your work with your social media presence.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Organization about page&lt;/strong&gt;: if you work for an organization like a news site, see if you can add a link to your Mastodon account on your profile page there. This associates your work at that organization with your Mastodon account and proves your authority when talking about your work.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another neat thing: you can verify multiple links! So I have cassidyjames.com, blaede.family, and my GitHub account all verified on my profile. The first link is what will show in some contexts like search results, so put the most well-known associated link first.&lt;/p&gt;

&lt;h3 id=&quot;technical-details&quot;&gt;Technical details&lt;/h3&gt;

&lt;p&gt;If you’re manually adding a link on your own site (or talking to a web developer to get support added to your organization’s site), here’s what you need to know:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The page needs to link back to your public profile, either with an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;a&amp;gt;&lt;/code&gt; on the page or a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;link&amp;gt;&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;head&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;The link needs to include &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rel=&quot;me&quot;&lt;/code&gt; to distinguish it from just linking to someone else’s account&lt;/li&gt;
  &lt;li&gt;The page needs to be secure (served over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;There’s a 1 MB page limit; if your page is too heavy, it won’t work&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;read-more&quot;&gt;Read more&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://washpost.engineering/heres-how-the-washington-post-verified-its-journalists-on-mastodon-7b5dbc96985c&quot;&gt;Here’s how The Washington Post verified its journalists on Mastodon&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://themarkup.org/levelup/2022/12/22/how-we-verified-ourselves-on-mastodon-and-how-you-can-too&quot;&gt;The Markup: How We Verified Ourselves on Mastodon — and How You Can Too&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://joinmastodon.org/verification&quot;&gt;Very high level information from JoinMastodon.org&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.joinmastodon.org/user/profile/#verification&quot;&gt;Slightly more technical information from the Mastodon documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://mastodon-link-debugger.vercel.app/&quot;&gt;Mastodon Link Debugger&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

          </description>

          <pubDate>Wed, 11 Oct 2023 00:00:00 +0000</pubDate>
          <link>https://cassidyjames.com/blog/mastodon-verification/</link>
          <guid isPermaLink="true">https://cassidyjames.com/blog/mastodon-verification/</guid>

          
            
            
            <enclosure url="https://cassidyjames.com/images/blog/mastodon-verification/verified.png" type="image/png" />
          

          

          
        </item>
      
    
      
        <item>
          <title>Use Commit from Flatpak Both Inside and Outside of Toolbx</title>

          <description>
            

            &lt;p&gt;This one’s gonna be a short one, and is mostly for my own notes. :)&lt;/p&gt;

&lt;p&gt;I like to use the &lt;a href=&quot;https://flathub.org/apps/re.sonny.Commit&quot;&gt;Commit&lt;/a&gt; app as a visual editor when committing changes to a git repo; it’s a simple dialog that gives some niceties over using the CLI, like spell check, a visual indication of line length, graying out comments, etc. It’s nice!&lt;/p&gt;

&lt;p&gt;Here are the instructions provided by Commit to edit your git config:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git config &lt;span class=&quot;nt&quot;&gt;--global&lt;/span&gt; core.editor &lt;span class=&quot;s2&quot;&gt;&quot;flatpak run re.sonny.Commit&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since I’m often in a &lt;a href=&quot;https://containertoolbx.org/&quot;&gt;toolbx&lt;/a&gt; container when developing, &lt;del&gt;I can’t directly access my host’s Flatpaks (which makes sense!), and thus the provided instructions don’t work in this context&lt;/del&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;update-just-install-flatpak-in-the-toolbx-container&quot;&gt;Update: Just Install Flatpak in the Toolbx Container!&lt;/h3&gt;

&lt;p&gt;Thanks to Felipe and Sebastian in the comments, I learned Flatpak inside a toolbx container is actually smart, and will launch host Flatpaks on the host! So all you actually need to do is:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dnf &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;flatpak
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;…or your toolbx container distro’s equivalent, then the instructions provided by Commit should Just Work™️.&lt;/p&gt;

&lt;p&gt;If you get an error about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unpacking rpm package flatpak&lt;/code&gt;, you may be on an older version of toolbx and need to work around a bug; just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo umount /var/lib/flatpak&lt;/code&gt;, then install Flatpak, then restart your container &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit&lt;/code&gt; it, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;podman stop fedora-toolbox-39&lt;/code&gt; (or your container name), then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toolbox enter fedora-toolbox-39&lt;/code&gt; (or your container name) again.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;edit-the-git-config-outdated&quot;&gt;Edit the Git Config (Outdated!)&lt;/h3&gt;

&lt;aside class=&quot;card&quot;&gt;
  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The above update should be all you need; the previous contents of this post are included here for posterity and to show the learning process, in case that’s still useful to anyone.&lt;/p&gt;
&lt;/aside&gt;

&lt;p&gt;I &lt;em&gt;could&lt;/em&gt; modify my git config to work in the container by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flatpak-spawn&lt;/code&gt; (which, despite its name, you can use to spawn things outside of toolbx containers as well as outside of flatpaks), but then it won’t work on the host, which I also need! So I have to dynamically handle both cases…&lt;/p&gt;

&lt;p&gt;After a bit of trial and error, I came up with this kludge:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git config &lt;span class=&quot;nt&quot;&gt;--global&lt;/span&gt; core.editor &lt;span class=&quot;s1&quot;&gt;'if [ -f /run/.toolboxenv ]; then prefix=&quot;flatpak-spawn --host&quot;; fi &amp;amp;&amp;amp; $prefix flatpak run re.sonny.Commit'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If all you wanted was for this to work for you, copy the above and you’re done. :)&lt;/p&gt;

&lt;h4 id=&quot;how-it-works&quot;&gt;How it works&lt;/h4&gt;

&lt;p&gt;Let’s step through it to better understand what’s going on. I’m going to break it into lines to make it easier to read; I know this can’t be parsed as-is by bash, but just bear with the visual:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git config &lt;span class=&quot;nt&quot;&gt;--global&lt;/span&gt; core.editor &lt;span class=&quot;s1&quot;&gt;'
  if [ -f /run/.toolboxenv ]; then 
    prefix=&quot;
      flatpak-spawn --host
    &quot;;
  fi 
  &amp;amp;&amp;amp; 
  $prefix flatpak run re.sonny.Commit
'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So the outer-most part is that we’re setting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;core.editor&lt;/code&gt; variable globally with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git config&lt;/code&gt;, just as Commit’s original instructions say. We’re using single-quotes (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;'&lt;/code&gt;) here because we don’t want our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$prefix&lt;/code&gt; to be interpreted as string replacement &lt;em&gt;at the time we set the variable&lt;/em&gt;, which double-quotes (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;&lt;/code&gt;) would do; we just want to include that in the literal string (to be replaced when git runs it).&lt;/p&gt;

&lt;p&gt;Next we have an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; to check if the file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/run/.toolboxenv&lt;/code&gt; exists; this exists in all toolbx containers, so it’s an easy way to know if we’re running in toolbx.&lt;/p&gt;

&lt;p&gt;If we’re in toolbx, we set a new variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prefix&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flatpak-spawn --host&lt;/code&gt; since we need to run the actual editor on the host, not in our container. We use double-quotes (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;&lt;/code&gt;) here since we’re inside of the single-quoted (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;'&lt;/code&gt;) string.&lt;/p&gt;

&lt;p&gt;After we successfully do the toolbx check and optionally set the prefix, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; will tell the shell that’s calling the commit program to execute the next bit.&lt;/p&gt;

&lt;p&gt;We include the actual original &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flatpak run re.sonny.Commit&lt;/code&gt;, this time prefixed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$prefix&lt;/code&gt;, which will either be string-replaced by a harmless empty string, or by our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flatpak-spawn --host&lt;/code&gt; if we’re in a toolbx container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We have to leave the command for the end of our kludged string because git will append the temporary filename&lt;/strong&gt; of the commit message to the end of the whole &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;core.editor&lt;/code&gt; string; if we included &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flatpak-span --host flatpak run re.sonny.Commit&lt;/code&gt; inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; statement, it would never get the name of the file to edit, and wouldn’t work (ask me how I know…).&lt;/p&gt;

&lt;p&gt;So there we are. It’s &lt;em&gt;super&lt;/em&gt; ugly, but hey, it works. How would you solve this in a better way? Let me know on social media. :)&lt;/p&gt;


          </description>

          <pubDate>Mon, 09 Oct 2023 00:00:00 +0000</pubDate>
          <link>https://cassidyjames.com/blog/use-commit-flatpak-inside-outside-toolbx/</link>
          <guid isPermaLink="true">https://cassidyjames.com/blog/use-commit-flatpak-inside-outside-toolbx/</guid>

          

          

          
        </item>
      
    
      
        <item>
          <title>Endless ♥ GNOME at GUADEC 2023</title>

          <description>
            
              
              
              
              
                &lt;img src=&quot;https://cassidyjames.com/images/blog/guadec-2023/attendees.jpg&quot; /&gt;
              
            

            &lt;p&gt;In July, my employer &lt;a href=&quot;https://endlessos.org&quot;&gt;Endless&lt;/a&gt; sponsored and attended the annual &lt;a href=&quot;https://gnome.org&quot;&gt;GNOME&lt;/a&gt; conference, &lt;a href=&quot;https://guadec.org&quot;&gt;GUADEC&lt;/a&gt;, in Rīga, Latvia. Endless has a long history of supporting and collaborating within the GNOME open source project, and it was great to support GUADEC again this year as the platinum sponsor of the event.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/guadec-2023/attendees.jpg&quot; alt=&quot;GUADEC 2023 Attendees&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Our support of GUADEC and GNOME is more than just a sponsorship, though; we showed up and participated all week to present and plan for our continued contributions to GNOME. The conference is designed around a one-day advisory board meeting, a few days of talks, and a few days of working sessions.&lt;/p&gt;

&lt;h3 id=&quot;advisory-board-meeting&quot;&gt;Advisory Board Meeting&lt;/h3&gt;

&lt;p&gt;We joined representatives from other organizations using and invested in the success of GNOME in meeting with the GNOME Foundation Board of Directors for an all-day Advisory Board meeting. There we discussed improving the accessibility of GNOME, the travel sponsorship process, reproducible builds for apps, how organizations can better upstream their non-code contributions to GNOME, and other topics raised by member organizations.&lt;/p&gt;

&lt;h3 id=&quot;talks&quot;&gt;Talks&lt;/h3&gt;

&lt;p&gt;Endless OS Foundation employees presented a total of nine talks across three broad topics:&lt;/p&gt;

&lt;h4 id=&quot;1-design&quot;&gt;1. Design&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;GNOME Design State of the Union&lt;/strong&gt;: I co-presented as part of the GNOME design team, showing our work over the past year and some plans for the future&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;How to Make a Delightful App Listing&lt;/strong&gt;: I taught app developers how to present their apps in their best light in app stores like GNOME Software, Flathub, and more&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;2-sharing-knowledge&quot;&gt;2. Sharing Knowledge&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Reaching New Users With GNOME&lt;/strong&gt;: Robert McQueen shared insights, knowledge, and ways forward learned by our work at Endless&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Maintaining Healthy Upstream Relationships as a Small Team&lt;/strong&gt;: Dylan McCall shared techniques for effectively communicating upstream, fostering a culture of collaboration, and managing disagreements&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;What is the GNOME Advisory Board?&lt;/strong&gt; I gave this impromptu “lightning talk” (five-minute talk prepared day-of) about my experience on the GNOME Advisory Board including what it is, how it works, and why more organizations should join&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;3-technical&quot;&gt;3. Technical&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;State of the Shell&lt;/strong&gt;: Georges Basile Stavracas Neto and other GNOME Shell developers shared the improvements, highlights, and latest development plans in Mutter and GNOME Shell&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Reducing Power &amp;amp; Bandwidth Use in Apps to Keep Users Happy&lt;/strong&gt;: Philip Withnall taught app developers how and why to change app behavior to save power and bandwidth when appropriate&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Slow Progress on App Save/Restore Support&lt;/strong&gt;: Philip Withnall shared an overview of the progress towards saving and restoring app state across restarts, including what’s left to do&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;working-sessions&quot;&gt;Working Sessions&lt;/h3&gt;

&lt;p&gt;Endless OS Foundation employees attended a variety of workshops including GTK Planning, GNOME Release Team, and GNOME OS. Throughout the week we also had countless conversations in hallways and over meals with other GNOME contributors—all of which helps share knowledge and shape the direction of GNOME.&lt;/p&gt;

&lt;p&gt;I’m proud to be part of an organization that takes this critical work seriously, collaborating deeply with and &lt;em&gt;within&lt;/em&gt; GNOME to widen our impact far beyond just users of Endless OS.&lt;/p&gt;

&lt;h3 id=&quot;read-more&quot;&gt;Read More&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://cassidyjames.com/blog/back-from-guadec-2023-riga-latvia/&quot;&gt;Cassidy James Blaede: &lt;strong&gt;I’m back from GUADEC 2023&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tecnocode.co.uk/2023/08/07/guadec-2023/&quot;&gt;Philip Withnall: &lt;strong&gt;GUADEC 2023&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://thisweek.gnome.org/posts/2023/07/twig-106/&quot;&gt;This Week In GNOME #106: &lt;strong&gt;GUADEC 2023&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.endlessnetwork.com/blog-1/guadec-2023&quot;&gt;Endless: &lt;strong&gt;Why Does Open Source Matter? Takeaways from GUADEC 2023&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;what-is-gnome&quot;&gt;What is GNOME?&lt;/h3&gt;

&lt;p&gt;GNOME is an expansive open source community developing an entirely free and open source modern computing ecosystem. GNOME technologies serve as the user interface and much of the technical stack of the most popular Linux-based operating systems including Endless OS, Ubuntu, Fedora, Red Hat Enterprise Linux, and more.&lt;/p&gt;

&lt;p&gt;Anyone can use and contribute to GNOME technologies to provide an alternative to Microsoft Windows, Google ChromeOS and Android, or Apple macOS and iOS.&lt;/p&gt;

&lt;h4 id=&quot;gnome-advisory-board&quot;&gt;GNOME Advisory Board&lt;/h4&gt;

&lt;p&gt;The GNOME Foundation is the non-profit organization that supports the GNOME community with staff, infrastructure, trademarks, legal framework, etc. The GNOME Foundation Board of Directors is democratically elected by the community to support and guide GNOME.&lt;/p&gt;

&lt;p&gt;Since GNOME technologies are so widely used, it’s beneficial to get the input and advice from other organizations that are invested in the success of GNOME—like Endless OS Foundation! The GNOME Advisory Board is an advisory committee made up of such organizations and meets with each other and the elected GNOME Foundation Board of Directors twice annually. There’s no decision-making authority, but it’s a way to collaborate and share individual organizations’ plans as they relate to their financial, technical, or labor investments into GNOME for the coming year.&lt;/p&gt;

          </description>

          <pubDate>Tue, 03 Oct 2023 00:00:00 +0000</pubDate>
          <link>https://cassidyjames.com/blog/endless-loves-gnome-guadec-2023/</link>
          <guid isPermaLink="true">https://cassidyjames.com/blog/endless-loves-gnome-guadec-2023/</guid>

          
            
            
            <enclosure url="https://cassidyjames.com/images/blog/guadec-2023/attendees.jpg" type="image/png" />
          

          

          
        </item>
      
    
      
        <item>
          <title>I’m back from GUADEC 2023</title>

          <description>
            
              
              
              
              
                &lt;img src=&quot;https://cassidyjames.com/images/blog/guadec-2023/card.jpg&quot; /&gt;
              
            

            &lt;p&gt;I’m back from Rīga, Latvia where I attended GUADEC 2023—the annual GNOME conference. It was my first time attending since 2019 due to COVID-19 plus having had another child in 2022. It simultaneously felt like it had been ages since seeing everyone, and like we picked back up after no time at all.&lt;/p&gt;

&lt;figure class=&quot;full-bleed&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/guadec-2023/hero.jpg&quot; alt=&quot;Old building&quot; /&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;For me, &lt;strong&gt;attending GUADEC in person is exceptionally important&lt;/strong&gt;: the face-to-face conversations, exploration of the host city, eating and drinking together, and spontaneous hacking all serve as powerful bonding experiences and help develop mutual understandings of the actual humans behind online usernames and avatars. We come away from GUADEC with fresh ideas, new perspectives, stronger friendships, and renewed energy to make GNOME and the open technologies we all care about better than before. You can get a small fraction of that from remote attendance—and remote participation is important to make the event as accessible and inclusive as possible—but I greatly prefer in-person participation if at all possible.&lt;/p&gt;

&lt;p&gt;While traveling from the US was as long and grueling as ever (and meant nearly two weeks away from my family), it was ultimately worth it to be in person. I just hope we can spread GUADEC out a bit more in coming years so it’s not this hard every year. 😅 More on that in a bit…&lt;/p&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#gnome-advisory-board&quot; id=&quot;markdown-toc-gnome-advisory-board&quot;&gt;GNOME Advisory Board&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#accessibility&quot; id=&quot;markdown-toc-accessibility&quot;&gt;Accessibility&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#member-participation&quot; id=&quot;markdown-toc-member-participation&quot;&gt;Member Participation&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#travel-sponsorship--hackfest-locations&quot; id=&quot;markdown-toc-travel-sponsorship--hackfest-locations&quot;&gt;Travel Sponsorship &amp;amp; Hackfest Locations&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#reproducibility-of-flatpaks&quot; id=&quot;markdown-toc-reproducibility-of-flatpaks&quot;&gt;Reproducibility of Flatpaks&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#upstreaming-more-than-code&quot; id=&quot;markdown-toc-upstreaming-more-than-code&quot;&gt;Upstreaming More than Code&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#my-talks&quot; id=&quot;markdown-toc-my-talks&quot;&gt;My Talks&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#how-to-make-a-delightful-app-listing&quot; id=&quot;markdown-toc-how-to-make-a-delightful-app-listing&quot;&gt;How to Make a Delightful App Listing&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#gnome-design-state-of-the-union&quot; id=&quot;markdown-toc-gnome-design-state-of-the-union&quot;&gt;GNOME Design: State of the Union&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#what-is-the-gnome-advisory-board&quot; id=&quot;markdown-toc-what-is-the-gnome-advisory-board&quot;&gt;What is the GNOME Advisory Board?&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#new-users-for-gnome&quot; id=&quot;markdown-toc-new-users-for-gnome&quot;&gt;New Users for GNOME&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#hallway-chats&quot; id=&quot;markdown-toc-hallway-chats&quot;&gt;Hallway Chats&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#guadec-2024-denver-co-usa-️&quot; id=&quot;markdown-toc-guadec-2024-denver-co-usa-️&quot;&gt;GUADEC 2024: Denver, CO, USA 🎉️&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#the-can-of-worms-metrics&quot; id=&quot;markdown-toc-the-can-of-worms-metrics&quot;&gt;The Can of Worms: Metrics&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#guerrilla-user-testing&quot; id=&quot;markdown-toc-guerrilla-user-testing&quot;&gt;Guerrilla User Testing&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#stars--thumbs-ratings--reviews&quot; id=&quot;markdown-toc-stars--thumbs-ratings--reviews&quot;&gt;Stars &amp;amp; Thumbs: Ratings &amp;amp; Reviews&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#summary--thanks&quot; id=&quot;markdown-toc-summary--thanks&quot;&gt;Summary &amp;amp; Thanks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;gnome-advisory-board&quot;&gt;GNOME Advisory Board&lt;/h3&gt;

&lt;p&gt;I was given the opportunity to attend the GNOME Advisory Board meeting for the first time, representing Endless. The Advisory Board is a group of organizations involved in and with a vested interest in the success of GNOME that meets twice annually—at GUADEC and FOSDEM. There is no decision making authority, but it serves as a time for people from these organizations to get together with one another and the elected GNOME Foundation Board of Directors to discuss their ongoing and upcoming plans as they relate to GNOME.&lt;/p&gt;

&lt;p&gt;There is a shared understanding of both collaboration and confidentiality—we share with one another what we can to coordinate our efforts, ultimately multiplying our individual organizations’ impact. Because of the understanding of confidentiality, I won’t go into detail; but here were common threads and conversations:&lt;/p&gt;

&lt;h4 id=&quot;accessibility&quot;&gt;Accessibility&lt;/h4&gt;

&lt;p&gt;Multiple people mentioned investing efforts into improving accessibility of GNOME technologies. Platform modernization with Wayland and GTK4 brought troves of technical improvements, but the resources for tackling accessibility to ensure it remains as good as or better than in the past have been lacking in recent years. This has been recognized and I’m confident it will be well-addressed.&lt;/p&gt;

&lt;p&gt;In addition to resources provided by organizations, there may be funding from grants to help in these areas in the coming years. If you are someone who is aware of grant application processes or knows of specific grant programs, this is a huge way you can contribute to GNOME; reach out to the Foundation to help coordinate securing additional funding in this area. Or contact me, and I can point you in the right direction—my contact details are in the footer!&lt;/p&gt;

&lt;h4 id=&quot;member-participation&quot;&gt;Member Participation&lt;/h4&gt;

&lt;p&gt;Due to a variety of reasons, the Advisory Board meeting was less-attended this year than in the past. We discussed this a bit—particularly over the lunch hour—and brainstormed ways to ensure everyone can be represented. One area identified was that the move from mailing lists to Discourse and GitLab may have left some folks behind, and this will be addressed. We also identified outdated contact details and planned to speak to specific individuals to help ensure member organizations knew of the meeting and knew their attendance was welcome and encouraged.&lt;/p&gt;

&lt;p&gt;We also chatted a bit—both at the meeting and throughout the week—about how we could encourage other organizations to join the Advisory Board to represent diverse interests. This inspired me to sign up for a “What is the GNOME Advisory Board?” lightning talk as a first step towards demystifying the Advisory Board—and encouraging more organizations to join.&lt;/p&gt;

&lt;h4 id=&quot;travel-sponsorship--hackfest-locations&quot;&gt;Travel Sponsorship &amp;amp; Hackfest Locations&lt;/h4&gt;

&lt;p&gt;A member of one organization reported that they were able to help GNOME by providing physical space at their organization’s offices for hackfests, which is another great way organizations can contribute to GNOME; travel is one aspect of organizing meetups, but having a well-resourced location is important as well. If you work for an organization that could help out in this area as well, let the Foundation know—or contact me via the details in the footer and I can forward it on.&lt;/p&gt;

&lt;p&gt;There was also feedback about the travel sponsorship process; this was an area the Foundation knew was a bit painful this year as things moved to GitLab, and some outdated information persisted in other places. But it’s being addressed.&lt;/p&gt;

&lt;h4 id=&quot;reproducibility-of-flatpaks&quot;&gt;Reproducibility of Flatpaks&lt;/h4&gt;

&lt;p&gt;We heard an update from Flathub as well as at least one member organization that there are mutual interests in getting reproducible Flatpak builds integrated with Flathub.&lt;/p&gt;

&lt;p&gt;I’m not deeply into the enterprise world, so forgive me if I don’t quite get this right, but; my understanding of one example was that if an enterprise distribution wants to encourage their customers to use Flathub because it’s where the apps are, they should be able to sign off on a hash of the app build built on their own infrastructure—even if the customer ends up downloading that build from Flathub’s infrastructure. If the apps are built reproducibly, the hashes would match, so it wouldn’t matter where the bits themselves came from.&lt;/p&gt;

&lt;p&gt;I know this is an important step in the overall trust model of a neutral infrastructure like Flathub, anyway; you should be able to trust the middleware not because of the people who are involved (and they’re good people!), but because it’s entirely transparent and auditable.&lt;/p&gt;

&lt;h4 id=&quot;upstreaming-more-than-code&quot;&gt;Upstreaming More than Code&lt;/h4&gt;

&lt;p&gt;Something raised was: how can the Foundation and Advisory Board organizations better support upstreaming more than just code contributions—that is, things like metrics, survey results, user study results, and rationale behind design decisions? For example, some downstream distributions make design decisions that aren’t upstreamed into GNOME (think: adding a dock, changing stylesheets, etc.). While downstream differentiation is important to those organizations, &lt;em&gt;are&lt;/em&gt; there ways we can better support that or learn from those changes upstream to make GNOME a better product for all the downstreams?&lt;/p&gt;

&lt;p&gt;This was more of a “get the gears turning” discussion without any specific immediate actions or outcomes, but it was an interesting conversation nonetheless.&lt;/p&gt;

&lt;h3 id=&quot;my-talks&quot;&gt;My Talks&lt;/h3&gt;

&lt;p&gt;I originally planned to give one talk this year: an updated and more GNOME-specific version of a talk I gave last year at the &lt;a href=&quot;/blog/ubuntu-summit&quot;&gt;Ubuntu Summit&lt;/a&gt;. Since I was involved with the GNOME Design team over the past year, I also ended up volunteering to co-present the annual &lt;em&gt;GNOME Design State of the Union&lt;/em&gt; talk, then I signed up for the aforementioned &lt;em&gt;What is the GNOME Advisory Board&lt;/em&gt; lightning talk—and then I was &lt;em&gt;almost&lt;/em&gt; roped into co-presenting another talk but ended up just helping write and prepare slides for it. 😅️&lt;/p&gt;

&lt;p&gt;I actually &lt;em&gt;really&lt;/em&gt; enjoyed being so involved this year, and I regret not getting signed up to help with introducing speakers, A/V, or some other volunteer position. Maybe I’ll make up for it next year…&lt;/p&gt;

&lt;h4 id=&quot;how-to-make-a-delightful-app-listing&quot;&gt;How to Make a Delightful App Listing&lt;/h4&gt;

&lt;p&gt;This was a fun talk, but I committed one of the conference sins I always try to avoid: I rewrote much of it the night before. 😬️ It was honestly not that bad since I’d presented a version of it last year, but it turns out that Flathub had since published &lt;a href=&quot;https://docs.flathub.org/docs/for-app-authors/appdata-guidelines/&quot;&gt;really great AppData guidelines&lt;/a&gt;—and I only learned of this at a bar the night before my talk. So… I rewrote the last section of my talk incorporating some of that advice.&lt;/p&gt;

&lt;p&gt;In the end, I think it made the talk &lt;em&gt;far&lt;/em&gt; better. It was a good taster of the guidelines and I hope it encouraged app developers—both of core GNOME apps, GNOME Circle apps, and the broader ecosystem—to revisit their app listings to present them in the best light possible.&lt;/p&gt;

&lt;p&gt;I’ve published the &lt;a href=&quot;/talks/guadec-2023/how-to-make-a-delightful-app-listing/&quot;&gt;slides, speaker notes, and a link to the stream&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;gnome-design-state-of-the-union&quot;&gt;GNOME Design: State of the Union&lt;/h4&gt;

&lt;p&gt;The annual update from the GNOME Design team was fun to participate in. While I wasn’t deeply involved in making mockups, icons, or major design decisions, I was involved nearly every week over the past year in providing feedback and insight. We divided the talk into a six sections plus an intro and summary, with us each presenting two of those. I took the Intro and Core Apps; while they were brief, it was great to be able to share the stage with (and show off the work of) talented folks constantly pushing GNOME design forward.&lt;/p&gt;

&lt;p&gt;Here are the &lt;a href=&quot;/talks/guadec-2023/gnome-design-state-of-the-union/&quot;&gt;slides and a link to the stream&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;what-is-the-gnome-advisory-board&quot;&gt;What is the GNOME Advisory Board?&lt;/h4&gt;

&lt;p&gt;This was the lightning talk I decided to put on the schedule after attending my first GNOME Advisory Board meeting. It was pretty rapid-fire, and most of the actual content came straight from the GNOME wiki, but I got a &lt;em&gt;lot&lt;/em&gt; of feedback afterwards that it helped demystify the Advisory Board—and even inspired a few people to reach out to organizations to encourage them to join. 🙌️&lt;/p&gt;

&lt;p&gt;I’ve published the &lt;a href=&quot;/talks/guadec-2023/what-is-the-gnome-advisory-board/&quot;&gt;slides and a link to the stream&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;new-users-for-gnome&quot;&gt;New Users for GNOME&lt;/h4&gt;

&lt;p&gt;This was a talk by Robert McQueen, CEO of the Endless OS Foundation and President of the GNOME Foundation Board of Directors—but Will Thompson and I did help out a bit in preparing notes and some slides. 😁️&lt;/p&gt;

&lt;p&gt;Rob pulled it all together into great talk sharing insights, knowledge, and ways forward learned by our work at Endless—particularly around how first-time computer users (including both kids and adults) are an impactful target audience for the work we do on GNOME.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/live/Pd4XSi4zrPs?feature=share&amp;amp;t=698&quot;&gt;YouTube Stream&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;hallway-chats&quot;&gt;Hallway Chats&lt;/h3&gt;

&lt;p&gt;A huge part of the GUADEC experience for me is the “hallway” chats often happening literally in hallways, but also over lunch, drinks, or late nights in someone’s accommodation.&lt;/p&gt;

&lt;h4 id=&quot;guadec-2024-denver-co-usa-️&quot;&gt;GUADEC 2024: Denver, CO, USA 🎉️&lt;/h4&gt;

&lt;p&gt;A persistent focus of mine was on GUADEC itself: how it was organized, how people “did” GUADEC, and what their feedback was. This was because—as was announced in the closing ceremony—&lt;strong&gt;GUADEC is coming to my home town of Denver, Colorado in 2024!&lt;/strong&gt; I think I kept the lid on it until the closing ceremony, but I made sure to pay attention people to and listen to their input.&lt;/p&gt;

&lt;p&gt;One tiny example of feedback: yoga mats! Someone suggested that with all the travel, walking, lugging backpacks, and late nights, it would be nice to have a quiet corner somewhere with half a dozen or more yoga mats and sanitizing spray. Attendees could take a moment to stretch out or just center themselves during a break. I thought this was a great idea, and I’ll be pushing for this in Denver—maybe it will become a recurring part of GUADEC?&lt;/p&gt;

&lt;p&gt;We also talked a lot about how to document things clearly on the GUADEC website, reducing the duplicated GUADEC communication channels (I think I counted five different channels on Matrix… and most people only used one), encouraging inclusive eating options like vegetarian, vegan, and gluten-free restaurants, and of course: all the fun things people would want to do in and around Denver (Casa Bonita? Meow Wolf? The mountains?).&lt;/p&gt;

&lt;p&gt;Another area we focused on was climate impact: while flying a bunch of Europeans to the US obviously has its impacts, there will also be significantly reduced travel for many of us within North, Central, and South America. Even so, I’d like to encourage lower-carbon transit options as much as possible, e.g. rail and bus if possible within the US, trying to keep everything for the week of GUADEC itself along convenient public transit or walkable, and reducing our impact in smaller but meaningful ways like encouraging reusing lanyards and avoiding other single-use waste. Philip Withnall provided some great tips for me, and I’ll be taking his advice for how to approach some of these areas.&lt;/p&gt;

&lt;h4 id=&quot;the-can-of-worms-metrics&quot;&gt;The Can of Worms: Metrics&lt;/h4&gt;

&lt;p&gt;Against my better judgment (and the advice of friends), I broached the topic of privacy-preserving metrics once or twice… In all honesty, GUADEC hallways/bars are the perfect sort of place to have these conversations without the pressure of forming an Internet Opinion™️ etched forever into the collective memory. We’ve regularly been having these sorts of conversations since at least 2018, anyway, and while recent Fedora Discourse threads of doom have made it more of “a thing” than in years past, I felt it was important to speak candidly about it in person.&lt;/p&gt;

&lt;p&gt;I came away with a few insights.&lt;/p&gt;

&lt;p&gt;First, there are real areas where GNOME maintainers literally don’t know if complex code paths are &lt;em&gt;ever&lt;/em&gt; touched in the real world, and this is an area a privacy-preserving tally-counter could provide real value to users; for example, GNOME Document Viewer (Evince) apparently handles something like ten more file formats than just PDFs, but nobody we talked to &lt;em&gt;at a GNOME developer conference&lt;/em&gt; even knew that. Document Viewer is also one of the handful of apps that hasn’t been ported to GTK4 and Libadwaita, in part due to the complexity of maintaining those codepaths. It sure would be beneficial to the maintainers to know if anyone actually uses those other formats in Document Viewer, and if not, it could greatly speed up the modernization of the app—bringing both consistent design and improved performance—by simplifying what it supports. At the same time, if it turns out that one or two other format than PDF is actually widely used in the wild, then that could inform the design of Document Viewer as well, making it better at handling the tasks it’s actually used for.&lt;/p&gt;

&lt;p&gt;Second, people &lt;em&gt;still&lt;/em&gt; don’t really know the details of the open source metrics system developed by Endless and proposed to be used by Fedora. For example, the system protects privacy by reducing precision on the client side while still answering broad topics, e.g. by filing off the last several digits of latitude and longitude in estimated geolocations. It can aggregate data points locally and only submit a &lt;em&gt;summary&lt;/em&gt; of events—e.g. an aggregate count of &lt;em&gt;how many times&lt;/em&gt; a specific feature was used over the past week rather than submitting a timestamped event &lt;em&gt;every time&lt;/em&gt; the feature was used. This was well received, but it was also clear that it could be better communicated since people didn’t know it.&lt;/p&gt;

&lt;p&gt;Third, the idea of further “fuzzing” data via &lt;a href=&quot;https://en.wikipedia.org/wiki/Differential_privacy&quot;&gt;differential privacy&lt;/a&gt; or &lt;a href=&quot;https://en.wikipedia.org/wiki/Randomized_response&quot;&gt;randomized response&lt;/a&gt; (techniques from at least as far back as the 1960s to collect aggregate information while protecting individual privacy) was very popular. While the aforementioned reduction in precision is already implemented, this sort of randomized response to ensure individual event deniability is not yet—this is a clear area that could improve the system for all users.&lt;/p&gt;

&lt;p&gt;Lastly, people seem to be scared to raise their (or affiliated organizations’) heads over the parapet to become a target of The Internet Mob. It’s understandable considering the difficulty in communicating nuance plus the knee-jerk backlash from people around the Fedora proposal. However, I think this is actually a downstream issue from the two above: if people don’t know how this works &lt;em&gt;and&lt;/em&gt; it doesn’t handle privacy preservation in some ways as thoroughly as say, Apple (even if it does so in a much more transparent and auditable way), then it sounds easier to just avoid it. Perhaps more energy could be spent around addressing those areas—in the end, GNOME contributors are some of the most privacy-conscious people and are &lt;em&gt;exactly&lt;/em&gt; the type of people I want designing and developing anything to do with metrics, but that’s a point that seems to be lost on the Internet at large.&lt;/p&gt;

&lt;h4 id=&quot;guerrilla-user-testing&quot;&gt;Guerrilla User Testing&lt;/h4&gt;

&lt;p&gt;An entertaining and at least mildly insightful task at GUADEC was cornering unsuspecting locals and getting them to try GNOME. Okay, it wasn’t &lt;em&gt;quite&lt;/em&gt; like that: we did find friendly faces at coffee shops and around town who were willing to take a few moments to run through some impromptu user testing around the Activities button and the new &lt;a href=&quot;https://www.omglinux.com/gnome-test-activities-button-replacement/&quot;&gt;proposed design&lt;/a&gt;. This included locals, staff of venues, and attendees’ partners who are not currently GNOME users.&lt;/p&gt;

&lt;p&gt;I think there will be more shared on this process in the future, but my take-away was that the informal nature of this served as a sort of vibe check more than anything; we weren’t disciplined in how we took notes, what leading questions we asked or avoided, and how we presented it from person to person. Allan Day did write up a great more formal process that I’d like us to follow to get better results from, though.&lt;/p&gt;

&lt;h4 id=&quot;stars--thumbs-ratings--reviews&quot;&gt;Stars &amp;amp; Thumbs: Ratings &amp;amp; Reviews&lt;/h4&gt;

&lt;p&gt;The topic of ratings and reviews (e.g. in GNOME Software) came up a few times, inspired from feedback from the Bottles developers, attendees of my App Listing talk, and other hallway chats. I’ve summarized my thoughts in a &lt;a href=&quot;/blog/stars-thumbs-app-ratings-reviews-odrs/&quot;&gt;blog post published last week&lt;/a&gt;; give it a read!&lt;/p&gt;

&lt;h3 id=&quot;summary--thanks&quot;&gt;Summary &amp;amp; Thanks&lt;/h3&gt;

&lt;p&gt;I originally set out to detail every talk I attended, each social venue, etc. but there was &lt;em&gt;so much&lt;/em&gt; to talk about around the “hallway” track that I wanted to detail that, instead. I would highly recommend taking a look at the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLcb5uDX8FIoCXfTI9t2a47WUDoPG7sIMD&quot;&gt;YouTube Playlist of talks&lt;/a&gt;: they were all professionally recorded and streamed, and a gracious commentor has provided timestamps to each talk. 🙏️&lt;/p&gt;

&lt;p&gt;I hope this write-up provided some insight into the goings-on of GUADEC and my experience there.&lt;/p&gt;

&lt;p&gt;I’d like to thank my employer, the Endless OS Foundation, for allowing me to spend an entire week of work at GUADEC; it’s an incredibly valuable aspect of GNOME, and I love that Endless sees that. I’d also like to thank the GNOME Foundation for partially sponsoring my attendance as a member of the GNOME Foundation; ensuring people can get to these events is crucial for community building and all of the high-bandwidth communication that can really only happen in person.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://wiki.gnome.org/Travel&quot;&gt;&lt;img src=&quot;/images/blog/guadec-2023/sponsored-by-foundation.png&quot; alt=&quot;Sponsored by GNOME Foundation&quot; width=&quot;160&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

          </description>

          <pubDate>Sun, 06 Aug 2023 00:00:00 +0000</pubDate>
          <link>https://cassidyjames.com/blog/back-from-guadec-2023-riga-latvia/</link>
          <guid isPermaLink="true">https://cassidyjames.com/blog/back-from-guadec-2023-riga-latvia/</guid>

          
            
            
            <enclosure url="https://cassidyjames.com/images/blog/guadec-2023/card.jpg" type="image/png" />
          

          

          
        </item>
      
    
      
        <item>
          <title>Stars &amp; Thumbs</title>

          <description>
            
              
              
              
              
                &lt;img src=&quot;https://cassidyjames.com/images/blog/stars-thumbs-app-ratings-reviews-odrs/card.png&quot; /&gt;
              
            

            &lt;p&gt;I’m on my way back from GUADEC in Rīga, Latvia and one recurring discussion (of many) was centered around how ratings and reviews are presented in GNOME software and other app stores.&lt;/p&gt;

&lt;p&gt;I’ve been building open app ecosystems for over a decade now. Ratings (quantitative feedback) and reviews (qualitative feedback) of apps can serve useful purposes: a powerful signal for ranking, a way to provide feedback to a developer, a way to demonstrate “social proof” (like testimonials or positive social media posts on a website), and a heads-up to other users for positive or negative experiences. But the widely-used five-star and review system has its problems.&lt;/p&gt;

&lt;p&gt;Since I’m sitting in an airport killing time while waiting to my flight back to Denver (where GUADEC 2024 is happening, if you haven’t heard!), let’s dig into this.&lt;/p&gt;

&lt;h2 id=&quot;whats-wrong-with-five-star-ratings&quot;&gt;What’s wrong with five-star ratings?&lt;/h2&gt;

&lt;p&gt;The meaning of the five-star rating system changes depending on culture, and even at its best, is a skewed system. If you’ve ever ridden in a ride-share like Lyft, Uber, or Bolt, you’re expected to give a five-star review unless something went wrong—and at least as of 2017, &lt;a href=&quot;https://www.buzzfeednews.com/article/carolineodonovan/the-fault-in-five-stars&quot;&gt;drivers with an average rating of less than 4.6 stars can lose their job&lt;/a&gt;. This is a circular problem: as more people are pressured to give drivers in general five stars, the average rating raises, which in turn raises the threshold at which ride-sharing companies will fire the drivers.&lt;/p&gt;

&lt;p&gt;There’s also the ambiguity: ask ten people what they would rate a product from an online retailer that they found “just fine,” and you’re likely to get at least three different answers: 2, 3, or 4 stars. If the spread is that wide, is it really a useful system? We’ve seen popular apps and platforms learn this over the years, too—and many have already abandoned the five-star rating system.&lt;/p&gt;

&lt;p&gt;YouTube used five-star reviews until 2009, when they &lt;a href=&quot;https://blog.youtube/news-and-events/five-stars-dominate-ratings/&quot;&gt;pointed out the issues&lt;/a&gt; across their growing platform: most people gave five stars, some gave one star, and basically nobody gave two or three stars. As a result, they switched to a like/dislike system.&lt;/p&gt;

&lt;p&gt;Netflix used five stars until 2017, and &lt;a href=&quot;https://www.businessinsider.com/why-netflix-replaced-its-5-star-rating-system-2017-4?op=1&quot;&gt;replaced them with thumbs-up and thumbs-down&lt;/a&gt;—though for slightly different reasoning; they use the ratings as a signal for recommendations rather than showing those ratings to other users. But by lowering the friction of providing feedback, they increased the amount of feedback given by over 200%.&lt;/p&gt;

&lt;p&gt;Even back in 2009, TechCrunch pointed out that &lt;a href=&quot;https://techcrunch.com/2009/09/22/youtube-comes-to-a-5-star-realization-its-ratings-are-useless/&quot;&gt;the Apple App Store’s five-star rating shared the same problems&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Specifically in the case of the &lt;a href=&quot;https://odrs.gnome.org/&quot;&gt;Open Desktop Ratings Service&lt;/a&gt; (ODRS) which is used to display ratings and reviews in app stores like GNOME Software, I’ve personally heard from app developers that a five-star rating system seems ill-suited when there are few total ratings; if just a few people give the app a low rating, it looks like the app is low quality—and it’s hard to get people to update those ratings, even after any raised issues are fixed.&lt;/p&gt;

&lt;h2 id=&quot;whats-wrong-with-written-reviews&quot;&gt;What’s wrong with written reviews?&lt;/h2&gt;

&lt;p&gt;Five-star ratings often come with free-form written reviews to explain &lt;em&gt;why&lt;/em&gt; a specific rating was given, but these have their own problems, too.&lt;/p&gt;

&lt;p&gt;Accepting written reviews can enable &lt;a href=&quot;https://en.wikipedia.org/wiki/Review_bomb&quot;&gt;review bombing&lt;/a&gt; and harassment of developers—even for reasons unrelated to their app. This happens pretty regularly on Steam and app stores like Google Play. Think about it: soliciting written reviews is basically making a comments section. All of the problems we’ve learned with comments sections over the years apply here.&lt;/p&gt;

&lt;p&gt;One solution could be having the app developer moderate their apps comments, but this too has problems: first, if a developer is being harassed, it’s not good for their mental health to make them be the one required to read every review. At the same time, if an app developer is ultimately in charge of what reviews are displayed, it creates an incentive to hide any negative reviews—potentially defeating the purpose of them in the first place. As a result, it should be a requirement to have a neutral third party screen reviews—and that’s very hard to scale properly, especially as an ecosystem grows.&lt;/p&gt;

&lt;p&gt;After a review is screened by some neutral party, you very much &lt;em&gt;do&lt;/em&gt; want the developer to be notified about it—otherwise it’s a post to other potential users without giving the developer the opportunity to improve. If people are going to spend their precious time writing a review, it should be as easy as possible for the developer of that app to actually receive the feedback!&lt;/p&gt;

&lt;p&gt;Especially if you’re thinking from the context of a relatively small or largely volunteer-driven app ecosystem, it seems like reviews are a &lt;em&gt;very&lt;/em&gt; difficult problem that is unsolved by some of the largest platforms at best, and a net negative on the ecosystem at worst.&lt;/p&gt;

&lt;h2 id=&quot;what-would-be-better&quot;&gt;What would be better?&lt;/h2&gt;

&lt;p&gt;I’ve long felt that the issues with the five-star rating plus review system could be remedied by using a simpler setup. So what’s the alternative?&lt;/p&gt;

&lt;p&gt;My first suggestion is to &lt;strong&gt;use a simpler signal for ratings&lt;/strong&gt;: something like a thumbs-up or heart icon to signal that someone likes the app. Combined with a tally of how many downloads there have been, this can give you relative rankings of apps with &lt;em&gt;very&lt;/em&gt; little interaction overhead. If &lt;em&gt;many&lt;/em&gt; people install an app and &lt;em&gt;nobody&lt;/em&gt; gives it a thumbs-up, it probably shouldn’t rank as highly as an app that has a &lt;em&gt;medium&lt;/em&gt; number of installs but a very &lt;em&gt;high&lt;/em&gt; thumbs-up:installs ratio.&lt;/p&gt;

&lt;p&gt;If you want to get more granular feedback, I still feel like something we discussed &lt;a href=&quot;https://medium.com/elementaryos/the-denver-appcenter-sprint-85f12a667e03&quot;&gt;back in 2017 at an elementary sprint&lt;/a&gt; could work: quantitative feedback in predetermined categories, e.g. binary options for “fast,” “useful,” or “works well.”&lt;/p&gt;

&lt;p&gt;I personally would &lt;strong&gt;avoid written reviews completely&lt;/strong&gt;. Each time an update is released, it could render all reviews irrelevant, or it could be an entirely non-visible change—any there’s no reliable way to know that from an app store point of view. A specific bug behind a one-star rating could have been fixed, yet that one-star rating will likely stay on the app’s listing in perpetuity—especially if it’s difficult or impossible for a user to update that rating if they’ve reinstalled their OS or just never visit the app’s listing again. Encouraging users to revisit old ratings could be possible in the context of the same OS installation or if there is an account system, but that introduces a ton of complexity to a concept (written reviews) that even at its best has issues of review bombing, moderation, and localization.&lt;/p&gt;

&lt;p&gt;An idea I’ve floated with mixed response has been to wire a thumbs-down to actually just open the AppStream MetaInfo issue reporting URL as a way to encourage people to directly file issues rather than leaving feedback somewhere simultaneously more public to users and less-viewed by the developers. However, this could seem a bit awkward or technical, so I’m not sure it’s a great idea—and there &lt;em&gt;is&lt;/em&gt; already a “report an issue” item in GNOME Software today if that metadata is provided by the developer.&lt;/p&gt;

&lt;h2 id=&quot;what-about-the-odrs&quot;&gt;What about the ODRS?&lt;/h2&gt;

&lt;p&gt;To be clear, &lt;strong&gt;I’m immensely impressed by and grateful for all the work that has gone into ODRS&lt;/strong&gt; so far: &lt;a href=&quot;https://blogs.gnome.org/hughsie/author/hughsie/&quot;&gt;Richard Hughes&lt;/a&gt; has done an incredibly thoughtful and admirable job at building something nobody else was doing in the open desktop space—that’s kind of his thing! At the same time, it seems like the traction behind ODRS—especially when it comes to scaling moderation and inspiring outside contributions—has been lower than would be sustainable. So… let’s iterate and improve!&lt;/p&gt;

&lt;p&gt;We have several interested parties in the ecosystem: GNOME Core and Circle apps, KDE apps, Flathub as an app store, cross-platform apps targeting Flatpak, elementary AppCenter and third-party apps, and downstream distros benefiting from the app ecosystem and repackaging apps for their own repos like Fedora, Debian, Ubuntu, Pop!_OS, and many more.&lt;/p&gt;

&lt;p&gt;Perhaps it’s time to reinvigorate ODRS with the kind of cross-desktop collaboration that makes our open ecosystem as a whole stronger: the beautiful &lt;strong&gt;coopertition&lt;/strong&gt; of working together on shared interests and technologies while striving to make what we each think is the best experience possible. I’m chatting with Richard and some of those folks mentioned to see how we can best direct this energy, and am looking forward to helping however I can—and if you’re interested in joining the effort, let me know!&lt;/p&gt;

          </description>

          <pubDate>Mon, 31 Jul 2023 00:00:00 +0000</pubDate>
          <link>https://cassidyjames.com/blog/stars-thumbs-app-ratings-reviews-odrs/</link>
          <guid isPermaLink="true">https://cassidyjames.com/blog/stars-thumbs-app-ratings-reviews-odrs/</guid>

          
            
            
            <enclosure url="https://cassidyjames.com/images/blog/stars-thumbs-app-ratings-reviews-odrs/card.png" type="image/png" />
          

          

          
        </item>
      
    
      
        <item>
          <title>Toot toot! Mastodon-powered Blog Comments</title>

          <description>
            
              
              
              
              
                &lt;img src=&quot;https://cassidyjames.com/images/blog/fediverse-blog-comments-mastodon/card.png&quot; /&gt;
              
            

            &lt;p&gt;If you follow me on Mastodon, you’ve probably heard that I’ve added Mastodon-powered comments to this here blog. If you missed it, &lt;a href=&quot;#comments&quot;&gt;check it out&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Read on to dive into my process, the first few iterations of how I did it, and what my hopes are for the future. There are lots of links to the source code on GitHub if you want to follow along, as well. Oh, and throughout this post I’ll be referring to “Mastodon” comments, but technically any &lt;a href=&quot;https://en.wikipedia.org/wiki/Fediverse&quot;&gt;Fediverse&lt;/a&gt; account that uses &lt;a href=&quot;https://en.wikipedia.org/wiki/ActivityPub&quot;&gt;ActivityPub&lt;/a&gt; can comment on my blog by replying to the the associated Mastodon post—and I do directly use the &lt;a href=&quot;https://docs.joinmastodon.org/api/&quot;&gt;Mastodon API&lt;/a&gt; to get those replies and associated data from my own instance.&lt;/p&gt;

&lt;h3 id=&quot;inspiration&quot;&gt;Inspiration&lt;/h3&gt;

&lt;p&gt;At some point, I had seen other folks on Mastodon sharing that they’d added comments to their websites powered by ActivityPub, but it always seemed daunting. After all, I don’t love complex web development and could see rolling my own commenting system as a never-ending web development project. At the same time, I have built a few &lt;a href=&quot;/blog/welcome-to-the-new-blog/#modern-features&quot;&gt;static websites&lt;/a&gt; and spent years &lt;a href=&quot;/blog/read-time-estimate-jekyll/&quot;&gt;iterating on them&lt;/a&gt; to feel more like something running on a dynamic server, all while being blazing fast. So the challenge sounded at least vaguely interesting. At some point, WordPress also acquired an &lt;a href=&quot;https://wordpress.org/plugins/activitypub/&quot;&gt;ActivityPub plugin&lt;/a&gt;, which seemed really cool for people using WordPress. Still, I forgot about it for a while.&lt;/p&gt;

&lt;p&gt;I was reminded about it when &lt;a href=&quot;https://jan.wildeboer.net/&quot;&gt;Jan Wildeboer&lt;/a&gt; shared &lt;a href=&quot;https://jan.wildeboer.net/2023/02/Jekyll-Mastodon-Comments/&quot;&gt;“Client-side comments with Mastodon on a static Jekyll website”&lt;/a&gt; on his blog—this seemed perfect! I peeked at it, bookmarked it, and moved on.&lt;/p&gt;

&lt;p&gt;Finally, when I was sharing my &lt;a href=&quot;/blog/freedesktop-accent-colors-gnome-proposal/&quot;&gt;FreeDesktop Accent Colors proposal for GNOME&lt;/a&gt;, I really wanted a better way for people to follow the conversation; that inspired me to finally actually dig in.&lt;/p&gt;

&lt;h3 id=&quot;first-iteration&quot;&gt;First Iteration&lt;/h3&gt;

&lt;p&gt;As a very first proof-of-concept, I read through &lt;a href=&quot;https://jan.wildeboer.net/2023/02/Jekyll-Mastodon-Comments/&quot;&gt;Jan’s post&lt;/a&gt; again (do so if you are interested in implementing this!), then just took his code verbatim and bolted it onto my own Jekyll site. It actually worked! That allowed me to start really understanding how it works.&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/fediverse-blog-comments-mastodon/first.png&quot; alt=&quot;Screenshot of comments at first&quot; class=&quot;card&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;They’re comments, and they work!&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I’ll leave a lot of the details for his post, but the super-simplified gist is:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Write a blog post&lt;/li&gt;
  &lt;li&gt;Post about it on Mastodon&lt;/li&gt;
  &lt;li&gt;Grab the resulting post ID and plug it back into the static site&lt;/li&gt;
  &lt;li&gt;The blog uses the Mastodon API client-side to fetch replies to the given post&lt;/li&gt;
  &lt;li&gt;Those replies are spit out onto the page and styled&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The majority of my work to ship the &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/pull/35/files&quot;&gt;first iteration&lt;/a&gt; was spent on tweaking the DOM that gets spit out and styling it up to fit the style of my site. It was a bit rough, but it worked!&lt;/p&gt;

&lt;h3 id=&quot;oops-emoji-and-avatars-️&quot;&gt;Oops, Emoji and Avatars 🤦️&lt;/h3&gt;

&lt;p&gt;I excitedly shared a few posts with comments enabled, then someone pointed out: custom emoji (in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:shortcode:&lt;/code&gt; format) didn’t work! Womp womp. Luckily, Jan had already solved this for display names, so I was able to &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/commit/dde9bf9b6436e0b75fb3f4cb0691a4ad37239b3f&quot;&gt;copy it for the comment itself&lt;/a&gt; pretty easily.&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/fediverse-blog-comments-mastodon/emoji.png&quot; alt=&quot;Screenshot of comments with no inline emoji&quot; class=&quot;card&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;:oops:, also note the interactions cluttering things up at the bottom&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Then it was pointed out they weren’t animated! Well, yeah, because I was requesting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt; versions of emoji (and user avatars, actually), so that was expected. I &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/commit/436b3208b326db2a98e7525c1150553ff5040bc6&quot;&gt;added support&lt;/a&gt; for animated emoji and avatars while respecting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prefers-reduced-motion&lt;/code&gt; media query that can be set by OSes and browsers. Neat!&lt;/p&gt;

&lt;p&gt;Someone pointed out that the avatar styling I was using wasn’t the prettiest with certain profile pictures, so I &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/commit/d69c5ac56ccb50f391e12cd5d6ac8b56292bc830&quot;&gt;rewrote that across my whole site&lt;/a&gt;—and then I noticed some avatars were provided at a too-small size, so I &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/commit/d0355a4ebd4d20b46c0fe84a49b4bbf26d487fdf&quot;&gt;fixed that&lt;/a&gt;, too.&lt;/p&gt;

&lt;h3 id=&quot;clean-up&quot;&gt;Clean Up&lt;/h3&gt;

&lt;p&gt;Along the way I noticed a few things that could be cleaned up. First, inline links were included in full, which is pretty ugly. Luckily the Mastodon API returns links with helpful utility classes included, meaning you just have to use a &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/commit/bbb9c6729adc77fec5154d2991919b067b312665&quot;&gt;tiny bit of CSS&lt;/a&gt; to imitate what Mastodon does on the web and in its apps. Second, I wasn’t handling accounts without an explicit display name as gracefully as I could; I first used some &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/commit/4d22f2e859871face3217045a49f0e622a413ec2&quot;&gt;dirty string splitting&lt;/a&gt;, then realized I could just &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/commit/9f5dba20850c61ac1cc223473be779748486a65d#diff-e224579ed0344a76bb3837aa2d28776274c7b0f5b201514e010cc8b3277e0b74L58-R46&quot;&gt;use the username&lt;/a&gt; from the API.&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/fediverse-blog-comments-mastodon/wrapping.png&quot; alt=&quot;Screenshot of comments with broken wrapping&quot; class=&quot;card&quot; width=&quot;358&quot; height=&quot;529&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;Check out that wrapping in the middle comment—that’s no good!&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I noticed wrapping was super broken with long names and small screen sizes, so I took the time to finally learn CSS grid; check out the excellent-as-usual &lt;a href=&quot;https://css-tricks.com/snippets/css/complete-guide-grid/&quot;&gt;CSS-Tricks complete guide&lt;/a&gt; if you’ve been putting it off like me. This allowed me to fine-tune the layout of the replies exactly how I wanted in a way that made sense to my brain.&lt;/p&gt;

&lt;p&gt;At this point, I was really getting unhappy with the massive blobs of HTML inside of JS inside of HTML—and my text editor’s syntax highlighting wasn’t a fan, either. So I spent some time iterating, rewriting, and simplifying things. First, since I was doing the same thing with emoji twice, I &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/commit/6c53413033b1154836cc8b0bd55d04b0f250ae94&quot;&gt;pulled out the emoji-replacing into its own function&lt;/a&gt;. Rather than using string replacement on large blobs of HTML, I (re)learned how to directly create and manipulate DOM elements with JavaScript. This was &lt;em&gt;so much cleaner&lt;/em&gt; in the resulting code, even if it technically takes a few more lines.&lt;/p&gt;

&lt;p&gt;After having a good experience switching to actual JavaScript DOM instead of strings, I took the plunge and &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/commit/9f5dba20850c61ac1cc223473be779748486a65d&quot;&gt;rewrote the whole thing&lt;/a&gt; in the same fashion. This was my favorite part of the process because it felt like I really finally understood every line of code—and I was in charge of how it worked! Even if it’s not the best way to write JavaScript (I don’t claim to be an expert, here), it really reminded me of whipping up native code in Vala for GTK apps. If you’ve spent any time reading or writing elementary Vala code, you can probably tell I have spent a lot of time doing so as well. 😅️&lt;/p&gt;

&lt;h3 id=&quot;design-iteration&quot;&gt;Design Iteration&lt;/h3&gt;

&lt;p&gt;Something I noticed when sharing links was that if I had a thread about a blog post, the first post was being omitted because I was only pulling its replies in as comments. I &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/compare/213a6ce07e170acf8ca2ad14e0245331e9ee1d54...4295df7f4c3e994910b3c8244ef2b4ed3bb053ba&quot;&gt;fixed this&lt;/a&gt; by hitting the Mastodon API to grab that first post before grabbing its replies.&lt;/p&gt;

&lt;p&gt;As a part of the above-mentioned JavaScript rewriting, I spent time thinking about how to clean up the visuals as well. I wanted to make the avatars a bit bigger and just declutter things a bit. I was especially unhappy with having a ton of default-styled links in the header of each reply, including the somewhat daunting full &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@username@example.com&lt;/code&gt; next to every single commenter’s display name.&lt;/p&gt;

&lt;p&gt;Literally while I was working on this, Facebook/Meta/Instagram &lt;a href=&quot;https://www.theverge.com/2023/7/5/23784263/instagram-threads-app-download-iphone-android&quot;&gt;launched their Threads app&lt;/a&gt;. I poked at it for a few minutes to see if ActivityPub/federation was working, and it wasn’t enabled yet, so I moved on. While I was poking at it, I noticed something interesting pointing towards that federation, though: on user profiles, Threads includes a little badge with your instance name (currently just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;threads.net&lt;/code&gt; since they’re not federating). I liked this styling, and wondered if I could do something similar to clean up the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@username@example.com&lt;/code&gt; styling that I didn’t like. So I took a stab at it!&lt;/p&gt;

&lt;p&gt;I made the decision to actually heavily deprioritize usernames in favor of display names plus instance badges. This is still a &lt;em&gt;little&lt;/em&gt; disjointed as inline @-mentions show usernames, but over all I &lt;em&gt;really&lt;/em&gt; like the look. To ensure readers can tell users apart, I added tooltips to the avatar and instance badge to expose the full username—and clicking either will open the commenter’s profile on their own instance. On mobile (at least in the browsers I am able to test), tapping-and-holding either will show the link to the profile which serves the same purpose.&lt;/p&gt;

&lt;p&gt;I also wanted a way to visually distinguish my own comments (and more generally, highlight the original poster or “OP” like on Reddit), so I added a sort of “verified” styling to any comments coming from my private instance; I add a check mark badged on my avatar and style the instance badge with a check mark and distinct accent color. I’d like to make this more generalized so if you theoretically had multiple authors on your blog, you could still highlight OP and/or trusted accounts—but that’s a problem for another day.&lt;/p&gt;

&lt;p&gt;I went back and forth a few times with if/how to handle post interactions like favorites and boosts; if I was going all-in, I’d figure out a way to use the reader’s Mastodon account to actually directly interact with posts, but that’s… a &lt;em&gt;lot&lt;/em&gt; more work. With all my excited sharing about this project on Mastodon, I inspired at least one other person; Julian Fietkau &lt;a href=&quot;https://fietkau.blog/2023/another_blog_resurrection_fediverse_new_comment_system&quot;&gt;wrote and shared his own implementation&lt;/a&gt;. His version also uses JavaScript DOM manipulation, but does a lot more like handling threading, re-ordering replies, stripping leading @-mentions, and more. I still have to dig into it and see if there is more I can pull into my implementation. I did like his styling of favorites, though, so I &lt;a href=&quot;https://github.com/cassidyjames/cassidyjames.github.io/commit/5d5bf43b37516d22fcae278b44987e64fc35a8c2&quot;&gt;did something similar&lt;/a&gt; for the time being.&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/fediverse-blog-comments-mastodon/current.png&quot; alt=&quot;Screenshot of comments today&quot; class=&quot;card&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;Culmination of these design iterations&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3 id=&quot;whats-next&quot;&gt;What’s Next&lt;/h3&gt;

&lt;p&gt;To be clear, this whole project was just something I’ve been hacking on for my own site in the evenings and in between my regular work—I don’t promise any future plans! That said, I figure it’s good to actually write up what I’d like to tackle next, if only for my own accountability.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Improved loading state&lt;/strong&gt;: along the way, I made the decision to auto-load the posts instead of requiring user interaction. However, with that change, the comments just pop in once loaded—all with no progress indication. This seems like a clear improvement to make with some sort of placeholder state.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Cache at build time&lt;/strong&gt; then update client-side? I’ve seen some &lt;em&gt;Opinions™&lt;/em&gt; about this since it would require storing others’ data, but this integration intentionally only handles non-private posts, so I think it would be okay? After all, ActivityPub servers cache content in a similar way, edited/deleted posts could be modified/removed client-side after page load, and all the data would be refreshed on the next site build to re-cache the changes. I think this would lead to an improved experience on page load since the comments would be there from the start and only the changes would need to load/shift on the page. Then again, it increases the complexity quite a bit, and basically means I have to maintain code in two places: at build time, and at page load.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Threading?&lt;/strong&gt; At one point I had some CSS to indent replies to other posts or to style them similarly to Twitter/Bluesky/Threads replies, but that quickly turns into a nightmare layout-wise. Naively indenting every reply results in terrible layouts as well. Julian’s implementation does handle some amount of threading, so perhaps I could revisit this and choose to just support one nested level for replies.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Reduce links out&lt;/strong&gt; to make it feel more integrated: instead of just always linking to the commenter’s profile, I could use the data already fetched by the Mastodon API to do something custom like a profile card when tapping or hovering the avatar. This could provide a commenter’s header image, bio, verified links, etc. in a nice digestable format instead of requiring people to follow links. Similarly, I wonder if I could use the Mastodon API to list people who fave’d a post locally/inline, instead of hackily linking to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/favourites&lt;/code&gt; URL like now? It’d be neat to have the little overlapping avatars for faves, anyway.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Auto-post to Mastodon with the API??&lt;/strong&gt; This would be the dream: write a blog post, publish it, then CI actually handles posting to Mastodon on my behalf, logs the resulting post ID, and makes comments appear automatically. Hmm… 🤔️&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Make reusable!&lt;/strong&gt; Right now this is somewhat reusable by others with static sites, but I know there are some weird me-isms included (like hardcoding my instance). It would be great to make this even more reusable by others.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;did-i-miss-anything&quot;&gt;Did I Miss Anything?&lt;/h3&gt;

&lt;p&gt;Okay, you got this far, so you’re dedicated. Let me know if you notice any glaring issues, have a brilliant idea, or have any kind of feedback for me by replying &lt;a href=&quot;#comments&quot;&gt;below&lt;/a&gt;. After all, &lt;a href=&quot;/blog/eating-our-own-dog-food/&quot;&gt;dog food is the best food&lt;/a&gt;!&lt;/p&gt;


          </description>

          <pubDate>Thu, 06 Jul 2023 00:00:00 +0000</pubDate>
          <link>https://cassidyjames.com/blog/fediverse-blog-comments-mastodon/</link>
          <guid isPermaLink="true">https://cassidyjames.com/blog/fediverse-blog-comments-mastodon/</guid>

          
            
            
            <enclosure url="https://cassidyjames.com/images/blog/fediverse-blog-comments-mastodon/card.png" type="image/png" />
          

          

          
        </item>
      
    
      
        <item>
          <title>Give your SVGs light/dark style support</title>

          <description>
            

            &lt;p&gt;I’ve recently been contributing to Flathub and updating my own website a bit, and I found myself wanting to recolor SVGs for light and dark style support. Let’s look at some examples:&lt;/p&gt;

&lt;h2 id=&quot;inline-svg&quot;&gt;Inline SVG&lt;/h2&gt;

&lt;p&gt;When using an inline SVG (including it directly in the DOM), I still recommend using your site or page’s CSS to style your icons.&lt;/p&gt;

&lt;p&gt;An SVG icon should look something like this, with the actual path data in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d&lt;/code&gt; attribute:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;svg&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;path&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;d=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;…&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You’ll want to make sure the SVG file doesn’t have its own styling, as that can override your page’s styles depending on specificity—it follows the “cascading” part of CSS, after all. Then just treat it like any other part of your page, remembering that paths use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fill&lt;/code&gt; property (instead of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;color&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;background&lt;/code&gt; as you might expect).&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.example&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;svg&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;#f00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Inline SVGs can inherit styles like any other element, so I always recommend specifying both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;color&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fill&lt;/code&gt; anywhere you want to set the foreground color on your site, so your icons pick up the text color automatically. So for your CSS:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;svg&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;inherit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.example-1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And then on your page:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;example-1&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;svg&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;path&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;d=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;…&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
  Some text
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;div class=&quot;example example-1&quot;&gt;
  &lt;!--?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?--&gt;
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; height=&quot;16px&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16px&quot;&gt;
  &lt;path d=&quot;m 1.5 1 c -0.132812 0 -0.261719 0.050781 -0.355469 0.144531 c -0.191406 0.195313 -0.191406 0.515625 0 0.710938 l 13 13 c 0.195313 0.191406 0.515625 0.191406 0.710938 0 c 0.191406 -0.195313 0.191406 -0.515625 0 -0.710938 l -1.898438 -1.894531 c 1.363281 -1.074219 2.339844 -2.558594 2.78125 -4.238281 c -0.90625 -3.535157 -4.089843 -6.007813 -7.738281 -6.011719 c -1.457031 0.003906 -2.882812 0.410156 -4.125 1.167969 l -2.019531 -2.023438 c -0.09375 -0.09375 -0.222657 -0.144531 -0.355469 -0.144531 z m 6.5 3 c 2.210938 0 4 1.789062 4 4 c 0 0.890625 -0.300781 1.75 -0.84375 2.449219 l -1.4375 -1.4375 c 0.179688 -0.304688 0.28125 -0.652344 0.28125 -1.011719 c 0 -1.105469 -0.894531 -2 -2 -2 c -0.359375 0 -0.707031 0.097656 -1.011719 0.28125 l -1.4375 -1.4375 c 0.695313 -0.546875 1.558594 -0.84375 2.449219 -0.84375 z m -5.785156 0.507812 c -0.230469 0.242188 -0.445313 0.5 -0.640625 0.773438 l 2.4375 2.4375 c 0.03125 -0.394531 0.117187 -0.785156 0.261719 -1.152344 z m -1.253906 1.746094 c -0.167969 0.316406 -0.316407 0.636719 -0.441407 0.96875 l 6.574219 6.5625 c 0.40625 0.214844 1.445312 0.121094 1.394531 0.121094 l -2.113281 -2.234375 c -0.902344 -0.402344 -1.628906 -1.128906 -2.03125 -2.03125 z m 7.539062 0.746094 c 0.277344 0 0.5 0.222656 0.5 0.5 c 0 0.214844 -0.136719 0.394531 -0.324219 0.46875 l -0.644531 -0.640625 c 0.074219 -0.191406 0.253906 -0.328125 0.46875 -0.328125 z m -2.476562 1.316406 c 0.128906 0.867188 0.8125 1.550782 1.679687 1.679688 z m -5.511719 0.484375 c 0.78125 2.105469 2.410156 3.785157 4.488281 4.628907 c -0.015625 -0.109376 -0.066406 -0.207032 -0.144531 -0.285157 z m 8.9375 2.941407 c -0.367188 0.144531 -0.757813 0.234374 -1.148438 0.261718 l 1.738281 1.742188 c 0.324219 -0.089844 0.648438 -0.195313 0.960938 -0.324219 c -0.019531 -0.105469 -0.070312 -0.203125 -0.144531 -0.277344 z m 0 0&quot; fill-rule=&quot;evenodd&quot; /&gt;
&lt;/svg&gt;

  Some text
  &lt;style&gt;
    svg path {
      color: inherit;
    }

    .example-1 {
      color: red;
      fill: red;
    }
  &lt;/style&gt;
&lt;/div&gt;

&lt;p&gt;And as you might expect, the inline SVG will follow your page or site’s media queries for dark style support:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.example-2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;maroon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;maroon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prefers-color-scheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dark&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;.example-2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;pink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;py&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;pink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Result (go ahead and try toggling your OS/browser’s dark style preference!):&lt;/p&gt;

&lt;div class=&quot;example example-2&quot;&gt;
  &lt;!--?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?--&gt;
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; height=&quot;16px&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16px&quot;&gt;
  &lt;path d=&quot;m 1.5 1 c -0.132812 0 -0.261719 0.050781 -0.355469 0.144531 c -0.191406 0.195313 -0.191406 0.515625 0 0.710938 l 13 13 c 0.195313 0.191406 0.515625 0.191406 0.710938 0 c 0.191406 -0.195313 0.191406 -0.515625 0 -0.710938 l -1.898438 -1.894531 c 1.363281 -1.074219 2.339844 -2.558594 2.78125 -4.238281 c -0.90625 -3.535157 -4.089843 -6.007813 -7.738281 -6.011719 c -1.457031 0.003906 -2.882812 0.410156 -4.125 1.167969 l -2.019531 -2.023438 c -0.09375 -0.09375 -0.222657 -0.144531 -0.355469 -0.144531 z m 6.5 3 c 2.210938 0 4 1.789062 4 4 c 0 0.890625 -0.300781 1.75 -0.84375 2.449219 l -1.4375 -1.4375 c 0.179688 -0.304688 0.28125 -0.652344 0.28125 -1.011719 c 0 -1.105469 -0.894531 -2 -2 -2 c -0.359375 0 -0.707031 0.097656 -1.011719 0.28125 l -1.4375 -1.4375 c 0.695313 -0.546875 1.558594 -0.84375 2.449219 -0.84375 z m -5.785156 0.507812 c -0.230469 0.242188 -0.445313 0.5 -0.640625 0.773438 l 2.4375 2.4375 c 0.03125 -0.394531 0.117187 -0.785156 0.261719 -1.152344 z m -1.253906 1.746094 c -0.167969 0.316406 -0.316407 0.636719 -0.441407 0.96875 l 6.574219 6.5625 c 0.40625 0.214844 1.445312 0.121094 1.394531 0.121094 l -2.113281 -2.234375 c -0.902344 -0.402344 -1.628906 -1.128906 -2.03125 -2.03125 z m 7.539062 0.746094 c 0.277344 0 0.5 0.222656 0.5 0.5 c 0 0.214844 -0.136719 0.394531 -0.324219 0.46875 l -0.644531 -0.640625 c 0.074219 -0.191406 0.253906 -0.328125 0.46875 -0.328125 z m -2.476562 1.316406 c 0.128906 0.867188 0.8125 1.550782 1.679687 1.679688 z m -5.511719 0.484375 c 0.78125 2.105469 2.410156 3.785157 4.488281 4.628907 c -0.015625 -0.109376 -0.066406 -0.207032 -0.144531 -0.285157 z m 8.9375 2.941407 c -0.367188 0.144531 -0.757813 0.234374 -1.148438 0.261718 l 1.738281 1.742188 c 0.324219 -0.089844 0.648438 -0.195313 0.960938 -0.324219 c -0.019531 -0.105469 -0.070312 -0.203125 -0.144531 -0.277344 z m 0 0&quot; fill-rule=&quot;evenodd&quot; /&gt;
&lt;/svg&gt;

  Some text
  &lt;style&gt;
    svg path {
      color: inherit;
    }

    .example-2 {
      color: maroon;
      fill: maroon;
    }

    @media (prefers-color-scheme: dark) {
      .example-2 {
        color: pink;
        fill: pink;
      }
    }
  &lt;/style&gt;
&lt;/div&gt;

&lt;p&gt;This is how I use SVGs if I can, as you get more flexibility over the styling, and can do things like changing the color on hover (e.g. for SVGs in a link). That all makes sense because the SVG is directly in the DOM and thus can be treated like any other element. But sometimes you aren’t including the SVG inline—what then?&lt;/p&gt;

&lt;h2 id=&quot;img--or-css-background-image&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;img /&amp;gt;&lt;/code&gt; or CSS background image&lt;/h2&gt;

&lt;p&gt;When you use an SVG in an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;img /&amp;gt;&lt;/code&gt; tag or as a background image in CSS, it doesn’t follow the CSS rules given to DOM elements—the SVG and thus its included &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;path&amp;gt;&lt;/code&gt;s are not actually in the DOM. In this case, if you control the SVG file I recommend using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element in the SVG itself! This is where it gets really cool: &lt;strong&gt;you can use media queries directly in the SVG&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;svg&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;path&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;d=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;…&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    path { fill: #273445 }

    @media (prefers-color-scheme: dark) {
      path { fill: #fafafa }
    }
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Result (toggle your browser’s dark style):&lt;/p&gt;

&lt;div class=&quot;example example-3&quot;&gt;
  &lt;img alt=&quot;Destiny icon&quot; src=&quot;/images/destiny.svg&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;This does not allow you to dynamically recolor the SVG from your site or page’s CSS&lt;/strong&gt;, so it has its limitations. But for brand icons where you want a light and a dark version, I love it.&lt;/p&gt;

&lt;h2 id=&quot;favicons&quot;&gt;Favicons&lt;/h2&gt;

&lt;p&gt;I discovered something thanks to my friend, GNOME designer, and Flathub brand designer &lt;a href=&quot;https://jimmac.eu/&quot;&gt;Jakub Steiner&lt;/a&gt;: &lt;strong&gt;you can use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prefers-color-scheme&lt;/code&gt; media query directly in an SVG&lt;/strong&gt;, and browsers will Do the Right Thing™! We are using this on the new &lt;a href=&quot;https://flathub.org/&quot;&gt;Flathub website&lt;/a&gt;; go ahead and toggle your OS’s dark style preference and watch the favicon in your browser’s UI.&lt;/p&gt;

&lt;p&gt;If you use this, make sure you &lt;strong&gt;provide a fallback PNG that works on both light and dark backgrounds&lt;/strong&gt;, as not all browsers support SVG favicons; check &lt;a href=&quot;https://caniuse.com/link-icon-svg&quot;&gt;Can I Use…&lt;/a&gt; for the details.&lt;/p&gt;

&lt;h2 id=&quot;css-filters&quot;&gt;CSS filters&lt;/h2&gt;

&lt;p&gt;Another option you have when using SVGs (or really, any images) on the page is to use CSS filters in light/dark style. Depending on how you use this, it can feel a bit more hack-ish, especially if you start manipulating colors—but it works. I used this on my &lt;a href=&quot;/starwars/andor&quot;&gt;Star Wars: Andor page&lt;/a&gt; for the logo:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prefers-color-scheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;light&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;.example-4&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; 
      &lt;span class=&quot;n&quot;&gt;brightness&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
      &lt;span class=&quot;nb&quot;&gt;invert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;14%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
      &lt;span class=&quot;n&quot;&gt;sepia&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;43%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
      &lt;span class=&quot;n&quot;&gt;saturate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;4969%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
      &lt;span class=&quot;n&quot;&gt;hue-rotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;343deg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
      &lt;span class=&quot;n&quot;&gt;brightness&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;89%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
      &lt;span class=&quot;n&quot;&gt;contrast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;107%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the resulting filters are &lt;em&gt;really&lt;/em&gt; messy, and it’s impossible to tell what it’s going to look like by reading it, which I don’t love. You can use an online &lt;a href=&quot;https://isotropic.co/tool/hex-color-to-css-filter/&quot;&gt;color to CSS filter converter&lt;/a&gt; to help compute the filters, as well.&lt;/p&gt;

&lt;p&gt;Result (toggle your browser’s dark style):&lt;/p&gt;

&lt;div class=&quot;example example-4&quot;&gt;
  &lt;img alt=&quot;Andor logo&quot; src=&quot;https://cassidyjames.com/images/starwars/andor/logo.png&quot; /&gt;
  &lt;style&gt;
  @media (prefers-color-scheme: light) {
    .example-4 img {
      filter: brightness(0) invert(14%) sepia(43%) saturate(4969%) hue-rotate(343deg) brightness(89%) contrast(107%);
    }
  }
  &lt;/style&gt;
&lt;/div&gt;

&lt;h2 id=&quot;thanks-for-reading&quot;&gt;Thanks for reading!&lt;/h2&gt;

&lt;p&gt;I hope this helps someone out there on the Internet, even if it’s just me the next time I go to manipulate SVGs. :)&lt;/p&gt;

&lt;style&gt;
    .example {
      margin: 1em auto;
      padding: 1em;
      background-color: var(--faint);
    }
&lt;/style&gt;


          </description>

          <pubDate>Fri, 30 Jun 2023 00:00:00 +0000</pubDate>
          <link>https://cassidyjames.com/blog/prefers-color-scheme-svg-light-dark/</link>
          <guid isPermaLink="true">https://cassidyjames.com/blog/prefers-color-scheme-svg-light-dark/</guid>

          

          

          
        </item>
      
    
      
        <item>
          <title>Accent Colors: A Proposal for GNOME</title>

          <description>
            
              
              
              
              
                &lt;img src=&quot;https://cassidyjames.com/images/blog/accent-colors/card.png&quot; /&gt;
              
            

            &lt;aside&gt;
  &lt;p&gt;&lt;strong&gt;This is not an announcement or guarantee of implementation from GNOME!&lt;/strong&gt; This post represents my personal opinions in tracking an ongoing discussion within GNOME and the FreeDesktop space. Also, &lt;strong&gt;all screenshots in this post are work-in-progress prototypes!&lt;/strong&gt; There may be issues and unsolved problems in them, so please don’t assume they represent a finished product.&lt;/p&gt;
&lt;/aside&gt;

&lt;p&gt;If you’ve been following GNOME development over the past few years you may be familiar with discussions around &lt;em&gt;accent colors.&lt;/em&gt; Specifically, could GNOME support some &lt;strong&gt;nice user expression&lt;/strong&gt; upstream while enabling downstream &lt;strong&gt;distributions to differentiate&lt;/strong&gt; themselves—all while considering the &lt;strong&gt;wants and needs of the expanding app developer community&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;I’m happy to report that we* now have a proposal and some prototype work of how to solve this complex request. Before we get into implementation details, let’s talk about the approaches we considered and how we arrived with this proposal.&lt;/p&gt;

&lt;aside class=&quot;card&quot;&gt;
  &lt;p&gt;*For the purposes of this post, “we” means myself, &lt;a href=&quot;https://blogs.gnome.org/alexm/&quot;&gt;Alice&lt;/a&gt;, &lt;a href=&quot;https://blogs.gnome.org/christopherdavis/&quot;&gt;Chris&lt;/a&gt;, and &lt;a href=&quot;https://itsjamie.dev/&quot;&gt;Jamie&lt;/a&gt;. While we’re all currently working within the GNOME community, &lt;strong&gt;our work here began as an independent effort&lt;/strong&gt; after having been involved over the past several years in these discussions. Alice, Chris, and Jamie have done the vast majority of the work, while I have been writing up our efforts and trying to help steer things where I can.&lt;/p&gt;

  &lt;p&gt;I’m now sharing this proposal with the broader GNOME community after a long process within the FreeDesktop space, and &lt;strong&gt;we are having ongoing discussions within the GNOME design team&lt;/strong&gt; to decide how to proceed.&lt;/p&gt;
&lt;/aside&gt;

&lt;p&gt;When solving a complex design problem, &lt;strong&gt;you have to consider the stakeholders.&lt;/strong&gt; Of course it’s easy to think of yourself (or whatever group you’re contributing to) as the sole stakeholder, but—especially with a space as complicated as FreeDesktop—there are several other parties involved.&lt;/p&gt;

&lt;p&gt;When I contributed to designing the &lt;a href=&quot;https://cassidyjames.com/blog/the-need-for-a-freedesktop-dark-style-preference/&quot;&gt;FreeDesktop color scheme preference&lt;/a&gt; (enabling the system-wide dark style preference) I was initially concerned about elementary OS and its users, but also actively engaged GNOME contributors, app developers, and other FreeDesktop platforms to get their input and ensure the spec could work for them. The reality is that &lt;strong&gt;this sort of feature only really works for users if it works for &lt;em&gt;most of their apps,&lt;/em&gt;&lt;/strong&gt; not just the handful they use that were designed explicitly for their corner of the wider ecosystem. As a result, the FreeDesktop color scheme spec is implemented across elementary OS, KDE, GNOME, and their ecosystems—including major cross-platform apps from large ISVs like Mozilla Firefox, Google Chrome, Brave Browser, and Microsoft Edge.&lt;/p&gt;

&lt;p&gt;We’re doing our best to take the same approach with accent colors.&lt;/p&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#the-stakeholders&quot; id=&quot;markdown-toc-the-stakeholders&quot;&gt;The Stakeholders&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#possible-accent-color-approaches&quot; id=&quot;markdown-toc-possible-accent-color-approaches&quot;&gt;Possible Accent Color Approaches&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#1-arbitrary-color&quot; id=&quot;markdown-toc-1-arbitrary-color&quot;&gt;1. Arbitrary Color&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#2-or-1b-nearest-accent&quot; id=&quot;markdown-toc-2-or-1b-nearest-accent&quot;&gt;2. (or 1b.) Nearest Accent&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#3-named-colors&quot; id=&quot;markdown-toc-3-named-colors&quot;&gt;3. Named Colors&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#proposal&quot; id=&quot;markdown-toc-proposal&quot;&gt;Proposal&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#gnome-design-considerations&quot; id=&quot;markdown-toc-gnome-design-considerations&quot;&gt;GNOME Design Considerations&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#app-developers&quot; id=&quot;markdown-toc-app-developers&quot;&gt;App Developers&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#semantic-color&quot; id=&quot;markdown-toc-semantic-color&quot;&gt;Semantic Color&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#dialogs&quot; id=&quot;markdown-toc-dialogs&quot;&gt;Dialogs&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#shell&quot; id=&quot;markdown-toc-shell&quot;&gt;Shell&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#downstream-distribution-examples&quot; id=&quot;markdown-toc-downstream-distribution-examples&quot;&gt;Downstream Distribution Examples&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#open-questions&quot; id=&quot;markdown-toc-open-questions&quot;&gt;Open Questions&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#prototype-progress&quot; id=&quot;markdown-toc-prototype-progress&quot;&gt;Prototype Progress&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#next-steps-for-gnome-design&quot; id=&quot;markdown-toc-next-steps-for-gnome-design&quot;&gt;Next Steps for GNOME Design&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#thanks-for-reading&quot; id=&quot;markdown-toc-thanks-for-reading&quot;&gt;Thanks for Reading!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-stakeholders&quot;&gt;The Stakeholders&lt;/h2&gt;

&lt;p&gt;For accent colors, we’ve specifically identified the following stakeholders based on extensive discussions and experience in the space:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Downstream distributions: Ubuntu, Fedora, Vanilla OS, etc.&lt;/li&gt;
  &lt;li&gt;FreeDesktop platforms: GNOME, elementary OS/Pantheon, KDE, etc.&lt;/li&gt;
  &lt;li&gt;App developers: those making apps for GNOME Circle, KDE, elementary AppCenter, and cross-desktop&lt;/li&gt;
  &lt;li&gt;End users: people using the thing!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Downstream distributions&lt;/strong&gt; have expressed the want to brand their experience via the default look and feel. Some distros like Ubuntu have done this with a different system stylesheet since the very beginning, while others like Fedora take more of a light-touch approach with wallpapers and logos in spots provided by the GNOME desktop. Distributions see their role as being close to end users and providing an experience they believe those users will want, and will recognize when they see it across the room or on the big screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FreeDesktop platforms&lt;/strong&gt; want to create what they believe is the best ecosystem of apps and desktop experience. This means shipping features their users want, but also cooperating in ensuring the different platforms remain interoperable with one another. We also have to consider accessibility and maintainability of the platforms as a whole, and how different features are used by different downstreams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App developers&lt;/strong&gt; want to design and make apps that look and work how they expect across supported platforms. They might want their app to look exactly the same across Ubuntu, elementary OS, and KDE, or they might want it to adapt to each platform in some way they define—but either way, it should be easy to achieve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;End users&lt;/strong&gt; want apps that work on their platform of choice, and if possible look and feel native—though that’s a secondary concern to the app being &lt;em&gt;usable&lt;/em&gt; in the first place. They also want their environment to look and feel like &lt;em&gt;their own,&lt;/em&gt; whether for aesthetic or accessibility concerns, e.g. by setting a wallpaper, a light or dark style, a font size, etc.&lt;/p&gt;

&lt;h2 id=&quot;possible-accent-color-approaches&quot;&gt;Possible Accent Color Approaches&lt;/h2&gt;

&lt;p&gt;When thinking through how we could approach this as a generic FreeDesktop spec, we came up with three potential approaches that &lt;em&gt;could&lt;/em&gt;, in theory, work. Each has trade-offs.&lt;/p&gt;

&lt;h3 id=&quot;1-arbitrary-color&quot;&gt;1. Arbitrary Color&lt;/h3&gt;

&lt;p&gt;A naive approach would be to enable the system (e.g. a distributor or user) to define an arbitrary accent color, and then toolkits would be expected to just… use that. This would theoretically provide the most flexibility for end users and distributions, but it falls apart.&lt;/p&gt;

&lt;p&gt;From the GNOME/Libadwaita side, we already support setting arbitrary accent colors &lt;em&gt;from the app developer side&lt;/em&gt;, where the app developer is expected to design and test their app to work or provide custom CSS to expand upon that. However, &lt;strong&gt;there’s no simple way the &lt;em&gt;system&lt;/em&gt; setting any potential arbitrary color would work for app developers&lt;/strong&gt;, as it would mean developers can no longer use accent colors in interesting ways with guarantees of contrast and thus accessibility—plus Libadwaita requires a &lt;em&gt;set&lt;/em&gt; of colors for different contexts (background and foreground, light style and dark style), not just a single base color.&lt;/p&gt;

&lt;p&gt;Libadwaita (and all toolkits) would need to not just accept the color as-is, but perform some amount of complicated and ultimately subjective transforms on the color to derive an accent &lt;em&gt;palette&lt;/em&gt; that can &lt;em&gt;then&lt;/em&gt; be used by apps. This might sound feasible, but it really falls apart when the provided color is gray, yellow, brown, or any number of other shades of colors. An implementation would need to algorithmically perform subjective color science like hue-rotating certain colors in certain directions and other colors in other directions when used as shadows or highlights, determine contrasting colors for the various contexts accents are used like text-on-background or icons-on-views, and all in both light and dark style variants, etc. while ensuring the colors never look plain… ugly (which again, is subjective). It’s &lt;em&gt;very&lt;/em&gt; complex and hand-wavy work and frankly seems like it would be extraordinarily over-engineered for a result that &lt;strong&gt;wouldn’t even spit out the original color that was chosen in the first place&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Different toolkits would inevitably use different color science and subjective implementations, resulting in mismatched colors across apps as well—if you chose Ubuntu orange, for example, there’s no guarantee that actual exact color would even appear &lt;em&gt;anywhere&lt;/em&gt; in the UI—but some possible muddied or hue-shifted version could. It’s not exactly on-brand in that way.&lt;/p&gt;

&lt;p&gt;However, this is the most flexible option and puts the complexity in the toolkits instead of in the spec.&lt;/p&gt;

&lt;h3 id=&quot;2-or-1b-nearest-accent&quot;&gt;2. (or 1b.) Nearest Accent&lt;/h3&gt;

&lt;p&gt;A different solution to (or variation on) the first approach would be to define the spec as &lt;em&gt;accepting&lt;/em&gt; an arbitrary color, but then letting the toolkit (or in this case, Libadwaita) algorithmically choose the “nearest” accent color from its existing palette. This approach could offer toolkits the most flexibility (as they’d need to only support a limited number of known colors), but &lt;strong&gt;it could have the same sort of end result problem as the first option&lt;/strong&gt;. It would be up to the individual platforms to decide how to expose this to users, whether they expose a full color picker, or just some predefined values.&lt;/p&gt;

&lt;p&gt;An issue we could see is that &lt;strong&gt;color palettes between platforms differ&lt;/strong&gt;, for example. If someone chooses a nice deep teal color for their accent, it might map to elementary’s lighter “Mint” accent color or even GNOME’s (slightly blue-leaning) green color. A GNOME/Libadwaita app would use one color while an app using the Ubuntu stylesheet might map to any of four different green-ish accent options.&lt;/p&gt;

&lt;p&gt;There’s &lt;strong&gt;potential for unpredictability and inconsistency, though it’s not quite as complex&lt;/strong&gt; as the first approach needing to support &lt;em&gt;any&lt;/em&gt; color in the toolkits.&lt;/p&gt;

&lt;h3 id=&quot;3-named-colors&quot;&gt;3. Named Colors&lt;/h3&gt;

&lt;p&gt;The last approach continues the line of thinking from the previous two: if you can’t perform a bunch of color science on an arbitrary color, and it’s not ideal to map an arbitrary color to a set of potential accent colors, what if you remove the arbitrary part, and make it more-well-defined? That’s what Named Colors attempts to solve.&lt;/p&gt;

&lt;p&gt;In this approach, the spec would define a set of named colors, like “red,” “orange, “yellow,” etc. that platforms could commit to supporting. The exact values of these colors are intentionally not defined in the spec, enabling the toolkit to take that color and present something from its own palette that fits. Like the nearest accent approach, &lt;strong&gt;it eases the burden a bit from implementors&lt;/strong&gt; as they would only need to test against a defined set of colors, and it &lt;strong&gt;allows for expression in each toolkit&lt;/strong&gt; or stylesheet’s own interpretation of a color. It also codifies setting user expectations of not necessarily picking “I want this exact shade of blurple,” but more, “I chose the ‘green’ option, so apps are using green accents!”&lt;/p&gt;

&lt;p&gt;We do have a great starting point for colors that’s been shipping to users for years: elementary OS! They have defined their own branded versions of red, orange, yellow, green, mint, blue, purple, pink, brown, and slate (a chromatic gray). These ten colors seem like an excellent jumping off point and could be adopted as Named Colors in the FreeDesktop spec. This would give a clear migration path for elementary OS, covers the spectrum of GNOME accent colors, and nearly matches the options in KDE today. Ubuntu specifically would likely need to change or remove a single accent color option they’re shipping today.&lt;/p&gt;

&lt;p&gt;The risks of this approach center around agreeing on that set of named colors in the first place—for example, Ubuntu currently ships accent color options that don’t neatly fit into a generic color spectrum, with several different shades of green. Some desktops that want to offer arbitrary colors might feel limited by this implementation, and &lt;strong&gt;you could &lt;em&gt;still&lt;/em&gt; have inconsistency&lt;/strong&gt; where different toolkits interpret named colors in ways unexpected by the user. There are also open questions around appending the spec with new colors in the future, should people want to.&lt;/p&gt;

&lt;h2 id=&quot;proposal&quot;&gt;Proposal&lt;/h2&gt;

&lt;p&gt;Named Colors was our preferred approach initially, as it seemed to be the least-bad and least complex option for GNOME and elementary OS. However, it didn’t really align with the direction for KDE, COSMIC, or tauOS contributors who were &lt;a href=&quot;https://github.com/flatpak/xdg-desktop-portal/pull/815&quot;&gt;proposing the FreeDesktop portal implementation&lt;/a&gt; in the first place.&lt;/p&gt;

&lt;p&gt;Given the above—and after literally a years-long process with multiple hours-long discussions and hundreds of comments from across the ecosystem—we have decided to back &lt;strong&gt;Arbitrary Color for the FreeDesktop spec&lt;/strong&gt;, proposed to be implemented as &lt;strong&gt;Nearest Accent for GNOME/Libadwaita&lt;/strong&gt; (and likely elementary OS as well). While a bit more complex for GNOME to implement than strict Named Colors, it does seem to offer a balance of flexibility for platforms, distribution differentiation, predictability and testability for GNOME-targeting app devs, and lower implementation complexity for GNOME than complete Arbitrary Colors—all while still enabling a lot of end user expression.&lt;/p&gt;

&lt;p&gt;Given an arbitrary color, platforms (e.g. via the toolkit or a platform library) would need to derive their palette that can be used by that platform’s apps. The exact implementation is up to each platform, but essentially if the FreeDesktop Portal says the accent color is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#f00&lt;/code&gt;, platforms should take that and decide how to use it in a way that makes sense for them.&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/banner-pink.png&quot; alt=&quot;Adwaita Demo with pink accent&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;
    &lt;p&gt;Adwaita Demo using a prototype pink accent color&lt;/p&gt;
  &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;For GNOME, we envision mapping it to the nearest accent color—perhaps including some additions inspired from the elementary palette, like pink and slate; so if the portal says &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#f00&lt;/code&gt;, we’d match that to our existing red palette. elementary OS could do something similar by having Granite automatically set the closest-matching stylesheet variant, similar to how they handle wallpaper-based accent colors today. In KDE (please excuse my limited knowledge of the inner workings!), I believe the chosen color could be given directly to QPalette. On Ubuntu, GNOME apps could map to the nearest palette color; the palette could be defined in the Yaru stylesheet as it is today. Flutter apps could potentially use an accent color directly e.g. to seed its Material Design 3 (“Material You”) support.&lt;/p&gt;

&lt;p&gt;In the future, if some sufficiently talented and motivated developer wanted to try to add arbitrary color support to GNOME in a way that ensures both accessibility and aesthetic quality, that &lt;em&gt;could theoretically&lt;/em&gt; be possible—or it could even be implemented as a third-party library on top of GTK; the FreeDesktop spec wouldn’t limit how the accent color could be used down the road.&lt;/p&gt;

&lt;h2 id=&quot;gnome-design-considerations&quot;&gt;GNOME Design Considerations&lt;/h2&gt;

&lt;p&gt;Let’s get into GNOME and Libadwaita specifics; if you were just here for the FreeDesktop stuff, that’s a wrap, and thanks for reading!&lt;/p&gt;

&lt;p&gt;First, we want to be clear: even though the FreeDesktop portal might accept and store arbitrary values, we see that as an implementation detail on GNOME desktop—&lt;strong&gt;we propose that the set of well-defined choices be exposed in Appearance Settings in a way similar to how elementary OS and Ubuntu display them today.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While thinking through this proposal for GNOME, some of the other biggest considerations were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Not adding an undue burden for app developers&lt;/li&gt;
  &lt;li&gt;How to ensure we retain semantic color (e.g. for destructive actions or warnings)&lt;/li&gt;
  &lt;li&gt;How it looks across the platform, e.g. in places like suggested actions in dialogs&lt;/li&gt;
  &lt;li&gt;How we would implement it in Shell&lt;/li&gt;
  &lt;li&gt;How downstream distributors could use this for differentiation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;app-developers&quot;&gt;App Developers&lt;/h3&gt;

&lt;p&gt;For app developers, an important thing to remember is that they’re always in control of how their app works. While Libadwaita could support FreeDesktop accent colors by default, &lt;strong&gt;a developer can always override the accent color used by their app&lt;/strong&gt;, as they see fit for their design and brand—just like today with the default blue accent color.&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/cal-red.png&quot; alt=&quot;Calendar with red accent&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;
    &lt;p&gt;Calendar with a prototype red accent color&lt;/p&gt;
  &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This is identical to how the FreeDesktop color scheme preference was implemented in Libadwaita for the dark style. If a developer wants to support accent colors, they would need to test with the colors in the GNOME palette—but by following best practices around color usage, they can be fairly confident the palette will just work for them by default.&lt;/p&gt;

&lt;h3 id=&quot;semantic-color&quot;&gt;Semantic Color&lt;/h3&gt;

&lt;p&gt;While color should never be used as the &lt;em&gt;only&lt;/em&gt; way to understand context (due to color blindness, inaccurate displays, and even Night Light altering visible colors), color can be used effectively to enhance the semantics of the desktop. However, this is a challenge when colors like red, yellow, and green exist in the set of potential accent colors in addition to being used semantically for things like “destructive,” “warning,” or “success.”&lt;/p&gt;

&lt;figure class=&quot;half&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/clocks-pink.png&quot; alt=&quot;Clocks with pink accent&quot; /&gt;
&lt;img src=&quot;/images/blog/accent-colors/clocks-red.png&quot; alt=&quot;Clocks with red accent&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;
    &lt;p&gt;Clocks with a prototype accent colors and new destructive button style&lt;/p&gt;
  &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;elementary OS alleviates this by using a lighter tint style for accent-colored buttons, while using a more aggressively-contrasty red style for destructive actions. We actually came to align on the same (well, opposite) approach: use the selected accent color similarly to how the blue accent is used in GNOME today, but tone down and differentiate destructive actions. This is actually &lt;a href=&quot;https://uxmovement.com/buttons/how-to-design-destructive-actions-that-prevent-data-loss/&quot;&gt;recommended by UX Movement&lt;/a&gt; precisely to avoid mistaking destructive actions as the suggested call to action—and it works well here, too.&lt;/p&gt;

&lt;figure class=&quot;half&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/clocks-slate.png&quot; alt=&quot;Clocks with slate accent&quot; /&gt;
&lt;img src=&quot;/images/blog/accent-colors/cal-slate.png&quot; alt=&quot;Calendar with slate accent&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;
    &lt;p&gt;A prototype slate accent color&lt;/p&gt;
  &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Something nice about a chromatic gray “slate” accent color is that it can reduce the amount of bright, potentially-distracting accent colors throughout the OS while retaining their semantic meaning—being different and distinct from non-accent buttons, labels, icons, etc. This accent color would also make other semantic colors like destructive actions stand out even more, which could be seen as an accessibility boon.&lt;/p&gt;

&lt;h3 id=&quot;dialogs&quot;&gt;Dialogs&lt;/h3&gt;

&lt;p&gt;For suggested actions in dialogs specifically, we had a different problem: the accent-colored text of red, pink, and orange could be very similar to the destructive red text, making it unclear which is the suggested and which is the destructive action. We could just make the suggestion action an accent background, but we did this in Adwaita for GTK3 and didn’t love it—it makes the dialog feel very unbalanced and overly aggressive.&lt;/p&gt;

&lt;figure class=&quot;half&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/dialog-pink.png&quot; alt=&quot;Dialog with pink accent color text&quot; /&gt;
&lt;img src=&quot;/images/blog/accent-colors/dialog-pink-bg.png&quot; alt=&quot;Dialog with pink accent color background&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;
    &lt;p&gt;&lt;strong&gt;Left:&lt;/strong&gt; Accent-colored text | &lt;strong&gt;Right:&lt;/strong&gt; Accent-colored background&lt;/p&gt;
  &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;We considered making the suggested action just &lt;em&gt;a bit&lt;/em&gt; more prominent—using an elementary-like tint in this context—while keeping the destructive action more toned down. This is what we currently do for the hover styles, so we’d need to adapt those a bit, too.&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/dialog-hover.png&quot; alt=&quot;Dialog with tinted suggested action button&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;
    &lt;p&gt;Suggested action hover styles&lt;/p&gt;
  &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;However, this still didn’t feel right with colors close to the destructive style because it matches the new proposed destructive style elsewhere, leading to potential confusion.&lt;/p&gt;

&lt;video width=&quot;520&quot; height=&quot;284&quot; autoplay=&quot;&quot; muted=&quot;&quot; loop=&quot;&quot; controls=&quot;&quot;&gt;
  &lt;source src=&quot;/videos/accent-colors/dialog-tint.mp4&quot; type=&quot;video/mp4&quot; /&gt;
Your browser does not support the video tag. &lt;a href=&quot;/videos/accent-colors/dialog-tint.mp4&quot;&gt;Download&lt;/a&gt;.
&lt;/video&gt;

&lt;p&gt;While thinking it through and playing with different styles, we thought: what if we simplify the styling in dialogs a bit, keeping the general layout, but treating buttons more similarly to everywhere else?&lt;/p&gt;

&lt;figure class=&quot;half&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/dialog-unstyled.png&quot; alt=&quot;Dialog with unstyled buttons&quot; /&gt;
&lt;img src=&quot;/images/blog/accent-colors/dialog-vertical.png&quot; alt=&quot;Dialog with vertical unstyled buttons&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;
    &lt;p&gt;&lt;strong&gt;Left:&lt;/strong&gt; New proposed dialog style | &lt;strong&gt;Right:&lt;/strong&gt; Adapted to vertical buttons&lt;/p&gt;
  &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Once we started playing with this, it just felt right. It feels a bit simpler and more modern than the old GTK3 styles or the current GTK4 styles while not fundamentally changing the layout. This has been one of the more controversial proposals within the GNOME design team, though, so we’ll see if it works or if we come up with something different.&lt;/p&gt;

&lt;h3 id=&quot;shell&quot;&gt;Shell&lt;/h3&gt;

&lt;p&gt;Shell uses its own toolkit, st, rather than GTK. As such, we’re working on an implementation of accent colors there, as well.&lt;/p&gt;

&lt;figure class=&quot;third&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/shell-purple.png&quot; alt=&quot;Shell with a purple accent&quot; /&gt;
&lt;img src=&quot;/images/blog/accent-colors/shell-yellow.png&quot; alt=&quot;Shell with a yellow accent&quot; /&gt;
&lt;img src=&quot;/images/blog/accent-colors/shell-pink.png&quot; alt=&quot;Shell with a pink accent&quot; /&gt;
&lt;img src=&quot;/images/blog/accent-colors/shell-orange.png&quot; alt=&quot;Shell with an orange accent&quot; /&gt;
&lt;img src=&quot;/images/blog/accent-colors/shell-teal.png&quot; alt=&quot;Shell with a teal accent&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;
    &lt;p&gt;Prototype Shell support for accent color&lt;/p&gt;
  &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This was actually easier than we expected it to be when we set out, and we think the results are nice!&lt;/p&gt;

&lt;h3 id=&quot;downstream-distribution-examples&quot;&gt;Downstream Distribution Examples&lt;/h3&gt;

&lt;p&gt;As a fun sort of exercise, I wanted to see if—theoretically—the proposed accent colors plus the existing color scheme preference could be a tool distributions use for differentiation. Using a very early prototype of accent colors in Libadwaita, see if you can identify each distro by a screenshot of its theoretical default settings:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/orange-light.png&quot; alt=&quot;Orange light&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/cyan-dark.png&quot; alt=&quot;Cyan dark&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/blue-light.png&quot; alt=&quot;Blue light&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/green-dark.png&quot; alt=&quot;Green dark&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/accent-colors/yellow-light.png&quot; alt=&quot;Yellow light&quot; /&gt;&lt;/p&gt;

&lt;details&gt;
  &lt;summary&gt;
    &lt;p&gt;Reveal Spoilers&lt;/p&gt;
  &lt;/summary&gt;
  &lt;p&gt;&lt;strong&gt;Top to bottom:&lt;/strong&gt; Ubuntu, Pop!_OS, Fedora, Manjaro, Vanilla OS&lt;/p&gt;
&lt;/details&gt;

&lt;p&gt;Did you get them all? Okay, perhaps that was too easy with the wallpapers, fonts, Shell extensions, etc… but that is kind of the point! I personally would love to see distributions using well-defined preferences for their differentiation while not resorting to the nuclear option of changing the entire system stylesheet out from under third-party apps. Using the accent color instead helps ensure apps can feel more at home across distributions right out of the box while also being predictable for the app developers.&lt;/p&gt;

&lt;h3 id=&quot;open-questions&quot;&gt;Open Questions&lt;/h3&gt;

&lt;p&gt;That just about wraps this up, but just for completeness-sake, we wanted to let you know that &lt;strong&gt;we do have some remaining questions&lt;/strong&gt; that will need to be solved.&lt;/p&gt;

&lt;p&gt;There are places in the Shell styling that use images—like checks and switches—that will either need to be ported to CSS, or (as a last resort) we’ll need to provide colored SVGs in all the accent colors.&lt;/p&gt;

&lt;p&gt;GNOME currently has (very nice!) blue folder icons, visible in GNOME Files and the file picker. With a user-selected accent color, would we &lt;em&gt;want&lt;/em&gt; those to follow along? Does that create a lot more work for maintaining the icon set? Is it fine if the folders are always GNOME-blue, regardless of the accent color? This is something we need to think about and discuss with the design team and icon maintainers.&lt;/p&gt;

&lt;p&gt;The actual accent color palettes for each of the ten colors needs to be chosen, and along with that, we should probably have internal guidelines/metrics for contrast and accessibility. E.g. we need to ensure yellow is as accessible as blue, and have a measure of how we know that.&lt;/p&gt;

&lt;p&gt;Lastly, there’s still more thought and discussion needed around semantic colors and how to ensure e.g. destructive and error states are visually distinct when using accent colors. For example, do we use different shades of the semantic colors with some of the accent colors? Do we avoid supporting a “red” accent color altogether (as a fan of red, I’m not a fan of that idea!)? Do we avoid using semantic color in most contexts altogether to allow the accent color to shine through more? These are all being discussed within GNOME, and I’m not sure where we’ll end up.&lt;/p&gt;

&lt;h2 id=&quot;prototype-progress&quot;&gt;Prototype Progress&lt;/h2&gt;

&lt;p&gt;There’s an open &lt;a href=&quot;https://github.com/flatpak/xdg-desktop-portal/pull/815&quot;&gt;pull request for the FreeDesktop portal&lt;/a&gt; we were involved in to add the tiny amount of support—and importantly, specification—needed for accent colors. We’ve also opened draft merge requests for &lt;a href=&quot;https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas/-/merge_requests/63&quot;&gt;the GNOME desktop schemas&lt;/a&gt; and &lt;a href=&quot;https://gitlab.gnome.org/GNOME/libadwaita/-/merge_requests/824&quot;&gt;Libadwaita&lt;/a&gt; which will be required to support accent colors.&lt;/p&gt;

&lt;p&gt;We’ve proposed updates to &lt;a href=&quot;https://gitlab.gnome.org/GNOME/libadwaita/-/merge_requests/810&quot;&gt;destructive styles&lt;/a&gt; and &lt;a href=&quot;https://gitlab.gnome.org/GNOME/libadwaita/-/merge_requests/812&quot;&gt;message dialog styles&lt;/a&gt; in Libadwaita which would address some of the considerations raised above.&lt;/p&gt;

&lt;p&gt;Finally, we’ve opened draft merge requests for &lt;a href=&quot;https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2715&quot;&gt;GNOME Shell&lt;/a&gt; and &lt;a href=&quot;https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/1728&quot;&gt;GNOME Settings&lt;/a&gt; for accent color support to bring it all together.&lt;/p&gt;

&lt;h2 id=&quot;next-steps-for-gnome-design&quot;&gt;Next Steps for GNOME Design&lt;/h2&gt;

&lt;p&gt;We’ve presented this proposal within the GNOME design team, and are actively working through the details to see if we can come to an agreement on the best way forward. There is still a lot of work to be done if it’s accepted, though!&lt;/p&gt;

&lt;p&gt;We would need to update the &lt;a href=&quot;https://developer.gnome.org/hig/&quot;&gt;GNOME Human Interface Guidelines&lt;/a&gt; to provide guidance to developers in using accent colors—including when to opt into the accent color, when to use and avoid semantic colors, and how to test against the supported accent colors. We would need to audit existing GNOME apps for color usage, e.g. in illustrations, animations, and semantic colors. For animations (like in the Mouse &amp;amp; Touchpad settings), we would need to update the source videos and styling to be recolorable based on the accent color.&lt;/p&gt;

&lt;p&gt;And there are probably 100 other, smaller things I’m forgetting that would need to be done.&lt;/p&gt;

&lt;h2 id=&quot;thanks-for-reading&quot;&gt;Thanks for Reading!&lt;/h2&gt;

&lt;p&gt;I know that was a &lt;em&gt;monster&lt;/em&gt; of a blog post, so props for getting through it to the end. We hope this proposal makes sense and serves as a kicking-off point for a long-awaited way for users to make their desktop their own, distributions to differentiate themselves in well-defined ways, and app developers to not be overwhelmed with the implementation. 😅️ Thanks to Alice, Chris, and Jamie for their collaboration, and for future related posts, be sure to follow &lt;a href=&quot;https://cassidyjames.com/blog&quot;&gt;my blog&lt;/a&gt;, &lt;a href=&quot;https://blogs.gnome.org/alexm/&quot;&gt;Alice’s blog&lt;/a&gt;, and &lt;a href=&quot;https://blogs.gnome.org/christopherdavis/&quot;&gt;Chris’ blog&lt;/a&gt;—or just subscribe to &lt;a href=&quot;https://planet.gnome.org/&quot;&gt;GNOME Planet&lt;/a&gt; to get it all!&lt;/p&gt;

&lt;p&gt;And to reiterate one more time, the “we” in this blog post is inclusive of myself, Alice, Chris, and Jamie—and ultimately, I wrote this blog post, so any mistakes are my own. We’ve been involved in discussions with other folks quite a bit, but we’re the ones attaching our names to this specific proposal. :) At the same time, we can’t promise that this will be accepted or come to fruition the way we’ve mapped out—in the next GNOME release or really, ever—but we wanted to put it out there for feedback and discussion. Thanks again for reading!&lt;/p&gt;

          </description>

          <pubDate>Mon, 26 Jun 2023 00:00:00 +0000</pubDate>
          <link>https://cassidyjames.com/blog/freedesktop-accent-colors-gnome-proposal/</link>
          <guid isPermaLink="true">https://cassidyjames.com/blog/freedesktop-accent-colors-gnome-proposal/</guid>

          
            
            
            <enclosure url="https://cassidyjames.com/images/blog/accent-colors/card.png" type="image/png" />
          

          

          
        </item>
      
    
      
        <item>
          <title>3D Printing on Endless OS</title>

          <description>
            
              
              
              
              
                &lt;img src=&quot;https://cassidyjames.com/images/blog/3d-printing-endless-os-linux-flathub/card.jpg&quot; /&gt;
              
            

            &lt;p&gt;&lt;img src=&quot;/images/blog/3d-printing-endless-os-linux-flathub/card.jpg&quot; alt=&quot;Screenshot&quot; class=&quot;card&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I recently got a 3D printer for my birthday, and I have been absolutely &lt;em&gt;loving&lt;/em&gt;
tinkering, printing, and learning with it. There is such a wealth of openly-shared 
and -licensed models out there, I’ve been having fun finding things to print for
myself, my friends, and especially my toddler. The best part for me, though? The
fact that I can dive deep into this whole new world of 3D modeling, slicing, and
printing using the computer I already have with freely-available software right
in the app store I already use on Endless OS: App Center with Flathub.&lt;/p&gt;

&lt;p&gt;I got a Creality Ender 3 v2 printer, which is to say: a popular and well-reviewed
printer that didn’t break the bank. For a super quick (and over-simplified) look
at the 3D printing process, there are a few steps to get from nothing to a
physical 3D object in your hands:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Design a thing;&lt;/strong&gt; this can be on a whiteboard, in a 2D design app, or whatever.
The point is, you have to start with some sort of specification/measurements.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Model that thing;&lt;/strong&gt; you have to take the idea you have and turn it into a 3D
shape on the computer. You can use a modeling program like Blender if you
know what you’re doing or want to use your model in different contexts, or 
you can use a computer-aided drawing (CAD) tool to define the shapes for your
object.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Slice the model;&lt;/strong&gt; this is the process of taking a defined 3D object and
turning it into actual instructions for your specific printer, filament, etc.
3D printer companies usually offer free slicing programs designed with their
own printers in mind, but it’s mostly all inter-compatible and based on the
same few open source projects.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Print the model;&lt;/strong&gt; slicing outputs a GCODE file, which is very literal instructions
for your printer to follow. You have to get that GCODE file onto your printer,
either with an SD card, a USB connection, or a network connection. Then it can
be printed!&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With all the open source software that powers 3D printing combined with the open
sharing culture, you can accomplish each of these steps on Endless OS or any other
Linux-based OS that has access to Flathub. Let’s look at each step and the options
you have:&lt;/p&gt;

&lt;h2 id=&quot;1-design-a-thing&quot;&gt;1. Design a thing&lt;/h2&gt;

&lt;p&gt;I love whiteboards, so I usually start there if I’m designing a new thing from
scratch. I’ll sketch a few angles out until I’m confident the measurements make
sense, then I’ll move on to modeling.&lt;/p&gt;

&lt;div class=&quot;app-badge&quot;&gt;
  &lt;a href=&quot;https://beta.flathub.org/apps/org.inkscape.Inkscape&quot; target=&quot;_blank&quot;&gt;
    &lt;header&gt;
      &lt;img class=&quot;icon&quot; src=&quot;https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.inkscape.Inkscape.png&quot; width=&quot;64&quot; height=&quot;64&quot; alt=&quot;Inkscape icon&quot; /&gt;
      &lt;strong&gt;Inkscape&lt;/strong&gt;
    &lt;/header&gt;
    &lt;span&gt;Vector Graphics Editor&lt;/span&gt;
    &lt;img class=&quot;badge&quot; src=&quot;https://beta.flathub.org/_next/static/media/flathub-badge-en.b42a637e.png&quot; width=&quot;180&quot; alt=&quot;Download on Flathub&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;However, if you’re trying to convert a 2D object into 3D, or you just want to
play around in a 2D space first, I recommend Inkscape! It’s a great vector image
editor, and it’s available on Flathub. You can lay things out and make sure they
make sense in 2D space before moving onto the more complex 3D modeling.&lt;/p&gt;

&lt;div class=&quot;app-badge&quot;&gt;
  &lt;a href=&quot;https://beta.flathub.org/apps/org.blender.Blender&quot; target=&quot;_blank&quot;&gt;
    &lt;header&gt;
      &lt;img class=&quot;icon&quot; src=&quot;https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.blender.Blender.png&quot; width=&quot;64&quot; height=&quot;64&quot; alt=&quot;Blender icon&quot; /&gt;
      &lt;strong&gt;Blender&lt;/strong&gt;
    &lt;/header&gt;
    &lt;span&gt;Free and open source 3D creation suite&lt;/span&gt;
    &lt;img class=&quot;badge&quot; src=&quot;https://beta.flathub.org/_next/static/media/flathub-badge-en.b42a637e.png&quot; width=&quot;180&quot; alt=&quot;Download on Flathub&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;If you already live in Blender, you can of course use it to design your object
from the start, as well. It’s also available on Flathub.&lt;/p&gt;

&lt;h2 id=&quot;2-model-that-thing&quot;&gt;2. Model that thing&lt;/h2&gt;

&lt;p&gt;Modeling is my weakest point personally, as I haven’t taken the time to really
learn Blender or the open source CAD tools. So for me, I only tackle simple 3D
models—and I use the web-based &lt;a href=&quot;https://www.tinkercad.com/&quot;&gt;Autodesk Tinkercad&lt;/a&gt; to do it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/3d-printing-endless-os-linux-flathub/tinkercad-install.png&quot; alt=&quot;Screenshot of Tinkercad in Chromium&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Luckily on Endless OS you can trivially install web apps like Tinkercad from the
included Chromium web browser; just hit the little “Install” button that pops up
on the address bar when you’re on the site. Then Tinkercad’s icon will be added
to the app grid on your home screen and you can add it to your favorites on the
dash.&lt;/p&gt;

&lt;div class=&quot;app-badge&quot;&gt;
  &lt;a href=&quot;https://beta.flathub.org/apps/org.gnome.Epiphany&quot; target=&quot;_blank&quot;&gt;
    &lt;header&gt;
      &lt;img class=&quot;icon&quot; src=&quot;https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.gnome.Epiphany.png&quot; width=&quot;64&quot; height=&quot;64&quot; alt=&quot;Web icon&quot; /&gt;
      &lt;strong&gt;Web&lt;/strong&gt;
    &lt;/header&gt;
    &lt;span&gt;Web browser for GNOME&lt;/span&gt;
    &lt;img class=&quot;badge&quot; src=&quot;https://beta.flathub.org/_next/static/media/flathub-badge-en.b42a637e.png&quot; width=&quot;180&quot; alt=&quot;Download on Flathub&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;GNOME Web also supports web apps, Tinkercad works there as well. If you use Google Chrome or any other browser based on Chromium, it should also have an easy to use install button. If you use Firefox, you can always use Tinkercad from in the browser itself.&lt;/p&gt;

&lt;div class=&quot;app-badge&quot;&gt;
  &lt;a href=&quot;https://beta.flathub.org/apps/org.freecadweb.FreeCAD&quot; target=&quot;_blank&quot;&gt;
    &lt;header&gt;
      &lt;img class=&quot;icon&quot; src=&quot;https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.freecadweb.FreeCAD.png&quot; width=&quot;64&quot; height=&quot;64&quot; alt=&quot;FreeCAD icon&quot; /&gt;
      &lt;strong&gt;FreeCAD&lt;/strong&gt;
    &lt;/header&gt;
    &lt;span&gt;An open source parametric 3D CAD modeler&lt;/span&gt;
    &lt;img class=&quot;badge&quot; src=&quot;https://beta.flathub.org/_next/static/media/flathub-badge-en.b42a637e.png&quot; width=&quot;180&quot; alt=&quot;Download on Flathub&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;div class=&quot;app-badge&quot;&gt;
  &lt;a href=&quot;https://beta.flathub.org/apps/org.openscad.OpenSCAD&quot; target=&quot;_blank&quot;&gt;
    &lt;header&gt;
      &lt;img class=&quot;icon&quot; src=&quot;https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.openscad.OpenSCAD.png&quot; width=&quot;64&quot; height=&quot;64&quot; alt=&quot;OpenSCAD icon&quot; /&gt;
      &lt;strong&gt;OpenSCAD&lt;/strong&gt;
    &lt;/header&gt;
    &lt;span&gt;The Programmer’s Solid 3D CAD Modeller&lt;/span&gt;
    &lt;img class=&quot;badge&quot; src=&quot;https://beta.flathub.org/_next/static/media/flathub-badge-en.b42a637e.png&quot; width=&quot;180&quot; alt=&quot;Download on Flathub&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;If you’re more experienced (or adventurous than I am now), you can also try something like FreeCAD or OpenSCAD from Flathub—available in App Center right out of the box on Endless OS.&lt;/p&gt;

&lt;h2 id=&quot;3-slice-the-model&quot;&gt;3. Slice the model&lt;/h2&gt;

&lt;p&gt;Slicing is the most exciting step of the process to me, if only because people keep innovating in 3D printing purely on the software side to get more speed, performance, etc. out of existing hardware—and that all happens in the slicers.&lt;/p&gt;

&lt;div class=&quot;app-badge&quot;&gt;
  &lt;a href=&quot;https://beta.flathub.org/apps/com.ultimaker.cura&quot; target=&quot;_blank&quot;&gt;
    &lt;header&gt;
      &lt;img class=&quot;icon&quot; src=&quot;https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/com.ultimaker.cura.png&quot; width=&quot;64&quot; height=&quot;64&quot; alt=&quot;Cura icon&quot; /&gt;
      &lt;strong&gt;Cura&lt;/strong&gt;
    &lt;/header&gt;
    &lt;span&gt;The world’s most advanced 3D printer software&lt;/span&gt;
    &lt;img class=&quot;badge&quot; src=&quot;https://beta.flathub.org/_next/static/media/flathub-badge-en.b42a637e.png&quot; width=&quot;180&quot; alt=&quot;Download on Flathub&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;Popular 3D printer companies like UltiMaker/MakerBot, Prusa Labs, and FlashForge have their slicers available on Flathub. While others might offer downloads for their software on their website, my experience has been it’s less integrated over all; I’d stick to the ones on Flathub.&lt;/p&gt;

&lt;div class=&quot;app-badge&quot;&gt;
  &lt;a href=&quot;https://beta.flathub.org/apps/com.prusa3d.PrusaSlicer&quot; target=&quot;_blank&quot;&gt;
    &lt;header&gt;
      &lt;img class=&quot;icon&quot; src=&quot;https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/com.prusa3d.PrusaSlicer.png&quot; width=&quot;64&quot; height=&quot;64&quot; alt=&quot;PrusaSlicer icon&quot; /&gt;
      &lt;strong&gt;PrusaSlicer&lt;/strong&gt;
    &lt;/header&gt;
    &lt;span&gt;Get perfect 3D prints!&lt;/span&gt;
    &lt;img class=&quot;badge&quot; src=&quot;https://beta.flathub.org/_next/static/media/flathub-badge-en.b42a637e.png&quot; width=&quot;180&quot; alt=&quot;Download on Flathub&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;If whoever makes your printer doesn’t have a slicer on Flathub, fret not! They’re basically all inter-compatible, as the slicers are all based on the same handful of open source projects. Personally, I prefer UltiMaker Cura, and I could even add my Creality-brand Ender 3 v2 from in Cura’s UI with all the right preset values. Some people prefer PrusaSlicer, and it’s a similar story there.&lt;/p&gt;

&lt;div class=&quot;app-badge&quot;&gt;
  &lt;a href=&quot;https://beta.flathub.org/apps/com.flashforge.FlashPrint&quot; target=&quot;_blank&quot;&gt;
    &lt;header&gt;
      &lt;img class=&quot;icon&quot; src=&quot;https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/com.flashforge.FlashPrint.png&quot; width=&quot;64&quot; height=&quot;64&quot; alt=&quot;FlashPrint icon&quot; /&gt;
      &lt;strong&gt;FlashPrint&lt;/strong&gt;
    &lt;/header&gt;
    &lt;span&gt;Slicer for the FlashForge 3D printers&lt;/span&gt;
    &lt;img class=&quot;badge&quot; src=&quot;https://beta.flathub.org/_next/static/media/flathub-badge-en.b42a637e.png&quot; width=&quot;180&quot; alt=&quot;Download on Flathub&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;h2 id=&quot;4-print-the-model&quot;&gt;4. Print the model&lt;/h2&gt;

&lt;p&gt;The simplest/most old-school way of printing is to save your sliced GCODE file out to a microSD card, eject it, then stick it in your printer, and use your printer’s physical screen and wheel to select the print file. And that will work just fine! You can also connect your printer over USB and print directly from your slicing software.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/3d-printing-endless-os-linux-flathub/prusa-gcode.png&quot; alt=&quot;Screenshot of Prusa's GCODE viewer inspecting a model&quot; class=&quot;card&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you want to learn more about how your model will print before actually printing, you can use your slicer or a separate program to preview the GCODE file. While Cura has a preview built in, sometimes I like using PrusaSlicer’s included GCODE viewer app (installed alongside PrusaSlicer) to inspect a specific GCODE file, too.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/3d-printing-endless-os-linux-flathub/raspi-octopi.png&quot; alt=&quot;Screenshot of the Raspberry Pi imager with OctoPi selected&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you really want to go all out and have a spare Raspberry Pi, you can install &lt;a href=&quot;https://octoprint.org/&quot;&gt;OctoPrint&lt;/a&gt; with the OctoPi OS, and print to, monitor, and control your printer remotely. I won’t get into all the details, but you can get started with the official Raspberry Pi Imager by navigating to install an “other specific-purpose OS,” “3D printing,” and then “OctoPi.”&lt;/p&gt;

&lt;div class=&quot;app-badge&quot;&gt;
  &lt;a href=&quot;https://beta.flathub.org/apps/org.raspberrypi.rpi-imager&quot; target=&quot;_blank&quot;&gt;
    &lt;header&gt;
      &lt;img class=&quot;icon&quot; src=&quot;https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.raspberrypi.rpi-imager.png&quot; width=&quot;64&quot; height=&quot;64&quot; alt=&quot;Raspberry Pi Imager icon&quot; /&gt;
      &lt;strong&gt;Raspberry Pi Imager&lt;/strong&gt;
    &lt;/header&gt;
    &lt;span&gt;Raspberry Pi imaging utility&lt;/span&gt;
    &lt;img class=&quot;badge&quot; src=&quot;https://beta.flathub.org/_next/static/media/flathub-badge-en.b42a637e.png&quot; width=&quot;180&quot; alt=&quot;Download on Flathub&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;hr /&gt;

&lt;p&gt;Hopefully these apps and tips are useful to you! I’ve been super happy with the experience of designing, modeling, slicing, and printing all entirely from Endless OS—and if you have access to Flathub on your OS of choice, you can do it, too!&lt;/p&gt;

          </description>

          <pubDate>Tue, 07 Mar 2023 00:00:00 +0000</pubDate>
          <link>https://cassidyjames.com/blog/3d-printing-endless-os-linux-flathub/</link>
          <guid isPermaLink="true">https://cassidyjames.com/blog/3d-printing-endless-os-linux-flathub/</guid>

          
            
            
            <enclosure url="https://cassidyjames.com/images/blog/3d-printing-endless-os-linux-flathub/card.jpg" type="image/png" />
          

          

          
        </item>
      
    
      
        <item>
          <title>Endless OS Foundation at Ubuntu Summit 2022</title>

          <description>
            
              
              
              
              
                &lt;img src=&quot;https://cassidyjames.com/images/blog/ubuntu-summit/georges-gtk4.jpg&quot; /&gt;
              
            

            

          </description>

          <pubDate>Mon, 28 Nov 2022 00:00:00 +0000</pubDate>
          <link>https://cassidyjames.com/blog/ubuntu-summit/</link>
          <guid isPermaLink="true">https://cassidyjames.com/blog/ubuntu-summit/</guid>

          
            
            
            <enclosure url="https://cassidyjames.com/images/blog/ubuntu-summit/georges-gtk4.jpg" type="image/png" />
          

          

          
        </item>
      
    
  </channel>
</rss>
