15 Sep 2025
Planet GNOME
Christian Hergert: Status Week 37
VTE
-
Little back-and-forth on what we can do to improve a11y further with VTE. Prototype'd a way to extract hyperlinks and provide them into AccessibleText, however that is not the right place.
We really need an implementation of the at-spi hyperlink API in GTK so that VteTerminal may implement it.
-
Merged a number of a11y fixes provided by Lukáš Tyrychtr which fix some of my original a11y implementation to follow the at-spi expectations better.
Also added one of my own to fix a potential uint underrun when describing runs thanks to
long
touint
conversion.
Ptyxis
-
Got a report of a bit of undesirable behavior when closing a window where close-able tabs are closed before showing the the special close dialog.
It's all more complex than I wish it was, because there are multiple ways we can enter that flow. Additionally, the asynchronous nature of closing tabs makes that state a bit "split brain" as it exists now. We may want to implement a "session" object to manage this stuff all in one place going forward.
-
When showing multiple tabs the "visual bell" background did not cover the entire headerbar. Quick CSS fix that.
-
Sebastian Wick needed a terminal with the Terminal Intents implemented so I took a crack at implementing that in Ptyxis. That allowed forward-progress on implementing the GLib side of things.
Doing so found a couple of things we want to address in the upcoming FreeDesktop terminal intent "standard" and thankfully they've been moving that forward (including the Ptyxis-side).
Libpeas
-
libpeas distro packaging was failing on the testsuite for Lua due to LGI not supporting girepository-2.0. Libpeas 2.x doesn't use girepository at runtime, so this is relegated to the testsuite.
For now, I've just disabled the Lua tests since they can't possibly work due to that girepository usage.
Some months back I provided patches for LGI to support girepository-2.0 but the project seems unmaintained and therefore hard for anyone to really say "yes merge this".
You can find some more information from Victoria Lacroix at https://www.vtrlx.ca/posts/2025/lgi-fork/
Builder
-
They don't get much testing during development so we had a small build regression on i686.
-
Spent a bunch of time on what will hopefully become Builder 50. This is a major rewrite on top of Foundry, Foundry-Gtk, and what will become Foundry-Adw in the 1.1 release of Foundry.
It is hard to describe how remarkably small this will make Builder as a project compared to previous versions. So much complexity in the Builder code-base was in response to all the async/finish flows required to keep things smooth. But now that we have libdex and libfoundry, it's just so easy to implement that sort of magic.
Libdex
-
Sebastian Wick had some great ideas on integrating libdex with gdbus-codegen. Discussed a few different ways we could go forward to make something ergonomic. It would be nice to implement both consuming as proxies and providing as skeletons with futures.
Libpanel
-
I noticed that the bottom corner buttons in Builder were not aligning with the external rounded corners of the window. That was fallout from a previous cleanup so fixed that up before release.
Template-GLib
-
Thanks to early testing by distributors we found an issue in the testsuite which was exercising GObject Introspection integration. It broke on 32-bit because the
gsize
parameters are different and I never implemented auto-casting of integers of different sizes.So if you did a call like
GLib.utf8_substring(str, i64(3), i64(-1))
and were on 32-bit that would fail since theoffset
/length
parameters areglong
which is sized differently.The quick fix that will still allow for errors to propagate was to implement auto up/down casting of numbers so long as they will fit in the destination type. Otherwise, you'll fail the cast operation and errors propagate as necessary.
This fix landed shortly before 3.38.0 but was tested on numerous architectures before release.
Foundry
-
Learned that even command-line tools get appdata now days so I went ahead and implemented that for the
foundry
CLI tool. -
We now dynamically link
foundry
binary. Originally I had plans to statically link it so that we can send it to a remote system and run it as a bridge. Since we aren't there yet anyway, it doesn't make sense to enforce that and/or make distributions patch it out. -
FoundryBuildManager
got a:busy
property which makes it much easier to implement UI like Builder has where you show a build button or a stop button based on status.It also got a new
stop()
method/GAction
for that too. This is a lot harder than it looks because you need to plumb through a cancellable to all of the build pipeline API which is going to be awaiting the first future of[cancellable, some_op]
.Was extremely happy to see it work on the first try which means I've done something right in the libdex design.
-
Once I did the above, adding a
rebuild
action and method was quite easy. We have all the necessary plumbing to either call an action or await a method future and get the same result. -
A last minute API was added to create a
producer
from aconsumer
PTY fd. Hopefully using this new nomenclature is not so confusing for people used to ancient PTY terminology which I know is extremely confusing to begin with. But we gotta move past those antiquated terms (which I wont repeat here) as they are both morally wrong and technically inaccurate. -
The
FoundryFileManager
can now automatically discover content-type when provided a filename. This vastly simplifies API usage when you have one-or-the-other to get a symbolic icon. Since we override many icons from the system, that is just a necessary abstraction. -
FoundrySearchResult
got an:icon
property which means it's basically usable to search UI now. Though there are not manyFoundrySearchProvider
s yet as they will land for 1.1. -
A new
context.file-manager-show
GAction
is provided which allows you to pass auri
as a"s"
-typedGVariant
. I feel stupid for not doing this a decade ago in Builder and quite frankly, it should probably just exist in GTK. -
Libpanel/Builder has this nice "Action Muxer" API for years now and that is exported in Foundry too so we can use it in libfoundry-gtk and libfoundry-adw. It's extremely handy when the built-in action support in GTK is not enough.
-
Foundry has a SQLite database of extended attributes on URIs when the underlying file-system does not support extended attributes. I made a little boo-boo there so made that to actually work.
-
Talked to dmalcom about supporting
SARIF
in Foundry for GNOME 50. They (the GCC project) would really like to see more consumers of it and Foundry is an obvious place to put that.It doesn't look terribly difficult and it should allow us to drop the whole "regex parsing of PTY content" if done right.
Foundry-Gtk
-
Fixed palette parsing and color application to VteTerminal.
-
Imported all the Ptyxis terminal palettes which can now be represented as a
FoundryTerminalPaletteSet
andFoundryTerminalPalette
.Ultimately, what this means is if you link against libfoundry and libfoundry-gtk you could functionally create your own Ptyxis replacement in very little code (assuming you don't use an agent on the host OS like Ptyxis does).
Just use the
FoundrySdk
as your container abstraction (which you can query usingFoundrySdkManager
) andFoundryTerminal
withFoundryTerminalPaletteSet
. -
You can now list/find available palettes with a
GListModel
API in the form offoundry_terminal_list_palette_sets()
andfoundry_terminal_find_palette_set()
. Each set has an easy light/dark property you can use based on your needs. -
The file-search plugin now properly implements the
load()
vfunc for search results so you can implement preview/opening in apps.
Foundry-Adw
-
A ton of work on the workspace, page, and panel APIs for 1.1. I'm really trying to find a way to re-use this across a number of applications such as Builder, Drafting, Sysprof, and more.
Releases
-
gnome-text-editor 49.0
-
gtksourceview 5.18.0
-
sysprof 49.0
-
gnome-builder 49.0
-
ptyxis 49.0
-
libdex 1.0.0
-
foundry 1.0.0
-
libpanel 1.10.2
-
template-glib 3.38.0
-
d-spy 49.0 (thanks to Jordan for the 49.1 w/ CI fixed)
-
gom 0.5.4
-
libpeas 2.2.0
-
manuals 49.0
Other
-
Team coffee hour, shared some battle wounds of trying to use AI for a pahole wrapper which fixed all my class structs to be cacheline aligned. Was just faster to write the damn code.
15 Sep 2025 6:44pm GMT
Gedit Technology blog: Mid-September News
Misc news about the gedit text editor, mid-September edition! (Some sections are a bit technical).
Next version will be released when Ready
While the release of GNOME 49.0 was approaching (it's this week!), I came to the conclusion that it's best for gedit to wait more, and to follow the Debian way of releasing software: when it's Ready. "Ready" with an uppercase letter 'R'!
So the question is: what is not ready? Two main things:
- The rework of the file loading and saving: it is something that takes time, and I prefer to be sure that it'll be a solid solution.
- The question about the Python support for implementing plugins. Time will tell what is the answer.
Rework of the file loading and saving (next steps)
Work continues to refactor that part of the code, both in libgedit-gtksourceview and gedit.
I won't go into too much technical details this time. But what the previous developer (Ignacio Casal Quinteiro, aka nacho) wrote (in 2011) in a comment at the top of a class is "welcome to a really big headache."
And naturally, I want to improve the situation. For a long time this class was used as a black box, using only its interface. Time has come to change things! It takes time, but I already see the end of the tunnel and I have good hopes that the code will be better structured. I intend to write about it more once finished.
But I can reveal that there is already a visible improvement: loading a big file (e.g. 200 MB) is now super fast! Previously, it could take one minute to load such file, with a progress bar shown and a Cancel button. Now there is not enough time to even click on (or to see) the Cancel button! (I'm talking about local files, for remote files with a slow network connection, the progress bar is still useful).
To be continued...
If you appreciate the work that I do, you can send a thank-you donation. Your support is much appreciated! For years to come, it will be useful for the project.
15 Sep 2025 10:00am GMT
13 Sep 2025
Planet GNOME
Alley Chaggar: Final Report
Intro:
Hi everyone, it's the end of GSoc! I had a great experience throughout this whole process. I've learned so much. This is essentially the 'final report' for GSoC, but not my final report for this project in general by a long shot. I still have so much more I want to do, but here is what I've done so far.
Project:
JSON, YAML, and/or XML emitting and parsing integration into Vala's compiler.
Mentor:
I would like to thank Lorenz Wildberg for being my mentor for this project, as well as the Vala community.
Description:
The main objective of this project is to integrate direct syntax support for parsing and emitting JSON, XML, and/or YAML formats in Vala. This will cut back the boilerplate code, making it more user-friendly and efficient for developers working with these formatting languages.
What I've done:
Research
- I've done significant research in both JSON and YAML parsing and emitting in various languages like C#, Java, Rust and Python.
- Looked into how Vala currently handles JSON using JSON GLib classes, and I then modelled the C code after the examples I collected.
- Modelled the JSON module after other modules in the codegen, specifically, mainly after Dbus, Gvariant, GObject, and GTK.
Custom JSON Overrides and Attribute
- Created Vala syntax sugar specifically making a [JSON] attribute to do serialization.
- Built support for custom overrides as in mapping JSON keys to differently named fields/properties.
- Reduced boilerplate by generating C code behind the scenes.
Structs
- I've created both Vala functions to deserialize and serialize structs using JSON boxed functions.
- I created a Vala
generate_struct_serialize_func
function to create a C code function called_%s_serialize_func
to serialize fields. -
I then created a Vala function
generate_struct_to_json
to create a C code function called_json_%s_serialize_mystruct
to fully serialize the struct by using boxed serialize functions. - I created a Vala
generate_struct_deserialize_func
function to create a C code function called_%s_deserialize_func
to deserialize fields. - I then created a Vala function
generate_struct_to_json
to create a C code function called_json_%s_deserialize_mystruct
to fully deserialize the struct by using boxed deserialized functions.
GObjects
- I've created both Vala functions to deserialize and serialize GObjects using json_gobject_serialize and JSON generator.
-
I then created a Vala function
generate_gclass_to_json
to create a C code function called_json_%s_serialize_gobject_myclass
to fully serialize GObjects. - I created a Vala
generate_gclass_from_json
function to create a C code function called_json_%s_deserialize_class
to deserialize fields.
Non-GObjects
- I've done serializing of non-GObjects using JSON GLib's builder functions.
- I then created a Vala function
generate_class_to_json
to create a C code function called_json_%s_serialize_myclass
to fully serialize non-objects that aren't inheriting from Object or Json.Serializable.
Future Work:
Research
- Research still needs to be put into integrating XML and determining which library to use.
- The integration of YAML and other formatting languages not only JSON, YAML, or XML.
Custom Overrides and Attributes
- I want to create more specialized attributes for JSON that only do serialization or deserialization. Such as [JsonDeserialize] and [JsonSerialize] or something similar.
- [JSON] attribute needs to do both deserializing and serializing, and at the moment, the deserializing code has problems.
- XML, YAML, and other formating languages will follow very similar attribute patterns:
[Yaml], [Xml], [Json]
.
Bugs
- unref c code functions are calling nulls, which shouldn't be the cause. They need proper types going through.
- Deserializing prompts a redefinition that needs to be corrected.
- Overridden GObject properties need to have setters made to be able to get the values.
Links
- Here is the JSON module that has majority of the code.
- Here is the merge request.
13 Sep 2025 12:00am GMT
12 Sep 2025
Planet GNOME
Allan Day: GNOME Foundation Update, 2025-09-12
It's been another busy week for the GNOME Foundation. Here's my attempt to summarise what's been happening. As with my previous update, this update is for the whole organisation rather than just me personally. It's also likely that I'll have missed some things. Hopefully I've captured the highlights though!
GNOME.Asia 2025
GNOME.Asia 2025 is happening in Toyko, Japan, in December. I'm sure that this is going to be a fantastic event, and the call for papers has recently been extended to 1st October. If you have an idea for a talk and would like to participate, go submit a proposal!
Digital wellbeing
The Foundation has been funding development work on digital wellbeing features in GNOME for almost two years now. This work is funded by a grant that we received from Endless, which is now in its final stages. I spent some of this week reviewing the budget and discussing the timeline with Philip and Ignacy, who are currently working on the project.
There are a number of features which are currently in development which will hopefully be landed for GNOME 50, including session time limits for accounts that are managed with parental controls. We also have a modernized parental controls app which is also in the works.
For Future Summit
Kristi attended the For Future Summit in the United Arab Emirates last weekend, where she gave a talk about GNOME and had some exciting hallway conversations. There were some very interesting organisations at the event, who we are hoping to have follow-up conversations with soon.
Thank you to For Future Summit for funding Kristi's attendance.
Flathub
We have a long-standing ambition to establish Flathub as an independent entity, so that it can do its own fundraising and spending. These plans have unfortunately suffered from delays. However, Rob has been working with Aleix from KDE on this recently, and they've made some positive progress this week, with lawyers being commissioned to provide some of the initial pieces that we need. I'm hopeful that this work can continue and we can finally get Flathub standing on its own feet.
Alongside this, Flathub infrastructure support continues to tick along. All of this Flathub support is being funded from our Endless grant, so many thanks to them for enabling it to happen.
Board regular meeting
The board had its first regular meeting of September this week (regular meetings are on the second and fourth Tuesday of the month). The Finance Committee have been working on the upcoming budget since the Board meeting, so this was a good opportunity for the Board to discuss the latest proposal.
This is the best budgeting process I've seen in my years on the board. Kudos to everyone who's been involved.
GIMP support
The GIMP project's grants program has been inching towards the finish line this week. It's taken a while, but we're almost there! It'll be so exciting to see two developers being funded from their donation stream.
Routine paperwork
A fair chunk of the work done by the Foundation is not very exciting, but is important nonetheless. This week featured a few items of that type, relating to our trademarks and insurance. These got done.
Message ends
See you again next week. o/
12 Sep 2025 3:40pm GMT
Michael Meeks: 2025-09-12 Friday
- Up early, bid 'bye to M. sync & brainstorming with Dave, quick sync with Frank, prepared slides for TTT:
- Gave a Tea Time Training on threading:
12 Sep 2025 12:32pm GMT
Varun R Mallya: PythonBPF - Writing eBPF Programs in Pure Python
Introduction
Python-BPF offers a new way to write eBPF programs entirely in Python, compiling them into real object files. This project is open-source and available on GitHub and PyPI. I wrote it alongside R41k0u.
Published Library with Future Plans
Python-BPF is a published Python library with plans for further development towards production-ready use.
You can pip install pythonbpf
but it's certainly not at all production ready and the code is hacky at best with more bugs than I could count. (This was a hackathon project afterall. We plan to fix it after we are done with the hackathon.)
The Old Way: Before Python-BPF
Before Python-BPF, writing eBPF programs in Python typically involved embedding C code within multiline strings, often using libraries like bcc
. eBPF allows for small programs to run based on kernel events, similar to kernel modules.
Here's an example of how it used to be:
from bcc import BPF
from bcc.utils import printb
# define BPF program
prog = """
int hello(void *ctx) {
bpf_trace_printk("Hello, World!\\n");
return 0;
}
"""
# load BPF program
b = BPF(text=prog)
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello")
# header
print("%-18s %-16s %-6s %s" % ("TIME(s)", "COMM", "PID", "MESSAGE"))
# format output
while 1:
try:
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
except ValueError:
continue
except KeyboardInterrupt:
exit()
printb(b"%-18.9f %-16s %-6d %s" % (ts, task, pid, msg))
This approach, while functional, meant writing C code within Python, lacking support from modern Python development tools like linters.
Features of the Multiline C Program Approach
# load BPF program
b = BPF(text="""
#include <uapi/linux/ptrace.h>
BPF_HASH(last);
int do_trace(struct pt_regs *ctx) {
u64 ts, *tsp, delta, key = 0;
// attempt to read stored timestamp
tsp = last.lookup(&key);
if (tsp != NULL) {
delta = bpf_ktime_get_ns() - *tsp;
if (delta < 1000000000) {
// output if time is less than 1 second
bpf_trace_printk("%d\\n", delta / 1000000);
}
last.delete(&key);
}
// update stored timestamp
ts = bpf_ktime_get_ns();
last.update(&key, &ts);
return 0;
}
""")
The multiline C program approach allowed for features like BPF MAPS (hashmap type), map lookup, update, and delete, BPF helper functions (e.g., bpf_ktime_get_ns
, bpf_printk
), control flow, assignment, binary operations, sections, and tracepoints.
Similar Program in Reduced C
For production environments, eBPF programs are typically written in pure C, compiled by clang
into a bpf target object file, and loaded into the kernel with tools like libbpf
. This approach features map sections, license global variables, and section macros specifying tracepoints.
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#define u64 unsigned long long
#define u32 unsigned int
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1);
__type(key, u32);
__type(value, u64);
} last SEC(".maps");
SEC("tracepoint/syscalls/sys_enter_execve")
int hello(struct pt_regs *ctx) {
bpf_printk("Hello, World!\\n");
return 0;
}
char LICENSE[] SEC("license") = "GPL";
Finally! Python-BPF
Python-BPF brings the true eBPF experience to Python by allowing the exact same functionality to be replaced by valid Python code. This is a significant improvement over multiline C strings, offering support from existing Python tools.
from pythonbpf import bpf, map, section, bpfglobal, compile
from ctypes import c_void_p, c_int64, c_int32, c_uint64
from pythonbpf.helpers import ktime
from pythonbpf.maps import HashMap
@bpf
@map
def last() -> HashMap:
return HashMap(key_type=c_uint64, value_type=c_uint64, max_entries=1)
@bpf
@section("tracepoint/syscalls/sys_enter_execve")
def hello(ctx: c_void_p) -> c_int32:
print("entered")
return c_int32(0)
@bpf
@section("tracepoint/syscalls/sys_exit_execve")
def hello_again(ctx: c_void_p) -> c_int64:
print("exited")
key = 0
last().update(key)
ts = ktime()
return c_int64(0)
@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"
compile()
Python-BPF uses ctypes
to preserve compatibility, employs decorators to separate the BPF program from other Python code, allows intuitive creation of global variables, and defines sections and tracepoints similar to its C counterpart. It also provides an interface to compile and run in the same file.
How it Works Under the Hood
-
Step 1: Generate AST The Python
ast
module is used to generate the Abstract Syntax Tree (AST). -
Step 2: Emit LLVM IR
llvmlite
from Numba emits LLVM Intermediate Representation (IR) and debug information for specific parts like BPF MAPs. The.py
file is converted into LLVM Intermediate Representation. -
Step 3: Compile LLVM IR The
.ll
file, containing all code written under the@bpf
decorator, is compiled usingllc -march=bpf -O2
. -
Step 4: Generate eBPF Object File The LLVM backend takes the IR and converts it into a bpf object file with eBPF bytecode, handling all optimizations.
Salient Features
Previous Python options for eBPF relied on bcc
for compilation, which is not ideal for production use. The only two real options for production-quality eBPF programs were aya
in Rust and Clang with kernel headers in C. Python-BPF introduces a third, new option, expanding the horizons for eBPF development.
It currently supports:
- Control flow
- Hash maps (with plans to add support for other map types)
- Binary operations
- Helper functions for map manipulation
- Kernel trace printing functions
- Timestamp helpers
- Global variables (implemented as maps internally with syntactical differences)
TL;DR
- Python-BPF allows writing eBPF programs directly in Python.
- This library compiles Python eBPF code into actual object files.
- Previously, eBPF programs in Python were written as C code strings.
- Python-BPF simplifies eBPF development with Python decorators.
- It offers a new option for production quality BPF programs in Python.
- The tool supports BPF maps, helper functions, and control flow, with plans to extend to completeness later.
Thanks for reading my poorly written blog :)
12 Sep 2025 12:00am GMT
This Week in GNOME: #216 Growing Community
Update on what happened across the GNOME project in the week from September 05 to September 12.
GNOME Core Apps and Libraries
Libadwaita ↗
Building blocks for modern GNOME apps using GTK4.
Alice (she/her) 🏳️⚧️🏳️🌈 announces
I just released libadwaita 1.8! Read the accompanying blog post for details.
Weather ↗
Show weather conditions and forecasts.
Emmanuele Bassi announces
The weather locations database used by libgweather now lives in its own project. If you want to add a city, airport, or weather station to the database used by GNOME apps like Weather, Clocks, and Maps, make sure to read the documentation.
Settings ↗
Configure various aspects of your GNOME desktop.
Hari Rana | TheEvilSkeleton (any/all) 🇮🇳 🏳️⚧️ announces
GNOME Settings underwent some last-minute changes that will make GNOME 49 an exciting release for everyone using the Orca screen reader:
- Orca will allow users to open the settings dialog while the Orca instance is running without ending its processes. It will also enable apps and services to open the dialog through D-Bus instead of using shell commands, specifically
orca -s
.- GNOME Settings has introduced a button to launch Orca's settings dialog from the Accessibility panel.
This was made possible thanks to Joanmarie Diggs, the Orca maintainer, who worked on these improvements.
GNOME Development Tools
Sysprof ↗
A profiling tool that helps in finding the functions in which a program uses most of its time.
Georges Stavracas (feaneron) says
Sysprof has been receiving a variety of new features, improvements, and bugfixes, as of lately. A few highlights:
- An important bug with counters was fixed, and further integration was added to WebKit
- It is now possible to hide marks from the waterfall view
- Further work on the remote inspector integration, wkrictl, was done
- Integration with the Mesa tracing mechanism
GNOME Circle Apps and Libraries
Apostrophe ↗
A distraction free Markdown editor.
Manu (he/they/she) announces
I've finally released Apostrophe 3.3. It features a new narrow mode, suitable even for smartphones and small displays, typst as the new default render engine, making the texlive extension unnecessary for exporting pdfs, crash recovery, inline previews, and many, many more improvements. Read the full release notes or download it from flathub
Third Party Projects
JumpLink announces
Learn 6502 v0.3.0 is out!
Learn 6502, the interactive environment for learning assembly through a virtual game console, just got a fresh polish! This release introduces a modern Floating Action Button for quick controls and a refreshed debugger built with Adwaita components.
Under the hood, the app now shares its TypeScript core with an experimental Android build (still in development) - while the GNOME app remains the main focus.
Get it on Flathub.
Sepehr Rasouli reports
Sudoku v1.4.0 is here!
- You can now add notes by right-clicking on an empty cell.
- Fixed a bug that allowed zero as a valid input. - thanks to @tahairavani
- Fixed a bug that applied the hovered style to the pencil toggle button icon. - thanks to @Revisto
- Fixed a bug that prevented the help overlay shortcut from working.
- Added Ctrl + num to the keyboard shortcuts menu. - thanks to @devforgely
- Improved small-screen support for Sudoku.
Install it from Flathub: https://flathub.org/apps/io.github.sepehr_rs.Sudoku
Jeffry Samuel says
Alpaca 8 is now available. It features folders, activities, a built-in web browser and much more.
https://flathub.org/apps/com.jeffser.Alpaca
Quadrapassel ↗
Fit falling blocks together.
Will Warner reports
Quadrapassel 49 is coming soon! This release of Quadrapassel will significantly change how the game works, looks, and feels.
Currently 49.rc.2 is out for testing (on Flathub beta and GNOME nightly).
Due a to lack of maintainership, it has been about 4 years since the last release of Quadrapassel, and Quadrapassel's codebase has aged significantly in that timeframe. Since I took over the project 2 months ago, a lot of work has been done to improve the game!
Here is a shortened list of recent changes:
- Thanks to the translation team, many translations have been either updated or added!
- Port to GTK 4
- Improve the UI and use Libadwaita
- Large improvements the preferences and the scoring
- Improved controls and gameplay
- Added custom seeds
- Made the game playable on a touchscreen
- Added a minimized width UI mode for use on phones
- Fixed many bugs
You can find a full changelog in Quadrapassel's NEWS.
GNOME Websites
Mir Sobhan reports
Hi there, greetings from the Persian GNOME community!
A little while ago, we launched https://fa.gnome.org to grow the GNOME community among Persian speakers. We're now active and excited to connect with anyone interested in free software and GNOME.
If you know any Persian-speaking friends, please invite them to join us! You can find us on Telegram at t.me/gnome_fa and on Matrix at #gnome-fa:gnome.org
Miscellaneous
Ada Magicat ❤️🧡🤍🩷💜 announces
Thanks to Ignacy's contributions, printing now works on GNOME OS. Any IPP printer should work, but more testing is always appreciated.
Additionally, we switched our filesystem from squashfs to erofs. This new filesystem is a bit faster and enables implementing delta updates. This will allow your system to only download the parts that changed, instead of the entire system image. However, this feature will need more work before it is ready. Stay tuned for future updates.
GNOME OS is still unstable, so testing is always appreciated. You can install it on virtual machines and most hardware. Images and installation instructions are available here: https://os.gnome.org/
Ada Magicat ❤️🧡🤍🩷💜 announces
Last week concluded the Summer of GNOME OS challenge, while this week the awards ceremony was held. Each participant's score was checked by the organizers and the final rankings are available here. We also held a meeting where we discussed further improvements and long term goals for the project.
During the challenge over 50 issues were filed, many changes were submitted and new hardware got tested. We got valuable feedback on how to improve the operating system, fixed some long standing issues and broadened our hardware support.
Thank you to everyone that participated and to all of you still sticking with GNOME OS as your operating system even after the challenge is done, your help is invaluable.
Benedek Dévényi reports
This week, we reached 450 applications listed on AreWeLibadwaitaYet! It's a comprehensive list of libadwaita-powered applications available on Flathub, aimed at making it easier to discover all that this ecosystem has to offer. If you are seeking an application for your needs, or just want a new icon in your app grid, check out the website!
Arjan announces
A new release of PyGObject is out: 3.54.0.
This release mainly contains improvements and fixes:
__enum_values__
/__flags_values__
are back- Param specs now also return the expected enum types
- Fix regression for functions with multiple callbacks
For a full list check out https://pygobject.gnome.org/changelog.html.
PyGObject can be installed from PyPI and download.gnome.org.
GNOME Foundation
Allan Day says
A GNOME Foundation update is available this week, covering what's been happening at the GNOME Foundation over the past 7 days. Highlights include the GNOME.Asia 2025 call for papers, digital wellbeing development planning, progress around Flathub, and more.
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!
12 Sep 2025 12:00am GMT
Alice Mikhaylenko: Libadwaita 1.8
Another six months have passed, and with that comes another libadwaita release to go with GNOME 49.
This cycle doesn't have a lot of changes due to numerous IRL circumstances I've been dealing with, but let's look at them anyway.
Shortcuts dialog
Last cycle GTK deprecated GtkShortcutsWindow
and all of the related classes. Unfortunately, this left it with no replacement, despite being widely used. So, now there is a replacement: AdwShortcutsDialog
. Same as shortcuts window, it has very minimal API and is intended to be static and constructed from UI files.
Structure
While the new dialog has a similar feature set to the old one, it has a very different organization, and is not a drop-in replacement.
The old dialog was structured as: GtkShortcutsWindow
→ GtkShortcutsSection
→ GtkShortcutsGroup
→ GtkShortcutsShortcut
.
Most apps only have a single shortcuts section, but those that have multiple would have them shown in a dropdown in the dialog's header bar, as seen in Builder:
Each section would have one or more shortcuts groups. When a section has too many groups, it would be paginated. Each group has a title and optionally a view, we'll talk about that a bit later.
Finally each groups contains shortcuts. Or shortcuts shortcuts, I suppose - which describe the actual shortcuts.
When sections and groups specify a view, the dialog can be launched while only showing a subset of shortcuts. This can be seen in Clocks, but was never very widely used. And specifically in Clocks it was also a bit silly, since the dialog actually becomes shorter when the button is clicked.


The new dialog drops the rarely used sections and views, so it has a simpler structure: AdwShortcutsDialog
→ AdwShortcutsSection
→ AdwShortcutsItem
.
Sections here are closer to the old groups, but are slightly different. Their titles are optional, and sections without titles behave as if they were a part of the previous section with an extra gap. This allows to subdivide the sections further, without adding an extra level of hierarchy when it's not necessary.
Since shortcuts are shown as boxed lists, apps should avoid having too many in a single section. It was already not great with the old dialog, but is much worse in the new one.
Finally, AdwShortcutsItem
is functionally identical to GtkShortcutsShortcut
, except it doesn't support specifying gestures and icons.
Why not gestures?
This feature was always rather questionable, and sometimes doing more harm than good. For example, take these 2 apps - the old and the current image viewer, also known as Eye of GNOME and Loupe respectively:
Both of them specify a two-finger swipe left/right to go to the next/previous image. Well, does it work? The answer depends on what input device you're using.
In Loupe it will work on a touchpad, but not touchscreen: on a touchscreen you use one finger instead.
Meanwhile, in EoG it only works on touchscreen instead. On touchpad 2-finger swipe scrolls the current image if it's zoomed in.
So - while both of these apps have a swipe gesture, they are completely different - yet the dialog makes no distinction between them.
It's also not discoverable. HIG recommends naming the menu entry Keyboard Shortcuts, and it doesn't make a lot of sense that these gestures would be in there too - they have nothing to do with keyboard or shortcuts.
A much better place to document this would be help pages. And of course, ideally apps should have all of the typical gestures people are used to from other systems (pinch to zoom and rotate, double tap to zoom, swipes to navigate, long press to open context menus when it's not available via other means), and clear feedback while those gestures are performed - so that there's less of a need to remember which app has which gestures in the first place and they can be documented system-wide instead.
Why not icons?
As for icons, the only app I'm aware of that did this was gnome-games
- it used them to show gamepad navigation:
This was problematic in a similar way, but also there was no way to open this dialog using a gamepad in the first place. A much better solution (and pretty much the standard for gamepad navigation) would have been always visible hints at the bottom of the window or inline.
Auto-loading
Most apps using GtkShortcutsWindow
weren't creating it programmatically - GtkApplication
loads it automatically and creates an action for it. So, we do the same thing: if a resource with the name shortcuts-dialog.ui
is present in the resource base path, AdwApplication
will create the app.shortcuts
action which will create and show the dialog in the active window when activated.
Some apps were already using an action with this name, in these cases no action will be created.
One thing that's not possible anymore is overriding the dialog for specific windows (gtk_application_window_set_help_overlay()
). This feature was extremely rarely used, and apps that really want different dialogs for different windows can just create the dialogs themselves instead of using auto-loading - this is just convenience API for the most common case.
Shortcut label
One of the widgets that was deprecated is GtkShortcutLabel
. However, it had uses outside of the shortcuts dialog as well. So, libadwaita has a replacement as well - AdwShortcutLabel
. Unlike the dialog itself, this is a direct fork of the GTK widget, and works the same way - though the separation between individual keycaps looks a bit different now, hopefully to make it clearer:


It also has a slightly different style, but it's been backported for GtkShortcutLabel
as well for the most part.
And, unlike the shortcuts dialog, AdwShortcutLabel
is a drop-in replacement.
CSS improvements
Media queries
This cycle, GTK has added support for CSS media queries, allowing to define styles for light and dark, as well as regular and high contrast styles in the same file.
Media queries is fully supported on libadwaita side, and apps are encouraged to use them instead of style-dark.css
, style-hc.css
and style-hc-dark.css
. Since this happened right at the end of the cycle (after the feature and API freeze, in fact, since GTK doesn't follow it), they are not deprecated just yet, but will be early next cycle.
Since we now have support for both variables and media queries, it's possible to do things like this now:
:root {
--card-border: var(--card-shade-color);
}
@media (prefers-contrast: more) {
:root {
--card-border: var(--border-color);
}
}
.card-separator {
background: var(--card-border);
}
Typography
Last cycle, I added document and monospace font variables and mentioned that the document font may change in future to be distinct from the UI font.
This has happened now, and it is actually distinct - Adwaita Sans 12pt instead of 11pt.
So - to mirror .monospace
, there's now a .document
style class as well. It uses the document font, and also increases the line height for better readability.
Additionally, the formerly mostly useless .body
style class increases line height as well now, instead of just setting the default font size and weight. Apps should use it when displaying medium-long text, and libadwaita is using it in a bunch of standard widgets, such as in preferences group and status page descriptions, alert dialog body, or various pages in the about dialog.
Fractal and Podcasts are already making use of both, and hopefully soon more apps will follow suit.
Other changes
-
AdwPreferencesGroup
can now be used with list models viaadw_preferences_group_bind_model()
. -
For convenience, it also allows adding rows that aren't
AdwPreferencesRow
to the internal list now, rather than treating them as other widgets. These rows will just not be searchable inAdwPreferencesDialog
. -
AdwPreferencesPage
has a way to insert groups anywhere now, rather than just append them at the end. -
Both
AdwPreferencesGroup
andAdwPreferencesPage
now have a way to inspect their groups/rows without peeking into their implementation:adw_preferences_page_get_group()
andadw_preferences_group_get_row()
. -
AdwWrapBox
now has a way to remove all children at once. -
GtkFlowBox
children have hover and active styles by default. Apps that use flowboxes in non-standard ways may need to disable this from CSS in some cases. -
AdwHeaderBar
now supports native window controls on macOS, same asGtkHeaderBar
from the last cycle. -
Window, dialog and sheet shadows have been reduced to increase performance.
Future
While this cycle was pretty short and unexciting, there's a thing in works for the next cycle.
One of the most glaring omissions right now is sidebars. While we have split views, we don't have anything pre-built that could go into the sidebar pane - it's up to the apps to invent something using GtkListBox
or GtkListView
, combined with the .navigation-sidebar
style class.
This is a lot messier than it may seem, and results in every app having sidebars that look and behave slightly different. We have helpers for boxed lists, so why not sidebars too?
There is also GtkStackSidebar
, but it's not flexible at all and doesn't play well with mobile phones.
Additionally, on mobile especially sidebars look and behave extremely out of place, and it would be nice to do something about - e.g. use boxed lists instead.


So, next cycle we'll (hopefully) have both a generic sidebar widget, and a stack sidebar replacement. They won't cover all of the use cases (I expect it to be useful for Builder's preferences dialog but not the main window), but a lot of apps don't do anything extraordinary and it should save them a lot of effort.
Thanks to the GNOME STF Team for providing the funding for this work. Also thanks to the GNOME Foundation for their support and thanks to all the contributors who made this release possible.
12 Sep 2025 12:00am GMT
11 Sep 2025
Planet GNOME
Michael Meeks: 2025-09-11 Thursday
- Slept extraordinarily poorly, up early, worked instead, fever-typing. Sleep, caught part of the tech-planning call.
- Sync with Pedro, admin, lunch, catch up with Lily. Tried to sleep.
11 Sep 2025 9:00pm GMT
10 Sep 2025
Planet GNOME
Debarshi Ray: Toolbx — about version numbers
Those of you who follow the Toolbx project might have noticed something odd about our latest release that came out a month ago. The version number looked shorter than usual even though it only had relatively conservative and urgent bug-fixes, and no new enhancements.
If you were wondering about this, then, yes, you are right. Toolbx will continue to use these shorter version numbers from now on.
The following is a brief history of how the Toolbx version numbers evolved over time since the beginning of the project till this present moment.

Toolbx started out with a MAJOR.MINOR.MICRO
versioning scheme. eg., 0.0.1, 0.0.2, etc.. Back then, the project was known as fedora-toolbox, was implemented in POSIX shell, and this versioning scheme was meant to indicate the nascent nature of the project and the ideas behind it.
To put it mildly, I had absolutely no idea what I was doing. I was so unsure that for several weeks or few months before the first Git commit in August 2018, it was literally a single file that implemented the fedora-toolbox(1)
executable and a Dockerfile for the fedora-toolbox
image on my laptop that I would email around to those who were interested.
A nano version was reserved for releases to address brown paper bag bugs or other critical issues, and for release candidates. eg., several releases between 0.0.98 and 0.1.0 used it to act as an extended set of release candidates for the dot-zero 0.1.0 release. More on that later.
After two years, in version 0.0.90, Toolbx switched from the POSIX shell implementation to a Go implementation authored by Ondřej Míchal. The idea was to do a few more 0.0.9x releases to shake out as many bugs in the new code as possible, implement some of the bigger items on our list that had gotten ignored due to the Go rewrite, and follow it up with a dot-zero 0.1.0 release. That was in May 2020.
Things went according to plan until the beginning of 2021, when a combination of factors put a spanner in the works, and it became difficult to freeze development and roll out the dot-zero release. It was partly because we kept getting an endless stream of bugs and feature requests that had to be addressed; partly because real life and shifting priorities got in the way for the primary maintainers of the project; and partly because I was too tied to the sanctity of the first dot-zero release. This is how we ended up doing the extended set of release candidates with a nano version that I mentioned above.
Eventually, version 0.1.0 arrived in October 2024, and since then we have had three more releases - 0.1.1, 0.1.2 and 0.2. Today, the Toolbx project is seven years old, and some things have changed enough that it requires an update to the versioning scheme.
First, both Toolbx and the ideas that it implements are a lot more mature and widely adopted than they were at the beginning. So much so, that there are a few independent reimplementations of it. It's time for the project to stop hiding behind a micro version.
Second, the practice of bundling and statically linking the Go dependencies sometimes makes it necessary to update the dependencies to address security bugs or other critical issues. It's more convenient to do this as part of an upstream release than through downstream patches by distributors. So far, we have managed to avoid the need to do minimal releases targeting only specific issues for conservative downstream distributors, but the recent NVIDIAScape or CVE-2025-23266 and CVE-2025-23267 in the NVIDIA Container Toolkit gave me pause. We managed to escape this time too, but it's clear that we need a plan to deal with these scenarios.
Hence, from now on, Toolbx releases will default to not having a micro version and use a MAJOR.MINOR
versioning scheme. A micro version will be reserved for the same purposes that a nano version was reserved for until now - to address critical issues and for release candidates.
It's easier to read and remember a shorter MAJOR.MINOR
version than a longer one, and appropriately conveys the maturity of the project. When a micro version is needed, it will also be easier to read and remember than a longer one with a nano version. Being easy to read and remember is important for version numbers, because it separates them from Git commit hashes.
So, this is why the latest release is 0.2, not 0.1.3.
10 Sep 2025 9:49pm GMT
Development blog for GNOME Shell and Mutter: GNOME Kiosk Updates
GNOME Kiosk is a separate Wayland compositor built on the same core components as GNOME Shell, such as Mutter.
While it does not provide a desktop UI, it is intended for kiosk and appliance use cases.
Originally designed to run a single application in fullscreen mode, recent development has expanded its scope toward more versatile window management and system integration.
Recent Releases Overview
47
- Support for Shell introspection API (in
--unsafe-mode
).
48
- Initial support for configurable windows via
window-config.ini
. - Added Shell Screenshot D-Bus API.
49
- Extended window configuration:
set-on-monitor
,set-window-type
, window tags. - Added support for remote sessions (Systemd).
- Fixes for GrabAccelerators, media keys, and compositor shortcut inhibition.
Window Configuration and Tagged Clients
One of the recent main areas of development has been window configuration.
- In GNOME 48, Kiosk gained initial support for configuring windows via a static configuration file (
window-config.ini
). - In GNOME 49, this functionality was extended with additional options:
set-on-monitor
: place windows on a specific monitor.set-window-type
: assign specific roles to windows (e.g.desktop
,dock
,splash
).- Matching based on Window tags: allow selection of windows based on toplevel tags, a new feature in Wayland protocols 1.43.
Additionally, with the new (in mutter from GNOME 49) gnome-service-client
utility, toplevel windows tags can be assigned to clients at launch, making it possible to configure their behavior in Kiosk without modification to the client.
Example: configuring a tagged client in Kiosk
GNOME Kiosk searches for the window configuration file window-config.ini
in the following locations:
- The base directory for user-specific application configuration usually
$HOME/.config/gnome-kiosk/window-config.ini
- The system-wide list of directories for application data
$XDG_DATA_DIRS
This list usually includes:/var/lib/flatpak/exports/share/gnome-kiosk/window-config.ini
/usr/local/share/gnome-kiosk/window-config.ini
/usr/share/gnome-kiosk/window-config.ini
Therefore, for a user configuration, edit $HOME/.config/gnome-kiosk/window-config.ini
to read:
[all]
set-fullscreen=false
set-above=false
[desktop]
match-tag=desktop
set-window-type=desktop
set-fullscreen=true
With this configuration, GNOME Kiosk will treat any surface with the toplevel tag desktop
as a "desktop" type of window.
launching a tagged client
gnome-service-client -t desktop weston-simple-shm
This command starts the weston-simple-shm
client and associates the tag desktop
with its surface.
The end result is the weston-simple-shm
window running as a background window placed at the bottom of the windows stack.
This combination makes it possible to build structured kiosk environments with different Wayland client used as docks or desktop windows for implementing root menus.
Accessibility and Input
Several improvements have been made to input handling and accessibility:
- Fixes for
GrabAccelerators
support. - Support for media keys in Systemd sessions.
- Ability to inhibit compositor shortcuts.
- Compatibility with screen reader usage.
Remote Sessions
As of GNOME 49, Kiosk supports remote sessions when run under Systemd. This allows kiosk sessions to be used not only on local displays but also in remote session contexts.
D-Bus APIs
Although GNOME Kiosk is a separate compositor, it implements selected D-Bus APIs also available in GNOME Shell for compatibility purposes. These include:
- Screenshot API (added in 48).
- Shell introspection when started with
--unsafe-mode
(added in 47).
This makes it possible to use existing GNOME testing and automation frameworks such as Ponytail and Dogtail with kiosk sessions.
These APIs allow automation scripts to inspect and interact with the user interface, enabling the creation of automated tests and demonstrations for kiosk application (using tools like GNOME ponytail and dogtail).
GNOME Kiosk is the Wayland compositor used with the Wayland enabled version of Anaconda, the installer for Fedora (and Red Hat Enterprise Linux as well). The support for introspection and screenshots is used by anabot, the framework for automated testing of the installer.
Development Direction
Future development of GNOME Kiosk is expected to continue along the following lines:
- Configuration refinement: further improving flexibility of the window configuration system.
- Accessibility: ensuring kiosk sessions benefit from GNOME's accessibility technologies.
The goal remains to provide a focused, reliable compositor for kiosk and appliance deployments, without implementing the full desktop UI features of GNOME Shell.
10 Sep 2025 7:03am GMT
09 Sep 2025
Planet GNOME
Marcus Lundblad: Maps and GNOME 49
As time is approaching the release of GNOME 49, I thought I should probably put together a small recap post covering some of the new things in Maps.
Metro Station Symbols
The map style now supports showing localized symbols for rail- and metro stations (relying on places being tagged with reference to the networks' entry in Wikidata.
Highway Symbols in Place Details
The existing code for showing custom highways shields in the map view (based on code from the OpenStreetMap Americana project) has been extended to expose the necessary bits to use it more generally as icon surfaces in a GtkImage widget. So now custom shields are shown in place details when clicking on a road label.
Adwaita Shortcuts Dialog
The keyboard shortcuts help dialog was ported by Maximiliano to use AdwShortcutsDialog, improving adaptivity.
Showing OSM Account Avatars in OSM Account Dialog
If a user has set up OAuth for an OpenStreetMap account, and has set a personal profile picture in their OSM account this is now shown in place of the generic "face" icon.
And speaking of editing points-of-interests, the edit dialog has been compacted a bit to better accomodate smaller screen sizes.
This screenshot also showcases the (fairly) new mobile form-factor emulation option in the GTK inspector.
Softer Labels
Some smaller adjustments has also been made to the map style, such as using slightly softer color for the place labels for towns and cities rather than pitch black (or bright white for dark mode).
Marker Alignments
Thanks to work done by Corentin Noël for libshumate 1.5, the center point for map markers can now be adjusted.
This means the place markers in Maps can now actually point to the actually coordinate (e.g. having the "tip of the needle" at the actual location).
Updating the Highway Shields Defintions
And finally of the last changes before the release was updating the definition for custom highway shields from OpenStreetMap Americana. So now, among others we support shields for national and regional highways in Argentina.
And that's some of the highlights from the 49 release cycle!
09 Sep 2025 10:43pm GMT
Christian Schaller: More adventures in the land of AI and Open Source
I been doing a lot of work with AI recently, both as part of a couple of projects I am part of at work, but I have also taken a personal interest in understanding the current state and what is possible. My favourite AI tool currently is Claude.ai. Anyway I have a Prusa Core One 3D printer now that I also love playing with and one thing I been wanting to do is to print some multicolor prints with it. So the Prusa Core One is a single extruder printer, which means it only has 1 filament loaded at any given time. Other printers on the market, like the PrusaXL has 5 extruders, so it can have 5 filaments or colors loaded at the same time.

Prusa Single Extruder Multimaterial setting
The thing is that the Prusa Slicer (the slicer is the software that takes a 3d model and prepares the instructions for the printer based on that 3d model) got this feature called Single Extruder Multi Material. And while it is a process that wastes a lot of filament and takes a lot of manual intervention during the print, it does basically work.
What I quickly discovered was that using this feature is non-trivial. First of all I had to manually add some G Code to the model to actually get it to ask me to switch filament for each color in my print, but the bigger issue is that the printer will ask you to change the color or filament, but you have no way of knowing which one to switch to, so for my model I had 15 filament changes and no simple way of knowing which order to switch in. So people where solving this among other things through looking through the print layer by layer and writing down the color changes, but I thought that this must be possible to automate with an application. So I opened Claude and started working on this thing I ended up calling Prusa Color Mate..
So the idea for the application was simple enough, have it analyze the project file, extract information about the order of color changes and display them for the user in a way that allows them to manually check of each color as its inserted. So I started off with doing a simple python script that would just print to the console. So it quickly turned out that the hard part of this project was to parse the input files and it was made worse by my ignorance. So what I learned the hard way is that if you store a project in Prusa Slicer it will use this format called 3mf. So my thought was, lets just analyze the 3mf file and extract the information I need. It took my quite a bit of back and forth with Claude, feeding claude source code from Prusa's implementation and pdf files with specifications, but eventually the application did spit out a list of 15 toolchanges and the colors associated with them. So I happily tried to use it to print my model. I quickly discovered that the color ordering was all wrong. And after even more back and forth with Claude and reading online I realized that the 3mf file is a format for storing 3d models, but that is not what is being fed your 3d printer, instead for the printer the file provided is a bgcode file. And while the 3mf file did contain the information that you had to change filament 15 times, the information on in which order is simply not stored in the 3mf file as that is something chosen as part of composing your print. That print composition file is using a file format called bgcode. So I now had to extract the information from the bgcode file which took me basically a full day to figure out with the help of Claude. I could probably have gotten over the finish line sooner by making some better choices underway, but the extreme optimism of the AI probably lead me to believe it was going to be easier than it was to for instance just do everything in Python.
At first I tried using this libbgcode library written in C++, but I had a lot of issues getting Claude to incorporate it properly into my project, with Meson and CMAKE interaction issues (in retrospect I should have just made a quick RPM of libbgcode and used that). After a lot of struggles with this Claude thought that parsing the bgcode file in python natively would be easier than trying to use the C++ library, so I went down that route. I started by feeding Claude a description of the format that I found online and asked it to write me a parser for it. It didn't work very well and I ended up having a lot of back and forth, testing and debugging, finding more documentation, including a blog post about this meatpack format used inside the file, but it still didn't really work very well. In the end what probably helped the most was asking it to use the relevant files from libbgcode and Prusa Slicer as documentation, because even if that too took a lot of back and forth, eventually I had a working application that was able to extract the tool change data and associated colors from the file. I ended up using one external dependency which was the heatshrink2 library that I PIP installed, but while that worked correctly, it took a look time for me and Claude to figure out exactly what parameters to feed it to work with the Prusa generated file.

Screenshot of Prusa Color Mate
So know I had the working application going and was able to verify it with my first print. I even polished it up a little, by also adding detection of the manual filament change code, so that people who try to use the application will be made aware they need to add that through Prusa Slicer. Maybe I could bake that into the tool, but atm I got only bgcode decoders, not encoders, in my project.

Warning showed for missing G Code Dialog that gives detailed instructions for how to add G Code
So to conclude, it probably took me 2.5 days to write this application using Claude, it is a fairly niche tool, so I don't expect a lot of users, but I made it to solve a problem for myself. If I had to write this pre-AI myself it would have taken me weeks, like figuring out the different formats and how library APIs worked etc. would have taken me a long time. So I am not an especially proficient coder, so a better coder than me could probably put this together quicker than I would, but I think this is part of what I think will change with AI, that even with limited time and technical skills you can put together simple applications like this to solve your own problems.
If you are a Prusa Core One user and would like to play with multicolor prints you can find Prusa Color Mate on Gitlab. I have not tested it on any other system or printer than my own, so I don't even know if it will work with other non-Core One Prusa printers. There are rpms for Fedora you can download in the packaging directory of the gitlab repo, which also includes a RPM for the heatshrink2 library.
As for future plans for this application I don't really have any. It solves my issue the way it is today, but if there turns out to be an interested user community out there maybe I will try to clean it up and create a proper flatpak for it.
09 Sep 2025 2:39pm GMT
08 Sep 2025
Planet GNOME
Georges Basile Stavracas Neto: Marks and counters in Sysprof
Last year the Webkit project started to integrate its tracing routines with Sysprof. Since then, the feedback I've received about it is that it was a pretty big improvement in the development of the engine! Yay.
People started using Sysprof to have insights about the internal states of Webkit, gather data on how long different operations took, and more. Eventually we started hitting some limitations in Sysprof, mostly in the UI itself, such as lack of correlational and visualization features.
Earlier this year a rather interesting enhancement in Sysprof was added: it is now possible to filter the callgraph based on marks. What it means in practice is, it's now possible to get statistically relevant data about what's being executed during specific operations of the app.
In parallel to WebKit, recently Mesa merged a patch that integrates Mesa's tracing routines with Sysprof. This brought data from yet another layer of the stack, and it truly enriches the profiling we can do on apps. We now have marks from the DRM vblank event, the compositor, GTK rendering, WebKit, Mesa, back to GTK, back to the compositor, and finally the composited frame submitted to the kernel. A truly full stack view of everything.

So, what's the catch here? Well, if you're an attentive reader, you may have noticed that the marks counter went from this last year:

To this, in March 2025:

And now, we're at this number:

I do not jest when I say that this is a significant number! I mean, just look at this screenshot of a full view of marks:

Naturally, this is pushing Sysprof to its limits! The app is starting to struggle to handle such massive amounts of data. Having so much data also starts introducing noise in the marks - sometimes, for example, you don't care about the Mesa marks, or the WebKit marks, of the GLib marks.
Hiding Marks
The most straightforward and impactful improvement that could be done, in light of what was explained above, was adding a way to hide certain marks and groups.
Sysprof heavily uses GListModels, as is trendy in GTK4 apps, so marks, catalogs, and groups are all considered lists containing lists containing items. So it felt natural to wrap these items in a new object with a visible
property, and filter by this property, pretty straightforward.
Except it was not
Turns out, the filtering infrastructure in GTK4 did not support monitoring items for property changes. After talking to GTK developers, I learned that this was just a missing feature that nobody got to implementing. Sounded like a great opportunity to enhance the toolkit!
It took some wrestling, but it worked, the reviews were fantastic and now GtkFilterListModel has a new watch-items
property. It only works when the the filter supports monitoring, so unfortunately GtkCustomFilter doesn't work here. The implementation is not exactly perfect, so further enhancements are always appreciated.
So behold! Sysprof can now filter marks out of the waterfall view:
Counters
Another area where we have lots of potential is counters. Sysprof supports tracking variables over time. This is super useful when you want to monitor, for example, CPU usage, I/O, network, and more.
Naturally, WebKit has quite a number of internal counters that would be lovely to have in Sysprof to do proper integrated analysis. So between last year and this year, that's what I've worked on as well! Have a look:

Unfortunately it took a long time to land some of these contributions, because Sysprof seemed to be behaving erratically with counters. After months fighting with it, I eventually figured out what was going on with the counters, and wrote the patch with probably my biggest commit message this year (beat only by few others, including a literal poem.)
Wkrictl
WebKit also has a remote inspector, which has stats on JavaScript objects and whatnot. It needs to be enabled at build time, but it's super useful when testing on embedded devices.
I've started working on a way to extract this data from the remote inspector, and stuff this data into Sysprof as marks and counters. It's called wkrict. Have a look:
This is far from finished, but I hope to be able to integrate this when it's more concrete and well developed.
Future Improvements
Over the course of an year, the WebKit project went from nothing to deep integration with Sysprof, and more recently this evolved into actual tooling built around this integration. This is awesome, and has helped my colleagues and other contributors to contribute to the project in ways it simply wasn't possible before.
There's still *a lot* of work to do though, and it's often the kind of work that will benefit everyone using Sysprof, not only WebKit. Here are a few examples:
- Integrate JITDump symbol resolution, which allows profiling the JavaScript running on webpages. There's ongoing work on this, but needs to be finished.
- Per-PID marks and counters. Turns out, WebKit uses a multi-process architecture, so it would be better to redesign the marks and counters views to organize things by PID first, then groups, then catalogs.
- A new timeline view. This is strictly speaking a condensed waterfall view, but it makes it more obvious the relationship between "inner" and "outer" marks.
- Performance tuning in Sysprof and GTK. We're dealing with orders of magnitude more data than we used to, and the app is starting to struggle to keep up with it.
Some of these tasks involve new user interfaces, so it would be absolutely lovely if Sysprof could get some design love from the design team. If anyone from the design team is reading this, we'd love to have your help
Finally, after all this Sysprof work, Christian kindly offered me to help co-maintain the project, which I accepted. I don't know how much time and energy I'll be able to dedicate, but I'll try and help however I can!
I'd like to thank Christian Hergert, Benjamin Otte, and Matthias Clasen for all the code reviews, for all the discussions and patience during the influx of patches.
08 Sep 2025 3:04pm GMT
07 Sep 2025
Planet GNOME
Hubert Figuière: Dev Log August 2025
Some of the stuff I did in August.
AbiWord
More memory leaks fixing.
gudev-rs
Updated gudev-rs to the latest glib-rs, as a requirement to port any code using it to the latest glib-rs.
libopenraw
A minor fix so that it can be used to thumbnail JPEG file extracting the preview.
Released alpha.12.
Converted the x-trans interpolation to use floats. Also removed a few unnecessary unsafe blocks.
Niepce
A lot of work on the importer. Finally finished that UI bit I had in progress of a while and all the downfall with it. It is in the develop
branch which mean it will be merged to main
. The includes some UI layout changes to the dialog.
Then I fixed the camera importer that was assuming everyone followed the DCIM specification (narrator: no they didn't). This mean it was broken on iPhone 14 and the Fujifilm X-T3 that has two card slot (really, use a card reader if the camera uses memory cards). Also sped it up, it's still really slow.
Also better handle the asynchronous tasks running on a thread like the thumbnailing or camera import list content. I'm almost ready to move on.
Tore up code using gdkpixbuf for many reasons. It's incompatible with multiple threads, gdk texture were already created from raw buffers. This simplify a lot of things.
07 Sep 2025 12:00am GMT
06 Sep 2025
Planet GNOME
Jussi Pakkanen: Trying out import std
Since C++ compilers are starting to support import std, I ran a few experiments to see what the status of that is. GCC 15 on latest Ubuntu was used for all of the following.
The goal
One of the main goals of a working module implementation is to be able to support the following workflow:
- Suppose we have an executable E
- It uses a library L
- L and E are made by different people and have different Git repositories and all that
- We want to take the unaltered source code of L, put it inside E and build the whole thing (in Meson parlance this is known as subproject)
- Build files do not need to be edited, i.e. the source of L is immutable
- Make the build as fast as reasonably possible
The simple start
We'll start with a helloworld example.
This requires two two compiler invocations.
g++-15 -std=c++26 -c -fmodules -fmodule-only -fsearch-include-path bits/std.cc
g++-15 -std=c++26 -fmodules standalone.cpp -o standalone
The first invocation compiles the std module and the second one uses it. There is already some wonkiness here. For example the documentation for -fmodule-only says that it only produces the module output, not an object file. However it also tries to link the result into an executable so you have to give it the -c argument to tell it to only create the object file, which the other flag then tells it not to create.
Building the std module takes 3 seconds and the program itself takes 0.65 seconds. Compiling without modules takes about a second, but only 0.2 seconds if you use iostream instead of println.
The module file itself goes to a directory called gcm.cache in the current working dir:
All in all this is fairly painless so far.
So ... ship it?
Not so fast. Let's see what happens if you build the module with a different standards version than the consuming executable.
It detects the mismatch and errors out. Which is good, but also raises questions. For example what happens if you build the module without definitions but the consuming app with -DNDEBUG. In my testing it worked, but is it just a case of getting lucky with the UB slot machine? I don't know. What should happen? I don't know that either. Unfortunately there is an even bigger issue lurking about.
Clash of File Name Clans
If you are compiling with Ninja (and you should) all compiler invocations are made from the same directory (the build tree root). GCC also does not seem to provide a compiler flag to change the location of the gcm.cache directory (or at least it does not seem to be in the docs). Thus if you have two targets that both use import std, their compiled modules get the same output file name. They would clobber each other, so Ninja will refuse to build them (Make probably ignores this, so the files end up clobbering each other and, if you are very lucky, only causes a build error).
Assuming that you can detect this and deduplicate building the std module, the end result still has a major limitation. You can only ever have one standard library module across all of your build targets. Personally I would be all for forcing this over the entire build tree, but sadly it is a limitation that can't really be imposed on existing projects. Sadly I know this from experience. People are doing weird things out there and they want to keep on weirding on. Sometimes even for valid technical reasons.
Even if this issue was fixed, it does not really help. As you could probably tell, this clashing will happen for all modules. So if your ever has two modules called utils, no matter where they are or who wrote them, they will both try to write gcm.cache/utils.gcm and either fail to build, fail on import or invoke UB.
Having the build system work around this by changing the working directory to implicitly make the cache directory go elsewhere (and repoint all paths at the same time) is not an option. All process invocations must be doable from the top level directory. This is the hill I will die on if I must!
Instead what is needed is something like the target private directory proposal I made ages ago. With that you'd end up with command line arguments roughly like this:
g++-15 <other args> --target-private-dir=path/to/foo.priv --project-private-dir=toplevel.priv
The build system would guarantee that all compilations for a single target (library, exe, etc) have the same target private directory and all compilations in the build tree get the same top level private directory. This allows the compiler to do some build optimizations behind the scenes. For example if it needs to build a std module, it could copy it in the top level private directory and other targets could copy it from there instead of building it from scratch (assuming it is compatible and all that).
06 Sep 2025 8:30pm GMT