• Pl chevron_right

      Sjoerd Stendahl: Graphs 2.0 is out!

      news.movim.eu / PlanetGnome • 15 May 2026 • 6 minutes

    After two years of development, Graphs 2.0 is finally out!

    This will be a shorter blog, as the changelist of the new features have been discussed in the previous post in more detail, you can check this out here in more detail if you’re interested: https://blogs.gnome.org/sstendahl/2026/04/14/announcing-the-upcoming-graphs-2-0/

    For a quick overview, a quick reprise of the most interesting features can be found here in bullet-point format:

      • New Data Types with proper equations: In this new release, we finally have proper support for equations, where equations are manipulated analytically (e.g. a derivative on y = 12x² will result in y = 24x, and be rendered accordingly), limits are rendered infinitely, and equations can be changed after importing them. To accomodate this change, we now have three different data types. Equations, Imported Data, and Generated Data. Imported Data is regular data that you import from file. Generated Data behaves the same as Imported Data, but you generate the dataset using an equation. For generate data you can also change the equation after the fact, and rerender, or change limits or amount of generated datapoints.
      • New Style Editor: We revamped the style editor. One major change is that you can now easily import new styles based on matplotlib-style themes, and you can also export your style and share it with others. If you have a nice style you want to share with us, open an issue on the GitLab page and let us know. We’re looking to expand the default choice of styles :). Furthermore, when editing  a style, you finally see a preview of how this affects the canvas. This way you don’t need to guess, or go back and forth when finetuning a style.
      • UX-changes : Whilst the general look-and-feel of Graphs is still mostly the same, we did make some UX-changes with how we handle settings. Mainly, instead of showing a modal popup dialog, settings that affect the canvas itself (i.e. item and figure settings) are now shown in the sidebar instead. The reason for this, is that the popup dialog hid the figure that you’re editing, making it difficult to see how your changes actually affect your canvas.
      • Improved data import. We revamped the data import completely. First of all, we have made the codebase here much more modular, making it easier to write new parsers for other filetypes. We now added support for SQLite Database Files, Microsoft Excel Sheets and .ods files from LibreOffice Calc. It’s also now possible to import multiple files at once, and finetuning the settings for each file individually. Another nice feature here is that you can now import multiple datasets from the same file without having to reimport them. Finally, we added proper-support also for single-column imports where x-data can be generated using your own equation
      • Error bar support: Graphs now has proper support for error bars. The error bar style can be set globally in the new style editor, or individually for each item.
      • Reworked Curve Fitting : The curve fitting logic has almost been completely rewritten. Whilst it mostly still works the same, the confidence band that is shown is now calculated properly using the Delta-method, instead of using a naive way using the limits of the standard deviations. We also added support to show the residuals to verify your fits, and added more useful error messages when things go wrong. The results in the curve fitting dialog now also show the root mean squared error as a second goodness-of-fit figure. The parameter values themselves in the curve fitting dialog are no longer rounded (e.g. 421302 used to be rounded to 421000) and finally custom equations in the curve fitting dialog now have an apply button, greatly improving the smoothness when entering new equations
      • Proper Mobile Support: With this release, we now officially feel confident in stating proper mobile support. The entire UI is tested on real mobile phones using PostMarketOS, and everything works properly. Labels are now also ellipsized earlier on narrow displays, so that the UI remains useable.
      • Reworked Figure Exports: Figure exports are reworked. Instead of simply taking a snapshot of the current canvas, you can set the actual size in pixels when exporting a figure. This is vital when trying to create reproducable figures for e.g. publications. Of course, you can also easily still use the same canvas that you see in the application.
      • Quality of life changes : We haven’t even gone through each individual change we made in the blog, but here’s a quick fire-round of more quality-of-life changes:
        • It is now possible to have multiple instances of Graphs open at the same time
        • The style editor now also has the option to draw tick labels (so the numeric values) on all axes containing ticks, this is not supported by default in Matplotlib, so we had to add our own parameter here
        • Graphs now inhibits the session when unsaved data is still open, so you get a warning if you close your computer with unsaved data.
        • Added support for base-2 logarithmic scaling
        • Graphical fixes for the drag-drop animations, which used to look somewhat glitchy
        • Panning and zooming are now done consistently on all axes when using multiple axes
        • Data can now be imported by drag-and-drop into Graphs
        • The subtitle now also shows the full file path for Flatpaks
        • Limits can now easily be clicking on the numbers near the axes
        • The custom transformation has gained the following extra variables: x_mean, y_mean, x_median, y_median, x_std, y_std and counts
        • Warnings are now displayed when trying to open a project from a beta version
        • The many code refactors and reimplementations from Python to Vala makes the application more robust, and significantly more performance. Especially when working with larger datasets.

    This release took a long time to get right, but we’re happy to get the new features to the public. Graphs is handcrafted by human hands, which takes more time than LLM-based slop. But the longer manual process does allow us to think through changes, and make intentional decisions with human care. I am very proud to say we are able to deliver something intentional where we can deliver the polish that both Graphs, as well as the users deserve. As always, thanks to anyone involved which includes everyone who has been providing feedback, reported issues, contributed with code, or helped in any other possible way. And of course especially to Christoph who has been maintaining Graphs with me and is responsible for a large part of the architectural changes that made this release possible.

    Go get the new release from Flathub here !

    p.s. On a more personal note with a shameless plug, I will be speaking at GUADEC 2026 about my journey into app development, and how to get into this world as an outsider without a CS degree. Be sure to check that out if you are interested in starting with applications, and want to know how it is to join a project in the GNOME ecosystem, it’s a lot less scary than it may sounds 🙂

    I’ll be joining on-site, so say hi to me there if you have any questions or are up for a chat :). Otherwise the whole event will be livestreamed as well, and you can always reach me at sstendahl@gnome.org.

    • Pl chevron_right

      Allan Day: GNOME Foundation Update, 2026-05-15

      news.movim.eu / PlanetGnome • 15 May 2026 • 2 minutes

    Welcome to another GNOME Foundation update post! Today’s installment covers highlights from what’s happened over the past two weeks.

    LAS 2026

    Linux Apps Summit 2026 starts tomorrow! The organizing team, which includes members from both GNOME and KDE, has been hard at work and is on the ground in Berlin making final preparations. The schedule looks great, and it promises to be a well-attended event.

    The talks are being streamed this year, so make sure to watch our social media for details, and tune in live to hear the talks.

    GUADEC 2026

    Preparations are continuing for July’s GUADEC. The call for Birds of a Feather sessions is currently open. If you want to hold an informal discussion or working session, please fill out the form before 5th June.

    Applications are still open for travel funding for GUADEC. The deadline for submissions is 24th May – that’s just over one week.

    Board meeting

    This week the Board of Directors had its regular meeting for May. A summary:

    • The Board authorized the closure of a bank account which we are no longer using.
    • I gave an update on operations over the past month, and got feedback from the Board
    • Felipe Borges from the Internship Committee joined, to give a report. The Board discussed how we can best support the committee.
    • Deepa gave a finance report, which included numbers from January and February. The main news here was that our finances are running close to what was projected for this year’s budget.
    • The Board discussed the draft of the report from the audit we recently underwent, as well as the draft of our latest annual tax filing. This is a routine part of the Board’s work, as it is required to perform a review before these documents are finalized.

    Office transitions

    Our long-running effort to enhance our internal accounting processes has continued over the past two weeks. A notable development has been the retirement of several finance platforms, which have been effectively replaced by the new payments platform that we adopted in January. This platform reduction will reduce operational complexity, as well as workloads. It is still ongoing – we have an additional two more platforms that are currently in the process of being retired.

    Another highlight has been the launch of a search for a new member to join our finance and operations team. This is a part-time, contract-based role, which has been shaped in close consultation with Dawn Matlak, who is supporting our finance and accounting operations on a temporary basis, and has already been factored into our budget projections.

    We are looking for someone at director level who brings substantial nonprofit finance experience — including audit preparation and compliance experience — which reflects how much the Foundation’s operational and regulatory requirements have grown, particularly in the run up to and following our audit last March, and will provide in-house expertise which will reduce our reliance on external consultants. You can read the full posting here .

    Thanks for reading, and see you in two week’s time!

    • Pl chevron_right

      Bart Piotrowski: How does Flathub even work? The CDN and caching layer

      news.movim.eu / PlanetGnome • 15 May 2026 • 4 minutes

    There is one specific way in which the non-corporate open source projects typically document how their infrastructure work: not at all, and Flathub is no different. The full picture likely lives only in my brain, and while it could be sorted out by anyone (especially in this LLM age, yay or nay), why should it only be me thinking at night about all the single points of failure?

    Like any system that evolved naturally, it's all over the place. It's tempting to tell its history chronologically, but even then, it's difficult to find a good entry point. Instead, this post focuses on what happens when users call flatpak install ; later entries will cover the website and, finally, the build infrastructure. Buckle up!

    CDN, caching proxies, the master server

    The secret of making computers work well is to have them not do anything at all, and that's the story behind serving Flathub's OSTree repository. Content-addressed objects are extremely cacheable as they are immutable, offloading the effort to the CDN provider.

    When the client connects to dl.flathub.org , you can be certain it hits some layer of cache. Almost all the heavy-lifting is done by Fastly. At the peak, when both EMEA and North America are awake and at computers, 50 million requests per hour are cache hits served by Fastly's infrastructure, with a modest 20 million being misses passed down to our servers. There would be no Flathub without Fastly; Fastly does it completely for free, not even for fake Internet points as we are incredibly bad at highlighting what our sponsors do for us.

    image

    image

    You can't do enough cache, and so various Fastly servers talk to Fastly-managed shield server which caches the most requested objects to avoid spilling over too much to us. For legit cache misses, the request will be served by one of 8 caching proxies we are running at different VPS providers. We use a chash director at Fastly which will pick the backend based on the path being requested. In the past, we used a dumb round-robin but as a result, each caching proxy had its own independent copy of the working set, wasting disk space and producing a higher miss rate against the master server. Hashing by URL behaves like one big cache instead of N copies.

    These days, the caching proxy fleet consists of 3 servers at Mythic Beasts, 2 servers at AWS, another 2 at NetCup and a single server at DigitalOcean. We don't collect overly detailed metrics, but on average, each proxy serves around 1 TB/month back to Fastly and pulls roughly 5 TB/month from origin. With only 100 GB of disk space per proxy against a multi-TB working set, we're not so much caching the long tail as smoothing it. In the ideal world, we would be retaining much more data at this layer, but it's not the world we live in.

    Each of these servers is running the latest stable Debian release. The requests are served by the usual nginx setup with proxy_cache enabled. There is some custom Lua code for invalidating certain paths after publishing new builds finishes (spoilers!). Vanilla nginx doesn't support the PURGE method, and third-party modules like ngx_cache_purge have not seen any maintenance for over 10 years. In the end, it was more maintainable to write Lua code to calculate the caching key of a URL and then run os.remove to "purge" it from the cache.

    There's also a systemd timer for refreshing the Fastly IP allowlist. We used to expose these servers publicly, but a vision of everything crumbling down due to a DDoS attack kept me awake at night so this had to change.

    On the far end of this setup sits a lonely physical server living in one of the Mythic Beasts' datacenters. This is The Server holding the entire Flathub repo on an equivalent of RAID10 in ZFS world: two 2-disk mirror vdevs on which ZFS stripes data across. There is more nuance to this setup, but the ultimate advantage is that we can tolerate a disk failure in each of the mirrors, while being less taxing to resilver after a swap. The entire reachable data set is around 4TB of data, with the remaining 6TB unused. There will be more about the repository maintenance later on!

    Ironically, it's the only server running Ubuntu. At the time, it was the easiest way to have support for ZFS readily available. We could re-provision it to Debian, but on the other hand, what for? It works fine that way. It has survived at least 2 major upgrades between LTS-es; if it ain't broke, don't fix it.

    The master server itself has to be partially public as it's where new builds are being uploaded. It no longer exposes the raw Flathub repository for the same reason caching proxies don't. This is accomplished with Tailscale and a lightweight ACL config ensuring caching proxies can talk only to the HTTP server running on the main repo server and vice versa (for issuing PURGE requests). Yes, all involved parties have public IP addresses assigned so this could technically be pure WireGuard setup but I prefer to make this someone else's concern, especially given how generous Tailscale's free plan is.

    Flathub CDN topology

    It's not much, but it's honest work. For how little we have, the file-serving half of Flathub's infrastructure works unreasonably well. Stay tuned for part 2!

    • Pl chevron_right

      Christian Hergert: Translating French

      news.movim.eu / PlanetGnome • 15 May 2026 • 1 minute

    I have been spending more time learning French lately, and as often happens, that turned into a small side project. liblingua is not intended to be a big mainstream translation platform. It is a fun GLib/GObject library for experimenting with local machine translation from applications.

    The library uses Bergamot from Mozilla for the translation backend. Instead of sending text to a web service, liblingua resolves the language pair you ask for, downloads the required language model into the local user cache, and then performs translation locally.

    The high-level API is built around a few small objects: LinguaRegistry discovers available translation profiles, LinguaProfile represents a model that can be loaded or downloaded, LinguaProgress reports download progress, and LinguaTranslator performs the translation.

    All potentially blocking work is exposed as DexFuture , so it fits naturally into libdex based applications. If you are already using fibers, the code can stay linear and easy to read with dex_await_object() .

    A Small Example

    Here is the basic shape of translating French into English:

    #include <liblingua.h>
    
    static void
    translate_example (void)
    {
      g_autoptr(LinguaProgress) progress = lingua_progress_new ();
      g_autoptr(LinguaRegistry) registry = NULL;
      g_autoptr(LinguaProfile) profile = NULL;
      g_autoptr(LinguaTranslator) translator = NULL;
      g_autoptr(LinguaTranslation) result = NULL;
      g_autoptr(GListModel) profiles = NULL;
      g_autoptr(GError) error = NULL;
    
      if ((registry = dex_await_object (lingua_registry_new (), &error)) &&
          (profiles = lingua_registry_resolve (registry, "fr", "en")) &&
          (profile = g_list_model_get_item (profiles, 0)) &&
          (translator = dex_await_object (lingua_profile_load (profile, progress), &error)) &&
          (result = dex_await_object (lingua_translator_translate (translator, "Bonjour"), &error)))
        g_print ("%s\n", lingua_translation_get_translation (result));
      else
        g_printerr ("Error: %s\n", error->message);
    }
    

    The first time a model is needed, loading the profile may download it. After that, the model is reused from the local cache. That makes liblingua useful for little tools, demos, and desktop experiments where local translation is preferable to wiring everything through a remote service.

    In the future this is probably the type of thing we would want as a desktop service to avoid duplicating caches amongst Flatpak applications. It would also be extremely useful to do live translation in Camera and Image Preview apps. I played a bit with that using Tesseract for OCR and it worked better than expected.

    • Pl chevron_right

      GIMP: GIMP @ Linux App Summit and ADULLACT Congress 2026

      news.movim.eu / PlanetGnome • 14 May 2026 • 1 minute

    We have been trying to encourage contributors to be more present on various events, international or local. Here is where you will find someone from the GIMP team in the coming weeks:

    Linux App Summit 2026

    The Linux App Summit ( LAS ) brings the global Linux community together to learn, collaborate, and help grow the Linux application ecosystem.

    Linux App Summit 2026 banner Linux App Summit 2026, May 16-17, 2026 - Berlin, Germany

    It happens this week-end, from May 16 to 17 in Berlin, Germany, and we will have one person attending, Michael Schumacher , one of our long term contributor, as well as member of our Committee.

    Unfortunately our project did not submit a talk, but we are still interested to meet more of the desktop software ecosystem contributors and see what’s happening around us! So if you attend too and spot Michael, do not hesitate to go and speak with him. He will likely have Wilber stickers to distribute too! 😍

    10th Congrès ADULLACT

    The Congrès ADULLACT is a conference gathering elected representatives of French local authorities, to discuss Free Software usage in the public sector.

    10th Congrès ADULLACT 2026 banner 10th Congrès ADULLACT , June 4-5, 2026 - Montpellier, France

    Jehan, GIMP Maintainer, will be present there to showcase GIMP as a Community, Free Software. Obviously GIMP is already quite massively present in France, but as many Free Software, administrators and users alike may not realize how it is being developed, by whom, why and how. Nor do they know that it is being developed by a major part in Europe and more particularly in France. Since one of the two main topics this year is the digital sovereignty, this is quite a major stake in this context.

    The event happens from June 4 to 5, 2026, in Montpellier, France. As one can imagine, it is a close event for elected representatives and civil servants only, so if this is your case, we hope you will show up and Jehan will be happy to discuss with you!

    Jehan’s talk will be on Friday, June 5, 2026, at 14:20 (French time) and he will introduce GIMP as a “Free Software and Community” .

    We hope you’ll be many to attend! (oh and Jehan as well will have Wilber stickers, even though it may less a selling point in such a conference 😋)

    • Pl chevron_right

      Nirbheek Chauhan: An Esoteric Type of Memory "Leak"

      news.movim.eu / PlanetGnome • 14 May 2026 • 2 minutes

    A little while ago, my colleague Sebastian started complaining about OOMs caused by Evolution taking up tens of gigabytes of memory. We discussed using sysprof to debug it, but it was too busy a time for Sebastian to set aside a few hours to do that.

    Funnily enough, the most efficient fix at the time was to buy more RAM, since rust-analyzer was also causing OOM issues.

    A few weeks went by. Restarting Evolution had become a daily ritual for Sebastian.

    Then, on a whim, I decided investigating this might be a good test for an LLM.

    I updated my Evolution git repo, built it, and started up Claude Code in the source root. This was the only prompt I supplied:

    Find memory leaks in Evolution, current sourcedir. Particularly leaks that could accumulate over several hours. A colleague has a leak that slowly accumulates memory usage to several GB over the course of a day, requiring a restart of Evolution. That is the main focus, but we can fix other leaks in the process.

    I wish I was lying, but that was all Claude Code needed to find the problem: Evolution just needed to call malloc_trim(0) from time to time .

    I refused to believe it at first. I was only convinced when we saw the memory drop after running gdb -p $(pidof evolution) -batch -ex "call malloc_trim(0)" -ex detach

    This seems absurd! Doesn't glibc reclaim freed memory from time to time?

    Yes, it does. It calls sbrk() to do that. However, sbrk() can only reclaim free memory at the top of the heap, since it simply moves the program break downward to do so. malloc_trim(0) calls sbrk() and then also calls madvise(..., MADV_DONTNEED) on the free pages, which allows the kernel to reclaim them.

    So if you have 10GB of unused memory followed by 4 bytes allocated at the top of the heap, your RSS is >10GB, even if you're using a few hundred megs. Till you call malloc_trim(0) .

    Note that you can only get into this situation if you have hundreds of thousands of small allocs/deallocs happening repeatedly. If your alloc is >128KB, mmap() is used for the allocation, and none of this applies.

    Coincidentally, GLib's use of GSlice for GObject allocations was masking this issue in the past, but GSlice has been a no-op for some time now (for good reasons). Ideally, Evolution should not be using GObject for such ephemeral objects.

    Lesson learned: if you have memory usage issues and you suspect fragmentation, try malloc_trim(0) before you go thinking about fancy allocators .

    • Pl chevron_right

      Christian Hergert: Limiters in libdex

      news.movim.eu / PlanetGnome • 14 May 2026 • 2 minutes

    Libdex now has DexLimiter , a small utility for bounding how much asynchronous work runs at once.

    This is useful when a workload can produce more parallelism than the underlying machine, subsystem, or service should actually handle. Common examples include indexing files, downloading URLs, generating thumbnails, parsing documents, or querying a service with a fixed concurrency budget.

    The usual API is dex_limiter_run() . It acquires a permit, starts a fiber, and releases the permit when that fiber finishes.

    static DexFuture *
    load_one_file (gpointer user_data)
    {
      GFile *file = user_data;
    
      return dex_file_load_contents_bytes (file);
    }
    
    DexLimiter *limiter = dex_limiter_new (8);
    DexFuture *future = dex_limiter_run (limiter,
                                         NULL,
                                         0,
                                         load_one_file,
                                         g_object_ref (file),
                                         g_object_unref);
    

    In this example, no more than eight file loads will run at the same time, regardless of how many files are queued. The returned DexFuture resolves or rejects with the result of the spawned fiber.

    One important detail is that dropping the returned future does not cancel a fiber that has already started. Once work has acquired a permit, it is allowed to complete so that the limiter can release the permit cleanly.

    For more specialized cases, DexLimiter also supports manual acquire and release:

    g_autoptr(GError) error = NULL;
    
    if (dex_await (dex_limiter_acquire (limiter), &amp;error))
      {
        do_limited_work ();
        dex_limiter_release (limiter);
      }
    

    This is useful when the limited section is not naturally represented by a single fiber. However, callers must release exactly once for every successful acquire. In most cases, dex_limiter_run() is preferable because it handles release on both success and failure paths.

    The limit should describe the constrained resource, not the number of items being processed. Remote APIs and databases may need a small limit. CPU-heavy work should usually be near the amount of useful worker parallelism. Local I/O can often tolerate a larger value, depending on the storage system. Separate resources should usually have separate limiters, so one workload does not consume another workload’s concurrency budget.

    Finally, dex_limiter_close() can be used during shutdown. Once closed, pending and future acquisitions reject with DEX_ERROR_SEMAPHORE_CLOSED . Work that already holds a permit may continue, but releasing after close does not make new permits available.

    The goal is to make bounded parallelism simple: queue as much asynchronous work as you need, but only run as much of it as the system should handle.

    • Pl chevron_right

      Christian Hergert: A Small Update from France

      news.movim.eu / PlanetGnome • 14 May 2026 • 2 minutes

    For about the past month, I have no longer been with Red Hat.

    That is a strange sentence to write after so many years, but life has a way of changing the scenery whether or not one has finished packing. My family and I have made it safely to France, and we are quite happy here. The light is different, the pace is different, and there is a great deal to learn. For now, that is exactly where our attention needs to be.

    I also think there is a broader lesson here for people whose safety, immigration status, or family stability may depend on employer flexibility. Do not assume that long tenure, remote work history, or prior verbal guidance will be enough. My own experience left me with the uncomfortable conclusion that these processes can become very narrow exactly when the human stakes are highest. Get things in writing, understand the policy surface area, and protect your family first.

    This also means that some of the things I wrote about in my earlier mid-life update remain unresolved. I am currently in France on a visitor visa, which does not authorize work here. Our focus is on integration, language learning, and getting ourselves properly settled for the long term. That takes time, patience, paperwork, and a certain tolerance for being a beginner again.

    As a result, I will not be taking on ongoing software maintenance responsibilities for the foreseeable future. I may still scratch the occasional itch where it directly improves my own computing life, but I am not currently able to provide the kind of broad, sustained stewardship that many projects deserve.

    That is not an easy thing to say. Open source is entering an especially difficult period. We are now seeing AI systems used not only to generate code, but also to probe, disrupt, and attack critical software infrastructure. I suspect this will have a negative effect on the maintenance burden for a lot of projects, particularly the foundational pieces that distributions, companies, and users all rely on without always seeing the people behind them.

    But there is a limit to what can reasonably be carried as unpaid labor, especially when the primary financial beneficiaries are downstream organizations with considerably more resources than the individual maintainers doing the work. At the moment, I need to prioritize my family, our stability, and the next chapter of our life here.

    That said, I am still reachable for appropriate professional inquiries, advisory conversations, or consulting opportunities where the structure and location make sense. The best address for that now is christian at sourceandstack dot com .

    For now, we are safe, settling in, and doing our best to build something durable out of a rather odd moment in the world. There are worse places to begin again than France.

    A calm Mediterranean shoreline at sunset, with gentle waves rolling onto a pebbled beach beneath a wide blue sky streaked with soft clouds and pastel pink light on the horizon.

    • Pl chevron_right

      Laureen Caliman: Introduction Post

      news.movim.eu / PlanetGnome • 13 May 2026 • 3 minutes

    May 13th, 2026

    My name is Laureen Caliman, and I am a contributor for GNOME Crosswords with Google Summer of Code 2026. Crosswords are a stimulating challenge that promotes engagement in education . Computing systems are now an indelible factor of daily life, which has raised concerns on maintaining attention, long-term memory, and reinforcement of knowledge in K-12. One study was performed in Indonesia to teach students English using crosswords. A measurable improvement in the students’ coherence to the foreign language material was seen, demonstrating benefit to their education.

    Unlike traditional crossword grids which are rigidly defined, vocab-style puzzles are fitted using algorithms to shape them together. Users will have the option to edit their crossword in the Editor, and open it in Crosswords. My project entails adding the proper backend and frontend support to create vocab-style crossword puzzles.

    My mentors are:

    • Jonathan Blandford
    • Federico Mena Quintero

    About Me:

    I am an incoming Computer Engineering student at Rose-Hulman Institute of Technology. I also teach K-12 computer science, so I really relate to this project’s mission about bridging software with education.

    I am eager to contribute to this community and learn more about the inner workings of GNOME. I intend to continue contributing to GNOME for a long time after this project finishes!

    GNOME Crosswords:

    Jonathan Blandford presented an in-depth overview of the history of GNOME at GUADEC 2017, which is available to watch here . Blandford also presented Crosswords to the 2024 GUADEC here .

    Crosswords consists of two domains:

    • The Crosswords Editor , which is a tool to create and edit crossword puzzles.
    • The Crosswords Game , which is where the user plays crossword puzzles.

    My project will see to both: the editor for a user to create the puzzle, and the game platform to play it. They will also have the option to print their game in black and white using Cairo Graphics.

    Technical Challenge:

    Traditional crosswords have a stable grid ready for play; the vocab-style crossword will be weaving words together in the most logical way upon a blank canvas. My project focuses on building the algorithm which will take in words and distribute them to form a connected puzzle.

    The biggest challenge is ensuring the program doesn’t get stuck. As it places words on the board one-by-one, it has to follow strict rules:

    • The words must be interlocked and aligned.
    • The whole puzzle must be connected as a single piece.
    • Words cannot form gibberish with their connecting path or neighboring words.
    • The grid must also not enter a permanent hangup trying to fit clashing words together.

    Approach:

    I will be splitting the work across the backend logic and frontend UI to make a presentable and functional puzzle.

    This program will use an algorithm to deal words. Upon a rule violation, it will backtrack to find an adequate fitting by reversing itself, deleting unideal portions of the current layout, and reseeding words differently. Essentially, it places a word on the grid, tests the board with another word, and if it hits a wall, the board cleanly undoes that path until it finds another valid one. This will continue until all words are fitted together and simultaneously satisfies the constraints.

    The frontend will contain stateless widgets that render with the flow of the grid. The widgets should simply read the state without mutating any data.

    This trial-and-error approach will afford the program the ability to test combinations until it finds a perfectly fitting, playable crossword puzzle!

    Currently, we are in the “Community Bonding Period” (May 1st-24th), and I have been communicating consistently with Jonathan Blandford to refine the approach and implementation. To gain practice, I have been working on this merge request for applicable practice towards my GSoC project.