You are here

Planet GNOME

Subscribe to Feed Planet GNOME
Planet GNOME - https://planet.gnome.org/
Përditësimi: 12 orë 54 min më parë

Felipe Borges: The Future of GNOME Boxes

Hën, 03/08/2026 - 1:28md

I have spent the last two years rebuilding GNOME Boxes from the ground up, driven by three main factors. I spoke extensively about this effort in my recent Linux App Summit, GUADEC 2025 and 2026 talks, but today I am excited to share the result for general testing.

First, shifting to a Flatpak-first (and only) model. As a solo developer, maintaining code paths for countless distributions isn’t sustainable. Since Boxes acts as a frontend for libvirt/qemu, its functionality relies heavily on the backend configuration. Flatpak lets me bundle the entire virtualization stack, giving me the control I need to fine-tune it for our specific use cases.

Second, migrating Boxes to GTK4 and Libadwaita. Beyond the obvious benefits (a modern UI, better responsiveness, and tighter desktop integration) this makes the codebase significantly easier to maintain. This transition required moving away from the GTK3-based SPICE display widget, which was too tightly coupled to older input and drawing methods. We’ve replaced it with Libmks, which has proven to be a solid alternative.

Lastly, modernizing the codebase to make it sustainable for new contributors. That meant adopting modern GNOME app design patterns and rethinking our underlying architecture.

I am now ready to share this work with a wider audience. However, please keep in mind that this is a Beta release meant for testing, not for production environments. If you plan to try it out, make sure to back up any important data in your virtual machines first.

If you want to test this new implementation of GNOME Boxes, you can set up the GNOME Nightly Flatpak Repository and install it with:

flatpak install org.gnome.Boxes.Devel

This new version already covers most of what the classic Boxes could do: creating virtual machines from ISO media and disk images (qcow2), configuring VM resources, sharing clipboard content, sending files to the guest, and more.

It can install Windows 11 without any manual workarounds. Boxes configures Secure Boot and a virtual TPM device automatically. Everything required to pass the Windows 11 hardware compatibility checks out of the box. This was the most requested feature for the classic version, so I am particularly glad it is fully functional in this rewrite.

As distributions shift toward image-based OSes, this Flatpak-only approach becomes even more valuable. Most other virtual machine managers rely on host services or privileged daemons that are difficult to configure on immutable systems. While hardware and host combinations vary, bundling the backend stack directly inside the Flatpak gives us a controlled baseline that we can actively support, configure, and refine over time.

Accessing VM contents used to be tricky due to Flatpak sandboxing. This version addresses that by introducing a VSOCK device to the box, allowing guests with systemd v256 or newer to be accessed directly over SSH. It also adds initial support for port forwarding, letting you reach services running inside the VM from your host.

Screenshot of a host terminal SSHing into the guest VM through VSOCK

All of this and more is detailed on our new website, nightly.gnomeboxes.org, where you can also learn how to help by testing and reporting issues.

Please keep in mind that I am working on this in my free time alongside maintaining GNOME Settings and my day-job responsibilities at Red Hat. I ask for your patience with issue responses, but I will do my best to address bugs and keep pushing feature development forward as time allows.

I love building GNOME Boxes, and I am constantly motivated by the positive feedback from our community. People appreciate Boxes because it lets them set up a VM quickly and get straight to work without needing deep knowledge of virtualization or operating system internals. That remains the core mission, and that is the user experience I want to continue building for.

A lot of this implementation will still change as I gather feedback and it matures. I have also drafted a series of follow-up blog posts to this one, which will describe and elaborate a bit more on the new features, explaining how to use them and how they have been implemented. Stay tuned!

Comments

Lucas Baudin: Visual Signatures in Papers (and Papers 51.beta)

Dje, 02/08/2026 - 2:00pd

We just merged the visual signature UI into Papers (GNOME Document Viewer), developed by Malika Asman during her Outreachy internship (funded by the GNOME Foundation).

Compared to digital signatures, visual signatures do not require a cryptographic certificate. As such, they do not really guarantee the authenticity of a signed document, but they are still widely accepted or required (e.g. in administrative documents).

Here are a few screenshots, the two first ones are context menus that are shown when doing a right click on the document, the third one shows the drawing dialog.

It is possible to import an image file instead of drawing the signature in Papers. Malika implemented a background removal step so that signatures don't look like a plain picture on the document. This is done using the imageproc crate which implements Otsu's method (for those wondering, there is no neural networks or models involved). This gives good results on our test files, let's take for instance this cute GNOME contributor by Jakub:

Once it is imported, the background is correctly removed and we can add this perplexed GNOME contributor to our PDFs:

Note that this is still a rather simple method, so we don't expect it to work in every case. If you have a file that can not be imported properly, please open an issue!

And digital signatures?

These new visual signatures cannot be used directly with digital signatures, but there are plans (and code) to extend the existing digital signature dialog to let users customize the way the signature is drawn on documents, including using one of the visual signatures.

There are other features that did not make it into this release, including the ability to copy/paste visual signatures, those will be for the next cycle!

Papers 51.beta

This is part of Papers 51.beta, there are a few other improvements and bug fixes, including a fix for fractional scaling taking advantage of latest GTK snapping API, read the news here.

Ramayanapu Jagath: Bringing App Uninstallation to the GNOME Shell App Grid

Sht, 01/08/2026 - 2:42md

Hey y’all! I’m Jagath Ramayanapu (Shyam) from India, and I’m a GNOME GSoC intern this year. This summer, I’m working on bringing app uninstallation directly to the GNOME Shell App Grid.

Previously, to remove an app in GNOME, you had to open GNOME Software, find the app, and click Uninstall. With this feature, users will soon be able to uninstall apps directly from the App Grid’s context menu.

This is the first of a two-part blog on how we are building this feature. In this post, we’ll cover the changes in GNOME Shell’s JavaScript that make it possible.

 

The Problem: Talking to the App Store

GNOME Shell is great at drawing your desktop, but it actually has no idea how to delete an app or clean up user data. To do that, it needs to ask a App Store like GNOME Software to do the heavy lifting.

To solve this, we created a d-bus interface called AppStoreIntegration. You can think of it as a dedicated middleman whose only job is to talk to GNOME Software in the background.

We designed this helper with a few key goals in mind:

At first, I planned to have GNOME Software own this interface. However, that would have tightly coupled the feature to GNOME Software. Based on feedback from my mentor, Adrian Vovk, I moved the ownership of AppStoreIntegration into GNOME Shell instead.

This design makes the interface app store agnostic. Any app store can implement the interface, allowing GNOME Shell to work with different app stores without depending on a specific one.

This interface has two methods :

  1. GetUninstallableApps :
    • What it does: The Shell calls this method to ask GNOME Software, “Give me a list of every installed app that the user is actually allowed to uninstall.”
    • What it returns: It returns a dictionary that maps each app’s desktop ID to a set of metadata properties (for example, a boolean flag telling us if the app supports deleting personal data)

2. UninstallApp :

    • What it does: When you click “Uninstall”, the Shell sends this command to GNOME Software.
    • What it accepts: It takes a dictionary containing the app’s id and a boolean purge-data flag (which tells GNOME Software whether it should wipe the user’s saved data along with the app).
Building the Integration Manager

Now that we had our D-Bus contract, we built a helper module in GNOME Shell called js/ui/appStoreIntegration.js Inside this file, we built a class called AppStoreIntegrationManager whose sole purpose is to call those two D-Bus methods.

We designed this manager with a few key goals:

  • Keep the Desktop Fast: When the manager connects to the D-Bus proxy, it does it asynchronously. This means if GNOME Software takes a second to wake up, your desktop won’t freeze.
  • Cache the Data: We don’t want to call GetUninstallableApps every single time you right-click an icon. Instead, the manager listens for a signal called installed-changed from the system. When it hears this signal, it quietly fetches the list of apps and caches it in memory.
  • Track the State: The manager keeps a list (set) of apps that are currently being uninstalled. This gives our UI a simple way to know exactly what is going on at any given moment.
Updating the App Menu

Once we had the cached data, we needed to update the UI in js/ui/appMenu.js.

We added a new “Uninstall” button to the right-click menu, but we had to be careful. We don’t want to show an “Uninstall” button for apps you aren’t allowed to remove (like core system apps).

To fix this, we tied the menu directly to our new manager using reactive signals. Every time you open the menu, a function called _updateUninstallItem runs. It asks the manager: appStoreIntegrationManager.canUninstall(appId). If the answer is false, the button completely hides itself.

Handling the User Interaction

Uninstalling an app isn’t always as simple as deleting a folder. Modern software, like Flatpaks, often leaves behind saved files and personal configurations. We wanted to give users the option to clean up this data, but only if the app store actually supports it.

When you click Uninstall in the right-click menu, the UI triggers a smooth, step-by-step interactive flow:

  • Checking for User Data: First, the code checks the metadata we got from D-Bus earlier to see if the app store supports wiping personal data for this specific app.
  • The Confirmation Dialog: We pop up a small confirmation window. If the app supports it, this window includes a checkbox asking if you want to clean up your personal files too.
  • Waiting in the Background: The desktop interface pauses the uninstallation logic and waits patiently in the background for you to make a decision, ensuring your system remains completely responsive.
  • Executing the Uninstall: Once you confirm your choice, the UI fires off the D-Bus command to GNOME Software. It immediately adds the app to a tracking list to prevent you from accidentally clicking the uninstall button multiple times.
  • Safe Error Handling: If GNOME Software runs into an unexpected error and fails to uninstall the app, the interface safely catches the problem. It removes the app from the busy tracker and displays a standard system notification to let you know what happened, keeping your desktop totally stable.
Thanks

Building this feature was a fantastic learning experience in bridging different parts of the GNOME ecosystem. A huge thanks to Adrian for mentoring me throughout this project and helping me navigate the architecture.

If you’d like to check out the changes, here’s my MR.

    Tobias Mueller: syncthing-socket for accessing machines through NATs

    Sht, 01/08/2026 - 10:50pd

    If you run a homelab, you’ve inevitably run into the absolute nightmare that is CGNAT (Carrier-Grade NAT) or strict corporate firewalls. You have a server at home that you want to SSH into, but your ISP doesn’t give you a public IP address. Or maybe you’re at a coffee shop or behind a strict corporate firewall that blocks all outbound SSH connections.

    Traditionally, the solutions are:

    1. Dynamic DNS and Port Forwarding: Useless if you’re behind CGNAT.
    2. Reverse SSH Tunnels / VPS: Requires renting a $5/month VPS and managing keys and infrastructure.
    3. Tailscale / ZeroTier: Excellent solutions, but they require installing kernel modules, managing accounts, and trusting a third-party control plane.

    What if there was a completely decentralised, free, open-source network of relays already spanning the globe that we could hijack to establish direct, multiplexed, end-to-end encrypted tunnels between any two machines without any accounts or infrastructure?

    Enter syncthing-socket and the Syncthing global relay network.

    The Syncthing Relay Network

    Syncthing is an incredible peer-to-peer file synchronisation tool. To ensure files sync even when both devices are behind strict NATs, the Syncthing community operates a global network of public relays and discovery servers.

    These servers are completely open and decentralised. They don’t care what data is being transmitted—they just facilitate STUN/TURN WebRTC connections to punch through NATs.

    I vibe-coded syncthing-socket as a standalone, lightweight Go daemon that securely hijacks this exact network to pipe raw TCP sockets, PTY shells, and HTTP proxies!

    How syncthing-socket Works

    Under the hood, syncthing-socket imports the official Syncthing protocol libraries but throws away the file-syncing logic. Instead, it uses the peer-to-peer WebRTC connection to multiplex raw byte streams using Yamux.

    When you start the server, it deterministically generates a Syncthing Device ID from a passphrase and connects to the global relay pool:

    $ ./syncthing-socket server --passphrase "my-super-secret" --forward 127.0.0.1:22

    This server is now securely listening on the decentralised Syncthing network. The discovery servers know how to route to it, but nobody can connect unless they have the mathematically paired client passphrase.

    From anywhere in the world, on any network, you run:

    $ ssh -o ProxyCommand="./syncthing-socket client --passphrase 'my-super-secret'" user@ignored_host

    syncthing-socket will instantly negotiate a WebRTC STUN/TURN connection via the nearest public relay, establish a direct end-to-end encrypted P2P tunnel, and pipe your SSH connection perfectly through it. If a direct P2P connection isn’t possible, it gracefully falls back to using the relay server as a TURN proxy.

    Beyond SSH: SOCKS5 and PTY Shells

    Because we established a fully multiplexed Yamux tunnel over WebRTC, we can do much more than just pipe a single TCP socket.

    Native PTY Shells:
    You can completely drop sshd and use syncthing-socket natively!

    # Server ./syncthing-socket server --passphrase "my-secret" --shell # Client ./syncthing-socket client --passphrase "my-secret" --shell

    This spawns a remote bash session and pipes your raw local terminal directly into it. It natively supports tab-completion, vim, htop, and even transmits window resizing events (SIGWINCH) over a dedicated control stream so the remote UI always perfectly fits your screen.

    Remote SOCKS5 Proxy:
    Want to browse the web through your homelab’s internet connection securely?

    # Server ./syncthing-socket server --passphrase "my-secret" --socks # Client ./syncthing-socket client --passphrase "my-secret" --socks 127.0.0.1:1080

    Just point your browser to socks5://127.0.0.1:1080 and you’re fully proxying your web traffic over an encrypted, decentralised P2P tunnel.

    Conclusion

    By standing on the shoulders of the incredible Syncthing project, syncthing-socket provides a zero-config, zero-infrastructure, completely decentralised way to punch through CGNATs and firewalls.

    Similar Projects

    While syncthing-socket fills a specific niche, it’s worth mentioning similar tools in this space. For raw socket routing, there’s gsocket and its clone minisocket. If you just want to share a terminal, tmate (though largely defunct) was a pioneer. For full remote desktop access, solutions like RustDesk, AnyDesk, and TeamViewer exist. In terms of underlying architecture, Magic-Wormhole uses a very similar P2P approach (with a modern Rust replacement being Iroh).

    Check out the code on GitHub and take back control of your homelab connectivity!

    GNOME Internationalization & Localization: GNOME 51 release is open on Damned Lies

    Enj, 30/07/2026 - 8:45md

    Happy GNOME translators, reviewers, and developers,

    I have just created the GNOME 51 release on Damned Lies, our translation platform.

    Have a look at the GNOME release calendar in order to know the coming due dates. As a reminder:

    • 2026-08-01 : API/ABI, Feature, UI, String Announcement Period
    • 2026-08-22 : String Freeze for GNOME 51
    • 2026-09-12 : GNOME 51 Tarballs due date

    You can of course start translating before the string freeze, but it might happen that you will have to rewrite some of the already updated strings.

    The string freeze occurs 3 weeks after, and changes are not expected to come, except those that have been declared (or detected by Damned) explicitly and validated by the Coordination team (which you can reach here: Teams / Translation / Coordination · GitLab ).

    If you are a developer, entering the String Announcement period means that you are likely to declare the update in your strings to the coordination project; this way, team coordinators can track the changes and know what requires their attention.

    Team coordinators, it’s time to rally your teams, review your documentation, and welcome new members! Please remember that translation is a great way to connect with our GNOME communities, and that your new members might be future maintainers of our ecosystem!

    Thank you all for your participation, happy translating!

    FYI: 42 languages reached > 85% for GNOME 50 UI, let’s do even better! Good luck, everyone!

    Jussi Pakkanen: Fixing a super 8 projector from the 70s

    Enj, 30/07/2026 - 7:18md

    Warning! Do not try any of this at home! Messing with internals of electronic devices is dangerous and can lead to electrical fires, serious injury and even loss of life.

    My dad started using a super 8 film camera as early as 1967 (the system was launched in 1965). He stopped doing it in the 1980s as it became pretty much impossible to buy film. Ever since then the films have been stored in multiple cardboard boxes in his basement. Recently he moved to a smaller apartment so all the films and related hardware had to go somewhere else. Namely, to me. Here is a representative sample.

    The picture does really not make justice to the projector. It is perhaps the only household appliance I have ever owned that could survive a head-on collision with an IBM Thinkpad from the 2000s. The projector weighs 10 kilos and consumes 200 watts when running, half of which is taken by its halogen light bulb. For comparison a typical modern LED light bulb consumes less than 5 watts.

    The projector has not been used this millennium so unsurprisingly it did nothing when I plugged it in. The back cover could be opened (with a screwdriver) revealing two glass fuses, one of which was burnt. I replaced it and plugged the machine back in. It immediately let loose the magic smoke even though everything was turned off. Fortunately I had kept the back cover open so could see the smoke the second it appeared and managed to cut the power before flames appeared. Unfortunately the smoke originated deep inside the machine so I could not see which component was the source. To get deeper I would have to remove all the covers. That is no small feat, mind you, I had to buy a whole new ratchet set to get all the various screws out.

    This thing predates printed circuit boards that would tell you which holes belong to which components. Instead all components have been soldered to the board by hand with Japanese meticulousness. The board won't give us any help on deciphering how things should work. Visual inspection also does not reveal any immediately broken components. Neither did poking around with a multimeter.

    The only life line was that even though a component had started smoking the fuse had not blown. In theory I could plug the machine in for a second and see if smoke appears again. If it does I can see the exact component faulty component. At this point I'd like to remind you of the warning at the top of the post. If you have a known broken electrical device, you should never connect it to any sort of a power source. Seek advice from a qualified professional instead. Even if you manage not to burn your house down, electric shocks are nasty any resulting smoke is almost certainly noxious.

    Anyhow, after taking sufficient precautions I plugged it back in and immediately got smoke and could decipher what was wrong. One of the main electrolytic capacitors (the one that was in the most inconvenient location, obviously) had dried out and shorted. This caused one of the bridge rectifiers to have its positive and negative output leads short circuited. Here are the problematic components.

    The dark blue capacitor on the right is the broken one. For some weird reason the three decoupling capacitors have different voltage ratings (16V, 25V and 50V) even though there is only one transformer and input voltage (12 V). The black circles are the bridge rectifiers. The one on the right is the broken one. In this picture the cracks are fairly visible but trying to detect them in person is very difficult, even with a magnifying glass and a flashlight. According to multimeter measurements the other two capacitors and rectifier are working, but it's better to replace all of them. 50 year old eletrolytic capacitors have a short life expectancy and the additional work needed to fix all instead of only one is insignificant.

    Here is a comparison shot of the old components and their modern replacements.

    After soldering in the new components you enter a paranoid session of measuring every possible combination on the board to ensure you have not accidentally created a short or put any of the components in the wrong way. Any failure can give you a live Electroboom experience in your own home. Even though it sounds exciting, you really don't want to see it with your own eyes. I don't speak from experience here, and intend to keep it that way.

    Anyhow, eventually you have to plug the power and try if the machine works. Amazingly enough it did without a hitch. Once you have it running you can truly appreciate how well the mechanical parts of the projector have been designed. It runs silent, smooth and with zero visible jitter. There is only one plastic knob in the entire device. Unfortunately it is the lens focus adjustment wheel, and it has broken off (as you can see in the first image). You can still sort of twist it with your fingers but the experience is inconvenient to say the least.

    What next?An obvious question some of you might have is "Wouldn't it be more convenient to watch films on a computer than an ancient and potentially deadly projector?" The answer to that is "Yes, it would indeed be." But more on that in a future blog post.

    Felipe Borges: You can now opt in to share your blog posts on GNOME’s Discourse

    Mër, 29/07/2026 - 1:45md

    We’ve just rolled out a new feature on Planet GNOME to bring our community discussions together! You can now opt in to automatically create a topic on discourse.gnome.org whenever you publish a new blog post.

    Having comments centralized on Discourse makes it much easier for readers to discuss your posts, while also ensuring that all interactions are moderated under the GNOME Code of Conduct for a safer, healthier space. It is also a great way to give your content a bit more visibility with the active Discourse community without any extra manual work.

    This is especially handy if you run a statically generated blog without an existing comment section, giving your readers a dedicated space to share feedback.

    This feature is completely opt-in, so nothing will change for your feed unless you choose to turn it on. To get started, simply send a merge-request to Planet GNOME adding discourse_comments=1 to your blog entry in our config.ini file.

    For this to work, I got the Planet’s static generator to produce a custom RSS feed for the blogs that flag the discourse_comments property. Then, Emmanuele Bassi configured our Discourse instance with the RSS Polling plugin, which creates a topic for each RSS feed entry.

    Since this is brand new, there might still be a few rough edges. If anything breaks or acts weird when you try it out, let us know and we’ll get it fixed as soon as we can.

    Happy blogging!