Signing PDFs without embedded forms under Linux

Posted on . Updated on .

Edit: I’ve added a couple more methods for modifying PDF files with suggestions from readers. Thanks everyone!

Picture the following situation: someone sends you a PDF document and asks you to send it back signed. Some problems, though:

  • The PDF doesn’t have an embedded form, it’s just something they exported from their word processor.

  • They’re not using any signing service like DocuSign, Dropbox Sign or any other.

Sounds implausible? I’ve faced the situation multiple times. From the top of my head:

  • When I joined Igalia some years ago I had to do that with a few documents.

  • Multiple times, one of them very recent, when interacting with some electronic administration websites, where the definition of electronic administration is:

    • We make the form available to you as a PDF document (thank us we don’t give you a .docx file at least).

    • You can send the form filled back to us through the internet, by attaching a file somehow.

    • No, we don’t have an HTML version of the form.

    • No, we don’t have anything set up so you can sign the document with your official electronic certificate or anything similar.

  • With documents from the homeowner association management company.

If you’re like me, what do you do? Print the document, fill it, scan it, attach it.

Side quest: scanning pages

No, I’m not taking pictures of the document with my phone to send it back. For me, that’s a solved problem now. The scanning system on Linux is called SANE (standing for Scanner Access Now Easy) and it has an official non-HTTPS site. If you want to properly scan an A4 or US-Letter sized document, you can get a desktop scanner. The SANE website has a list of supported devices, indicating how well-supported each is. Long story short? I’m partial to Canon scanners because I know they work reasonably well. In their website, as of the time I’m writing this, they list a couple of them: the CanoScan LIDE 300 and the CanoScan LIDE 400. Both of them are very well supported under SANE. I got the 300 model some time ago. Plug it in, open the document scanner Gnome app and start scanning. No setup needed.

Back to signing

Can we do better than the print+scan cycle? Can you insert your scanned signature into the document easily? For that, you have to solve two separate problems.

  • Getting a nice version of your signature in image form.

    • Ideally, as a PNG with a transparent background.

    • If not, a clear image with a light background could do it.

  • Inserting that image on the PDF somehow.

I don’t know if this sounds surprising to you, but the hardest problem is the first one. However, you only have to solve it once. Let’s start, then, by the second one.

Inserting the signature

Thanks Emma Anholt for mentioning you can open PDFs with LibreOffice Draw and use it to insert images and text anywhere in the document! Thanks also to Alyssa Rosenzweig for also mentioning Xournal (or Xournal++), which I’ve found to work much better at that task compared to LibreOffice. Also special thanks to everybody who contacted me mentioning different methods and tools! I really enjoy posting these articles just for the reactions, comments and suggestions.

Method 1: Xournal++

Xournal++ is an open source program you can typically install from your distribution repositories. I installed it from Gnome Software on Fedora without issues, and selected the official RPM as the source.

Gnome Software showing Xournal++ as installed

The application is designed to create notes in general, using images, text or typically a graphics tablet, but it turns out it has an option to annotate an existing PDF.

Xournal++ File menu showing an option to annotate a PDF file

It will open the PDF and let you put anything on it. You can use a wide variety of tools to insert images, text boxes or even draw anything on top by hand, if you have a graphics tablet or incredible mouse skills. You should take a look at the toolbar and/or the tools menu to see what it can do. The easiest option is clicking on the image insertion tool, click anywhere in the document and select the image you want to insert. If it turns out to be too big or small, you can drag the corner to increase or decrease size preserving the image aspect, and you can move it around freely. The text insertion tool is also handy to fill complex forms that can’t be filled as a proper form. When done, use “File > Export as PDF” to generate a new document. End of the journey!

Method 2: Firefox

Amazingly, I wasn’t aware of this option until it was mentioned to be by a couple of people. Thanks to Sasi Péter and an anonymous user for the tip.

When you open a PDF file under Firefox, there’s a toolbar that lets you insert text, draw and insert images, much like Xournal++.

Screenshot of the Firefox PDF editing toolbar

If, as it was my case, you don’t have the image insertion button, you need to take a look at the pdfjs.enableStampEditor in about:config. Once you’ve finished modifying the document click on the Save icon (folder with an arrow pointing down) to save the modified version.

Method 3: LibreOffice Draw

You can also open PDFs with LibreOffice Draw and you can use its incredibly wide variety of tools to modify the document. That includes inserting images, text or whatever you need. However, I’ve found LibreOffice Draw to be a bit lacking when preserving the original PDF contents. For example, one of the documents I had to sign had an appended Latex-generated subdocument in the last pages, and LibreOffice Draw was not able to preserve the font and style of those last pages after inserting the signature. Xournal++, on the other hand, preserved it without issues.

Method 4: falsisign

Suggested by Anisse on Mastodon.

falsisign is a tool intended to be used for automation and it probably falls out of what most people would consider a friendly tool. However, it looks incredibly practical if you need to sign a lot of pages in a document, and its default behavior allows the final document to look like if it had been printed, signed and then scanned again, if you want or need your document to look that way. There are options to disable that behavior, though.

Creating a nice version of your signature as a PNG file

This is getting long so I’ll cut it short: follow one of the available video tutorials on YouTube. I used the one I just linked, and I can boil it down to the following steps, but please follow the video in case of doubt:

  1. If possible, scan your signature on a white paper using a pen that leaves a clear mark, like a marker pen or Pilot V5 or something like that.

  2. If you don’t have a scanner, take a picture with your phone trying not to create a shadow from your body or the phone on the paper.

  3. Import the image into Gimp and crop it as you see fit.

  4. Decrease saturation to make it gray-scale.

  5. Play with the color value curves, moving up the highest part of the curve so the white (or almost white) background becomes fully white, and moving down the lowest part of the curve so the trace becomes even more dark and clear, until you’re satisfied with the results.

  6. Remove any specks from the white background using the drawing tools.

  7. Duplicate the main layer adding a copy of it.

  8. Invert the colors of the layer copy so it becomes white-on-black.

  9. Add a transparency mask to the original layer, with black as transparent.

  10. Copy the inverted layer and paste it into the transparency mask of the original layer (this will make the white background transparent).

  11. Export the final result as a PNG.


Take into account it’s easy to extract images from PDF files, so using this method it may be easy for someone to extract your signature from the generated document. However, this can also be easily done if you scan or take a picture of a physical document already signed, even if the signature crosses some lines in the document, with minimal image manipulation skills, so I don’t think it changes the threat model in a significant way compared to the most common solution.

The Dark Side of the Blog

Posted on .

If you’re browsing this blog from a device in which the preferred theme is dark you may notice the blog now has a dark theme. This is an idea that had crossed my mind multiple times in the past months but it’s not until very recently that I decided to take a serious look at how to do it. My decision to finally tackle the issue was motivated by “contradicting” reports I read online. Some people complain about how the lack of a light mode option is an accesibility or usability issue for them, making it impossible to read a long text. For other people, it’s the other way around. The only proper solution to this is to have both a dark mode and a light mode and use the one preferred by the user, which is what this blog does now. No JavaScript was harmed (or used) in the process, so lets take a quick look at how to achieve this. In other words, follow me in this journey to the basic stuff from a non-web developer point of view.

The first thing I did was to replace all the colors in my CSS file with variables. This is not only helpful to create a dark theme, but it also helps keep the colors defined in a single place and makes changing them much easier. The programmer in me is now glad the color scheme is no longer full of magic constants. Achieving this is easy. If you previoysly had…​

body {
  background: white;

Now you can have…​

:root {
  --background-color: white;
body {
  background: var(--background-color);

When you define a CSS variable (or custom CSS property, which I think is the proper term to refer to them), you can give it an arbitrary name starting with a double dash. Later, you can use those properties as values using var() with the name inside the parens. You’re not restricted to colors. You can define more things like linear gradients, filters, etc.

After that, defining an alternative dark or light theme is as easy as doing…​

@media (prefers-color-scheme: dark) {
  :root {
    --background-color: black;

And that’s it. You can now change the main colors to alternative versions for dark or light modes.

For my blog, the main theme is still going to be light. This is reflected when sometimes I insert images or other content and, if I can’t easily make the background transparent, I’m going to default to white. However, I’ll try to add white margings in the future so images don’t look as bad in the dark theme as the Igalia logo next to the Vulkan logo I used in a recent post.

One small trick I’m using that required a bit more digging is handling the Github icon in the “About Me” page. It’s an SVG icon drawn in an almost-black color and it’s referenced as an external resource, so we cannot change the fill property of the SVG to switch to a different color when using dark mode. Yet, if you look at the page in dark mode, you’ll see the icon is displayed in an almost-white color. The key, in this case, is a custom invert filter. In the CSS, I specify:

:root {
  --github-icon-filter: invert(0);
@media (prefers-color-scheme: dark) {
  :root {
    --github-icon-filter: invert(1);
.githubicon {
  filter: var(--github-icon-filter);

This means the icon colors are inverted for dark mode and are kept as is for light mode.

And that’s it! Sorry if I bored you with basic stuff (web developer maybe?) and glad if you found this interesting! See you on the dark side of the Moon.

Year-end donations round, 2023 edition

Posted on .

As in previous years, I’ve made a small round of personal donations now that the year-end is approaching. This year I’ve changed my strategy a bit, donating a bit more and prioritizing software projects. My motivation to publish the list is to encourage others to donate and to give ideas for those looking for possible recipients.

This year, the list of projects and organizations is:

  • Signal, because I use it daily.

  • Notepad++ because my wife uses it daily for both work and personal tasks.

  • WinSCP for similar reasons.

  • Transmission, the BitTorrent client, because I also use it from time to time and it’s really nice.

  • Gnome because it’s my desktop environment these days.

  • LibreOffice because I also use it a lot and I think it’s an important piece of software in any desktop computer.

  • OpenStreetMap because it plays a major role in having freely available maps outside major corporation control.

  • Software Freedom Conservancy because it’s a nice organization and the X.Org Foundation, for example, will be under its umbrella soon.

  • Pi-Hole because I have one installed in my home network and it’s a really nice piece of software.

  • Aegis Authenticator because it’s another one of those apps I use daily. Edit: I cannot get this payment through. Aegis uses Buy Me a Coffee, the payment goes through Stripe and all my cards are rejected. 🤷

Vulkan extensions Igalia helped ship in 2023

Posted on .

Filed under: igalia

Last year I wrote a recap of the Vulkan extensions Igalia helped ship in 2022, and in this post I’ll do the exact same for 2023.

Igalia Logo next to the Vulkan Logo

For context and quoting the previous recap:

The ongoing collaboration between Valve and Igalia lets me and some of my colleagues work on improving the open-source Vulkan and OpenGL Conformance Test Suite. This work is essential to ship quality Vulkan drivers and, from the Khronos side, to improve the Vulkan standard further by, among other things, adding new functionality through API extensions. When creating a new extension, apart from reaching consensus among vendors about the scope and shape of the new APIs, CTS tests are developed in order to check the specification text is clear and vendors provide a uniform implementation of the basic functionality, corner cases and, sometimes, interactions with other extensions.

In addition to our CTS work, many times we review the Vulkan specification text from those extensions we develop tests for. We also do the same for other extensions and changes, and we also submit fixes and improvements of our own.

So, without further ado, this is the list of extensions we helped ship in 2023.


This extension builds on last year’s VK_EXT_attachment_feedback_loop_layout, which is used by DXVK 2.0+ to more efficiently support D3D9 games that read from active render targets. The new extension shipped this year adds support for setting attachment feedback loops dynamically on command buffers. As all extensions that add more dynamic state, the goal here is to reduce the number of pipeline objects applications need to create, which makes using the API more flexible. It was created by our beloved super good coder and Valve contractor Mike Blumenkrantz. We reviewed the spec and are listed as contributors, and we wrote dynamic variants of the existing CTS tests.


A new extension proposed by Joshua Ashton that also helps with layering D3D9 on top of Vulkan. The original problem is quite specific. In D3D9 and other APIs, applications can specify what is called a “depth bias” for geometry using an offset that is to be added directly as an exact value to the original depth of each fragment. In Vulkan, however, the depth bias is expressed as a factor of “r”, where “r” is a number that depends on the depth buffer format and, furthermore, may not have a specific fixed value. Implementations can use different values of “r” in an acceptable range. The mechanism provided by Vulkan without this extension is useful to apply small offsets and solve some problems, but it’s not useful to apply large offsets and/or emulate D3D9 by applying a fixed-value bias. The new extension solves these problems by giving apps the chance to control depth bias in a precise way. We reviewed the spec and are listed as contributors, and wrote CTS tests for this extension to help ship it.


This extension was proposed by Piers Daniell from NVIDIA to lift some restrictions in the original VK_KHR_dynamic_rendering extension, which is used in Vulkan to avoid having to create render passes and framebuffer objects. Dynamic rendering is very interesting because it makes the API much easier to use and, in many cases and specially in desktop platforms, it can be shipped without any associated performance loss. The new extension relaxes some restrictions that made pipelines more tightly coupled with render pass instances. Again, the goal here is to be able to reuse the same pipeline object with multiple render pass instances and remove some combinatorial explosions that may occur in some apps. We reviewed the spec and are listed as contributors, and wrote CTS tests for the new extension.


Shipped at the beginning of the year by Mike Blumenkrantz, the extension again helps emulating other APIs on top of Vulkan. Specifically, the extension allows creating 3D views of 3D images such that the views contain a subset of the slices in the image, using a Z offset and range, in the same way D3D12 allows. We reviewed the spec, we’re listed as contributors, and we wrote CTS tests for it.


This one comes from Valve contractor Hans-Kristian Arntzen, who is mostly known for working on Proton projects like VKD3D-Proton. The extension is related to ray tracing and adds more flexibility when creating ray tracing pipelines. Ray tracing pipelines can hold thousands of different shaders and are sometimes built incrementally by combining so-called pipeline libraries that contain subsets of those shaders. However, to properly use those pipelines we need to create a structure called a shader binding table, which is full of shader group handles that have to be retrieved from pipelines. Prior to this extension, shader group handles from pipeline libraries had to be requeried once the final pipeline is linked, as they were not guaranteed to be constant throughout the whole process. With this extension, an implementation can tell apps they will not modify shader group handles in subsequent link steps, which makes it easier for apps to build shader binding tables. More importantly, this also more closely matches functionality in DXR 1.1, making it easier to emulate DirectX Raytracing on top of Vulkan raytracing. We reviewed the spec, we’re listed as contributors and we wrote CTS tests for it.


Shader objects is probably the most notorious extension shipped this year, and we contributed small bits to it. This extension makes every piece of state dynamic and removes the need to use pipelines. It’s always used in combination with dynamic rendering, which also removes render passes and framebuffers as explained above. This results in great flexibility from the application point of view. The extension was created by Daniel Story from Nintendo, and its vast set of CTS tests was created by Žiga Markuš but we added our grain of sand by reviewing the spec and proposing some changes (which is why we’re listed as contributors), as well as fixing some shader object tests and providing some improvements here and there once they had been merged. A good part of this work was done in coordination with Mesa developers which were working on implementing this extension for different drivers.

VK_KHR_video_encode_h264 and VK_KHR_video_encode_h265

Fresh out of the oven, these Vulkan Video extensions allow leveraging the hardware to efficiently encode H.264 and H.265 streams. This year we’ve been doing a ton of work related to Vulkan Video in drivers, libraries like GStreamer and CTS/spec, including the two extensions mentioned above. Although not listed as contributors to the spec in those two Vulkan extensions, our work played a major role in advancing the state of Vulkan Video and getting them shipped.


That’s it for this year! I’m looking forward to help ship more extension work the next one and trying to add my part in making Vulkan drivers on Linux (and other platforms!) more stable and feature rich. My Vulkan Video colleagues at Igalia have already started work on future Vulkan Video extensions for AV1 and VP9. Hopefully some of that work is ratified next year. Fingers crossed!

I'm playing Far Cry 6 on Linux

Posted on . Updated on .

Filed under: igalia

2023-12-10 UPDATE: From Mastodon, arcepi suggested the instability problems that I described below and served as a motivation to try Far Cry 6 on Linux could be coming from having switched from NVIDIA to AMD without reinstalling Windows, because of leftover files from the NVIDIA drivers. Today morning I reinstalled Windows to test this and, indeed, the Deathloop and Far Cry 6 crashes seem to be gone (yay!). That would have removed my original motivation to try to run the game on Linux, but it doesn’t take away the main points of the post. Do take into account that the instability doesn’t seem to exist anymore (and I hope this applies to more future titles I play) but it’s still the background story to explain why I decided to install Far Cry 6 on my Fedora 39 system, so the original post follows below.

If you’ve been paying attention to the evolution of the Linux gaming ecosystem in recent years, including the release of the Steam Deck and the new Steam Deck OLED, it’s likely your initial reaction to the blog post title is a simple “OK”. However, I’m coming from a very particular place so I wanted to explain my point of view and the significance of this, and hopefully you’ll find the story interesting.

steam running on fedora
Figure 1. Steam running on Fedora Linux 39

As a background, let me say I’ve always gamed on Windows when using my PC. If you think I’m an idiot for doing so lately, specially because my work at Igalia involves frequently interacting with Valve contractors like Samuel Pitoiset, Timur Kristóf, Mike Blumenkrantz or Hans-Kristian Arntzen, you’d be more than right. But hear me out. I’ve always gamed on Windows because it’s the safe bet. With a couple of small kids at home and very limited free time, when I game everything has to just work. No fiddling around with software, config files, or wasting time setting up the software stack. I’m supposed to boot Windows when I want to play, play, and then turn my computer off. The experience needs to be as close to a console as possible. And, for anything non-gaming, which is most of it, I’d be using my Linux system.

In the last years, thanks to the work done by Valve, the Linux gaming stack has improved a lot. Despite this, I’ve kept gaming on Windows for a variety of reasons:

  1. For a long time, my Linux disk only had a capacity of 128GB, so installing games was not a real possibility due to the amount of disk space they need.

  2. Also, I was running Slackware and installing Steam and getting the whole thing running implied a fair amount of fiddling I didn’t even want to think about.

  3. Then, when I was running Fedora on a large disk, I had kids and I didn’t want to take any risks or possibly waste time on that.

So, what changed?

sapphire pulse amd rx 6700 box
Figure 2. Sapphire Pulse AMD Radeon RX 6700 box

Earlier this year I upgraded my PC and replaced an old Intel Haswell i7-4770k with a Ryzen R5 7600X, and my GPU changed from an NVIDIA GTX 1070 to a Radeon RX 6700. The jump in CPU power was much bigger and impressive than the more modest jump in GPU power. But talking about that and the sorry state of the GPU market is a story for another blog post. In any case, I had put up with the NVIDIA proprietary driver for many years and I think, on Windows and for gaming, NVIDIA is the obvious first choice for many people, including me. Dealing with the proprietary blob under Linux was not particularly problematic, specially with the excellent way it’s handled by RPMFusion on Fedora, where essentially you only have to install a few packages and you can mostly forget about it.

However, given my recent professional background I decided to go with an AMD card for the first time. I wanted to use a fully open source graphics stack and I didn’t want to think about making compromises in Wayland support or other fronts whatsoever. Plus, at the time I upgraded my PC, the timing was almost perfect for me to switch to an AMD card, because:

  1. AMD cards were, in general, performing better for the same price than NVIDIA cards, except for ray tracing.

  2. The RX 6700 non-XT was on sale.

  3. It had the same performance as a PS5 or so.

  4. It didn’t draw a ton of power like many recent high-end GPUs (175W, similar to the 1070 and its 150W TDP).

After the system upgrade, I did notice a few more stability problems when gaming under Windows, compared to what I was used to with an NVIDIA card. You can find thousands of opinions, comments and anecdotes on the Internet about the quality of AMD drivers, and a lot of people say they’re a couple of steps below NVIDIA drivers. It’s not my intention at all to pile up on those, but it’s true my own personal experience is having generally more crashes in games and having to face more weird situations since I switched to AMD. Normally, it doesn’t get to the point of being annoying at all, but sometimes it’s a bit surprising and I could definitely notice that increase in instability without any bias on my side, I believe. Which takes us to Far Cry 6.

A few days ago I finished playing Doom Eternal and its expansions (really nice game, by the way!) and I decided to go with Far Cry 6 next. I’m slowly working my way up with some more graphically demanding games that I didn’t feel comfortable with playing on the 1070. I went ahead and installed the game on Windows. Being a big 70GB download (100GB on disk), that took a bit of time. Then I launched it, adjusted the keyboard and mouse settings to my liking and I went to the video options menu. The game had chosen the high preset for me and everything looked good, so I attempted to run the in-game benchmark to see if the game performed well with that preset (I love it when games have built-in benchmarks!). After a few seconds in a loading screen, the game crashed and I was back to the desktop. “Oh, what a bad way to start!”, I thought, without knowing what lied ahead. I launched the game again, same thing.

On the course of the 2 hours that followed, I tried everything:

  1. Launching the main game instead of the benchmark, just in case the bug only happened in the benchmark. Nope.

  2. Lowering quality and resolution.

  3. Disabling any advanced setting.

  4. Trying windowed mode, or borderless full screen.

  5. Vsync off or on.

  6. Disabling the overlays for Ubisoft, Steam, AMD.

  7. Rebooting multiple times.

  8. Uninstalling the drivers normally as well as using DDU and installing them again.

Same result every time. I also searched on the web for people having similar problems, but got no relevant search results anywhere. Yes, a lot of people both using AMD and NVIDIA had gotten crashes somewhere in the game under different circumstances, but nobody mentioned specifically being unable to reach any gameplay at all. That day I went to bed tired and a bit annoyed. I was also close to having run the game for 2 hours according to Steam, which is the limit for refunds if I recall correctly. I didn’t want to refund the game, though, I wanted to play it.

The next day I was ready to uninstall it and move on to another title in my list but, out of pure curiosity, given that I had already spent a good amount of time trying to make it run, I searched for it on the Proton compatibility database to see if it could be run on Linux, and it seemed to be possible. The game appeared to be well supported and it was verified to run on the Deck, which was good because both the Deck and my system have an RDNA2 GPU. In my head I wasn’t fully convinced this could work, because I didn’t know if the problem was in the game (maybe a bug with recent updates) or the drivers or anywhere else (like a hardware problem).

And this was, for me, when the fun started. I installed Steam on Linux from the Gnome Software app. For those who don’t know it, it’s like an app store for Gnome that acts as a frontend to the package manager.

gnome software
Figure 3. Gnome Software showing Steam as an installed application

Steam showed up there with 3 possible sources: Flathub, an “rpmfusion-nonfree-steam” repo and the more typical “rpmfusion-nonfree” repo. I went with the last option and soon I had Steam in my list of apps. I launched that and authenticated using the Steam mobile app QR code scanning function for logging in (which is a really cool way to log in, by the way, without needing to recall your username and password).

My list of installed games was empty and I couldn’t find a way to install Far Cry 6 because it was not available for Linux. However, I thought there should be an easy way to install it and launch it using the famous Proton compatibility layer, and a quick web search revealed I only had to right-click on the game title, select Properties and choose to “Force the use of a specific Steam Play compatibility tool” under the Compatibility section. Click-click-click and, sure, the game was ready to install. I let it download again and launched it.

Context menu shown after right-clicking on Far Cry 6 on the Steam application, with the Properties option highlighted
Far Cry 6 Compatibility tab displaying the option to force the use of a specific Steam Play compatibility tool

Some stuff pops up about processing or downloading Vulkan shaders and I see it doing some work. In that first launch, the game takes more time to start compared to what I had seen under Windows, but it ends up launching (and subsequent launches were noticeably faster). That includes some Ubisoft Connect stuff showing up before the game starts and so on. Intro videos play normally and I reach the game menu in full screen. No indication that I was running it on Linux whatsoever. I go directly to the video options menu, see that the game again selected the high preset, I turn off VSync and launch the benchmark. Sincerely, honestly, completely and totally expecting it to crash one more time and that would’ve been OK, pointing to a game bug. But no, for the first time in two days this is what I get:

far cry 6 benchmark
Figure 4. Far Cry 6 benchmark screenshot displaying the game running at over 100 frames per second

The benchmark runs perfectly, no graphical glitches, no stuttering, frame rates above 100FPS normally, and I had a genuinely happy and surprised grin on my face. I laughed out loud and my wife asked what was so funny. Effortless. No command lines, no config files, nothing.

As of today, I’ve played the game for over 30 hours and the game has crashed exactly once out of the blue. And I think it was an unfortunate game bug. The rest of the time it’s been running as smooth and as perfect as the first time I ran the benchmark. Framerate is completely fine and way over the 0 frames per second I got on Windows because it wouldn’t run. The only problem seems to be that when I finish playing and exit to the desktop, Steam is unable to stop the game completely for some reason (I don’t know the cause) and it shows up as still running. I usually click on the Stop button in the Steam interface after a few seconds, it stops the game and that’s it. No problem synchronizing game saves to the cloud or anything. Just that small bug that, again, only requires a single extra click.

2023-12-10 UPDATE: From Mastodon, Jaco G and Berto Garcia tell me the game not stopping problem is present in all Ubisoft games and is directly related to the Ubisoft launcher. It keeps running after closing the game, which makes Steam think the game is still running. You can try to close it from the tray if you see the Ubisoft icon there and, if that fails, you can stop the game like I described above.

Then I remember something that had happened a few months before, prior to starting to play Doom Eternal under Windows. I had tried to play Deathloop first, another game in my backlog. However, the game crashed every few minutes and an error window popped up. The amount and timing of the crashes didn’t look constant, and lowering the graphics settings sometimes would allow me to play the game a bit longer, but in any case I wasn’t able to finish the game intro level without crashes and being very annoyed. Searching for the error message on the web, I saw it looked like a game problem that was apparently affecting not only AMD users, but also NVIDIA ones, so I had mentally classified that as a game bug and, similarly to the Far Cry 6 case, I had given up on running the game without refunding it hoping to be able to play it in the future.

Now I was wondering if it was really a game bug and, even if it was, if maybe Proton could have a workaround for it and maybe it could be played on Linux. Again, ProtonDB showed the game to be verified on the Deck with encouraging recent reports. So I installed Deathloop on Linux, launched it just once and played for 20 minutes or so. No crashes and I got as far as I had gotten on Windows in the intro level. Again, no graphical glitches that I could see, smooth framerates, etc. Maybe it was a coincidence and I was lucky, but I think I will be able to play the game without issues when I’m done with Far Cry 6.

In conclusion, this story is another data point that tells us the quality of Proton as a product and software compatibility layer is outstanding. In combination with some high quality open source Mesa drivers like RADV, I’m amazed the experience can be actually better than gaming natively on Windows. Think about that: the Windows game binary running natively on a DX12 or Vulkan official driver crashes more and doesn’t work as well as the game running on top of a Windows compatibility layer with a graphics API translation layer, on top of a different OS kernel and a different Vulkan driver. Definitely amazing to me and it speaks wonders of the work Valve has been doing on Linux. Or it could also speak badly of AMD Windows drivers, or both.

Sure, some new games on launch have more compatibility issues, bugs that need fixing, maybe workarounds applied in Proton, etc. But even in those cases, if you have a bit of patience, play the game some months down the line and check ProtonDB first (ideally before buying the game), you may be in for a great experience. You don’t need to be an expert either. Not to mention that some of these details are even better and smoother if you use a Steam Deck as compared to an (officially) unsupported Linux distribution like I do.