01 May 2024

feedPlanet GNOME

Sonny Piers: Workbench 46.1

International Workers' Day marks the release of Workbench 46.1

Download on Flathub

This new release comes with

Save/restore window state and dimensions for each session/project. I couldn't use the method defined in Saving and restoring state into GSettings because resizing manually with the mouse triggers a lot of blocking disk writes and cause the user action to appear sluggish. So I debounce the events and write to gsettings manually.

Find text in the current editor. The keyboard shortcut is Ctrl+F. This is a feature started by Sriyansh Shivam during their GSoC 2023 internship and finished by UrtsiSantsi. Thanks!

SVG Library entry. Gtk (via gdk-pixbuf) draws SVGs at their intrisic sizes (what is defined in the svg document). If you use different dimensions for example using GtkImage.pixel-size then it is the pixmap that gets upscaled resulting in pixelated / blurry images. This new Library entry showcases how to render an SVG at arbitrary dimensions using librsvg. We may need a better primitive in the future, if you need an SVG Paintable; GTK Demo contains an example. See also this conversation.

A screenshot of the

Reveal In Files. This is a new option available in the menu that will reveal the session/project in Files. You can use it to add assets to your project and load them using workbench.resolve or as icons.

Import icons into your projects. Using the "Reveal In Files" option you can now add custom icons to your projects. It's just a matter of dropping the files in the right folder. See the "Using Icons" Library entry.

A screenshot of the

Workbench included an Icon Library and icon-development-kit for a while but in an effort to simplify Workbench and since we already have an Icon Library app, I decided to remove both in favor of per project icons.

I'm quite happy with the developer experience there and I hope we can provide something similar in the future to move beyond GtkIconTheme. We probably need to keep icon-name as suggested in Updates from inside GTK but I'd be very interested supporting relative paths in GTK Builder. Thankefully we already have GResource to allow for something like

Gtk.Image {
  src: "./smile-symbolic.svg";
}

7 new Library entries ported to Vala

Also

Thank you contributors and GSoC applicants.

01 May 2024 7:51am GMT

30 Apr 2024

feedPlanet GNOME

GNOME Foundation News: Call for GNOME Asia 2024 Location Proposals

The GNOME Foundation invites bids for hosting GNOME Asia 2024. This is your chance to bring GNOME Asia to your city!

If you are interested in submitting a proposal to host GNOME Asia in your city, please submit an intent to bid by filling out this short form. Intent to Bid submissions are due by end-of-day May 15, 2024.

Final proposals should be submitted using our online form and are due by June 6, 2024.

Be prepared to include the following details in your proposal:

Deadlines
Intention to bid: May 15, 2024
Final proposal submission: June 6, 2024

Proposals from previous years are available for reference and you can talk to the Foundation Board and previous GNOME Asia organizers to find out more about what is involved. If you need more time to finalize your bid please contact kprogri@gnome.org.

Organizing GUADEC is a large undertaking but local teams will have help from Foundation Staff members and Engagement Team contributors!

If you have any questions, don't hesitate to contact Kristi at kprogri@gnome.org or the GNOME Asia team at asia@gnome.org.

Submit an Intent to Bid
Submit a Proposal

30 Apr 2024 5:51pm GMT

29 Apr 2024

feedPlanet GNOME

Hans de Goede: Moving GPU drivers out of the initramfs

The firmware which drm/kms drivers need is becoming bigger and bigger and there is a push to move to generating a generic initramfs on distro's builders and signing the initramfs with the distro's keys for security reasons. When targetting desktops/laptops (as opposed to VMs) this means including firmware for all possible GPUs which leads to a very big initramfs.

This has made me think about dropping the GPU drivers from the initramfs and instead make plymouth work well/better with simpledrm (on top of efifb). A while ago I discussed making this change for Fedora with the Red Hat graphics team spoiler: For now nothing is going to change.

Let me repeat that: For now there are no plans to implement this idea so if you believe you would be impacted by such a change: Nothing is going to change.

Still this is something worthwhile to explore further.

Advantages:

1. Smaller initramfs size:

* E.g. a host specific initramfs with amdgpu goes down from 40MB to 20MB
* No longer need to worry about Nvidia GSP firmware size in initrd
* This should also significantly shrink the initrd used in liveimages

2. Faster boot times:

* Loading + unpacking the initrd can take a surprising amount of time. E.g. on my old AMD64 embedded PC (with BobCat cores) the reduction of 40MB -> 20MB in initrd size shaves approx. 3 seconds of initrd load time + 0.6s seconds from the time it takes to unpack the initrd
* Probing drm connectors can be slow and plymouth blocks the initrd -> rootfs transition while it is busy probing

3. Earlier showing of splash. By using simpledrm for the splash the splash can be shown earlier, avoiding the impression the machine is hanging during boot. An extreme example of this is my old AMD64 embedded PC, where the time to show the first frame of the splash goes down from 47 to 9 seconds.

4. One less thing to worry about when trying to create a uniform desktop pre-generated and signed initramfs (these would still need support for nvme + ahci and commonly used rootfs + lvm + luks).

Disadvantages:

Doing this will lead to user visible changes in the boot process:

1. Secondary monitors not lit up by the efifb will stay black during full-disk encryption password entry, since the GPU drivers will now only load after switching to the encrypted root. This includes any monitors connected to the non boot GPU in dual GPU setups.

Generally speaking this is not really an issue, the secondary monitors will light up pretty quickly after the switch to the real rootfs. However when booting a docked laptop, with the lid closed and the only visible monitor(s) are connected to the non boot GPU, then the full-disk encryption password dialog will simply not be visible at all.

This is the main deal-breaker for not implementing this change.

Note because of the strict version lock between kernel driver and userspace with nvidia binary drivers, the nvidia binary drivers are usually already not part of the initramfs, so this problem already exists and moving the GPU drivers out of the initramfs does not really make this worse.


2. With simpledrm plymouth does not get the physical size of the monitor, so plymouth will need to switch to using heuristics on the resolution instead of DPI info to decide whether or not to use hidpi (e.g. 2x size) rendering and even when switching to the real GPU driver plymouth needs to stay with its initial heuristics based decision to avoid the scaling changing when switching to the real driver which would lead to a big visual glitch / change halfway through the boot.

This may result in a different scaling factor for some setups, but I do not expect this really to be an issue.

3. On some (older) systems the efifb will not come up in native mode, but rather in 800x600 or 1024x768.

This will lead to a pretty significant discontinuity in the boot experience when switching from say 800x600 to 1920x1080 while plymouth was already showing the spinner at 800x600.

One possible workaround here is to add: 'video=efifb:auto' to the kernel commandline which will make the efistub switch to the highest available resolution before starting the kernel. But it seems that the native modes are simply not there on systems which come up at 800x600 / 1024x768 so this does not really help.

This does not actually break anything but it does look a bit ugly. So we will just need to document this as an unfortunate side-effect of the change and then we (and our users) will have to live with this (on affected hardware).

4. On systems where a full modeset is done the monitor going briefly black from the modeset will move from being just before plymouth starts to the switch from simpledrm drm to the real driver. So that is slightly worse. IMHO the answer here is to try and get fast modesets working on more systems.

5. On systems where the efifb comes up in the panel's native mode and a fast modeset can be done, the spinner will freeze for a (noticeable) fraction of a second as the switch to the real driver happens.

Preview:

To get an impression what this will look / feel like on your own systems, you can implement this right now on Fedora 40 with some manual configuration changes:

1. Create /etc/dracut.conf.d/omit-gpu-drivers.conf with:

omit_drivers+=" amdgpu radeon nouveau i915 "

And then run "sudo dracut -f" to regenerate your current initrd.

2. Add to kernel commandline: "plymouth.use-simpledrm"

3. Edit /etc/selinux/config, set SELINUX=permissive this is necessary because ATM plymouth has issues with accessing drm devices after the chroot from the initrd to the rootfs.

Note this all assumes EFI booting with efifb used to show the plymouth boot splash. For classic BIOS booting it is probably best to stick with having the GPU drivers inside the initramfs.

comment count unavailable comments

29 Apr 2024 1:13pm GMT

26 Apr 2024

feedPlanet GNOME

Robert McQueen: Update from the GNOME board

It's been around 6 months since the GNOME Foundation was joined by our new Executive Director, Holly Million, and the board and I wanted to update members on the Foundation's current status and some exciting upcoming changes.

Finances

As you may be aware, the GNOME Foundation has operated at a deficit (nonprofit speak for a loss - ie spending more than we've been raising each year) for over three years, essentially running the Foundation on reserves from some substantial donations received 4-5 years ago. The Foundation has a reserves policy which specifies a minimum amount of money we have to keep in our accounts. This is so that if there is a significant interruption to our usual income, we can preserve our core operations while we work on new funding sources. We've now "hit the buffers" of this reserves policy, meaning the Board can't approve any more deficit budgets - to keep spending at the same level we must increase our income.

One of the board's top priorities in hiring Holly was therefore her experience in communications and fundraising, and building broader and more diverse support for our mission and work. Her goals since joining - as well as building her familiarity with the community and project - have been to set up better financial controls and reporting, develop a strategic plan, and start fundraising. You may have noticed the Foundation being more cautious with spending this year, because Holly prepared a break-even budget for the Board to approve in October, so that we can steady the ship while we prepare and launch our new fundraising initiatives.

Strategy & Fundraising

The biggest prerequisite for fundraising is a clear strategy - we need to explain what we're doing and why it's important, and use that to convince people to support our plans. I'm very pleased to report that Holly has been working hard on this and meeting with many stakeholders across the community, and has prepared a detailed and insightful five year strategic plan. The plan defines the areas where the Foundation will prioritise, develop and fund initiatives to support and grow the GNOME project and community. The board has approved a draft version of this plan, and over the coming weeks Holly and the Foundation team will be sharing this plan and running a consultation process to gather feedback input from GNOME foundation and community members.

In parallel, Holly has been working on a fundraising plan to stabilise the Foundation, growing our revenue and ability to deliver on these plans. We will be launching a variety of fundraising activities over the coming months, including a development fund for people to directly support GNOME development, working with professional grant writers and managers to apply for government and private foundation funding opportunities, and building better communications to explain the importance of our work to corporate and individual donors.

Board Development

Another observation that Holly had since joining was that we had, by general nonprofit standards, a very small board of just 7 directors. While we do have some committees which have (very much appreciated!) volunteers from outside the board, our officers are usually appointed from within the board, and many board members end up serving on multiple committees and wearing several hats. It also means the number of perspectives on the board is limited and less representative of the diverse contributors and users that make up the GNOME community.

Holly has been working with the board and the governance committee to reduce how much we ask from individual board members, and improve representation from the community within the Foundation's governance. Firstly, the board has decided to increase its size from 7 to 9 members, effective from the upcoming elections this May & June, allowing more voices to be heard within the board discussions. After that, we're going to be working on opening up the board to more participants, creating non-voting officer seats to represent certain regions or interests from across the community, and take part in committees and board meetings. These new non-voting roles are likely to be appointed with some kind of application process, and we'll share details about these roles and how to be considered for them as we refine our plans over the coming year.

Elections

We're really excited to develop and share these plans and increase the ways that people can get involved in shaping the Foundation's strategy and how we raise and spend money to support and grow the GNOME community. This brings me to my final point, which is that we're in the run up to the annual board elections which take place in the run up to GUADEC. Because of the expansion of the board, and four directors coming to the end of their terms, we'll be electing 6 seats this election. It's really important to Holly and the board that we use this opportunity to bring some new voices to the table, leading by example in growing and better representing our community.

Allan wrote in the past about what the board does and what's expected from directors. As you can see we're working hard on reducing what we ask from each individual board member by increasing the number of directors, and bringing additional members in to committees and non-voting roles. If you're interested in seeing more diverse backgrounds and perspectives represented on the board, I would strongly encourage you consider standing for election and reach out to a board member to discuss their experience.

Thanks for reading! Until next time.

Best Wishes,
Rob
President, GNOME Foundation

Update 2024-04-27: It was suggested in the Discourse thread that I clarify the interaction between the break-even budget and the 1M EUR committed by the STF project. This money is received in the form of a contract for services rather than a grant to the Foundation, and must be spent on the development areas agreed during the planning and application process. It's included within this year's budget (October 23 - September 24) and is all expected to be spent during this fiscal year, so it doesn't have an impact on the Foundation's reserves position. The Foundation retains a small % fee to support its costs in connection with the project, including the new requirement to have our accounts externally audited at the end of the financial year. We are putting this money towards recruitment of an administrative assistant to improve financial and other operational support for the Foundation and community, including the STF project and future development initiatives.

(also posted to GNOME Discourse, please head there if you have any questions or comments)

26 Apr 2024 10:39am GMT

Felix Häcker: #145 Quality Over Quantity

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

GNOME Core Apps and Libraries

GTK

Cross-platform widget toolkit for creating graphical user interfaces.

Matthias Clasen says

GTK 4.15.0 is out.

This release changes the default GSK renderer to be Vulkan, on Wayland. Other platforms still use ngl.

The intent of this change is to get wider testing and verify that Vulkan drivers are good enough for us to rely on. If significant problems show up, we will revert this change for 4.16.

You can still override the renderer choice using the GSK_RENDERER environment variable.

This release also changes font rendering settings by introducing a new high-level gtk-font-rendering settings which gives GTK more freedom to decide on font rendering.

You can still use the low-level font-related settings by changing the new property to 'manual'.

If you are building GTK for a distribution, notice that some deprecated build options have been removed.

GNOME Circle Apps and Libraries

FineFindus reports

I've released a new version of Hieroglyphic. This version features a new app icon by Tobias Bernard, refines the UI and improves the symbol recognition speed. You can download it from Flathub.

Graphs

Plot and manipulate data

Sjoerd Stendahl reports

This week we released version 1.8 of Graphs. This release mostly focuses on background changes to the code, but there's still a number of nice quality of life changes that are interesting to highlight:

  • Graphs now has full support for touchscreen devices
  • Equation handling has been improved. Now it is no longer needed to add a * symbol between every single parameter upon multiplication, instead an equation such as y = 4sin(2x + pi) is handled without any issues.
  • Support has been added for additional trigonometric functions and their inverses, such as sinh and cosh. Now the vast majority of trig functions should work without any issues.
  • Help has been ported to Yelp, and can now be accesed directly from the app. This documentation is still a work in progress and will be expanded upon throughout this release cycle.
  • There is now a warning when editing a style with poor contrast between the labels and background colours.
  • Numerical entries throughout the application now indicate whenever an invalid input is given.
  • Multiple bug fixes were implemented, especially with regard to the equation handling in the curve fitting dialog.
  • Many different improvements have been added to the translation process such as more translatable strings, and added context to strings. Thanks for the feedback from the translation team :)

As always, the latest release can be found on Flathub. For any feedback, suggestions or bug reports, please file an issue at the GitLab issue tracker.

GNOME Foundation

ramcq announces

The board of the GNOME Foundation is pleased to share an update about finances, strategy, fundraising, and our exciting plans to bring more diverse and inclusive representation into how the Foundation is governed and can best support and promote the GNOME community. We're adding two seats to the board from the upcoming election which starts next month, and are interested to speak with prospective candidates about what's involved and how they can help.

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!

26 Apr 2024 12:00am GMT

25 Apr 2024

feedPlanet GNOME

Ismael Olea: Small GLAM Slam Pilot 1 project update

Wikibase logotype

This is a project update for the SGS Pilot 1 project. This is a WMF funded project (ID: 22444585).

They have been created two relevant places:

You can observe que are now using the coined term «Very Small GLAM». This will be the activity scope from now as we consider it short and and precise. The Small GLAM Slam denomination will be kept for the ID: 22444585 project.

What the Very Small GLAM term refers to? It identifies GLAM entities of very small size. How small? We got the inspiration from the concept of VSE (very small entities) coined for the ISO/IEC 29110 Series for software development entities up to 25 members. To set a focus we, a bit arbitrarily, chose the number 5 as «up to 5» members an institution or team working in GLAM. Very Small GLAM non circunscribes to Open GLAM, but Open GLAM would probably be the best approach or complement for this teams with not so much resources.

Wikimedia LEADS logotype

Wikimedia LEADS spin-off

An unexpected spin-off has been the conceptualization of the new initiative, Wikimedia LEADS (Learning Ecosystems and Ameliorating Data Space) when attending EU's Next Generation Internet (NGI) funding call. The goal is to develop an advanced learning free/open data space and software ecosystem for the Wikimedia Movement.

Wikimedia LEADS first goal is to attend the GLAM Wiki learning needs. GLAM Wiki also shares a lot of commonalities with the Europeana community.

By extension, all practices, tools and many of the specific contents will be applicable to all other areas of the human knowledge.

Project's activity areas

The SGS Pilot 1 is now structured in these work-packages:

WP1-IT system, update

The selected operating system is UNRAID. The technical justifications are:

At this point the most important update about UNRAID is, since the grant approval, it changed their licensing model and fees.

Current project hardware details are:

In the next days we'll buy the three HGST hard drives and other minor components for the firsts tests.

For the system configuration development phase, we'll use another lend computer as a test server.

Software systems

This is a proposal of software architecture for a local installation of Wikibase in a GLAM context:

There is not advances to report about software.

WP2-Wikibase suite configuration, update

As we are not still familiar with the Wikibase ecosystem we are practicing setting up some instances in Wikibase.cloud. Also, we are starting to identify relevant Wikibase features. We are using wikibase.world as inventory of:

WP3-GLAM ontologies and vocabularies, update

Here we have the most juicy results for the moment. After a papers research we identified the CIDOC Conceptual Reference Model (CIDOC-CRM) as an international reference model for museums. It's more relevant when you find it's being used as a reference for mapping or extending to other domains like CRMdig (digitalization) and CRMsoc (social phenomena and constructs), which are relevant for the «Memorias del Cine» archive. Very relevant is the availability of a CRM OWL ontology (non official, but apparently up to date) and some minor Wikidata mapping (https://w.wiki/9r$s, 24 items) Also, we identified the Records in Contexts-Conceptual Model (RiC-CM), whose ontology is also published in OWL format. RiC-CM is a reference for archival and we found initial works for CRM <-> RiC-CM mapping. The current mapping with Wikidata is anecdotal (https://w.wiki/9sAh, 4 items).

In the context of models of practices we are learning about SEMAT Essence. The formal specifications are expressed in text and in a UML metamodel file (.xmi). The concept of metamodel is practically equivalent to the LOD ontology. It took a while but now we know more about how to manage this XMI formats using Magic Draw. The plan is to import the ontology to Wikibase using the same tools than for CRM and related. We found the Essence «Package Competency» model is relevant for populating a map of competences/abilities for the Movement, as Wikimedia LEADS proposes.

For managing this information we are getting familiar with tools like Protégé, Fuseki, Magic Draw and some others.

A very happily discovery has been a couple set of tools for mapping and importing to Wikibase ontologies based in CIDOC-CRM. They are output of the projects SAF-Lux and GeoKB. We expect we'll make intensive use of them or their derivatives.

An open question is, do we need to create a new Wikidata property for CRM identifier? Probably yes. I'm keeping some notes about ontologies for archival in my Wikidata user page.

WP4-GLAM practices, update

There is not so much real work on this side, since we are not ready to work modeling with Essence. But we are collecting some relevant bibliography for the project scope:

WP5-data import, update

There have been not activity. We'll start the data import when we have a first server operating.

Dissemination

Strictly focused in the SGS Pilot 1:

Related to Wikimedia LEADS:

What's next

In the next days we'll procure the pending hardware component to set up the server prototype. Then we'll define the configuration and procedure to set up an UNRAID server instance ready for data preservation tasks. Then we'll migrate the multimedia archive of «Memorias del Cine» to the server. The fun part of cataloging the archive in Wikibase would start as soon as we have an stable ontology model for digital archives.

Also, in May I'll be attending the Wikimedia Hackathon in Tallinn and the AI Sauna in Helskinki. Reach me there in person if you are interested in our work.

PS: Adding references to WP5 (20240430).

25 Apr 2024 10:00pm GMT

24 Apr 2024

feedPlanet GNOME

Christian Hergert: Collaborating on Builder

It's no secret I have way more projects to manage than hours in the day.

I hope to rectify this by sharing more knowledge on how my projects are built. The most important project, Builder, is quite a large code-base. It is undoubtedly daunting to dive in and figure out where to start.

A preview of a few pages of the book including the cover, and two pages from the table of contents.

Here is a sort of engineers journal (PDF) in book form about how the components fit together. The writing tries to be brief and to the point. You can always reference the source code for finer points.

There is so much more that can happen with Builder if we have regular contributors and subsystem maintainers.

We still need to bring back a new designer. We still need real strong git commit integration. We still need a physical device simulator to go with our architecture emulator. Our debugger API could use data visualizers and support for the debug-adapter-protocol. Container integration has a long tail of desired features.

You get the idea.

Lots of exciting features will happen once people dive into the code-base to learn more. Hopefully this book helps you along that journey.

24 Apr 2024 10:14pm GMT

Miguel de Icaza: 23 Apr 2024

Embeddable Game Engine

Many years ago, when working at Xamarin, where we were building cross-platform libraries for mobile developers, we wanted to offer both 2D and 3D gaming capabilities for our users in the form of adding 2D or 3D content to their mobile applications.

For 2D, we contributed and developed assorted Cocos2D-inspired libraries.

For 3D, the situation was more complex. We funded a few over the years, and we contributed to others over the years, but nothing panned out (the history of this is worth a dedicated post).

Around 2013, we looked around, and there were two contenders at the time, one was an embeddable engine with many cute features but not great UI support called Urho, and the other one was a Godot, which had a great IDE, but did not support being embedded.

I reached out to Juan at the time to discuss whether Godot could be turned into such engine. While I tend to take copious notes of all my meetings, those notes sadly were gone as part of the Microsoft acquisition, but from what I can remember Juan told me, "Godot is not what you are looking for" in two dimensions, there were no immediate plans to turn it into an embeddable library, and it was not as advanced as Urho, so he recommended that I go with Urho.

We invested heavily in binding Urho and created UrhoSharp that would go into becoming a great 3D library for our C# users and worked not only on every desktop and mobile platform, but we did a ton of work to make it great for AR and VR headsets. Sadly, Microsoft's management left UrhoSharp to die.

Then, the maintainer of Urho stepped down, and Godot became one of the most popular open-source projects in the world.

Last year, @Faolan-Rad contributed a patch to Godot to turn it into a library that could be embedded into applications. I used this library to build SwiftGodotKit and have been very happy with it ever since - allowing people to embed Godot content into their application.

However, the patch had severe limitations; it could only ever run one Godot game as an embedded system and could not do much more. The folks at Smirk Software wanted to take this further. They wanted to host independent Godot scenes in their app and have more control over those so they could sprinkle Godot content at their heart's content on their mobile app (demo)

They funded some initial work to do this and hired Gergely Kis's company to do this work.

Gergely demoed this work at GodotCon last year. I came back very excited from GodotCon and I decided to turn my prototype Godot on iPad into a complete product.

One of the features that I needed was the ability to embed chunks of Godot in discrete components in my iPad UI, so we worked with Gergely to productize and polish this patch for general consumption.

Now, there is a complete patch under review to allow people to embed arbitrary Godot scenes into their apps. For SwiftUI users, this means that you can embed a Godot scene into a View and display and control it at will.

Hopefully, the team will accept this change into Godot, and once this is done, I will update SwiftGodotKit to get these new capabilities to Swift users (bindings for other platforms and languages are left as an exercise to the reader).

It only took a decade after talking to Juan, but I am back firmly in Godot land.

24 Apr 2024 1:41am GMT

23 Apr 2024

feedPlanet GNOME

Development blog for GNOME Shell and Mutter: Notifications in 46 and beyond

One of the things we're tackling as part of the STF infrastructure initiative is improving notifications. Other platforms have advanced significantly in this area over the past decade, while we still have more or less the same notifications we had since the early GNOME 3 days, both in terms of API and feature set. There's plenty to do here 🙂

The notification drawer on GNOME 45

Modern needs

As part of the effort to port GNOME Shell to mobile Jonas looked into the delta between what we currently support and what we'd need for a more modern notification experience. Some of these limitations are specific to GNOME's implementation, while others are relevant to all desktops.

Tie notifications to apps

As of GNOME 45 there's no clear identification on notification bubbles which app they were sent by. Sometimes it's hard to tell where a notification is coming from, which can be annoying when managing notifications in Settings. This also has potential security implications, since the lack of identification makes it trivial to impersonate other apps.

We want all notifications to be clearly identified as coming from a specific app.

Global notification sounds

GNOME Shell can't play notification sounds in all cases, depending on the API the app is using (see below). Apps not primarily targeting GNOME Shell directly tend to play sounds themselves because they can't rely on the system always doing it (it's an optional feature of the XDG Notification API which different desktops handle differently). This works, but it's messy for app developers because it's hard to test and they have to implement a fallback sound played by the app. From a user perspective it's annoying that you can't always tell where sounds are coming from because they're not necessarily tied to a notification bubble. There's also no central place to manage the notification behavior and it doesn't respect Do Not Disturb.

Notification grouping

Currently all notifications are just added to a single chronological list, which gets messy very quickly. In order to limit the length of the list we only keep the latest 3 notifications for every app, so notifications can disappear before you have a chance to act on them.

Other platforms solve this by grouping notifications by app, or even by message thread, but we don't have anything like this at the moment.

Notifications grouped by app on the iOS lock screen

Expand media support

Currently each notification bubble can only contain one (small) image. It's mostly used for user avatars (for messages, emails, and the like), but sometimes also for actual content (e.g. a thumbnail for the image someone sent).

Ideally what we want is to be able to show larger images in addition to avatars, as the actual content of the notification.

As of GNOME 45 we only have a single slot for images on notifications, and it's too small for actual content.
Other platforms have multiple slots (app icon, user avatar, and content image), and media can be expanded to much larger sizes.

There's also currently no way to include descriptive text for images in notifications, so they are inaccessible to screen readers. This isn't as big a deal with the current icons since they're small and mostly used for ornamental purposes, but will be important when we add larger images in the body.

Updating notification content

It's not possible for apps to update the content inside notifications they sent earlier. This is needed to show progress bars in notifications, or updating the text if a chat message was modified.

How do we get there?

Unfortunately, it turns out that improving notifications is not just a matter of standardizing a few new features and implementing them in GNOME Shell. The way notifications work today has grown organically over the years and the status quo is messy. There are three different APIs used by apps today: XDG Notification, Gio.Notification, and XDG Portal.

How different notification APIs are used today

XDG Notification

This is the Freedesktop specification for a DBus interface for apps to send notifications to the system. It's the oldest notification API still in use. Other desktops mostly use this API, e.g. KDE's KNotification implements this spec.

Somewhat confusingly, this standard has never actually been finalized and is still marked as a draft today, despite not having seen significant changes in the past decade.

Gio.Notification

This is an API in GLib/Gio to send notifications, so it's only used by GTK apps. It abstracts over different OS notification APIs, primarily the XDG one mentioned above, a private GNOME Shell API, the portal API, and Cocoa (macOS).

The primary one being used is the private DBus interface with GNOME Shell. This API was introduced in the early GNOME 3 days because the XDG standard API was deemed too complicated and was missing some features (in particular notifications were not tied to a specific app).

When using Gio.Notification apps can't know which backend is used, and how a notification will be displayed or behave. For example, notifications can only persist after the app is closed if the private GNOME Shell API is used. These differences are specific to GNOME Shell, since the private API is only implemented there.

XDG Portal

XDG portals are secure, standardized system APIs for the Linux desktop. They were introduced as part of the push for app sandboxing around Flatpak, but can (and should) be used by non-sandboxed apps as well.

The XDG notification portal was inspired by the private GNOME Shell API, with some additional features from the XDG API mixed in.

XDG portals consist of a frontend and a backend. In the case of the notification portal, apps talk to the frontend using the portal API, while the backend talks to the system notification API. Backends are specific to the desktop environment, e.g. GNOME or KDE. On GNOME, the backend uses the private GNOME Shell API when possible.

The plan

From the GNOME Shell side we have the XDG API (used by non-GNOME apps), and the private API (used via Gio.Notification by GNOME apps). From the app side we additionally have the XDG portal API. Neither of these can easily supersede the others, because they all have different feature sets and are widely used. This makes improving our notifications tricky, because it's not obvious which of the APIs we should extend.

After several discussions over the past few months we now have consensus that it makes the most sense to invest in the XDG portal API. Portals are the future of system APIs on the free desktop, and enable app sandboxing. Neither of the other APIs can fill this role.

Our plan for notification APIs going forward: Focus on the portal API

This requires work in a number of different modules, including the XDG portal spec, the XDG portal backend for GNOME, GNOME Shell, and client libraries such as Gio.Notification (in GLib), libportal, libnotify, and ashpd.

In the XDG portal spec, we are adding support for a number of missing features:

  • Tying notifications to apps
  • Grouping by message thread
  • Larger images in the notification body
  • Special notifications for e.g. calls and alarms
  • Clearing up some instances of undefined behavior (e.g. markup in the body, playing sounds, whether to show notifications on the lock screen, etc.)

This is the draft XDG desktop portal proposal for the spec changes.

On the GNOME Shell side, these are the primary things we're doing (some already done in 46):

  • Cleanups and refactoring to make the code easier to work on
  • Improve keyboard navigation and screen reader accessibility
  • Header with app name and icon
  • Show full notification body and buttons in the drawer
  • Larger notification icons (e.g. user avatars on chat notifications)
  • Group notifications from the same app as a stack
  • Allow message threads to be grouped in a single notification bubbles
  • Larger images in the notification body
Mockups of what we'd ideally want, including grouping by app, threading, etc.

There are also animated mockups for some of this, courtesy of Jakub Steiner.

The long-term goal is for apps to switch to the portal API and deprecate both of the others as application-facing APIs. Internally we will still need something to communicate between the portal backend and GNOME Shell, but this isn't public API so we're much more flexible here. We might expand either the XDG API or the private GNOME Shell protocol for this purpose, but it has not been decided yet how we'll do this.

What we did in GNOME 46

When we started the STF project late last year we thought we could just pull the trigger on a draft proposal Jonas for an API with the new capabilities needed for mobile. However, as we started discussing things in more detail we realized that this was the the wrong place to start. GNOME Shell already didn't implement a number of features that are in the XDG notification spec, so standardizing new features was not the main blocker.

The code around notifications in GNOME Shell has grown historically and has seen multiple major UI redesigns since GNOME 3.0. Additional complexity comes from the fact that we try to avoid breaking extensions, which means it's difficult to e.g. change function names or signatures. Over time this has resulted in technical debt, such as weird anachronistic structures and names. It was also not using many of the more recent GJS features which didn't exist yet when this code was written originally.

Anyone remember that notifications used to be on the bottom? This is what they looked like in GNOME 3.6 (2012).

As a first step we restructured and cleaned up legacy code, ported it to the most recent GJS features, updated the coding style, and so on. This unfortunately means extensions need to be updated, but it puts us on much firmer ground for the future.

With this out of the way we added the first batch of features from our list above, namely adding notification headers, expanding notifications in the drawer, larger icons, and some style fixes to icons. We also fixed a very annoying issue with "App is ready" notifications not working as expected when clicking a notification (!3198 and !3199).

We also worked on a few other things that didn't make it in time for 46, most notably grouping notifications by app (which there's a draft MR for), and additionally grouping them by thread (prototype only).

Throughout the cycle we also continued to discuss the portal spec, as mentioned above. There are MRs against against XDG desktop portal and the libportal client library implementing the spec changes. There's also a draft implementation for the GTK portal backend.

Future work

With all the groundwork laid in GNOME 46 and the spec draft mostly ready we're in a good position to continue iterating on notifications in 47 and beyond. In GNOME 47 we want to add some of the first newly spec'd features, in particular notification sounds, markup support in the body, and display hints (e.g. showing on the lock screen or not).

We also want to continue work on the UI to unlock even more improvements in the future. In particular, grouping by app will allow us to drop the "only keep 3 notifications per app" behavior and will generally make notifications easier to manage, e.g. allowing to dismiss all notifications from a given app. We're also planning to work on improving keyboard navigation and ensuring all content is accessible to screen readers.

Due to the complex nature of the UI for grouping by app and the many moving parts with moving forward on the spec it's unclear if we'll be able to do more than this in the scope of STF and within the 47 cycle. This means that additional features that require the new spec and/or lots of UI work, such as grouping by thread and custom UI for call or alarm notifications will probably be 48+ material.

Conclusion

As we hope this post has illustrated, notifications are way more complex than they might appear. Improving them requires untangling decades of legacy stuff across many different components, coordinating with other projects, and engaging with standards bodies. That complexity has made this hard to work on for volunteers, and there has not been any recent corporate interest in the area, which is why it has been stagnant for some time.

The Sovereign Tech Fund investment has allowed us to take the time to properly work through the problem, clean up technical debt, and make a plan for the future. We hope to leverage this momentum over the coming releases, for a best-in-class notification experience on the free desktop. Stay tuned 🙂

23 Apr 2024 1:01pm GMT

21 Apr 2024

feedPlanet GNOME

Jussi Pakkanen: C is dead, long live C (APIs)

In the 80s and 90s software development landscape was quite different from today (or so I have been told). Everything that needed performance was written in C and things that did not were written in Perl. Because computers of the time were really slow, almost everything was in C. If you needed performance and fast development, you could write a C extension to Perl.

As C was the only game in town, anyone could use pretty much any other library directly. The number of dependencies available was minuscule compared to today, but you could use all of them fairly easily. Then things changed, as they have a tendency to do. First Python took over Perl. Then more and more languages started eroding C's dominant position. This lead to a duplication of effort. For example if you were using Java and wanted to parse XML (which was the coolness of its day), you'd need an XML parser written in Java. Just dropping libxml in your Java source tree would not cut it (you could still use native code libs but most people chose not to).

The number of languages and ecosystems kept growing and nowadays we have dozens of them. But suppose you want to provide a library that does something useful and you'd like it to be usable by as many people as possible. This is especially relevant for providing closed source libraries but the same applies to open source libs as well. You especially do not want to rewrite and maintain multiple implementations of the code in different languages. So what do you do?

Let's start by going through a list of programming languages and seeing what sort of dependencies they can use natively (i.e. the toolchain or stdlib provides this support out of the box rather than requiring an addon, code generator, IDL tool or the like)

The message is quite clear. The only thing in common is C, so that is what you have to use. The alternative is maintaining an implementation per language leaving languages you explicitly do not support out in the cold.

So even though C as a language is (most likely) going away, C APIs are not. In fact, designing C APIs is a skill that might even see a resurgence as the language ecosystem fractures even further. Note that providing a library with a C API does not mean having to implement it in C. All languages have ways of providing libraries whose external API is compatible with C. As an extreme example, Visual Studio's C runtime libraries are nowadays written in C++.

CapyPDF's design and things picked up along the way

One of the main design goals of CapyPDF was that it should provide a C API and be usable from any language. It should also (eventually) provide a stable API and ABI. This means that the ground truth of the library's functionality is the C header. This turns out to have design implications to the library's internals that might be difficult to add in after the fact.

Hide everything

Perhaps the most important declaration in widely usable C headers is this.

typedef struct _someObject SomeObject;

In C parlance this means "there is a struct type _someObject somewhere, create an alias to it called SomeObjectType". This means that the caller can create pointers to structs of type SomeObject but do nothing else with them. This leads to the common "opaque structs" C API way of doing things:

SomeObject *o = some_object_new();
some_object_do_something(o, "hello");
some_object_destroy(o);

This permits you to change the internal representation of the object while still maintaining stable public API and ABI. Avoid exposing the internals of structs whenever possible, because once made public they can never be changed.

Objects exposed via pointers must never move in memory

This one is fairly obvious when you think about it. Unfortunately it means that if you want to give users access to objects that are stored in an std::vector, you can't do it with pointers, which is the natural way of doing things in C. Pushing more entries in the vector will eventually cause the capacity to be exceeded so the storage will be reallocated and entries moved to the new backing store. This invalidates all pointers.

There are several solutions to this, but the simplest one is to access those objects via type safe indices instead. They are defined like this:

typedef struct { int32_t id; } SomeObjectId;

This struct behaves "like an integer" in that you can pass it around as an int but it does not implicitly convert to any other "integer" type.

Objects must be destructable in any order

It is easy to write into documentation that "objects of type X must be destroyed before any object Y that they use". Unfortunately garbage collected languages do not read your docs and thus provide no guarantee whatsoever on object destruction order. When used in this way any object must be destructable at any time regardless of the state of any other object.

This is the opposite of how modern languages want to work. For the case of CapyPDF especially page draw contexts were done in an RAII style where they would submit their changes upon destruction. For an internal API this is nice and usable but for a public C API it is not. The implicit action had to be replaced with an explicit function to add the page that takes both object pointers (the draw context and document) as arguments. This ensures that they both must exist and be valid at the point of call.

Use transactionality whenever possible

It would be nice if all objects were immutable but sadly that would mean that you can't actually do anything. A library must provide ways for end users to create, mutate and destroy objects. When possible try to do this with a builder object. That is, the user creates a "transactional change" that they want to do. They can call setters and such as much as they want, but they don't affect the "actual document". All of this new state is isolated in the builder object. Once the user is finished they submit the change to the main object which is then validated and either rejected or accepted as a whole. The builder object then becomes an empty shell that can be either reused or discarded.

CapyPDF is an append only library. Once something has been "committed" it can never be taken out again. This is also something to strive towards, because removing things is a lot harder than adding them.

Prefer copying to sharing

When the library is given some piece of data, it makes a private copy of it. Otherwise it would need to coordinate the life cycle of the shared piece of data with the caller. This is where bugs lie. Copying does cost some performance but makes a whole class of difficult bugs just go away. In the case of CapyPDF the performance hit turned out not to be an issue since most of the runtime is spent compressing the output with zlib.

Every function call can fail, even those that can't

Every function in the library returns an error code. Even those that have no way of failing, because circumstances can change in the future. Maybe some input that could be anything somehow needs to be validated now and you can't change the function definition as it would break API. Thus every function returns an error code (except the function that converts an error code into an error string). Sadly this means that all "return values" must be handled via out parameters.

ErrorCode some_object_new(SomeObject **out_ptr);

This is not great, but such is life.

Think of C APIs as "in-process RPC"

When designing the API of CapyPDF it was helpful to think of it like a call to a remote endpoint somewhere out there on the Internet. This makes you want to design functions that are as high level as possible and try to ignore all implementation details you can, almost as if the C API was a slightly cumbersome DSL.

21 Apr 2024 1:39pm GMT

20 Apr 2024

feedPlanet GNOME

Michael Meeks: 2024-04-20 Saturday

20 Apr 2024 10:03am GMT

19 Apr 2024

feedPlanet GNOME

Michael Meeks: 2024-04-19 Friday

19 Apr 2024 9:00pm GMT

Christian Hergert: Builder of Things

Sometimes I build stuff other than software and this is a post about that.

My wife and I had to postpone our honeymoon for a couple years due to COVID. Last spring we were able to take a trip to Thailand and really enjoyed it. So much so that when we got back we had a desire recreate that sort of relaxed urban yet tropical feel we enjoyed so much in various cities.

We don't have a lot of extra space at our house but we did have some in the back which was vacated by recently fell Elm which were diseased.

I'm not one to shy away from projects I've never done before so why not build a deck and pergola to fill out that space for entertaining and hacking?

The first step was to even the grade. When we bought the house it was already sloped but the grinding of Elm tree trunks added another layer on top of that.

That is a lot of work but to make something 8'×20′ we need to clear a lot more than this. Only to be made worse by root after root of dead Elm tree remnants. Pick axe and sweat.

That's more like it.

We don't have much of a frost line here so you don't need to do the whole concrete-pylon thing for the deck and integrated pergola. But what we do need to do is ensure that we have a retaining wall to keep wet ground from touching the cedar for the deck.

The 2×4 cedar topper is mostly just there to match what will be the cedar floor of the deck.

A bunch of gravel of various grades under the cinders create something stable that drains water beneath the cedar 4×4 which will be our columns.

This is built as two 8'×10′ sections which are connected. That makes the math much easier in my head but also easier to source good wood. Above you see the rim and floor joists for the first side with the blocking yet to be done.

I lucked out that the cedar supplier gave me 12′ 4×4s instead of the requested 10′. That gave me 2′ extra to use when framing without having to first get the whole 10′ columns leveled. Later one we'll take them out one-by-one and replace them with the columns.

Now we have the columns in place and the whole thing leveled. Blocking has started and will get completed before adding the floor boards. I ended up using screws at an angle from the rounded corners of the ceder floor boards using "camo hidden fasteners". After seeing how they handled the winter that was definitely the right decision.

Thankfully I had help from my wife and emeritus GNOMie Cosimo with all this.

Now we have all the floor boards on. The cedar appearance board is tacked on the edge of the rim joist to hide the pressure treated lumber. The beams have been connected at the top of the columns. The start of a privacy wall is in place to see how it will fit together. Next up, all those rafters which I used some simple angle cuts and a multi-tool to extract pockets to interference-fit over the beams.

Lastly my wife did her design magic after gathering all the outdoor furniture together.

This year I have jasmine and honeysuckle doing it's thing to hopefully start getting some of this pergola covered with leaves and flowers by summer. I also extended the privacy wall a bit more since this picture to have a lattice for the vines to climb.

That's it!

19 Apr 2024 1:32am GMT

Felix Häcker: #144 Better Printing

Update on what happened across the GNOME project in the week from April 12 to April 19.

Sovereign Tech Fund

Sonny says

As part of the GNOME STF (Sovereign Tech Fund) initiative, a number of community members are working on infrastructure related projects.

Here are the highlights for the past week

We welcome Felix in the team 🎉. Felix is helping towards making Key Rack a viable password manager for the GNOME desktop.

We welcome Adrien in the team 🎉. Adrien is working on the initiative to stop using TreeView to improve accessibility.

Sophie started C bindings for glycin. It's possible to get a GdkTexture for an image.

Sophie opened an MR to test bst cargo git with GNOME

Sophie fixed an issue in xdg-dbus-proxy that affected threaded DBus libraries like godbus or zbus.

Dorota is making good progress on global shortcuts portal support.

Joanie made tons of code cleanup in Orca - as usual - and

Tobias added colorful illustrations to the GNOME Human Design Guidelines

Matt started working on AccessKit integration in GTK which will bring support for the new accessibiliity architecture and potentially a11y support on macOS and Window.

Matt prepared his talk "Modernizing Accessibility for Desktop Linux" he gave at Open Source Summit North American in Seattle. Slides available and the recording should be published soon, we will make sure to twig it.

Tobias refreshed the command search/palette concept.

Sam submitted a refreshed concept for the global shortcuts design.

Sam redesigned the network proxy settings.

Sam made a website for Orca, it's now live at https://orca.gnome.org/.

Antonio worked on using Nautilus as the FileChooser portal on GNOME. He's already wrote the backofice of the portal impelementation.

Julian notifications portal v2 work is ready for review! https://github.com/flatpak/xdg-desktop-portal/pull/1298

Andy released GOA 3.50.1, with backported fixes for WebDAV, OAuth 2.0 URI handling & PKCE: https://gitlab.gnome.org/GNOME/gnome-online-accounts/-/tags/3.50.1

Alice implemented buttons rows un libadwaita https://gitlab.gnome.org/GNOME/libadwaita/-/merge_requests/1086

Evan finished the v4 beta of ts-for-gir - the new TypeScript bindings

Georges landed better printing support in Flatpak / portal

Felix landed tons of code improvements in Key Rack

Dhanuka released gcr 4.3.0

Tom submitted a pull request to implement a dbus service for systemd sysupdate.

GNOME Core Apps and Libraries

Libadwaita

Building blocks for modern GNOME apps using GTK4.

Alice (she/her) reports

libadwaita now has AdwButtonRow, implementing another missing pattern for boxed lists. Additionally, there's a .boxed-list-separate style class now, that has each row in its own card with spacing between them, and AdwPreferencesGroup:separate-rows to toggle it for preferences groups

Software

Lets you install and update applications and system extensions.

Philip Withnall announces

Dawid Osuchowski added app icons in notifications from GNOME Software (https://gitlab.gnome.org/GNOME/gnome-software/-/merge_requests/1964)

Maps

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

mlundblad reports

Maps now has dark mode variants for the default renderings (when no line color is available from a public transit provider)

GNOME Circle Apps and Libraries

Podcasts

Podcast app for GNOME.

Julian 🍃 announces

Podcasts 0.7.1 is out and can be found on Flathub. Most contributions come from nee. The highlights are:

  • Replace add button popover with a dedicated page
  • Add streaming support
  • Add additional keyboard shortcuts
  • Several fixes and performance improvements

Gaphor

A simple UML and SysML modeling tool.

Arjan reports

This week @danyeaw released Gaphor 2.25.0.

The biggest update is a UI refresh: Gaphor's UI now better follows the Adwaita style (feedback is welcome). The Property editor has be revised, so it can be used both from diagrams and the model browser. You can read the full list of changes in our ChangeLog. Builds for Windows, macOS and Linux Flatpak are available from the website and FlatHub.

Dialect

Translate between languages.

Rafael Mardojai CM announces

We have merged support for the free DeepL API in Dialect. This resolves the most popular and oldest provider request in the app.

Third Party Projects

Sonny says

Retro; the customizable clock widget is now available on Flathub in v2

https://flathub.org/apps/re.sonny.Retro

This new release comes with

Support both 12h and 24h clock format. It follows GNOME Date & Time preference while being sandboxed thanks to libportal new API for the settings portal.

Energy usage has been improved by using a more efficient method to get the time and by making use of the magic GtkWindow.suspended property to stop updating the clock when the window is not visible.

Better support for round clocks. The new GTK renderer fixed the visual glitch on transparent corners caused by large border radius. Retro now restores window dimensions and disables the border radius on maximize to make it look good, no matter the shape.

Controls have been moved to a floating header bar to stay out of the way and prevent interference with customizations.

Mahjongg

A solitaire version of the classic Eastern tile game.

Mat reports

Mahjongg 3.40.1 has been released, and is available on Flathub.

This release fixes a few regressions in the GTK 4 port. Most notably, the game no longer freezes after finishing a round, and the tile layout can be changed when using a language other than English.

I will also maintain Mahjongg from now on. If you want to help out with development, e.g. replace deprecated widgets, feel free to submit a MR on GitLab.

Fractal

Matrix messaging app for GNOME written in Rust.

Kévin Commaille reports

📣 👀 Fractal 7.rc 🆕 🎉

  • Account recovery, introduced during this cycle, could lead to an unclear situation where it was still incomplete even after successfully going through the process. We added some explanations on how to solve this. Thanks to anyone who tried it in the beta and provided us with feedback!
  • After fixing a focus issue upstream in GtkListView, we got rid of more focus issues in our widgets. That should make the room history completely accessible with keyboard navigation.
  • Third party verification, that happens in a direct chat, was partly broken as the banner about an ongoing verification was not showing up anymore. The culprit was found and we took that opportunity to improve the security instructions. Along with this bugfix, a coat of polish has been applied.

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

It is available to install via Flathub Beta, see the instructions in our README.

As the version implies, it should be mostly stable and we expect to only include minor improvements until the release of Fractal 7.

We always welcome any help we can get, come ask for guidance in our Matrix room.

Flatseal

A graphical utility to review and modify permissions of Flatpak applications.

Martín Abente Lahaye reports

Flatseal 2.2.0 is out. This new release comes with refined visuals, navigation and adaptive behavior, much more streamlined with the latest GNOME release. It also comes with bug fixes for edge cases involving global overrides and Greek translation by Athanasios Karachalios.

Documentation

Arjan announces

The PyGObject Documentation now has a new place at https://pygobject.gnome.org. This URL is easier to remember (and discover). Over time we also want to bring API docs and user guides/tutorials to this site, so we have one central place for everything Python.

Arjan says

The GNOME API docs for Python over at https://amolenaar.pages.gitlab.gnome.org/pygobject-docs/ have had a revamp over the past week. Thanks to Rafael Mardojai CM, property names are now properly presented. Properties and signals are also cross-referenced in the docs. Method signatures have been improved, based on the latest version of the pygobject-stubs project.

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!

19 Apr 2024 12:00am GMT

18 Apr 2024

feedPlanet GNOME

GNOME Foundation News: Call for GUADEC 2025 Location Proposals

The GNOME Foundation invites bids for hosting GUADEC 2025. For next year's annual gathering of GNOME users and developers, we're looking for location proposals from anywhere in the world. This is your chance to bring GUADEC to your city!

If you are interested in submitting a proposal to host GUADEC 2025 in your city, please submit an intention to bid by filling out this short form. Intent to Bid submissions are due by end-of-day May 3, 2024.

Final proposals should be submitted using our online form and are due by May 31, 2024.

Be prepared to include the following details in your proposal:

Deadlines
Intention to bid: May 3, 2024
Final proposal submission: May 31, 2024

Proposals from previous years are available for reference and you can talk to the Foundation Board and previous GUADEC organizers to find out more about what is involved. If you need more time to finalize your bid please contact kprogri@gnome.org.

Organizing GUADEC is a large undertaking but local teams will have help from Foundation Staff members and Engagement Team contributors!

If you have any questions, don't hesitate to contact Kristi at kprogri@gnome.org or the Foundation board at board@gnome.org.

Submit an Intent to Bid
Submit a Proposal

18 Apr 2024 5:38pm GMT

Peter Hutterer: udev-hid-bpf: quickstart tooling to fix your HID devices with eBPF

For the last few months, Benjamin Tissoires and I have been working on and polishing a little tool called udev-hid-bpf [1]. This is the scaffolding required quickly and easily write, test and eventually fix your HID input devices (mouse, keyboard, etc.) via a BPF program instead of a full-blown custom kernel driver or a semi-full-blown kernel patch. To understand how it works, you need to know two things: HID and BPF [2].

Why BPF for HID?

HID is the Human Interface Device standard and the most common way input devices communicate with the host (HID over USB, HID over Bluetooth, etc.). It has two core components: the "report descriptor" and "reports", both of which are byte arrays. The report descriptor is a fixed burnt-in-ROM byte array that (in rather convoluted terms) tells us what we'll find in the reports. Things like "bits 16 through to 24 is the delta x coordinate" or "bit 5 is the binary button state for button 3 in degrees celcius". The reports themselves are sent at (usually) regular intervals and contain the data in the described format, as the devices perceives reality. If you're interested in more details, see Understanding HID report descriptors.

BPF or more correctly eBPF is a Linux kernel technology to write programs in a subset of C, compile it and load it into the kernel. The magic thing here is that the kernel will verify it, so once loaded, the program is "safe". And because it's safe it can be run in kernel space which means it's fast. eBPF was originally written for network packet filters but as of kernel v6.3 and thanks to Benjamin, we have BPF in the HID subsystem. HID actually lends itself really well to BPF because, well, we have a byte array and to fix our devices we need to do complicated things like "toggle that bit to zero" or "swap those two values".

If we want to fix our devices we usually need to do one of two things: fix the report descriptor to enable/disable/change some of the values the device pretends to support. For example, we can say we support 5 buttons instead of the supposed 8. Or we need to fix the report by e.g. inverting the y value for the device. This can be done in a custom kernel driver but a HID BPF program is quite a lot more convenient.

HID-BPF programs

For illustration purposes, here's the example program to flip the y coordinate. HID BPF programs are usually device specific, we need to know that the e.g. the y coordinate is 16 bits and sits in bytes 3 and 4 (little endian):

SEC("fmod_ret/hid_bpf_device_event")
int BPF_PROG(hid_y_event, struct hid_bpf_ctx *hctx)
{
        s16 y;
        __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);

        if (!data)
                return 0; /* EPERM check */

        y = data[3] | (data[4] << 8);
        y = -y;

        data[3] = y & 0xFF;
        data[4] = (y >> 8) & 0xFF;

        return 0;
}
  

That's it. HID-BPF is invoked before the kernel handles the HID report/report descriptor so to the kernel the modified report looks as if it came from the device.

As said above, this is device specific because where the coordinates is in the report depends on the device (the report descriptor will tell us). In this example we want to ensure the BPF program is only loaded for our device (vid/pid of 04d9/a09f), and for extra safety we also double-check that the report descriptor matches.

// The bpf.o will only be loaded for devices in this list
HID_BPF_CONFIG(
        HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 0x04D9, 0xA09F)
);

SEC("syscall")
int probe(struct hid_bpf_probe_args *ctx)
{
        /*
        * The device exports 3 interfaces.
        * The mouse interface has a report descriptor of length 71.
        * So if report descriptor size is not 71, mark as -EINVAL
        */
        ctx->retval = ctx->rdesc_size != 71;
        if (ctx->retval)
                ctx->retval = -EINVAL;

        return 0;
}

Obviously the check in probe() can be as complicated as you want.

This is pretty much it, the full working program only has a few extra includes and boilerplate. So it mostly comes down to compiling and running it, and this is where udev-hid-bpf comes in.

udev-hid-bpf as loader

udev-hid-bpf is a tool to make the development and testing of HID BPF programs simple, and collect HID BPF programs. You basically run meson compile and meson install and voila, whatever BPF program applies to your devices will be auto-loaded next time you plug those in. If you just want to test a single bpf.o file you can udev-hid-bpf install /path/to/foo.bpf.o and it will install the required udev rule for it to get loaded whenever the device is plugged in. If you don't know how to compile, you can grab a tarball from our CI and test the pre-compiled bpf.o. Hooray, even simpler.

udev-hid-bpf is written in Rust but you don't need to know Rust, it's just the scaffolding. The BPF programs are all in C. Rust just gives us a relatively easy way to provide a static binary that will work on most tester's machines.

The documentation for udev-hid-bpf is here. So if you have a device that needs a hardware quirk or just has an annoying behaviour that you always wanted to fix, well, now's the time. Fixing your device has never been easier! [3].

[1] Yes, the name is meh but you're welcome to come up with a better one and go back in time to suggest it a few months ago.
[2] Because I'm lazy the terms eBPF and BPF will be used interchangeably in this article. Because the difference doesn't really matter in this context, it's all eBPF anyway but nobody has the time to type that extra "e".
[3] Citation needed

18 Apr 2024 4:17am GMT