From d122b825ee3ebdf66399998e13a234415ad58185 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 8 Aug 2015 13:08:21 +0200 Subject: [PATCH 1/5] gears.timer: Fix the traceback on errors With the second argument being 2, the traceback will not include the error handling function, but instead end at the actual place of the error. Signed-off-by: Uli Schlachter --- lib/gears/timer.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gears/timer.lua b/lib/gears/timer.lua index cda03b3b6..135f95794 100644 --- a/lib/gears/timer.lua +++ b/lib/gears/timer.lua @@ -109,7 +109,7 @@ capi.awesome.connect_signal("refresh", function() local success, message = xpcall(function() callback[1](unpack(callback, 2)) end, function(err) - print(debug.traceback("Error during delayed call: "..tostring(err))) + print(debug.traceback("Error during delayed call: "..tostring(err), 2)) end) end delayed_calls = {} From e5a9eef1574a24074f7e05ead887b29ae2251be4 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 8 Aug 2015 13:09:25 +0200 Subject: [PATCH 2/5] Widget drawing: Add a traceback on errors Signed-off-by: Uli Schlachter --- lib/wibox/layout/base.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/wibox/layout/base.lua b/lib/wibox/layout/base.lua index 97e939661..3842a6b67 100644 --- a/lib/wibox/layout/base.lua +++ b/lib/wibox/layout/base.lua @@ -6,7 +6,7 @@ --------------------------------------------------------------------------- local pairs = pairs -local pcall = pcall +local xpcall = xpcall local print = print local min = math.min local max = math.max @@ -67,10 +67,11 @@ function base.draw_widget(wibox, cr, widget, x, y, width, height) cr:clip() -- Let the widget draw itself - local success, msg = pcall(widget.draw, widget, wibox, cr, width, height) - if not success then - print("Error while drawing widget: " .. msg) - end + xpcall(function() + widget:draw(wibox, cr, width, height) + end, function(err) + print(debug.traceback("Error while drawing widget: "..tostring(err), 2)) + end) -- Register the widget for input handling wibox:widget_at(widget, base.rect_to_device_geometry(cr, 0, 0, width, height)) From 31b69dbe1a48f60aff54808fc434accf227ad743 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 8 Aug 2015 13:13:47 +0200 Subject: [PATCH 3/5] 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 --- lib/awful/titlebar.lua | 6 ++++- lib/wibox/drawable.lua | 43 +++++++++++++++++++++++++++++++++--- lib/wibox/init.lua | 2 +- lib/wibox/widget/systray.lua | 2 +- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/lib/awful/titlebar.lua b/lib/awful/titlebar.lua index d0249147e..e7ab8d99b 100644 --- a/lib/awful/titlebar.lua +++ b/lib/awful/titlebar.lua @@ -76,7 +76,11 @@ local function new(c, args) local ret 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 args = bars[position].args ret:set_bg(get_color("bg", c, args)) diff --git a/lib/wibox/drawable.lua b/lib/wibox/drawable.lua index c9d0a483d..8176b8ce3 100644 --- a/lib/wibox/drawable.lua +++ b/lib/wibox/drawable.lua @@ -24,6 +24,43 @@ local timer = require("gears.timer") local drawables = setmetatable({}, { __mode = 'k' }) 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 surf = surface(self.drawable.surface) -- 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 = {} if self.widget and self.widget.visible then 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) end @@ -229,10 +266,10 @@ local function setup_signals(_drawable) clone_signal("property::y") end -function drawable.new(d, widget_arg, drawable_name) +function drawable.new(d, widget_context_skeleton, drawable_name) local ret = object() ret.drawable = d - ret.widget_arg = widget_arg or ret + ret._widget_context_skeleton = widget_context_skeleton setup_signals(ret) for k, v in pairs(drawable) do diff --git a/lib/wibox/init.lua b/lib/wibox/init.lua index efbbef965..5ea72c748 100644 --- a/lib/wibox/init.lua +++ b/lib/wibox/init.lua @@ -108,7 +108,7 @@ local function new(args) local ret = object() local w = capi.drawin(args) ret.drawin = w - ret._drawable = wibox.drawable(w.drawable, ret, + ret._drawable = wibox.drawable(w.drawable, { wibox = ret }, "wibox drawable (" .. object.modulename(3) .. ")") for k, v in pairs(wibox) do diff --git a/lib/wibox/widget/systray.lua b/lib/wibox/widget/systray.lua index f2afefced..1414cd756 100644 --- a/lib/wibox/widget/systray.lua +++ b/lib/wibox/widget/systray.lua @@ -41,7 +41,7 @@ function systray:draw(wibox, cr, width, height) else base = in_dir / num_entries 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) end From 88b98789a055616aece6df5422dcbedf1dadd4e0 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 8 Aug 2015 13:18:54 +0200 Subject: [PATCH 4/5] Rename the first argument to :draw to "context" Signed-off-by: Uli Schlachter --- lib/awful/widget/graph.lua | 2 +- lib/awful/widget/progressbar.lua | 2 +- lib/wibox/layout/align.lua | 12 ++++++------ lib/wibox/layout/base.lua | 9 +++++---- lib/wibox/layout/constraint.lua | 4 ++-- lib/wibox/layout/fixed.lua | 6 +++--- lib/wibox/layout/flex.lua | 6 +++--- lib/wibox/layout/margin.lua | 4 ++-- lib/wibox/layout/mirror.lua | 8 +++----- lib/wibox/layout/rotate.lua | 6 +++--- lib/wibox/widget/background.lua | 4 ++-- lib/wibox/widget/imagebox.lua | 2 +- lib/wibox/widget/systray.lua | 4 ++-- lib/wibox/widget/textbox.lua | 2 +- 14 files changed, 35 insertions(+), 36 deletions(-) diff --git a/lib/awful/widget/graph.lua b/lib/awful/widget/graph.lua index abe464fbe..a1252fadd 100644 --- a/lib/awful/widget/graph.lua +++ b/lib/awful/widget/graph.lua @@ -69,7 +69,7 @@ local properties = { "width", "height", "border_color", "stack", "stack_colors", "color", "background_color", "max_value", "scale" } -function graph.draw(_graph, wibox, cr, width, height) +function graph.draw(_graph, context, cr, width, height) local max_value = data[_graph].max_value local values = data[_graph].values diff --git a/lib/awful/widget/progressbar.lua b/lib/awful/widget/progressbar.lua index e85d1d951..1e92326ab 100644 --- a/lib/awful/widget/progressbar.lua +++ b/lib/awful/widget/progressbar.lua @@ -71,7 +71,7 @@ local properties = { "width", "height", "border_color", "vertical", "value", "max_value", "ticks", "ticks_gap", "ticks_size" } -function progressbar.draw(pbar, wibox, cr, width, height) +function progressbar.draw(pbar, context, cr, width, height) local ticks_gap = data[pbar].ticks_gap or 1 local ticks_size = data[pbar].ticks_size or 4 diff --git a/lib/wibox/layout/align.lua b/lib/wibox/layout/align.lua index de4682e9e..3b6d4431d 100644 --- a/lib/wibox/layout/align.lua +++ b/lib/wibox/layout/align.lua @@ -16,11 +16,11 @@ local widget_base = require("wibox.widget.base") local align = {} --- Draw an align layout. --- @param wibox The wibox that this widget is drawn to. +-- @param context The context in which we are drawn. -- @param cr The cairo context to use. -- @param width The available width. -- @param height The available height. -function align:draw(wibox, cr, width, height) +function align:draw(context, cr, width, height) -- Draw will have to deal with all three align modes and should work in a -- way that makes sense if one or two of the widgets are missing (if they -- are all missing, it won't draw anything.) It should also handle the case @@ -42,7 +42,7 @@ function align:draw(wibox, cr, width, height) -- if all the space is taken, skip the rest, and draw just the middle -- widget if size_second >= size_remains then - base.draw_widget(wibox, cr, self.second, 0, 0, width, height) + base.draw_widget(context, cr, self.second, 0, 0, width, height) return else -- the middle widget is sized first, the outside widgets are given @@ -81,7 +81,7 @@ function align:draw(wibox, cr, width, height) w = size_remains end end - base.draw_widget(wibox, cr, self.first, 0, 0, w, h) + base.draw_widget(context, cr, self.first, 0, 0, w, h) end -- size_remains will be <= 0 if first used all the space if self.third and size_remains > 0 then @@ -107,7 +107,7 @@ function align:draw(wibox, cr, width, height) end end local x, y = width - w, height - h - base.draw_widget(wibox, cr, self.third, x, y, w, h) + base.draw_widget(context, cr, self.third, x, y, w, h) end -- here we either draw the second widget in the space set aside for it -- in the beginning, or in the remaining space, if it is "inside" @@ -130,7 +130,7 @@ function align:draw(wibox, cr, width, height) x = floor( (width -w)/2 ) end end - base.draw_widget(wibox, cr, self.second, x, y, w, h) + base.draw_widget(context, cr, self.second, x, y, w, h) end end diff --git a/lib/wibox/layout/base.lua b/lib/wibox/layout/base.lua index 3842a6b67..117cafd7f 100644 --- a/lib/wibox/layout/base.lua +++ b/lib/wibox/layout/base.lua @@ -45,17 +45,18 @@ function base.fit_widget(widget, width, height) end --- Draw a widget via a cairo context --- @param wibox The wibox on which we are drawing +-- @param context The context in which we are drawn. -- @param cr The cairo context used -- @param widget The widget to draw (this uses widget:draw(cr, width, height)). -- @param x The position that the widget should get -- @param y The position that the widget should get -- @param width The widget's width -- @param height The widget's height -function base.draw_widget(wibox, cr, widget, x, y, width, height) +function base.draw_widget(context, cr, widget, x, y, width, height) if not widget.visible then return end + -- Use save() / restore() so that our modifications aren't permanent cr:save() @@ -68,13 +69,13 @@ function base.draw_widget(wibox, cr, widget, x, y, width, height) -- Let the widget draw itself xpcall(function() - widget:draw(wibox, cr, width, height) + widget:draw(context, cr, width, height) end, function(err) print(debug.traceback("Error while drawing widget: "..tostring(err), 2)) end) -- Register the widget for input handling - wibox:widget_at(widget, base.rect_to_device_geometry(cr, 0, 0, width, height)) + context:widget_at(widget, base.rect_to_device_geometry(cr, 0, 0, width, height)) cr:restore() end diff --git a/lib/wibox/layout/constraint.lua b/lib/wibox/layout/constraint.lua index 34b552bd0..b4e0e3770 100644 --- a/lib/wibox/layout/constraint.lua +++ b/lib/wibox/layout/constraint.lua @@ -15,12 +15,12 @@ local math = math local constraint = { mt = {} } --- Draw a constraint layout -function constraint:draw(wibox, cr, width, height) +function constraint:draw(context, cr, width, height) if not self.widget then return end - base.draw_widget(wibox, cr, self.widget, 0, 0, width, height) + base.draw_widget(context, cr, self.widget, 0, 0, width, height) end --- Fit a constraint layout into the given space diff --git a/lib/wibox/layout/fixed.lua b/lib/wibox/layout/fixed.lua index 5329e1fd6..a5cce63be 100644 --- a/lib/wibox/layout/fixed.lua +++ b/lib/wibox/layout/fixed.lua @@ -13,12 +13,12 @@ local pairs = pairs local fixed = {} --- Draw a fixed layout. Each widget gets just the space it asks for. --- @param wibox The wibox that this widget is drawn to. +-- @param context The context in which we are drawn. -- @param cr The cairo context to use. -- @param width The available width. -- @param height The available height. -- @return The total space needed by the layout. -function fixed:draw(wibox, cr, width, height) +function fixed:draw(context, cr, width, height) local pos,spacing = 0,self._spacing or 0 for k, v in pairs(self.widgets) do @@ -46,7 +46,7 @@ function fixed:draw(wibox, cr, width, height) (self.dir ~= "y" and pos-spacing > width) then break end - base.draw_widget(wibox, cr, v, x, y, w, h) + base.draw_widget(context, cr, v, x, y, w, h) end end diff --git a/lib/wibox/layout/flex.lua b/lib/wibox/layout/flex.lua index 55107c9d0..a24af0be4 100644 --- a/lib/wibox/layout/flex.lua +++ b/lib/wibox/layout/flex.lua @@ -18,12 +18,12 @@ local function round(x) end --- Draw a flex layout. Each widget gets an equal share of the available space. --- @param wibox The wibox that this widget is drawn to. +-- @param context The context in which we are drawn. -- @param cr The cairo context to use. -- @param width The available width. -- @param height The available height. -- @return The total space needed by the layout. -function flex:draw(wibox, cr, width, height) +function flex:draw(context, cr, width, height) local pos,spacing = 0,self._spacing or 0 local num = #self.widgets local total_spacing = (spacing*(num-1)) @@ -48,7 +48,7 @@ function flex:draw(wibox, cr, width, height) x, y = round(pos), 0 w, h = floor(space_per_item), height end - base.draw_widget(wibox, cr, v, x, y, w, h) + base.draw_widget(context, cr, v, x, y, w, h) pos = pos + space_per_item + spacing diff --git a/lib/wibox/layout/margin.lua b/lib/wibox/layout/margin.lua index 2a1a0df36..7e164b50d 100644 --- a/lib/wibox/layout/margin.lua +++ b/lib/wibox/layout/margin.lua @@ -16,7 +16,7 @@ local cairo = require("lgi").cairo local margin = { mt = {} } --- Draw a margin layout -function margin:draw(wibox, cr, width, height) +function margin:draw(context, cr, width, height) local x = self.left local y = self.top local w = self.right @@ -37,7 +37,7 @@ function margin:draw(wibox, cr, width, height) cr:restore() end - base.draw_widget(wibox, cr, self.widget, x, y, width - x - w, height - y - h) + base.draw_widget(context, cr, self.widget, x, y, width - x - w, height - y - h) end --- Fit a margin layout into the given space diff --git a/lib/wibox/layout/mirror.lua b/lib/wibox/layout/mirror.lua index 78162d495..cace8c0bd 100644 --- a/lib/wibox/layout/mirror.lua +++ b/lib/wibox/layout/mirror.lua @@ -16,10 +16,8 @@ local widget_base = require("wibox.widget.base") local mirror = { mt = {} } --- Draw this layout -function mirror:draw(wibox, cr, width, height) - if not self.widget then - return { width = 0, height = 0 } - end +function mirror:draw(context, cr, width, height) + if not self.widget then return end if not self.horizontal and not self.vertical then base.draw_widget(wibox, cr, self.widget, 0, 0, width, height) return -- nothing changed @@ -40,7 +38,7 @@ function mirror:draw(wibox, cr, width, height) cr:translate(t.x, t.y) cr:scale(s.x, s.y) - self.widget:draw(wibox, cr, width, height) + self.widget:draw(context, cr, width, height) -- Undo the scale and translation from above. cr:restore() diff --git a/lib/wibox/layout/rotate.lua b/lib/wibox/layout/rotate.lua index 22d3c646b..3e687525b 100644 --- a/lib/wibox/layout/rotate.lua +++ b/lib/wibox/layout/rotate.lua @@ -25,9 +25,9 @@ local function transform(layout, width, height) end --- Draw this layout -function rotate:draw(wibox, cr, width, height) +function rotate:draw(context, cr, width, height) if not self.widget or not self.widget.visible then - return { width = 0, height = 0 } + return end local dir = self:get_direction() @@ -45,7 +45,7 @@ function rotate:draw(wibox, cr, width, height) -- Since we rotated, we might have to swap width and height. -- transform() does that for us. - base.draw_widget(wibox, cr, self.widget, 0, 0, transform(self, width, height)) + base.draw_widget(context, cr, self.widget, 0, 0, transform(self, width, height)) end --- Fit this layout into the given area diff --git a/lib/wibox/widget/background.lua b/lib/wibox/widget/background.lua index 8dd7f4354..940dff20d 100644 --- a/lib/wibox/widget/background.lua +++ b/lib/wibox/widget/background.lua @@ -17,7 +17,7 @@ local type = type local background = { mt = {} } --- Draw this widget -function background:draw(wibox, cr, width, height) +function background:draw(context, cr, width, height) if not self.widget or not self.widget.visible then return end @@ -40,7 +40,7 @@ function background:draw(wibox, cr, width, height) cr:save() cr:set_source(self.foreground) end - layout_base.draw_widget(wibox, cr, self.widget, 0, 0, width, height) + layout_base.draw_widget(context, cr, self.widget, 0, 0, width, height) if self.foreground then cr:restore() end diff --git a/lib/wibox/widget/imagebox.lua b/lib/wibox/widget/imagebox.lua index a8374372a..24a03cc94 100644 --- a/lib/wibox/widget/imagebox.lua +++ b/lib/wibox/widget/imagebox.lua @@ -16,7 +16,7 @@ local print = print local imagebox = { mt = {} } --- Draw an imagebox with the given cairo context in the given geometry. -function imagebox:draw(wibox, cr, width, height) +function imagebox:draw(context, cr, width, height) if not self._image then return end if width == 0 or height == 0 then return end diff --git a/lib/wibox/widget/systray.lua b/lib/wibox/widget/systray.lua index 1414cd756..1c692b05c 100644 --- a/lib/wibox/widget/systray.lua +++ b/lib/wibox/widget/systray.lua @@ -19,7 +19,7 @@ local horizontal = true local base_size = nil local reverse = false -function systray:draw(wibox, cr, width, height) +function systray:draw(context, cr, width, height) local x, y, _, _ = lbase.rect_to_device_geometry(cr, 0, 0, width, height) local num_entries = capi.awesome.systray() local bg = beautiful.bg_systray or beautiful.bg_normal or "#000000" @@ -41,7 +41,7 @@ function systray:draw(wibox, cr, width, height) else base = in_dir / num_entries end - capi.awesome.systray(wibox.wibox.drawin, math.ceil(x), math.ceil(y), + capi.awesome.systray(context.wibox.drawin, math.ceil(x), math.ceil(y), base, is_rotated, bg, reverse, spacing) end diff --git a/lib/wibox/widget/textbox.lua b/lib/wibox/widget/textbox.lua index c8096c533..6b99b16e2 100644 --- a/lib/wibox/widget/textbox.lua +++ b/lib/wibox/widget/textbox.lua @@ -27,7 +27,7 @@ local function setup_layout(box, width, height) end --- Draw the given textbox on the given cairo context in the given geometry -function textbox:draw(wibox, cr, width, height) +function textbox:draw(context, cr, width, height) cr:update_layout(self._layout) setup_layout(self, width, height) local ink, logical = self._layout:get_pixel_extents() From 1ebc34b5e9c31b82013ed7ef2c59716d31333267 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 8 Aug 2015 13:43:35 +0200 Subject: [PATCH 5/5] Widgets: Also add a context argument to :fit() Together with the context argument to :draw(), this even allows widgets to have DPI-dependant size. Signed-off-by: Uli Schlachter --- lib/awful/tooltip.lua | 2 +- lib/awful/widget/graph.lua | 2 +- lib/awful/widget/progressbar.lua | 2 +- lib/naughty/core.lua | 6 +++--- lib/wibox/layout/align.lua | 19 ++++++++++--------- lib/wibox/layout/base.lua | 5 +++-- lib/wibox/layout/constraint.lua | 4 ++-- lib/wibox/layout/fixed.lua | 9 +++++---- lib/wibox/layout/flex.lua | 5 +++-- lib/wibox/layout/margin.lua | 4 ++-- lib/wibox/layout/mirror.lua | 4 ++-- lib/wibox/layout/rotate.lua | 4 ++-- lib/wibox/widget/background.lua | 4 ++-- lib/wibox/widget/base.lua | 2 +- lib/wibox/widget/imagebox.lua | 2 +- lib/wibox/widget/systray.lua | 2 +- lib/wibox/widget/textbox.lua | 2 +- spec/wibox/test_utils.lua | 2 +- 18 files changed, 42 insertions(+), 38 deletions(-) diff --git a/lib/awful/tooltip.lua b/lib/awful/tooltip.lua index 2f4b12483..a308f0e49 100644 --- a/lib/awful/tooltip.lua +++ b/lib/awful/tooltip.lua @@ -83,7 +83,7 @@ end local function set_geometry(self) local my_geo = self.wibox:geometry() -- calculate width / height - local n_w, n_h = self.textbox:fit(-1, -1) + local n_w, n_h = self.textbox:fit(nil, -1, -1) -- Hack! :( n_w = n_w + self.marginbox.left + self.marginbox.right n_h = n_h + self.marginbox.top + self.marginbox.bottom if my_geo.width ~= n_w or my_geo.height ~= n_h then diff --git a/lib/awful/widget/graph.lua b/lib/awful/widget/graph.lua index a1252fadd..b5b4309c6 100644 --- a/lib/awful/widget/graph.lua +++ b/lib/awful/widget/graph.lua @@ -158,7 +158,7 @@ function graph.draw(_graph, context, cr, width, height) end end -function graph.fit(_graph, width, height) +function graph.fit(_graph) return data[_graph].width, data[_graph].height end diff --git a/lib/awful/widget/progressbar.lua b/lib/awful/widget/progressbar.lua index 1e92326ab..08d679238 100644 --- a/lib/awful/widget/progressbar.lua +++ b/lib/awful/widget/progressbar.lua @@ -154,7 +154,7 @@ function progressbar.draw(pbar, context, cr, width, height) end end -function progressbar.fit(pbar, width, height) +function progressbar.fit(pbar) return data[pbar].width, data[pbar].height end diff --git a/lib/naughty/core.lua b/lib/naughty/core.lua index bc6579f38..14d1a6b1b 100644 --- a/lib/naughty/core.lua +++ b/lib/naughty/core.lua @@ -526,7 +526,7 @@ function naughty.notify(args) actiontextbox:set_font(font) actiontextbox:set_markup(string.format('%s', action)) -- calculate the height and width - local w, h = actiontextbox:fit(-1, -1) + local w, h = actiontextbox:fit(nil, -1, -1) -- Hack! :( local height = h + 2 * margin local width = w + 2 * margin @@ -596,7 +596,7 @@ function naughty.notify(args) -- calculate the height if not height then - local w, h = textbox:fit(-1, -1) + local w, h = textbox:fit(nil, -1, -1) -- Hack! :-( if iconbox and icon_h + 2 * margin > h + 2 * margin then height = icon_h + 2 * margin else @@ -608,7 +608,7 @@ function naughty.notify(args) -- calculate the width if not width then - local w, h = textbox:fit(-1, -1) + local w, h = textbox:fit(nil, -1, -1) -- Hack! :-( width = w + (iconbox and icon_w + 2 * margin or 0) + 2 * margin end diff --git a/lib/wibox/layout/align.lua b/lib/wibox/layout/align.lua index 3b6d4431d..1a048b854 100644 --- a/lib/wibox/layout/align.lua +++ b/lib/wibox/layout/align.lua @@ -37,7 +37,7 @@ function align:draw(context, cr, width, height) -- if the second widget doesn't exist, we will prioritise the first one -- instead if self._expand ~= "inside" and self.second then - local w, h = base.fit_widget(self.second, width, height) + local w, h = base.fit_widget(context, self.second, width, height) local size_second = self.dir == "y" and h or w -- if all the space is taken, skip the rest, and draw just the middle -- widget @@ -57,7 +57,7 @@ function align:draw(context, cr, width, height) -- into the remaining space if self._expand ~= "outside" then if self.dir == "y" then - _, h = base.fit_widget(self.first, width, size_remains) + _, h = base.fit_widget(context, self.first, width, size_remains) size_first = h -- for "inside", the third widget will get a chance to use the -- remaining space, then the middle widget. For "none" we give @@ -68,7 +68,7 @@ function align:draw(context, cr, width, height) size_remains = size_remains - h end else - w, _ = base.fit_widget(self.first, size_remains, height) + w, _ = base.fit_widget(context, self.first, size_remains, height) size_first = w if self._expand == "inside" or not self.second then size_remains = size_remains - w @@ -88,13 +88,13 @@ function align:draw(context, cr, width, height) local w, h, _ = width, height, nil if self._expand ~= "outside" then if self.dir == "y" then - _, h = base.fit_widget(self.third, width, size_remains) + _, h = base.fit_widget(context, self.third, width, size_remains) -- give the middle widget the rest of the space for "inside" mode if self._expand == "inside" then size_remains = size_remains - h end else - w, _ = base.fit_widget(self.third, size_remains, height) + w, _ = base.fit_widget(context, self.third, size_remains, height) if self._expand == "inside" then size_remains = size_remains - w end @@ -123,10 +123,10 @@ function align:draw(context, cr, width, height) end else if self.dir == "y" then - _, h = base.fit_widget(self.second, width, size_remains) + _, h = base.fit_widget(context, self.second, width, size_remains) y = floor( (height - h)/2 ) else - w, _ = base.fit_widget(self.second, width, size_remains) + w, _ = base.fit_widget(context, self.second, width, size_remains) x = floor( (width -w)/2 ) end end @@ -166,14 +166,15 @@ end --- Fit the align layout into the given space. The align layout will -- ask for the sum of the sizes of its sub-widgets in its direction -- and the largest sized sub widget in the other direction. +-- @param context The context in which we are fit. -- @param orig_width The available width. -- @param orig_height The available height. -function align:fit(orig_width, orig_height) +function align:fit(context, orig_width, orig_height) local used_in_dir = 0 local used_in_other = 0 for k, v in pairs{self.first, self.second, self.third} do - local w, h = base.fit_widget(v, orig_width, orig_height) + local w, h = base.fit_widget(context, v, orig_width, orig_height) local max = self.dir == "y" and w or h if max > used_in_other then diff --git a/lib/wibox/layout/base.lua b/lib/wibox/layout/base.lua index 117cafd7f..8af64702e 100644 --- a/lib/wibox/layout/base.lua +++ b/lib/wibox/layout/base.lua @@ -29,11 +29,12 @@ function base.rect_to_device_geometry(cr, x, y, width, height) end --- Fit a widget for the given available width and height +-- @param context The context in which we are fit. -- @param widget The widget to fit (this uses widget:fit(width, height)). -- @param width The available width for the widget -- @param height The available height for the widget -- @return The width and height that the widget wants to use -function base.fit_widget(widget, width, height) +function base.fit_widget(context, widget, width, height) if not widget.visible then return 0, 0 end @@ -41,7 +42,7 @@ function base.fit_widget(widget, width, height) local width = math.max(0, width) local height = math.max(0, height) - return widget._fit_geometry_cache:get(width, height) + return widget._fit_geometry_cache:get(context, width, height) end --- Draw a widget via a cairo context diff --git a/lib/wibox/layout/constraint.lua b/lib/wibox/layout/constraint.lua index b4e0e3770..5a0c975c7 100644 --- a/lib/wibox/layout/constraint.lua +++ b/lib/wibox/layout/constraint.lua @@ -24,13 +24,13 @@ function constraint:draw(context, cr, width, height) end --- Fit a constraint layout into the given space -function constraint:fit(width, height) +function constraint:fit(context, width, height) local w, h if self.widget then w = self._strategy(width, self._width) h = self._strategy(height, self._height) - w, h = base.fit_widget(self.widget, w, h) + w, h = base.fit_widget(context, self.widget, w, h) else w, h = 0, 0 end diff --git a/lib/wibox/layout/fixed.lua b/lib/wibox/layout/fixed.lua index a5cce63be..1a2ea1dbb 100644 --- a/lib/wibox/layout/fixed.lua +++ b/lib/wibox/layout/fixed.lua @@ -28,7 +28,7 @@ function fixed:draw(context, cr, width, height) x, y = 0, pos w, h = width, height - pos if k ~= #self.widgets or not self._fill_space then - _, h = base.fit_widget(v, w, h); + _, h = base.fit_widget(context, v, w, h); end pos = pos + h + spacing in_dir = h @@ -36,7 +36,7 @@ function fixed:draw(context, cr, width, height) x, y = pos, 0 w, h = width - pos, height if k ~= #self.widgets or not self._fill_space then - w, _ = base.fit_widget(v, w, h); + w, _ = base.fit_widget(context, v, w, h); end pos = pos + w + spacing in_dir = w @@ -59,14 +59,15 @@ function fixed:add(widget) end --- Fit the fixed layout into the given space +-- @param context The context in which we are fit. -- @param orig_width The available width. -- @param orig_height The available height. -function fixed:fit(orig_width, orig_height) +function fixed:fit(context, orig_width, orig_height) local width, height = orig_width, orig_height local used_in_dir, used_max = 0, 0 for k, v in pairs(self.widgets) do - local w, h = base.fit_widget(v, width, height) + local w, h = base.fit_widget(context, v, width, height) local in_dir, max if self.dir == "y" then max, in_dir = w, h diff --git a/lib/wibox/layout/flex.lua b/lib/wibox/layout/flex.lua index a24af0be4..0b47ff784 100644 --- a/lib/wibox/layout/flex.lua +++ b/lib/wibox/layout/flex.lua @@ -75,9 +75,10 @@ function flex:set_max_widget_size(val) end --- Fit the flex layout into the given space. +-- @param context The context in which we are fit. -- @param orig_width The available width. -- @param orig_height The available height. -function flex:fit(orig_width, orig_height) +function flex:fit(context, orig_width, orig_height) local used_in_dir = 0 local used_in_other = 0 @@ -86,7 +87,7 @@ function flex:fit(orig_width, orig_height) local sub_width = self.dir == "y" and orig_width or floor(orig_width / #self.widgets) for k, v in pairs(self.widgets) do - local w, h = base.fit_widget(v, sub_width, sub_height) + local w, h = base.fit_widget(context, v, sub_width, sub_height) local max = self.dir == "y" and w or h if max > used_in_other then diff --git a/lib/wibox/layout/margin.lua b/lib/wibox/layout/margin.lua index 7e164b50d..0fc2117e2 100644 --- a/lib/wibox/layout/margin.lua +++ b/lib/wibox/layout/margin.lua @@ -41,12 +41,12 @@ function margin:draw(context, cr, width, height) end --- Fit a margin layout into the given space -function margin:fit(width, height) +function margin:fit(context, width, height) local extra_w = self.left + self.right local extra_h = self.top + self.bottom local w, h = 0, 0 if self.widget then - w, h = base.fit_widget(self.widget, width - extra_w, height - extra_h) + w, h = base.fit_widget(context, self.widget, width - extra_w, height - extra_h) end return w + extra_w, h + extra_h end diff --git a/lib/wibox/layout/mirror.lua b/lib/wibox/layout/mirror.lua index cace8c0bd..b03924095 100644 --- a/lib/wibox/layout/mirror.lua +++ b/lib/wibox/layout/mirror.lua @@ -45,11 +45,11 @@ function mirror:draw(context, cr, width, height) end --- Fit this layout into the given area -function mirror:fit(...) +function mirror:fit(context, ...) if not self.widget then return 0, 0 end - return base.fit_widget(self.widget, ...) + return base.fit_widget(context, self.widget, ...) end --- Set the widget that this layout mirrors. diff --git a/lib/wibox/layout/rotate.lua b/lib/wibox/layout/rotate.lua index 3e687525b..cf929c096 100644 --- a/lib/wibox/layout/rotate.lua +++ b/lib/wibox/layout/rotate.lua @@ -49,11 +49,11 @@ function rotate:draw(context, cr, width, height) end --- Fit this layout into the given area -function rotate:fit(width, height) +function rotate:fit(context, width, height) if not self.widget then return 0, 0 end - return transform(self, base.fit_widget(self.widget, transform(self, width, height))) + return transform(self, base.fit_widget(context, self.widget, transform(self, width, height))) end --- Set the widget that this layout rotates. diff --git a/lib/wibox/widget/background.lua b/lib/wibox/widget/background.lua index 940dff20d..5847cc3eb 100644 --- a/lib/wibox/widget/background.lua +++ b/lib/wibox/widget/background.lua @@ -47,12 +47,12 @@ function background:draw(context, cr, width, height) end --- Fit this widget into the given area -function background:fit(width, height) +function background:fit(context, width, height) if not self.widget then return 0, 0 end - return self.widget:fit(width, height) + return layout_base.fit_widget(context, self.widget, width, height) end --- Set the widget that is drawn on top of the background diff --git a/lib/wibox/widget/base.lua b/lib/wibox/widget/base.lua index f57c01f56..ef562d779 100644 --- a/lib/wibox/widget/base.lua +++ b/lib/wibox/widget/base.lua @@ -142,7 +142,7 @@ function base.check_widget(widget) debug.assert(type(widget[func]) == "function", func .. " is not a function") end - local width, height = widget:fit(0, 0) + local width, height = widget:fit({}, 0, 0) debug.assert(type(width) == "number") debug.assert(type(height) == "number") end diff --git a/lib/wibox/widget/imagebox.lua b/lib/wibox/widget/imagebox.lua index 24a03cc94..e623525db 100644 --- a/lib/wibox/widget/imagebox.lua +++ b/lib/wibox/widget/imagebox.lua @@ -39,7 +39,7 @@ function imagebox:draw(context, cr, width, height) end --- Fit the imagebox into the given geometry -function imagebox:fit(width, height) +function imagebox:fit(context, width, height) if not self._image then return 0, 0 end diff --git a/lib/wibox/widget/systray.lua b/lib/wibox/widget/systray.lua index 1c692b05c..25db97d8b 100644 --- a/lib/wibox/widget/systray.lua +++ b/lib/wibox/widget/systray.lua @@ -45,7 +45,7 @@ function systray:draw(context, cr, width, height) base, is_rotated, bg, reverse, spacing) end -function systray:fit(width, height) +function systray:fit(context, width, height) local num_entries = capi.awesome.systray() local base = base_size local spacing = beautiful.systray_icon_spacing or 0 diff --git a/lib/wibox/widget/textbox.lua b/lib/wibox/widget/textbox.lua index 6b99b16e2..a5cb35301 100644 --- a/lib/wibox/widget/textbox.lua +++ b/lib/wibox/widget/textbox.lua @@ -42,7 +42,7 @@ function textbox:draw(context, cr, width, height) end --- Fit the given textbox -function textbox:fit(width, height) +function textbox:fit(context, width, height) setup_layout(self, width, height) local ink, logical = self._layout:get_pixel_extents() diff --git a/spec/wibox/test_utils.lua b/spec/wibox/test_utils.lua index 01879cca4..d993baf75 100644 --- a/spec/wibox/test_utils.lua +++ b/spec/wibox/test_utils.lua @@ -35,7 +35,7 @@ local function widget_fit(state, arguments) local widget = arguments[1] local given = arguments[2] local expected = arguments[3] - local w, h = widget:fit(given[1], given[2]) + local w, h = widget:fit({ "fake context" }, given[1], given[2]) local fits = expected[1] == w and expected[2] == h if state.mod == fits then