drawable: Use a context table as first argument to :draw()

This table contains the drawable, wibox and titlebar that we are drawing on, but
also includes the screen and the DPI of that screen. This allows widgets to
depend on the DPI in their rendering.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2015-08-08 13:13:47 +02:00
parent e5a9eef157
commit 31b69dbe1a
4 changed files with 47 additions and 6 deletions

View File

@ -76,7 +76,11 @@ local function new(c, args)
local ret local ret
if not bars[position] then if not bars[position] then
ret = drawable(d, nil, "awful.titlebar") local context = {
client = c,
position = position
}
ret = drawable(d, context, "awful.titlebar")
local function update_colors() local function update_colors()
local args = bars[position].args local args = bars[position].args
ret:set_bg(get_color("bg", c, args)) ret:set_bg(get_color("bg", c, args))

View File

@ -24,6 +24,43 @@ local timer = require("gears.timer")
local drawables = setmetatable({}, { __mode = 'k' }) local drawables = setmetatable({}, { __mode = 'k' })
local wallpaper = nil local wallpaper = nil
-- This is awful.screen.getbycoord() which we sadly cannot use from here (cyclic
-- dependencies are bad!)
function screen_getbycoord(x, y)
for i = 1, screen:count() do
local geometry = screen[i].geometry
if x >= geometry.x and x < geometry.x + geometry.width
and y >= geometry.y and y < geometry.y + geometry.height then
return i
end
end
return 1
end
-- Get the widget context. This should always return the same table (if
-- possible), so that our draw and fit caches can work efficiently.
local function get_widget_context(self)
local geom = self.drawable:geometry()
local s = screen_getbycoord(geom.x, geom.y)
local context = self._widget_context
local dpi = beautiful.xresources.get_dpi(s)
if (not context) or context.screen ~= s or context.dpi ~= dpi then
context = {
screen = s,
dpi = dpi,
drawable = self,
widget_at = function(_, ...)
self:widget_at(...)
end
}
for k, v in pairs(self._widget_context_skeleton) do
context[k] = v
end
self._widget_context = context
end
return context
end
local function do_redraw(self) local function do_redraw(self)
local surf = surface(self.drawable.surface) local surf = surface(self.drawable.surface)
-- The surface can be nil if the drawable's parent was already finalized -- The surface can be nil if the drawable's parent was already finalized
@ -59,7 +96,7 @@ local function do_redraw(self)
self._widget_geometries = {} self._widget_geometries = {}
if self.widget and self.widget.visible then if self.widget and self.widget.visible then
cr:set_source(self.foreground_color) cr:set_source(self.foreground_color)
self.widget:draw(self.widget_arg, cr, width, height) self.widget:draw(get_widget_context(self), cr, width, height)
self:widget_at(self.widget, 0, 0, width, height) self:widget_at(self.widget, 0, 0, width, height)
end end
@ -229,10 +266,10 @@ local function setup_signals(_drawable)
clone_signal("property::y") clone_signal("property::y")
end end
function drawable.new(d, widget_arg, drawable_name) function drawable.new(d, widget_context_skeleton, drawable_name)
local ret = object() local ret = object()
ret.drawable = d ret.drawable = d
ret.widget_arg = widget_arg or ret ret._widget_context_skeleton = widget_context_skeleton
setup_signals(ret) setup_signals(ret)
for k, v in pairs(drawable) do for k, v in pairs(drawable) do

View File

@ -108,7 +108,7 @@ local function new(args)
local ret = object() local ret = object()
local w = capi.drawin(args) local w = capi.drawin(args)
ret.drawin = w ret.drawin = w
ret._drawable = wibox.drawable(w.drawable, ret, ret._drawable = wibox.drawable(w.drawable, { wibox = ret },
"wibox drawable (" .. object.modulename(3) .. ")") "wibox drawable (" .. object.modulename(3) .. ")")
for k, v in pairs(wibox) do for k, v in pairs(wibox) do

View File

@ -41,7 +41,7 @@ function systray:draw(wibox, cr, width, height)
else else
base = in_dir / num_entries base = in_dir / num_entries
end end
capi.awesome.systray(wibox.drawin, math.ceil(x), math.ceil(y), capi.awesome.systray(wibox.wibox.drawin, math.ceil(x), math.ceil(y),
base, is_rotated, bg, reverse, spacing) base, is_rotated, bg, reverse, spacing)
end end