In awesome wm 3.5 you can create custom widgets using cairo to draw its visual. I want a widget which displays monochrome PNG icon (like wibox.widget.imagebox do it) and allows quickly change its color. I tried modify several lines in draw function of wibox.widget.imagebox
local cairo = require("lgi").cairo
--- Draw an imagebox with the given cairo context in the given geometry.
function imagebox:draw(wibox, cr, width, height)
if not self._image then return end
if width == 0 or height == 0 then return end
cr:save()
if not self.resize_forbidden then
-- Let's scale the image so that it fits into (width, height)
local w = self._image:get_width()
local h = self._image:get_height()
local aspect = width / w
local aspect_h = height / h
if aspect > aspect_h then aspect = aspect_h end
cr:scale(aspect, aspect)
end
-- Here is my modifications
cr:set_source_surface(self._image, 0, 0)
cr:paint()
cr:set_operator(cairo.Operator.IN)
cr:set_source_rgba(0, 0, 1, 0.5)
cr:paint()
-- End of my my modifications
-- This is original draw code how it was
--cr:set_source_surface(self._image, 0, 0)
--cr:paint()
cr:restore()
end
But it doesn't work. I tried set several other cairo's compositing operators and most of them works not as expected. Wrong overlapping areas and black regions instead of wibox background color. SOURCE and OVER are only works right. Where did I make mistake?
The mistake is your understanding of cairo's drawing methods. Black/transparent is just what IN leaves behind in the places that it did not touch. In other words, you are first drawing something else over the background and thus the background is lost.
Try this instead:
local pat = require("lgi").cairo.Pattern
cr:set_source_rgba(0, 0, 1, 0.5)
cr:mask(pat.create_for_surface(self._image), 0, 0)