• Pl chevron_right

      Ondřej Holý: What’s new in GVfs for GNOME 51?

      news.movim.eu / PlanetGnome • 8:16 • 1 minute

    It has been quite a long time since my last post with release news for GVfs. I haven’t had much time for upstream development recently. Furthermore, I was out for health reasons for almost the entire last year, so development has been mostly focused on bug fixes. Still, there are some changes in GVfs 1.62 and 1.60 worth mentioning.

    Auto-unmount of inactive backends

    The biggest addition is the auto-unmount feature ( !330 ), which fixes a very old feature request ( #31 ). This feature introduces a mechanism where certain backend can be automatically unmounted after a defined period of inactivity. This was enabled for the most of auto-mounted locations (i.e., admin , computer , http , network , recent , trash ). This solves a long-standing issue where auto-mounted locations couldn’t be easily unmounted via the file manager, causing their daemons to run until the end of the session and needlessly waste system resources.

    Security fixes

    The current influx of CVEs hasn’t missed GVfs. The highlight of the 1.62 release is a fix for a local privilege escalation issue ( CVE-2026-88924 ), which I describe in more detail in a separate post . Aside from that, several other lower severity CVEs were addressed ( CVE-2026-28295 , CVE-2026-28296 , CVE-2026-84267 , CVE-2026-84268 , CVE-2026-84269 , and CVE-2026-84270 ). Also other potential security vulnerabilities that didn’t receive specific CVE assignments were patched across these releases.

    Deprecating backends

    I am also continuing to clean up the codebase. As part of this effort, the legacy burn backend and several deprecated APIs have been completely removed. Additionally, the afp and archive backends were marked as deprecated and will be removed in future releases. The google backend has also been disabled and marked as deprecated, however, there is an ongoing effort to restore this functionality, but it did not make it into this release cycle though.


    I would like to thank all the GVfs contributors who helped keep the project moving forward, especially while I was away. Let me know in the comments if you have any thoughts on the recent changes!

    • Pl chevron_right

      Ondřej Holý: Local privilege escalation in GVfs

      news.movim.eu / PlanetGnome • 8:16 • 1 minute

    A security vulnerability ( #875 ) in the gvfsd-admin daemon that allows local privilege escalation was recently discovered and is tracked as CVE-2026-88924 .

    What is the issue?

    The problem relates to how the daemon creates a private D-Bus socket. Previously, the socket was created with root privileges, and then a chown() call was used to change its ownership to the invoking user. Because this happened inside a user-controlled directory, a local attacker could exploit a race condition by quickly replacing the newly created socket with a symlink pointing to a root-owned file (e.g., /etc/pam.d/su ). This would grant the attacker ownership of that critical file, leading to a local root privilege escalation.

    Who is affected?

    To exploit this vulnerability, an attacker needs local code execution within an active graphical session and must belong to a privileged desktop group (like wheel or sudo ). The gvfsd-admin backend must also be installed. Unfortunately, these conditions are met by default on many standard desktop installations.

    What to do?

    The fix is already merged ( !352 ). The issue was resolved by using setfsuid() to set the correct filesystem UID before the socket creation. New versions 1.62.0, 1.60.3, and 1.58.5 containing this fix have just been released. I strongly recommend all users and distribution maintainers to update as soon as possible.


    Finally, I would like to thank the security researcher lain for discovering the vulnerability and providing a very detailed report!

    • Pl chevron_right

      Matthias Klumpp: JPEG-XL, AppStream, and better media processing

      news.movim.eu / PlanetGnome • 1 day ago • 12 minutes

    Two weeks ago, I released AppStream 1.2.0. This release contains a lot of great changes, but one of the most important ones concerns how media are being handled, and AppStream’s default image export format.

    AppStream is a Freedesktop metadata standard to describe software components. That can be anything from system services over fonts to console and graphical applications. AppStream metadata is supposed to give users enough information to decide whether they want to install a piece of software, to represent that piece of software, and to give the operating system enough information to decide whether a software component should be installed automatically and (to some extent) what capabilities and relations it has, to provide the user with sensible options.

    Especially for the first two goals, and especially for GUI applications, AppStream supports icons and screenshots, which are used to showcase applications. Today, AppStream is used by all kinds of services, from Linux distributions over firmware updates to Flatpak and desktops directly. AppStream’s original design however comes from the perspective of Linux distributions in 2011, where you may want to browse the software catalog offline, without delay, and without pinging an external server (which could be a privacy concern).

    Therefore, a common way to deploy an AppStream-enabled software repository is to ship all icons of all applications in the repository to the user as part of the repository metadata download. AppStream does support remote icon downloads nowadays, and for a while I thought that this would become the default eventually. However, especially in today’s world, having a bandwidth-saving, instantly responsive, privacy-protecting application browsing experience seems more important that ever.

    PNG images are great!

    The only format that AppStream supports for icons and screenshots (which are downloaded on-demand from your distributor’s CDN) has always been exclusively PNG . PNG images are perfect for icons, because they compress well (especially for common icon shapes), are fast and simple to load, and can be loaded anywhere, by any toolkit or webbrowser. They also ensure we deliver faithful screenshot images, even though we may have scaled or re-rendered them. Still though, PNG images are less great for screenshots, as they are not very efficient, which puts strain on any CDN that has to deliver them, as well as on people’s internet connections when browsing screenshots. Having smaller thumbnails alleviates that problem a little, but does not fully solve it.

    But even for icons, PNG could be improved upon: In many cases, icons are re-downloaded with the repository metadata again and again, so having a large icon tarball adds up to the data transferred during metadata refreshes. AppStream also now supports large 128x128px icons, which nobody in 2012 expected we would need, adding even more data that will be re-downloaded. Saving some space here translates directly to lower bandwidth costs as well as faster downloads for users.

    To improve PNG file sizes, the AppStream Compose library, which handles all image processing and metadata catalog composition, was running optipng on all generated PNG images. That does create smaller PNG images, but they were still relatively large compared to other image formats.

    For a long time though, there was no alternative to PNG images for icons: There was no lossless image compression format that could give us the same quality as PNG images and that was also widely supported.

    JPEG-XL vs PNG in AppStream

    Since 2021 we have JPEG-XL (JXL), which offers a true lossless mode with often better compression than PNG. The issue was that JPEG-XL wasn’t widely supported. Then, in 2025, the PDF Association selected JPEG-XL as the preferred image format for HDR images in PDFs, and now we are finally getting browser support and more ubiquitous availability of the format (you can try it right now in Firefox!).

    For screenshots, using JXL’s lossy mode, it has obvious and extreme size advantages over PNG, so supporting JXL or WebP for screenshot images was an obvious choice. If JXL would support the lossless case very well as well though, we could serve many use cases with the same exported image format, which is very attractive to me.

    So, the obvious next question was whether it was worth the pain of switching the icon format, so I did some measurements on real icons. For that I used the AppStream component icon pool that Debian Unstable ships, which is almost 5000 application icons of various sizes, and converted them to PNG:

    Icon size Icons PNG total JXL total Pool saved PNG avg JXL avg Median saved Mean saved Worst Best Larger as JXL
    TOTAL 4973 21.9 MiB 17.5 MiB 19.9% 4.5 KiB 3.6 KiB 18.6% 16.6% -118.7% 70.0% 694
    48×48 1544 3.7 MiB 3.0 MiB 17.8% 2.4 KiB 2.0 KiB 17.9% 16.7% -118.7% 60.0% 206
    64×64 2018 7.0 MiB 5.8 MiB 17.8% 3.6 KiB 2.9 KiB 18.0% 15.8% -112.7% 70.0% 279
    128×128 1411 11.2 MiB 8.7 MiB 22.0% 8.1 KiB 6.3 KiB 20.1% 17.5% -89.7% 61.0% 209

    PNG images saved with libpng at effort=4, compression=9 , then optimized using optipng -o2 , JXL images encoded using vips jxlsave lossless=1 effort=7 strip=1 via VIPS/libjxl.

    As the table shows, using lossless JXL images over size-optimized PNG images (using optipng’s default settings) provides a roughly 20% gain. This does not look like much, until you consider how often these files are downloaded: A 20% file size reduction may only save 1-2 MiB of disk space, but if they are downloaded over and over again by many clients, it will save a lot of bandwidth.

    Interesting JXL encoding findings

    As a sidequest, I was curious why some images were larger than their PNG counterparts when encoded with JXL, and what the ones that were significantly smaller were.

    In short, the biggest size reductions for JXL existed on images that were already small as PNG, and contained large, flat color surfaces with hard edges and simple shapes. They were not very interesting, and much of JXL’s wins come from accumulating smaller gains across all files, which compound the bigger icons get (especially at 128x128px, where JXL truly shines).

    The events were JXL loses to PNG are more interesting: For example, it does quite poorly with pixel-art images that have a lot of repeating patterns. Those are encoded well by PNG, but less efficiently by JXL. Take for example Vonsh:

    Icon of Vonsh , an SDL-based snake game, which PNG compresses better than JXL

    My guess is that while PNG can exploit the repeating pixel patterns for compression, JXL’s predicts surrounding pixels from its neighbours, which fails too often and makes it pay almost full entropy per pixel. In this single rare case, the PNG is at 5.4 KiB, while the JXL is almost 8 KiB in size.

    Other cases I looked at were arguably buggy input data, where color channels were hidden under the alpha channel of the input image. PNG could probably again exploit repeats, while we were forcing JXL to encode pixels that were invisible in the final image. This is arguably a problem with the original input data. Currently, AppStream does not make any changes to icons at all, but in future we might add a filter that removes invisible colors from images to solve this pathological case (it was only two icons out of 5000 though, so it is not a high priority).

    The third case I found where JXL loses to PNG were icons with checkerboard-like patterns:

    Icon of x3270 , an IBM 3270 Terminal Emulator

    For those, PNG can likely again exploit the repeating patterns, while a checkerboard layout is pretty bad for left/top predictors like JXL’s. However, in this case the size difference (and loss for JXL) is only 450 bytes, so even though JXL loses to PNG, it does so not by much.

    JXL in AppStream

    Given these findings, JPEG-XL is the default image format starting with AppStream 1.2.0. AppStream Compose will encode all images losslessly as JXL, while screenshots are encoded in lossy mode at Q=90 effort=7 . Since the optipng step does not happen for JXL images, this comes at no speed penalty and is even a bit faster on modern x86_64 CPUs (where libjxl can use SIMD). PNG is still available, and Compose can be told to switch between the two formats.

    Upsides of JXL in AppStream right now

    If you use JXL in Compose or the recent release of appstream-generator , you will get much smaller images and, for screenshots, will benefit from other JPEG-XL features such as progressive decoding, providing a far nicer user experience. libAppStream has supported JXL icons since version 1.1.3, so your clients will need that version or a newer one, and all software centers will have to support loading JXL images (which all of them do, provided the right plugins are installed).

    Downsides of switching to JXL too quickly

    JXL is a very new format, so web browsers might not yet display it if you are serving webpages. Your clients may also have bugs in processing JXL images, as the format is still “new”. For example, switching on JXL in Debian sent KDE Discover into an infinite loop on startup while trying to load the icons (an issue which has been fixed , but clients will need that patch first before JXL is switched on).

    This currently makes JXL enablement only possible when you know that your clients can support it. This is the case for me in Debian Unstable and Debian 14, which are using JXL images for a few weeks now, but not for any older releases. Platforms like Flatpak have it even harder, because they do know even less about their clients. So, even though it has big advantages, you may want to hold off on using JXL right away, and force PNG by setting the ImageFormat key to png in appstream-generator ‘s configuration, or passing --image-format=png to appstreamcli compose .

    It is also worth mentioning that JPEG-XL is much, much slower on systems that do not have SIMD instructions or for which the libjxl/jxl-rs library does not have them (such as apparently riscv64 right now). If this is a concern, you might not want to switch to JXL right away.

    Media pipeline improvements

    Besides the JXL default switch, AppStream 1.2.0 also comes with a complete overhaul of its media processing pipeline. While libappstream , AppStream’s main library, does not do any media processing and comes with very minimal dependencies to be embedded in client applications, the same can not be said about libappstream-compose , AppStream’s library to build metadata generating applications (the server-side part, usually).

    The compose library has to render fonts into font specimen cards, inspect translation files, render SVG images, read & render all kinds of images, inspect video files, etc. Especially the fonts, and the fact that fonts can appear in SVG images, has caused issues in the past, as libappstream-compose is a heavily threaded library and most font libraries can only work from a single thread. This forced the library to essentially go into single-thread mode anytime anything that could touch a font was processed.

    AppStream originally was created for a “safe world” where applications were vetted by the distributors. This is increasingly not the case, so it made sense to put at least a few guardrails on the most complex part of the pipeline: The media processing. As part of the change, media processing was split out into a separate worker process. This solved two problems at once: Font handling was isolated in a single-threaded binary and if we wanted to handle fonts in parallel, we could simply spawn more workers. And, being in a separate process, the media processing could now be sandboxed.

    As part of the multiprocess changes, Compose also switched from using GdkPixbuf to VIPS for image processing. The latter allows for much more fine-grained control over the image output, and comes with a lot of well-maintained filters and operations, which made it possible to eliminate a fair chunk of AppStream’s hand-rolled image processing operations. As part of this transition, we unfortunately lost the ability to read XPM images, which dropped about 20-30 applications from the pool. But in the name of security, this is a sensible choice, especially since most XPM icons were very small and low-resolution, and applications using them could benefit from a high-quality PNG icon anyway. With VIPS, we also now restrict the amount of images we can load to a sensible set, so extremely niche formats will be outright rejected (this includes sane-but-unusual formats for screenshots and icons, such as TIFF images).

    The Compose library, with all of these changes, will now just request high-level operations (e.g. “render a font card for this font to a JXL image”) from the worker, and provide it with input data in sealed memfd s and output locations as FDs as well. On Linux systems, the worker will use Landlock if available, to block all write access to the filesystem and deny TCP and UDP as well. The sandbox can certainly be tightened a fair bit in future, but this was a good and safe start to gain some experience with it without having things break too easily (also, Landlock’s API is surprisingly nice to use, so it was easy to add in this early version).

    With all of these changes, the libappstream-compose library is now also marked API-stable, so you should be able to rely on it in future to build new things (it has barely changed in the past, and now with the new media API, it was time to declare it stable).

    I want to see / try this!

    Currently, the easiest way to have a look at the new data is to check out Debian Unstable. If you have a JXL-enabled browser, you can also see the icons in AppStream Generator’s HTML pages for Debian Sid . If you are using appstream-generator for your distribution, you will also get much more pleasant statistics and HTML pages, as well as fully deterministic media output and a whole bunch of security updates, so, update to its recent 1.0 release.

    Please keep in mind that if you switch to JXL, the client tools have to support it. Support varies depending on the Linux distribution, so, test it first and switch the default back to PNG in case you encounter any issues.

    What’s next?

    With so many features and changes landed, the next changes in AppStream will focus on improving what already exists and seeing if there are any issues. Testing with the entire Debian archive as data source makes me fairly confident though that there will not be many issues. In the longer term, tightening the media processing sandbox will also be something we might want to do.

    For JPEG-XL, one obvious question is “Will you add support for it to the Freedesktop icon-theme specification as supported format alongside PNG, SVG(Z), and XPM?”. For on-disk icon repositories, JXL’s space-savings are less compelling, and it being HDR-capable is also not necessarily a killer feature. However, JPEG-XL’s ability to immediately decode larger images at reduced resolution without resampling could legitimately be very powerful here, as applications could ship a single large image and quickly decode it at 1/2, 1/4 or 1/8 the size without resampling. Extra channels for spot-coloring would also allow it to recolor symbolic icons on-the-fly without SVG and CSS, which could be very appealing. So, the answer here is: Maybe it makes sense to allow another format, but this will have to be discussed first, as it will force JXL into every toolkit and desktop, which is a much bigger ask than supporting it only in AppStream.

    As always, let me know what you think and please report any issues or bugs directly against AppStream or AppStream Generator .

    • Pl chevron_right

      Georges Basile Stavracas Neto: What’s New in Calendar 51: Prologue

      news.movim.eu / PlanetGnome • 1 day ago • 3 minutes

    It’s been a long time since I last posted anything here, huh.

    Well, a few hours ago I was preparing the release notes for the next release of GNOME Calendar. It is yet to be reviewed, but this is how it reads at the time I write this blog post:

    This is a remarkable release for us, as it is one of the biggest releases in the history of the project, and we're excited to share a slightly longer update on it.
    
    The first thing many users will notice is how GNOME Calendar will feel snappier now. During the past six months, a lot of work was put in optimizing GNOME Calendar from the inside out. This includes a major change in how it handles events internally, vastly reducing the amount of data transferred between GNOME Calendar and other components of the desktop, and applying many different tricks and strategies to make it render faster. Really, this is probably the most optimized the project has ever been.
    
    Another front in which GNOME Calendar has been consistently improving is accessibility and keyboard navigation. During this development cycle, another big batch of improvements on these fronts were merged. You can now navigate between events and days in the Month view using only your keyboard. Notification bubbles are properly read out loud (thanks also to Orca developers for accommodating our use case!). The Week view is now properly styled when the high-contrast setting is enabled.
    
    […]
    
    On the non-technical side, in the past few months the project received contributions from many new contributors, as well as long time contributors. Our issue tracker continues to be in excellent shape, well triaged, and properly labeled. Our three latest releases were the biggest releases in the history of the project. Thank you all very much for using, developing, documenting, translating, testing, and fixing GNOME Calendar!

    This release of Calendar has lots to talk about. It is, as mentioned, the biggest release in the history of the project. Not in numbers of line added, or patch count, but certainly in terms of contributor involvement, code reviews, code quality, and features. We’re not just a bunch of bored university students pushing unreviewed patches non-stop to the main branch anymore!

    For the next few weeks, I’ll be writing more focused blog posts about the work I’ve done in Calendar this cycle. I’ve focused mostly on performance and reorganizing the internals of the application to be more resilient. It’s not glorious work, but I do love working on optimization problems!

    GNOME Calendar will complete 15 years in a few months from now. The project is one of the few lucky projects in GNOME – and, I’d argue, in the free software scene in general – that has such a thriving community of contributors. It’s one of the few GNOME core apps that survived the great purge. It’s a super rare example of a GNOME app with a product manager.

    It is also the project that brought me in in GNOME, so pardon me if I get a little emotional when I see the project thriving as it is, and think back of all the good friends that came and went, the hard lessons from maintaining it over over a third of my life, and the prospects for the future.

    GNOME Calendar is entirely developed and maintained by volunteers. We have never received any kind of funding, be it corporate, from grants, or other forms of patronage. This gives us freedom from these kinds of influences (mostly to complain about how so many big companies fail to meet the calendaring standards that they themselves helped create), but the reality is that it is really damn hard to pitch for funds for a calendaring application.

    Please consider donating to GNOME , or to the individual contributors of your choice. It makes a difference. All the difference.

    • Pl chevron_right

      Jakub Steiner: The other WTC Attack

      news.movim.eu / PlanetGnome • 1 day ago • 2 minutes

    In 1993, I stood at the top of the World Trade Center feeling like being on top of everything. It was the culmination of my first proper trip west, a stark contrast to a country behind an iron curtain or even a small-town Amherst, New Hampshire, where I had to earn my way into that adventure.

    Leaflet for the World Trade Center and Empire State Building, an Empire State ticket, Air India tickets for the flight to NYC JFK, and a bus ticket to London from Prague

    Many people can't wrap their heads around how such enormous buildings could collapse on September 11. What I can't wrap my head around is that they survived the first attack, which happened in February of '93, when I was, entirely oblivious to what had happened on the ground floor a few months earlier, soaking in those panoramic views.

    View of the two towers from the sidewalk in front of them

    Me at 18 with Margriet, whose last name will remain a mystery

    The attack was carried out by a group of radicals led by mastermind Ramzi Yousef. In the underground parking garage of the North Tower, they detonated a yellow Ford van packed with explosives. It's often claimed that the terrorists used Czechoslovak Semtex, but in reality it was a massive, roughly 600-kilogram homemade explosive charge, further reinforced with pressurized hydrogen tanks. Semtex was only a trigger explosive.

    The explosion was devastating. The blast tore a 30-meter crater through five floors of underground parking and damaged several support columns, though the main structural frame of the tower held. Though the tower didn't collapse as the terrorists had originally planned, the shockwave destroyed the main electrical wiring and emergency lighting, and smoke rose as high as the 93rd floor. Six people lost their lives and more than a thousand were injured, most from smoke inhalation during the grueling evacuation through dark stairwells. Operations in both towers were completely paralyzed and the complex had to be shut down for nearly a full month. Total damages and subsequent repairs cost roughly half a billion dollars.

    Because of the '93 bombing, the Port Authority installed photoluminescent safety markings along the steps, landings, and handrails throughout the towers. When the planes struck eight years later and emergency lights flickered or failed, these glow-in-the-dark strips guided occupants downward. According to National Institute of Standards and Technology, 33% of survivors in the North Tower and 17% in the South Tower directly credited these markings with aiding their escape. The stairs were well-lit by battery-pack emergency lights and photoluminescent guides, and people moved much faster. Survivors who had been in the building during both attacks noted that the 2001 descent took roughly half the time it did in 1993.

    I only know about all of this because of the internet — a firehose of news and dangers pouring at me every hour of every day. Could I stand up there today, soaking in those fantastic views, still so oblivious and happy?

    • Pl chevron_right

      GIMP: GIMP 3.2.6 Released

      news.movim.eu / PlanetGnome • 1 day ago • 14 minutes

    We’re happy to announce the release of GIMP 3.2.6 ! This stable release contains several months worth of patches, bug fixes, security updates, and more from new and longtime contributors.

    Special thanks to Bruno Lopes , who has taken charge of backporting fixes from our development branch to the 3.2 stable branch.

    This news posts provides an overview of the changes since GIMP 3.2.4. For a more detailed review, check out the NEWS changelog.

    Don't squash bugs, free them, by Aryeom “Don’t squash bugs… free them!”, by Aryeom, CC BY - SA 4.0 (a poetic approach to debugging), 2019

    General Highlights and UX Improvements

    A number of the fixes we first mentioned in our last development update were backported to GIMP 3.2.6.

    Cheesequake has added code so you can use Cut on a layer group. This will allow you to cut the same section of all layers in the group, provided they are rasterized and not locked. Jehan made further improvements to this code.

    The Sample Merged option for the Color Picker tool should now include any filters applied to a single layer when selecting colors. This was originally ignored due to an older optimization used for single layer images.

    Balooii made many improvements to boost performance when loading a large number of fonts. While some lag remains and will likely require us to update to GTK4 , the initial GIMP start-up, typing in the text tool, and closing font lists should be much faster!

    Ondřej Míchal and Jehan have begun making changes to GIMP ’s codebase to support an eventual GTK4 port. This includes swapping out the deprecated gtk_widget_show () functions with gtk_widget_set_visible () , replacing direct access to GdkEvent types with getter functions, replacing GDK_WA_CURSOR flags for explicit gdk_window_set_cursor () calls, and more. Even though we are not yet planning a GTK4 port, it doesn’t hurt to start preparing for it!

    New contributor Ryan McDonald and Idriss Fekir have fixed an issue where the end of a line might be hidden on the left/right side when the text layout is set to “fixed”. When loading older XCFs, the problem will still be visible, but any changes to the text layer will update it to the correct view.

    Kaushik B. has fixed an issue with the Heal Tool where you might get dark smudges if you move outside the bounds of a layer that’s smaller than the image canvas.

    New contributor Manu Cornet and Jehan fixed a crash that could happen in certain circumstances when pressing keys too quickly after releasing the spacebar when panning.

    Brandon Henderson reduced the sensitivity of the pan gestures when using the touchpad on macOS. This should make it easier to make fine-grain adjustments while editing an image on that platform!

    Richard Gitschlag has adjusted the Text Tool so that you can still select the text to edit even if it has a layer mask that partially covers it.

    Jacob Boerema resolved a bug in our metadata code that prevented GIMP from loading the Licensor metadata for an image.

    Alx Sa added a maximum width of tooltips, preventing options with long descriptions from filling the entire screen.

    Rodrigo Lledó Milanca updated our information on the ART Camera RAW plug-ins.

    Several bugs related to rasterized vector layers have been resolved. Thanks to BobsDaughter , teapot , and Richard Gitschlag for their testing and feedback!

    New Rotation Stylus Dynamics Input

    Jehan recently implemented a new dynamic input for painting - Rotation (also known as Barrel Rotation ). This feature is prominently used in the original Wacom Art Pen and newer Wacom Art Pen 2 pens, and allows GIMP to react to how you have rotated the brush in your hand as you draw.

    You can adjust this value for custom brushes in the Dynamics editor . The MyPaint Brush tool is integrated with this feature as well, so it will automatically pass the rotation on as you paint if your stylus supports it.

    OS and Platform Specific Improvements

    GIMP uses GTK3 , a cross-platform library for GUIs, to display its windows, widgets, and more. While it does a very good job of this, GIMP requires a lot of very complex interactions, and sometimes this can expose bugs that are only visible on certain platforms.

    Bruno Lopes has been hard at work making a staggering number of platform-specific improvements to make GIMP work better. These include (but are not limited to):

    • Using “Server-side Decorations” for dialogs on KDE instead of GNOME -style “Client-side Decorations”. (In other words, the buttons appear at the bottom of the dialog instead of the header bar).

    • Secondary “pop-up” windows such as the resource selection and metadata editor dialogs should now appear in front of the first dialogue on Windows and macOS.

    • The System theme now uses your system’s defined accent colors on Windows and macOS.

    • Many improvements to proper focus setting on Windows and macOS.

    • Improvements to multi-window mode operations on Windows and macOS.

    • More system theme leaks caught on KDE Breeze system themes. This should help with graphical glitches in the UI .

    • We now depend on winflexbison on Windows for building the Image Map plugin . This fixes an issue where Windows users couldn’t reopen their image maps, even when created with GIMP .

    • Send to Email now works on MS Windows too using MAPI (works with Thunderbird and Outlook Classic).

    • Windows users can now use “Open With” on multiple files on start, without creating multiple instances of GIMP . This is consistent with how Linux and other platforms operate.

    Because these improvements are wide-ranging, it is possible that we missed some interactions during testing that could cause a regression. If you notice any problems in GIMP 3.2.6, please let us know !

    New macOS Package

    Starting with GIMP 3.2.6, the .dmg package is now created at the same time as the Linux and Windows packages. This has not been possible for many years!

    We used to create binaries for macOS on a separate GitLab repository, which was mirrored to another repository on GitHub, which was connected to a proprietary CI service (CircleCI) which then was connected to a MacStadium runner. All of that with dozens and dozens of additional patches, scripts etc! As you can see, this was extremely complicated, but it was the only way to ship macOS binaries back then.

    Thanks to your donations , we were able to sponsor a MacBook Pro M5 for Bruno Lopes , who has been working since December 19, 2025 to fix that situation. As a result, GIMP can now be easily built on macOS with both MacPorts and Homebrew packages.

    The macOS version of GIMP is now much more integrated with system-specific features, similar to the Linux and Windows version. A few examples:

    • Titlebars on macOS now follow the dark/light mode settings of the current theme.

    • Scrollbars now follow the macOS preference for whether they should be always visible or not.

    • The more standard ~/Library/Caches/ location is used for storing caches of GIMP resources, fixing a bug of brushes directory not being created on macOS.

    • GIMP ’s number input buttons now respond to Cmd on macOS, like they do to Ctrl on other platforms. Some standard Mac shortcuts like, Ctrl + F2 , Cmd + Shift + / / Cmd + Ctrl + Space and Cmd + ` work as well.

    • Meta and Hyper modifiers now work.

    • Incorrect offsets when drag-n-dropping colors and layers/channels/paths have been fixed.

    • Filters now accept negative values regardless of your system language settings.

    • Plug-ins are treated as children of the main GIMP application, so they do not appear in the dock anymore.

    • GIMP custom cursors are now properly set for all tools (previously, they were being overwritten by the macOS arrow).

    • GIMP ”, “Windows” and “Help” menus now match the standard macOS menus with proper localization.

    • Dialogs that shouldn’t be minimized (such as the search actions dialog shown with / ) no longer show a minimize button on macOS.

    • Remote files can be opened thanks to using the native macOS API , since GIO does not support HTTPS on this platform.

    • Dashboard Backtraces are now supported using libunwind from libSystem.

    In the process of implementing all these improvements, the separate macOS “developer package” was dropped. It was created due to the limitations of the previous macOS build infrastructure and became unnecessary now that it is way easier to build GIMP on macOS.

    Plug-in and script developers should use the new GIMP SDK instead, or build GIMP directly.

    Again, this is a brand new package. So, if you notice any problems in GIMP 3.2.6, please let us know !

    Security updates

    GIMP has added support for importing many different file formats over the years. In recent years, security detection tools have improved and found more and more potential exploits in open source software. Jacob Boerema and Alx Sa have been busy testing and patching these.

    For reference, the following Common Vulnerabilities and Exposures ( CVE ) have been patched in this release:

    CVE -2026-18301, CVE -2026-18304, CVE -2026-18302, CVE -2026-18303, CVE -2026-18305, CVE -2026-18306, CVE -2026-18307, CVE -2026-18308, CVE -2026-18309, CVE -2026-62438, CVE -2026-62439, ZDI - CAN -29400, CVE -2026-59087, CVE -2026-59088, CVE -2026-59089, CVE -2026-66757, CVE -2026-59090, CVE -2026-59091, CVE -2026-66758, CVE -2026-66759, CVE -2026-78465, CVE -2026-78475, CVE -2026-79902, CVE -2026-80101, CVE -2026-82324, CVE -2026-82328, CVE -2026-82330, CVE -2026-82343

    We want to thank Jace , Brent Hull , Tristan Madani , Florent Saudel , bb1abu , Yukihiro Nakamura , Securin Disclose , and Zero Day Initiative for their security reports and suggestions. We also want to thank Michael Catanzaro for his help in organzing these reports and requesting CVEs for them.

    For Plug-in/Script Authors and Builders

    Our GdkPixbuf dependency minimum version has been updated to 2.32.0 due to an issue with Glycin printing a bunch of unnecessary messages on start-up related to a deprecated to-pixdata function.

    PDB commands now only show error/warning messages when run in interactive mode. For non-interactive modes, you won’t see anything printed in the console on PDB function failure. Instead, you can check the return values of the function and provide any messages you want to users.

    Jehan improved our method for checking if a plug-in has been updated since the last time you opened GIMP . Now we check creation time (ctime) instead of just modified time (mtime) since it might be always 0 on certain packages like flatpak. This should mean that changes you make during development are more likely to be loaded if you’re testing on flatpak.

    Kamil Burda fixed documentation for integer and double types in the Procedure Browser .

    Pranav P corrected a build issue that caused a freeze on s390x systems.

    GIMP SDK

    You can now build C plug-ins and GEGL filters from all the official packages we distribute by using the gimptool commandline tool. That is because we now ship all required headers and libraries for compiling (in total, less than 20MB ).

    Before now, this was possible only on flatpak and Snap. So, Bruno Lopes extended it to the AppImage, Windows and macOS packages. We call this new feature the “ GIMP SDK ”.

    Take a look at the build instructions if you are interested.

    Around GIMP

    GIMP 3.2 Help Manual Updates

    Jacob Boerema , maintainer of the GIMP help manual repo, has released an updated version that contains all the changes brought in GIMP 3.2. It is available online , or you can download it if you want to keep a local copy.

    Historical News

    Balooii has been working to restored older news posts that have been lost to the ages. You can now see almost all news posts from 2004 to 2008 on the main site now - just navigate back to that point in time in the archive .

    GEGL and babl

    GIMP 3.2.6 also shares a release with new versions of GEGL and babl by maintainer Øyvind Kolås !

    babl 0.1.128 includes several fixes for building on macOS, initial WebAssembly support, and better checks at runtime for avx512 - all by Bruno Lopes .

    GEGL 0.4.72 updates its OpenCL support to version 3.0. Ondřej Míchal worked on important stability fixes for the OpenCL code (though such code path is still disabled by default in GIMP ). Jacob Boerema made several fixes to the RGBE file format import and export functions. Aruius made the GeglColor comparison functions public, for future use in better comparing comparing colors in GIMP and other software. Tal Regev added support for building GEGL using only MSVC , and Bruno Lopes added support for WebAssembly as well. Luigino Camastra added more security checks to prevent potential overflows.

    More details can be found in the GEGL NEWS document!

    Release Stats

    Since GIMP 3.2.4 , in the main GIMP repository:

    • 179 reports were closed as FIXED .
    • 104 merge requests were merged.
    • 871 commits were pushed.
    • 21 translations were updated: Belarusian, Brazilian Portuguese, Chinese (China), Dutch, Georgian, German, Hebrew, Hungarian, Kazakh, Lithuanian, Norwegian Bokmål, Norwegian Nynorsk, Slovenian, Swedish, Serbian, Slovak, Spanish, Thai, Turkish, Ukrainian, Vietnamese.

    58 people contributed changes or fixes to GIMP 3.2.6 codebase (order is determined by number of commits; some people are in several groups):

    • 22 developers to core code: Bruno Lopes, Alx Sa, Jehan, Ondřej Míchal, balooii balooii, Richard Gitschlag, Michael Natterer, programmer-ceds, Ahmed E. Yassin, Andreas Vukman, Estecka, Idriss Fekir, Jacob Boerema, Manu Cornet, Petr Vorel, Ryan McDonald, balooii, cheesequake, kaushik_B, screem02, v4vansh, woot000.
    • 14 developers to plug-ins or modules: Alx Sa, Bruno Lopes, Ondřej Míchal, Jacob Boerema, Jehan, Dimitriy Ryazantcev, lloyd konneker, balooii balooii, Frank Teklote, Harsh Verma, Michal Vašut, Mike Gorse, Richard Allen, Rodhos.
    • 23 translators: Dick Groskamp, luming zh, Martin, Yuri Chornoivan, Ekaterine Papava, Rodrigo Lledó, Aefgh Threenine, Anders Jonsson, Kolbjørn Stuestøl, Baurzhan Muftakhidinov, Emin Tufan Çetin, Aurimas Aurimas Černius, Jose Riha, Марко Костић, Rafael Coelho Costa, Trần Ngọc Quân, Vasil Pupkin, Balázs Úr, Carsten Drewes, Juliano de Souza Camargo, Kjartan Maraas, Sabri Ünal, Yaron Shahrabani.
    • 3 theme designers: Bruno Lopes, Alx Sa, Ondřej Míchal.
    • 9 build, packaging or CI contributors: Bruno Lopes, Jehan, Jacob Boerema, Petr Vorel, Harsh Verma, Lukas Oberhuber, Ondřej Míchal, balooii balooii, lloyd konneker.
    • 3 contributors on other types of resources: Jehan, Bruno Lopes, Aryeom.
    • The gimp-data submodule had 16 commits by 7 contributors: Bruno Lopes, Jehan, Alx Sa, Anders Jonsson, Denis Rangelov, Lukas Oberhuber, balooii balooii.
    • 4 image creators: Bruno Lopes, Jehan, Anders Jonsson, Lukas Oberhuber.
    • 1 icon designers: Denis Rangelov.
    • 1 cursor designers: balooii balooii.

    Contributions on other repositories in the GIMPverse (order is determined by number of commits):

    • Our UX tracker had 3 reports closed as FIXED .
    • babl 0.1.128 is made of 70 commits by 3 contributors: Bruno Lopes, Øyvind Kolås, Jehan.
    • GEGL 0.4.72 is made of 234 commits by 28 contributors: Bruno Lopes, Ondřej Míchal, Øyvind Kolås, luming zh, Jacob Boerema, Jehan, Kolbjørn Stuestøl, Tal Regev, WarisMaqbool, Aefgh Threenine, Anders Jonsson, Martin, Yuri Chornoivan, Baurzhan Muftakhidinov, Dick Groskamp, Ekaterine Papava, Sabri Ünal, aruius, Alan Mortensen, Asier Saratsua Garmendia, Chao-Hsiung Liao, DiGro, Marco Ciampa, Rodrigo Lledó, Saikeo Kavhanxay, Thomas Manni, YOSHIDA Shigeto, Марко Костић.
    • ctx had 150 commits since 3.2.4 release by 3 contributors: Øyvind Kolås, Bruno Lopes, Tal Regev.
    • The gimp-test-images (unit testing repository) repository had 5 commits by 1 contributors: Jacob Boerema.
    • The flatpak release had 35 commits by 3 contributors: Bruno Lopes, Erick555, Jehan.
    • Our main website (what you are reading right now) had 182 commits by 7 contributors: Bruno Lopes, Jehan, Alx Sa, balooii balooii, balooii, Liam Quin, Allan Day.
    • Our developer website had 110 commits by 5 contributors: Bruno Lopes, Jehan, Alx Sa, aruius, Ondřej Míchal.
    • Our 3.0 documentation had 276 commits by 20 contributors: Jacob Boerema, Dick Groskamp, DiGro, Kolbjørn Stuestøl, Marco Ciampa, Anders Jonsson, Yuri Chornoivan, Марко Костић, Richard Gitschlag, Alx Sa, Baurzhan Muftakhidinov, Christian Kirbach, Mateusz Jastrząb, YOSHIDA Shigeto, Andre Klapper, Balázs Úr, Chas Belov, Kristjan ESPERANTO , Rodrigo Lledó, Víttor Paulo Vieira da Costa.

    Let’s not forget to thank all the people who help us triaging in Gitlab, report bugs and discuss possible improvements with us. Our community is deeply thankful as well to the internet warriors who manage our various discussion channels or social network accounts such as Ville Pätsi, Liam Quin, Michael Schumacher and Sevenix!

    *Note: considering the number of parts in GIMP and around, and how we get statistics through git scripting, errors may slip inside these stats. Feel free to tell us if we missed or m

    Downloading GIMP 3.2.6

    You will find all our official builds on GIMP official website (gimp.org) :

    • Linux AppImages for x86 and ARM (64-bit)
    • Linux Flatpaks for x86 and ARM (64-bit)
    • Linux Snaps for x86 and ARM (64-bit)
    • Universal Windows installer for x86 and ARM (64-bit)
    • Microsoft Store for x86 and ARM (64-bit)
    • macOS DMG packages for Intel/x86 and Apple/ ARM hardware (64-bit)

    Other packages made by third-parties are obviously expected to follow (Linux or * BSD distributions’ packages, etc).

    What’s Next

    Work these days has mainly and already shifted to the development series which will eventually lead to GIMP 3.4 versions. For anyone who missed it, the Development Update, August 2026 news is interesting on this aspect. In the meantime, we will obviously still continue backporting bug fixes on the 3.2 series, of which GIMP 3.2.6 is a part of.

    This new version should widely improve stability, and in particular it looks like macOS users should particularly appreciate it (thank Bruno for that)! We are also extremely thankful to the new skilled contributors the project has been getting. Don’t forget that, as long as you don’t use genAI in your toolset, everyone is very welcome to participate! 🤗

    Don’t forget you can donate and personally fund GIMP developers , as a way to give back and accelerate the development of GIMP . Community commitment helps the project to grow stronger!

    • Pl chevron_right

      Matthew Garrett: SystemIO conflicts are not firmware bugs

      news.movim.eu / PlanetGnome • 2 days ago • 5 minutes

    I’m looking at something entirely unrelated, but tripped over some search results that made me realise that a lot of people still think getting errors like ACPI Warning: SystemIO range 0x0000000000001828-0x000000000000182F conflicts with OpRegion 0x0000000000001800-0x000000000000187F indicate a firmware bug. This is generally untrue. We need to dive a little into what ACPI is to clarify why.

    The Advanced Configuration and Power Interface 1 specification defines a whole bunch of stuff, but what’s interesting to us here is the hardware abstraction it performs. While PCs are nominally a well-defined platform that’s really not true at the hardware level once you get beyond a certain level of complexity. When you suspend a system you want to power down the hardware in the correct order, for instance, and knowing what that order is requires you to know details about the specific motherboard design. The approach taken in the embedded world is to just bake that knowledge into the OS in some form, which is how we end up with Devicetree . ACPI takes an alternative approach - rather than provide that information as data that has to be consumed by OS drivers, it distributes it as code.

    The ACPI Source Language, or ASL, is a simple language that gets compiled into a bytecode that’s then interpreted by the OS at runtime. One of the features of this language is the ability to define “Operation Regions”, effectively structure definitions that describe access to underlying hardware. Let’s imagine a simple device with two exposed registers. The first is an index register - it describes which internal register we want to access. The second is a data register, where reading it gives us the value of the internal register whose address is currently in the index register, and writing to it modifies that register. An example operation region declaration would look something like

    1
    2
    3
    4
    5
    6
    
    OperationRegion(OPR1, SystemIO, 0x400, 0x2)
    Field(OPR1, ByteAcc, NoLock, Preserve)
    {
      INDX, 8
      DATA, 8
    }
    

    This defines an operation region called “OPR1” at IO port 0x400, 2 bytes long. Inside it are two 8-bit fields, INDX and DATA. These are to be accessed one at a time, do not need the ACPI interpreter to take a global lock when accessing them, and if a subset of the register is modified then the other values should be preserved (irrelevant in this case since the fields are only a byte wide). Now any references to INDX or DATA in this scope will trigger accesses to those registers. So, a method to read the value of register 0x03 would look something like:

    1
    2
    3
    4
    
    Method (RD03) {
      INDX = 0x3
      Return (DATA)
    }
    

    ie, set INDX to 3, and then read the value of DATA and return it. But! What if another ACPI method is running at the same time? Let’s say we have one that writes to register 0x05:

    1
    2
    3
    4
    
    Method (WR05, 1) {
      INDX = 0x05
      DATA = Arg1
    }
    

    What happens if RD03 executes while we’re part-way through WR05? INDX might get reset to 0x03, and now WR05 will modify register 0x03 instead of 0x05. Oh no! But we can avoid this - we declare a mutex ( Mutex (MUTX, 0x00) ), and update our methods to be something like:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    Method (RD03) {
      Acquire (MUTX, 0xFFFF)
      INDX = 0x3
      Local0 = DATA
      Release (MUTX)
      Return (Local0)
    }
    
    Method (WR05, 1) {
      Acquire (MUTX, 0xFFFF)
      INDX = 0x05
      DATA = Arg1
      Release (MUTX)
    }
    

    Each method takes a lock (waiting up to 0xffff milliseconds and then erroring out if it doesn’t), and performs the access. There’s now no chance of a race. Phew!

    Now suppose someone writes a Linux driver for this piece of hardware. It accesses the hardware directly, with no knowledge of ACPI. What stops the driver from racing against one of the ACPI access methods? Nothing at all. Oh no! Again! This isn’t hypothetical, by the way - here’s a relatively harmless example, but back in the day we did trip over cases where temperature monitoring chips would be accessed by the firmware and Linux simultaneously and as a result you might end up thinking you’re reading a temperature when you’re actually reading a status flag, resulting in an impossibly high temperature and an immediate thermal shutdown.

    In this case, the kernel saves you from this (potentially hardware damaging) outcome by printing a message like ACPI Warning: SystemIO range 0x0000000000000400-0x000000000000401 conflicts with OpRegion 0x0000000000000400-0x0000000000000401 (OPR1) , telling you that the kernel has detected that a driver is attempting to allocate IO ports 0x400-0x401, but that there’s an ACPI operation region called OPR1 that is claiming the same addresses. The kernel isn’t in a position to know what type of access the firmware might perform in that region, so assumes that it might be dangerous and blocks the driver from loading.

    But all is not lost! The kernel also prints some helpful advice, ACPI: If an ACPI driver is available for this device, you should use it instead of the native driver . And ACPI tables will often actually have a definition that looks like this:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    Device (HDW1)
    {
      Name (_HID, "VEND0001")
      OperationRegion(OPR1, SystemIO, 0x400, 0x2)
      Field(OPR1, ByteAcc, NoLock, Preserve)
      {
        INDX, 8
        DATA, 8
      }
      Mutex (MUTX, 0)
      Method (RD03) {
        Acquire (MUTX, 0xFFFF)
        INDX = 0x3
        Local0 = DATA
        Release (MUTX)
        Return (Local0)
      }
    
      Method (WR05, 1) {
        Acquire (MUTX, 0xFFFF)
        INDX = 0x05
        DATA = Arg1
        Release (MUTX)
      }
    }
    

    which defines an ACPI device and associated methods. The _HID field defines the device type, and a Linux driver can be written that will be automatically loaded if a device with type VEND0001 is seen. That driver can then call ACPI methods associated with the device and access the resources in a way that matches the firmware’s expectations.

    (Interested in writing such a driver? I wrote a guide back in 2009)

    The firmware did absolutely nothing wrong here 2 , but trying to load the native ddriver will generate an error and the internet will tell you that PC firmware developers are incompetent 3 and you should pass a kernel argument that overrides this behaviour and it never did them any harm, and it probably won’t do you any harm either but it might and you might never know why your system occasionally wedges or catches fire.


    1. The ACPI spec used to live at acpi.info , but sadly that seems to have vanished some time after UEFI took over stewardship of the spec ↩︎

    2. You might argue that the firmware should simply not do anything at runtime because it is not the firmware’s job to do that, and I do understand that and you can certainly boot with acpi=off if you want to and no ACPI code will be executed at runtime. Let me know how that goes. ↩︎

    3. I’m not going to present an opinion on that here, merely say that this provides no supporting evidence for that assertion ↩︎

    • Pl chevron_right

      vixalien: Project Final Report: Adding Debug Adapter Protocol Support to GJS

      news.movim.eu / PlanetGnome • 4 days ago • 12 minutes

    Hello again! A few weeks ago, I wrote about the work I've been doing this summer adding Debug Adapter Protocol (DAP) support to GJS as part of Google Summer of Code (GSoC) 2026. If you haven't read that post, start there for the background on what GJS and DAP are and why this matters.

    As my GSoC is wrapping up, I wanted to share you an update on what I've done, what I've learnt, and what I'm planning for the future.

    Instead of a lengthy report, I actually want to walk you through debugging a real GJS application using the DAP support I've added to GJS.

    By the end of this post, you'll know how to launch a GJS app in Zed, set breakpoints (including on exceptions), step through code, inspect variables and more, all from inside your editor.

    Setting Up

    The code I've implemented is currently in a Merge Request being reviewed , so to you use it, you will need to clone and build GJS from source (until GNOME 52).

    Cloning and Building GJS from source

    You can build GJS from source by following the Hacking guide , but here's a shorter version of it

    # 1. Clone GJS
    git clone https://gitlab.gnome.org/GNOME/gjs.git
    cd gjs
    
    # 2. Checkout my branch
    git checkout wip/vixalien/dap
    
    # 3. Setup meson
    meson setup _build
    
    # 4. Build GJS
    ninja -C _build
    
    # 5. Verify
    meson devenv -C _build gjs-console ../script.js
    

    This will be required before GNOME 52.

    Please note the path where you cloned GJS (e.g. ~/Projects/gjs ). We will need it later.

    Editor setup

    You will also need to download and install the Zed editor . The currently supported editors for GJS DAP are Zed and VS Code. We will use the Zed editor since it's more validated to work with the GJS DAP support currently.

    You will also need to install the GJS Debugger Extension for Zed , which is currently pending review to be included in the Zed extension store .

    But you can build it locally, by cloning my Extension . To install within Zed, Press Ctrl+Shift+X , then click "Install Dev Extension". A file picker will open, so navigate to the directory where you cloned the extension and select it.

    This will require a Rust toolchain to be installed, so the extension can be built.

    Let me know if you want to debug GJS apps from other editors (not just Zed).

    Navigating Around

    To make this concrete, I'm going to walk through debugging an standard example application.

    1. Setting up the application

    The application we are going to debug is a simple Calculator, as found in the GJS Examples

    Create a simple file called calc.js in a new project directory and save the contents of the Calculator app above into it.

    Then open the project in Zed as you normally would.

    Calc project open in zed

    2. Opening the Project in the Debugger

    To open the project in the Debugger, you can use the F4 key to start debugging.

    A dialog will then pop up asking for the Debugger configuration.

    1. Select the Launch tab to launch a new debugger instance.
    2. Select GJS as the debugger.
    3. Type calc.js as the program to debug.
    4. Disable "Stop On Entry" so that the debugger doesn't stop at the first line of the script.
    5. Press Ctrl+Enter or select "Edit in debug.json" to open the configuration file.

    GJS debugger launch options

    This will create a new configuration file at .zed/debug.json in the project directory, we will use this file to configure the debugger and make sure our debugger settings are saved across sessions.

    That file will look like this:

    // Project-local debug tasks
    //
    // For more documentation on how to configure debug tasks,
    // see: https://zed.dev/docs/debugger
    [
      {
        "adapter": "gjs",
        "label": "calc.js (gjs)",
        "args": [],
        "cwd": "/home/alien/Projects/calc",
        "program": "calc.js",
        "stopOnEntry": false,
      },
    ]
    

    We will need to make a small modification to it to point it to the GJS we just compiled (otherwise it will use the default GJS from our system, which doesn't have the unmerged DAP changes).

    This is needed before GNOME 52 is released (which means gjs will be able to do this natively).

    We will do it by adding a gjsPath field to the configuration in this format:

    ...
         "program": "calc.js",
         "stopOnEntry": false,
    +    "gjsPath": "flatpak-spawn --host meson devenv -C ~/Projects/gjs  --workdir . gjs-console",
       },
     ]
    

    Where ~/Projects/gjs is the path to the GJS repository you cloned.

    After making this change, press F5 again, and now you will see an option called calc.js (gjs) in the dialog's "Debug" tab.

    GJS debugger run dialog

    Click that configuration, and this will launch the debug configuration we just saved.

    Now you have a running GJS debugger session!

    Running debugger

    3. Navigating the Debugger

    At the bottom of the window, you will see a debug toolbar with various sections, panes and controls.

    Fret not! The debugger toolbar is simple to understand, as I will explain here below.

    Debugger controls

    The debugger toolbar is made up of controls at the top, then 3 horizontal panes.

    1. The controls bar

    This is where you have different buttons to control the state of the program. In order, we have the Pause/Resume button, Step Over (or Next) button, Step In, Step Out, then the Restart and Quit buttons.

    Controls bar

    2. The frames pane

    This pane shows the currently active stack frames (or call stacks).

    Frames pane

    This frame has another tab that shows the various set breakpoints.

    Breakpoints

    3. The console pane

    This pane shows the console output of the program and allows you to potentially execute commands (not yet supported in the GJS debugger).

    Console pane

    It has a different tab that shows the different scopes . Here, you can expand a scope to see variables inside that scope.

    Variables pane

    4. The terminal pane

    Last, but not least, the terminal pane shows regular terminal output from the running program. This is also not currently implemented in the GJS debugger.

    Terminal pane

    Debugging

    Now that you can navigate around the debugger, let's get to debugging!

    1. Using the debugger statement.

    The debugger statement is a built-in statement in JavaScript that pauses execution and allows you to inspect the current state of the program at the time it pauses.

    You can add a debugger statement to calc.js at the end of the file to test it out.

    Debugger Statement

    Then click F5 again to start debugging. This will launch the debugger and pause execution at the debugger statement.

    Note: Ignore the "the debugger statement is not allowed" message for now, but remember to remove it before building/shipping your application.

    The highlighted line is where the debugger paused execution.

    Paused Debugger

    2. Inspecting Variables

    With the debugger now paused, you can inspect the variables in the current scope.

    Click on a scope's name to expand the variables under it.

    Inspecting Variables

    You can click on one of the objects to inspect its properties, for example, in the module scope, click on Gtk to see all the widgets available in the GTK library.

    Inspecting Variable Properties

    Inspecting all types of variables is implemented and you can inspect numbers, booleans, strings, symbols, functions, classes and most other types of objects.

    3. Adding breakpoints

    Adding the debugger statement is not the only way you can stop execution, you can also quite easily add breakpoints by clicking on the line number you want to pause at in the editor.

    For example, let's add a breakpoint on the first line of the pressedEquals function.

    Adding Breakpoint

    Then we can stop and restart the debugger. In the running program, type a simple equation like 1+1 , then click = .

    Pressing Equals

    The debugger panel will now show that you're paused, and allow you to view the stack frames as well as the scopes.

    Equals Debugger

    With this approach, you can debug applications and pause execution at any point to inspect the state of the program.

    Also note that the breakpoints tab is now updated to show the breakpoint we just set.

    Equals Breakpoints

    Note: The main Calculator window might now appear as Frozen (e.g. with a "« gjs-console » is not responding" message). Don't worry, this is because the program is paused in the debugger.

    Note2: You can set/remove breakpoints anytime the app is running or before it starts.

    4. Stepping through the code

    With the application now paused, we can progressively move execution line-by-line by stepping through the code.

    To "Step Over" (execute the current line and move to the next one), press the "Step Over" button in the debugger toolbar.

    <video src="/images/posts/gjs-dap-report/equals-stepping.webm" loop muted autoplay controls></video>

    You can also click the "Step Into" button to step into a function call (or just step over).

    Here's an example where I've added a breakpoint on Line 40 (first line of pressedOperator button) and stepping into the updateDisplay function call.

    <video src="/images/posts/gjs-dap-report/step-into.webm" loop muted autoplay controls></video>

    Stepping back is currently not implemented.

    5. Breaking on Exceptions

    Another way to pause execution is to set to break on exceptions. The GJS debugger supports breaking on breakpoints that would either be caught (i.e. in a try {} catch {} block) or not caught (i.e. unhandled exceptions).

    You can set these options by going to the Breakpoints tab and then clicking either the "Uncaught Exceptions" or "Caught Exceptions" button (or both).

    Exception Breakpoints

    VS Code Extension

    I've also worked on a VS Code extension, which enables debugging GJS applications inside of VS Code, however it reamins highly experimental and many features are not working yet.

    This is because I focused on the Zed extension and it's the one I used during development extensively, so the VS Code extension is not as well tested as the Zed one, but I am also planning to improve it and submit it to the VS Code extensions marketplace in-time for the GNOME 52 release!

    You can find instructions to use the VS Code extension in it's repo . Here is an example of it debugging an application:

    <video src="/images/posts/gjs-dap-report/vscode.webm" loop muted autoplay controls></video>

    Challenges

    While working on this project, I had a few challenges:

    Firstly, I really had trouble working well because of the remote nature of GSoC, and sometimes collaborating with my mentor would get off-tracked because I tended towards working alone instead of realising my mentor was available to help me. For future participants, I would advise you to realise that your mentor is available to help you, instead of feeling like you should be 100% independent. In my experience, a mentor will usually point you to the right solution, or even help you understand topics you might otherwise get blocked on for too long.

    Code-wise, the most challenging part was getting the message parsing (i.e. sending DAP messages and receiving them through stdio) to work. I tried many approaches on my own (see point 1 above) but at the end it got resolved when I decided to ask my mentor for help.

    The issue was complex because we needed to have access to the standard input as a stream so we can parse the protocol's Content-Length: {nBytes}\r\n headers , then read the corresponding number of bytes exactly. My first instinct was to use Gio.DataInputStream directly, but it didn't because it wasn't possible to load Gio / GLib imports in the main realm. The solution was to create a few functions ( openInputStream , readLine and readBytes ) on the C++ side since it can use the Gio/GLib APIs, then expose them to the JS code that implements the DAP communication (and linking with Firefox/Spidermonkey's Debugger API).

    Another challenge I had was when implementing the VS Code extension. In the beginning, I wrote a Zed extension that would expose GJS' DAP capabilities to the Zed Editor. When working on a similar extension for VS Code, I got stuck a bit because VS Code doesn't have a native way to easily show the communications happening between the DAP client (in this case VS Code) and the DAP server (GJS), while Zed had an easy way to show them. This effectively hid a bug where Zed was sending/requesting an extra /r/n in the DAP requests & responses, while VS Code was not (they both implemented the standard differently). In the end, I created a wrapper script that would also log all the communications between the client and the server differently so I can diagnose that bug and fix it.

    A recommendation I would give to future GSoC participants is to also track time and progress well. When working on the project, I didn't regularly check my proposal and the different activities and their timelines, so I ended up moving/reprioritising tasks towards the end of the program, which could have been avoided if I always checked the timeline to make sure I'm still on track and adjusting early.

    Further Steps

    There are some remaining tasks that could be done to make the GJS debugger better, and here's some of them.

    1. Bring the VS Code extension to feature parity as the Zed extension ( see above ).
    2. Add support for debugging GJS applications in GNOME Builder: Currently blocked by GNOME Builder itself lacking DAP support
    3. Add support for evaluating expressions in the debugger when paused.
    4. Correctly stop/kill the script when the debug session ends.
    5. Enabling source map support, which will make debugging compiled GJS (and TypeScript!) applications (like GNOME Weather, GNOME Sound Recorder) easier.
    6. Testing and ensuring the debugger works well on macOS and Windows (I only tested on Linux).
    7. Redirect console.log and other output to the debug console.
    8. Allow attaching to already running GJS applications (potentially by implementing a SIGUSR1 handler and communicating via unix socket).
    9. Allow pausing the program that's being debugged (at any point).
    10. Implement setting or modifying variables in the debugger.
    11. Give information about the current exception when we hit an exception breakpoint (needs the VS Code extension).
    12. Maybe implement watching source code and live-reload of the code while debugging.
    13. Implement more DAP capabilities (e.g. function breakpoints, conditional breakpoints) to improve the debugging experience even more (including correct presentationHint )
    14. Show the scopes in a better way (e.g. merge the global and GjsGlobal scopes, potentially merge the class body scopes, etc...)
    15. Maybe support debugging the GNOME Shell??
    16. Maybe implement GJS debugging (and provide instructions) for other DAP clients like Emacs, Vim, etc. (see full list of tools implementing DAP here )
    17. Maybe add documentation for debugging a GJS application while developing with meson (will need to add a run_target ).

    Let me know if there's more support you may want, or if you'd like to work on any of these.

    Improving WASM Support

    As part of the GSoC project, during the initial community bonding period, I also worked on improving WASM support in GJS . The MR essentially connects WASM's event loop to the GLib main loop set up by GJS.

    Conclusion

    I would like to thank Google Summer of Code for selecting me to work on this project, which I hope will improve the experience of writing, debugging and improve GJS applications.

    I'd also like to thank the GNOME Project for hosting GJS, which is an important part of the GNOME ecosystem.

    Finally, I'd like to thank my mentor Philip Chimento so much for his important skills, guidance, and support while I was working on this project.

    You can reach out in the GNOME JavaScript room in Matrix: #javascript:gnome.org for any questions or feedback.

    • Pl chevron_right

      This Week in GNOME: #264 Version Picking

      news.movim.eu / PlanetGnome • 4 September 2026 • 4 minutes

    Update on what happened across the GNOME project in the week from August 28 to September 4.

    GNOME Foundation

    marimaj reports

    We’ve held an AUA on Reddit with GNOME’s new Board members last Saturday. Sri Ramkrishna — President, Jonathan Blandford — Vice-President, Maria Majadas — Chair, and Adrian Vovk — Vice-Secretary, answered all the proposed questions from the participants. You can read them in:

    https://www.reddit.com/r/gnome/comments/1vz7pja/meet_the_board/

    Thank you for joining us!

    GNOME Fellowship

    Peter Eisenmann says

    I posted about all the cool things I got up to in August as part of the GNOME Fellowship, read about it here :) https://blogs.gnome.org/p3732/fellowship-report-august-2026-rivendell/

    Sophie (she/her) says

    New month, new GNOME Fellowship report. You can read about my contributions in my August 2026 blog post .

    GNOME Core Apps and Libraries

    Files

    Providing a simple and integrated way of managing your files and browsing your file system.

    Peter Eisenmann reports

    Files, aka nautilus, received some great changes in the 51 cycle, here is a selection of my favorites:

    • AdwTabOverview is used in narrow mode
    • Slightly smoother navigation by delayed clearing
    • Show count badge when while dragging multiple files
    • Open locations from other apps in new tabs
    • Add an empty document menu entry in case of empty templates directory
    • Selection handling improvements:
      • Correctly restore focus and selection if a file gets removed
      • Don’t unselect when right clicking the view’s background
      • Don’t override manual selection with file operation results
    • Correctly raise the window when other apps call “Open location”
    • Type-to-search support in app chooser dialog
    • Accessibility enhancement, e.g. for filename entry feedback
    • More tests (📈 44%)

    PS: Ctrl+E is a not-yet-documented shortcut to focus the file chooser filename entry

    Peter’s work is funded by the GNOME Fellowship program. You can support the fellowship program via a donation .

    GNOME Circle Apps and Libraries

    Alexander Vanhee announces

    In Bazaar, we are dropping the dialog you sometimes see when installing an app that makes you pick a specific source, in favor of just putting the non-primary sources somewhere on the app’s page. This should make the most common case of just installing the normal version of the app faster and avoid confusion for new users who don’t know what option to install.

    pCuqMLpDEWOGymDrWsgVTjPG_other_sources.b4BFbw0g_ZKiead.webp

    Third Party Projects

    Lanséria reports

    Hey people, this week I’ve finally published the new version of PedantiK, 1.6.0, that includes new language packs!

    PedantiK is a game where you need to find the hidden Wikipedia page by guessing words one by one. The new version include a new English language pack, allowing you to play in English or French by installing what language you want!

    PedantiK is available through Flathub

    gsqhNHKakThAIyLfuRXUdIla_image.d4S9XA3C_1mXyY7.webp

    YwRORuVUzJqSriogkPckjDIU_main-window-mobile.C3M6VIrW_Z2fzwGV.webp

    Shell Extensions

    Christian W reports

    It’s sci-fi week for Gnome. This week cwittenberg published two purely-for-fun sci-fi extensions:

    Matrix turns your desktop into the familiar falling digital rain from The Matrix, while still keeping your normal desktop usable underneath it.

    Starfield takes things a little further into space, adding a Star Trek: The Next Generation-inspired starfield that makes it look like your desktop is flying through the stars.

    Both extensions preserve your existing wallpaper and renders the effects efficiently on the GPU using a shader, consuming hardly any CPU.

    Neither extension will make you more productive. They may, however, make staring at your desktop considerably more entertaining.

    Extension app: search for “Matrix code” Matrix: https://extensions.gnome.org/extension/10708/matrix-code-rain/ Source: https://github.com/cwittenberg/matrix-rain

    Extension app: search for “starfield” from @cwittenberg Starfield: https://extensions.gnome.org/extension/10743/starfield/ Source: https://github.com/cwittenberg/starfield

    Tomáš Gažovič reports

    RSS Feed GNOME Shell extension has a new release (version 9.0).

    Adding your feeds no longer means typing them in one by one: you can import the whole list at once from an OPML file, the same format you can export from pretty much any other reader. Export works too, so moving your feeds somewhere else is no problem.

    Accessibility also improved: the panel menu is now fully keyboard operable, and the view scrolls along to keep the focused item visible.

    Under the hood, the extension now checks whether a feed changed before downloading it, so refreshes are lighter on the network. Feed data also lives in a JSON store instead of GSettings, which handles larger feed lists better.

    Supports GNOME 46 to 51.

    Get it on EGO | Source on GitHub

    CFpWhkgVgmgZDUhszGsXftYG_ScreenshotFrom2026-09-0209-01-21.BLyg8zbI_moAbj.webp

    Miscellaneous

    Sophie (she/her) announces

    We are in the process of introducing a new decision-making process into the GNOME project. The specification of the RFC process is available as a merge request on GitLab . The discussion is happening on the respective Discourse thread . I am now announcing the start of the final comment period for the adoption of this RFC process. We are deviating from the proposal’s 14-day period for this occasion and instead will consider concerns raised up until October 4th at 23:59 UTC. All active GNOME Foundation members remain invited to contribute to the discussion.

    That’s all for this week!

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