• Pl chevron_right

      Jussi Pakkanen: Pystd standard library, similar-ish functionality with a fraction of the compile time

      news.movim.eu / PlanetGnome • 26 June 2026 • 4 minutes

    I submitted talk proposals about Pystd, the from-scratch written standard library for C++ (custom design, not a implementation of the ISO specification) to a bunch of conferences. Unfortunately all of them were rejected, so it's blog posting time.

    A controversial opinion

    Pretty much everybody agrees that compiling C++ is slow, but I personally feel that it is intolerably slow . Other people might disagree, and that is fine, but let's look at some numbers.

    Compiling a helloworld executable in C takes approximately 0.02 seconds. Compiling a C++ exe that does the same thing using #include<print> takes a second if optimizations are disabled and up to 2.3 seconds with them enabled. This is approximately a 100x slowdown. I'm using a Ryzen 7 3700X processor, so not the latest and greatest but not too shabby either. I have talked about this slowdown with some people in person and weirdly often their answers have been "that's not a problem, two seconds is insignificant". Even if you accepted this (which personally I don't) the big problem comes from scaling because the slowdown factor is approximately linear. Let's assume that in a less extreme case the slowdown was only 20x instead of 100x. In this case a program that should be done in 0.1 seconds takes 2 seconds, and therefore a program that should compile in one minute would take on the order of 20 minutes to compile.

    Why is compilation so slow?

    C++ is actually very fast to compile, the slowdowns come mostly from the way the standard library is implemented. This is actually fairly easy to test yourself by running the following shell snippet.

    echo '#include<vector>' | g++ -x c++ -E - -std=c++23 | wc

    The -E flag tells the compiler to stop after preprocessing. The output is the source code that is fed to the compiler proper. Instead we pass it to wc and find out that merely including vector expands out to 29 000 lines of code. The number is not directly comparable to "human written code", but still, almost 30k lines of code just to get a growable array of elements seems a bit much. And vector is actually one of the lighter headers. Memory is 55 thousand lines (especially bad, since 99% of the time people just want unique_ptr), print is 65 thousand lines and filesystem is 80 thousand lines.

    The unfortunate reality is that if you include even a single standard library header, your compile times tank and there's nothing you can do about it.

    Just say no

    Pystd was originally just a project for me to implement low level primitives (hash maps etc) for scratch for the fun of it. Pretty quickly I came to the three design priorities:

    1. Compilation time
    2. Simplicity of implementation
    3. Performance

    I'm not aware of an existing standard library where build time minimization would have been a design priority. Those that are fast, like the standard libraries of C and Go, seem to mostly follow from the simplicity of their respective languages.

    At the time of writing building Pystd and all tests from scratch using a single core takes 4 seconds. This consists of 45 individual processes (mostly compiles, a few links). Enabling optimizations balloons the build time to 9 seconds. Using all 16 cores brings it down to 1.9 seconds.

    What we have thus far

    If we ignore test code, Pystd has 6500 lines of headers and 5600 lines of source in total. Even adding these two together yields a line count of roughly one third of std::vector 's (preprocessed) implementation. Functionality provided by Pystd includes:

    • vector, string, validating u8string, string views, spans
    • Hash map, ordered map (using a B-tree)
    • sort (approximately as fast as stdlibc++), stable_sort (faster than stdlibc++)
    • Random selection of things in the ISO algorithm header
    • Optional, expected, variant, unique_ptr
    • Functionality roughly equivalent to Python modules argparse, pathlib (including the ** operator), regular expressions (using pcre) and tempfile

    Note that all of these are "complete" as it were. Typically they only contain the most commonly used subset of functionality. That might be a fairly small.

    Performance

    There is an earlier blog post about the performance. The numbers for converting the CapyPDF library are as follows:

    • Compile times dropped ~80%
    • Unstripped binary size reduced by ~75%
    • Stripped binary size reduced by ~30%
    • Runtime performance became ~25% faster (yes, faster, not slower)

    Regression can be prevented

    Two typical issues people raise when hearing something needs to be "fast to compile" are the following:

    1. What even is "fast"? It is highly subjective thing that depends on each person and the computer they are using.
    2. Even if something is fast now, it can not remain fast. New functionality gets added all the time, so the code is destined to become ever slower and eventually it is just as slow as the default standard library.

    The boring solution to both of these issues is the same: a predefined time budget. Pystd has a requirement that compiling a source file that includes any single public header must take at most 0.15 seconds. This limit was originally 0.1 seconds and it worked perfectly with GCC, but Clang's process startup time is longer than that. The test script that validates the performance is here . It must pass even on a Raspberry Pi.

    Interestingly the tester script was not originally single-threaded. I parallelised it only because it was the single slowest part of Pystd's compile-test cycle taking over a second.

    This is the requirement that all new functionality in Pystd must meet. If the code you want to add compiles too slow then either you rewrite the whole package to compile faster or you submit a patch to the upstream compiler to make it run faster.

    Try it yourself

    The code for Pystd is available in the usual places . Beginners might want to try using the sample project instead .

    The code works on Linux and macOS. It does not support MSVC, because the implementation uses pack indexing, which MSVC has not implemented yet.

    • Pl chevron_right

      Lennart Poettering: Mastodon Stories for systemd v261

      news.movim.eu / PlanetGnome • 25 June 2026 • 1 minute

    On June 19 we released systemd v261 into the wild .

    In the weeks leading up to that release (and since then) I have posted a series of serieses of posts to Mastodon about key new features in this release, under the #systemd261 hash tag. In case you aren't using Mastodon, but would like to read up, here's a list of all 27 posts:

    I intend to do a similar series of serieses of posts for the next systemd release (v262), hence if you haven't left tech Twitter for Mastodon yet, now is the opportunity. My series for v262 will begin in a few weeks most likely, under the #systemd262 hash tag.

    In case you are interested, here is the corresponding blog story for systemd v260 , here for v259 , here for v258 , here for v257 , and here for v256 .

    • Pl chevron_right

      Asman Malika: The Day I Learned That “Remove” Doesn’t Mean Remove

      news.movim.eu / PlanetGnome • 25 June 2026 • 4 minutes

    When I started contributing to Flatseal through the Igalia Coding Experience program, I expected to spend most of my time writing code.

    I quickly discovered that I was wrong.

    Over the past few weeks, I’ve been working on two seemingly unrelated areas of Flatpak permissions: conditional permissions and USB permissions. On paper, they looked like straightforward tasks. One involved understanding a relatively new Flatpak feature, while the other appeared to be a bug fix in Flatseal.

    What I didn’t expect was that both tasks would teach me the same lesson: understanding the semantics of a system is often harder, and more important than writing the code itself.

    Flatseal is a GNOME application that provides a graphical interface for managing Flatpak permissions. It gives users visibility into what applications can access and allows them to modify those permissions without manually editing override files.

    At first glance, permissions seem simple. An application is either allowed to do something or it isn’t.

    The reality is far more nuanced.

    One of the first areas I explored was Flatpak’s conditional permissions. These permissions allow an application to request access only when certain runtime conditions are met.

    Initially, I thought of permissions as static declarations. An application requests access to a resource, and Flatpak either grants it or denies it.

    Conditional permissions challenge that assumption.

    Instead of saying “always grant this permission,” an application can say “grant this permission only if a particular condition is true.”

    The override file showing a conditional permission: if:x11:!has-wayland grants X11 access only when Wayland is unavailable.


    The more I learned about the feature, the more I realized that permissions are not always permissions. Sometimes they are fallback mechanisms. Sometimes they are compatibility layers. Sometimes they exist purely because different systems support different capabilities.

    This raised an interesting question for Flatseal.

    If a permission only applies under certain conditions, how should that be represented to users? Should it be visible? Should it be editable? Should the interface expose the raw configuration or explain the effective behavior?

    Those questions had less to do with coding and more to do with understanding the intent behind the feature.

    While I was still thinking through those questions, I moved on to USB permissions.

    That was when things became even more interesting. Flatpak exposes two related USB concepts:

        • Allowed USB devices
        • Blocked USB devices

    These are represented internally through enumerable-devices and hidden-devices .

    At first, this seemed straightforward. A device is either allowed or blocked. Then I started experimenting with flatpak override .

    Flatseal’s USB section


    I discovered that the same USB device can appear in both lists at the same time. Not only is this valid, but it is an expected configuration.

    The key detail is that the hidden list always wins.

    A device can be present in the allowed list and the blocked list simultaneously, and Flatpak will still treat it as blocked.

    That discovery completely changed how I thought about the problem.

    The original bug I was investigating involved removing USB devices through Flatseal’s interface. My initial assumption was simple: if a user removes a device from the allowed list, then the device should no longer be allowed.

        • But what does “remove” actually mean?
        • Does it mean deleting an override?
        • Does it mean explicitly blocking the device?
        • Does it mean restoring the original application defaults?

    The answer depends on where the permission came from in the first place.

    An original permission declared by an application is different from a permission added by the user. Removing those two things should not necessarily produce the same result.

    What looked like a small UI interaction suddenly became a question about semantics.

    I found myself spending more time reading source code, experimenting with Flatpak commands, and discussing expected behavior with maintainer and my mentor, Martin Abente , than writing actual implementation code.

    At one point, I realized that I had been approaching the problem from the wrong direction entirely.

    I was asking: “How should I implement this?”.  The better question was: “What behavior is Flatpak trying to express?”

    Only after answering that question could I determine how Flatseal should behave. That shift in mindset has probably been the most valuable lesson of this experience. As developers, we often think of programming as the process of building things.

    Increasingly, I’m learning that a significant part of software engineering is understanding things.

        • Understanding why a feature exists.
        • Understanding the assumptions behind a design.
        • Understanding what users expect to happen.
        • Understanding what maintainers intended years before you ever opened the codebase.

    The code is often the final step. The real work happens before that.

    Looking back, neither conditional permissions nor USB permissions taught me the most important lesson. The lesson was that software behavior is defined by semantics, not implementation details.

    A user clicks “remove” and expects a particular outcome.

    A maintainer designs a feature with a specific meaning in mind.

    A system applies rules according to semantics that may not be obvious from the UI.

    Bridging those perspectives is where much of the engineering happens. And that’s exactly what has made contributing to Flatseal such a rewarding experience.

    I started this journey expecting to write code. Instead, I learned how to ask better questions.

    Ironically, that has probably made me a better engineer than the code itself ever could 😀

    • Pl chevron_right

      Jakub Steiner: Flatpak.org Rewrite

      news.movim.eu / PlanetGnome • 23 June 2026 • 1 minute

    The Flatpak website has been running on Middleman for years and time hasn't been kind. Touching the project resulted in seeing 42 vulnerability warnings. The gem itself hasn't seen an update in ages, and the dependency list is rather large.

    Flatpak Pixel art - a package delivery guy carrying a box with an open truck with warning lights

    Very recently, which happens to be 4 years ago, we've done a rebrand to reflect the fact that Flatpak has hit it big . There were a few hints of the old baggage, but overall it didn't feel like a website from 2007. But it was just lipstick.

    For the layout, I reached for the same named-grid approach we designed for gnome.org . Instead of fighting with a rigid single column you get a multi-column grid with named areas. This allows you to escape the column to span across the whole width or do side-by-side layouts with overflow.

    Most of the navigation is left to the footer. Another pattern we've embraced elsewhere and has worked well. A major simplification came from the great work of Kolja ( razze ) on Flathub -- all the distro setup instructions are maintained in one place.

    Most benefits remain on the backend — keeping the site up to date won't be such a chore. Shoutout goes to Bart, AsciiWolf and Sebastian, thank you for caring. On to the next one!

    • Pl chevron_right

      Christian Hergert: Asynchronous State Machines with Fibers

      news.movim.eu / PlanetGnome • 21 June 2026 • 2 minutes

    Writing state machines gets a bit of a bad reputation because they are often implemented in complex manners which are specific to the problem domain. I think that makes people shy away from writing them when they are truly beneficial, including myself.

    Where they often go awry is when you have some sort of work that needs to be done asynchronously. This is exceedingly common in UI programming like GTK applications but just as easily found in daemons.

    Because of this, I see people explicitly avoiding the state machine, or worse, implicitly avoiding its correctness by open-coding a solution across a dozen callbacks.

    With DexLimiter and DexFiber I find I can write these state machines better.

    You can use the limiter with a max-concurrency of 1 to get an “asynchronous Mutex” of sorts. No lock management necessary.

    static void
    password_daemon_init (PasswordDaemon *daemon)
    {
      daemon->limiter = dex_limiter_new (1);
    }

    Imagine, if you will, that a limiter is a mutex plus a callback/closure which fires as soon as a slot is free. That means we need a little state to send to our transition callback.

    /* Define our closure state for a transition */
    DEX_DEFINE_CLOSURE_TYPE (StateTransition, state_transition,
      DEX_DEFINE_CLOSURE_OBJECT (PasswordDaemon, daemon),
      DEX_DEFINE_CLOSURE_VALUE (PasswordDaemonMode, target))

    That is a nice wrapper around defining a struct with a new and free function.

    Now we can request a transition of the state machine. Since our DexLimiter is an asynchronous mutex (with a single runnable slot), the fiber will not be spawned until it is the highest priority.

    DexFuture *
    password_daemon_transition (PasswordDaemon     *daemon,
                                PasswordDaemonMode  mode)
    {
      StateTransition *transition;
    
      transition = state_transition_new ();
      transition->daemon = g_object_ref (daemon);
      transition->target = model;
    
      return dex_limiter_run (daemon->limiter, NULL, 0,
                              password_daemon_transition_fiber,
                              transition,
                              state_transition_free);
    }

    That makes our transition code very clean when you combine the fiber with g_autoptr() and dex_await() to await the completion of futures. So a state machine might look like the following:

    static DexFuture *
    password_daemon_transition_fiber (gpointer user_data)
    {
      TransitionState *state = user_data;
      GError *error = NULL;
    
      switch (state->target)
        {
         case PASSWORD_DAEMON_MODE_HANDOFF:
           if (state->daemon->mode != PASSWORD_DAEMON_MODE_INITIAL)
             return invalid_transition (state->daemon->mode,
                                        state->target);
    
           if (!password_daemon_enter_handoff (self, &error))
             return dex_future_new_for_error (&error);
    
           break;
    
          case PASSWORD_DAEMON_MODE_LOCKED:
            ...
    
          case PASSWORD_DAEMON_MODE_UNLOCKED:
            ...
        }
    
      return dex_future_new_enum (state->daemon->mode);
    }
    
    static gboolean
    password_daemon_enter_handoff (PasswordDaemon  *daemon,
                                   GError         **error)
    {
      GSocket *control;
    
      if (!(control = dex_await_object (create_socket (), error)))
        return FALSE;
    
      ...
    }

    What I find nice about this is enter / leave transition components can be customized for the state machine transition. That leaves room for transitions between states which require specialization for correctness.

    This is much cleaner than ad-hoc callbacks chained together because you can await in the transition fiber for asynchronous work to complete and the state machine itself is preserved. No shoving temporary state in your class instance. No testing hell to see if you caught all the failure cases. No pain with sequencing or order of main loop processing.

    Hopefully that shows you can use libdex to write more correct and cleaner state machines by keeping the majority of the implementation in one place.

    • Pl chevron_right

      Hylke Bons: Icon for ChiPass

      news.movim.eu / PlanetGnome • 21 June 2026

    Icon for ChiPass

    Week 23

    This week's icon is for whitequark 's project:
    ChiPass : "Store and autofill passwords"

    Check out all weekly app icons created so far over here and follow my icon creation adventures as they happen (including sketches) on the Fediverse .

    Need icons?

    I love designing icons and am happy to contribute them free of charge when your project is Free and Open Source . Funded by community sponsors (every little helps!).

    • Pl chevron_right

      This Week in GNOME: #254 Commit Graph

      news.movim.eu / PlanetGnome • 20 June 2026 • 5 minutes

    Update on what happened across the GNOME project in the week from June 13 to June 20.

    Third Party Projects

    Sjoerd Stendahl says

    This week I released Lockpicker.

    Lockpicker is a tool to recover passwords from a hash. Essentially it functions as a front-end for hashcat, making it possible to do password recovery without the hassle of hashcat syntax in a GNOME native graphical interface.
 It’s mainly useful for anyone that is curious about password recovery, security or as a companion app for CTF-challenges.

    You can check it out on Flathub .

    Lockpicker.T76OApkd_Z1IBAxP.webp

    Luiggi R. Cardoso reports

    Draft’s v2.3 is out now!

    Now Draft has a new backend and cleaner code, making it easier and faster to add features.

    This new version brings:

    • Markdown-inspired styling to make it simpler to organize your notes and snippets;
    • Zoom functionality to make the text larger and easier to read;
    • Now the app fully follows your accent color, making the interface seamless with your desktop.

    Download it on Flathub | Contribute on GitLab | Weblate will be back soon!

    draft-screenshot.DbwfSS7g_2h2lcq.webp

    JumpLink reports

    Learn 6502 Assembly (learn assembly programming on a virtual retro console) just shipped 0.7.0 . The app now speaks Hebrew, fully translated by Menachem (@naattxx), who also tested and contributed the new right-to-left support. That makes Hebrew our first RTL language and prepares the app for more. This release also welcomes a new Indonesian translation by Arif Budiman, alongside the usual round of small fixes and improvements.

    learn6502_v0.7.0_he.BOp9ZW7s_2kT4Jx.webp

    tanay says

    Whisp has surpassed 1,000 downloads this week within 15 days(I am in Awe, Thank you so so much). The application now includes several quality-of-life improvements, including the List module, tree-style lists for better organization, note pinning, and keyboard shortcuts for faster navigation.

    Development is now moving into Phase 2, focused on expanding Whisp beyond note-taking. Planned features include a built-in Math Engine for calculations, unit and measurement conversions, and Image-to-Text functionality powered by OCR.

    Thank you to everyone who has tried, reported issues, and contributed feedback. Community support has been invaluable in helping shape the project.

    Project website: https://tanaybhomia.github.io/Whisp/ Source code: https://github.com/tanaybhomia/Whisp

    If you’d like to support development, UPI donations are now available through the website, and COFI support is planned soon.

    whisp.D7DFX3fS_xcLDA.webp

    whisp2.BxwUibRK_Z1tEKmA.webp

    Gitte

    A simple Git GUI for GNOME

    Christian reports

    Gitte, a simple Git client for GNOME built with GTK4, libadwaita and Relm4, just got its 0.7.0 release! 🎉

    The headline feature this time is a visual commit graph in the commit log: branches are drawn with color-coded lines, so commits off the mainline get a distinct per-branch color and it’s much easier to follow how history actually branches and merges. Stashes and pending changes show up as commits in that graph too, giving you a complete picture of your repository at a glance. You can also drop multiple commits at once now.

    Diffs got a lot smarter as well. Gitte now detects renames, and the word-based diff has been overhauled to highlight intra-line changes more often. There’s also a new shortcut ( Ctrl+D ) to switch between staged and unstaged in the working copy view.

    There’s more control over your lists and directories: you can toggle whether Gitte recurses into untracked directories, and the branch and tag lists now have a configurable sort order, with global defaults available in the preferences.

    This release also comes with a broad UI overhaul. The main layout has been greatly reworked (special thanks to Brage Fuglseth!), and the preferences dialog is now a standard Adwaita preferences dialog. The columns now each have a distinct background color, the sidebar was reorganized, and the commit-graph and “rebase in progress” banners were revamped. On top of that come nice new action buttons in the sidebar, better spinners if an operations takes a bit longer, pane widths kept in sync across all views, and the usual round of consistent title casing and spacing fixes.

    Under the hood there’s a performance pass too: file diff lists now show at most 100 files (30 expanded by default, with an option to force loading everything), more operations run asynchronously, and the diff view isn’t reloaded when it doesn’t need to be.

    And of course there’s the usual pile of fixes: diff lines are redrawn on theme switch, scroll position is preserved while staging and unstaging, long labels break correctly, tag badges got a better color, and the window size is now saved correctly — including when quitting with Ctrl+Q .

    Get it on Flathub , for macOS or have a look at the Code .

    gitte-commit-graph.striOZ-l_Z24BgUw.webp

    gitte-working-copy-view.BDrVL5Fq_Z1UuMH8.webp

    GDM Settings

    Customize your login screen.

    Mazhar Hussain says

    It has been almost 2 years since I last posted about GDM Settings on TWIG. While there have been some releases during that time, the development wasn’t happening really consistently. I’m really sad to announce that the development of GDM Settings is on hold for now. I’m not sure when (or if) I’ll pick up the development of this app again.

    See issue#324 for information.

    Thank you all for the support! It really meant a lot. ❤️

    Shell Extensions

    Christian W reports

    macOS-style text capture now also for GNOME: select any screen area, OCR it, copy instantly, optionally translate with this new extension https://extensions.gnome.org/extension/10209/snap-text-extractor/

    snap_text.B2deEQXo_Z1mgval.webp

    Tomáš Gažovič says

    RSS Feed extension is back after a long time and ported to latest GNOME. Same old feeds, but with a modern look. If you like your news directly from shell you can give it a try https://extensions.gnome.org/extension/948/rss-feed Project page: https://github.com/todevelopers/gnome-shell-extension-rss-feed

    Miscellaneous

    balooii reports

    For the two people out there that might be interested in trying out GIMP 0.54 from 1996 on your modern Linux system: Now you can, I created a Flatpak just for fun. It’s the last version using Motif before it’s creators decided to kick off a little toolkit called GTK… https://gitlab.gnome.org/balooii/gimp-0.54

    gimp.BbFPZO4u_ZlMkAt.webp

    GNOME OS

    The GNOME operating system, development and testing platform

    Bilal Elmoussaoui reports

    GNOME OS is now using oo7 by default as a replacement of gnome-keyring-daemon, oo7-portal for the XDG Secrets portal implementation and oo7-cli as a replacement for secret-tool.

    That’s all for this week!

    See you next week, and be sure to stop by #thisweek:gnome.org with updates on your own projects!

    • Pl chevron_right

      Hari Rana: Draft-Driven Blogging

      news.movim.eu / PlanetGnome • 20 June 2026 • 1 minute

    From 2021 to 2023, I was really motivated to write articles regularly, but that is no longer the case. Most of my energy goes into programming nowadays. Whenever I try to write about a complicated topic in a digestible manner, I quickly lose motivation and don’t publish it.

    For half a year, I’ve been trying to write an article about the thought process that went through when making the month view in GNOME Calendar accessible, as well as the implementation details. However, explaining complicated technical details into something that is simultaneously digestible to non-developers interested in accessibility and free and open-source calendar application developers requires me to withdraw my knowledge and assumptions, consider the perspective of someone who is not knowledgeable in this topic, and then recall the events that led me to take certain decisions, which demands a lot of energy.

    Due to a lack of motivation, I want to try a different approach. I am calling this approach “draft-driven blogging”. Instead of publishing articles once they are complete, I will publish the draft publicly. This draft may contain keywords, incomplete sentences, random notes, empty sections and other characteristics that are only found in drafts. I will then iteratively improve the draft until it is considered finished.

    This approach makes sense to me in terms of publishing and getting things done. I tend to seek perfection, which is great for maximizing quality, but it comes at the cost of motivation. Without external pressure, I am not motivated to fix something if it is not already publicly available. Seeing an unfinished blog post publicly is simply appalling. As it’s ugly, it motivates me to fix and complete it. So, instead of writing and publishing the ‘perfect’ article, I publish the ugly draft and complete it out of spite. Maybe “spite-driven blogging” is a better term for it?

    Of course, communication is important. With drafts, I will add a disclaimer stating that the article in question is a draft. The published date will be the date of the last edit, and all previous drafts will be deleted. To avoid spamming RSS feeds and notifications, I will try to republish drafts infrequently.

    It’s all an experiment; it might work well, or it might not. I might keep this approach or just pretend that I never tried it in the first place. We’ll see.

    • Pl chevron_right

      Hylke Bons: Icon for Hex Colordle

      news.movim.eu / PlanetGnome • 19 June 2026

    Week 22

    This week's icon is for Krafting 's project:
    Hex Colordle : "Find the color"

    Check out all weekly app icons created so far over here and follow my icon creation adventures as they happen (including sketches) on the Fediverse .

    Need icons?

    I love designing icons and am happy to contribute them free of charge when your project is Free and Open Source . Funded by community sponsors (every little helps!).