From 68f6a567d1887e3039c2f16cabfbdeec70d7aded Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 5 Apr 2019 21:02:16 -0400 Subject: [PATCH 01/29] tests: Prevent a rare-ish race condition in the buttons test suite. Given there is some async wibox redraw operations, there is a tiny, tiny chance the test suite callback will be executed before the redraw. It has been seen on the CI, so it is not 100% impossible. --- tests/test-awful-widget-button.lua | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/test-awful-widget-button.lua b/tests/test-awful-widget-button.lua index 0b399f04..09c608de 100644 --- a/tests/test-awful-widget-button.lua +++ b/tests/test-awful-widget-button.lua @@ -69,7 +69,7 @@ table.insert(steps, function() awful.button({}, 1, nil, function () button:emit_signal_recursive("test::recursive") end) -)) + )) layout:connect_signal("test::recursive", function() got_called = true @@ -89,7 +89,7 @@ table.insert(steps, function() end) table.insert(steps, function() - assert(button._private.image ~= img) + if button._private.image == img then return end return true end) @@ -115,30 +115,30 @@ table.insert(steps, function() end) table.insert(steps, function() -assert(button._private.image ~= img) + if button._private.image == img then return end -return true + return true end) table.insert(steps, function() --- just make sure the button is not released for nothing -assert(button._private.image ~= img) + -- just make sure the button is not released for nothing + assert(button._private.image ~= img) --- test if the button is released when the mouse move out -awful.placement.right(mouse--[[, {parent = w}]]) -root.fake_input("button_release", 1) -awesome.sync() + -- test if the button is released when the mouse move out + awful.placement.right(mouse--[[, {parent = w}]]) + root.fake_input("button_release", 1) + awesome.sync() -return true + return true end) table.insert(steps, function() -assert(button._private.image == img) + assert(button._private.image == img) --- The button had plenty of clicks by now. Make sure everything worked -assert(got_called) + -- The button had plenty of clicks by now. Make sure everything worked + assert(got_called) -return true + return true end) runner.run_steps(steps) From 50d4e8f04b2a6095d36e91b09b96eaa83b946f96 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 12 Mar 2019 14:36:32 -0400 Subject: [PATCH 02/29] doc: Add a deprecated property section. --- docs/config.ld | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/config.ld b/docs/config.ld index 5a264241..e47df040 100644 --- a/docs/config.ld +++ b/docs/config.ld @@ -53,6 +53,8 @@ tparam_alias('screen_or_idx', 'screen|int') new_type("function", "Functions") -- Documentation for objects properties new_type("property", "Object properties", false, "Type") +-- Documentation for objects deprecated properties +new_type("deprecatedproperty", "Deprecated object properties", false, "Type") -- New type for signals new_type("signal", "Signals", false, "Arguments") -- New type for signals connections @@ -142,7 +144,8 @@ file = { } local no_prefix = { - property = true, signal = true, clientruleproperty = true + property = true, signal = true, clientruleproperty = true, + deprecatedproperty = true, } custom_display_name_handler = function(item, default_handler) @@ -153,7 +156,7 @@ custom_display_name_handler = function(item, default_handler) return name ~= "" and name or item.name end - if item.type == "deprecated" then + if item.type == "deprecated" or item.type == "deprecatedproperty" then return default_handler(item) .. " [deprecated]" end From 7997549067a2ee9761ce5e46b12fdfcb23a3e899 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 8 Mar 2019 13:39:46 -0500 Subject: [PATCH 03/29] shims: Do not select all tags by default. It will now behave closer to the default config. --- tests/examples/shims/tag.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/examples/shims/tag.lua b/tests/examples/shims/tag.lua index f445f485..b0bd4947 100644 --- a/tests/examples/shims/tag.lua +++ b/tests/examples/shims/tag.lua @@ -2,13 +2,22 @@ local gears_obj = require("gears.object") local tag, meta = awesome._shim_fake_class() +local function has_selected_tag(s) + for _, t in ipairs(root._tags) do + if t.selected and ((not s) or s == t.screen) then + return true + end + end + return false +end + local function new_tag(_, args) local ret = gears_obj() ret.data = {} ret.name = args.name or "test" ret.activated = true - ret.selected = true + ret.selected = not has_selected_tag(args.screen) function ret:clients(_) --TODO handle new local list = {} From 936040a2834debfde065ed8d90d660a5cb96125a Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 8 Mar 2019 13:40:21 -0500 Subject: [PATCH 04/29] shims: Add disconnect_signal. It is necessary when adding many wibars. --- tests/examples/shims/awesome.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/examples/shims/awesome.lua b/tests/examples/shims/awesome.lua index 4d8f0323..8d1616d9 100644 --- a/tests/examples/shims/awesome.lua +++ b/tests/examples/shims/awesome.lua @@ -13,12 +13,17 @@ local function _shim_fake_class() __newindex = function()end, } - obj._connect_signal = obj.connect_signal + obj._connect_signal = obj.connect_signal + obj._disconnect_signal = obj.disconnect_signal function obj.connect_signal(name, func) return obj._connect_signal(obj, name, func) end + function obj.disconnect_signal(name, func) + return obj._disconnect_signal(obj, name, func) + end + function obj.set_index_miss_handler(handler) meta.__index = handler end From 8111495c8806f16c059b61aee9b4df14a7a38c3c Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 14 Mar 2019 20:56:20 -0400 Subject: [PATCH 05/29] shims: Set the client metatable earlier. Once the signals get propagated, it means "manage" will call code before the metatable is set. If this happens and it sets some properties, they will perpetually bypass the `awful.client.object` handler. --- tests/examples/shims/client.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/examples/shims/client.lua b/tests/examples/shims/client.lua index 8b3cdda3..54b0df35 100644 --- a/tests/examples/shims/client.lua +++ b/tests/examples/shims/client.lua @@ -140,13 +140,15 @@ function client.gen_fake(args) client.focus = ret + setmetatable(ret, { + __index = function(...) return meta.__index(...) end, + __newindex = function(...) return meta.__newindex(...) end + }) + client.emit_signal("manage", ret) assert(not args.screen or (args.screen == ret.screen)) - return setmetatable(ret, { - __index = function(...) return meta.__index(...) end, - __newindex = function(...) return meta.__newindex(...) end - }) + return ret end function client.get(s) From be72b4033a3d437c20e132d441ae6047ba8d1bdb Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 14 Mar 2019 21:13:03 -0400 Subject: [PATCH 06/29] shims: Prevent a potential stack overflow in the client shims. --- tests/examples/shims/client.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/examples/shims/client.lua b/tests/examples/shims/client.lua index 54b0df35..d4bddd78 100644 --- a/tests/examples/shims/client.lua +++ b/tests/examples/shims/client.lua @@ -33,6 +33,12 @@ function client.gen_fake(args) ret.icon_sizes = {{16,16}} ret.name = "Example Client" + -- This is a hack because there's a `:is_transient_for(c2)` method + -- and a `transient_for` property. It will cause a stack overflow + -- since the auto-alias will kick in if the property is allowed to + -- be `nil`. + ret.transient_for = false + -- Apply all properties for k,v in pairs(args or {}) do ret[k] = v From 6aabb73fa362bfd1ca2139885fce2f6bd586a478 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 8 Mar 2019 13:55:55 -0500 Subject: [PATCH 07/29] shims: Implement signal forwarding. This make the rules, among other things, work. --- tests/examples/shims/awesome.lua | 10 ++++++++++ tests/examples/shims/client.lua | 2 ++ tests/examples/shims/screen.lua | 2 ++ tests/examples/shims/tag.lua | 1 + 4 files changed, 15 insertions(+) diff --git a/tests/examples/shims/awesome.lua b/tests/examples/shims/awesome.lua index 8d1616d9..3e97847a 100644 --- a/tests/examples/shims/awesome.lua +++ b/tests/examples/shims/awesome.lua @@ -42,8 +42,18 @@ local function _shim_fake_class() return obj, meta end +local function forward_class(obj, class) + assert(obj.emit_signal) + local es = obj.emit_signal + function obj:emit_signal(name, ...) + es(obj, name, ...) + class.emit_signal(name, obj, ...) + end +end + local awesome = _shim_fake_class() awesome._shim_fake_class = _shim_fake_class +awesome._forward_class = forward_class -- Avoid c.screen = acreen.focused() to be called, all tests will fail awesome.startup = true diff --git a/tests/examples/shims/client.lua b/tests/examples/shims/client.lua index d4bddd78..bf76a426 100644 --- a/tests/examples/shims/client.lua +++ b/tests/examples/shims/client.lua @@ -25,6 +25,8 @@ end -- Create fake clients to move around function client.gen_fake(args) local ret = gears_obj() + awesome._forward_class(ret, client) + ret.data = {} ret.type = "normal" ret.valid = true diff --git a/tests/examples/shims/screen.lua b/tests/examples/shims/screen.lua index 09df1108..10abbc9c 100644 --- a/tests/examples/shims/screen.lua +++ b/tests/examples/shims/screen.lua @@ -5,6 +5,8 @@ screen._count = 0 local function create_screen(args) local s = gears_obj() + awesome._forward_class(s, screen) + s.data = {} s.valid = true diff --git a/tests/examples/shims/tag.lua b/tests/examples/shims/tag.lua index b0bd4947..60ef6b4a 100644 --- a/tests/examples/shims/tag.lua +++ b/tests/examples/shims/tag.lua @@ -13,6 +13,7 @@ end local function new_tag(_, args) local ret = gears_obj() + awesome._forward_class(ret, tag) ret.data = {} ret.name = args.name or "test" From 0c53d76f253a26a664e2b0976930806ee4b15699 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 8 Mar 2019 14:09:24 -0500 Subject: [PATCH 08/29] shims: Emit property::geometry when resizing screens. It allows to wibars to be resized. --- tests/examples/shims/screen.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/examples/shims/screen.lua b/tests/examples/shims/screen.lua index 10abbc9c..4fbdb5e7 100644 --- a/tests/examples/shims/screen.lua +++ b/tests/examples/shims/screen.lua @@ -19,10 +19,12 @@ local function create_screen(args) } function s._resize(args2) + local old = s.geometry geo.x = args2.x or geo.x geo.y = args2.y or geo.y geo.width = args2.width or geo.width geo.height = args2.height or geo.height + s:emit_signal("property::geometry", old) end s.outputs = { ["LVDS1"] = { From 59e2ae6800adad08b80a584cb62e703f4d107eb7 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sun, 10 Mar 2019 15:00:57 -0400 Subject: [PATCH 09/29] shims: Set capi.screen.primary. This is used as a fallback when some objects go out of screen. --- tests/examples/shims/screen.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/examples/shims/screen.lua b/tests/examples/shims/screen.lua index 4fbdb5e7..bf7f119c 100644 --- a/tests/examples/shims/screen.lua +++ b/tests/examples/shims/screen.lua @@ -136,6 +136,7 @@ screen._add_screen {width=320, height=240} screen._grid_vertical_margin = 10 screen._grid_horizontal_margin = 10 +screen.primary = screen[1] function screen.count() return screen._count From 02ed7ceed5fee8392dc3859696ce9509d854ce19 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 6 Mar 2019 23:42:06 -0500 Subject: [PATCH 10/29] widget.base: Allow widgets constructor in the declarative template. This avoids the boilerplate of having to do: { widget = awful.widget.mywidget } in the templates. --- lib/wibox/widget/base.lua | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/wibox/widget/base.lua b/lib/wibox/widget/base.lua index 15096b1e..a0ddf551 100644 --- a/lib/wibox/widget/base.lua +++ b/lib/wibox/widget/base.lua @@ -420,6 +420,14 @@ function base.place_widget_at(widget, x, y, width, height) return base.place_widget_via_matrix(widget, matrix.create_translate(x, y), width, height) end +-- Check if `obj` can be called (either using the metacall or as a function) +local function is_callable(obj) + local t = type(obj) + return t == "function" or ( + t == "table" and getmetatable(obj) and getmetatable(obj).__call + ), t +end + -- Read the table, separate attributes from widgets. local function parse_table(t, leave_empty) local max = 0 @@ -491,9 +499,11 @@ local function drill(ids, content) local v, id2, e = widgets[k], id, nil if v then -- It is another declarative container, parse it. - if not v.is_widget then + if (not v.is_widget) and (v.widget or v.layout) then e, id2 = drill(ids, v) widgets[k] = e + elseif (not v.is_widget) and is_callable(v) then + widgets[k] = v() end base.check_widget(widgets[k]) @@ -599,13 +609,11 @@ end -- @param[opt=nil] ... Arguments passed to the contructor (if any). -- @treturn The new widget. function base.make_widget_from_value(wdg, ...) - local is_table = type(wdg) == "table" - local is_function = ((not is_table) and type(wdg) == "function") - or (is_table and getmetatable(wdg) and getmetatable(wdg).__call) + local is_function, t = is_callable(wdg) if is_function then wdg = wdg(...) - elseif is_table and not wdg.is_widget then + elseif t == "table" and not wdg.is_widget then wdg = base.make_widget_declarative(wdg) else assert(wdg.is_widget, "The argument is not a function, table, or widget.") From 81ff4d730c067396243afee426ccc5abb36190df Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 12 Mar 2019 14:13:21 -0400 Subject: [PATCH 11/29] background: Always allow a border. Previously, the border "support" was limited to shapes and would not move the content by the offset of the border. Borders are now better supported and thus renamed from `shape_border_width` to `border_width. In the end, shrinking the widget by the border size is too common to ignore. It should have been the default all along, just like the clip. --- lib/wibox/container/background.lua | 84 +++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 13 deletions(-) diff --git a/lib/wibox/container/background.lua b/lib/wibox/container/background.lua index d7f8403a..5815b35f 100644 --- a/lib/wibox/container/background.lua +++ b/lib/wibox/container/background.lua @@ -14,6 +14,7 @@ local surface = require("gears.surface") local beautiful = require("beautiful") local cairo = require("lgi").cairo local gtable = require("gears.table") +local gshape = require("gears.shape") local setmetatable = setmetatable local type = type local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1) @@ -30,8 +31,11 @@ end -- Prepare drawing the children of this widget function background:before_draw_children(context, cr, width, height) + local bw = self._private.shape_border_width or 0 + local shape = self._private.shape or (bw > 0 and gshape.rectangle or nil) + -- Redirect drawing to a temporary surface if there is a shape - if self._private.shape then + if shape then cr:push_group_with_content(cairo.Content.COLOR_ALPHA) end @@ -63,15 +67,17 @@ end -- Draw the border function background:after_draw_children(_, cr, width, height) - if not self._private.shape then + local bw = self._private.shape_border_width or 0 + local shape = self._private.shape or (bw > 0 and gshape.rectangle or nil) + + if not shape then return end -- Okay, there is a shape. Get it as a path. - local bw = self._private.shape_border_width or 0 cr:translate(bw, bw) - self._private.shape(cr, width - 2*bw, height - 2*bw, unpack(self._private.shape_args or {})) + shape(cr, width - 2*bw, height - 2*bw, unpack(self._private.shape_args or {})) cr:translate(-bw, -bw) if bw > 0 then @@ -126,7 +132,12 @@ end -- Layout this widget function background:layout(_, width, height) if self._private.widget then - return { base.place_widget_at(self._private.widget, 0, 0, width, height) } + local bw = self._private.border_strategy == "inner" and + self._private.shape_border_width or 0 + + return { base.place_widget_at( + self._private.widget, bw, bw, width-2*bw, height-2*bw + ) } end end @@ -136,7 +147,14 @@ function background:fit(context, width, height) return 0, 0 end - return base.fit_widget(self, context, self._private.widget, width, height) + local bw = self._private.border_strategy == "inner" and + self._private.shape_border_width or 0 + + local w, h = base.fit_widget( + self, context, self._private.widget, width - 2*bw, height - 2*bw + ) + + return w+2*bw, h+2*bw end --- The widget displayed in the background widget. @@ -207,7 +225,7 @@ function background:get_fg() return self._private.foreground end ---- The background shap e. +--- The background shape. -- -- Use `set_shape` to set additional shape paramaters. -- @@ -240,38 +258,63 @@ end --- When a `shape` is set, also draw a border. -- -- See `wibox.container.background.shape` for an usage example. --- @property shape_border_width +-- @deprecatedproperty shape_border_width -- @tparam number width The border width +-- @see border_width -function background:set_shape_border_width(width) +--- Add a border of a specific width. +-- +-- If the shape is set, the border will also be shaped. +-- +-- See `wibox.container.background.shape` for an usage example. +-- @property border_width +-- @tparam[opt=0] number width The border width. +-- @see border_color + +function background:set_border_width(width) if self._private.shape_border_width == width then return end self._private.shape_border_width = width self:emit_signal("widget::redraw_needed") end -function background:get_shape_border_width() +function background:get_border_width() return self._private.shape_border_width end +background.get_shape_border_width = background.get_border_width +background.set_shape_border_width = background.set_border_width + --- When a `shape` is set, also draw a border. -- -- See `wibox.container.background.shape` for an usage example. --- @property shape_border_color +-- @deprecatedproperty shape_border_color -- @param[opt=self._private.foreground] fg The border color, pattern or gradient -- @see gears.color +-- @see border_color -function background:set_shape_border_color(fg) +--- Set the color for the border. +-- +-- See `wibox.container.background.shape` for an usage example. +-- @property border_color +-- @param[opt=self._private.foreground] fg The border color, pattern or gradient +-- @see gears.color +-- @see border_width + +function background:set_border_color(fg) if self._private.shape_border_color == fg then return end self._private.shape_border_color = fg self:emit_signal("widget::redraw_needed") end -function background:get_shape_border_color() +function background:get_border_color() return self._private.shape_border_color end +background.get_shape_border_color = background.get_border_color +background.set_shape_border_color = background.set_border_color + function background:set_shape_clip(value) if value then return end require("gears.debug").print_warning("shape_clip property of background container was removed." @@ -284,6 +327,21 @@ function background:get_shape_clip() return true end +--- How the border width affects the contained widget. +-- +-- The valid values are: +-- +-- * *none*: Just apply the border, do not affect the content size (default). +-- * *inner*: Squeeze the size of the content by the border width. +-- +-- @property border_strategy +-- @param[opt="none"] string + +function background:set_border_strategy(value) + self._private.border_strategy = value + self:emit_signal("widget::layout_changed") +end + --- The background image to use -- If `image` is a function, it will be called with `(context, cr, width, height)` -- as arguments. Any other arguments passed to this method will be appended. From eb1c45b656c8c3b2ec099aae04e8a662abff878e Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 5 Apr 2019 16:52:01 -0400 Subject: [PATCH 12/29] background: Update all users so they don't use the deprecated name. This is done before deprecating the API so no commit ever use the deprecated name. --- lib/awful/tooltip.lua | 28 ++++++------- lib/awful/widget/calendar_popup.lua | 24 ++++------- lib/awful/widget/common.lua | 6 +-- tests/examples/awful/popup/wiboxtypes.lua | 4 +- tests/examples/awful/template.lua | 12 +++--- .../wibox/awidget/tasklist/rounded.lua | 6 +-- .../wibox/container/background/shape.lua | 10 ++--- .../wibox/container/defaults/background.lua | 10 ++--- .../wibox/container/defaults/template.lua | 26 ++++++------ .../examples/wibox/container/rotate/angle.lua | 42 +++++++++---------- .../wibox/widget/calendar/fn_embed_cell.lua | 12 +++--- 11 files changed, 85 insertions(+), 95 deletions(-) diff --git a/lib/awful/tooltip.lua b/lib/awful/tooltip.lua index 62970d96..5fb6db1f 100644 --- a/lib/awful/tooltip.lua +++ b/lib/awful/tooltip.lua @@ -465,7 +465,7 @@ end -- @param number function tooltip:set_border_width(val) - self.widget.shape_border_width = val + self.widget.border_width = val end --- The border color. @@ -476,7 +476,7 @@ end -- @param gears.color function tooltip:set_border_color(val) - self.widget.shape_border_color = val + self.widget.border_color = val end --- Set the margins around the left and right of the tooltip textbox @@ -679,23 +679,23 @@ function tooltip.new(args) self.widget = wibox.widget { { { - id = 'text_role', - font = font, + id = 'text_role', + font = font, widget = wibox.widget.textbox, }, - id = 'margin_role', - left = m_lr, - right = m_lr, - top = m_tb, + id = 'margin_role', + left = m_lr, + right = m_lr, + top = m_tb, bottom = m_tb, widget = wibox.container.margin, }, - id = 'background_role', - bg = bg, - shape = self._private.shape, - shape_border_width = border_width, - shape_border_color = border_color, - widget = wibox.container.background, + id = 'background_role', + bg = bg, + shape = self._private.shape, + border_width = border_width, + border_color = border_color, + widget = wibox.container.background, } self.textbox = self.widget:get_children_by_id('text_role')[1] self.marginbox = self.widget:get_children_by_id('margin_role')[1] diff --git a/lib/awful/widget/calendar_popup.lua b/lib/awful/widget/calendar_popup.lua index d4bc8128..df49c89c 100644 --- a/lib/awful/widget/calendar_popup.lua +++ b/lib/awful/widget/calendar_popup.lua @@ -39,14 +39,12 @@ local calendar_popup = { offset = 0, mt = {} } local properties = { "markup", "fg_color", "bg_color", "shape", "padding", "border_width", "border_color", "opacity" } local styles = { "year", "month", "yearheader", "monthheader", "header", "weekday", "weeknumber", "normal", "focus" } - --- The generic calendar style table. -- -- Each table property can also be defined by `beautiful.calendar_[flag]_[property]=val`. -- @beautiful beautiful.calendar_style -- @tparam cell_properties table Table of cell style properties - --- Cell properties. -- @field markup Markup function or format string -- @field fg_color Text foreground color @@ -69,8 +67,6 @@ local styles = { "year", "month", "yearheader", "monthheader", "header", "weekda -- @field focus Current day cell properties table -- @table cell_flags - - --- Create a container for the grid layout -- @tparam table tprops Table of calendar container properties. -- @treturn function Embedding function widget,flag,date -> widget @@ -98,20 +94,19 @@ local function embed(tprops) margins = props.padding + props.border_width, widget = wibox.container.margin }, - shape = props.shape or gears.shape.rectangle, - shape_border_color = props.border_color, - shape_border_width = props.border_width, - fg = props.fg_color, - bg = props.bg_color, - opacity = props.opacity, - widget = wibox.container.background + shape = props.shape or gears.shape.rectangle, + border_color = props.border_color, + border_width = props.border_width, + fg = props.fg_color, + bg = props.bg_color, + opacity = props.opacity, + widget = wibox.container.background } return out end return fn end - --- Parse the properties of the cell type and set default values -- @tparam string cell The cell type -- @tparam table args Table of properties to enforce @@ -165,7 +160,6 @@ local function parse_all_options(args) return props end - --- Make the geometry of a wibox -- @tparam widget widget Calendar widget -- @tparam object screen Screen where to display the calendar (default to focused) @@ -236,14 +230,12 @@ function calendar_popup:call_calendar(offset, position, screen) return self end - --- Toggle calendar visibility function calendar_popup:toggle() self:call_calendar(0) self.visible = not self.visible end - --- Attach the calendar to a widget to display at a specific position. -- -- local mytextclock = wibox.widget.textclock() @@ -286,7 +278,6 @@ function calendar_popup:attach(widget, position, args) return self end - --- Return a new calendar wibox by type. -- -- A calendar widget displaying a `month` or a `year` @@ -385,7 +376,6 @@ function calendar_popup.month(args) return get_cal_wibox("month", args) end - --- A year calendar wibox. -- -- It is highly customizable using the same options as for the widgets. diff --git a/lib/awful/widget/common.lua b/lib/awful/widget/common.lua index 8649dad0..0bff7a77 100644 --- a/lib/awful/widget/common.lua +++ b/lib/awful/widget/common.lua @@ -148,9 +148,9 @@ function common.list_update(w, buttons, label, data, objects, args) }) end - cache.bgb.shape = item_args.shape - cache.bgb.shape_border_width = item_args.shape_border_width - cache.bgb.shape_border_color = item_args.shape_border_color + cache.bgb.shape = item_args.shape + cache.bgb.border_width = item_args.shape_border_width + cache.bgb.border_color = item_args.shape_border_color end diff --git a/tests/examples/awful/popup/wiboxtypes.lua b/tests/examples/awful/popup/wiboxtypes.lua index 1a47c627..5c0f679b 100644 --- a/tests/examples/awful/popup/wiboxtypes.lua +++ b/tests/examples/awful/popup/wiboxtypes.lua @@ -198,8 +198,8 @@ local function create_info(text, x, y, width, height) forced_width = width, forced_height = height, shape = gears.shape.rectangle, - shape_border_width = 1, - shape_border_color = beautiful.border_color, + border_width = 1, + border_color = beautiful.border_color, bg = "#ffff0055", widget = wibox.container.background }, {x = x, y = y}) diff --git a/tests/examples/awful/template.lua b/tests/examples/awful/template.lua index 17c56935..75c4feec 100644 --- a/tests/examples/awful/template.lua +++ b/tests/examples/awful/template.lua @@ -141,12 +141,12 @@ local function client_widget(c, col, label) }, layout = wibox.layout.stack }, - shape_border_width = bw, - shape_border_color = beautiful.border_color, - shape_clip = true, - fg = beautiful.fg_normal or "#000000", - bg = col, - shape = function(cr2, w, h) + border_width = bw, + border_color = beautiful.border_color, + shape_clip = true, + fg = beautiful.fg_normal or "#000000", + bg = col, + shape = function(cr2, w, h) return shape.rounded_rect(cr2, w, h, args.radius or 5) end, diff --git a/tests/examples/wibox/awidget/tasklist/rounded.lua b/tests/examples/wibox/awidget/tasklist/rounded.lua index df75ecf1..247f7f71 100644 --- a/tests/examples/wibox/awidget/tasklist/rounded.lua +++ b/tests/examples/wibox/awidget/tasklist/rounded.lua @@ -26,9 +26,9 @@ end --DOC_HIDE filter = awful.widget.tasklist.filter.currenttags, buttons = tasklist_buttons, style = { - shape_border_width = 1, - shape_border_color = "#777777", - shape = gears.shape.rounded_bar, + border_width = 1, + border_color = "#777777", + shape = gears.shape.rounded_bar, }, layout = { spacing = 10, diff --git a/tests/examples/wibox/container/background/shape.lua b/tests/examples/wibox/container/background/shape.lua index f4556dcf..bf8552d7 100644 --- a/tests/examples/wibox/container/background/shape.lua +++ b/tests/examples/wibox/container/background/shape.lua @@ -30,11 +30,11 @@ parent : setup { bottom = 3, widget = wibox.container.margin }, - shape = gears.shape.hexagon, - bg = beautiful.bg_normal, - shape_border_color = beautiful.border_color, - shape_border_width = beautiful.border_width, - widget = wibox.container.background + shape = gears.shape.hexagon, + bg = beautiful.bg_normal, + border_color = beautiful.border_color, + border_width = beautiful.border_width, + widget = wibox.container.background }, spacing = 10, layout = wibox.layout.fixed.vertical diff --git a/tests/examples/wibox/container/defaults/background.lua b/tests/examples/wibox/container/defaults/background.lua index 858f00a1..75813b71 100644 --- a/tests/examples/wibox/container/defaults/background.lua +++ b/tests/examples/wibox/container/defaults/background.lua @@ -17,11 +17,11 @@ return { valign = "center", widget = wibox.widget.textbox, }, - shape = gears.shape.circle, - shape_border_width = 5, - shape_border_color = "#ff0000", - bg = beautiful.bg_highlight, - widget = wibox.container.background + shape = gears.shape.circle, + border_width = 5, + border_color = "#ff0000", + bg = beautiful.bg_highlight, + widget = wibox.container.background } --DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/tests/examples/wibox/container/defaults/template.lua b/tests/examples/wibox/container/defaults/template.lua index e628a982..33bafa37 100644 --- a/tests/examples/wibox/container/defaults/template.lua +++ b/tests/examples/wibox/container/defaults/template.lua @@ -13,10 +13,10 @@ local container = wibox.widget { { { before, - shape_border_color = beautiful.border_color, - shape_border_width = beautiful.border_width, - shape = shape.rounded_rect, - widget = wibox.container.background, + border_color = beautiful.border_color, + border_width = beautiful.border_width, + shape = shape.rounded_rect, + widget = wibox.container.background, }, strategy = 'exact', width = 70, @@ -29,11 +29,11 @@ local container = wibox.widget { text = " ", widget = wibox.widget.textbox, }, - bg = beautiful.bg_normal, - shape_border_color = beautiful.border_color, - shape_border_width = beautiful.border_width, - widget = wibox.container.background, - shape = shape.transform(shape.arrow) + bg = beautiful.bg_normal, + border_color = beautiful.border_color, + border_width = beautiful.border_width, + widget = wibox.container.background, + shape = shape.transform(shape.arrow) : rotate_at(15,15,math.pi/2) : translate(0,-8) : scale(0.9, 0.9), @@ -46,10 +46,10 @@ local container = wibox.widget { { { after, - shape_border_color = beautiful.border_color, - shape_border_width = beautiful.border_width, - shape = shape.rounded_rect, - widget = wibox.container.background, + border_color = beautiful.border_color, + border_width = beautiful.border_width, + shape = shape.rounded_rect, + widget = wibox.container.background, }, strategy = 'exact', width = 70, diff --git a/tests/examples/wibox/container/rotate/angle.lua b/tests/examples/wibox/container/rotate/angle.lua index b6e71946..7deee84c 100644 --- a/tests/examples/wibox/container/rotate/angle.lua +++ b/tests/examples/wibox/container/rotate/angle.lua @@ -4,27 +4,27 @@ local wibox = require("wibox") --DOC_HIDE local gears = {shape = require("gears.shape")} --DOC_HIDE local beautiful = require("beautiful") --DOC_HIDE -local function create_arrow(text) --DOC_HIDE - return { --DOC_HIDE - { --DOC_HIDE - { --DOC_HIDE - text = text, --DOC_HIDE - align = "center", --DOC_HIDE - valign = "center", --DOC_HIDE - widget = wibox.widget.textbox, --DOC_HIDE - }, --DOC_HIDE - shape = gears.shape.arrow, --DOC_HIDE - bg = beautiful.bg_normal, --DOC_HIDE - shape_border_color = beautiful.border_color, --DOC_HIDE - shape_border_width = beautiful.border_width, --DOC_HIDE - widget = wibox.container.background --DOC_HIDE - }, --DOC_HIDE - strategy = 'exact', --DOC_HIDE - width = 70, --DOC_HIDE - height = 70, --DOC_HIDE - widget = wibox.container.constraint --DOC_HIDE - } --DOC_HIDE -end --DOC_HIDE +local function create_arrow(text) --DOC_HIDE + return { --DOC_HIDE + { --DOC_HIDE + { --DOC_HIDE + text = text, --DOC_HIDE + align = "center", --DOC_HIDE + valign = "center", --DOC_HIDE + widget = wibox.widget.textbox, --DOC_HIDE + }, --DOC_HIDE + shape = gears.shape.arrow, --DOC_HIDE + bg = beautiful.bg_normal, --DOC_HIDE + border_color = beautiful.border_color, --DOC_HIDE + border_width = beautiful.border_width, --DOC_HIDE + widget = wibox.container.background --DOC_HIDE + }, --DOC_HIDE + strategy = 'exact', --DOC_HIDE + width = 70, --DOC_HIDE + height = 70, --DOC_HIDE + widget = wibox.container.constraint --DOC_HIDE + } --DOC_HIDE +end --DOC_HIDE local normal = create_arrow("Normal") diff --git a/tests/examples/wibox/widget/calendar/fn_embed_cell.lua b/tests/examples/wibox/widget/calendar/fn_embed_cell.lua index a3eb9997..e1ca6c36 100644 --- a/tests/examples/wibox/widget/calendar/fn_embed_cell.lua +++ b/tests/examples/wibox/widget/calendar/fn_embed_cell.lua @@ -67,12 +67,12 @@ beautiful.bg_focus = "#b9214f" --DOC_HIDE margins = (props.padding or 2) + (props.border_width or 0), widget = wibox.container.margin }, - shape = props.shape, - shape_border_color = props.border_color or "#b9214f", - shape_border_width = props.border_width or 0, - fg = props.fg_color or "#999999", - bg = props.bg_color or default_bg, - widget = wibox.container.background + shape = props.shape, + border_color = props.border_color or "#b9214f", + border_width = props.border_width or 0, + fg = props.fg_color or "#999999", + bg = props.bg_color or default_bg, + widget = wibox.container.background } return ret end From c1596f0b4e323fcfe73a9ef5264bd33d0160f032 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 5 Apr 2019 17:03:12 -0400 Subject: [PATCH 13/29] background: Deprecate `shape_border_(width|color)`. In favor of `border_width` and `border_color`. --- lib/wibox/container/background.lua | 31 ++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/wibox/container/background.lua b/lib/wibox/container/background.lua index 5815b35f..a88d9dd7 100644 --- a/lib/wibox/container/background.lua +++ b/lib/wibox/container/background.lua @@ -15,6 +15,7 @@ local beautiful = require("beautiful") local cairo = require("lgi").cairo local gtable = require("gears.table") local gshape = require("gears.shape") +local gdebug = require("gears.debug") local setmetatable = setmetatable local type = type local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1) @@ -282,8 +283,19 @@ function background:get_border_width() return self._private.shape_border_width end -background.get_shape_border_width = background.get_border_width -background.set_shape_border_width = background.set_border_width +function background.get_shape_border_width(...) + gdebug.deprecate("Use `border_width` instead of `shape_border_width`", + {deprecated_in=5}) + + return background.get_border_width(...) +end + +function background.set_shape_border_width(...) + gdebug.deprecate("Use `border_width` instead of `shape_border_width`", + {deprecated_in=5}) + + background.set_border_width(...) +end --- When a `shape` is set, also draw a border. -- @@ -312,8 +324,19 @@ function background:get_border_color() return self._private.shape_border_color end -background.get_shape_border_color = background.get_border_color -background.set_shape_border_color = background.set_border_color +function background.get_shape_border_color(...) + gdebug.deprecate("Use `border_color` instead of `shape_border_color`", + {deprecated_in=5}) + + return background.get_border_color(...) +end + +function background.set_shape_border_color(...) + gdebug.deprecate("Use `border_color` instead of `shape_border_color`", + {deprecated_in=5}) + + background.set_border_color(...) +end function background:set_shape_clip(value) if value then return end From 8ac1f672375bf42351530e0286afecd81cbbe12f Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 12 Mar 2019 14:00:11 -0400 Subject: [PATCH 14/29] container.margins: Allow the `margins` property to be a table. It makes some code easier to write. It is mostly useful when the margins are exposed through another widget. In that case it avoids having to proxy 5 different property or re-invent the wheel there. --- lib/wibox/container/margin.lua | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/wibox/container/margin.lua b/lib/wibox/container/margin.lua index dcdd2f1b..632a007e 100644 --- a/lib/wibox/container/margin.lua +++ b/lib/wibox/container/margin.lua @@ -95,20 +95,30 @@ end --- Set all the margins to val. -- @property margins --- @tparam number val The margin value +-- @tparam number|table val The margin value. It can be a number or a table with +-- the *left*/*right*/*top*/*bottom* keys. function margin:set_margins(val) - if self._private.left == val and - self._private.right == val and - self._private.top == val and - self._private.bottom == val then - return + + if type(val) == "number" or not val then + if self._private.left == val and + self._private.right == val and + self._private.top == val and + self._private.bottom == val then + return + end + + self._private.left = val + self._private.right = val + self._private.top = val + self._private.bottom = val + elseif type(val) == "table" then + self._private.left = val.left or self._private.left + self._private.right = val.right or self._private.right + self._private.top = val.top or self._private.top + self._private.bottom = val.bottom or self._private.bottom end - self._private.left = val - self._private.right = val - self._private.top = val - self._private.bottom = val self:emit_signal("widget::layout_changed") end From 7adbbd3f7c2e0a8c594347183c154fb6308eab40 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 12 Mar 2019 14:06:50 -0400 Subject: [PATCH 15/29] awful.common: When a border is set, shrink the widget by its size. --- lib/awful/widget/common.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/awful/widget/common.lua b/lib/awful/widget/common.lua index 0bff7a77..95c8fa27 100644 --- a/lib/awful/widget/common.lua +++ b/lib/awful/widget/common.lua @@ -62,6 +62,7 @@ local function default_template() return custom_template { widget_template = { id = 'background_role', + border_strategy = 'inner', widget = wibox.container.background, { widget = wibox.layout.fixed.horizontal, From d99f8461ef32efb96b2dcbf8f011d899d36fd38a Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 5 Apr 2019 14:58:07 -0400 Subject: [PATCH 16/29] naughty.legacy: Do not update the text if the notification has no widget If the notification has been created without a legacy widget, it would try to update some widgets that have never been created. --- lib/naughty/layout/legacy.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/naughty/layout/legacy.lua b/lib/naughty/layout/legacy.lua index e1162061..07fdbaa1 100644 --- a/lib/naughty/layout/legacy.lua +++ b/lib/naughty/layout/legacy.lua @@ -241,10 +241,6 @@ local function set_escaped_text(self) if self.size_info then update_size(self) end end -naughty.connect_signal("property::text" ,set_escaped_text) -naughty.connect_signal("property::title",set_escaped_text) - - local function cleanup(self, _ --[[reason]], keep_visible) -- It is not a legacy notification if not self.box then return end From 441c4ae98cd020845c0c2da692411f3042a5a702 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sat, 1 Jul 2017 22:39:29 -0400 Subject: [PATCH 17/29] tests: Add a notification template. --- tests/examples/naughty/template.lua | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/examples/naughty/template.lua diff --git a/tests/examples/naughty/template.lua b/tests/examples/naughty/template.lua new file mode 100644 index 00000000..1c2314f0 --- /dev/null +++ b/tests/examples/naughty/template.lua @@ -0,0 +1,55 @@ +local file_path, image_path = ... +require("_common_template")(...) +local wibox = require("wibox") + +-- For the connections +require("naughty") + +-- Create a screen +screen[1]._resize {x = 0, width = 800, height = 600} + +-- Let the test request a size and file format +loadfile(file_path)() + +-- Emulate the event loop for 10 iterations +for _ = 1, 10 do + awesome:emit_signal("refresh") +end + +local rect = {x1 = math.huge ,y1 = math.huge , x2 = -math.huge , y2 = -math.huge} + +-- Get the region with wiboxes +for _, d in ipairs(drawin.get()) do + local w = d.get_wibox and d:get_wibox() or nil + if w then + local geo = w:geometry() + rect.x1 = math.min(rect.x1, geo.x ) + rect.y1 = math.min(rect.y1, geo.y ) + rect.x2 = math.max(rect.x2, geo.x + geo.width + 2*w.border_width) + rect.y2 = math.max(rect.y2, geo.y + geo.height + 2*w.border_width) + end +end + +-- Get rid of invalid drawins. The shims are very permissive and wont deny this. +if rect.x1 == rect.x2 or rect.y1 == rect.y2 then return end + +local multi = wibox.layout { + forced_width = rect.x2 - rect.x1, + forced_height = rect.y2 - rect.y1, + layout = wibox.layout.manual +} + +-- Draw all normal wiboxes +for _, d in ipairs(drawin.get()) do + local w = d.get_wibox and d:get_wibox() or nil + if w then + local geo = w:geometry() + multi:add_at(w:to_widget(), {x = geo.x - rect.x1, y = geo.y - rect.y1}) + end +end + +wibox.widget.draw_to_svg_file( + multi, image_path..".svg", multi.forced_width, multi.forced_height +) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 From fe10119933602207aabf32e32796390048b0d287 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sat, 1 Jul 2017 22:39:47 -0400 Subject: [PATCH 18/29] tests: Test the notifications. --- tests/examples/awful/notification/corner.lua | 20 +++++++++++++ tests/examples/naughty/actions.lua | 19 ++++++++++++ tests/examples/naughty/colors.lua | 19 ++++++++++++ tests/examples/naughty/helloworld.lua | 18 ++++++++++++ tests/examples/naughty/shape.lua | 31 ++++++++++++++++++++ 5 files changed, 107 insertions(+) create mode 100644 tests/examples/awful/notification/corner.lua create mode 100644 tests/examples/naughty/actions.lua create mode 100644 tests/examples/naughty/colors.lua create mode 100644 tests/examples/naughty/helloworld.lua create mode 100644 tests/examples/naughty/shape.lua diff --git a/tests/examples/awful/notification/corner.lua b/tests/examples/awful/notification/corner.lua new file mode 100644 index 00000000..9cbc9128 --- /dev/null +++ b/tests/examples/awful/notification/corner.lua @@ -0,0 +1,20 @@ +--DOC_HIDE_ALL +local naughty = require("naughty") --DOC_HIDE + +for _, pos in ipairs { + "top_left", + "top_middle", + "top_right", + "bottom_left", + "bottom_middle", + "bottom_right", +} do + naughty.notify { + title = pos, + position = pos, + text = "", + } +end + + +--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/tests/examples/naughty/actions.lua b/tests/examples/naughty/actions.lua new file mode 100644 index 00000000..f21d73ef --- /dev/null +++ b/tests/examples/naughty/actions.lua @@ -0,0 +1,19 @@ +--DOC_NO_USAGE +--DOC_HIDE_ALL +-- local naughty = require("naughty") + +dbus.notify_send( + --[[data]] { + member = "Notify", + }, + --[[app_name]] "Notification demo", + --[[replaces_id]] nil, + --[[icon]] "", + --[[title]] "You got a message!", + --[[text]] "This is a message from above.\nAwesomeWM is your faith.", + {"Accept", "Dismiss", "Forward"}, + --[[hints]] {}, + --[[expire]] 5 +) + +--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/tests/examples/naughty/colors.lua b/tests/examples/naughty/colors.lua new file mode 100644 index 00000000..2149e429 --- /dev/null +++ b/tests/examples/naughty/colors.lua @@ -0,0 +1,19 @@ + +local beautiful = require("beautiful") --DOC_HIDE + +local text = [[An important +notification +]] + +require("naughty").notify { + title = "Hello world!", + text = text, + icon = beautiful.icon, + bg = "#0000ff", + fg = "#ff0000", + font = "verdana 14", + border_width = 1, + border_color = "#ff0000" +} + +--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/tests/examples/naughty/helloworld.lua b/tests/examples/naughty/helloworld.lua new file mode 100644 index 00000000..5c6daecc --- /dev/null +++ b/tests/examples/naughty/helloworld.lua @@ -0,0 +1,18 @@ +--DOC_HIDE_ALL +-- local naughty = require("naughty") + +dbus.notify_send( + --[[data]] { + member = "Notify", + }, + --[[app_name]] "Notification demo", + --[[replaces_id]] nil, + --[[icon]] "", + --[[title]] "Hello world!", + --[[text]] "The notification content", + --[[actions]] {}, + --[[hints]] {}, + --[[expire]] 5 +) + +--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/tests/examples/naughty/shape.lua b/tests/examples/naughty/shape.lua new file mode 100644 index 00000000..b685b605 --- /dev/null +++ b/tests/examples/naughty/shape.lua @@ -0,0 +1,31 @@ + +local beautiful = require("beautiful") --DOC_HIDE +local gears = {shape=require("gears.shape")} --DOC_HIDE +local naughty = require("naughty") --DOC_HIDE + +local text = [[An important +notification +]] + +local shapes = { + gears.shape.rounded_rect, + gears.shape.hexagon, + gears.shape.octogon, + function(cr, w, h) + return gears.shape.infobubble(cr, w, h, 20, 10, w/2 - 10) + end +} + +for _, s in ipairs(shapes) do + naughty.notify { + title = "Hello world!", + text = text, + icon = beautiful.icon, + shape = s, + border_width = 3, + border_color = beautiful.bg_highlight, + margin = 15, + } +end + +--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 From 97417121ad620da268b9829ae89f156deb3c83d8 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 6 Mar 2019 23:30:46 -0500 Subject: [PATCH 19/29] naughty: Add a property to get all active notifications. --- lib/naughty/core.lua | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/naughty/core.lua b/lib/naughty/core.lua index 57879115..98bbb08f 100644 --- a/lib/naughty/core.lua +++ b/lib/naughty/core.lua @@ -111,6 +111,17 @@ gtable.crush(naughty, require("naughty.constants")) -- @property expiration_paused -- @param[opt=false] boolean +--- A table with all active notifications. +-- +-- Please note that this list is kept up-to-date even in suspended mode. +-- +-- **Signal:** +-- +-- * property::active +-- +-- @property active +-- @param table + local properties = { suspended = false, expiration_paused = false @@ -129,6 +140,9 @@ local properties = { -- @field id Unique notification id based on a counter -- @table notifications naughty.notifications = { suspended = { }, _expired = {{}} } + +naughty._active = {} + screen.connect_for_each_screen(function(s) naughty.notifications[s] = { top_left = {}, @@ -315,12 +329,17 @@ function naughty.get_by_id(id) for _, notification in pairs(naughty.notifications[s][p]) do if notification.id == id then return notification - end + end end end end end +-- Use an explicit getter to make it read only. +function naughty.get_active() + return naughty._active +end + --- Set new notification timeout. -- -- This function is deprecated, use `notification:reset_timeout(new_timeout)`. @@ -380,6 +399,14 @@ local function cleanup(self, reason) n.idx = k end + -- Remove from the global active list. + for k, n in ipairs(naughty._active) do + if n == self then + table.remove(naughty._active, k) + naughty.emit_signal("property::active") + end + end + -- `self.timer.started` will be false if the expiration was paused. if self.timer and self.timer.started then self.timer:stop() @@ -439,8 +466,6 @@ end -- including, but not limited to, all `naughty.notification` properties. -- @signal request::preset - - -- Register a new notification object. local function register(notification, args) @@ -451,6 +476,7 @@ local function register(notification, args) local s = get_screen(args.screen or notification.preset.screen or screen.focused()) -- insert the notification to the table + table.insert(naughty._active, notification) table.insert(naughty.notifications[s][notification.position], notification) notification.idx = #naughty.notifications[s][notification.position] notification.screen = s @@ -464,6 +490,8 @@ local function register(notification, args) assert(rawget(notification, "preset")) + naughty.emit_signal("property::active") + -- return the notification return notification end From d5a06b0c680c7fe0c07c9361f177d3a13d1396c4 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 8 Mar 2019 14:02:27 -0500 Subject: [PATCH 20/29] tests: Share the "default look&feel" boilerplate code among the tests. This will avoid some copy/paste in future tests. The commit also fixes a typo and a missing --DOC_NO_DASH which breaks rendering with one of the markdown implementation. --- tests/examples/awful/popup/wiboxtypes.lua | 64 ++------------------ tests/examples/shims/_default_look.lua | 74 +++++++++++++++++++++++ 2 files changed, 79 insertions(+), 59 deletions(-) create mode 100644 tests/examples/shims/_default_look.lua diff --git a/tests/examples/awful/popup/wiboxtypes.lua b/tests/examples/awful/popup/wiboxtypes.lua index 5c0f679b..02e851cb 100644 --- a/tests/examples/awful/popup/wiboxtypes.lua +++ b/tests/examples/awful/popup/wiboxtypes.lua @@ -1,11 +1,13 @@ --DOC_GEN_IMAGE --DOC_HIDE_ALL --DOC_NO_USAGE +--DOC_NO_DASH require("_date") local awful = require("awful") local gears = require("gears") local wibox = require("wibox") local beautiful = require("beautiful") --DOC_HIDE +local look = require("_default_look") screen[1]._resize {width = 640, height = 480} @@ -23,36 +25,6 @@ c:geometry { c._old_geo = {c:geometry()} c:set_label("A client") -local wb = awful.wibar { - position = "top", -} - --- Create the same number of tags as the default config -awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, screen[1], awful.layout.layouts[1]) - --- Only bother with widgets that are visible by default -local mykeyboardlayout = awful.widget.keyboardlayout() -local mytextclock = wibox.widget.textclock() -local mylayoutbox = awful.widget.layoutbox(screen[1]) -local mytaglist = awful.widget.taglist(screen[1], awful.widget.taglist.filter.all, {}) -local mytasklist = awful.widget.tasklist(screen[1], awful.widget.tasklist.filter.currenttags, {}) - -wb:setup { - layout = wibox.layout.align.horizontal, - { -- Left widgets - layout = wibox.layout.fixed.horizontal, - awful.titlebar.widget.iconwidget(c), --looks close enough - mytaglist, - }, - mytasklist, -- Middle widget - { -- Right widgets - layout = wibox.layout.fixed.horizontal, - mykeyboardlayout, - mytextclock, - mylayoutbox, - }, -} - -- The popup awful.popup { widget = wibox.widget { @@ -112,37 +84,11 @@ local p10 = awful.popup { } require("gears.timer").run_delayed_calls_now() -p10:bind_to_widget(mytextclock) +p10:bind_to_widget(look.mytextclock) -- The titlebar -local top_titlebar = awful.titlebar(c, { - height = 20, - bg_normal = "#ff0000", -}) - -top_titlebar : setup { - { -- Left - awful.titlebar.widget.iconwidget(c), - layout = wibox.layout.fixed.horizontal - }, - { -- Middle - { -- Title - align = "center", - widget = awful.titlebar.widget.titlewidget(c) - }, - layout = wibox.layout.flex.horizontal - }, - { -- Right - awful.titlebar.widget.floatingbutton (c), - awful.titlebar.widget.maximizedbutton(c), - awful.titlebar.widget.stickybutton (c), - awful.titlebar.widget.ontopbutton (c), - awful.titlebar.widget.closebutton (c), - layout = wibox.layout.fixed.horizontal() - }, - layout = wibox.layout.align.horizontal -} +c:emit_signal("request::titlebars", "rules", {})--DOC_HIDE -- Normal wiboxes @@ -228,7 +174,7 @@ create_info("awful.wibar", 200, 50, 100, 30) create_info("awful.titlebar", 250, 350, 100, 30) create_info("awful.tooltip", 30, 130, 100, 30) create_info("awful.popup", 450, 240, 100, 30) -create_info("Standard `wibox1`", 420, 420, 130, 30) +create_info("Standard `wibox`", 420, 420, 130, 30) create_line(250, 10, 250, 55) create_line(75, 100, 75, 135) diff --git a/tests/examples/shims/_default_look.lua b/tests/examples/shims/_default_look.lua new file mode 100644 index 00000000..87e7a508 --- /dev/null +++ b/tests/examples/shims/_default_look.lua @@ -0,0 +1,74 @@ +local awful = require("awful") +local wibox = require("wibox") +local beautiful = require("beautiful") +require("_date") + +-- Create the same number of tags as the default config +awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, screen[1], awful.layout.layouts[1]) +local mykeyboardlayout = awful.widget.keyboardlayout() +local mytextclock = wibox.widget.textclock() +local mylayoutbox = awful.widget.layoutbox(screen[1]) +local mytaglist = awful.widget.taglist(screen[1], awful.widget.taglist.filter.all, {}) +local mytasklist = awful.widget.tasklist(screen[1], awful.widget.tasklist.filter.currenttags, {}) + +local wb = awful.wibar { position = "top" } +wb:setup { + layout = wibox.layout.align.horizontal, + { + layout = wibox.layout.fixed.horizontal, + { + image = beautiful.awesome_icon, + widget = wibox.widget.imagebox, + }, + mytaglist, + }, + mytasklist, + { + layout = wibox.layout.fixed.horizontal, + mykeyboardlayout, + mytextclock, + mylayoutbox, + }, +} + + +client.connect_signal("request::titlebars", function(c) + local top_titlebar = awful.titlebar(c, { + height = 20, + bg_normal = beautiful.bg_normal, + }) + + top_titlebar : setup { + { -- Left + awful.titlebar.widget.iconwidget(c), + layout = wibox.layout.fixed.horizontal + }, + { -- Middle + { -- Title + align = "center", + widget = awful.titlebar.widget.titlewidget(c) + }, + layout = wibox.layout.flex.horizontal + }, + { -- Right + awful.titlebar.widget.floatingbutton (c), + awful.titlebar.widget.maximizedbutton(c), + awful.titlebar.widget.stickybutton (c), + awful.titlebar.widget.ontopbutton (c), + awful.titlebar.widget.closebutton (c), + layout = wibox.layout.fixed.horizontal() + }, + layout = wibox.layout.align.horizontal + } +end) + +require("gears.timer").run_delayed_calls_now() + +return { + mykeyboardlayout = mykeyboardlayout, + mytextclock = mytextclock , + mylayoutbox = mylayoutbox , + mytaglist = mytaglist , + mytasklist = mytasklist , + mywibox = wb, +} From db2d4b92dfc3d7ebfed1debad435de3159cc8219 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 6 Mar 2019 14:06:11 -0500 Subject: [PATCH 22/29] awful.widget: Add support for icon_size. This decision was taken out of necessity. While adding more style elements to `awful.widget.common` isn't something I want, there is little else to do here. The problem is that popup based lists only have size constraints in one direction. So without a way to limit the icon size, it will take 9999 pixels. --- lib/awful/widget/common.lua | 8 ++++++++ lib/awful/widget/taglist.lua | 2 ++ lib/awful/widget/tasklist.lua | 3 +++ 3 files changed, 13 insertions(+) diff --git a/lib/awful/widget/common.lua b/lib/awful/widget/common.lua index 95c8fa27..c1d2e5ae 100644 --- a/lib/awful/widget/common.lua +++ b/lib/awful/widget/common.lua @@ -161,6 +161,14 @@ function common.list_update(w, buttons, label, data, objects, args) cache.ibm:set_margins(0) end + if item_args.icon_size and cache.ib then + cache.ib.forced_height = item_args.icon_size + cache.ib.forced_width = item_args.icon_size + elseif cache.ib then + cache.ib.forced_height = nil + cache.ib.forced_width = nil + end + w:add(cache.primary) end end diff --git a/lib/awful/widget/taglist.lua b/lib/awful/widget/taglist.lua index d806ada1..80690bda 100644 --- a/lib/awful/widget/taglist.lua +++ b/lib/awful/widget/taglist.lua @@ -261,6 +261,7 @@ function taglist.taglist_label(t, args) local shape = args.shape or theme.taglist_shape local shape_border_width = args.shape_border_width or theme.taglist_shape_border_width local shape_border_color = args.shape_border_color or theme.taglist_shape_border_color + local icon_size = args.icon_size or theme.taglist_icon_size -- TODO: Re-implement bg_resize local bg_resize = false -- luacheck: ignore local is_selected = false @@ -379,6 +380,7 @@ function taglist.taglist_label(t, args) shape = shape, shape_border_width = shape_border_width, shape_border_color = shape_border_color, + icon_size = icon_size, } return text, bg_color, bg_image, not taglist_disable_icon and icon or nil, other_args diff --git a/lib/awful/widget/tasklist.lua b/lib/awful/widget/tasklist.lua index 332927b5..825e36b2 100644 --- a/lib/awful/widget/tasklist.lua +++ b/lib/awful/widget/tasklist.lua @@ -279,6 +279,7 @@ local function tasklist_label(c, args, tb) local shape = args.shape or theme.tasklist_shape local shape_border_width = args.shape_border_width or theme.tasklist_shape_border_width local shape_border_color = args.shape_border_color or theme.tasklist_shape_border_color + local icon_size = args.icon_size or theme.tasklist_icon_size -- symbol to use to indicate certain client properties local sticky = args.sticky or theme.tasklist_sticky or "▪" @@ -394,6 +395,7 @@ local function tasklist_label(c, args, tb) shape = shape, shape_border_width = shape_border_width, shape_border_color = shape_border_color, + icon_size = icon_size, } return text, bg, bg_image, not tasklist_disable_icon and c.icon or nil, other_args @@ -451,6 +453,7 @@ end -- @tparam[opt=nil] string args.style.bg_image_urgent -- @tparam[opt=nil] string args.style.bg_image_minimize -- @tparam[opt=nil] boolean args.style.tasklist_disable_icon +-- @tparam[opt=nil] number args.style.icon_size The size of the icon -- @tparam[opt=false] boolean args.style.disable_task_name -- @tparam[opt=nil] string args.style.font -- @tparam[opt=left] string args.style.align *left*, *right* or *center* From e79a5c59883d9d289d360d27c4c8d4431baa56df Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 6 Mar 2019 18:30:20 -0500 Subject: [PATCH 23/29] awful.widget: Add a `create_callback` to the common list. This is like its template equivalent, but "private" to the list widget. --- lib/awful/widget/common.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/awful/widget/common.lua b/lib/awful/widget/common.lua index c1d2e5ae..043cece4 100644 --- a/lib/awful/widget/common.lua +++ b/lib/awful/widget/common.lua @@ -116,6 +116,10 @@ function common.list_update(w, buttons, label, data, objects, args) cache.create_callback(cache.primary, o, i, objects) end + if args and args.create_callback then + args.create_callback(cache.primary, o, i, objects) + end + data[o] = cache elseif cache.update_callback then cache.update_callback(cache.primary, o, i, objects) From d5a2fe007242a349a8a4738b47b6216f78b0ea78 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 6 Mar 2019 22:20:14 -0500 Subject: [PATCH 24/29] awful.widget: Add an helper to set a property on all template widgets With this helper, it becomes possible to avoid manually setting common properties such as the client in the tasklist of tag in the taglist when the children widgets of the template have a set_+property_name. --- lib/awful/widget/common.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/awful/widget/common.lua b/lib/awful/widget/common.lua index 043cece4..35dbfb7c 100644 --- a/lib/awful/widget/common.lua +++ b/lib/awful/widget/common.lua @@ -91,6 +91,19 @@ local function default_template() } end +-- Find all the childrens (without the hierarchy) and set a property. +function common._set_common_property(widget, property, value) + if widget["set_"..property] then + widget["set_"..property](widget, value) + end + + if widget.get_children then + for _, w in ipairs(widget:get_children()) do + common._set_common_property(w, property, value) + end + end +end + --- Common update method. -- @param w The widget. -- @tab buttons From e452ec8e273262f182211cb2d400478e877095a5 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 6 Mar 2019 22:44:02 -0500 Subject: [PATCH 25/29] awful.widget: Use private `args` for the update_function. Previously, it would use the "real" args passed to the constructor. It was a bad decision since: * It doesn't allow the tag/tasklist to add properties internally * It forces the widget to be created with a constructor rather than the alternate declarative syntax * It doesn't allow a tag/tasklist to be part of a widget_template Technically this is a behavior change, but I doubt anybody will notice given it is a dark and little documented corner of the API. Chances are nobody have been using this API for years. --- lib/awful/widget/taglist.lua | 4 +++- lib/awful/widget/tasklist.lua | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/awful/widget/taglist.lua b/lib/awful/widget/taglist.lua index 80690bda..0fd08ab1 100644 --- a/lib/awful/widget/taglist.lua +++ b/lib/awful/widget/taglist.lua @@ -400,7 +400,9 @@ local function taglist_update(s, w, buttons, filter, data, style, update_functio local function label(c) return taglist.taglist_label(c, style) end - update_function(w, buttons, label, data, tags, args) + update_function(w, buttons, label, data, tags, { + widget_template = args.widget_template, + }) end --- Create a new taglist widget. The last two arguments (update_function diff --git a/lib/awful/widget/tasklist.lua b/lib/awful/widget/tasklist.lua index 825e36b2..d1141aa3 100644 --- a/lib/awful/widget/tasklist.lua +++ b/lib/awful/widget/tasklist.lua @@ -417,7 +417,9 @@ local function tasklist_update(s, w, buttons, filter, data, style, update_functi local function label(c, tb) return tasklist_label(c, style, tb) end - update_function(w, buttons, label, data, clients, args) + update_function(w, buttons, label, data, clients, { + widget_template = args.widget_template, + }) end --- Create a new tasklist widget. From aa6ab69ffc8afc6fb35a8525ac060ad4059f54cf Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 6 Mar 2019 22:56:58 -0500 Subject: [PATCH 26/29] taglist: Auto-call set_tag on each widgets of the template. This reduced the boilerplate code. --- lib/awful/widget/taglist.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/awful/widget/taglist.lua b/lib/awful/widget/taglist.lua index 0fd08ab1..a384ed1d 100644 --- a/lib/awful/widget/taglist.lua +++ b/lib/awful/widget/taglist.lua @@ -386,6 +386,11 @@ function taglist.taglist_label(t, args) return text, bg_color, bg_image, not taglist_disable_icon and icon or nil, other_args end +-- Remove some callback boilerplate from the user provided templates. +local function create_callback(w, t) + common._set_common_property(w, "tag", t) +end + local function taglist_update(s, w, buttons, filter, data, style, update_function, args) local tags = {} @@ -402,6 +407,7 @@ local function taglist_update(s, w, buttons, filter, data, style, update_functio update_function(w, buttons, label, data, tags, { widget_template = args.widget_template, + create_callback = create_callback, }) end From a081413339eaab5d6e4de4f6131181dee4db3cbf Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 6 Mar 2019 22:57:34 -0500 Subject: [PATCH 27/29] tasklist: Auto-call set_client on all template widgets This commit also update one of the example to remove its now redundant boilerplate code. --- lib/awful/widget/tasklist.lua | 6 ++++++ tests/examples/wibox/awidget/tasklist/windows10.lua | 8 +------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/awful/widget/tasklist.lua b/lib/awful/widget/tasklist.lua index d1141aa3..5fc7699c 100644 --- a/lib/awful/widget/tasklist.lua +++ b/lib/awful/widget/tasklist.lua @@ -401,6 +401,11 @@ local function tasklist_label(c, args, tb) return text, bg, bg_image, not tasklist_disable_icon and c.icon or nil, other_args end +-- Remove some callback boilerplate from the user provided templates. +local function create_callback(w, t) + common._set_common_property(w, "client", t) +end + local function tasklist_update(s, w, buttons, filter, data, style, update_function, args) local clients = {} @@ -419,6 +424,7 @@ local function tasklist_update(s, w, buttons, filter, data, style, update_functi update_function(w, buttons, label, data, clients, { widget_template = args.widget_template, + create_callback = create_callback, }) end diff --git a/tests/examples/wibox/awidget/tasklist/windows10.lua b/tests/examples/wibox/awidget/tasklist/windows10.lua index 8ba40c9b..8bf59c19 100644 --- a/tests/examples/wibox/awidget/tasklist/windows10.lua +++ b/tests/examples/wibox/awidget/tasklist/windows10.lua @@ -52,17 +52,11 @@ end --DOC_HIDE widget = wibox.container.background, }, { - { - id = "clienticon", - widget = awful.widget.clienticon, - }, + awful.widget.clienticon, margins = 5, widget = wibox.container.margin }, nil, - create_callback = function(self, c, index, objects) --luacheck: no unused args - self:get_children_by_id("clienticon")[1].client = c - end, layout = wibox.layout.align.vertical, }, } From 5c57f43643906b8e7e9f04fbbb516b0482b0343d Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 6 Mar 2019 23:16:34 -0500 Subject: [PATCH 28/29] tasklist: Use awful.widget.clienticon by default. This allows sharper icons to be used. Fixes #2143 --- lib/awful/widget/tasklist.lua | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/awful/widget/tasklist.lua b/lib/awful/widget/tasklist.lua index 5fc7699c..bfe6a070 100644 --- a/lib/awful/widget/tasklist.lua +++ b/lib/awful/widget/tasklist.lua @@ -87,7 +87,13 @@ local timer = require("gears.timer") local gcolor = require("gears.color") local gstring = require("gears.string") local gdebug = require("gears.debug") +local dpi = require("beautiful").xresources.apply_dpi local base = require("wibox.widget.base") +local wfixed = require("wibox.layout.fixed") +local wmargin = require("wibox.container.margin") +local wtextbox = require("wibox.widget.textbox") +local clienticon = require("awful.widget.clienticon") +local wbackground = require("wibox.container.background") local function get_screen(s) return s and screen[s] @@ -247,6 +253,32 @@ local instances -- Public structures tasklist.filter, tasklist.source = {}, {} +-- This is the same template as awful.widget.common, but with an clienticon widget +local default_template = { + { + { + clienticon, + id = "icon_margin_role", + left = dpi(4), + widget = wmargin + }, + { + { + id = "text_role", + widget = wtextbox, + }, + id = "text_margin_role", + left = dpi(4), + right = dpi(4), + widget = wmargin + }, + fill_space = true, + layout = wfixed.horizontal + }, + id = "background_role", + widget = wbackground +} + local function tasklist_label(c, args, tb) if not args then args = {} end local theme = beautiful.get() @@ -423,7 +455,7 @@ local function tasklist_update(s, w, buttons, filter, data, style, update_functi local function label(c, tb) return tasklist_label(c, style, tb) end update_function(w, buttons, label, data, clients, { - widget_template = args.widget_template, + widget_template = args.widget_template or default_template, create_callback = create_callback, }) end From 28541c8e82ba6ffe6209f40b37c0409390513fa2 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 5 Apr 2019 16:24:52 -0400 Subject: [PATCH 29/29] doc: Update the NEWS for the new features added by this pull request. --- docs/89-NEWS.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/89-NEWS.md b/docs/89-NEWS.md index 4b118781..ed991c8a 100644 --- a/docs/89-NEWS.md +++ b/docs/89-NEWS.md @@ -21,6 +21,15 @@ This document was last updated at commit v4.3-148-g795c792d1. * `naughty` was rewritten TODO TODO say more about this TODO TODO * The `rules` argument in `awful.spawn.once` and `.single_instance` is now optional +* The `wibox.container.background` now has a `border_strategy` property to + define how the content is resized when a border is present. +* The `wibox.container.margin` now allows tables in the `margins` property. +* The declarative widget systax now allows to directly use functions instead of + `{widget = myfunction}`. +* The `awful.widget.tasklist` now resize the client icons properly. +* The `awful.widget.tasklist` and `awful.widget.taglist` will now set the + `client` and `tag` properly respectively on each widget of the template + automatically. This reduces the amount of boilerplate code. ## Noteworthy fixes