For the past few years I have been managing GNOME’s participation in the Google Summer of Code and Outreachy internship programs. As a former alumni myself more than a decade ago, I believe these programs are a fundamental tool to onboard new contributors to our community and to provide opportunities for contributors to learn and join a thriving open source community. While I enjoy part of this management role, I am still a developer, and some of the internship activities are really energy/time consuming. So I have been looking for ways to improve that.
Now the Board has voted to approve the creation of the committee! This means that now the Board will always have a liason member dedicated to facilitate the communication between the Board and the internship administrators. This also means that now the Internship Committee has more formal responsibilities, such as the ones defined on the committee charter. The committee already has multiple community members and is working towards improving our processeses.
Another step I wanted to take was to produce a documentation for the internship administration processeses so that we eliminate the bus factor and have also a easy time onboarding new admins.
I just pushed the initial version of the Internship Admin guide, containing also my personal collection of templates for communication with interns, mentors, program organizations, etc… This allows for community members to improve the processes themselves all in once place. A lot of the templates I wrote need update and rewording (contributions are welcome).
Greetings! It’s been a long time since my last article.
I’d like to share some recent developments in GNOME Calendar that got some people really excited about: the infinitely scrolling month view.
Before GNOME 45, Calendar offers two views – week and month – as well as a sidebar with a list of events.
The headerbar offers controls to navigate back and forth in time. The effect of these controls depends on the current view: if you’re in the week view, going forward in time moves you a week ahead; in the month view, it moves you a month.
Both views have evolved to be strictly about their respective time ranges. That means the month view, for example, strictly deals with the current month. Days from other months that sneak into the view are not interactive, and it doesn’t show events on them. This has been a long-standing feature request in GNOME Calendar.
The week view doesn’t really suffer from the same problem, even though it has the same constraint, since weeks are not variable in length like months.
While this approach has served us well enough for more than a decade, it had significant usability issues. One of the primary goals of a calendaring application is to facilitate planning ahead. The static month view made harmed the usability of the application, in particular when in the last days of the month, since you could not see ahead without chaging the month entirely.
Another shortcoming of the static month view was scrolling. Because the view was bound to a particular month, there was no way to transition between months smoothly. I eventually added mouse & touchpad scroll support to it, but it has been a source of bugs and confusion since the view abruptly switches after an apparently random amount of scrolling.
Overall, despite the constant efforts to improve it, it felt like we were hitting the limitations of the current design. To the drawing board we needed to go.
New possibilities with GTK4?
GTK4 introduces a family of data-oriented widgets (GtkListView, GtkGridView, GtkColumnView) that are able to handle virtually endless datasets, we had a promising start with rethinking the month view. We could just stuff weeks into a GtkListView, or days into a GtkGridView, and be done with it, right?
Well, not quite.
There is a fundamental difference between datasets and timelines, which very directly informs the architecture of these GTK widgets: timelines are infinite, datasets are bounded.
No matter how many entries you add to a dataset, or how large you make that dataset, it will still have a countable number of items. Timelines are uncountably infinite, both towards the past and the future. ¹
This, by itself, directly affects the user interface we can present, and prevents us from using GtkListView, or pretty much anything that uses a GtkAdjustment as the underlying controller of position. I originally assumed that the number of workarounds to make a new month work with adjustment would be manageable, but after some weeks of experimentation, it became abundantly clear that this approach cannot work without either a massive number of hacks, and at the cost of maintainability and my own sanity.
Eventually I bowed to the fate, and wrote a completely custom layout for the new month.
Extending the month to infinity
As it happens so often in computing, we don’t necessarily have to implement material infinity to give people the impression of infinity.
The ultimate goal here is to make the month view smoothly scroll between weeks. In principle, the smallest way to create the illusion of infinity is to show current weeks, plus one or more offscreen rows above and below.
Due to the way calendars are stored by evolution-data-server, where data transfers happen over D-Bus, we have to be particularly careful to prefetch more events than visible onscreen, and keep them cached. Scrolling still changes the date range in which the month view operates – every time a week is moved up or down, we need to discard events of weeks that went out of range, and request events of week that are now within range.
All these range changes needs to be carefully managed so that we don’t blow evolution-data-server too much with range changes.
Fundamentally, the architecture of the new month view is based on a row recycling mechanism. Conceptually, the month view is just a list of rows, each row representing a week, laid out vertically given the available width. It’s as if the month view is a partial circular buffer of time. Moving the bottom row to the top, and vice versa, during scroll, allows the month view to keep a static number of row widgets allocated at all times,
After experimenting with different ranges and caching a bit, I’ve arrived at the wonderful number of 10 weeks of wiggle room – so in addition to the 5 visible week rows, there’s 10 weeks above them, and 10 weeks below them. This completely arbitrary value seems enough to cache just enough events for the transitions not to be noticeable.
The new month view can now anchor itself against any particular week, and is no more limited to a single month. On months that take precisely 5 rows, you’ll be able to see events from the previous and next month as well – something that’s been requested over and over for a long time now.
Most of the expected features – dragging events around, creating events, etc – continue to work exactly as they used to.
Touching the limits of infinity
Of course, being able to fetch, cache, layout, and render 25 weeks worth of events pushed Calendar’s backend to its limits. We had to make things fast, real fast, in order to keep up with e.g. scrolling at 60 FPS.
This was a good opportunity to revisit how the month view calculates the layout and overflow of each week. The layout algorithm had to be reworked almost from scratch, and I eventually figured out that it was still violating GTK4 layout rules during the layout phase – it was changing visibility of events during layout, which causes a relayout inside a relayout. These days, GTK4 has some tolerance for that, but after increasing the number of events by a factor of 5x, not even GTK4 could be so complacent with Calendar.
Now we pre-calculate the event layout while building up the list of events, and keep it cached in a size-agnostic way. During layout, it only resolves overflow, and it does so by carefully changing child visibility of the widgetry.
This not only enables the month view to actually render its contents, but we also don’t do any significant calculation at layout time, which makes Calendar smoother overall. Nice.
While developing this new month view, every single potential threading issue in Calendar showed up as a nasty crash as well. Most of them should be fixed now.
This, at last, allows us to have this nice, beautiful, smooth Calendar app:
A story of ups and downs
It is not a secret that calendars aren’t the most exciting applications humankind has ever conceived. In an era where we have to look at hands to detect whether a picture is generated by AI; an era where we watch the dusk of both the eleventh and the 45-billion-dollar Xs; an era where we Linux has become a mainstream gaming platform, and all the problems that come with that; who on actual Earth gives a damn about a niche-of-a-niche calendar app?!
During the development of GNOME 45, I finally could squeeze some dry drops of free time to dedicate some love to Calendar again. It took some serious effort to make the new month view a reality, but looking at it now, I think it was worth it.
After the original maintainer and the main designer left the project and the community, around 2016, it felt a tad bit lonely. Motivation to continue working on was eroding at a slow but constant pace. Calendar’s issue tracker was out of control. The IRC and Matrix channels were dead. Attempts to get some funding for Calendar development led nowhere – who would be willing to pay people to work on such an uninteresting, unmarketable component of the desktop?! – and of course, there was no reason for day job to give me work time to dedicate to Calendar. The project was, by all measurements, a dying project. This was not healthy.
But lurking in the darkest corners of Canada, silent, and always on the watch, a night elf with personal investment in the project noticed the situation. And acted. Over the last couple of months, Jeff single-handedly tamed the issue tracker again; triaged and labeled every single issue; closed almost 300 issues; made everything actionable again; helped building up a roadmap; and, the most important to me, offered a friendly hand and brought back the fun of developing an open source app.
It made me realize that, contrary to what I believed for too many years, and despite not being exactly what’s advertised as free software culture, it really is all about people. The whole thing. Just being there, talking and discussing and having fun and eventually doing some contribution – that’s the sweet spot of free software culture to me. The reason I’m still involved with other GNOME projects? The people. The reason Calendar didn’t just die? The people.
I’m pretty attached to Calendar as it was the first project I contributed with code on GNOME, and it makes me happy to see that the project is slowly getting back to track, and a community is gathering around once again.
Over the past few months, the Endless OS Foundation has been putting focus on improving GNOME Software’s reliability and performance. Endless OS is an OSTree-based immutable OS, and applications are entirely distributed as Flatpaks. GNOME Software is the frontend to that, and since our target userbase is definitely not going to use a terminal, we need to make sure GNOME Software delivers a good experience.
This focus has been materializing with Philip’s long effort to switch GNOME Software to a different threading model, more suitable to what Software does these days; and more recently, I’ve been tasked to look at GNOME Software’s performance from a profiling perspective.
Profile, Profile, Profile
I’ve been looking at performance-related tasks for many years now. It’s a topic of investigation that I personally enjoy, even if it’s a bit annoying and frustrating at times. My first real, big performance investigation was some good six years ago, on GNOME Music. Back then, the strategy to profiling was: guess what’s wrong, change that, see if it works. Not exactly a robust strategy. Luckily, it worked for that particular case.
Then over the next year I started to contribute to Mutter and GNOME Shell, and one of my first bigger performance-related investigations in this area involved frame timings, GJS, and some other complicated stuff. That one was a tad bit more complicated, and it still relied on gut feelings, but luckily some good improvements came out of that too.
Those two instances of gut-based profiling are successful when put like this, but that’s just a trick with words. Those two efforts were successful due to a mix of ungodly amounts of human effort, and luck. I say this because just a few months after, the GNOME Performance Hackfest took place in Cambridge, UK, and that was the beginning of a massive tsunami that took the GNOME community.
This tsunami is called profiling.
In that hackfest, Christian and Jonas started working on integrating Sysprof and Mutter / GNOME Shell. Sysprof was already able to collect function calls without any assistance, but this integration work enabled, for example, measuring where in the paint routines was GNOME Shell taking time to render. Of course, we could have printed timestamps in the console and parsed that, but let’s be honest, that sucks. Visualizing data makes the whole process so much easier.
That integration, alone, allowed us to abandon the Old Ways of profiling, and jump head first into a new era of data-based optimizations. Just looking at the data above, without even looking at function calls, we can extract a lot of information. We can see that the layout phase was taking 4ms, painting was taking 5ms, picking was taking ~2ms, and the whole process was taking ~12ms. Looking at this data in depth is what allowed, for example, reducingpick timesby 92%, and rendering times by a considerable factor too.
The most important lesson I could derive from that is: optimizing is borderline useless if not backed by profiling data. Always profile your app, and only optimize based on profiling data. Even when you think you know which specific part of your system is problematic, profile that first, just to confirm.
With these lessons learned, of course, I used this approach to profile GNOME Software.
Profiling an App Store
Naturally, the problem domain that GNOME Software – an app store – operates into is vastly different from that of GNOME Shell – a compositor. GNOME Software is also in the middle of a major transition to a new threading model, and that adds to the challenge of profiling and optimizing it. How do you optimize something that’s about to receive profound changes?
This proved to be a successful strategy. Here’s what profiling GNOME Software gave us:
Zoom in in the image. Take a few seconds to analyse it. Can you spot where the issue is?
If not, let’s do this together.
This slice of profiling shows that the GsPluginJobListApps operation (first line) took 4 whole seconds to execute. That’s a long time! This operation is executed to list the apps of a particular category. This means people have to wait 4 entire seconds, just to see the apps of a category. Certainly a usability killer, exploring these apps is supposed to be fun and quick, and this issue hurts that.
You may notice that there are other sub-events beneath GsPluginJobListApps. The first line is the timing of the whole operation, and beneath that, we have the timings of each individual sub-operation it does to end up with a list of apps.
Skimming through the entire profiler window, the widest black bars beneath the first line are, in order of appearance:
GsPluginJobListApps:flatpak taking 600ms
GsPluginJobRefine taking 3.6 seconds
GsPluginJobRefine:flatpak taking 600ms
GsPluginJobRefine:icons taking about 3 seconds
What that tells us is that the GsPluginJobListApps operation runs a GsPluginJobRefine sub-operation, and the icons are what’s taking most of the time there. Icons!
Refining is GNOME Software terminology for gathering metadata about a certain app, such as the name of the author, origin of the application, description, screenshots, icons, etc.
Contrary to all my expectations, what was clear in these profiling sessions is that loading icons was the worst offender to GNOME Software’s performance when navigating through categories. This required further investigation, since there’s a fair bit of code to make icon management fast and tight on memory.
It didn’t take long to figure out what was happening.
Some applications declare remote icons in their metadata, and GNOME Software needs to download these icons. Turns out, in Flathub, there are a couple of apps that declare such remote icons, but the icons don’t actually exist in the URL they point to! Uh oh. Obviously these apps need to fix their metadata, but we can’t let that make GNOME Software slow to a crawl.
Knowing exactly what was the problem, it wasn’t difficult to come up with potential solutions. We always have to download and cache app icons, but we can’t let that block loading categories, so the simplest solution is to queue all these downloads and continue loading the categories. The difference is quite noticeable when comparing with the current state:
Most of the time, GNOME Software already has access to a local icon, or a previously downloaded and cached icon, so in practice it’s hard to see them downloading.
I hope to have convinced you, the reader, that profiling your application is an important step when working on optimization. This article is focused on the timing marks, since they’re the easiest to understand on a quick glance, but these marks have little meaning when not accompanied with the function calls stack. There’s a lot to unpack on the subject, and sometimes this feels more like an art than simply a mechanical evaluation of numbers, but it sure it a fun activity.
Sadly, until very recently, even profiling was still a major pain – although much less painful than guess-based profiling – since you’d need to build at least your app and some of its dependencies with debug symbols to get a meaningful call stack. Most of the profiling I’ve mentioned above required building all dependencies up to GLib with debug symbols.
However, seems like a game changing decision has been made by the Fedora community to finally enable frame pointers on their packages by default. And that means that the setup overhead to perform profiling like the above is brutally reduced, it’s almost trivial even, and I’m hopeful with the prospects of democratizing profiling like this. At the very least, I can say that this is a massive improvement to desktop developers.
Não sei se você está sabendo, mas a versão nova do Evince (3.30) está com um atalho bastante útil.
Agora você pode destacar uma parte do texto selecionando-a com o mouse e pressionando as teclas:
CTRL + H
Este post poderia parar por aqui, mas eu gostaria de escrever mais um pouco acerca do que está por trás de um simples atalho.
O Evince e Eu
O Evince é um visualizador de documentos do GNOME. De acordo com a Wikipedia ele foi incluído no GNOME em sua versão 2.12.
No meu dia a dia, de grande consumo de informações através de arquivos PDF, um bom leitor é fundamental. O Evince sempre supriu bem este papel, porém havia um ponto que me incomodava: a falta de um atalho para destacar as partes relevantes do texto.
Para fazer isso eu tinha que utilizar o mouse, movimentando o cursor do texto até o botão de destaque, ou fazendo o contrário.
Em conversas informais no canal do IRC do GNOME Brasil1, comentei que sentia falta deste recurso. Na época usava o Evince 3.28.
Durante a conversa, o amigo Felipe Borges feborges pediu um tempinho e, em poucos minutos, disse que tinha implementado tal recurso e que ele viria, possivelmente, na próxima versão do Evince.
Lembro que fiquei num misto de alegria e de espanto pela rapidez do processo e também pela consideração de feborges.
Bem, estou usando a versão 3.30 do Evince e estou usando bastante o recurso. Recomendo
Queria concluir este post agradecendo ao Felipe pelo recurso, mas também deixando uma reflexão sobre como o software livre e open source é produzido e melhorado.
Acompanho, em muitos espaços, usuários reclamando da falta do recurso X ou do bug Y, porém pouca gente abre alguma issue para relatar algum bug ou propor alguma melhoria.
Diversas vezes esse modelo de desenvolvimento de software é enquadrado em uma lógica diferente e sofre análises, muito deslocadas a meu ver, como se fosse um modelo proprietário. Mas isso é um papo para um outro post.
Não, eu não estou com a paciência esgotada! Hoje estou comemorando que um antigo erro na verificação ortográfica do gedit foi corrigido, de forma que palavras hifenizadas (“corrigi-la-ia”) ou contendo apóstrofo (“d’água”) poderão ser verificadas por inteiro pelo verificador ortográfico.
É uma pena que eu não tenha conseguido o subdomínio leonardof.wordpress.com. Tenho muito carinho por “leonardof” desde que esse se tormou o nome da minha conta no SVN (hoje Git) do GNOME. Só que eu preciso dedicar menos tempo em manutenção de webapps, domínios etc, para ter mais tempo para as atribuições profissionais e pessoais.
Espero ter uma novidade em breve para contar a vocês, então não sumam!
Planeta GNOME Brasil é uma janela para o mundo, o trabalho e as vidas dos membros da comunidade GNOME Brasil.
O design deste site é baseado no modelo dos sites do GNOME e Planet GNOME.
Planeta GNOME Brasil automaticamente republica artigos de blogs da comunidade GNOME Brasil. Os artigos nessa página são de responsabilidade de seus respectivos autores. Nós não editamos ou endossamos o conteúdo de cada artigo.
Atualizado em UTC. Os horários das publicações estão convertidos para UTC.
GNOME pelo mundo
Comunidades GNOME ao redor do mundo por região e idioma: