From 1a9887335e1d78227429693fbe44bfdf22a70609 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Oct 2016 13:57:04 +0200 Subject: [PATCH 1/3] wibox: Add shape property This bridges between gears.shape and the shapes. So far, it does not try to do any kind of anti-aliasing magic, so you get "steep edges". Signed-off-by: Uli Schlachter --- lib/wibox/init.lua | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/lib/wibox/init.lua b/lib/wibox/init.lua index e9c22b634..e02489a45 100644 --- a/lib/wibox/init.lua +++ b/lib/wibox/init.lua @@ -17,6 +17,7 @@ local object = require("gears.object") local grect = require("gears.geometry").rectangle local beautiful = require("beautiful") local base = require("wibox.widget.base") +local cairo = require("lgi").cairo --- This provides widget box windows. Every wibox can also be used as if it were -- a drawin. All drawin functions and properties are also available on wiboxes! @@ -61,6 +62,53 @@ function wibox:find_widgets(x, y) return self._drawable:find_widgets(x, y) end +function wibox:_apply_shape() + local shape = self._shape + + if not shape then + self.shape_bounding = nil + self.shape_clip = nil + return + end + + local geo = self:geometry() + local bw = self.border_width + + -- First handle the bounding shape (things including the border) + local img = cairo.ImageSurface(cairo.Format.A1, geo.width + 2*bw, geo.height + 2*bw) + local cr = cairo.Context(img) + + shape(cr, geo.width + 2*bw, geo.height + 2*bw) + cr:set_operator(cairo.Operator.SOURCE) + cr:fill() + self.shape_bounding = img._native + img:finish() + + -- Now handle the clip shape (things excluding the border) + img = cairo.ImageSurface(cairo.Format.A1, geo.width, geo.height) + cr = cairo.Context(img) + + shape(cr, geo.width, geo.height) + cr:set_operator(cairo.Operator.SOURCE) + cr:fill() + self.shape_clip = img._native + img:finish() +end + +--- Set the wibox shape. +-- @property shape +-- @tparam gears.shape A gears.shape compatible function. +-- @see gears.shape + +function wibox:set_shape(shape) + self._shape = shape + self:_apply_shape() +end + +function wibox:get_shape() + return self._shape +end + function wibox:get_screen() if self.screen_assigned and self.screen_assigned.valid then return self.screen_assigned @@ -196,6 +244,9 @@ local function new(args) -- Make sure the wibox is drawn at least once ret.draw() + ret:connect_signal("property::geometry", ret._apply_shape) + ret:connect_signal("property::border_width", ret._apply_shape) + -- If a value is not found, look in the drawin setmetatable(ret, { __index = function(self, k) @@ -229,6 +280,8 @@ local function new(args) ret:set_screen ( args.screen ) end + ret.shape = args.shape + return ret end From 144b9ef6976388c9f6d860f244f016f529083c43 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Oct 2016 14:57:58 +0200 Subject: [PATCH 2/3] Add a kind of test for wibox shape support Signed-off-by: Uli Schlachter --- tests/test-wibox-shape.lua | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/test-wibox-shape.lua diff --git a/tests/test-wibox-shape.lua b/tests/test-wibox-shape.lua new file mode 100644 index 000000000..62166f10d --- /dev/null +++ b/tests/test-wibox-shape.lua @@ -0,0 +1,31 @@ +-- A quick-and-dirty test of wibox shapes ("Does it error out?") + +local runner = require("_runner") +local wibox = require("wibox") +local shape = require("gears.shape") + +local was_drawn +local widget = wibox.widget.base.make_widget() +function widget.draw() + was_drawn = true +end + +local wb = wibox { + shape = shape.powerline, + widget = widget, + border_width = 42, +} +wb:geometry(screen[1].geometry) +wb.visible = true + +runner.run_steps({ + function() + assert(wb.shape == shape.powerline) + assert(wb.shape_bounding) -- This is a memory leak! Don't copy! + if was_drawn then + return true + end + end +}) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 From ddfe652173db1463d35d1b2d203ea24bee534440 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Mon, 26 Dec 2016 13:55:33 +0100 Subject: [PATCH 3/3] fixup! wibox: Add shape property --- lib/wibox/init.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/wibox/init.lua b/lib/wibox/init.lua index e02489a45..757b2473a 100644 --- a/lib/wibox/init.lua +++ b/lib/wibox/init.lua @@ -78,6 +78,7 @@ function wibox:_apply_shape() local img = cairo.ImageSurface(cairo.Format.A1, geo.width + 2*bw, geo.height + 2*bw) local cr = cairo.Context(img) + -- We just draw the shape in its full size shape(cr, geo.width + 2*bw, geo.height + 2*bw) cr:set_operator(cairo.Operator.SOURCE) cr:fill() @@ -88,9 +89,18 @@ function wibox:_apply_shape() img = cairo.ImageSurface(cairo.Format.A1, geo.width, geo.height) cr = cairo.Context(img) - shape(cr, geo.width, geo.height) + -- We give the shape the same arguments as for the bounding shape and draw + -- it in its full size (the translate is to compensate for the smaller + -- surface) + cr:translate(-bw, -bw) + shape(cr, geo.width + 2*bw, geo.height + 2*bw) cr:set_operator(cairo.Operator.SOURCE) - cr:fill() + cr:fill_preserve() + -- Now we remove an area of width 'bw' again around the shape (We use 2*bw + -- since half of that is on the outside and only half on the inside) + cr:set_source_rgba(0, 0, 0, 0) + cr:set_line_width(2*bw) + cr:stroke() self.shape_clip = img._native img:finish() end