loading...
Cover image for "Reading mode" for i3

"Reading mode" for i3

kantord profile image Daniel Kantor ・2 min read

After reading about the benefits of using your phone in grayscale mode, I wanted to try it on my computer too.

Grayscale mode in the browser

I started by creating a userstyle with the following content:

html {
    filter: grayscale() !important;
}

this actually worked great! It is blazing fast on most websites, and it's even applied to things like videos!

The problems started to arise when I realized that on websites that my laptop is getting louder than usual when I'm using websites that are already somewhat resource-intensive, like YouTube. Besides, there was a noticeable framerate drop in videos!

I tried several of the already existing browser plugins that aim to implement this, but they had the same performance issues.

That's not a price I wanted to pay for this feature.

Compton GLX shaders

When I was setting up compton as my compositor for i3, I noticed that it has a weird flag that I'm not using:

--glx-fshader-win SHADER
  GLX backend: Use specified GLSL fragment shader for rendering window contents. See compton-default-fshader-win.glsl
  and compton-fake-transparency-fshader-win.glsl in the source tree for examples.

I have no idea about how shaders work, but I figured if it can be used in compton-fake-transparency-fshader-win, it might be useful for a color filter too.

After Googling some examples, I figured something like this should work for a shader:

uniform sampler2D tex;

void main() {
   vec4 c = texture2D(tex, gl_TexCoord[0].xy);
   float y = dot(c.rgb, vec3(0.299, 0.587, 0.114));
   vec4 gray = vec4(y, y, y, 1.0);
   gl_FragColor = mix(c, gray, 0.95);

}

I chose to drastically desaturate the image rather than turning it completely grayscale. This way, colors are displayed in a very very subtle way.

I passed that shader to compton --glx-fshader-win, and it works!

Alt Text

Not only I haven't experienced any performance drop this way, but as an added benefit, I now have a reading mode in my entire OS, not just the browser. I can even play games in grayscale mode!

I created this shell script so that I can easily turn it on and off through keybinding.

#!/usr/bin/env bash

 #Define shader
GRAYSCALE=$(cat <<-END
uniform sampler2D tex;
void main() {
   vec4 c = texture2D(tex, gl_TexCoord[0].xy);
   float y = dot(c.rgb, vec3(0.299, 0.587, 0.114));
   vec4 gray = vec4(y, y, y, 1.0);
   gl_FragColor = mix(c, gray, 0.95);
}
END
)

# Restart compton with the selected mode
killall -q compton
if [[ $MODE == "grayscale" ]]; then
   compton "$@" --glx-fshader-win "$GRAYSCALE" --backend glx
else
   compton "$@"
fi

You can grab that script from GitHub:

compton-grayscale-reading-mode

This script implements a reading mode/grayscale mode in i3 window manager and other window managers using compton.

The level of desaturation is 95%, so there is still some color present, but it's desaturated to a very large degree. This has no effect on your wallpaper: I recommend setting a black wallpaper using hsetroot.

In grayscale mode, backend is always glx.

Usage

compton-grayscale-reading-mode is a wrapper around compton. Any command line arguments are passed along to compton.

Any running compton instances are killed, therefore this script can be used to switch grayscale mode on and off.

Enable grayscale mode

MODE=grayscale compton.sh

Disable grayscale mode

MODE=normal compton.sh

Discussion

pic
Editor guide