GIMP

@GIMP

Interview with Nara Oliveira, Free Software Artist

GIMP is Free and Libre Open Source Software, but none of it is possible without the people who create with and contribute to it. Our project maintainer Jehan wanted to interview the volunteers who make GIMP what it is, and share their stories so you can learn more about the awesome people behind GIMP!

Early interviews from co-maintainer Michael Natterer and Michael Schumacher were published shortly after the first Wilber Week. The remaining interviews from this event, about Simon Budig and Øyvind Kolås were published years later as a revival of the series. While these interviews are a bit old and reference outdated versions and features of GIMP, we believe they still have value and show the evolution of our community.

This next interview is the first one recorded at the 2017 Libre Graphics Meeting in Rio de Janeiro, Brazil. The subject is Nara Oliveira, co-founder of Estudio Gunga. She is a Brazilian artist and advocate who uses free software exclusively to develop professional works in many fields, including design, illustration, and animation.

This interview took place over April 21 - 23, 2017. In addition to Jehan and Nara, Simon Budig, and Aryeom Han were also involved and asked questions.

Nara Oliveira, CC-BY-SA
Nara Oliveira, CC-BY-SA

Jehan: Hello Nara. Can you introduce yourself to the people?

Nara: My name is Nara Oliveira. I am a Brazilian designer. I am from Brasília, the capital. The city name is Taguatinga. I study design and today I work with free software. I have my own company with some partners and we work in audio, video, design, and animation.

Jehan: What is the name of your company?

Nara: Gunga. Gunga is an instrument from Capoeira. We have the berimbau with the “calabash”, I think – it’s an instrument from Capoeira.

Jehan: Okay. From what we understood, you mainly use free software

Nara: Yes.

Jehan: Mainly, or only?

Nara: Only.

Jehan: And which ones in particular?

Nara: I use GIMP, Inkscape, MyPaint, sometimes Krita – I’ve tried it – Scribus, FontForge, FontMatrix, and others like everybody uses.

Jehan: Do you use Linux?

Nara: Yes, Arch Linux.

Jehan: So full free software from start to end! Okay, and why do you do this?

Nara: When I heard about free software and Linux, I was working in a cultural space. I was working with theater and with drawing, and we already have that culture of sharing things and sharing knowledge. So when I met these guys in free software, they told me about what GNU and Linux were and the philosophy – and when I heard about it I fell in love with it. Because I already think that way, and so free software is applying what I think is right onto software and onto technology. So for me it just makes sense.

So I started to use this software. In the beginning it was difficult to make the transition, but with some time I got into it.

Jehan: So you made a transition from proprietary software?

Nara: Yes, from proprietary software to Linux.

Farid: When was this?

Nara: When? Ah, let me count…

[group laughter]

I was not finished studying then, so like around 2006 or 2007 I started. I really started to use Linux and everything for working in 2008, for everything.

Jehan: So you studied design in university?

Nara: Yes, in university.

Jehan: With proprietary software?

Nara: Yes, with proprietary software only. But my university was not so focused on software. In five years of studying, we only had one class about software. And as the class went on, everyone already knows how to use it! So it’s like a class that has to be on the curriculum, but it’s not like you have to use – it’s more like conceptual.

Estudio Gunga Presentations and Workshops, by Nara Oliveira, CC-BY-SA - 2025
Estudio Gunga Presentations and Workshops, by Nara Oliveira, CC-BY-SA - 2025

Simon: Something I do a lot is that - I’m a software developer mainly, so I do a lot of my own tool development. Like I have a specific problem and I know there is an algorithm in my mind that I know would solve the problem (or might solve the problem), so I start implementing my own tools for very specific, very weird tasks, because I can’t do it with GIMP.

Nara: I would like to do that!

Simon: So this is what I wanted to ask – do you have programming experience? Do you have an idea of what it means to develop software?

Nara: No, but I think I have an idea – but I do not develop programs. I’ve studied a little, but it’s not like I can do something. I can see the code lines and know more or less what’s happening, but I can’t write lines by myself.

Jehan: You’ve told me that sometimes you will see some scripts and guess what it can be, and change the numbers…

Nara: Yeah, but more in insights and not in the programming itself.

Jehan: Since we’re doing this interview for gimp.org, what can you tell us about GIMP? How do you like it? How do you hate it? Tell us everything!

Nara: [Laughing] The first thing is, I like GIMP. I use it a lot. My work and style is more vector, but I use GIMP a lot and I like it.

When I made the transition to free software, until today one thing I didn’t like is that you don’t see the effects. You have do something, turn back, “Oh no!” - I have to change two, three points here, then I have to undo and do it again and come back. For me, it’s one of the things that makes the work not fluid.

I’m so happy to see GEGL on-canvas effects.

[Editor’s note: This feature was already implemented in the development version of GIMP 2.10, officially released about a year after this interview.]

Jehan: So, some other comments on GIMP?

Nara: Yeah, I really like it but, for example, I have some problems with my tablet. When I bought my first tablet, it simply didn’t work on GIMP. And I think it’s because of that, I use MyPaint. Because I have to work, and I have to work right now and the pressure doesn’t work, so what can I do with my tablet – so I found MyPaint, and I started to work with MyPaint, and it’s because of that I use it. Not because I think it’s more powerful than GIMP – it’s just because of that. At the time I liked it, and today I still use it.

[Editor’s note: GIMP 3.0 improved many issues with tablet support that were mentioned here.]

Jehan: So MyPaint is your main software?

Nara: For drawing, yeah. Because I am a designer, but I’m an illustrator too. So for illustration I use MyPaint, just for that. For small drawings, I use vectors in Inkscape, and so on.

I use GIMP more for photos, for editing, composing, correcting photos.

Estudio Gunga Projects and Film Fests, by Nara Oliveira, CC-BY-SA - 2025
Estudio Gunga Projects and Film Fests, by Nara Oliveira, CC-BY-SA - 2025

Jehan: Yesterday when we spoke, you had this nice example of a job you did with Scribus. Like your first job with free software, I think?

Nara: No, my first book.

Jehan: Ah, your first book, not your first job with free software. Could you tell it again, now that we’re recording?

Nara: I was called on to make a big book, like three hundred pages. There was little time to do it, like three, two weeks. I am from Brasília, and they said you have to do it here with us to get it quicker. I traveled to Bahia to do it, and when I arrived there, there were two other designers. It was funny because I worked in Scribus, one worked in Corel Draw, and the other one in InDesign. So you had three designers, three different software.

Jehan: And three different operating systems.

Nara: Yeah, and three different operating systems, and we had to do one book, the same book!

So we met each other and said “Okay, let’s do it!”. We separated the book into pages, so I would do the first one to 100, the other designer would do 101 to 200, and so on. And we together figured out how the design of the book would be, and the rules to make each part feel like the same book.

So we started, and just like that, I finished first! I was worried, because I had not used Linux for too long, and if there was something wrong in the software or in the distribution, I would not know how to fix it. One of the designers had Mac and the other had Windows and I was so worried.

But it went well and I finished first – and it was very encouraging for me. It’s just a tool you know? I can do it, he can do it, she can do it – everyone can make it, so I was very happy. Because in the beginning I was worried about everything going wrong, and that there would be problems when I saved the PDF and printed it, but it was all okay.

The book was about experiences with, we call it here “apprentice to Griô”. It’s from the French language, because it came from Africa but a country that speaks French.

It’s like an old master who teaches the people around them, the community, something – knowledge about herbs, which can be medicinal herbs, or teaches about techniques about how to construct instruments, or make music, or dancing – like masters of Brazil, of all Brazil. So it’s because of that it’s a big book!

Years later, in the north of Brazil, when the waters came and filled the houses in the city – a flood. I was seeing that on the TV there was an old lady with her flooded house beside her, everything destroyed. And she had that book in her hand. She was crying because her house was destroyed, but she had the book, and she was happy she still had the book even though she didn’t have her house anymore.

So it was a meaningful project, and it was the beginning of my using Scribus.

Jehan: Are there things sometimes you feel you are not able to do with free software? You already answered this yesterday, so I’m just asking again to hear you saying it.

Nara: When I see art – art is everything, design is everywhere – I can’t see something and think about “I can’t it do with free software”. I can do it – maybe I can’t do it because of my creativity or because I don’t think about it, but technically I can do it, you know. We have the tools to do it. We have other ways, but we have the tools I think – in my area of design.

Simon: What would interest me is, you mention that you use quite a lot of different tools, like GIMP, Inkscape, Blender, Scribus -

Nara: Blender not yet, though I started animating in the timeline. In the movie that we showed, the first one that was in 2D, I animated parts of that.

Simon: But there are a lot of different tools that you and your colleagues use. When you start a project, do you pick one of the tools and stick to it, or is more like you start using one tool then transfer the result to a different tool?

Nara: Yes, it was like each tool was like a room of a house. I live in the house, there’s a lot of rooms, and sometimes I’m in the living room, other times I’m in the bed room, other times I go to the kitchen. It’s like I have a bottle, and I take the bottle here and there.

I don’t choose the software. I plan the project, I think about it, and think “How am I going to make this?” So I will start drawing in MyPaint. But I need it to be a vector, so I save it, open in Inkscape and add a vector. But ah, I need an image in the background. So I open the image in GIMP, I work with the image there, then import into Inkscape, okay. But oh, now I have to print it. So I save what I can save in vector I save in vector, and what I can’t save, I export. And I go to GIMP, transform it and edit it, and I take everything, go to Scribus, put them together, and make a PDF. More or less like this. I’m always going back and forth between the programs.

Estudio Gunga Projects and Film Fests, by Nara Oliveira, CC-BY-SA - 2025
Estudio Gunga Projects and Film Fests, by Nara Oliveira, CC-BY-SA - 2025

I think it’s very complicated, but for me it’s very simple. But when I teach things like that it sounds very complicated.

Jehan: Do you have any questions, Aryeom?

Aryeom: I feel like I am in her head. I totally understand – I work the same way. Maybe later if I have any questions I’ll ask.

Nara: I learned everything by myself. So I don’t like tutorials, you know?

Aryeom: You don’t like tutorials?

Nara: Yeah, I don’t have the mind to read or watch them. I learn all by myself. I think my way of working is just my way, because I learn by myself. And sometimes I get in touch with people who use the software too, I like to watch them because people do things very different that I do, and things more easily. And sometimes I teach the software to someone, and in two weeks or three, I go to see what the people are doing. “Oh my God, I’d never think of that way!”. It’s very fun because of this.

I don’t like to do workshops because of that. I think my style of work is very crazy. But we can talk about it!

Jehan: So right now you have a big animation project. So maybe can you speak about it?

Nara: Well, Farid is the director. He writes the script. I am the art director, but I also help him with the script and doing all the storyboards. I do it in MyPaint. I was a little worried because I’ve never done a storyboard before. So I study a little, see other’s storyboards, and make it for the animation. And we are talking with people who want to work with us on the animation – and I was happy because people always say “You have a beautiful storyboard!”. I was worried about that.

I think we are, I don’t know, opening ways. Because we are not a 3D studio but we want to do 3D animation, so we have to contact on a lot of other people in Brazil and Latin America, and even in Europe. It’s been like a dream to make it. And we want to make it very fine, very good, because today if you are seeing bad 3D, then you don’t watch it. Because you have Pixar, you have Disney, you have a lot of others. I don’t think that we’ll be like Pixar, but we have to do something very good and great to be seen, you know? I think this is our goal. We want to make something very nice, very good that everyone wants to see.

We’re telling Brazilian history of Quilombo, when there was slavery. Some slaves ran away and made a tribe, a community of their own and lived there. And these communities survive until today. And some of them have a lot of different cultures. It’s like they’re isolated. And the story is about one of these communities. In Brazil the agriculture is taking the lands of these people, because they have a paper that says “We own these lands”, but actually these peoples have been there for 300, 400 years.

So we are telling the story of a girl who lived in a community like this. And they’re being pressured to go out and leave their lands. The story is a fiction, but it’s based on real facts. This is the history. It’s going to be like 10 minutes, it’s a short one, but it’s a real movie and after it’s finished, we want to continue it. Make like episodes or a long movie – it’s just like a pilot. But we need the pilot to get a bigger step.

Aryeom: I feel so moved, because our ZeMarmot project is also like this.

Nara: Here in Brazil there’s a law, I’m not quite sure, that for free television and private television, 50% of programs have to be Brazilian programs. Because it’s all foreign programs, so the government says that 50% have to be produced here in Brazil. So I have a lot of opportunities in that way for animated series.

Jehan: So you plan to distribute on TV.

Nara: Yeah.

Aryeom: Why did you choose 3D? Why not 2D?

Nara: Because we love it! We really love 3D, we’re really passionate. We started using Blender, even for 2D, but we want to go to 3D you know. We have some experiences, and we like the visuals of the movie – we actually don’t work with 3D, but we want to. A lot of people do that – I think 2D is less expensive and -

Jehan & Aryeom [in unison and laughing]: I don’t think it’s less expensive!

Nara: No? We like 3D. We want to make it – it’s so popular for the kids, for everyone. We want this movie not to go to the festivals and stay there. A lot of good films here are made this way. The very good films go to the festivals, earn their prizes, and no one’s ever seen the movie. “Oh you’ve seen that movie? No!”. It will never go to the cinemas.

We want it to have the chance to become popular, you know, a lot of people really watching it. And 3D has this affection, people really like these.

Estudio Gunga Projects and Film Fests, by Nara Oliveira, CC-BY-SA - 2025
Estudio Gunga Projects and Film Fests, by Nara Oliveira, CC-BY-SA - 2025

Jehan: I know you said you also appreciate Creative Common licenses and stuff like that, so is this movie going to be under such a license?

Nara: Yes, it’s going to be an open movie! You can take the characters and make another animation by yourself. If you want to take everything, the characters, the background, everything, and animate another story, you can do this.

Jehan: Which license?

Nara: We haven’t thought about it yet, but the kind of license where you can make anything.

Simon: You said 3D. I sometimes have the impression that 3D in some way is more limited in what you can do artistically compared to 2D.

Nara: Yes, it is.

Simon: So this is not a factor for you?

Nara: No. Because in 3D, it’s like you said. If you’re doing a 2D animation, I don’t know, you can do a lot of types of techniques. Like it can be black & white, it can be color, or so many types – it’s like art in stop motion. 3D is different – you have a character, and you have the scenery, and the scenery is just the scenary. You can make some tricks with lighting and shading and colors, but it stops there. It’s an artistic limitation, I agree with that.

Aryeom: In your team, no one had any experience making 3D animations?

Nara: I animate, but I know how to take the characters and make them move. But I’m not an expert. Farid knows that too and know how to make a 2D animation in Blender. But 3D is a new challenge for us.

Jehan: I think also the question was, you are a designer so you usually work in 2D. So we would expect something who draws would want this drawing to come to life, than just doing the drawing and give it to someone else to make the actual final thing.

Nara: I have difficulties with this. I get tired of drawing very quickly. I can’t imagine myself drawing the same character more than, I don’t know, 10 times. I think I would die if I did that.

Aryeom: Haha, I’m dying!

Nara: It’s like my style. This book was difficult to me, because I had to draw the characters the same. They have to look the same every time I draw it. I don’t like that. I like to do one drawing and it’s over. They have to repeat and be the same. I like the work, but the process of doing the same thing is difficult for me.

Jehan: So you prefer to just draw something and let someone else repeat it again and again.

Nara: Yes, like the computer!

Aryeom: To make a series, an episodic drama, it’s easier to make in 3D. For long form, it’s good I think.

Jehan: Yes, for long form, but for short movies it takes longer due to preparations.

Nara: So it’s not my kind of thing.

[Nara hands out a book]

Nara: It’s by a friend of mine who wrote the story and he asked me to make the drawings. I don’t do a lot of kid stuff, but I like it. And it invites kids to draw at the end of it. It talks about what city do kids want to live in, and what city we want for ourselves. We have a lot of problems in the cities here, and I like the idea of book, to let kids dream about the city because we want that dream to come true.

Aryeom: What about Gunga’s future?

Nara: Ehh, I expect in the future that we have more people working with us. And we have more companies work with us with free software, you know. I’d like to get larger but not too larger. Because I want my life too!

Aryeom: Wise!

Nara: But I’m happy now because last year two new people joined the studio, and it’s a lot more fun to work with more people. We exchange experiences, and I think I want to grow in that way, to get a little bigger and get more partners. And work with more cinemas! It’s more difficult because it’s expensive to work with cinemas, working with animations. We like to do more for ourselves. We make a lot of productions, videos for other companies, for the government, so we’d like to do more for ourselves – like our stories, less for them, more for us.

Estudio Gunga Projects and Film Fests, by Nara Oliveira, CC-BY-SA - 2025
Estudio Gunga Projects and Film Fests, by Nara Oliveira, CC-BY-SA - 2025

Jehan: Okay, maybe the last question unless someone has something. Do you have any requests for GIMP developers? Other than on-canvas preview because we already have it!

Nara: I will see the new version you talked about after this.

No, I’m okay. I think I’ve used it for such a long time that I’m so adjusted to it. In the beginning I had a lot of issues – if you gave me a paper then I would fill it with “I want this, I want that! Why do I have this? I can’t believe it!”

But today it is so natural to me that I had to think about it before coming here, because I’ll be meeting people that I want to talk about it with. And I think well, there are little things I want to change in the software. But I think that I have this because I’ve been using it for so long. People are always comparing it with propriety software, and I don’t compare it anymore because it’s been such a long time since I’ve opened something like Photoshop.

So, I’ll think about it.

Jehan: But in the end it just works!_

Nara: Yeah. I’ve written some*, but not for GIMP, for Inkscape, Scribus…

[Editor’s note: Jehan misheard the word “some” here as “song”]

Jehan: Ah! A song for everyone but us?

Nara: I used an earlier version of Inkscape which had a lot of bugs. They just changed it and so I have just bugs for Inkscape. Bugs are bugs.

Jehan: Ah, it’s bugs, not a song!

Nara: Yes, for Inkscape. For Scribus, I have some issues with development.

Aryeom: So you have bugs for them, but you have requests for us. So it’s good!

Jehan: Ah, okay. I thought you’d wrote a song.

Nara: No no – I know my letters are beautiful but it’s not a song.

And I’m happy to meet you! Very happy. I don’t go to a lot of events like here in Brazil. I don’t have a lot of time to do that. And it’s like an investment to travel here because it’s very expensive and the country is too big, haha. So my involvement with free software is like in my community. On our street where we work, a lot of people use Linux because of us. It’s like a center, you know? Time to time, someone goes there, “Oh, I bought a new notebook, I want to install Linux, let’s do it together”.

I think my part in this is more local than global – in the community. I feel better like this. Real connection, offline. I’m not so close to the development here and the other artists. And most of them, they’re just show artists. They don’t really work with design, they don’t really live from this, you know? I tend to know people who live from free software. Most of them are professionals, who are really good at one software, but they don’t put food on the table with it. It’s a little different. I learn from them, but I want to know people who have real issues.

Because when you don’t work with it, you just experiment, you make your own goals. Like “I’m going to make this girl have make-up on her face”, and then you do that. When you work, another person puts a goal on you. Like, “Make this girl have a guitar”, and you have to find a way to do that. And the process when you make a goal versus when another person makes a goal you have to achieve, it’s very different when you’re working with the software. Because you have to go somewhere you’ve never went before. And it makes you use the software in a different way.

You understand what I’m saying? Because when I see the workshops, people are very good at doing something they always do. I want to see people doing very good things they’ve never done before. These things show the real potential of the software.

Jehan: And the potential of the artist.

Nara: Yes, and the potential of the artist. Because you can show me, Inkscape or GIMP is doing this new thing. But maybe I’m not going to use it just because it’s in the software. I’m only will use it if I need it. So, there are a lot of people who are experts in the tools and what the tools can do – to make it, you have to use all the tools combined. It’s different, it’s another level.

Jehan: Well, I think that’s a good interview. Thank you Nara!

Nara: Thank you!


Estudio Gunga

Display Next Hackfest 2026

This year was the fourth year in a row that a bunch of display driver and compositor developers met for the Display Next Hackfest, to discuss, present, and tackle issues related to displays, GPUs, and compositors. Thanks to Collabora (Robert Mader and Mark Fillion specifically) for continuing this tradition!

(Check out the 2025 edition)

This time we met in Nice, France, after Embedded Recipes and right next to the PipeWire and libcamera hackfests. I took the opportunity to have a chat with the PipeWire developers about Flatpak, Portals, and the direction we would like to take in regard to video and audio access. Arun Raghavan has a nice summary if you’re interested.

That also brings me to another point: I have mostly stopped working on compositor and color-related areas. It’s not because I lost interest, but rather that I took over Flatpak and Portals maintenance. That by itself was taking a big chunk of time, but then LLMs became good at finding security vulnerabilities and now this takes more time than I have.

Before the hackfest, I sat down for one week and hacked on Mutter (the GNOME Shell compositor) to create a prototype with all the changes I wanted to do but never found the time for:

  • dropping colord
  • configuring ICC profiles and white point via the display config
  • splitting our color transformation code to provide a color pipeline
  • offloading color transforms to the KMS color pipeline
  • achieving color-accurate white point adjustment and night light

With the prototype done, I made my way to Nice, taking a sleeper train from Paris and waking up to the Côte d’Azur in the morning. Then I met with Robert in the botanic garden, where he used his deep cross-stack offloading knowledge to test a bunch of video playback scenarios.

Over the hackfest days we found some glitches in the AMD driver, which were promptly fixed by Harry Wentland. We also had some discussions on strategies to do KMS color pipeline offloading, which prompted some changes in the prototype, and now have something we can start upstreaming.

For the KMS color pipeline, we got a new fixed matrix operation for YCbCr to RGB conversion, and new named curves for important video playback cases. We talked about control over the color format on the cable (which has been merged by now), as well as control over the minimum BPC.

Another thing that we all got annoyed by was all the funky colors our in-kernel console became when our offloading worked a bit too well. We’ve wanted a reset mechanism for KMS for a few years now anyway, so we decided to prototype it and test it on Smithay. Proper patches are now on the mailing list thanks to Maxime Ripard.

Mario Limonciello managed to push out patches for backlight support via KMS before the hackfest – another thing we’ve wanted for years. We tested them on Mutter, and KWin added support for it as well.

Xaver Hugl showed that we can easily support AMD FreeSync Premium Pro, the worst name for a feature that is essentially Source-Based Tone Mapping (SBTM). We also got good news regarding SBTM on HDMI. In general, it looks like we might finally get HDR that isn’t entirely awful.

DisplayID, the replacement for EDID, is going to become much more prevalent, and we discussed how we’re going to roll out support in the kernel and in libdisplay-info.

We once again managed to put enough wayland developers in a room for a bigger protocol change to get merged. This time it was multi device dmabuf feedback which made Victoria Brekenfeld happy.

There was a lot more happening — check out Xaver’s and Louis Chauvet’s blog posts.

Even though I wasn’t as prepared as the previous times, it was very productive and there was more actual hacking this year. I also enjoyed meeting everyone again a lot, hanging out in the water while watching the 1% take off in their private jets, struggling to find an adequate Döner, and eating lots of pizza.

Until next time!

Michael Meeks

@michael

2026-07-08 Wednesday

  • Up too early, mail chew, plugged at stats generation. Encouraging scripting call with Stephan and others.
  • Sync with Gokay, Tracie, Anna & Laser, then Tobias & Thorsten, Alex & Victor, Anna & Timur then snatched lunch.
  • Published the next strip: An interview with Brigit - who wants everyone to be happy
    The Open Road to Freedom - strip#74 - an interview with Brigit
  • COOL TC meeting, some hacking, chat with Dave, admin.

    Transparency report from October 2025 to June 2026

    GNOME’s Code of Conduct is our community’s shared standard of behavior for participants in GNOME. This is the Code of Conduct Committee’s periodic summary report of its activities from October 2025 to June 2026.

    The current members of the CoC Committee are:

    • Anisa Kuci
    • Carlos Garnacho
    • Christopher Davis
    • Federico Mena Quintero
    • Michael Downey
    • Rosanna Yuen

    All the members of the CoC Committee have completed Code of Conduct Incident Response training provided by Otter Tech, and are professionally trained to handle incident reports in GNOME community events.

    The committee has an email address that can be used to send reports: conduct@gnome.org as well as a website for report submission.

    Reports

    Since October 2025, the committee has received reports on a total of 17 possible incidents. Several of these were not actionable; all the incidents listed here were resolved during the reporting period. There is currently a total of 7 incidents in process.

    • We were made aware of concerns regarding online comments made on social media by a GNOME Foundation member. Upon review, we found these comments to fall outside the scope of the Code of Conduct in this instance.
    • Report about messages sent to a Telegram channel. Contacted the reported person about the inappropriate nature of the messages.
    • Report about unfriendliness to newcomers in a localisation team. Asked the team lead to write down documentation on their procedures.
    • Question about clarification on the CoC’s text; replied suitably since the question was not actually about the CoC’s contents.
    • Tech support request; redirected to discourse.gnome.org.
    • Malicious question; closed without reply.
    • Report about homophobia; removed privileges for the reported person.
    • Report about a Mastodon post which was subsequently removed. Reminded the reported person that Mastodon posts in the context of GNOME are also under the scope of the Code of Conduct.
    • Report about two Mastodon posts which were subsequently removed. Reminded the reported people that Mastodon posts in the context of GNOME are also under the scope of the Code of Conduct.
    • Report about a TWIG submission, not actionable as there is no violation of the CoC.
    • Report unrelated to GNOME; notified the reporter and closed as non-actionable.
    • Report about an interaction in gitlab.gnome.org. Reminded the reported person about how to politely deal with disagreement.
    • Tech support request; already solved.
    • Report about suspicious activity in Matrix; not actionable other than to keep an eye out for the reported person.
    • Report about a person exhibiting bad behavior outside of the scope of the CoC. We will keep an eye on it.

    Meetings of the CoC committee

    The CoC committee has two meetings each month for general updates, and weekly ad-hoc meetings when they receive reports. There are also in-person meetings during GNOME events.

    Ways to contact the CoC committee

    The website repository, and the Code of Conduct itself and the committee’s procedures, are kept at https://gitlab.gnome.org/Teams/Conduct/gnome-code-of-conduct

    The Code of Conduct Committee is happy to receive questions about the CoC itself and its procedures, and we will gladly assist you. Please use the communications channels listed above.

    Sophie Herold

    @sophieherold

    Accessibility in GNOME

    July is Disability Pride Month. I want to use the occasion to speak about my perspective on accessibility in GNOME and what I think we should do.

    For disabled people, computers are often even more important than for abled (non-disabled) people. Many areas of everyday life are currently only accessible via a computer for many disabled people. Still, accessibility is often an afterthought in software and hardware development.

    GNOME is fortunate enough to have many disabled contributors in its community. We have contributors who are visually impaired, deaf, autistic, ADHD, or who live with migraines and other chronic conditions. While we have people that care about accessibility and work on improving it, the general state is far from ideal.

    The reality of tech communities is that they are often ableist and elitist. Probably more so than the average population. If a user or contributor struggles with a tool, blame is shifted to a “skill issue,” if an interface is simplified to make it accessible to more people, it’s “dumbed down”. Assistive technologies are often developed by abled people, without involving and paying disabled people. This also leads to an attitude where contributors expect gratefulness from disabled people for providing them with the most basic needs. All these issues are also not absent from the GNOME community.

    What We Already Do

    The goal of this section isn’t to boast about GNOME’s accessibility efforts. I believe that accessibility is a fundamental right, and nothing any disabled person is obligated to praise contributors for. Instead, the goal is to capture where we stand, and give other projects ideas they can adopt. Equally, I would be very happy to learn how other FLOSS projects try to work towards better accessibility.

    Our review criteria for Core and Circle apps require checking if keyboard navigation, screen reader support, large text, and high contrast mode work. We also require sufficient contrast in apps, which we usually use the Contrast app to check against the WCAG requirements. We have shown that we are able to enforce these requirements by delaying the inclusion or replacement of apps until accessibility issues were actually fixed. That’s also an improvement GNOME has seen over the last years, since originally, no quality criteria for apps existed.

    Many of the accessibility aspects are automatically covered by using our toolkits GTK and libadwaita correctly. I witnessed that accessibility is often considered during initial design and implementation. However, we don’t have any guidelines or requirements in GNOME for the development of these libraries.

    The GNOME Foundation funded work on screen reader support in GTK 4 in 2020 and 2021. In 2023 and 2024, accessibility was also one of the larger areas the GNOME STF project worked on. That means both the GNOME Foundation, and the STF organizers were willing to allocate money for accessibility, which is a good sign.

    However, accessibility is so much more than screen reader support. I think that GNOME’s general design philosophy is very important to being more accessible to a broader audience. This includes the focus on simplicity with good defaults, trying to avoid the possibility of misconfiguring the system, and the attempt to distract less. Translations, while often overlooked as an accessibility aspect, are another huge factor that makes our software accessible to so many more people. This shows that accessibility is hardly a separate set of features. Instead, it has to be considered as part of every area in a project.

    Among the more “traditional” accessibility tools within GNOME are the screen reader, high contrast, reduced motion, always show scrollbars, sound over-amplification, input adjustments, and magnification. But equally important are the “Dark Mode” and “Do Not Disturb” mode, which are not directly labeled as accessibility.

    How We Can Improve

    Disability Pride is about being proud of who you are. But, like Queer Pride, it is also about fundamentally changing the society in which we live. Hence, for this year’s Disability Pride, I am also thinking of what we can change within GNOME.

    Create an Accessibility Team

    Except for a dedicated accessibility chat room, there is currently very little coordination for accessibility within GNOME. My goal for this month is to establish a formal Accessibility Team. My initial ideas for the team are to prioritize voices of those with lived experience, instead of having others make decisions for us. Nothing about us without us. In more practical terms, the team should help to maintain and develop guidelines and review criteria that are especially relevant for accessibility. The team should also review larger changes in the GNOME project that affect accessibility. Ideally, we could provide and user testing on accessibility features directly from the people who rely on them.

    In addition to guarding the accessibility aspects of the software we produce, the team should also advocate for accessibility in our events, workflows, and tooling.

    If you are interested in contributing, please reach out via #a11y or in our issue #1. Let us know where and how you want to contribute.

    Use This Month Yourself

    If you are disabled, and you want to share your experience in FLOSS communities or have accessibility issues in GNOME or other FLOSS software, report the issues and/or post about them on social media under #AccessibilityInFreeSoftware.

    If you are a contributor, see if you can tackle one of the roughly 450 open issues that are labeled with “Accessibility” this month. Try to broaden your horizons by reading articles from disabled people you know less about, or follow them on a social media platform. Embrace accessibility as a fundamental human right, not something disabled people have to show gratefulness for. Try to reflect on your language. Don’t use sanist language like “sane defaults,” using “good defaults” does the job. Ask yourself if you want to keep words like “idiot” in your vocabulary, knowing that “idiocy” was the first category the Nazis used to systematically kill people.

    But also, don’t be scared of disabled people. We want to and deserve to be part of the community like everyone else.

    Happy Disability Pride Month! Let’s build a desktop that is accessible to as many people as possible.

    This blog post represents my personal opinions and not those of any organization I work for.

    Hylke Bons

    @hbons

    Icon for Demostage

    Icon for Demostage

    Week 25

    This week's icon is for Val Packett's project:
    Demostage: "Perform live demos from a virtual desktop"

    Check out all weekly app icons created so far over here and follow my icon creation adventures as they happen (including sketches) on the Fediverse.

    Need icons?

    I love designing icons and am happy to contribute them free of charge when your project is Free and Open Source. Funded by community sponsors (every little helps!).

    Jakub Steiner

    @jimmac

    The Machinist

    I couldn't remember something for weeks. It popped into my head during a run — a relief, even though the memory itself was not pleasant. This episode of my flaky mind reminded me of this movie.

    I won't give you even a hint of what the movie is about. The strength of it is not the premise, but the mood, the superb acting and Christian Bale's physical dedication to the role impressed me, alongside a cast of wonderfully weird characters and ominous presence of giant spinning machines. If you somehow missed the movie, give it a go. It's one of those that keep coming back to you.

    Michael Meeks

    @michael

    2026-07-05 Sunday

    • Up early, packed variously, bid 'bye to M&D, and the American Meeks.
    • Into Cambridge for H's baptism at Christ Church; with B&C&C, Mary Rogers and several of H's friends. A lovely service & dunking - out to Browns for lunch together.
    • Bid 'bye to N., dropped M & J & Sade to the station to help move M. into her new London home.
    • Dropped Mary home, slugged a bit, prepped music for and ran the evening service - Charlee spoke well. Relaxed.

      Hylke Bons

      @hbons

      Icon for Meshy

      Icon for Meshy

      Week 24

      This week's icon is for Jiří Eischmann's project:
      Meshy: "Meshcore mesh network client"

      Check out all weekly app icons created so far over here and follow my icon creation adventures as they happen (including sketches) on the Fediverse.

      Need icons?

      I love designing icons and am happy to contribute them free of charge when your project is Free and Open Source. Funded by community sponsors (every little helps!).

      This Week in GNOME

      @thisweek

      #256 Beyond 8-Bit

      Update on what happened across the GNOME project in the week from June 26 to July 3.

      Third Party Projects

      Haydn Trowell says

      The latest version of Typesetter updates the built-in Typst compiler to version 0.15, which brings a long-awaited feature: variable font support – no more warnings and faulty font rendering when using your system’s default fonts. This release also adds a popularly requested feature to the editor: manual font size adjustment – use the standard keyboard shortcuts to make the text larger and smaller.

      Get it on Flathub: https://flathub.org/apps/net.trowell.typesetter

      albfan reports

      Finally is here: gitg 50, more stable and customizable

      Full of new actions to interact with your git repos, even customizable ones

      Once downstream packaging is available, give it a try and send feedback

      Shell Extensions

      Fabiano Junior says

      Hello everyone! I’ve just released new updates for ChromaLeon, my extension that extracts and applies colors from your wallpaper to your GNOME Shell and LibAdwaita theme.

      The focus of these updates was refinement: the color extraction system is now smarter, ensuring better compliance with WCAG accessibility guidelines regarding contrast. Additionally, I’ve improved the icon generation system (folders and apps) to make it much faster and more efficient, now generating icons almost instantly.

      You can check out the project on GitHub and GNOME Extensions.

      storageb reports

      Create custom time-of-day schedules for the Night Light!

      Night Light Scheduler lets you create a custom schedule for GNOME’s built-in Night Light allowing you to automatically adjust the color temperature throughout the day according to your schedule.

      Features:

      • Create a schedule to automatically adjust Night Light color temperature throughout the day
      • Smoothly transition between temperatures with an adjustable transition time
      • Import and export schedule configuration as an editable .ini file
      • Uses GNOME’s built-in Night Light functionality
      • Easy to use visual interface

      More information is available on the project’s GitHub page.

      Miscellaneous

      Cleo Menezes Jr. | World Cup mode 🇧🇷🇧🇷 says

      Mosaic WM is maturing and being refined, polishing the rough edges, finding bugs, hearing from you.

      To do that, I’ve created a Matrix room and I’d like you to be there. You don’t need to be an expert, just someone who wants to help make it better.

      In?

      Damned Lies

      The internal application to manage localization of GNOME & friends modules

      Guillaume Bernard announces

      This week, we released for Damned Lies a new feature for team coordinators. When updating your team details, you can now create a presentation that will be sent to new team members as a notification. Use it to present the team, the workflow, link your docs, identify a module for newcomers…

      Internships

      AnonymouX47 announces

      Five weeks into GSoC 2026, I’ve made solid progress on GPU reset recovery in Mutter!

      When a GPU reset occurs, Mutter currently has no way to recover; the desktop either freezes or crashes. My project implements a recovery path: detecting the reset, waiting for it to complete, recreating the context, and propagating that change through the compositor to recreate resources so rendering can resume.

      The display now comes back after a reset, and the session remains usable, though there’s still work ahead: notably, automatic framebuffer recreation and fixing the desktop background, which currently renders with garbled textures after recovery.

      Read the full details, including a demo: https://blogs.gnome.org/anonymoux47/2026/07/02/gpu-reset-recovery-in-mutter-a-progress-update

      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!

      Laureen Caliman

      @lcaliman

      Pick a word, any word

      Over the past few weeks, I have been writing the backend for the vocabulary-puzzle generator for Crosswords.

      But what entirely dictates a valid word placement whilst being mindful of all edge cases and managing the state of the puzzle upon the exploration of possible solutions?

      Finding valid intersections

      For each word in the list, the vocab generator searches for every valid location where the word at the current depth could be added (or not added) to the current puzzle. A candidate must satisfy several constraints:

      • Word must intersect existing puzzle.
      • Intersecting characters must match.
      • Existing letters must not be overwritten by conflicting letters.
      • The word is within a 30×30 board boundary.
      • Puzzle remains entirely connected.
      • Word placements cannot connect flush to their head/tail to another word.
      • Could there be multiple valid intersections?

      As more words are added, the number of possible intersections rapidly grow. A single placement may produce several valid connections, each of which must be evaluated independently.

      Modeling the intersections

      The vocab grid generator represents candidate placements by using the coordinates of the intersection, placement direction (across, down), and the offset of the intersecting character within the word. As a whole, an intersection can transform the entire puzzle. For instance, “APPLE” and “PEAR” are just two words, but share four possible intersections. Rather than selecting one immediately, we ultimately want to record every valid candidate.

      Each of these shared candidates then become a potential node in our recursive search tree. As our puzzle grows in size, the problem becomes less about placing words and more about exploring all valid intersections whilst preserving the integrity of the puzzle state as we add and rearrange words.

      Securing agentic identity

      As is the case for many people working in the security industry, the last few months of my life have been focused on dealing with people wanting to use LLMs everywhere. From an enterprise security perspective that’s not an inherent problem - what’s more of a problem is that people want those agents to have access to resources like their calendar and email and so on, and now we have somewhat non-deterministic agents that seem very enthusiastic to achieve what you asked whether that’s a good idea or not, and we’re combining this with credentials that give them access to sensitive data, and leaving those credentials on disk where they can be committed into git repos or exfiltrated to some other service to make use of them on the agent’s behalf or well just any other number of things, at which point your CEO’s email is suddenly readable by everyone and you’re having a bad day.

      As I mentioned in my last post, pretty much every strong mechanism for keeping credentials in place is just not supported in the wider world. We can imagine a universe where agents use hardware (or at least hypervisor) backed certificates to obtain credentials and any that end up leaking are worthless as a result. But, sadly, that’s not an option for most people using existing identity providers. The state of the art is that you use the device code flow and a human authenticates and the token ends up back inside the agent environment and then it proceeds to do whatever it wants with it and you just hope that you wake up the next morning without an awful infoleak occurring.

      (An aside: I do not like the device code flow as used in enterprise environments, and I never will. The identity provider doesn’t have a real opportuity to inspect the security posture of the system asking for the token, and as a result some identity providers will restrict tokens that are issued in this way. The common alternative of doing stuff using a more standard flow and having a redirect URI pointing at localhost works fine for local systems and is a pain for remote ones, even if you can commit crimes with SSH forwarding. I’m going to suggest something that I think is better, and you are free to disagree)

      I’m not in a position to get every identity provider and service provider to change their security posture, so I’m somewhat stuck in terms of the tokens they’re willing to issue me - largely either JWTs or opaque access tokens, with no support for any mechanism of binding that token to an instance. The token that’s going to have to be provided to the remote service is something I have little influence over. But that doesn’t mean I can’t influence the token that lands inside the agent’s environment. I can issue a placeholder token to the agent, and force it to communicate via a proxy that swaps out the placeholder for the real thing. The worst the agent can do is exfiltrate the placeholder token, and as long as malicious actors don’t have access to that proxy, it doesn’t matter - nobody else can do anything with the placeholder.

      This isn’t a terribly novel insight, and it seems like almost everybody has reinvented this on their own. But a lot of these implementations involve you somehow obtaining the real token in advance and then pasting that into something that generates a placeholder that you provide to your agent environment somehow, and it’s all a bit clunky and awkward, and it also means that you need to deal with something that keeps track of the mapping between placeholders and real tokens and oh no we’ve just invented a secret store, and if you want this to work at scale and reliably you’re just invented a high availability distributed secret store, and a lot of people who’ve read that are now shaking their heads and reaching for gin. Can we simplify this, and improve security at the same time? I think we can!

      Remember when I said “as long as malicious actors don’t have access to that proxy, it doesn’t matter”? What if they do? What if they compromise one machine inside your environment and are then able to email a bunch of employees and convince their agents to send more tokens back to them and then delete the email before a human reads it? Now you have someone inside the wall with access to those tokens, and presumably with access to the proxy, and now they can be anyone whose agent was gullible enough to think sending them a token was a good idea. This isn’t good!

      So, I thought for a while, and I came up with a new idea. We can have a broker service that obtains credentials for us. We can run that centrally, away from the agents. A client in an agentic environment can request a token, and that can result in a URL being generated and the user being directed to open a URL in a browser and authenticate. When the user authenticates, the authentication flow redirects the confirmation back via the broker, and the broker obtains the real auth token. The obvious thing to do now would be to return the auth token to the client in the agentic environment, but we don’t do that. Instead, we mint a new JWT, and add a new claim - one that contains an encrypted copy of the token. In the process we can copy over all the original claims, because those aren’t secret - and now even if the client inspects the token to figure out what access it has, it’ll get a correct answer. We sign the new token with our own signing key, and pass that back to the client. The client now has a legitimate JWT that is utterly useless, because the signature isn’t trusted by anyone other than us.

      How does it use it? It makes an API request via a proxy, including the new token in the Authorization: header. The proxy verifies the signature on the token, and then decrypts the original token and swaps out the fake token for the real one. The remote API sees what it expects, and everyone is happy. There’s never a real token in the agentic environment, but also we don’t need to store anyting anywhere. The only state is the encryption keys, and those can be injected into the environment at startup. You need to scale? Just start more of these processes. You need to support multiple availability zones? Just start more of these processes in different places. No persistent data is ever held in the broker or the proxy. You don’t need to care about distributed databases or secret stores.

      This felt wonderfully elegant and I felt smug about coming up with a better idea, and then I went to a bar earlier this week and sat down to read RFC 8705 and the guy next to me saw that over my shoulder and asked what I was reading and I explained why I was interested and we talked about agentic identity and then he mentioned that fly.io had something that sounded very similar and I read that and gosh yes it is very similar, so damn you fly.io for stealing my ideas 3 years before I even had them. Anyway. Now I need to do better.

      Remember that there’s still a risk around anyone who has access to the proxy having access to the encrypted keys? We can remove that risk as well. It’s not uncommon for agentic environments to have an identity issued via something like SPIFFE, at which point they have a client certificate. You can probably guess where I’m going with this. If we require that an agent present a client cert to the broker when requesting a token, we can embed a representation of that client cert into the token we mint. The proxy can then require mTLS for the client connection, and can verify that the presented certificate matches the one represented in the token. If it does then whoever’s using the token has access to the private key associated with the environment it was issued to. If we then ensure that the private keys backing these certificates are either hardware or hypervisor backed, and as such tied to a specific instance, we now have a high degree of confidence that the token can only be used in its intended environment. Even if our identity provider doesn’t support RFC 8705, we can.

      This is fairly straightforward where you’re using a platform where your identity provider is also the environment that’s consuming your tokens, and more annoying for third parties. The broker potentially needs some amount of third party vendor knowledge to make that work for everyone. This is even more the case where login isn’t via your identity provider (thanks, github), but none of this is insurmountable - just annoying. And where vendors issue opaque tokens rather than JWTs, this still isn’t a problem; we can just mint a new JWT that includes the opaque token as an encrypted claim, and include the same certificate binding. The opaque token ends up being the thing that’s presented to the third party, but only after we’ve verified the mTLS binding.

      In an ideal world none of this would be necessary - someone would spin up a new agentic environment, a user would prove their identity, and a certificate embodying that identity would be issued to the environment with a private key that can’t be exfiltrated. That certificate would be sufficient to obtain new certificates associated with the same private key, and we could still bind that into mTLS identity. This would be much simpler, but browsers don’t support it, so it’s not likely to happen any time soon.

      Anyway. Even if we can’t have the best thing, we can do better than we are at the moment, and also it would be lovely if we could standardise on this rather than have everyone build their own thing. The end.

      Toluwaleke Ogundipe

      @toluwalekeog

      GPU Reset Recovery in Mutter: A Progress Update

      It’s overdue, but here is my first progress update. If you haven’t read my introductory post, the short version: I’m implementing GPU reset recovery in Mutter, the Wayland compositor at the heart of GNOME Shell. When the GPU encounters a hardware- or driver-level fault and resets, invalidating the EGL context and wiping out all allocated GPU memory, Mutter currently has no way to recover. My project aims to change that.

      Here is where things stand at the time of this writing:

      Graphics reset recovery demo

      After a period of normal operation, a reset is triggered: the display goes dark, then comes back once a new framebuffer is created (currently triggered manually by maximizing the active window via a keyboard shortcut). Windows are rendering, input works, the session is alive. You’ll notice the desktop background looks wrong after recovery; I’ll explain why later in this post. The compositor itself, however, is no longer dead.

      The Problem

      A GPU reset is the hardware’s way of recovering from a hang or fault in the graphics pipeline. For the rest of the system, it means the GPU’s state has been wiped: any GL context that existed before the reset is invalid, and all GPU-allocated memory (textures, framebuffers, shader programs, etc) is lost.

      Mutter’s fundamental problem is that it doesn’t create a robust GL context. While Mutter does call GetGraphicsResetStatus() as part of its existing rendering logic, without opting into the appropriate reset notification mechanism, that call will never return a reset status, even when one has occurred. Mutter (on main) simply has no way to detect a GPU reset, let alone recover from one.

      The consequences in practice are severe. On some drivers (notably Mesa’s radeonsi/amdgpu), the driver deliberately kills the process when a non-robust GL context is present for a GPU that was reset. On others, Mutter would continue rendering blindly against an invalid context, with monitors on the affected GPU frozen on the last frame before the reset. GL errors accumulate on every subsequent frame, and the only way out is to kill the process. Either way, the session is lost, along with every application running within it. This has been a known, long-standing issue.

      The Foundation

      The API that makes detection and recovery possible is provided by the EXT_robustness OpenGL ES extension and its EGL counterpart, EXT_create_context_robustness. By specifying the EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY attribute with the value EGL_LOSE_CONTEXT_ON_RESET at context creation, we opt into deterministic reset notification: GetGraphicsResetStatus() will now reliably return a reset status when one has occurred, and the context is invalidated in a well-defined manner. Additionally, GetGraphicsResetStatus() can be called repeatedly with the lost context itself and will return NO_ERROR once the reset has fully completed, which is precisely how we know when it is safe to attempt restoration. It’s worth noting this isn’t universally available: not every driver implements reset notification, and even where the EGL/GL layer supports it, actual reset detection depends on cooperation from the kernel driver. Robustness is something we can build on, not something we can assume.

      Before GSoC began, Robert had already laid the groundwork for this. His commit did the following:

      • Registered EXT_create_context_robustness as a Cogl EGL winsys feature, so that its availability can be queried at runtime.
      • Added EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY and EGL_LOSE_CONTEXT_ON_RESET to the attribute list at context creation, when that feature is available, creating a robust context for the first time.
      • Added a stub clutter_backend_reset_context() as the hook where recovery logic would eventually live. For the time being, it simply emitted a warning.
      • Wired up the detection path in meta_compositor_real_after_paint(); whenever GetGraphicsResetStatus() returned a reset status, the stub was called.

      He also added support for simulating GPU resets in Mesa’s llvmpipe software renderer (MR !40681). By creating or modifying a file at a path specified by the LP_CONTEXT_RESET_FILE environment variable, all llvmpipe contexts using the LOSE_CONTEXT_ON_RESET strategy that were created before that file start reporting a reset; contexts created afterwards correctly report no error. Without this, the only way to test would be to induce actual hardware or driver failures, which is considerably less convenient.

      The Recovery Cycle

      The naive first instinct, which is to detect the reset, immediately recreate the context, and resume rendering, does not work, and for a subtle reason: a GPU reset is not instantaneous. After GetGraphicsResetStatus() first returns an error, the hardware may still be in the process of resetting. Attempting to recreate the context mid-reset invites further failure, and so the correct approach is to wait for the reset to complete before attempting any restoration.

      This led to designing the recovery as a cycle with two phases, Reset and Restoration, tracked by a set of five states:

      A state diagram showing the five states of Mutter's graphics reset recovery cycle: Normal Operation transitions to Reset in Progress when a reset is detected, which transitions to Reset Completed once the hardware finishes resetting or after a 2 second timeout. Reset Completed transitions down to Restoring, which either loops back to Normal Operation once the context and resources are successfully restored, or transitions to Recovery Failed after retries time out, exiting the process.
      Graphics reset recovery cycle

      All of this state management currently lives in ClutterBackend, with initial reset detection in ClutterStageView‘s frame handler. When GetGraphicsResetStatus() first returns an error, the state transitions to RESET_IN_PROGRESS and a GLib timeout source begins polling for reset completion every 20 milliseconds. Once GetGraphicsResetStatus() returns NO_ERROR, indicating the hardware has finished resetting, we move to RESET_COMPLETED. If the reset takes longer than 2 seconds, we proceed to restoration anyway; empirically, if a reset is going to complete, it does so quickly.

      The restoration phase runs entirely outside the frame dispatch loop, using GLib idle and timeout sources. When this starts, the state transitions to RESTORING. Thanks to Jonas, an important lesson from an earlier implementation was that restoration must not happen during frame dispatch, because that code runs per monitor; you do not want to recreate the EGL context for every connected display.

      During recovery, every frame dispatch is aborted. The frame handler signals to the frame clock that the frame should be dropped without scheduling a replacement. This check occurs both at the beginning of the frame handler, before any rendering occurs, and at the end, to catch resets that occur mid-frame.

      If restoration fails and retries exhaust a 2-second timeout, the state transitions to FAILED and Mutter exits gracefully with a descriptive error message, rather than aborting or hanging indefinitely.

      Restoring The Graphics Pipeline

      Once RESET_COMPLETED is reached, restoration begins. The core of it lives in clutter_backend_restore_graphics(), and the sequence is:

      1. Unref and destroy the current CoglContext.
      2. Tear down the CoglDisplay, destroying the underlying EGLContext.
      3. Re-setup the CoglDisplay, creating a fresh EGLContext.
      4. Create a new CoglContext against the newly set up display.
      5. Emit ClutterBackend::graphics-reset to notify everything else.

      Step 2 required a small new addition to Cogl: cogl_display_destroy(). Previously, there was no way to tear down a CoglDisplay‘s contents without destroying the object itself, which would have invalidated references to it held throughout the codebase. The function calls the object’s destroy() implementation and marks it as no longer set up, leaving the object intact and ready to be re-setup.

      Straightforward in isolation, but the interesting work is in everything that happens at step 5.

      Propagating the reset through the compositor

      ClutterBackend::graphics-reset is the hook through which the rest of the compositor learns that a new EGL context exists and needs to respond. Several objects connect to it, and the order in which their handlers run matters significantly.

      The current sequence, enforced through the use of the G_CONNECT_AFTER flag, is as follows:

      1. ClutterStage unrealizes: The stage is hidden and unrealize() is called on the stage actor, cascading down to all child actors (including every ClutterText in the scene graph). This must happen before the font renderer is recreated; more on why in the next section.
      2. ClutterContext recreates the font renderer: ClutterPangoRenderer, which holds the GPU-backed glyph cache, is destroyed and recreated with the new CoglContext.
      3. MetaBackend updates the stage: Stage views are rebuilt, and cursor rendering is updated.
      4. ClutterStage realizes: The stage is realized against the freshly rebuilt views and shown again.

      One improvement made along the way: Compositor view recreation was previously triggered by a signal emitted when monitors or monitor settings change. With graphics reset recovery requiring the same operation, MetaCompositor would have needed to listen to two sources, along with ordering concerns relative to MetaBackend’s handler, which rebuilds the stage views. Instead, a new MetaRenderer::views-rebuilt signal was added, and emitted at the end of meta_renderer_real_rebuild_views() regardless of what triggered the rebuild. MetaCompositor now listens to that single, unified signal, and the ordering fragility is avoided entirely.

      The signal handler ordering for the graphics-reset signal still depends to some extent on GLib connection order, which is not ideal. A more explicit, well-defined ordering mechanism is already in the works.

      Recovering the glyph cache

      Window content and client-rendered surfaces come back naturally once the context is recreated and stage views are rebuilt, clients re-render their Wayland buffers, and Mutter composites them. But some GPU-tied state lives inside the compositor itself and needs explicit recovery. The most intricate case encountered so far is the glyph cache.

      ClutterPangoRenderer maintains a texture atlas of rendered glyphs, built up as text is drawn to the screen. When the GPU context is lost, that atlas is gone. Simply recreating the renderer, as ClutterContext does in step 2 above, creates a fresh, empty one. But there is a subtlety: ClutterText actors internally cache PangoLayout objects, and each layout carries rendering data tied to the old renderer via GObject qdata. Drawing text with a stale layout against the new renderer produces incorrect results or crashes.

      The fix required a small chain of additions:

      • clutter_forget_layout(), a new function in clutter-pango-render, removes the qdata from a given PangoLayout, severing its tie to the old renderer. It verifies that both the renderer and the qdata exist and that the qdata was produced by the current renderer before clearing it.
      • ClutterText.unrealize(), a new virtual method implementation, calls clutter_forget_layout() on each of ClutterText‘s internally cached layouts when the actor is unrealized.
      • When ClutterStage unrealizes (step 1), the unrealize cascade reaches every ClutterText actor in the scene graph, clearing stale layout data across the board.

      This is precisely why the stage must unrealize before the font renderer is recreated. ClutterText‘s unrealize() calls clutter_forget_layout(), which requires the old renderer to still be alive to destroy the layout’s qdata. If the renderer were already replaced, it would be impossible to correctly destroy the data. The stage is then re-realized in step 4, after the new renderer exists and stage views have been rebuilt, allowing text to render cleanly from a fresh cache.

      Where things stand

      As the recording shows, the compositor survives a GPU reset, and the session remains usable: windows update correctly, input is responsive, and the session doesn’t crash or freeze. There are two notable gaps, though.

      First, framebuffer recreation isn’t automatic yet. After recovery, the display stays dark until something triggers the creation of a new framebuffer; in the recording, I do this manually by maximizing the active window via a keyboard shortcut. Without that nudge, stage views are rebuilt, but nothing causes a fresh framebuffer to actually be allocated, so the screen just stays black. Making this automatic is one of the next things to sort out.

      Second, once the display is back, the desktop background renders with incorrect or garbled textures. MetaBackgroundImage and MetaBackground hold references to GPU textures (primarily the background image loaded from disk), and MetaBackgroundContent defines GLSL shaders, all of which are invalidated by the reset. Recovering them requires updating these objects to re-upload their GPU-side resources after the reset.

      There are also residual GL errors after recovery that need investigation, and the signal handler ordering situation deserves a more deterministic solution.

      What’s next

      • Signal handler ordering: replacing the implicit connection order dependency with an explicit, documented mechanism.
      • Automatic framebuffer recreation: removing the dependency on a manual trigger (like maximizing a window) for the display to actually come back after recovery.
      • Background texture recovery: getting MetaBackground and its counterparts to listen to the graphics reset signal and reload their GPU-side resources.
      • Auditing remaining GPU-tied resources: ensuring nothing else in the compositor holds stale references after recovery.
      • MR review and upstream integration: the current implementation lives on my fork and is primarily only reviewed by my mentors; as the approach stabilises, it will be proposed for upstream review.

      Thanks

      A huge thank you to my mentors Jonas Ådahl, Robert Mader, and Carlos Garnacho for their incredible guidance since the beginning. I’d also like to thank Bilal Elmoussaoui for the valuable review comments on my merge request. On to what’s next! 🦾❤

      Preventing token theft

      When you log into a service you’re given an authentication token. Each further request to the site includes that token, allowing the server to figure out who you are and ensuring that you have access to your data. Depending on site policy, this token may either be stored in memory (and so vanish if you restart your browser) or disk. The token is the proof of your identity. As far as the site is concerned, anyone with your token is you. These tokens may be traditional browser cookies, but they may also be stored in either site local storage or (if you’re not using a browser) in some other storage location.

      In recent years we’ve seen infostealer malware (like LummaC2) gain the ability to exfiltrate user tokens, allowing attackers to gain access to the user’s data without needing to retain access to the user’s machine. This attack is viable even if the site has strong MFA requirements, so passkeys don’t help. Encrypting the tokens on disk doesn’t prevent the malware from scraping them out of the browser’s RAM or obtaining whatever key is used to encrypt them. This feels like a pretty hard problem to solve.

      But that hasn’t stopped people from trying! Dirk Balfanz wrote an IETF draft describing a mechanism for using self-signed certificates for TLS authentication. This uses the mutual authentication feature of the TLS protocol that requires both sides prove their identity to each other. In regular TLS, the remote site presents a signed certificate that tells you who it is. When performing mutual authentication, you then present a certificate to the remote site telling it who you are. These client certificates are largely unused outside enterprise environments because they’re a huge pain to deploy. It’s not so much that this has sharp edges, it’s that it’s entirely made of sharp edges. Managing certificate deployment to your devices is hard. Browsers get confused if the certificates change under them. You have one certificate and it lives forever, so sites you present it to can track your identity. Users are prompted to choose a certificate to authenticate with, and if they pick the wrong one everything breaks and is hard to recover. I’ve deployed this and I did not have a good time.

      But Balfanz’s idea was simple. Rather than require certificates to be deployed, browsers would simply generate a certificate on the fly. The goal wasn’t to prove the device or user’s identity in any global way - but it would associate a TLS session with a specific certificate. You could then, for example, include a hash of the certificate in the cookie, and if someone tried to use that cookie without presenting that certificate then the cookie could be rejected. If the browser used a hardware-backed private key for the certificate then it would be impossible for an attacker to steal it. Sure, you could still steal cookies, but you wouldn’t be able to use them.

      This was written almost 15 years ago, and seems simple, elegant, and functional. It didn’t happen. Part of the reason for that is that, well, it wasn’t quite so simple. One problem was privacy related. Cookies are only sent after the TLS session is established, so anyone monitoring the network doesn’t know anything about the user identity. A naive implementation of this approach would have meant the client certificate being sent before session establishment, and now user identity can be tracked (no longer an issue if this was implemented on top of TLS 1.3, but this was a log time ago). This was avoided by reordering the client handshake, but that meant having to modify the TLS specification and implementations would have to be updated to support this. Another was that figuring out the granularity of the certificates was difficult. You’d want to use different certificates for every site to avoid them effectively becoming tracking cookies, but you need to provide the certificate before cookies are set, and you don’t know what origin the site is going to set in its cookies. If you generate a certificate for a.example.com and a different one for b.example.com, and a.example.com sets a cookie for *.example.com and includes the certificate you used for a.example.com, that cookie isn’t going to work on b.example.com and things are broken. This meant supporting it wasn’t as straightforward as it seemed - you’d need to ensure that your cookie scope was compatible with the certificate scope. You could probably make this work well enough by aligning it with the Public Suffix List, but there was still some risk of expectations not being aligned.

      And, perhaps most importantly, TLS session resumption (replaced by pre-shared keys in TLS 1.3) somewhat defeats the purpose of the exercise - clients store state that allows them to re-establish a TLS connection without performing certificate exchange (this reduces overhead if a connection gets interrupted or you switch to a new network or anything along those lines), and anyone in a position to steal cookies could steal that state as well.

      The followup attempt was channel IDs. This simplified the implementation somewhat - rather than certificates, a raw public key would be sent, along with proof of possession of the private key in the form of a signature over a portion of the TLS handshake. This was required even in the event of session resumption, which avoided having to worry about theft of session secrets. The timing of the exchange was after the encrypted session had been established, so user identity couldn’t be leaked that way either. Cookies could then be bound to this identifier. Unfortunately it didn’t really deal with the problem of scoping keys in a way that would match cookie requirements, and the spec suggests that the right way of handling this is to scope keys to TLDs, which would enable user tracking across sites (Chrome’s implementation apparently restricted it to eTLD+1, which would match the third party cookie policy and avoid the tracking risk).

      Chrome added support for this, but it was removed in early 2018. The discussion of some of the pain points in that message is interesting, explicitly calling out problems with connection coalescing across domains and the incompatibility with zero-RTT TLS1.3. The overall consensus at the time seems to be that trying to solve this entirely at the TLS layer has too many rough edges, and a different approach should be taken.

      And so almost 7 years after the initial draft for origin bound certificates, we come to token binding. This ended up being a rather more complex endeavour, covering 3 different RFCs describing how it impacts TLS, how to incorporate it into HTTP, and how to manage all the various parties involved in the process. The short version is that it’s pretty similar to channel ID, except that there’s also a documented mechanism for allowing tokens to be bound to one party and consumed by another, avoiding any need for widely scoped keys. Token binding effectively solved all the issues in the original proposal, but at the cost of somewhat more complexity.

      The RFC was finalised in October 2018. Chrome removed its (incomplete, draft) support for token binding in November 2018. Edge carried support until late 2024. Despite getting all the way through the RFC process, it’s functionally dead.

      The process up until this point had been largely initiated by Google, with Microsoft contributing significantly to the token binding standards. The work had been focused on identifying a generic solution to the problem rather than tying it to any specific authentication flow. The next step was in a different direction - rather than trying to fix this for the entire internet, how about we try to fix it for OAuth?

      RFC 8705 is titled “OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens”. This is basically the 2011 approach, but (a) with an explicit definition of how the certificate should be incorporated into issued auth cookies, and (b) with a proviso that well uh if you’re going to use tokens issued by your IdP to authenticate to someone else then well you’re going to need to use the same cert for both. This is probably fine for the company-owned-laptop case where you’re actually fine with multiple sites being able to tie identities together (that’s kind of the point here!), and also works for “I am using an app and not a browser”, but doesn’t work for more generic scenarios. It also doesn’t seem to take the session resumption case into account at all? Support for RFC8705 seems poor, as far as I can tell of the big players only Auth0 implements it. In theory it works fine with self-signed client certs but in reality that’s going to be almost as difficult to support across multiple platforms as just issuing proper client certs in the first place, so deployment is going to be kind of a pain. But the good news is it doesn’t rely on any TLS extensions or custom browser behaviour, so at the client side it works fine with any browser.

      Which brings us on to RFC 9449, “Demonstrating Proof of Possession”. This goes even further than RFC8705 in terms of reducing the burden of deployment - it works fine with existing browsers, and it doesn’t even require any certs. The client generates a keypair and provides the pubkey when requesting the cookie. The cookie contains the pubkey. Every request to the service now provides the cookie with the pubkey and also provides a signature over the URI and HTTP method. If the signature matches the pubkey in the token then clearly the signature came from the machine the token was issued to, and everything is good.

      This does come with some downsides, though. The first is that it uses browser interfaces to generate the keys (typically crypto.subtle.generatekey()) and as far as I can tell there are no browsers that guarantee that that key is going to be generated in hardware even if it’s marked non-exportable, so anyone able to steal the cookies can also steal the keys. The second is that the signature only covers the URI and HTTP method, and not the message content or any other headers, so anyone able to exfiltrate a valid signature can replay it against the same URI with different message content. The recommended way to handle this is to reject any signatures that weren’t generated within the last few seconds, which is a wonderful additional way to allow clock skew to give you a Bad Day. And the third is that every single request has to be separately signed, which is not intrinsically a problem because computers are fast and have multiple cores, but if you’re trying to solve the first problem by sticking the key in a TPM then you’re dealing with something that’s slow and single threaded and that’s maybe acceptable if you’re using client certificates (because there’s going to be one signature per session and you can use the same session for multiple requests) but probably not if you’re dealing with a user opening a browser that restores previous tabs and each of those is a webapp that fires off 100 requests in parallel.

      In case it wasn’t clear, I don’t like DPoP. It doesn’t feel like it actually solves the underlying problem that we see in the real world (malware running in a context where if it can grab the tokens it can grab the keys), it adds a massive amount of overhead, and it has baked in replay vulnerabilities. I don’t know why it exists and I’m incredibly suspicious of vendors telling me that it fixes my problems, because if they’re telling me that then I’m going to end up assuming that they either don’t understand my problems or they don’t understand their technology, and neither of those is good.

      Still. Then we get to the thing that prompted me to write this - Chrome’s announcement that they had launched device-bound session credentials. This is interesting because it’s a Chrome feature that’s explicitly intended to counter on-device malware, which was one of the things that was out of scope in 2018 when token binding was being removed. Since this is entire web level it doesn’t have to be an RFC, and so is instead defined by W3C. I’m going to handwave all the complexity and say that it’s basically a way to register a public key when a cookie is issued, and then prove possession of the private key when it’s time to renew the cookie. By making the cookies shortlived and having support for rotating them in the background, user impact is basically zero and while it’s still possible for an attacker to exfiltrate and use a cookie they’ll only be able to do so for a short window before it needs to be refreshed - something the attacker can’t do, since they don’t have the private key. This avoids the DPoP overhead because you only need to do signing once per cookie per cookie lifetime, and not on every single request. I don’t like this due to the window where exfiltrated tokens can be used, but it feels like a strict improvement over the status quo. An extension called device-bound session credentials for enterprise allows pre-enrollment of device keys, so even though the actual runtime DBCE flow doesn’t involve certificates, certificates can be used for device registration in enterprise environments and you can make sure that auth cookies only go to trusted devices. Unfortunately this is Chrome-only, and so we’re going to need to wait for it to be backported to all the random app frameworks for it to have widespread support on mobile or for almost everyone’s desktop app that’s actually three websites in an Electron wrapper. Mozilla’s current position is that they’re not in favour of it, so I guess we’ll see where Safari lands in terms of broad uptake.

      The last thing on my list is another client cert/OAuth binding, this one still in draft state at the time of writing. This one is aimed primarily at the use of agent-driven tooling, where you have something running in the background using a whole bunch of tools that are each acting on your behalf. Authenticating to all of them separately isn’t a fun time, but giving broadly scoped access tokens to a non-deterministic agent and trusting that it’ll never post them somewhere public also isn’t a fun time. The key distinction between it and RFC8705 is that it’s aimed at connections rather than sessions, which avoids the worries about session resumption. This is done with TLS Exporters, which in TLS 1.3 should be unique to the connection even over session resumption (TLS 1.2 may reuse some of the same key material for exporters over session resumption, so it’s recommended to enforce 1.3 for this). By providing a new signature alongside the cookie on every new connection, the client proves that it still has access to the private key. This is a very new spec and I haven’t had much time to work through it yet, but my naive understanding is that unlike RFC8705 this would require some additional client support to be able to regenerate the client signature on every TLS reconnection.

      This doesn’t avoid all the problems that RFC8705 has, including how to scope certificates. For the agentic use case that probably doesn’t matter - all these tools are acting on behalf of the same user, it’s fine if all the sites involved know they’re the same user. But it doesn’t solve the general purpose user use case, and right now DBSC seems like the best we have there.

      But. Part of me still wonders whether Dirk Balfanz’s approach was the right one. Yes, there’s risk associated with TLS session resumption, but in the worst case you could just switch that off for high risk setups. The cookie scope argument is real, and also in cases where it could violate privacy the site owner could already choose to broaden their cookie scope and violate your privacy, and in cases where it breaks things you could just not make use of it. The other problems are largely fixed by TLS 1.3, and then we’re just left with “Browsers handle client certificates badly” to which my answer is “Yes, and we should fix that anyway”.

      Despite having a pretty good answer to this solution over a decade ago, the closest we have to actual deployment is something that offers strictly worse security guarantees. And tokens keep getting stolen, and compromises keep occurring, and for the most part people shrug and get on with things.

      Michael Calabrese

      @mccalabrese

      Pitivi Timeline Ruler | Widget Maturing

      Hello GNOME, This is a progress report on the Pitivi Timeline Ruler Rust rewrite.

      Progress

      We are rewriting the Pitivi Ruler in Rust using a modern GtkSnapshot rendering pipeline to improve performance and memory safety. At its current stage the ruler is being constructed as a standalone widget in a personal repository that can be found here:

      Pitivi Timeline Ruler

      GTK_DEBUG=interactive cargo run --example sandbox
      

      Any feedback on the code is greatly appreciated!

      Updates

      The widget is drawing well and a lot of the initial bugs have been ironed out.

      A major structural change that has been made after mentor feedback was to pull state orchestration out of the widget itself, and keep more of the logic on the app side. The goal is a "dumb widget, smart app" framework, where the ruler acts as a stateless viewport. The app (or sandbox example) provides the logic for how to handle gestures and what to do when the user interacts with the widget. One example of this is that project_duration was removed as a property entirely, and logic around bounds is now handled entirely on the app side. This allows the widget to be used in a variety of contexts, and allows the app to handle bounds in whatever way is appropriate for the context.

      Beyond the pivot on structure, some key systems-level refinements were made:

      • Property types we refactored heavily as this moved past the rough prototype stage. zoom_level received a rename to ns_per_pixel to better reflect what the property actually represents. Many properties dealing with pixels were changed to unsigned integers, which allowed me to delete out some negative checks.

      • The project does now include a rough doc string and comment draft for the widget, which will be fleshed out more as the widget matures and more of the public API is finalized.

      • Cache clearing was added to set_ns_per_pixel to prevent modulo math escapes during purging of cached layouts when users change the zoom level.

      Next Steps

      The major milestone ahead is the implementation of a custom gtk::LayoutManager to handle the layout of children widgets.

      Once the PitiviTimelineLayoutManager is implemented, the playhead rendering will be moved out of the ruler's snapshot pipeline and into the layout manager as a distinct child widget. This will allow Pitivi to easily inject custom markers, loop-brackets, and multiple playheads without modifying the underlying ruler engine.

      I am currently studying Marc-André Lureau's rdw (Remote Desktop Widget) repository as a guide on how to make this update.

      Michael Catanzaro

      @mcatanzaro

      Your _get_type() function is not G_GNUC_CONST: Part Two

      This blog post is a sequel to Your _get_type() function is not G_GNUC_CONST.

      GNOME developers have long used G_GNUC_CONST, which expands to __attribute__((const)), to annotate GObject _get_type() functions, despite knowing that it is incorrect to do so. const functions by definition have no side effects, but _get_type() functions actually have a side effect the first time the function is called: they initialize the type. Why apply an incorrect annotation to these functions? Because it makes the code faster.

      Although this was long known to be incorrect, it worked fine in practice… until now. Regrettably, Sam James has discovered that GCC 16 may optimize away the type initialization, resulting in crashes. This is our fault for providing the compiler with wrong information about our code, so it’s time to audit your use of const attributes to remove them from _get_type() functions. Most GNOME programs use these attributes only for _get_type() functions, but if you use it in more places, then check to make sure those functions are actually const, as defined by the GCC documentation.

      Sadly, there is no suitable replacement attribute for _get_type() functions. Two decades ago, Behdad requested a new idempotent attribute for expressing the desired semantics, but nobody has implemented it.

      Nathan Willis

      @n8willis

      Conferring notes (aka SCALE|LGM|WAVE|ATypI|LAS|Grapholinguistics)

      File under: brief half-year catch-ups, me not remembering when I last updated the back-end of this blog

      I’m writing this from a terrible AirBnB in Reading, having just wrapped up a four-day visit to my old Typography & Graphic Communication alma mater and happy to have an excuse to put off re-packing. I’ve been fortunate in the first six months of this year to have time to participate in a number of in-person conferences after a few years of not being able to travel, and when I was looking back at the calendar I noticed that these events have been evenly split between FOSS events and type-related events, so I decided it’s worth jotting down a few of the thoughts that presented themselves before they fade away entirely. Here’s a recap:

      SCALE: The Southern California Linux Expo (which, for the record, I refuse to bacronymize in a mixed-case form, so don’t at me about the capital A). I’ve been a regular for yikes years at this point, and have helped coordinate the “libre graphics track” for the past several, but this time I actually had to present a workshop as part of that. It was on the subject of learning Scribus if you’re coming from the world of LibreOffice / Microsoft Word / Google Docs / Etc. Turns out that’s an ambitious subject, scope-wise, and we didn’t get through everything I wanted to.

      But for me, that highlights the fact that shifting from one Do Real Work application to another is always a monumental effort. Sure, you can fire up GIMP and do some cropping of images in a matter of minutes. But you can’t drop a full production workflow without a lot of spare time, because every individual sub-task now involves a different order of operations (or different operations), a different cycle of tool-switching, and a different set of cross-checks and QA. I don’t think we give this problem enough attention, especially when the well-meaningers on social media (and yeah, that includes Mastodon, as fully as whatever platform you don’t like) entice people to give it a try like it’s no big thing.

      It also reiterated for me how important document templates are. Those are fairly forgettable 99% of the time, but what ships in the template choosers of LibreOffice, WhateverOfficeOnline, and in more specialist apps is what people end up using when they need to get things done. The typography in most FOSS templates is pretty awful: the fonts are weak, the hierarchies are non-existent, the alignments are haphazard, and the optical balance is even more non-existent than the hierarchies. I suspect that this can only be improved with a long, slow, many-person grind. I don’t know where to start.

      WAVE and ATypI: Both of these are type-related or type-adjacent events, so I don’t have much that feels relevant to say about them here. WAVE is quite specialized, since it focuses on human writing: just as many of the presenters are linguists as anything else, and the type people made a stronger showing this year than they did in the original event a couple of years back but aren’t the majority. It is genuinely a wake-up call to sit down and learn about a written language that does not operate in the way that your own does, and to hear exactly how many people use it every day (as well as to see photos to remind you that all of this happens in the present, when it’s incredibly easy to write off those concerns as belonging to an earlier era in printing and just presume that Computers Fixed All That. Or that OpenType and Unicode did. Or that FOSS did.).

      I do think, however, that most of the FOSS projects I’m involved with keep a stout set of blinders on about non-majority language systems and scripts, and that that’s deeply problematic. Indeed, it was not long ago that I mentioned IRL that GNOME could do a valuable bit of good for the global user community by finding and supporting scripts other than Latin/Greek/Cyrillic — in contrast to today, where the attitude is “oh, those users will figure it out for themselves like they always do aren’t they great over there” and/or “Noto Fixed All That.” It’s not hard to say that the next release of your project will also support, say, Arabic, and to at the very least be deliberate about bringing people into the room to find and test the fonts you need to determine if things are working and look good. Yes, you do have to do actual tests. Yes, I mean you.

      ATypI, in contrast, is very much a “type production” event. For me, this year the bit that stood out was behind-the-scenes stuff that eeped out around the seams and got more widely discussed. Like, there was evidently initial interest from some on the local organizing side that there would be a verrrry small list of presenters: less than two dozen, total, for 3–4 days (depending on how you count workshops and exhibits). Far less than two dozen. There are two big gotchas there. First, you have to contend with gatekeeping. All of the well-known people are likely to be the ones with The Exciting Announcement to announce and, in theory, they’re a big part of the draw. But that keeps all the new community members out. Second, it crashes the economic viability of attending the event. The locale this time was Stanford, which (despite being perhaps the world’s only Junior University, look it up) is outrageously expensive, even if you already live outrageously in nearby northern California. And any time people can’t justify the cost of travel, yes you’re gatekeeping again (particularly of the hallway track), but you’re also twisting the dial on your conference further from “I Should Go” over to “Going Is Just Paying Money To Be In The Audience Of A YouTube Video That I Can Watch Any Other Time” … which is a hard dial to reverse.

      LGM: The Libre Graphics Meeting seems to be back on its feet and in good form after several post-pandemic years of bumping into things. Massive props. I had a lot of side-project stuff I brought along in disorganized form, although I attended every session. I also quasi-roundtabled a session to talk about how the now defunct “Planet LibreGraphics”, may it rest unpeacefully, used to be the clear answer to the perpetual question of “how do we maintain momentum and connection the rest of the year?”

      But whereas the old Planet site was a garden variety class-M aggregator of individual blogs’ RSS or Atom feeds, I’m of the unprofessional opinion that a true community aggregator today has to account for different types of inputs and outputs and user modes (sideputs?). E.g., many projects don’t announce new releases on their project blog anymore; they tag a release on GitHub. That’s a different input. A lot of people don’t post long-form content anymore, but do a lot of microblogging. That might suggest having an ActivityPub output … but it would be a bot, and it would incur a TON of overhead and put scores of messages out all day long, which you definitely couldn’t use on the traditional RSS output. So you probably need to handle those differently, maybe batching the Mastodon bits into a once-per-day blog output?

      Ultimately, I’m not sure; there are a lot of these details. We’re way out in the high-cosmic-ray environment of the trans-neptunians here, or some other metaphor. Ping me if you find the question interesting, because I want to talk a lot more about it.

      LAS: It was my first time going to the Linux Application Summit, as the kids call it these days, so I have more thoughts to get down about that one. For starters, it wasn’t what I expected, because I expected there to be more people there who develop Linux applications. I covered a lot of growth of post–CD-delivered-and-RPM/Apt-updated packaging efforts when I was toiling as a not-so-young FOSS journalist, so I do think I have the right grounding in systems like Snap, Flatpak, FlatHub, AppKit, immutable-image OS approaches and other user-code–confinement technical building blocks. Except Kubernetes; I never cared about that and never will.

      Anyway, all of that stuff (hand-waving) is very much where LAS takes place. It’s really good to see that there are people from multiple application ecosystems talking about how they handle the current set of unsolved problems. Selfishly, one of the sessions that stood out most to me was Carlos Garnacho’s talk about the data-search layer that he’s been working on. The gist there is that it’s for searching local data … which you might think you can already do, but you’d be wrong. You can sort of do filesystem-level text searching, but that doesn’t handle complex stuff, and it really, really doesn’t let you handle per-application searching well. I’ve got a keen interest in what people do with their “big data exports” — we FOSS people like to look down our noses at the public and tell them that they should take all of their content out of The Bad Services and walk into the sunlight. But there’s not anything they can do with it when they get here (or there, depending on how you feel), and they’re the ones holding the bag. The TinySparql and LocalSearch stuff, I think, holds the potential to improve on that in a big way.

      I was also quite interested to learn more about how the KDE ecosystem does its builds. I don’t do … builds, at least not in the sense that KDE and GNOME do (nor, who else, who else … Enlightenment, maybe?). But I have been forced against my will to get up to speed on some things like GitHub Actions, and the session about KDE’s build architecture did make me want to go back and re-examine some stuff I’ve built. That being the other sense of “build.” I was also very interested in Evangelos Paterakis’s talk about the gritty realities of picking up an abandoned project, reviving it in fork-form, and getting hit with the consequences of that decision from both upstream and downstream.

      For most people, what matters in these sort of pseudoplumbing projects in what’s going to be accessible in end-user applications whenever they land on the next platform releases. That’s why I thought I might encounter app developers at LAS. Instead, much of the session content was about enhancing the the plumbing layer themselves: what’s going on with portals, how sandbox/confinement techniques either fail-open or fail-closed, and where the confined-application model is still leaking.

      I suggest checking out Sebastien Wick’s talk about the portal situation if nothing else; the slides are available now, even if the video is not. Whenever the videos go up, I also suggest that everyone watches the session about forking a defunct project … not because it’s something everyone should do, although let’s face it, projects appear and fizzle all the time. But mainly because the social aspects of how a revived fork does or doesn’t catch on are things the FOSS community doesn’t say out loud. Not bad or shameful things, just sharp corners.

      All that said, I think that what really needs to happen is for application developers to actually go to this event. I know you think you don’t need to. But the platform layer is another one of those things about which you can easily say “Didn’t Somebody Already Handle That?” and be incorrect for a long period of time before it bites you. Moreover, every time I’ve ever asked the developer of a Mac or Windows desktop app what they know about developing Linux apps, they tell me a story about running into giant potholes, missing documentation, and mismatched API expectations. The presence of Linux app developers at a plumbing-layer conference will not instantly fix that, but I do know that a lot of those Linux developers hit the same roadblocks.

      LGM made a massive improvement to the ecosystem of creative-arts apps in FOSS specifically because it involved getting users, app developers, and subsystem developers into a single space. That’s not a magic trick, and the general Linux app universe would benefit from repeating the technique.

      Grapholinguistics in the 21st century, also known as /gʁafematik/: This is the one I just came from, and I don’t quite have it all simmered from ingredients into stew just yet. Apart from being hosted in an initially un-airconditioned spot at the university in the hottest UK week since 1666, I don’t think I have any complaints. I introduced speakers and acted as moderator for Q&A blocks, and apart from that I visited with most but not all of the rest of the quantitative type-research clique. You know where to find us.

      One takeaway, perhaps, that will be generally useful is that I spent much of the inter-session time when I was on moderator duty trying to gauge the level of nervousness of the upcoming speaker and attempting to defuse it. I don’t know how successful that actually was, but I do think there were sessions elsewhere where it might have made a difference. I don’t know; perhaps that’s projecting.

      Anyway, before the Internet runs out of bits, I should wrap up. I do need to be sure to express my appreciation to the GNOME Foundation, who chipped in with some travel expense assistance for LAS, as well as to my friend and mentor-in-a-few-very,-very-limited-capacities-I-can’t-emphasize-that-part-enough Sri Ramkrishna for pinging me about it and then reminding me. I’m definitely glad I went.

      At the moment, I’m halfway through reconfiguring the blog site here into static format (fighting Unicode support in the old platform), so don’t count on commenting to work. If you want to reply to anything I said here, try me on Mastodon.

      This Week in GNOME

      @thisweek

      #255 Curated Updates

      Update on what happened across the GNOME project in the week from June 19 to June 26.

      Third Party Projects

      Alexander Vanhee reports

      I have overhauled Bazaar’s curated page. Vendors, such as distributions, can now make use of several widget types to showcase the apps they want to promote to their users. One of these widgets displays articles, which can be used to recommend apps or share general news about the OS in a place where users will naturally discover them.

      (The data shown is only for illustrative purposes.)

      jjjjjj0 reports

      I published last week the first release of EdiTidE.

      It’s a simple source-code editor, something between the GNOME Text Editor and GNOME Builder. Think of it as an alternative to Notepad++ in terms of features.

      It works fully sandboxed, and is quite convenient to quickly open a project and browse the code in.

      It has a bunch of settings for customization (like for replacing the menubar by a hamburger button, to make it more GNOME-ish), and can be enhanced with extensions (in Python).

      Get it on Flathub Contribute to translations

      Tanay Bhomia reports

      Whisp Update: Smart Text Expansions, 4k Downloads, & Donations!

      Whisp just crossed 4,000 downloads on Flathub! Thank you all for the incredible support. Donations are officially live! If Whisp helps your workflow, you can now support its solo student development via Ko-fi or GitHub Sponsors on the website.

      In v1.3.4, we’ve also added a major new feature to remove friction from your workflow: Smart Text Expansions.

      Typing :: anywhere in a note now opens a lightning-fast, completely keyboard-navigable GTK popover to instantly insert dynamic data:

      ::today / ::date(5) for dynamically calculated dates. ::roll(d20) for D&D dice rolls. ::random(str, 20) for instant secure passwords or placeholder text.

      Links: https://flathub.org/en/apps/io.github.tanaybhomia.Whisp | https://github.com/tanaybhomia | https://tanaybhomia.github.io/Whisp/

      Sjoerd Stendahl announces

      This week I’ve released several updates to Lockpicker, a new tool to recover passwords from their hash. The most obvious change is that the console-output has been replaced by friendly widgets, giving a much more convenient overview. The status overview also spots a progress bar to see how many candidates have been tested. And the ordering of the sidebar should be more intuitive. The logo has also been updated to look a bit more proper for now.

      Lockpicker now also has support for sessions. You can pause a session, or run multiple in parallel. Sessions persist over reboots, so you can pick up any time it’s convenient. Finally word lists and rules can now imported into the application, and be chosen from a dropdown menu.

      Get it on Flathub here!

      francescocaracciolo announces

      Newelle (AI assistant and agent for Gnome) updated to 1.4.5

      This new release features:

      🖼 Image generation support (supporting an integrated stablediffusion instance or cloud models)

      💬 New chat redesign: a more minimal and space efficient layout

      🐞 Minor improvements like support for STDIO MCP Servers

      Get it on Flathub

      Anton Isaiev announces

      RustConn 0.17 Released

      This is the first release since RustConn turned one, and it landed just two weeks after 0.16. Despite the long feature list, the goal hasn’t changed: RustConn is still a simple address book and orchestration layer over your connections, nothing more.

      The headline this cycle is Workspaces. With a dozen sessions open across split panes, you can now save the whole set as a named workspace and reopen it in one click - every connection, tab order, split layout, and tab group restored. Reboot the laptop, come back, and your working set is exactly where you left it. No more leaning on clusters and re-clicking reconnect.

      A few other highlights, mostly user requests:

      • Simple Sync - opt-in bidirectional sync of connections, groups, templates, and snippets across devices. Passwords stay in each device’s keyring, never in the sync file.
      • Native PKCS#11 / YubiKey SSH auth - hardware-token keys offered directly, no SSH-agent workaround, works through jump hosts too.
      • Built-in port knocking and fwknop SPA - open a firewall before connecting, pure-Rust, no external CLI.
      • Security hardening - clipboard auto-clear, SSH passwords zeroized from memory, and a couple of command-injection paths closed off. Homepage: https://github.com/totoshko88/RustConn Flathub: https://flathub.org/apps/io.github.totoshko88.RustConn Snap: https://snapcraft.io/rustconn

      Gitte

      A simple Git GUI for GNOME

      Christian says

      Gitte, a simple Git client for GNOME built with GTK4, libadwaita and Relm4, just got its 0.8.0 release! 🎉

      The headline feature this time is cherry-picking: you can now grab one or more commits straight from the commit log and apply them onto your current branch. Diffs also learned to handle the awkward cases gracefully. Binary files and overly large diffs are now clearly marked as such across all diff views, and there’s a new “filtered files” option that lets you configure paths which are treated like binary files and kept out of diffs. In the working copy view you can filter what’s shown to new, tracked or all files.

      You also get more space when you need it: you can maximize the diff view with Ctrl+M, and in the commit graph that shortcut cycles between maximizing the graph, the diff and the normal layout.

      A few new things can now be configured per repository: you can set merge-/pull-request and issue URLs manually for each one, and pick a default location for new and cloned repositories (thanks to René Fouquet!).

      On the UI side, the revert dialog and the commit detail box got an overhaul.

      And of course there’s the usual pile of fixes: bad SSH-signed commits are now shown as bad instead of “key unavailable”, commit messages now conform to the Git specification, and signature verification finally works under Flatpak, where the verification temp file is now written to a path that’s also reachable from the host.

      Under the hood there’s a fresh Chinese (zh_CN) translation (thanks to Dawnchan030920), new just / bacon developer commands including recipes to build and run as a Flatpak (thanks to Bahrom Magdiyev), and the Nix flake can now build and run Gitte directly with nix build / nix run (thanks to bitSheriff).

      Get it on Flathub, for macOS or have a look at the Code.

      Gir.Core

      Gir.Core is a project which aims to provide C# bindings for different GObject based libraries.

      Marcel Tiede reports

      New GirCore C# bindings got released in version 0.8.0. The most prominent feature is GTK-Template support which required some breaking changes. Please read the release announcement for details. Further changes included support for GNOME SDK 50, several under the hood fixes and improvements to make working with GirCore easier.

      Bouncer

      Bouncer is an application to help you choose the correct firewall zone for wireless connections.

      justinrdonnelly reports

      Bouncer 50.1.0 is here, and it’s a big one!

      Thanks to user submissions, this release includes new and updated translations and improved accessibility. There are also some subtle bug fixes alongside some more noticeable new features.

      Bouncer now uses more modern Adwaita widgets throughout, replacing basic labels and buttons for a more polished look and feel. The dashboard has also been redesigned as a tabbed interface, with a new Networks tab where you can change the firewall zone for a saved network or make Bouncer’s forget it altogether.

      As always, Bouncer is available on Flathub!

      Shell Extensions

      Christian W reports

      On the road a lot of frequently use VPNs? Show External IP extension does what it says and displays your external IP in the Toolbar, including Country flag. It sends a system notification if your IP has changed. Shows also IP history with Export and an image of the approximate location.

      This extension is handy for those who work at different locations or with different VPNs to quickly see your public IP and country.

      Search for “Show External IP” in Extension Manager Download here: https://extensions.gnome.org/extension/5368/show-external-ip-thisipcancyou/ Github: https://github.com/cwittenberg/thisipcan.cyou

      Aryan K announces

      Medialine is a GNOME Shell extension that shows your currently playing media right in the top bar, in a minimal and elegant way.

      It detects any MPRIS-compatible player (Spotify, Chrome and even PWAs) and displays the track inline in the panel. Click the indicator to open a rich popup with album art, a live seekable progress bar, and full playback controls — shuffle, previous, play/pause, next, and repeat. Supports multiple playing media in a compact view.

      The highlight is basically the support for PWA, it properly recognises the PWA icons and opens the correct window when clicked. Also has dynamic background color for the pop-up, based on the album art of the playing media.

      Get it today from: https://extensions.gnome.org/extension/10076/medialine/ Homepage: https://github.com/funinkina/medialine

      Miscellaneous

      Evangelos “GeopJr” Paterakis 🏳️‍⚧️🏳️‍🌈 reports

      This week I launched a small unofficial website to share a few demo test builds of some GTK, Granite and libadwaita apps on Android. Give them a try!

      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!

      Jussi Pakkanen

      @jpakkane

      Pystd standard library, similar-ish functionality with a fraction of the compile time

      I submitted talk proposals about Pystd, the from-scratch written standard library for C++ (custom design, not a implementation of the ISO specification) to a bunch of conferences. Unfortunately all of them were rejected, so it's blog posting time.

      A controversial opinion

      Pretty much everybody agrees that compiling C++ is slow, but I personally feel that it is intolerably slow. Other people might disagree, and that is fine, but let's look at some numbers.

      Compiling a helloworld executable in C takes approximately 0.02 seconds. Compiling a C++ exe that does the same thing using #include<print> takes a second if optimizations are disabled and up to 2.3 seconds with them enabled. This is approximately a 100x slowdown. I'm using a Ryzen 7 3700X processor, so not the latest and greatest but not too shabby either. I have talked about this slowdown with some people in person and weirdly often their answers have been "that's not a problem, two seconds is insignificant". Even if you accepted this (which personally I don't) the big problem comes from scaling because the slowdown factor is approximately linear. Let's assume that in a less extreme case the slowdown was only 20x instead of 100x. In this case a program that should be done in 0.1 seconds takes 2 seconds, and therefore a program that should compile in one minute would take on the order of 20 minutes to compile.

      Why is compilation so slow?

      C++ is actually very fast to compile, the slowdowns come mostly from the way the standard library is implemented. This is actually fairly easy to test yourself by running the following shell snippet.

      echo '#include<vector>' | g++ -x c++ -E - -std=c++23 | wc

      The -E flag tells the compiler to stop after preprocessing. The output is the source code that is fed to the compiler proper. Instead we pass it to wc and find out that merely including vector expands out to 29 000 lines of code. The number is not directly comparable to "human written code", but still, almost 30k lines of code just to get a growable array of elements seems a bit much. And vector is actually one of the lighter headers. Memory is 55 thousand lines (especially bad, since 99% of the time people just want unique_ptr), print is 65 thousand lines and filesystem is 80 thousand lines.

      The unfortunate reality is that if you include even a single standard library header, your compile times tank and there's nothing you can do about it.

      Just say no

      Pystd was originally just a project for me to implement low level primitives (hash maps etc) for scratch for the fun of it. Pretty quickly I came to the three design priorities:

      1. Compilation time
      2. Simplicity of implementation
      3. Performance

      I'm not aware of an existing standard library where build time minimization would have been a design priority. Those that are fast, like the standard libraries of C and Go, seem to mostly follow from the simplicity of their respective languages.

      At the time of writing building Pystd and all tests from scratch using a single core takes 4 seconds. This consists of 45 individual processes (mostly compiles, a few links). Enabling optimizations balloons the build time to 9 seconds. Using all 16 cores brings it down to 1.9 seconds.

      What we have thus far

      If we ignore test code, Pystd has 6500 lines of headers and 5600 lines of source in total. Even adding these two together yields a line count of roughly one third of std::vector's (preprocessed) implementation. Functionality provided by Pystd includes:

      • vector, string, validating u8string, string views, spans
      • Hash map, ordered map (using a B-tree)
      • sort (approximately as fast as stdlibc++), stable_sort (faster than stdlibc++)
      • Random selection of things in the ISO algorithm header
      • Optional, expected, variant, unique_ptr
      • Functionality roughly equivalent to Python modules argparse, pathlib (including the ** operator), regular expressions (using pcre) and tempfile

      Note that not all of these are "complete" as it were. Typically they only contain the most commonly used subset of functionality. That might be a fairly small.

      Performance

      There is an earlier blog post about the performance. The numbers for converting the CapyPDF library are as follows:

      • Compile times dropped ~80%
      • Unstripped binary size reduced by ~75%
      • Stripped binary size reduced by ~30%
      • Runtime performance became ~25% faster (yes, faster, not slower)

      Regression can be prevented

      Two typical issues people raise when hearing something needs to be "fast to compile" are the following:

      1. What even is "fast"? It is highly subjective thing that depends on each person and the computer they are using.
      2. Even if something is fast now, it can not remain fast. New functionality gets added all the time, so the code is destined to become ever slower and eventually it is just as slow as the default standard library.

      The boring solution to both of these issues is the same: a predefined time budget. Pystd has a requirement that compiling a source file that includes any single public header must take at most 0.15 seconds. This limit was originally 0.1 seconds and it worked perfectly with GCC, but Clang's process startup time is longer than that. The test script that validates the performance is here. It must pass even on a Raspberry Pi.

      Interestingly the tester script was not originally single-threaded. I parallelised it only because it was the single slowest part of Pystd's compile-test cycle taking over a second.

      This is the requirement that all new functionality in Pystd must meet. If the code you want to add compiles too slow then either you rewrite the whole package to compile faster or you submit a patch to the upstream compiler to make it run faster.

      Try it yourself

      The code for Pystd is available in the usual places. Beginners might want to try using the sample project instead.

      The code works on Linux and macOS. It does not support MSVC, because the implementation uses pack indexing, which MSVC has not implemented yet.

      Lennart Poettering

      @mezcalero

      Mastodon Stories for systemd v261

      On June 19 we released systemd v261 into the wild.

      In the weeks leading up to that release (and since then) I have posted a series of serieses of posts to Mastodon about key new features in this release, under the #systemd261 hash tag. In case you aren't using Mastodon, but would like to read up, here's a list of all 27 posts:

      I intend to do a similar series of serieses of posts for the next systemd release (v262), hence if you haven't left tech Twitter for Mastodon yet, now is the opportunity. My series for v262 will begin in a few weeks most likely, under the #systemd262 hash tag.

      In case you are interested, here is the corresponding blog story for systemd v260, here for v259, here for v258, here for v257, and here for v256.