Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Widget Rendering Sandboxing #14

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/cpu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions examples/graphs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions examples/text.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
86 changes: 55 additions & 31 deletions src/widget.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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


Expand Down