Writing own widgets
This article is for awesome git master / 3.5. It does not work with awesome 3.4
With awesome 3.5 it becomes possible to write your own widgets, without (ab)using the imagebox widget. We will do this by writing a widget that shows a simple cross in the wibox' foreground color.
local mycross = wibox.widget.base.make_widget() mycross.fit = function(mycross, width, height) local size = math.min(width, height) return size, size end mycross.draw = function(mycross, wibox, cr, width, height) cr:move_to(0, 0) cr:line_to(width, height) cr:move_to(width, 0) cr:line_to(0, height) cr:set_line_width(3) cr:stroke() end
That's it. We just needed to write two functions and now we got a simple widget which displays a cross.
What the heck does it do?
Our widget consists of just two functions. Isn't that really easy?
The fit() function
The first function is called fit. It is called whenever the widget needs to decide how large it should be. This function gets three arguments: - The widget itself - The available width - The available height
Based on this information, this function has to decide how large the widget should be. In the example above, we just decide that the widget should be quadratic and its size should be the smaller one of the available width and height.
Please note that the fit function's result is only a hint and the widget may be drawn at different sizes, depending on the layout used. Some layouts don't even call the fit function at all. This means that your fit function should not do any important calculations and should not change any state.
The draw() function
The other function is called draw. Obviously, it gets called to actually draw the widget. The arguments to this function are: - Again, the widget itself - The wibox or titlebar that the widget is being painted to - A cairo context that should be used for drawing the widget - The available width and height that the widget got allocated
The widget should then draw itself to the given cairo context in the area between the top-left corner (0, 0) and the bottom right corner at (width, height). The above example just draws a cross in this area. Please refer to cairo's documentation for more information about the available functions.
Notice that we did not specify any color for our cross. Which color gets used in this case? It is the wibox' foreground color. This is of course a nice thing and you should avoid setting specific colors in your own widgets, when possible.
Also, we did not draw any background for the widget. The widget's background is automatically filled with the wibox' background color. This means that your own widgets shouldn't draw their own background if they don't really have to.
Redrawing the widget
There is one last thing that is missing. Let's say we are writing an actual widget, for example a battery widget. How can the widget be forced to redraw itself?
This is as easy as mycross:emit_signal("widget::updated").
Know you should know enough so that you can write your own widgets. Have fun!
For more examples on cairo's API, you can read https://github.com/pavouk/lgi/blob/master/samples/cairo.lua and http://cairographics.org/manual/.