You are here

Planet GNOME

Subscribe to Feed Planet GNOME
Planet GNOME - https://planet.gnome.org/
Përditësimi: 2 ditë 9 orë më parë

Martin Pitt: Syncing Gmail with mbsync using OAuth2

Dje, 16/08/2026 - 2:00pd
I wholeheartedly dislike GMail (ethically, technically, and UX), and for my personal email I have always run my own server. But for work email I don’t have a choice. I am using isync/mbsync to make it usable for me and mutt. Until now I’ve used a Google app password to authenticate, but they are a security nightmare. OAuth2 is a better way. Sadly the interwebs have only scarce, outdated, or buggy recipes, so I finally spent the better part of an afternoon and moved OAuth2.

GIMP: Development Update, August 2026

Dje, 16/08/2026 - 12:00pd

For the past few months, we’ve been developing all kinds of features for the future GIMP 3.4 release. We noticed recently that our changelog was getting quite long - a good problem to have!

While there’s been a lot going on internally, it’s been a while since we made a public progress report. So we want to share details on some of the new features and UX improvements that’ll be available in the first development release, GIMP 3.3.2. This won’t be an exhaustive list (we have to save at least some news for the release itself!) but hopefully it will give you some insight into the current direction and progress of GIMP’s development.

New Project File Format

The big focus for maintainer Jehan recently has been developing a new project file format for GIMP.

XCF has been GIMP’s primary project format since 1997, and it has served many users well. Over time however, we’ve observed more and more limitations of the binary XCF format. Among other issues, it does not easily support very large or complex projects, such as the multi-page and animation features currently planned for GIMP 3.6.

The new project file format will follow a more common “zipped XML” structure. While the technical details are still being designed and implemented, this change will allow for faster saving since we’ll only need to update parts of the file instead of the whole thing each time. It will also set the stage for much desired features such as auto-saving, which will now be much more feasible.

That said, XCF is not going away! Backwards compatibility is important to us, and we will continue to support loading XCFs in all future versions of GIMP. (For instance, we’re quite proud that a XCF file made by a small company for their logo in 1998 still renders the same way in the latest version of GIMP)

However, going forward we will only add support for saving/loading new features in the new project file format once it is finalized.

MyPaint Brush: Spectral Blending

During GIMP 3.2’s development, we upgraded to a newer version of the MyPaint brush engine. While this brought new brushes and canvas interactions to the MyPaint Brush Tool, one feature that was left out was Spectral Blending.

Spectral Blending simulates the effects of blending physical pigments in digital art. For example, blending yellow and blue will produce a green color instead of darker yellow, and blending red and yellow will create an orange mix.

Fortunately, new contributor Cassidie Grogan picked up the slack and implemented this feature. There is now a Spectral Blending checkbox in the MyPaint Brush Tool Options. If checked, the new blending method is used. You can control the strength of the blending with the Pigment slider.

Demonstration of MyPaint Spectral Blending


In addition, maintainer Michael Natterer improved the MyPaint Brush preview code to display at their full size instead of 48x48 pixels. This fixes an issue where the previews appeared blurry on larger screens.

Non-Destructive Editing

Alx Sa has continued making updates to our non-destructive filter code. To list a few:

You can now apply filters non-destructively to Layer masks! To go along with this, the filter popover has been redesigned by Reju to show the active filters for both the layer and its mask, so you can interact with both on the same screen.

The Gradient Tool can now be used non-destructively! If you check Editable Gradient in the Tool Options, the gradient you create will be added to the filter stack like any other effect. You can toggle its visibility, rearrange its position in the filter stack and delete it. You can also edit the gradient, which will switch back to the Gradient Tool to let you make further changes.

User interface with a live Gradient filter on the layer, and a live filter on the layer mask

Filters without dialogs (such as Invert) can now be applied non-destructively on non-raster layers such as layer groups and link, text, and vector layers.

PSD Support Improvements

Normally we list all file format updates in a combined section, but there has been so much work done on PSD support (and by so many people) that we wanted to highlight it in more detail.

First, new contributor Frank Teklote has been busy improving our compatibility with PSDs. His big project for this release was creating a PSD metadata export procedure for TIFFs and JPEGs. This complements our existing PSD metadata import procedure, meaning that if you import a JPEG with paths or a TIFF with layers (or create one in GIMP), that information can now be retained in the exported image.

Another great thing about Frank’s work is that as we continue to improve our PSD compatibility, the TIFF and JPEG export features will automatically get those updates too!

Related to that, Jacob Boerema has implemented PSD Descriptor import support. Most of our current PSD support has been based on the public Adobe specification. This document was last updated in 2019 however, and modern PSDs use a relatively undocumented text format called Descriptors to store many features.

Now that GIMP can read descriptors, we’ve begun drastically improving our PSD import support. To list just a few updates: text layers are now editable, a number of adjustment layers and modern layer styles appear as their GEGL equivalents, and solid color shapes are imported as vector layers. This is an active area of development, including by two of our GSoC students Akascape and Waris Maqbool. We hope this work will make it easier for GIMP users to interact with existing PSD projects!

Editable PSD text layers in GIMP Native File Chooser Dialogs

We have always used the file chooser dialog provided by the GTK GUI library for people to find, load, and save files in GIMP. While the file chooser does the job, it often works differently than the “native” file chooser on non-GNOME platforms like Windows, macOS, and KDE. Additionally there have been some changes to the UI of this dialog in GTK3, which has inspired some strong feedback in our issue tracker!

Therefore, Alx Sa has begun porting GIMP’s file choosers to the “native” option provided in GTK3. This means that when you open or save a file, you will see your platform’s standard file chooser dialog instead of the GTK dialog (unless your platform uses that already, in which case there will be no change!)

Example of native file chooser on macOS, by Bruno Lopes

Many of the simple dialogs have already been converted. Those with more complex additional features will require some workflow redesigns, which we’re still developing.

User Experience and Interface Updates

A lot of new and existing contributors have submitted improvements to GIMP’s user interface and its user experience. We wanted to highlight their efforts, and encourage you all to continue sharing your feedback on our design issue tracker.

Designer Denis Rangelov has been hard at work updating GIMP’s UI icons. He recreated our layer lock icons to create a more consistent look.

He also took on the monumental task of converting all 78 of our cursor icons to SVG, which will allow us to scale them for higher resolution displays without losing quality!

Original Raster Cursor Denis’s Vector Cursor Example of original and vector cursors


There have been reported performance issues when drawing or zooming into the canvas when the canvas view was rotated. New contributor woot000 diagnosed the problem and created a fix. Now the “checkerboard” transparency pattern no longer rotates when the canvas does, which significantly boosts performance when painting or editing. They also fixed a related issue where the checkerboard pattern would disappear when zooming into the canvas past a certain point.

Gabriele Barbero implemented a redesign of the Search Action UI which was designed by Denis Rangelov. The new layout makes the associated shortcut key more visible, and is more consistent with the menu layouts.

Bruno Lopes has been working to fix issues with pop-up dialog displays on macOS. Since traditionally we have fewer macOS developers compared to other platforms, we’re really happy to see improvements for these users!

New contributor Andreas Vukman improved our Pattern dock display. Now smaller patterns tile to fill the available space, creating a consistent preview for all patterns instead of having some patterns display with odd amounts of padding. We think it makes the dock look much nicer!

Richard Gitschlag has updated the on-canvas text editor to allow selections when you Shift+Click in the text. It should now work similar to what you can do in a word processor like LibreOffice.

In previous versions of GIMP, you imported or exported metadata from the Metadata Editor by selecting an option in a dropdown. Ahmed E. Yassin has made this process more intuitive (and more consistent with the rest of GIMP’s UI) by replacing the dropdown with two buttons instead.

Ondřej Míchal reviewed several portions of GIMP’s UI and replaced many instances of the Spin Entry widget with Spin Scale. The Spin Entry widget is difficult to use when the width is shrunk, so this change improves usability in many areas of the UI.

Assorted Changes and Fixes

Our four GSoC interns have been continuing their work since the midpoint update. Recently, Waris Maqbool‘s Sharpen filter was merged into GEGL, so it’ll be available in the next GEGL release.

New contributor Dimitriy Ryazantcev has submitted several patches for improving our Windows ICO/CUR/ANI support. They’ve already fixed the rendering for certain 32bit ICO formats and made our loading and preview algorithms better match the Windows specification.

Estecka has fixed a rendering issue when applying NDE filters on passthrough layer groups, which made the image look different depending on whether the group had child layers or not.

New contributor Petr Vorel fixed a bug where pressing Alt+0 did not open the tenth most recent image in your history.

Lloyd Konneker, our main Script-fu contributor, fixed a regression in third party scripts where the number range for certain parameters wasn’t shown in the GUI.

Jacob Boerema and Alx Sa have responded to and patched a number of security reports about potential flaws in some of our image plug-ins.

What’s Next

There’s more in-progress work that we look forward to sharing with you all soon!

There is not an official 3.3.2 development release yet, as several roadmap items are still in-progress. If you’re feeling really adventurous and just can’t wait, you can try our “nightly” builds. Instructions are under the Automatic Development Builds header.

In the meantime, we are planning to release GIMP 3.2.6 in the coming weeks. It is a stable release so it won’t include many of the new features described here. However, it will have a number of important bug fixes and small improvements. We’ll discuss these more in the 3.2.6 release news post!

Philipp Sauberzweig: Fellowship Update, 2026-08-13

Enj, 13/08/2026 - 7:40md

It’s been about a month since I started my Sovereign Tech Fellowship in mid-July, and I want to give you some updates about what’s been going on before I go on summer holiday for the next two weeks. The idea behind these update posts is to highlight certain aspects of my activities and get people interested in getting involved with design.

GUADEC 2026 This year I attended GUADEC in person for the first time and I really enjoyed it. There were three days of interesting talks followed by two days of productive workshops and hacking. My favorite talks were about:

I gave a short update on the GNOME Design Team’s recent achievements and challenges, announced my fellowship and invited interested individuals to join us. Tobias and I lead the Design BoF where we discussed some recent design pattern standardization efforts and received helpful feedback from the audience. Furthermore, the discussions in between talks and workshops were an amazing opportunity to connect with other contributors.

I was not able to attend GUADEC in the past because of the locations, but also because of high travel costs. The GNOME Foundation provides travel sponsorships, and this year’s budget was not used completely. Please reach out to the Travel Committee if you are a contributor and need financial support to attend conferences and hackfests.

Kicking Things Off

Traveling to GUADEC marked the start of my fellowship, and the weeks after that I was pretty much busy with kicking off things of various kinds.

Internal

As an employee of the Sovereign Tech Agency, I went through the onboarding process, set up hardware and software tools, and got to know the team. The 2026 cohort of the Sovereign Tech Fellowship comprises 14 people from a variety of different projects, which provides an amazing opportunity to share knowledge and establish cross-project collaborations. I am responsible for organizing a monthly ‘Lightning Talks’ series, in which fellows give short presentations on topics of broader interest, with the intention of leading to longer peer mentoring sessions. For my own presentation, I chose to talk about This Week in GNOME, the GNOME project’s weekly blog that covers news from the community. I believe it is a major success because it enables our community members to share project news without having to set up their own blog. The numbers speak for themselves: a total of 2,643 news posts have been submitted by 335 individuals over a period of 261 weeks. I would like to take this opportunity to thank Felix Häcker for developing ‘This Week in GNOME’ and for curating a weekly post for more than four years.

Design

There are a few design patterns we have wanted to standardize for a while. These include Action Rows with a scale, time and date pickers, drag and drop target styling, and floating controls. I discussed with Alice which ones to prioritize and started with Action Rows with a scale. If your app uses a scale in an Action Row in a way that hasn’t been mentioned in the issue yet, please leave a comment with a screenshot. You are also welcome to contribute state-of-the-art examples from other platforms.

Another topic I plan to work on is the credentials portal and I’ve had a first video meeting with the maintainers of credentialsd to coordinate our timelines and clarify the requirements.

I also reviewed a few merge requests and provided some design feedback in issues and on Matrix. One topic I find particularly interesting and worth sharing is adjusting arbitrary colors to ensure contrast of the event widgets in Calendar. Other apps that have to handle arbitrary colors (e.g. user-selected colors) in the user interface might benefit from looking into using the oklab color space too. Alice has published a blog post about the CSS capabilities which helped me to figure out the proposal for Calendar.

Community

I’ll soon begin reviewing apps for GNOME Circle, and I’ve already had an onboarding meeting with Tobias from the Circle Committee and another interested contributor. My plan is to support new reviewers through peer reviews and feedback so they can gain experience in GNOME design.

I attended a video meeting about Test Center, a new app for installing experimental versions of apps and system components. It makes testing much easier, and I see some potential for newcomers to get involved through coordinated user testing.

Until now, I’ve never had the time to blog about my design work for GNOME, but I’ve finally set up this blog and have been really enjoying it so far. Since this is my first time blogging, I’d appreciate any feedback via Matrix.

Thanks for reading. I’ll be back in September after my holiday.

Jussi Pakkanen: Digitizing super 8 film yourself

Mër, 12/08/2026 - 11:53md

In our previous post we looked at fixing a super 8 film projector. While watching filme with a real projector has its own charm, it is inconvenient to say the least. First of all you make the entire room properly dark or you can't see anything. This is regardless of the fact that the projector bulb is consuming 100 watts of power to show the image. Even if you manage not to burn the film merely running it through the projector causes wear, scratches and tearing. While film typically ages very well, eventually it will turn into magenta goop or gets eaten by vinegar syndrome. Thus you'd really want to convert all these films into high quality digital files.

There are several companies that offer this service. If you only have a few rolls, using those is the smart thing to do. I, on the other hand, have so much material that using a commercial service would cost thousands (possibly tens of thousands) of euros. Fortunately, this is a fairly common problem and there are dozens of existing projects on the Internet to be inspired by. 

The main technical problem with super 8 film is that it is very small. A sequence of 10 super 8 images is approximately as long as a matchstick. The fact that projectors can display 18 frames per second with sub millimeter registration is an astounding achievement of mechanical engineering. How do they do that? Very difficultly.

Many of the DIY solutions start by taking an existing projector and modifying it to run slower. Then you remove the projection lens and aim a digital camera with a macro lens at the gate. This yields incredible results quality-wise but requires a fairly expensive macro lens and typically the modification on the projector is destructive. So that's out. Some more searching eventually lead me to this Github project.

The basic idea is simple. Instead of using a projector or trying to replicate a film transport (which proper tension and all that) instead rely on the basic stiffness on film and drive it directly with stepper motor. Film is not aligned mechanically but instead by detecting the sprocket hole with some straightforward machine vision code. Time to fire up the ol' 3D printer and order components. This is what the end result looks like after assembly

The thing at the top left that looks like a space cannon prop from a scifi movie is actually a microscope lens. Not only can it do > 1x optical magnification, it can do so at a cost of about 25 euros. The downside is noticeable chromatic aberration. The small flat thing on the other end is the Raspberry Pi HQ camera module that can do 4k at 12 bits per channel. The whole thing is run via a single Raspberry Pi 3 with a stepper motor hat. The board at the bottom is used to distribute 12V DC power to the lamp and motors.

Before going further, let's just spend some time appreciating just how awesome colors look in this film. Props to the chemical engineers at Kodak. And remember, the original image is about one third of the size of your smallest fingernail.

The Github repo says that you probably need to adapt the code to your setup. I basically ended up rewriting all of it from scratch. In the process I learned that OpenCV has its own GUI toolkit which is both simple (one could even say simplistic) and perfect for this use case. The first attempt took nine hours to process one 3.5 minute reel of film. Then I realized that trying to do 4k on material that physically maxes out at approximately 2k with the processing power of a potato is not a recipe for success. Halving the capture resolution and a few other optimizations brought the runtime down to about one hour per reel.

With this, some more custom software for image processing and stabilization coupled with FFmpeg scripts one can start to go through the archive of films. Doing so raises a fair bit of questions. For example:

Is that a 3 year old child driving a jury-rigged go-kart on a frozen lake on his own without even wearing a helmet?

Yes it is. A bit later a grown up drives the car but he is too heavy so the ice cracks under him. No one seems particularly concerned. This may seem strange to us but you have to understand that this was the very early 70s. The concept of safety had not been invented yet.

Peter Eisenmann: Fellowship Report July 2026

Mër, 12/08/2026 - 2:44pd

Hi, I’m Peter, a software dev and currently a maintainer of nautilus, the GNOME project’s file manager.
This blog will foremost contain monthly updates on what I did as a GNOME Fellow.

# The Fellowship

> The [GNOME Fellowship program](https://fellowship.gnome.org/) provides financial support for critical and under-resourced areas of the GNOME project.

In July [Sophie Herold](https://blogs.gnome.org/sophieh/) and I were selected as the first GNOME Fellows.
I am very grateful to everyone that put effort into launching this program and hope we will be able to use this great opportunity to provide impactful contributions to the project.
My work will mostly focus on nautilus, its file chooser capabilities, and its integration into the system.
I have a vague roadmap of things I want to achieve in this year of Fellowship:

![progress chart july](/p3732/files/2026/08/0726-chart.png){width=100%}

I also have aspirations of doing things beyond the listed items, but this roadmap will provide a nice, feasible baseline.

# XDG Directory Localization
If you have ever used GNOME with a non-English localization, you will probably be familiar with this little dialog:

![current xdg-user-dirs-gtk dialog](/p3732/files/2026/08/xdg-gtk3.png){width=100%}

It not only interrupts you out of nowhere on session start, it also looks somewhat dated, given it still uses GTK3.
Corey Berla [ported it to GTK4](https://gitlab.gnome.org/GNOME/xdg-user-dirs-gtk/-/merge_requests/13), but also sprinkled some libadwaita usages in, making the port unfit for a generic GTK program.
For modern GNOME styling we of course want libadwaita, so I took the port and [integrated it into nautilus](https://gitlab.gnome.org/GNOME/nautilus/-/merge_requests/1831).

![current state of integrated dialog](/p3732/files/2026/08/0726-xdg-integrated.png){width=100%}

This standalone dialog is shown when opening nautilus and is integrated into nautilus’ bookmark system.
There are more opportunities to improve the user experience though, so expect another update on this in the coming months.

# Sushi
Sushi is nautilus’ previewer companion.
When installed, it can be activated by pressing `Spacebar`.
It is a very versatile tool that can preview many different file types.

In May I decided to push sushi’s development forward, by landing [Corey Berla’s GTK4 port](https://gitlab.gnome.org/GNOME/sushi/-/merge_requests/43) along with [Tau Gärtli’s fix-up](https://gitlab.gnome.org/GNOME/sushi/-/merge_requests/68) and further porting commits.
Throughout June, Tau, Lorenzo Ubaldi, and I made many other adjustments, modernizations and cleanups to sushi.
This continued throughout July, and I believe the application is now again in a state where it lives up to the standards of a modern GNOME application.

![Sushi version 51 screenshot](/p3732/files/2026/08/sushi-v51.png){width=100%}

More detail on changes I made in July (selection):
* [Smoother view changes](https://gitlab.gnome.org/GNOME/sushi/-/merge_requests/122) and a loading spinner
* [Reworked overlays](https://gitlab.gnome.org/GNOME/sushi/-/merge_requests/124) and hid headerbars in fullscreen
* [Documented plugins](https://gitlab.gnome.org/GNOME/sushi/-/merge_requests/113) and a new system-wide plugin path
* [Fixed some](https://gitlab.gnome.org/GNOME/sushi/-/merge_requests/114) [memory leaks](https://gitlab.gnome.org/GNOME/sushi/-/merge_requests/121) to reduce memory usage (unfortunately there are still some left)
* [Added clicking/tapping](https://gitlab.gnome.org/GNOME/sushi/-/merge_requests/109) pausing/fullscreening support for videos
* Small [headerbar polish](https://gitlab.gnome.org/GNOME/sushi/-/merge_requests/123)

# Other
I also wrapped up [two](https://gitlab.gnome.org/GNOME/glib/-/merge_requests/5193) [minor](https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4919) GLib MRs this month.
They added [`g_set_date_time`](https://docs.gtk.org/glib/func.set_date_time.html) and [`g_string_free_deep`](https://docs.gtk.org/glib/method.String.free_deep.html), two convenience functions that will be available in GLib version 2.90.

# Support the GNOME Project

![GNOME Donation graphic](/p3732/files/2026/08/donate-card.png){width=80%}

The GNOME Fellowships are funded by our community. If you would like to help the GNOME project to stay sustainable, please [consider donating](https://donate.gnome.org/).

AI Summary

The described story is set in a magical underwater world where a fellowship of gnomes sets out to calm the eldritch nautilus god.
In this chapter they provide an offering of sushi, but the nautilus is not satisfied.
They craft a roadmap to localize the magical XDG creature.

Important note: All statements in this blog are fictional.

![footer](/p3732/files/2026/08/hobbit-footer.png){width=100%}

Asman Malika: My First GUADEC: From Kenya to the GNOME Community

Mar, 11/08/2026 - 4:18pd

I honestly wasn’t sure I was going to make it to GUADEC.

For months, the travel committee and I had been going back and forth trying to get all the documents needed for my visa application. The visa took longer than expected. I even lost hope at some point, and eventually got it just four days before my travel date.

This was my first GUADEC, and I was really looking forward to finally meeting the GNOME community in person.

I was also going to give a talk about my Outreachy project, which was probably something I should have been more nervous about than I was.

So between getting everything ready at the last minute, travelling from Kenya to Spain, and preparing for my talk, there was quite a lot going on.

But I made it to A Coruña.

Appreciation

I want to appreciate the people who made it possible for me to be there.

A big thank you to the GUADEC organizers and volunteers for all the work they put into making the event happen. I know there is a lot of work that goes on behind the scenes, and I really appreciate the time and effort that went into making everyone feel welcome.

I also want to especially thank the travel committee. I know the visa process wasn’t straightforward, and they spent months helping me get the right documents together and working through everything with me. Getting the visa just four days before my trip made the whole process even more stressful, so I really appreciate that they didn’t give up on it.

And of course, I want to thank my mentor, Lucas Baudin, for the support and guidance throughout my Outreachy internship. Having someone to learn from and ask questions along the way made the experience much easier.

Meeting the GNOME Community

This was probably the part I was most excited about.

For months, I had interacted with people through GitLab, Matrix, emails, and meetings, and it felt so nice to finally meet them in person.

I got to meet contributors from different parts of the GNOME community, and I loved hearing about what everyone was working on. Some conversations were technical, some were about the community, and some had absolutely nothing to do with GNOME.

I came to GUADEC wanting to meet the community.

I definitely did.

Sharing My Outreachy Experience

I also got the opportunity to speak about my Outreachy project during GUADEC.

During my internship, I had been working on Papers, improving its document signing features. Most of the work happened from my laptop in Kenya, so being able to stand in front of the GNOME community and share what I had been working on felt a little strange, in a good way.

Outreachy gave me the opportunity to contribute to a project I hadn’t worked on before, but it also taught me a lot about working in an open source community.

Giving the talk was definitely one of the highlights of GUADEC for me. I was a little nervous before getting on stage, but once I started, it felt much easier than I had expected.

What I liked most was the conversations afterwards. Different contributors came up to ask questions and share their thoughts, and it was really nice to continue those conversations outside the presentation.

Learning and Sharing

Throughout the conference, I attended talks covering a wide range of topics, including GNOME development, design, accessibility, and the future of the project.

I got to learn about projects I had never come across before, which was one of the things I really enjoyed. There was always something new to discover.

I also appreciated seeing how diverse the GNOME community is, and how much the community cares about making GNOME a welcoming and inclusive space for people from different backgrounds. Coming from Kenya, it was especially nice to see people from different parts of the world coming together around the same project.

Bringing the Experience Back to Kenya

Returning home, I wanted to ensure that the knowledge and inspiration I gained at GUADEC would benefit others as well.

I recently started the GNOME Kenya community, where we hope to introduce more people to GNOME and open source contribution. We are beginning with translation efforts while also encouraging contributors to explore development, documentation, design, and other areas that match their interests.

We are also having our first meetup soon, where we will officially introduce GNOME Kenya and GNOME to the community in Kenya.

My goal is to make GNOME more accessible to new contributors in Kenya and help build a sustainable local community that contributes back to the global project.

Looking Ahead

I came back from GUADEC with a lot to think about, and even more excitement to keep contributing to GNOME.

 I look forward to contributing more, supporting new contributors, and hopefully attending future GUADECs, InshaAllah!

Laureen Caliman: Vocab-style Crosswords Update | Final Stretch

Mar, 11/08/2026 - 12:29pd

The timeline for Google Summer of Code is coming to an end, and us interns are piecing together the final touches to our projects for submission. Thanks to the help of my mentors, and the duck sitting on my monitor, the algorithm that beats the heart of Vocab Crosswords in GNOME Crosswords has been tremendous strides in accuracy and testability. The primary focus shifted to getting the algorithm landed by the end of the summer, and working on the frontend of the application post-GSoC.

Unit Tests

At GUADEC, with the help of Federico, I created unit tests to see how my functions reacted in a given circumstance. Jonathan and I worked on creating different circumstances for the run and helper functions.

Optimization

For user optimization, we don’t want to keep the board at a strict 30×30 grid and only allow for the first viable option. We decided to incorporate a new function to trim the dimensions of the generated grids based on the outermost edges of the letters, create a new board based on the newly calculated dimensions, trim that board down respectively, and copy the words over in the exact respective format. This is due to the libipuz grid’s origin point (0, 0) being fixed at the uppermost left corner cell. All in all, the trimming function essentially does this:

Additionally, it is pretty ideal to have some leeway of choice on how you want your puzzle to look. Some puzzles might generate lanky, while others extensively branched out all the way to the maximum borders, and the rest perhaps condensed together. The ability to rearrange the ordering of the words is already a feature in Crosswords thanks to PuzzleTask. But, it is for known grids of typically 15×15 sandwiched together. What is different with the vocab puzzle is that the rearrangement must still respect the same constraints of intersecting at a single letter nodal point, words cannot be on top of nor right next to each other (edge of nodes must respect space), and no islands (all words must share at least one node with another word). For instance, grids A and B here pertain the same words 1 through 6, but these words can connect differently on the graph, producing two options to choose from.

Tested, I achieved these 3 different versions of grids based off the same word bank:

           

Island Checking

The final component I will implement within GSoC’s timeline is checking for islanding words. Say a user provides a list of words and one word absolutely cannot intersect with any other word, it shares no node. The backtracking algorithm will spend a lot of time trying to place it, or invalidate any graph generation at all. We want to check beforehand if a word would not belong along the rest, and warn the user about it. Because there are many alphabets that exist, we are going to analyze the sets of characters as guint64 bitsets and GHashTable. Every unique character gets its own bit-slot, and every word’s 64-bit mask is compared to available words using bit operations.

Hylke Bons: NLnet funds SparkleShare

Hën, 10/08/2026 - 2:00pd

I’m happy to announce that the SparkleShare project will receive a grant from the NLnet Foundation’s NGI0 Commons fund!


SparkleShare and NGI0 Commons Sync files with Git

SparkleShare is a Free and Open Source collaboration app. It allows people who are not software developers or otherwise technical (designers, lawyers, students, academics, etc.) to work together and share files in projects that use the Git version control system.

SparkleShare provides an automatic sync algorithm and a friendly user interface to review changes and restore files from history.

What happened?

SparkleShare has been around since 2010. I guess that makes it an “old” project now… Since then, the Mono/C# community active around that time has all but disbanded. The platform underneath slowly started to rot.

Eventually the app had to be removed from Flathub, also due to my own maintainer burnout. Providing maintenance and support next to a full-time job proved too much.

But that’s no longer an issue.

Now I have an opportunity to rebuild and address long-standing issues and feature requests. I have renewed energy to bring back the project better than ever!

The work

The funding proposal is to finish porting to Rust, bring SparkleShare in line with modern security and privacy practices, and design a fresh user interface informed by years worth of community feedback.

The goal is to get a Linux release back on Flathub. I’m planning to post frequent updates, so subscribe or follow me on GitHub or the Fediverse.

Ivan Molodetskikh: Easy Sandboxing on Linux with Bubblewrap

Dje, 09/08/2026 - 6:51md

In these turbulent times, one frequently needs to run some tooling in a sandbox. The goal is mainly to reduce the blast radius: make it so programs within the sandbox cannot damage the host system (e.g. delete or overwrite something unintended), but also, to a lesser extent, to hide most of the filesystem to avoid exfiltrating sensitive data.

Recently, Bartosz Taudul (of Tracy fame) showed how to use systemd-nspawn for this purpose. He creates a container configuration, installs a distro inside, and bind-mounts some cache and project folders from the host. The mounts have an overlayfs on top, so within the container, tools can write over the files, but those writes do not affect the host filesystem.

I also want to share my sandboxing approach. My goal was to make it easy to use and reduce friction as much as possible, so that I always have a sandbox at my fingertips.

The result boils down to spawning a container-like environment, sharing enough of the host filesystem read-only to make all host binaries runnable, and sharing the current working directory read-write. Within this sandbox, you don’t need to install a separate distro—everything from your host just works, while the filesystem is kept mostly isolated (except for the folder where you run the sandbox).

For example, I’ll run the script in a Tracy checkout.

┌ ((8c8d451a)) ~/s/c/tracy └─ box fish Welcome to fish, the friendly interactive shell Type help for instructions on how to use fish yalter@sandbox ~/s/c/tracy>

I can run the build since all my host binaries are accessible:

yalter@sandbox ~/s/c/tracy> meson setup build The Meson build system Version: 1.11.2 Source dir: /home/yalter/source/cpp/tracy Build dir: /home/yalter/source/cpp/tracy/build Build type: native build Project name: tracy Project version: 0.13.1 C++ compiler for the host machine: /usr/bin/ccache c++ (clang 22.1.8 "clang version 22.1.8 (AerynOS)") C++ linker for the host machine: c++ ld.lld 22.1.8 Host machine cpu family: x86_64 Host machine cpu: x86_64 Checking if define "_MSC_VER" exists: NO Run-time dependency threads found: YES Found pkg-config: YES (/usr/bin/pkg-config) 2.5.1 Build targets in project: 1 Found ninja-1.13.2 at /usr/bin/ninja yalter@sandbox ~/s/c/tracy> ninja -C build ninja: Entering directory `build' [2/2] Linking target libtracy.so

The home folder contains the working directory, and is otherwise mostly empty:

yalter@sandbox ~/s/c/tracy> ls -l ~ total 0 drwx------ 4 1000 1000 80 Aug 9 20:20 source/

I can write into the home folder, but the write will go into a tmpfs, and will not affect the host system:

yalter@sandbox ~/s/c/tracy> touch ~/evil yalter@sandbox ~/s/c/tracy> ^D ┌ ((8c8d451a)) ~/s/c/tracy └─ cat ~/evil cat: /home/yalter/evil: No such file or directory

Only changes to the Tracy folder, where I ran the sandbox, persisted on the host, all with correct user ID and everything:

┌ ((8c8d451a)) ~/s/c/tracy └─ ls -l build/ total 28K drwxr-xr-x 1 yalter yalter 48 Aug 9 20:21 libtracy.so.p drwxr-xr-x 1 yalter yalter 496 Aug 9 20:21 meson-info drwxr-xr-x 1 yalter yalter 56 Aug 9 20:21 meson-logs drwxr-xr-x 1 yalter yalter 310 Aug 9 20:21 meson-private drwxr-xr-x 1 yalter yalter 40 Aug 9 20:21 meson-uninstalled -rw-r--r-- 1 yalter yalter 5,3K Aug 9 20:21 build.ninja -rw-r--r-- 1 yalter yalter 545 Aug 9 20:21 compile_commands.json -rwxr-xr-x 1 yalter yalter 14K Aug 9 20:21 libtracy.so The box script #

I use Bubblewrap to spawn the sandbox. This is an unprivileged sandboxing tool used by Flatpak (though, I hear there are plans to replace it with something else).

The script itself composes a long bwrap invocation. Let’s look at some of the parts.

#!/usr/bin/env bash set -euo pipefail # Export ALLOW_NET=0 to disable network access inside the sandbox. # # Keep in mind that if your X11/Xwayland doesn't check Xauth, # then network access lets the sandbox connect to your X11 # via an abstract Unix socket. This is quite dangerous. ALLOW_NET="${ALLOW_NET:-1}" # The current folder that we're binding read-write. REPO="$(readlink -f .)" BWRAP=( bwrap --die-with-parent # Unshare (isolate) a bunch of things inside the sandbox. --unshare-pid --unshare-uts --unshare-cgroup-try --unshare-user-try --cap-drop ALL # Create/mount important folders. --proc /proc --dev /dev --tmpfs /tmp --tmpfs /var --dir /run --dir /etc --hostname sandbox # Warning: this script shares all environment variables. # If on your system the environment can contain secrets, # you may want to clear them: # --clearenv # Bind the current folder read-write and chdir there. --bind "$REPO" "$REPO" --chdir "$REPO" ) # --- Read-only system binds --- SYS_RO_BINDS=( # Folders with binaries and libraries. /usr /bin /sbin /lib /lib64 # Random configuration files that programs tend to need. /etc/alternatives /etc/nsswitch.conf /etc/hosts /etc/localtime /etc/timezone /etc/pki /etc/ca-certificates /etc/ssl /etc/crypto-policies /etc/fonts # I fill these as I bump into problems, more or less. /etc/java /etc/texlive /var/lib/texmf /usr/lib/jvm /usr/share/java ) # Bind all of them read-only. for p in "${SYS_RO_BINDS[@]}"; do [[ -e "$p" ]] && BWRAP+=( --ro-bind "$p" "$p" ) done BWRAP+=( --ro-bind-try /etc/ld.so.cache /etc/ld.so.cache ) # resolv.conf is fun because it's a symlink into /run, # a folder which we do not want to expose. RESOLV_REAL="$(readlink -f /etc/resolv.conf 2>/dev/null || true)" if [[ -n "$RESOLV_REAL" && -f "$RESOLV_REAL" ]]; then BWRAP+=( --ro-bind "$RESOLV_REAL" /etc/resolv.conf ) fi # Unshare the network if needed. if [[ "$ALLOW_NET" -eq 0 ]]; then BWRAP+=( --unshare-net ) fi # Create a fresh home directory. # The username and the path is the same as on the host # so that everything keeps working. BWRAP+=( --setenv HOME "$HOME" --dir "$HOME" ) # --- Home read-only binds --- HOME_RO_BINDS=( .cargo/bin .cargo/config.toml .local/bin .local/lib/node_modules .rustup .fonts .local/share/fonts .local/share/nvim/site/parser .gitconfig .config/git .config/tmux .cache/ms-playwright .cache/corepack ) for rel in "${HOME_RO_BINDS[@]}"; do [[ -e "$HOME/$rel" ]] && BWRAP+=( --ro-bind "$HOME/$rel" "$HOME/$rel" ) done # --- Home overlays --- # The sandbox can write here, but the changes # will not affect the host filesystem. HOME_TMP_OVERLAYS=( .cache/fontconfig .cargo/registry .cargo/git .gradle .npm .cache/npm .local/share/pnpm/store .cache/yarn .cache/cpm .texlive2023 ) for rel in "${HOME_TMP_OVERLAYS[@]}"; do [[ -d "$HOME/$rel" ]] && BWRAP+=( --overlay-src "$HOME/$rel" --tmp-overlay "$HOME/$rel" ) done # Set up $PATH with the paths that we have inside this sandbox. BWRAP+=( --setenv PATH "$HOME/.cargo/bin:$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin" ) # Execute our big commandline and pass it # the rest of the arguments (the command to run). CMD=( "${@:-bash}" ) exec "${BWRAP[@]}" "${CMD[@]}"

Many lines, but most of them are just listing directories to mount.

If you want to run GUI apps in the sandbox, you’ll need to create an XDG_RUNTIME_DIR and mount a Wayland socket:

# Export PASS_WAYLAND=1 to enable Wayland access. # Warning: it is currently NOT SANDBOXED (e.g. with security-context protocol). # See https://niri-wm.github.io/niri/Security-Model.html#unsandboxed-clients # for an example of what that implies. PASS_WAYLAND="${PASS_WAYLAND:-0}" # Export PASS_DRI=1 to enable DRI (GPU) access for hardware acceleration. PASS_DRI="${PASS_DRI:-0}" # Export PASS_X11=1 to enable X11 (Xwayland) access. PASS_X11="${PASS_X11:-0}" if [[ "$PASS_DRI" -eq 1 && -d /dev/dri ]]; then BWRAP+=( --dev-bind /dev/dri /dev/dri ) fi # EGL complains without this. BWRAP+=( --ro-bind /sys /sys ) # Wayland: bind only the socket into a fresh runtime dir. XDG_RT="${XDG_RUNTIME_DIR:-}" WAYLAND_SOCK="${WAYLAND_DISPLAY:-wayland-0}" if [[ "$PASS_WAYLAND" -eq 1 && -n "$XDG_RT" && -S "$XDG_RT/$WAYLAND_SOCK" ]]; then BWRAP+=( --dir /run/user --dir /run/user/1000-sbox --bind "$XDG_RT/$WAYLAND_SOCK" "/run/user/1000-sbox/$WAYLAND_SOCK" --setenv XDG_RUNTIME_DIR /run/user/1000-sbox --setenv WAYLAND_DISPLAY "$WAYLAND_SOCK" ) else BWRAP+=( --unsetenv WAYLAND_DISPLAY ) fi # X11. DISPLAY_VAR="${DISPLAY:-}" if [[ "$PASS_X11" -eq 1 && -n "$DISPLAY_VAR" && -d /tmp/.X11-unix ]]; then BWRAP+=( --ro-bind /tmp/.X11-unix /tmp/.X11-unix --setenv DISPLAY "$DISPLAY_VAR" ) else # Make it harder for accidental X11: unset DISPLAY. BWRAP+=( --unsetenv DISPLAY ) fi

That’s about it for the script. If needed, it’s easy to mount more folders by adding them into one of the arrays. The script doesn’t require elevated privileges to run.

Just remember that the folder where you run it is mounted read-write with the sandbox. When I want to run a dangerous command without affecting the files in the repository I’m working on, I just make a temporary copy:

project > cd .. > git clone project project2 > cd project2 project2 > box fish project2@sandbox > ...some dangerous command... ... project2@sandbox > ^D project2 > cd .. > rm -rf project2

Another trick I recently did: I created a read-only GitHub personal access token, and automatically put it into $GH_TOKEN in the sandbox. This way, commands like gh pr list work in the sandbox without having any write access.

Conclusion #

This is very much not a polished tool, but rather a script I’ve been adding on to here and there for several months. I wanted to share it because I think it’s fairly generic (works on both Fedora and AerynOS at least), and avoids a number of pain points with other sandboxing approaches:

  • no extra setup required, just one command
  • no separate distro installation, uses the host system binaries and libraries directly. As a corollary, anything you build inside this sandbox will work on the host
  • no manual folder binding, passes through the current folder
  • paths and UID match the host, no broken file permissions
  • no sudo needed

One limitation is that I haven’t been able to make podman run inside this sandbox yet. I tried once briefly, but kept hitting weird errors. Maybe it needs some capabilities exposed; not sure.

This is also obviously not intended as a bulletproof sandbox for running fully untrusted code, in fact I wouldn’t be too surprised if I left some gaping holes by mistake (please let me know if I did).