Writing own widgets

From awesome
Jump to: navigation, search
Time machine.pngThis page contains version-specific content
Code or instructions listed here may not work for all versions of Awesome.
You can help the community by creating pages for other versions.
Proven working in: 3.5

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.

Full code[edit]

   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?[edit]

Our widget consists of just two functions. Isn't that really easy?

The fit() function[edit]

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[edit]

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[edit]

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").

Now you should know enough so that you can write your own widgets. Have fun!

Further reading[edit]

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/.