This feed omits posts by jwz. Just 'cause.

Richard Stallman
Connected car ideal for coercive control

A connected car is an ideal weapon for coercive control — by people you know, or by strangers working for your country's government, or by strangers working for another country's government.

Posted
Richard Stallman
Neo-Nazis in Republican employment

Some Republican officials are treating and describing neo-Nazis as toxic in their employment.

That is a positive change, but they need to understand that if you run in the same circles as Nazis — in the circles that have vicious ideas that attract Nazis — you will have opportunity after opportunity to take up with someone who is a Nazi. Look how many Republicans associate willingly with Elon Musk, or the monster in the White House. They can hardly avoid

I praise the old ACLU for defending freedom of speech for everyone, to express any views whatsoever — even including Nazis. I cite Nazis as an example here because their views are as vicious as can be. I am sure the ACLU's leaders judged them that way too. But they recognized that when you start denying people's freedom of speech because you dislike their views, that is the start of tyranny — and people who criticize the powerful in any way are likely to be on the receiving end.

I am not surprised that the extent of support for Nazi views in some countries today goes hand in hand with hatred and cruelty for many disprivileged groups.

Recognizing the freedom to advocate vicious views does not imply ceasing to castigate them.

Posted
Richard Stallman
Protecting Koalas and allowing greenhouse gas emissions

Australia is considering a deal to protect more of the forests where koalas (vulnerable) live in exchange for allowing additional greenhouse gas emissions.

In effect, planet roasters are holding adorable koalas hostage with a demand to let them continue destroying civilization and the biosphere. Bravo for the Green legislators with the courage to denounce that ransom demand.

Posted
Richard Stallman
Support for affordability and accountability

Progressive campaigners report that most Americans would support a political campaign that joins the goals of "affordability" (to benefit the non-rich) and "accountability" (to be imposed on the rich).

It is useful to know that this combination — lowering prices by eliminating corruption -- can defeat the magats and plutocratists. However, it is not evident to me that the combination includes or implies preventing climate disaster, restoring human rights, upholding science, protecting everyone from Orwellian surveillance, and rejecting bigotry.

Thus, if "accountability" and "corruption" are interpreted in the usual narrow sense, I'd have to say these two goals alone are disastrously insufficient.

Posted
Richard Stallman
Urgent: Block destruction of national parks and forests

US citizens: call on Congress to block the saboteur in chief from destroying America's national parks and forests.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Posted
Bram Cohen
The Rules Of Dominoes

Robin Linus has done some truly heroic work showing that verbatim Poker can be done in Bitcoin script as it exists today with no extensions. This is still very much a prototype. Much further along than a prototype Nokitlan is supporting games on Chia, including dominoes (this is built on the Chia gaming work of been doing as the fundamental building block and interoperability substrate). Which got me thinking: What are the best dominoes rules to play on Chia? There are many different dominoes variants, with not that much standardization. The tournaments are a four player version which has a very bridge-like feel and is obviously a complete nonstarter for remote play because it’s just begging for cheating via collusion. For two players there isn’t even a completely standardized set of rules, so that’s my excuse for pondering variants, which I’ll do now.

The double-six set of dominoes is a pretty good start for the medium, because if two players alternate discards that’s 28 turns total max is which is more than ideal but somewhat workable. But there are some things which are problematic:

Thanks for reading Bram’s Thoughts! Subscribe for free to receive new posts and support my work.

There’s a lot of go-fish-like cheating, where a player is required to do something based on information only they can see. Go fish is a terrible game, it has tons of cheating by accident which small children will of course do and then learn that that’s a good thing to do. At the very start of the game a player has to do discard with a double or can use any tile they want out of their hand if they don’t have one. It’s much simpler to just make the double six be the first tile on the board at the beginning of every game.

Passing is only allowed if you don’t have a legal move to play, which is a obviously also a huge cheating problem. This doesn’t come up all that often because usually it’s counterproductive to pass, but adjudicating it after the fact is a disaster, especially in combination with tiles getting pulled from the boneyard later so there’s no way for an outside observer to tell what tiles each person had at each time from later play. It’s much better to simply allow passing at any time. If two passes in a row happen then the hand is over. It wouldn’t be too difficult to implement a rule that a player can’t do a second pass ending the hand if they have a legal move but I suspect that would result in some very cheeseball strategies where one player passes until the other player has very few tiles and then with the greater control of ensuing play easily wins the hand.

Pulling from the boneyard is awkward to implement. Notably the common four player game has no boneyard. All 28 tiles are dealt out at the beginning, 7 each to four players. It does result in some interesting hidden information play, but the lesson from Poker seems to be that when it comes to hidden information less is more, and you want it to stay relevant up until the very end instead of having everything eventually become known and then a straightforward endgame. To that end, and because this is a game mechanic I’ve long wanted to use, I think the best approach is to deal out all tiles at the beginning of the game except for one which is permanently out of play and the players don’t find out until the very end which one it is. Then the game becomes all about guessing what that tile is based on the opponent’s play and there’s lots of room for deceptive play.

There’s some random advantage to the player who gets to go first. That could be counteracted with an amount added to the final pip count like komi in Go but there would need to be some playtesting to figure out what a good value for that would be.

Putting this all together here are the draft rules of Bram’s dominoes. Needs playtesting:

Played with double six dominoes. At the start of the hand a random domino is removed from play, the double six is played out as the start, and the other 26 dominoes are dealt out 13 to each player. The first player to play is selected randomly.

Players alternate putting down a domino which extends one of the two ends of the chain on the board. They must match the number at the end of that chain with the domino they place. A player may alternately pass and must do so if they have no legal placement move.

If a player plays their last tile then they win. If both players pass in a row then their remaining tiles are revealed and which ever one of them has fewer total pips wins (possibly plus komi added to the player who went first).

Thanks for reading Bram’s Thoughts! Subscribe for free to receive new posts and support my work.

Posted
Bram Cohen
Math Tidbits

Maximal Fences

I got nerd sniped by this video and with some help from my friend Claude was able to optimize some of the existing records and set some new ones.1

Infinite Tetration

There are a bunch of videos talking about how the infinite tetration function is only defined in a specific range and strangely only hits finite values at the ends of the range, but they don’t show what it actually looks like as a function, so here it is:

Thanks for reading Bram’s Thoughts! Subscribe for free to receive new posts and support my work.

You might wonder what’s going on at the end points here. On the right it’s going completely vertical. There’s nothing actually funny happening on the left, that’s just where the formula for it using the W function splits into two value. But we can make an analytic continuation of it like so:2

Since we’re defining tetration we can make the rules and there’s no reason to limit it to the happenstance constraints of W. But this still leaves the question of what’s going on on the right. It turns out it does extend, but going up, like this:

Looking at it this way raises the question of what the inverse of this function is. It turns out it’s y=x^(1/x). So the natural way of defining this stuff is to start with that function then wonder what happens if we take its inverse and wonder what happens at the points where the W function splits. But in that direction it seems like a bunch of bizarre leaps and generalizations which require justification, where if we instead work backwards from infinite tetration they’re strange phenomena which need explanation.

The big lesson to take away is that if you see W turn up you’re probably looking at the inverse of something, and being able to support that is how W has worked its way into the canon of standard functions.

Unit Distances

After thinking about the unit distance conjecture I came to the surprising realization that for any asymptotic bound it must be possible to constrain the points to being in a ‘barbell’ of two discs exactly a unit distance apart and only take a constant factor hit based on the diameters of the discs. Writeup over here3. I was hoping that this would result in better bounds but it works out that the amount of constant factor on tightening the disc radii exactly cancels out the reduction in number of points covered by their areas. But it does seem to imply that you can find solutions whose points are within arbitrarily tight disc pairs by taking subsets of ever larger solutions. So maybe the optimal solutions all have this form and have some parameterizable epsilon how big the discs can be where any value works.

I don’t know if this observation is novel or is something obvious to people actively studying the problem and they just haven’t written it up because it hasn’t lead anywhere. But I found it interesting and surprisingand hopefully you do too.

1

It turns out Claude was taking my suggested search areas and implementing them verbatim using SLSQP which explains why nobody else had already done it with a bare prompt.

2

It’s possible to do an analytic continuation into the complex numbers which produces all kinds of interesting stuff but I’m not about to make a half hour long video with lots of 3d animations. If somebody else does that I would much appreciate it.

3

I was discussing this with Claude as I worked through it and Claude’s profound inability at geometric visualization made it not follow anything I was saying until I got to this very specific statement and then it was able to prove it immediately in a much more elegant way than I had worked out.

Posted
Tom (Jon Lund Steffensen)
Integrering af en valutaberegner i dine softwareprojekter

Hvorfor it-afdelingens budget ofte rammes af valutakursudsving

Globale it-investeringer og driftsomkostninger er i vid udstrækning underlagt internationale markedskræfter, hvilket gør it-budgetter særligt sårbare over for fluktuationer på valutamarkedet. Ifølge en analyse fra analysehuset Gartner i 2026 udgør software- og cloud-tjenester nu over 35 % af de samlede globale it-omkostninger, og størstedelen af disse afregnes i amerikanske dollars (USD). Når den danske krone (DKK) svækkes over for dollaren, stiger de reelle driftsomkostninger for danske virksomheder øjeblikkeligt, selvom det faktiske forbrug af ressourcer forbliver uændret.

Mange virksomheder opererer med faste årlige budgetter, som lægges i fjerde kvartal af det foregående regnskabsår. Hvis en virksomhed har budgetteret med en USD/DKK-kurs på 6,80, og kursen i løbet af året stiger til 7,20, repræsenterer dette en stigning i omkostningerne på knap 6 %. For en mellemstor it-afdeling med et årligt cloud-budget på 500.000 USD svarer dette til en uforudset ekstraudgift på 200.000 DKK, hvilket kan tvinge ledelsen til at udskyde andre kritiske udviklingsprojekter.

Særligt hardwareindkøb påvirkes også af disse mekanismer, da mikrochips, servere og netværksudstyr produceres globalt med afregning i USD. Selvom udstyret købes gennem en dansk distributør, er priserne ofte indeksreguleret i forhold til dollarkursen på leveringstidspunktet. Dette skaber en uforudsigelighed i forsyningskæden, som kræver konstant overvågning og finansiel risikostyring.

“Valutarisiko i it-afdelingen er ikke længere et perifert problem for finansafdelingen. Det er en direkte operationel udfordring, som kræver præcise værktøjer og proaktiv risikostyring for at undgå budgetskred.”
– Finansiel analytiker i it-sektoren, 2026

SaaS-licenser og cloud-hosting: De skjulte valutaomkostninger i USD

Software as a Service (SaaS) og Infrastructure as a Service (IaaS) har ændret it-afdelingens omkostningsstruktur fra kapitalomkostninger (CAPEX) til operationelle omkostninger (OPEX). Store udbydere som Amazon Web Services (AWS), Microsoft Azure og Google Cloud Platform afregner som standard deres ydelser i USD eller EUR. For europæiske virksomheder betyder det, at den månedlige hostingregning ændrer sig i takt med de globale valutakurser.

Mange af disse cloud-baserede services kører i øvrigt på open-source infrastruktur, hvilket du kan læse mere om i artiklen Hvad er Linux? – En komplet guide til det åbne styresystem. Selvom selve styresystemet ofte er licensfrit, betales der stadig store summer for den underliggende hardwarekapacitet og supportaftaler, som næsten altid afregnes i udenlandsk valuta.

For at styre disse fluktuerende omkostninger anvender mange finansansvarlige en digital valutaberegner, som henter realtidsdata direkte fra de globale finansmarkeder. Dette gør det muligt at estimere de præcise månedlige udgifter i danske kroner og foretage de nødvendige budgetjusteringer i tide. For præcise, bank-verificerede kurser kan man også anvende en ekstern Valutaberegner – omregn opdaterede valutakurser til at verificere de daglige transaktioner og sikre mod ubehagelige overraskelser på kreditkortudtogene.

Udover selve hostingafgifterne er mange enterprise-softwarelicenser (såsom Salesforce, Adobe Creative Cloud og Jira) bundet til dollarpriser. Selv når faktureringen sker via en europæisk enhed i euro, er prisen ofte fastsat ud fra en omregningskurs fra USD, hvilket betyder, at valutasvingninger indirekte overføres til den europæiske køber.

Styr på økonomien ved outsourcing af it-udvikling til udlandet

Outsourcing af softwareudvikling til lande i Østeuropa eller Asien er en udbredt strategi for at reducere lønomkostninger og imødekomme manglen på kvalificeret arbejdskraft i Danmark. Men når man samarbejder med eksterne udviklingshuse i eksempelvis Polen, Ukraine eller Indien, introduceres der komplekse valutarisici. Kontrakter indgås ofte i lokal valuta (såsom polske zloty (PLN) eller indiske rupees (INR)) eller i USD for at skabe en fælles standard.

Hvis den lokale valuta i modtagerlandet styrkes over for den danske krone, stiger timeprisen for udviklerne tilsvarende. En stigning på 10 % i den polske zloty kan hurtigt eliminere den økonomiske fordel, der oprindeligt var ved at outsource opgaven frem for at løse den internt eller med lokale konsulenter. Det er derfor afgørende at indbygge valutaklausuler i samarbejdsaftalerne eller foretage finansiel kurssikring (hedging).

Når der afregnes med udenlandske leverandører, skal moms- og skatteforhold indberettes korrekt til de danske myndigheder, hvor man med fordel kan konsultere SKATs officielle Valutaomregner – info.skat.dk. Korrekt omregning på faktureringstidspunktet er afgørende for at undgå efterreguleringer og sikre, at bogføringen overholder gældende dansk lovgivning.

Brug en præcis valutaberegner til at sikre dine it-budgetter

For at imødegå de risici, som valutafluktuationer medfører, bør it-afdelingen og økonomifunktionen samarbejde tæt om at overvåge markedet. En manuel omregning baseret på tilfældige søgninger på internettet er sjældent tilstrækkelig, da kurserne ændrer sig sekund for sekund. Anvendelsen af professionelle værktøjer sikrer, at man altid arbejder med de mest aktuelle og præcise tal.

Der findes forskellige finansielle strategier til at minimere valutarisikoen, og valget afhænger af virksomhedens risikoprofil og budgetstørrelse. Nedenstående tabel illustrerer de mest almindelige metoder til håndtering af valutarisiko i forbindelse med it-indkøb:

Strategi Beskrivelse Fordele Ulemper
Spot-kontrakter Køb af valuta til den aktuelle dagspris. Enkel administration, ingen langsigtede forpligtelser. Ingen beskyttelse mod fremtidige kursstigninger.
Terminskontrakter (Forwards) Låsning af en valutakurs til levering på en bestemt fremtidig dato. 100 % budgetgaranti og fuld økonomisk forudsigelighed. Man går glip af potentielle gevinster, hvis kursen falder.
Valutaoptioner Retten, men ikke pligten, til at købe valuta til en fastsat kurs. Maksimal fleksibilitet og beskyttelse mod tab. Kræver betaling af en præmie (gebyr) up-front.

Ved systematisk at anvende en præcis beregner kan it-chefen hurtigt simulere forskellige scenarier. Hvis dollarkursen eksempelvis stiger med 5 %, 10 % eller 15 %, kan man øjeblikkeligt se konsekvenserne for det samlede årsbudget og træffe beslutning om, hvorvidt der skal foretages kurssikring via virksomhedens bankforbindelse.

Sådan integrerer du valutadata direkte i dine egne it-systemer

For større virksomheder er manuel indtastning af valutakurser i ERP-systemer (Enterprise Resource Planning) både tidskrævende og forbundet med risiko for menneskelige fejl. Den mest effektive løsning er at automatisere processen ved at integrere realtids-valutadata direkte i virksomhedens økonomisystemer via et API (Application Programming Interface).

Moderne ERP-systemer som Microsoft Dynamics 365, SAP eller NetSuite tilbyder standardmoduler til automatisk valutaopdatering. Ved at forbinde systemet til en pålidelig datakilde via en REST-API kan systemet hente de officielle lukkekurser hver nat. Dette sikrer, at alle indgående fakturaer i fremmed valuta automatisk bogføres med den korrekte omregningskurs på transaktionsdatoen.

En typisk integration fungerer ved, at et script (eksempelvis skrevet i Python eller afviklet som en serverless funktion i cloud’en) kalder API’et, modtager data i JSON-format og opdaterer databasen. Dette reducerer tidsforbruget i finansafdelingen markant og minimerer risikoen for differencer i årsregnskabet, som skyldes forældede eller fejlagtige kursberegninger.

Ofte stillede spørgsmål

Hvorfor svinger it-budgetter på grund af valutakurser?

Mange it-ydelser, herunder cloud-hosting (AWS, Azure) og softwarelicenser (SaaS), afregnes i amerikanske dollars (USD). Når den danske krone svækkes over for dollaren, stiger de reelle udgifter i danske kroner, selvom det faktiske forbrug af it-ressourcer forbliver uændret.

Hvordan påvirker USD-kursen prisen på cloud-hosting?

Cloud-leverandører prissætter som regel deres globale infrastruktur i USD. Hvis dollarkursen stiger med f.eks. 8 % i løbet af et regnskabsår, vil den månedlige regning for cloud-hosting stige med nøjagtig samme procentsats for danske virksomheder, medmindre der er indgået en fast prisaftale.

Hvad er forskellen på en standard valutaberegner og en bank-kurs?

En standard valutaberegner viser typisk midterkursen (spotkursen) på det globale interbank-marked uden tillæg. Når man veksler penge eller betaler fakturaer gennem en erhvervsbank, pålægger banken normalt et vekselgebyr eller et kurstillæg, hvilket gør den reelle afregningskurs en smule dyrere.

Kan man automatisere valutaomregning i sit ERP-system?

Ja, de fleste moderne ERP- og økonomisystemer understøtter automatisk integration via API’er. Ved at opsætte en daglig synkronisering kan systemet automatisk hente og opdatere valutakurserne, hvilket eliminerer manuelt arbejde og sikrer præcis bogføring af udenlandske fakturaer.

Posted
Peter Hutterer
libei and graphics tablets stylus support

While you (yes, you! no, not you, the one behind you) have been sweltering in the heatwaves of the northern hemispheres (Assisted-by: AI), I've been busy adding graphics tablet support to libei. This is scheduled for the soon to be released libei 1.7.0.

The initial work was done by Jason Gerecke and Josh Dickens from Wacom, I've been extending, polishing and testing it for the last few weeks.

Also, upfront: this only covers the stylus part of a tablet, we do not yet have an implementation for the "pad" part (the buttons, dials, rings, strips).

libei is, of course, the library for Emulated Input, a good-enough transport layer for sending logical input events between processes. We're already using libei as part of the XDG Portal Remote Desktop and Input Capture portals where we've been busy hurtling key and pointer events between the participating parties (and soon gesture events and text).

In the next release of libei, we will now also have "ei stylus" capabilities, i.e. the ability to send tablet stylus events. Getting pointer, keyboard and touch events supported was a long undertaking, everything was new and shiny and needed to be added everywhere in the stack. Now that all this is in place, scuffed and scratched, adding tablet events will be quite simple.

The ei stylus interface

Here's a short outline of how libei handles tablet events because it is, of course, different to how libinput handles them. Logical events are much nicer after all than physical hardware events.

First: we have a new interface: "ei_stylus". An EIS implementation (e.g. your compositor) may provide you, the libei client, with a device that supports this interface and one or more associated regions (typically representing the available screen areas). Typically this will be a separate device to the pointer devices or the keyboard devices but it's not a requirement. The ei_stylus interface comes with a bunch of capabilities you'd expect from a stylus (tilt, pressure, distance, ...) that you can selectively enable to emulate the stylus you want to. So basically, EIS will say "here's a stylus device, I support pressure, tilt, rotation, ..." and then the libei client says "This stylus should have pressure and tilt but nothing else". And then you do the normal thing: send proximity events, send tip down/up events, send data for the various capabilities you've enabled.

Happily for the EIS implementation, libei forces the client to take the guesswork out of everything: if you select the pressure capability, you must send a pressure value when coming into proximity. Where libei is used to forward data from a physical stylus (e.g. via some remoting protocol) it is up to the client to deal with firmware bugs that e.g. won't send data until a few frames in.

Note that there is no "tablet" anywhere. The tablet is represented by the region that the device may interact with. So in some ways every tablet is an on-screen tablet (which makes sense since we have logical events).

Multiple styli

The only quirky thing is how to request multiple styli[1]: libei 1.5.0 has added a "request device" request that allows a client to say "hey, EIS, I want a new device with capabilities pointer, keyboard, ...". And, if you've been a nice client, minding your own business, the EIS implementation may just create such a device for you.

So for the case of multiple styli: if the default stylus (if any) isn't good enough, you can now tell EIS that you want a(nother) device with stylus capability, configure the stylus capabilities once the device shows up and voila, you now have a normal pen, an art pen and maybe even an airbrush represented as logical device in libei. And since they're all separate devices in the protocol, they can be individually tracked and used, much like libinput tracks individual styli.

[1] For the "lots" of users that actually use multiple styli...

Peter Hutterer
libei and gesture events

/me gestures vaguely at everything

Oh, hey, this works now? Great!

libei 1.7.0 (to be released soon) comes with a new interface: "ei_gestures" which, creatively, will allow for gestures to be sent between a libei client and an EIS implementation (typically: a Wayland compositor).

I'm not going to go too deeply into how pinch, swipe and hold gestures work, suffice to say we've had those in libinput (for touchpads) for years now so compositors and toolkits should already support those. And since libei and libinput have vaguely equivalent API layers integrating gestures for libei devices in compositors should be fairly straightforward.

The plumbing layers in the portals exist already too, so adding gestures to libei means that - once the compositors support it - we can have gestures support in remote desktop and input capture implementations without needing to update anything else. Hooray! Join in with me. Hooray! Louder! HOORAY!

For testing I had a (vibe-coded and thus immediately abandoned once testing was complete) gesturemouse utility which translates input events from a mouse into gesture events (depending which button is down). But don't let my lack of be a limit to your imagination, I'm sure you can come up with good use-cases for this.

Peter Hutterer
libei and keysym/text events

If you've been paying attention (and I know you have, because it'd be embarrassing for you if you didn't) you'd have noticed that libei 1.6 (May 2026) added support for keysym and text events.

libei sends logical events between a libei client and an EIS implementation (typically: a Wayland compositor) but the keyboard interface it had was designed like real keyboards: key codes together with an (XKB) key map. You press one key, the keymap decides what that key means on the compositor side and off we go. This is easy but not always useful.

As of 1.6.0 libei now also supports an "ei_text" interface. A compositor may choose to provide you[0] with a device that supports this interface and that gives you two really nice opportunities.

First, you can now send a key sym. Instead of sending the KEY_Q key code and hoping it actually translates to 'q' (and if there's e.g. a frenchman^Wfrenchperson lurking behind the keyboard it may mean 'a'), you can now send 'q' as actual keysym. Or 'Q' instead of sending shift+q and hoping for no french influence in the process. It becomes the EIS implementation's job to handle that keysym - if it's a shortcut it may handle it directly, otherwise it may pass it on via Wayland to an application[1]. This centralises the keysym to keycode handling in the EIS implementation which is a pain for compositor authors (though they likely have that code already for e.g. RDP support) but reduces the variety of differently-wrong implementations in clients and of course makes it so much simpler to write clients.

Second, a client can send UTF-8 text to the compositor. So instead of emulating shift, keycodes, etc. you can literally send "Hello World" and expect the EIS implementation to pass that one. Again, makes a bunch of utilities a lot simpler to write and I mostly leave it up to your imagination to figure out what to do with that.

Notably for both cases: libei is about logical events that have a specific meaning that do not need further interpretation. If a client sends 'Q' that means it is supposed to be an uppercase Q. Sending keysym Shift_L and Q makes little sense. And for the utf8 text events: how the text comes to be matters doesn't matter for libei so you may use an IM to make up the text to begin with and send it, once committed, to EIS. It's not for sending partial strings.

As mentioned in the previous post: the plumbing for this is already in place so both clients and compositors can add support for this new interface without having to bother the rest of the stack (e.g. portals). So, hooray I guess.

The text/keysym support is relatively recent so expect this to hit the next compositor version (or the one after that).

[0]: the EIS implementation decides which devices are available and arguing about this is even less useful than arguing with a world cup ref
[1]: after converting it to a key code with possible keymap changes... but hey, such is life

Peter Hutterer
libei integrations in the XDG RemoteDesktop and InputCapture portals

Turns out it's been years since I've talked about eggs, so let's change this. libei is, of course, the library for Emulated Input[1].

This post is mostly a refresher because it's been so long and a short summary of some of the work we've done so far, in preparation for some more posts that come soon.

libei is a transport layer for logical input events, unlike libinput which is a hardware abstraction layer. In libinput's case the device's firmare/kernel pass events that are somewhere on the sanity spectrum, libinput tries to make sense of those and then we convert those to logical events to be consumed by the next layer (typically the Wayland compositor or Xorg). This is how e.g. "touch down at position x1/y1, touch up at position x1/y2" is converted into a button click event if touchpad tapping is enabled. Or maybe into nothing if we find it was an accidental palm touch.

libei works purely on the logical level - you as the libei client pass logical events to the EIS (Emulated Input Server) implementation (typically the compositor). No guesswork, you say button click, EIS gets a button click. libei supports a "sender" and "receiver" mode, depending on whether events are sent to the EIS implementation (input emulation) or receive from the EIS implementation (input capture). libei is designed for the Wayland stack but there are zero requirements for Wayland on either the client or the EIS implementation.

Core to libei's design is that the EIS implementation is in control of virtually everything, it decides which devices are available to the client, when those devices can send events, etc. Much like the compositor is in charge when it comes to physical devices - if a compositor decides a physical device doesn't exist, a Wayland client cannot get events from it.

Since the original proposal (again, [1]!) we've been busy bees and libei is now a part of the XDG Remote Desktop portal and the XDG Input Capture (both since version 1.17, mid 2023). In both cases the portal is for the negotiation and initial agreement of what should happen, libei is then used as the transport layer between the two processes [2].

More recently we also added session persistence support so you don't have to allow access on every connecton. Much of the work enabling this was done by Jonas Ådahl, it is now in the portals since version 1.21.0 and should be in the major compositors in the current or next versions.

Plumbing the Pipes

Getting all this into place was a huge amount of work across several pieces of the stack. This isn't exciting in the same way as laying plumbing pipes isn't particularly exciting but much like regular plumbing: once it's in place you can change your diet without severely impacting everyone again. Try get that analogy out of your head now. You're welcome.

In libei's case this means three things:

  • if you have a client that uses the XDG portals to send/receive events they will now work with any compositor that implements the portal. No need for GNOME/KDE/... specific APIs.
  • if you have a compositor that implements EIS you have all the infrastructure in place to talk to libei clients from somewhere else, if need be. The use-cases for this aren't fully scoped yet (assisitive technologies, virtual keyboards, touchpads, etc?) but the piping is there and ready to be (ab)used .
  • since the actual events back and forth don't affect the layers in between, we can now add new events to libei without having to change everything else again.
Let's look at how this works in practice.

The XWayland XTEST use-case

An example for such a case where we can now abuse the piping is Xwayland support for XTEST. XTEST is the protocol that everyone uses to emulate input under X but in Wayland it's not hooked up to anything so those APIs simply won't work.

But what we can do in Xwayland is translate XTEST to libei events and facilitate the portal interaction. This means our stack looks roughly like this:

    +--------------------+             +------------------+
    | Wayland compositor |---wayland---| Wayland client B |
    +--------------------+\            +------------------+
    | libinput |   EIS   | \_wayland______
    +----------+---------+                \
        |          |           +-------+------------------+
 /dev/input/       +-----------| libei |     XWayland     |
                               +-------+------------------+
                                                |
                                                | XTEST
                                                |
                                         +-----------+
                                         |  X client |
                                         +-----------+
And if said X client uses XTEST to try to emulate devices, Xwayland will ask the Remote Desktop portal for permission and set up the session, then pass the XTEST events on as libei events and voila - your 20 year old X client can send pointer and keyboard events through an XDG Portal without knowing about it (and the user can prohibit this and even gets some information on who is sending events which is not possible with normal XTEST at all). This has now been supported since Xwayland 23.2.0. Compositors don't need extra support for this.

What's next

So we have a lot of the plumbing in place, or in another anology: we have a hammer, let's go looking for nails. And right now the nails we can see are sending text, gestures, and tablet support. And those will be the subject of the next few posts.

[1]: 6 years ago?! whoah...
[2]: in Remote Desktop's case replacing the DBus emulation APIs which were a Newton's Cradle of wakeups for at least 4 processes per event