diff --git a/examples/cpu.lua b/examples/cpu.lua index dbf00f8..39dc249 100644 --- a/examples/cpu.lua +++ b/examples/cpu.lua @@ -71,6 +71,7 @@ local conkyrc = conky or {} conkyrc.config = { lua_load = script_dir .. "cpu.lua", lua_startup_hook = "conky_setup", + lua_draw_hook_pre = "conky_paint_background", lua_draw_hook_post = "conky_update", update_interval = 1, diff --git a/examples/graphs.lua b/examples/graphs.lua index 0a89399..1b2b18b 100644 --- a/examples/graphs.lua +++ b/examples/graphs.lua @@ -52,6 +52,7 @@ local conkyrc = conky or {} conkyrc.config = { lua_load = script_dir .. "graphs.lua", lua_startup_hook = "conky_setup", + lua_draw_hook_pre = "conky_paint_background", lua_draw_hook_post = "conky_update", update_interval = 1, diff --git a/examples/text.lua b/examples/text.lua index aa8b492..15b1ab7 100644 --- a/examples/text.lua +++ b/examples/text.lua @@ -73,6 +73,7 @@ local conkyrc = conky or {} conkyrc.config = { lua_load = script_dir .. "text.lua", lua_startup_hook = "conky_setup", + lua_draw_hook_pre = "conky_paint_background", lua_draw_hook_post = "conky_update", update_interval = 1, diff --git a/src/widget.lua b/src/widget.lua index 234380a..9b225c8 100644 --- a/src/widget.lua +++ b/src/widget.lua @@ -82,6 +82,9 @@ function Renderer:init(args) self._background_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, args.width, args.height) + self._main_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + args.width, + args.height) end --- Layout all Widgets and cache their backgrounds. @@ -91,57 +94,62 @@ function Renderer:layout() local widgets = self._root:layout(self._width, self._height) or {} table.insert(widgets, 1, {self._root, 0, 0, self._width, self._height}) - local background_widgets = {} + self._background_widgets = {} self._update_widgets = {} self._render_widgets = {} - for widget, x, y in util.imap(unpack, widgets) do - local matrix = cairo_matrix_t:create() - cairo_matrix_init_translate(matrix, floor(x), floor(y)) + for widget, x, y, _width, _height in util.imap(unpack, widgets) do if widget.render_background then - table.insert(background_widgets, {widget, matrix}) + local wsr = cairo_surface_create_for_rectangle(self._background_surface, + floor(x),floor(y),floor(_width),floor(_height)) + table.insert(self._background_widgets, {widget, wsr}) end if widget.render then - table.insert(self._render_widgets, {widget, matrix}) + local wsr = cairo_surface_create_for_rectangle(self._main_surface, + floor(x),floor(y),floor(_width),floor(_height)) + local wcr = cairo_create(wsr) + table.insert(self._render_widgets, {widget, wsr}) end if widget.update then table.insert(self._update_widgets, widget) end end - local cr = cairo_create(self._background_surface) + local bcr = cairo_create(self._background_surface) -- clear surface - cairo_save(cr) - cairo_set_source_rgba(cr, 0, 0, 0, 0) - cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE) - cairo_paint(cr) - cairo_restore(cr) + cairo_save(bcr) + cairo_set_source_rgba(bcr, 0, 0, 0, 0) + cairo_set_operator(bcr, CAIRO_OPERATOR_SOURCE) + cairo_paint(bcr) + cairo_restore(bcr) - cairo_save(cr) - for widget, matrix in util.imap(unpack, background_widgets) do - cairo_set_matrix(cr, matrix) - widget:render_background(cr) + -- render to backgrounds to surface + for widget, wsr in util.imap(unpack, self._background_widgets) do + local wcr = cairo_create(wsr) + cairo_save(wcr) + widget:render_background(wcr) + cairo_restore(wcr) + cairo_destroy(wcr) end - cairo_restore(cr) if DEBUG then local version_info = table.concat{"conky ", conky_version, " ", _VERSION, " cairo ", cairo_version_string()} - cairo_set_source_rgba(cr, 1, 0, 0, 1) - ch.set_font(cr, "Ubuntu", 8) - ch.write_left(cr, 0, 8, version_info) + cairo_set_source_rgba(bcr, 1, 0, 0, 1) + bcr.set_font(bcr, "Ubuntu", 8) + bcr.write_left(bcr, 0, 8, version_info) for _, x, y, width, height in util.imap(unpack, widgets) do if width * height ~= 0 then - cairo_rectangle(cr, x, y, width, height) + cairo_rectangle(bcr, x, y, width, height) end end - cairo_set_line_width(cr, 1) - cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE) - cairo_set_source_rgba(cr, 1, 0, 0, 0.33) - cairo_stroke(cr) + cairo_set_line_width(bcr, 1) + cairo_set_antialias(bcr, CAIRO_ANTIALIAS_NONE) + cairo_set_source_rgba(bcr, 1, 0, 0, 0.33) + cairo_stroke(bcr) end - cairo_destroy(cr) + cairo_destroy(bcr) end --- Update all Widgets @@ -157,17 +165,33 @@ function Renderer:update(update_count) end function Renderer:paint_background(cr) - cairo_set_source_surface(cr, self._background_surface, 0, 0) + cairo_set_source_surface(cr, self._main_surface, 0, 0) cairo_paint(cr) end --- Render to the given context -- @tparam cairo_t cr function Renderer:render(cr) - for widget, matrix in util.imap(unpack, self._render_widgets) do - cairo_set_matrix(cr, matrix) - widget:render(cr) - end + -- It doesn't render without these two lines + cairo_set_source_surface(cr, self._main_surface, 0, 0) + cairo_paint(cr) + mcr = cairo_create(self._main_surface) + cairo_save(mcr) + -- Clear previous render for transparent widgets + cairo_set_source_rgba(mcr, 0, 0, 0, 0) + cairo_set_operator(mcr, CAIRO_OPERATOR_SOURCE) + cairo_paint(mcr) + cairo_restore(mcr) + -- Overlay background surface + cairo_set_operator(mcr, CAIRO_OPERATOR_OVER); + cairo_set_source_surface(mcr, self._background_surface, 0, 0); + -- render forground widgets + for widget, wsr in util.imap(unpack, self._render_widgets) do + local wcr = cairo_create(wsr) + widget:render(wcr) + cairo_destroy(wcr) + end + cairo_paint(mcr); end