Search code examples
awesome-wm

Anti-aliasing in the awesome window manager


Ok so basically, can we somehow get anti-aliasing in the awesome window manager?

The fonts look amazing and everything but it would be really nice to have anti-aliasing applied to regular widgets in awesome. Anti-aliased round-cornered titlebars would be amazing. Also the other shapes applied to widgets like gears.shape.rounded_rect or gears.shape.circle. Or all of the others that have rounded anything.

Is it even possible? I searched for cairo and anti aliasing and I barely found anything and even the people that said something said that it's really hard or just not possible to get really good anti aliasing in cairo.

Also, I looked through an old copy of the awesome-wm repository and at some point I found this in the draw.c file:

draw_rectangle_gradient(draw_context_t *ctx, area_t geometry, float line_width, bool filled,
                        vector_t gradient_vector, const color_t *pcolor,
                        const color_t *pcolor_center, const color_t *pcolor_end)
{
    cairo_pattern_t *pat;

    cairo_set_antialias(ctx->cr, CAIRO_ANTIALIAS_NONE);
    cairo_set_line_width(ctx->cr, line_width);
    cairo_set_miter_limit(ctx->cr, 10.0);
cairo_set_line_join(ctx->cr, CAIRO_LINE_JOIN_MITER);

Now in the current repository I was not able to find anything like this, so my question is "can we users do something to make the rounded shapes in awesome be anti-aliased?"

EDIT: If there is not an easy way, could you direct me into what the changes required would be to make this work?


Solution

  • Anti-aliased round-cornered titlebars would be amazing

    Non-rectangular windows are done in X11 with the SHAPE extension. This extension only allows "this pixel is in the window" or "this pixel is outside of the window". Thus, no anti-aliasing is possible here. https://www.x.org/releases/X11R7.7/doc/xextproto/shape.html

    However, when you have a compositing manager running, one can add an alpha channel to a window. This allows things to be e.g. 50% translucent. Thus, with this, an alpha channel is possible.

    So, in AwesomeWM, you could do a outside-rounded border around a client by setting border width to zero and instead adding a titlebar on each side of the client that contains some "real transparency".

    A cheap example that does not actually do rounded corners, but shows transparency:

    local my_widget = wibox.widget.base.make_widget()
    local cairo = require("lgi").cairo
    function my_widget:draw(_, cr, width, height)
        cr:set_operator(cairo.Operator.SOURCE)
        cr:set_source(gears.color.create_linear_pattern{
            from = { 0, 0 },
            to = { width, 0 },
            stops = {
                { 0, "#f000" },
                { 1, "#0f0f" },
            },
        })
        cr:paint()
    end
    awful.titlebar(c, { position = "bottom" }):set_widget(my_widget)
    

    window with partially transparent titlebar on the bottom

    In this way, one could do a titlebar that draws a rounded corner in an anti-aliased way. However, this would require doing things in multiple pieces, because we need to create each titlebar separately.

    Also, this can only do a rounded corner on the outside. On the inside (i.e. towards the actual client content), AwesomeWM only provides access to the shape extension. However, we would have to draw something on the actual client window to have an antialiased rounded corner. This is currently not possible.

    (I hope this paragraph can be understood. Somehow I feel like it is hard to describe/understand.)

    Also the other shapes applied to widgets like gears.shape.rounded_rect or gears.shape.circle.

    Well... I'm not sure why you think that there is no antialiasing here.

    local w = wibox{ x = 10, y = 10, height = 300, width = 300 }
    w:setup {
        widget = wibox.container.background,
        bg = '#f00',
        {
            widget = wibox.container.background,
            shape = gears.shape.circle,
            bg = '#0f0',
        }
    }
    w.visible = true
    

    A zoom into the resulting image clearly shows antialiasing:

    enter image description here

    Or all of the others that have rounded anything.

    This is actually not specific to the shape, but to the thing that applies the shape. For example wibox.container.background (which "draws directly" and thus can do antialiasing) versus awful.client.shape (which uses the X11 shape extension and thus cannot do antialiasing).