• Pl chevron_right

      Aryan Kaushik: Open Forms is now 0.4.0 - and the GUI Builder is here

      news.movim.eu / PlanetGnome • 3 weeks from now • 3 minutes

    Open Forms is now 0.4.0 - and the GUI Builder is here

    A quick recap for the newcomers

    Ever been to a conference where you set up a booth or tried to collect quick feedback and experienced the joy of:

    • Captive portal logout
    • Timeouts
    • Flaky Wi-Fi drivers on Linux devices
    • Poor bandwidth or dead zones

    Meme showcasing wifi fails when using forms

    This is exactly what happened while setting up a booth at GUADEC. The Wi-Fi on the Linux tablet worked, we logged into the captive portal, the chip failed, Wi-Fi gone. Restart. Repeat.

    Meme showing a person giving their child a book on 'Wifi drivers on linux' as something to cry about

    We eventually worked around it with a phone hotspot, but that locked the phone to the booth. A one-off inconvenience? Maybe. But at any conference, summit, or community event, at least one of these happens reliably.

    So I looked for a native, offline form collection tool. Nothing existed without a web dependency. So I built one.

    Open Forms is a native GNOME app that collects form inputs locally, stores responses in CSV, works completely offline, and never touches an external service. Your data stays on your device. Full stop.

    Open Forms pages

    What's new in 0.4.0 - the GUI Form Builder

    The original version shipped with one acknowledged limitation: you had to write JSON configs by hand to define your forms.

    Now, I know what you're thinking. "Writing JSON to set up a form? That's totally normal and not at all a terrible first impression for non-technical users." And you'd be completely wrong, to me it was normal and then my sis had this to say "who even thought JSON for such a basic thing is a good idea, who'd even write one" which was true. I knew it and hence it was always on the roadmap to fix, which 0.4.0 finally fixes.

    Open Forms now ships a full visual form builder.

    Design a form entirely from the UI - add fields, set labels, reorder things, tweak options, and hit Save. That's it. The builder writes a standard JSON config to disk, same schema as always, so nothing downstream changes.

    It also works as an editor. Open an existing config, click Edit, and the whole form loads up ready to tweak. Save goes back to the original file. No more JSON editing required.

    Open forms builder page

    Libadwaita is genuinely great

    The builder needed to work well on both a regular desktop and a Linux phone without me maintaining two separate layouts or sprinkling breakpoints everywhere. Libadwaita just... handles that.

    The result is that Open Forms feels native on GNOME and equally at home on a Linux phone, and I genuinely didn't have to think hard about either. That's the kind of toolkit win that's hard to overstate when you're building something solo over weekends.


    The JSON schema is unchanged

    If you already have configs, they work exactly as before. The builder is purely additive, it reads and writes the same format. If you like editing JSON directly, nothing stops you. I'm not going to judge, but my sister might.

    Also thanks to Felipe and all others who gave great ideas about increasing maintainability. JSON might become a technical debt in future, and I appreciate the insights about the same. Let's see how it goes.

    Install

    Snap Store

    snap install open-forms
    

    Flatpak / Build from source

    See the GitHub repository for build instructions. There is also a Flatpak release available .

    What's next

    • A11y improvements
    • Maybe and just maybe an optional sync feature
    • Hosting on Flathub - if you've been through that process and have advice, please reach out

    Open Forms is still a small, focused project doing one thing. If you've ever dealt with Wi-Fi pain while collecting data at an event, give it a try. Bug reports, feature requests, and feedback are all very welcome.

    And if you find it useful - a star on GitHub goes a long way for a solo project. 🙂

    Open Forms on GitHub

    • Pl chevron_right

      Arun Raghavan: Notes from the PipeWire Hackfest 2026: Part 2

      news.movim.eu / PlanetGnome • 2:23 • 9 minutes

    (these notes are being posted in two parts to make the length more manageable, part 1 is here )

    Continuing from where we left off, about topics discussed at the PipeWire hackfest in Nice…

    DSP features

    We discussed a number of features related to digital signal processing blocks which are typically realised on specialised hardware (often a DSP core that can directly interface with physical audio inputs and outputs on your laptop/phone/…).

    There is currently no standard way for the firmware running on these DSPs to signal what features can be realised directly on DSP. We also would want to allow such features, if exposed from PipeWire, to be realisable on CPU.

    Now we do have a way to hide away signal processing in a specific node, which is the filter-graph parameter on the audioconvert node that wraps all audio nodes.

    We could extend this mechanism to allow the internal node (say the ALSA node implementation), to expose what filtering it can perform “in hardware” (i.e. the software running on DSP). This would allow the audioconvert to delegate some or all processing to the internal node, with fallbacks available on the CPU.

    We would need a number of pieces to do this, including:

    • Some standard definition of filters and associated parameters, so different implementations could have a standard “API” to express any given filter.

    • The DSP block would need to expose what features it has and how they might be used. We could imagine extending the ALSA UCM configuration to do that.

    • The audioconvert node would need to have a way to push down filter-graph params to the internal node, and negotiate what work it is doing vs. what is being delegated

    This is a non-trivial effort, but gives us some sketch of what might be possible.

    More DSP features

    In addition to standard filters, we spoke about two topics that have come up commonly in the past.

    The first is some way to expose the processing graph in the DSP, so PipeWire and other userspace daemons have a better view of what is happening on the DSP. With the ability to push dynamic topologies to DSP, there was some renewed interest in exposing and using the ASoC DAPM widget graph. As always, the devil is in the details.

    The second thing that came up is speaker calibration. There is a lot of processing and tuning that goes into driving speakers on modern devices as much as possible without destroying them. Some of these are one-time parameters decided at product design time, and some of these translate to runtime parameters based on voltage and current feedback from the speaker amplifier.

    For some systems (like Qualcomm platforms), speaker calibration might be run on each system start to perform dynamic tuning. We had some discussion of how this might tie in with the rest of the system for both determining the parameters (separate startup daemon vs. in-process initialisation), as well as uploading parameters to the speaker (some ALSA UCM extensions to load parameters on PCM open but before start, or preloading parameters into ALSA kernel controls and having the driver feed them in at the right point).

    Volume limits

    A way to set a limit on the maximum volume for a given device has been a common user request ([ 1 ] [ 2 ]). We discussed the possibility of creating a per-route property (with a fallback to the node, if there are no routes), which WirePlumber could manage to provide users a simple interface to control.

    Since the hackfest, Wim has already done some work on this, and we need to bubble this up as a more user-accessible setting.

    Performance

    A number of performance-related topics were discussed.

    The first was an option of a combined DSP mode, where instead of one port per channel, a node would expose one port for all the channels of the stream (but continue to run in the configured “DSP” format/rate). This would improve stream performance for non-JACK-like use-cases, especially in resource-constrained environments.

    On the WirePlumber side, there was a discussion about using LuaJIT instead of standard Lua. There are some compatibility issues to be determined there (such as language version supported, etc.), but there might be some quick performance wins to be made if this is feasible.

    There is a plan to move some of the WirePlumber core to Rust, and that might be a good time to also port over some of the more standard functionality that tends not to change from Lua to Rust (though that could happen in a Lua->C transition and does not really need to wait on a Rust port).

    Declarative Session Management

    Another interesting, and broader, thread is the imperative nature of WirePlumber scripts – that is, policy decisions and associated action are often interwoven. It might be helpful to be able to make a clearer split where all policy decisions are first run, and then decisions are translated into actions at one go.

    There are some historical choices that make this hard – for example, changing the profile of a device might create and destroy nodes, which makes it hard to be able to make decisions that are independent of the action. There were some ideas around redoing the profile concept such that all nodes are always exposed, but nodes could get a new state to signal availability (and profiles that would allow availability to change). That might make a declarative system possible to implement.

    We also discussed the possibility of a “transaction” system. Something that would allow a client to submit a set of objects (think links between nodes), and then “commit” that transaction. This would also help reduce the number of roundtrips between PipeWire and WirePlumber, and generally help performance.

    Bluetooth

    Being colocated with the BlueZ face-to-face meeting, we had representation from the BlueZ community, so we were able to dive into a number of topics related to Bluetooth, primarily LE Audio.

    The first topic was Auracast, the LE Audio system for broadcast audio, allowing listeners to tune into public broadcasts in a space, or to have a device stream audio to multiple headsets concurrently for shared listening. George had a demo system showing an implementation of Auracast with PipeWire, WirePlumber and BlueZ.

    We had some discussion of where this feature should live, and the consensus was that we would probably want a separate daemon to manage Auracast settings and loading up the appropriate nodes (either for receiving or sending) based on users’ preferences.

    This led to a more general discussion about the current split of the Bluetooth implementation in PipeWire being SPA modules, which include streaming and some policy, and a lot more policy living inside WirePlumber. We could, and likely should, move all of this into higher level PipeWire modules instead, which could make these easier to work with overall.

    There was also a discussion about the complexities of LE Audio, and the state of the current user experience with actual devices:

    • Device interop is not always great, as the spec is new, the BlueZ implementation is still being completed, and device implementations seem of variable quality
    • Reliable pairing/feature detection is hard, partly due to how BlueZ exposes the ability to talk to devices in Bluetooth Classic or Bluetooth LE modes
    • Pairing left/right pairs currently needs individual pairing, which does not seem to be needed by other implementations (Android for example)
    • Inter-device synchronisation might need some work as well

    While there is much work to be done here, the pieces are coming together for first-class LE Audio support on Linux-based systems.

    Audio analytics

    We also spoke about “analytics” – using local neural networks to implement things like text-to-speech, speech-to-text, language translation, or other forms of processing.

    These pose an interesting problem, because they look like a standard-ish audio stream on one side, but are effectively a sparse stream on the other side if we are talking about text. Even conversion between languages does not look like a standard filter, because the underlying model might consume a varying amount of data before generating an output, and the input and output lengths are not tightly correlated.

    While it should be possible to implement such a system with PipeWire, it is not quite clear whether we should . As the application space in this area becomes more mature, it may become clearer what the right place in the stack is for these features.

    Click detection and elimination

    We spoke about detecting and eliminating clicks at the stop or start of a stream.

    If an application is playing back audio, and suddenly stops (i.e. feeds silence, or just nothing), then the sudden drop in the signal might cause a click to be output. If you think of the corresponding waveform as representing the physical displacement of the speaker, then the drop to zero is like a sudden brake to a halt, which isn’t possible, and manifests as a jolt that you hear as a clicky noise. The same analogy holds for resuming from a pause, but in the opposite direction.

    The solution is usually to smooth out the end of the sound by fading out, but most applications do not do this, so this problem manifests quite clearly for most browser or application streams if you listen closely.

    Wim described a number of experiments he has done for detecting such abrupt changes in audioconvert , but he was not happy with the results. We discussed some of these approaches, and what might work as acceptable tradeoffs to capture the most common cases while still trying to respect the integrity of the signal being sent by the application.

    (sorry about the vagueness here, I missed taking more detailed notes)

    Miscellanea

    The rest of the discussion covered disparate topics that I don’t have long form notes on:

    • Hardware profiles: Shipping hardware-specific configuration for PipeWire and WirePlumber is hard. We discussed some approaches using context properties and conditions, but this is an area that needs more work.

    • Data loop management: PipeWire allows splitting work across data loops so different nodes in a graph can be assigned to different threads. This is currently an all-or-nothing system, where either all nodes go to a single data loop, or every node must be manually assigned a specific data loop. There was some desire to have the ability for there to be a default data loop to make the manual management less cumbersome.

    • ACP -> UCM: PipeWire inherits the ALSA card profile configuration from PulseAudio, which has been helpful in making the migration path smoother on most hardware. There was always some desire to have a single configuration system (probably ALSA UCM) for all hardware, but this likely needs some work on what we can express in UCM configuration, but we also need to clean up how we translate our UCM handling code (George has an RFC for this ).

    Thanks

    That’s it, thank you for reading if you made it this far, and a shout out to George, Mark, and others organising the event!

    It was great to see continued interest and so much exciting work that is yet to come. I hope to see more of the community in the next edition of the hackfest.

    • Pl chevron_right

      Arun Raghavan: Notes from the PipeWire Hackfest 2026: Part 1

      news.movim.eu / PlanetGnome • 1:07 • 6 minutes

    (these notes are being posted in parts to make the length more manageable, a link to the next part will come here when it is posted)

    The PipeWire community organised a hackfest in Nice , France, colocated with Embedded Recipes, the GStreamer hackfest, and a number of other events.

    In attendance were members of the upstream community, as well as folks interested in PipeWire from Collabora, Red Hat, Qualcomm, Stream Unlimited, Texas Instruments, and Valve. In some cases these were the same person wearing upstream and professional hats, as some of us often do! :)

    It was two days of fruitful and deep technical discussions, and lovely evenings hanging out in the Côte d’Azur. Shout out to George Kiagiadakis and Mark Filion for putting this together!

    A photo of the waters in Nice from a rooftop Beautiful view of the Côte d’Azur

    The topics were disparate and can be somewhat esoteric for folks who are not familiar with the Linux audio space. I will try to strike a balance between providing context and summarising the finer details we discussed. Please feel free to write in if I missed or can expand on anything.

    Multistream nodes

    A recurring topic for the last couple of years has been supporting multistream nodes. The PipeWire API currently offers a pw_stream interface that can offer a node with single input or output (closer to the PulseAudio API), and the pw_filter interface that provides a lower-level freeform API to individually manage ports on a node (closer to the JACK API).

    The stream API while convenient, can be a bit unwieldy for realising concepts such as loopbacks and filters, because each set of inputs and outputs needs to be implemented as an individual node. If you’ve ever loaded the loopback module , for example, you would have noticed that there are two nodes created for each instance.

    Wim has created a version of the API that allows a node to provide multiple streams, which allows us to keep the conveniences of the stream API, but more easily express ideas like the loopbacks, filters, etc. Each stream is effectively a group of ports on the node, and nodes can have an arbitrary number of input and output streams.

    The code on the PipeWire side is ready. The primary idea is there will be a PortConfig param per stream, and this is where the format of the stream, and other metadata expressed on port groups (which is essentially what a stream is) will live.

    We discussed what is needed in WirePlumber to make sure the linking logic adapts to this concept, and Julian will be implementing that in the coming weeks.

    Settings

    PipeWire has a generic metadata system based on the JACK API that is used for storing metadata (allowing you to attach a key/type/value, optionally attached to an object). This is also used by WirePlumber to provide its settings system (see wpctl settings ), along with some key features such as a schema and persistence.

    We discussed that it might be nicer to have the concept of settings as a first-class citizen, and possibly even standardise some settings for desktop wide usage (such as common processing elements). There was consensus that:

    • A new settings interface (instead of extending metadata) would make sense
    • The API should be asynchronous, and can fail
    • A schema for valid settings and their types could be exposed as a well-known metadata key
    • Implementors of the interface would perform validation

    Security

    We spoke about the current state of security for applications using PipeWire. For context, PipeWire has a fine-grained permissions model where each client can have selective access to what objects are visible to it, and what actions it may perform. There is also a less granular system, where a “manager” application can connect to the manager socket for full access. We broadly think about restricted security for sandboxed applications (primarily Flatpak).

    One scenario is sandboxed PulseAudio applications getting full access via the pipewire-pulse server on the host. The discussion on this concluded that there is a way for pipewire-pulse to forward enough security-related information from sandboxed applications for us to apply sandbox restrictions to them, and we need to make that system work.

    There was a discussion that it might be reasonable for our default policies to apply for all applications connecting to the regular PipeWire socket to be restricted (this does not prevent malicious applications from accessing the manager socket, but helps applications not do bad things erroneously).

    This might be disruptive to introduce as a default change, so we might implement it via an opt-in setting so that there can be some broader testing and refinement of default permissions before flipping the switch for all users.

    There are a number of mechanisms related to how security context properties are relayed, and how those properties are used by WirePlumber to determine permissions. We need to document and verify the expected behaviour here.

    Flatpak and Portals

    Relatedly there was a discussion about how things should fit in with Flatpak, and Sebastian Wick from the Flatpak team joined us briefly on the second day.

    There was some discussion of making sure the PulseAudio socket is provided to the sandbox in a similar way to the PipeWire socket, such that some additional security properties can be assigned from the host in a way that the sandboxed client cannot override.

    We agreed that we needed the ability for applications to specify with some granularity what permissions they require (via portals), and for us to grant only that (with user intervention, if needed). Broadly this is:

    • Playback (optionally enumeration of sinks)
    • Capture (optionally enumeration of sources)
    • Default visibility of only the application’s own nodes

    We also spoke about how we might want to associate PipeWire objects with applications. With Flatpak moving to using a cgroup for each application, this should become easier. We may also want to be able to have a way to associate a stream with a specific window (to, for example, share a window and its audio), which should be possible.

    It was also noted that for some classes of applications, we may want a way for users to allow some of these permissions at install time (for example, a remote desktop application asking permission on every start can be annoying). This is already possible with Flatpak manifests (which are static, but we might need to add some more options here), and there is a potential entitlement system being discussed (for server-driven overrides to be distributed for malicious applications, for example).

    Encapsulation and Collections

    One topic that came up last year is the ability to encapsulate a group of nodes such that they appear as a single node to other applications in the system. This could be useful for:

    • Collapsing all the output from an application so it appears to be providing a single stream
    • Grouping all the filters for a sink or source node, and making it appear as a single node with all the processing hidden away

    One piece to making such a system possible is to have a first-class notion of this group. Julian has an implementation of such an entity, called a “collection”. This is currently implemented on top of PipeWire metadata, but we agree that this is likely worth having an explicit PipeWire interface for.

    Once that is in place, we discussed the possibility of having a smarter “proxy” node that can act as the interface that translates from the “outside” of the encapsulated region to the “inside”, so that format selection, volume changes, etc. can properly be proxied to the underlying device, for example.

    Tooling improvements

    It was noted that the tools we have (such as pw-top and pw-dot ) can make it hard to get at some information, such as negotiated formats, rates, etc. They can also be “noisy” when we have a large number of filters and loopbacks.

    While we did not have a concrete plan to tackle this, some of us have been playing with LLM-based tooling to generate some helper code for this sort of thing. At least my attempts have been too sloppy to share as yet, but it should be possible to get something useful with a structured approach.

    That’s it for now. Watch this space for part 2!

    • Pl chevron_right

      Matthias Klumpp: Introducing pkgcli: A nicer command-line interface for PackageKit

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

    For almost two decades, the PackageKit package management abstraction layer has shipped with pkcon as its command-line client. pkcon does its job, but it was always kind of a “testing” front-end for the PackageKit daemon rather than a tool designed for everyday use. The focus has instead been on the GUI tools, automatic system updates, GUI application managers and other front-ends. Its command names mirror the D-Bus API almost one-to-one ( get-details , get-updates , get-depends ), output is very plain, and there is no machine-readable mode for scripting. Most importantly though, there has been no development on it at all for almost a decade, so pkcon was stuck in its rudimentary state from that era.

    Since a lot of changes will be coming to PackageKit, and testing the daemon and working with it from the command-line was not very pleasant anymore in 2025/2026, I decided to modernize the tool as part of my work as fellow for the Sovereign Tech Agency last year. pkgcli is the new command-line client for PackageKit. It is built from the ground up to be pleasant to use interactively and easy to drive from scripts.

    Why a new tool?

    Of course, instead of introducing a new tool, I could have just expanded pkcon instead. The problem with that approach is that the pkcon utility has been around for so long and its command-line API had ossified so much, that rather than changing it and potentially breaking a lot of scripts relying on its quirks, I decided to introduce a new tool instead. pkcon can still be optionally compiled for people who need it in their scripts and workflows.

    The goals for pkgcli , and the features it now has are:

    • Human-friendly command names. Verbs that read the way you’d describe the task, instead of mirroring the D-Bus API 1:1: show , search , list-updates , what-provides , instead of get-details and friends.
    • Readable, c o l o r e d output by default (still respecting NO_COLOR and degrading gracefully).
    • A real scripting mode. A global --json flag emits JSONL instead of fully human-readable output when possible, to make it easier to use the tool for scripting purposes.
    • Sensible defaults. A few defaults have been changed, such as the metadata cache-age, or automatic cleanup of unused dependencies being enabled by default. This is more in line with current defaults by other tools and frontends. We also print package information in a slightly different, more readable way.
    • Better handling of internationalized text . Text should now align properly in the terminal window, and we should no longer have completely chaotic text output on non-English locales (especially Chinese/Japanese).

    Why not pkgctl ?

    Originally, this tool was called pkgctl , to match other common cross-distro tool names. However, that name was already taken by an Arch-specific distro development tool . When this issue was raised, we decided to just rename our tool to pkgcli with the next release, to avoid the name clash on Arch Linux.

    Examples!

    Here are some examples on how to use the new tool (some of which include the abridged output pkgcli prints).

    Search for anything containing the string “editor” in name or description, then look at the details of one result:

    $ pkgcli search editor
     ace-of-penguins 1.5~rc2-7.amd64 [debian-testing-main]
     acorn-fdisk 3.0.6-14.amd64 [debian-testing-main]
     ardour 1:9.2.0+ds-1.amd64 [debian-testing-main]
     audacity 3.7.7+dfsg-1.amd64 [manual:debian-testing-main]
     audacity-data 3.7.7+dfsg-1.all [auto:debian-testing-main]
     augeas-tools 1.14.1-1.1.amd64 [debian-testing-main]
     emacs 1:30.2+1-3.all [debian-testing-main]
     gedit 48.1-9+b1.amd64 [debian-testing-main]
     gedit-common 48.1-9.all [debian-testing-main]
     gedit-dev 48.1-9+b1.amd64 [debian-testing-main]
    [...]
    
    $ pkgcli show nano
    Querying                  [████████████████████████████████████████] 100%
    Package: nano
    Version: 9.0-1
    Summary: small, friendly text editor inspired by Pico
    Description: GNU nano is an easy-to-use text editor originally designed as
     a replacement for Pico, the ncurses-based editor from the non-free mailer
     package Pine.
    [...]
    URL: https://www.nano-editor.org/
    Group: publishing
    Installed Size: 2.9 MB
    Download Size: 646.0 KB

    Search only within package names rather than descriptions:

    $ pkgcli search name python3

    Check for updates. refresh updates the metadata, then list-updates reports what’s available:

    $ pkgcli refresh && pkgcli list-updates
    Loading cache            [████████████████████████████████████████] 100%
     cme 1.048-1.all [debian-testing-main]
     gir1.2-gdm-1.0 50.1-2.amd64 [debian-testing-main]
     imagemagick 8:7.1.2.24+dfsg1-1.amd64 [debian-testing-main]
     imagemagick-7-common 8:7.1.2.24+dfsg1-1.all [debian-testing-main]
     imagemagick-7.q16 8:7.1.2.24+dfsg1-1.amd64 [debian-testing-main]
     libdlrestrictions1 0.22.0.amd64 [debian-testing-main]
     libfftw3-bin 3.3.11-1.amd64 [debian-testing-main]
     libfftw3-dev 3.3.11-1.amd64 [debian-testing-main]

    Explore relationships between packages:

    $ pkgcli list-depends inkscape  # list what inkscape depends on
    $ pkgcli list-requiring libappstream5  # list what requires libappstream5

    Find the package that provides a capability, here the AV1 GStreamer decoder:

    $ pkgcli what-provides "gstreamer1(decoder-video/x-av1)"
     gstreamer1.0-plugins-bad 1.28.3-1.amd64 [auto:debian-testing-main]

    You can also have JSON output for most commands! Attach --json to any query and pipe the result straight into jq . Each line is a self-contained JSON object:

    $ pkgcli --json list-updates | jq -r '.name'
    cme
    gir1.2-gdm-1.0
    imagemagick
    imagemagick-7-common
    imagemagick-7.q16
    libdlrestrictions1
    libfftw3-bin
    libfftw3-dev
    libfftw3-double3

    Try it

    pkgcli is built by default alongside the rest of PackageKit since PackageKit 1.3.4. If your distribution ships a recent enough PackageKit, it should already be on your PATH . You can read its man page man pkgcli for more information. Feedback, bug reports, and patches are very welcome .

    • Pl chevron_right

      Christian Hergert: Testing Keyboard Input Latency

      news.movim.eu / PlanetGnome • 1 day ago • 1 minute

    I occasionally see people go through great effort to do end-to-end testing of keyboard input latency. That is fantastic but it requires hardware and patience I don’t, nor will ever, have.

    Here is a much simpler way to get about 90% of the value. For example, everything but driver/interrupt handler latency and display link scanout/monitor visibility latency and of course your app side (but you could theoretically rig this up to do that too, inside your app). Not that those aren’t important, but they definitely fall into the category of things I personally cannot control for you.

    Keyspeed is a very simple GTK application which uses /dev/uinput to synthesize keypresses. Since it knows the time of provenance, it can compare that to when it gets the event back from compositor delivery.

    Wrap all that data up in Sysprof capture marks, pull in some from the compositor (GNOME Shell/Mutter support this), tie in some callgraphs/flamegraphs, and you have a very good overview of what is going on during your keypress.

    Run it like this (but remember to chmod back when you’re done less you have attack surface available).

    $ sudo chmod 660 /dev/uinput
    $ git clone https://gitlab.gnome.org/chergert/keypress
    $ sudo dnf install sysprof-devel libinput-devel gtk4-devel
    $ make
    $ sysprof-cli --gtk --gnome-shell capture.syscap -- ./keyspeed
    $ sysprof capture.syscap

    a screenshot of keypress. key being press/release on left, time it took on the right.

    Currently, this only shows you keypress send to receive in GTK, but if someone cared enough, you could make it take the next GtkFrameTimings and use that to get the presentation time. I don’t need that for what I’m doing, so it doesn’t.

    If you go to the marks section, you can dive in to a specific keypress/release cycle. Zoom in on just that section, switch back to callgraph/flamegraph profiler and see what was going on.

    Pretty simple, no special hardware needed.

    You can see how long it took, where time was spent, and more importantly, how much time was empty between things that matter.

    A screenshot of sysprof showing the marks section with timing information for minutia happening across GTK/Mutter for full event delivery timing.

    A screenshot of sysprof showing the marks section with timing information for minutia happening across GTK/Mutter for full event delivery timing.

    • Pl chevron_right

      Hylke Bons: Hello again, Planet GNOME!

      news.movim.eu / PlanetGnome • 2 days ago • 1 minute

    Greetings from Planet Peanut!

    Since there’s a whole new generation of GNOME contributors active right now, I’ll do a short reintroduction: Hello, I’m Hylke !

    I was a design contributor in the late 2.X, early 3.X days. Mainly icons and theming. I’ve attended many GUADECs .

    I’m also the developer of SparkleShare , a Git-based file sync app. Once a much used tool by the Design Team to collaborate on mockups, now in need for some love and care.

    After many years just lurking I’m happy to be officially back as a GNOME Foundation member now that Bobby has joined Circle .


    hello.png App icons created in recent months

    New plan

    I lost my job this year due to the big tech layoffs . Also dealing with burnout, it made me realise I need to go back to working on things that matter to me.

    I would love to contribute design full-time.

    If you like my work and want to support me, I’m trying to gather enough small monthly sponsors to support me with a basic income. Every little helps.

    My focus for 2026:

    • Supply a stream of icons to the Linux ecosystem by designing at least one app icon a week . Developers can request free icons .
    • Reboot SparkleShare . Finish the rewrite in Rust and redesign the interface with GTK4 and libadwaita .
    • Launch a FOSS design service . Make a plan for sustainably assist FOSS communities with product design work.

    I will post frequent updates here and on the Fediverse .

    Good to be back!

    • Pl chevron_right

      This Week in GNOME: #254 Fellowships

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

    Update on what happened across the GNOME project in the week from June 5 to June 12.

    GNOME Foundation

    marimaj reports

    The GNOME Foundation has selected the first recipients who will receive funding through its new Fellowship program, and is delighted to announce that Peter Eisenmann and Sophie Herold will begin work as our first Fellows in July.

    Sophie and Peter are both long-running GNOME contributors, with many significant contributions as members of the GNOME community. Sophie is known as developer of apps, libraries, and websites, including Loupe, Pika Backup, Glycin, and welcome.gnome.org. Peter is a long-standing Nautilus maintainer (officially known as the Files app), as well as an experienced contributor to platform libraries, including GTK and GLib.

    Full announcement: https://blogs.gnome.org/foundation/2026/06/11/announcing-our-first-fellows/

    Miscellaneous

    Philipp Sauberzweig reports

    I’m excited to share with you that I’ll be joining the Sovereign Tech Agency as a fellow for the GNOME Design Team starting in July. Check out the announcement and the full cohort of fellows in the official blogpost .

    During my two-year fellowship, I will support GNOME maintainers and developers with design feedback and reviews, create mockups, and coordinate efforts to standardize design patterns. My focus will be on increasing the visibility of design work, improving documentation, tools, and templates, and supporting the onboarding of new contributors.

    I’m looking forward to meeting many of you (again) at GUADEC and I’ll post more about my activities soon. I’m currently wrapping up projects from my previous job and taking some time off. See you all back in July.

    GNOME Core Apps and Libraries

    Maps

    Maps gives you quick access to maps all across the world.

    mlundblad reports

    Maps now shows departures (and arrivals) for public transit stops/stations (when data is available in Transitous)

    departures-buses.BRB5fbk0_ZcmhUU.webp

    departures-flights.B8wXH3ax_Z210nyf.webp

    departures-multiple.C_3yTjku_ZY03f9.webp

    departures-trains.UQdciuvK_ZrHy5J.webp

    GNOME Circle Apps and Libraries

    Tuba

    Browse the Fediverse.

    GeopJr 🏳️‍⚧️🏳️‍🌈 says

    This week, Tuba was ported to Android, opening up exciting new opportunities, as we get closer to the next release!

    Third Party Projects

    Jiri Eischmann reports

    Meshy 26.06 has been released . It’s the first stable release of MeshCore client for Linux written in Python, GTK 4, and libadwaita.

    It has a feature parity with the official client, but provides native look & feel striving for the best possible integration with the Linux desktop, primarily GNOME.

    You can install stable releases of Meshy from Flathub or developoment releases from the app’s flatpak repo .

    Stable releases are planned at a rate of once per month.

    meshy.Cy16YB4p_1XtshH.webp

    Anton Isaiev announces

    RustConn 0.16 Released

    RustConn just turned one year old, and 0.16 is out. Thank you to everyone who uses it and files reports - that feedback shapes every release.

    The biggest change this cycle is the move to IronRDP 0.15: bulk compression for lower bandwidth on slow links, slow-path rendering (XRDP and older Windows no longer show a blank screen), and better compatibility with GNOME Remote Desktop. Huge thanks to the IronRDP project and to all the open projects RustConn builds on for its connections.

    Other highlights, all requested by users:

    • Connections with notes now show a small badge in the sidebar, so you can see at a glance which entries have documentation (search also takes into account the content of notes).
    • Snap packaging caught up with the Flatpak build.
    • A lot of macOS fixes (Keychain, SSH password auth, tray).
    • A new Windows / WSL2 setup guide.
    • Plus many small GNOME HIG refinements across the settings dialog and sidebar.

    Homepage: https://github.com/totoshko88/RustConn Flathub: https://flathub.org/apps/io.github.totoshko88.RustConn

    RustConn.Rlu2AypV_yCMSK.webp

    austin says

    Gelly 1.6 was released this week. Gelly is a Jellyfin and Subsonic/Navidrome compatible player using GNOME technologies. The last month has seen an uptick in development and contributions, with a few major features added:

    • Gapless playback
    • UI polish, including a new compact mode
    • NFC card support with the companion gelly-nfc project
    • Favorites
    • Internationalization

    Gelly needs help with translations! Please see the README for details. Thanks to all that have already contributed!

    https://flathub.org/en/apps/io.m51.Gelly

    gelly_june_2026.DKfuNg51_ZYHTEX.webp

    Ans Ibrahim announces

    Memento , the movie and tv tracking app, got updates this week with version 1.3.0 :

    • Backup and Restore functionality was implemented
    • Import from Ticketbooth is supported
    • Import for Movary plays and watchlist is supported
    • Users can add plays without date

    Fractal

    Matrix messaging app for GNOME written in Rust.

    Kévin Commaille reports

    Fractal 14 has landed and is packed with lots of small changes, that make for an even better experience. Here is a quick reminder of the changes since Fractal 13:

    • Call rooms are identified with a camera icon in the sidebar and show a banner to warn that other users might not read messages in these rooms.
    • Calls are rendered in the timeline and incoming calls trigger a notification. We still don’t support calls, but at least now you know when someone is calling and can open another client to answer.
    • While we still support signing in via SSO, we have dropped support for identity providers, to simplify our code and a have a closer experience to signing in with OAuth 2.0.
    • The sidebar room filter has been improved: Enter goes to first room result, and there’s an empty state when no results match the term.
    • The performance of the room list has also been improved, it should be mostly noticeable for accounts that have joined a lot of rooms.
    • Informative events ( Unable to decrypt , server notices…) are now styled differently to reflect their special nature and differentiate them from regular text messages that anyone can send.
    • Sending files & location is properly disabled while editing/replying, as it doesn’t work anyway.

    As usual, this release includes other improvements and fixes thanks to all our contributors, and our upstream projects.

    We want to address special thanks to the translators who worked on this version. We know this is a huge undertaking and have a deep appreciation for what you’ve done. If you want to help with this effort, head over to Damned Lies .

    This version is available right now on Flathub .

    This cycle, we were lucky enough to get a higher than usual number of new contributors. Most of the changes listed above come from them. If you want to join the gang, you can start by fixing one of our newcomers issues . We are always looking for new members!

    fractal-utds-and-calls.C3136pYS_2vinAj.webp

    Shell Extensions

    Carlos Jiménez reports

    New version of Gnome Football extension, now with a calendar panel integration: https://github.com/carlosjdelgado/GnomeFootball/releases/tag/v2.0.0

    gnome-football-2-0-0.C_W1gaea_Z2lh7pg.webp

    Arnis (kem-a) announces

    Kiwi (is not Apple) brings a bit of macOS feel to GNOME without getting in the way of the desktop you already use. The idea is to help people coming from macOS settle into Linux and feel at home on GNOME right away. It is fairly feature-rich and modular: macOS-style window control buttons, window controls and titles in the top panel for maximized apps, battery percentage when you are getting low, and a calendar moved to the right with notifications tucked into Quick Settings, accent colored menu entries, among others. The restyling is deliberately minimal, so it plays nice with default Adwaita theme and the rest of your setup.

    The latest update v1.7.0 improves the dynamic blur implementation (of course, there is blur) to the top panel, dash via Dash to Dock, and the Overview background, and adds a smoother, slowed workspace switch transition.

    Install it from GNOME Extensions or get it from GitHub

    kiwi-is-not-apple-2._CWhqVBP_2fqhIU.webp

    Just Perfection says

    A new rule has been added to the EGO review guidelines to prevent GNOME Shell extensions from including unnecessary keys in metadata.json .

    That’s all for this week!

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

    • Pl chevron_right

      Hylke Bons: Hello again, GNOME!

      news.movim.eu / PlanetGnome • 3 days ago • 1 minute

    Greetings from Planet Peanut!

    Since there’s a whole new generation of GNOME contributors active right now, I’ll do a short reintroduction: Hello, I’m Hylke !

    I was a design contributor in the late 2.X, early 3.X days. Mainly icons and theming. I’ve attended many GUADECs .

    I’m also the developer of SparkleShare , a Git-based file sync app. Once a much used tool by the Design Team to collaborate on mockups, now in need for some love and care.

    After many years just lurking I’m happy to be officially back as a GNOME Foundation member now that Bobby has joined Circle .


    hello.png App icons created in recent months

    New plan

    I lost my job this year due to the big tech layoffs . Also dealing with burnout, it made me realise I need to go back to working on things that matter to me.

    I would love to contribute design full-time.

    If you like my work and want to support me, I’m trying to gather enough small monthly sponsors to support me with a basic income. Every little helps.

    My focus for 2026:

    • Supply a stream of icons to the Linux ecosystem by designing at least one app icon a week . Developers can request free icons .
    • Reboot SparkleShare . Finish the rewrite in Rust and redesign the interface with GTK4 and libadwaita .
    • Launch a FOSS design service . Make a plan for sustainably assist FOSS communities with product design work.

    I will post frequent updates here and on the Fediverse .

    Good to be back!

    ]
    • Pl chevron_right

      Laureen Caliman: Extending Libipuz

      news.movim.eu / PlanetGnome • 3 days ago • 1 minute

    From white-boarding my ideas on a Google Doc, to writing a formal design document in Crosswords, my ability to communicate technical ideas clearly is being put to the test.

    Writing documentation is critical to guide others’ understanding of the code and choices made on a particular codebase. Especially when several developers are introduced to the system, a way to reference material leads to more preparedness to contribute to the codebase.

    I wrote a design document introducing the concepts I would like to implement towards creating a way to generate a dynamic grid. Critique is welcome.

    Standard libipuz crosswords currently rely on using an existing dictionary to fill a static box of X length x Y width. However, the implementation of vocab puzzles goes against this logic and instead generates a new grid of N length x M width based on a list of 0 <= W <= 30 words of 1 <= L <= 25 characters long.

    I reconsidered the idea of using a GArray to store unplaced words because I want something idempotent. To avoid unwanted time complexity bloat, the backend should not carry the memory of unplaced words. Instead, the frontend will compare the generated grid against the original list to manage words that couldn’t be placed.

    Integrating this new feature will be a fascinating technical challenge.

    I created a new IpuzVocab class which inherits from IpuzCrossword. I learned how GNOME manages its developer documentation by writing a file myself to introduce this class. Writing this document made me think about the whole picture: how vocab puzzles handle grids, clues, and guesses, comparing it to standard crossword puzzles. I wrote the support to display a vocab puzzle in light and dark mode, with my next goal to integrate them via gi-docgen.