From 4b606fb3d717037984dda10fbab32d15174b2125 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 5 Jul 2021 01:26:33 -0700 Subject: [PATCH 01/16] notification: Fix rendering during early screen creation. If the problem happens early enough, it was possible that the screen arrway wasn't initialized yet. In that case, the notification would fail to render. --- lib/naughty/core.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/naughty/core.lua b/lib/naughty/core.lua index da783839..0afd5508 100644 --- a/lib/naughty/core.lua +++ b/lib/naughty/core.lua @@ -191,7 +191,9 @@ naughty.notifications = { suspended = { }, _expired = {{}} } naughty._active = {} -screen.connect_for_each_screen(function(s) +local function init_screen(s) + if naughty.notifications[s] then return end + naughty.notifications[s] = { top_left = {}, top_middle = {}, @@ -201,7 +203,9 @@ screen.connect_for_each_screen(function(s) bottom_right = {}, middle = {}, } -end) +end + +screen.connect_for_each_screen(init_screen) capi.screen.connect_signal("removed", function(scr) -- Allow the notifications to be moved to another screen. @@ -646,6 +650,10 @@ local function register(notification, args) assert(s) + if not naughty.notifications[s] then + init_screen(get_screen(s)) + end + -- insert the notification to the table table.insert(naughty._active, notification) table.insert(naughty.notifications[s][notification.position], notification) From d9f27bdf4befbce310dc06325ea7450ea539cfff Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 5 Jul 2021 01:29:07 -0700 Subject: [PATCH 02/16] placement: Do not leak the composed placement "override" in the args. Without this change, if a composed placement was used, it would leak the "override_geometry" in the args, which would be kept cached during the next composed node. If that node had no override of its own, it would use the previous one by accident. In practice, it means it was impossible to resize a `wibar` manually. The `wibar` would always restore itself to the height (or width, for vertical ones) it previously had. --- lib/awful/placement.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/awful/placement.lua b/lib/awful/placement.lua index c7599e8a..32ebd846 100644 --- a/lib/awful/placement.lua +++ b/lib/awful/placement.lua @@ -184,6 +184,10 @@ local function compose(...) attach(d, ret, args) end + -- Cleanup the override because otherwise it might leak into + -- future calls. + rawset(args, "override_geometry", nil) + return last_geo, rets end, "compose") From b4afd0206b99218719339a3a88357c338c5fff2c Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 6 Jul 2021 01:13:48 -0700 Subject: [PATCH 03/16] tests: Make sure wibar resize works. Also add some garbage collection tests. This was my original theory about why resizing was broken, but it turned out something in `awful.placement` leaked, not the wibar references. --- tests/test-struts.lua | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/test-struts.lua b/tests/test-struts.lua index 5e4e17da..2cfee925 100644 --- a/tests/test-struts.lua +++ b/tests/test-struts.lua @@ -9,6 +9,9 @@ local parent, small local twibar, bwibar, lwibar, rwibar = screen.primary.mywibox +-- Track garbage collection. +local wibars = setmetatable({screen.primary.mywibox}, {__mode="v"}) + -- Pretty print issues local function print_expected() local wa, sa = mouse.screen.workarea, mouse.screen.geometry @@ -219,6 +222,9 @@ table.insert(steps, function() bwibar = wibar {position = "bottom", bg = "#00ff00"} lwibar = wibar {position = "left" , bg = "#0000ff"} rwibar = wibar {position = "right" , bg = "#ff00ff"} + table.insert(wibars, bwibar) + table.insert(wibars, lwibar) + table.insert(wibars, rwibar) validate_wibar_geometry() @@ -469,6 +475,16 @@ table.insert(steps, function() rwibar:remove() twibar:remove() + -- Make sure the placement doesn't hold a reference. + bwibar, lwibar, rwibar, twibar = nil, nil, nil, nil + screen.primary.mywibox = nil + + for _=1, 3 do + collectgarbage("collect") + end + + assert(not next(wibars)) + return true end) @@ -497,18 +513,22 @@ table.insert(steps, function() lwibar = wibar{position = "top", screen = s, height = 15, visible = true, bg = "#660066"} lwibar:setup(wdg2) + table.insert(wibars, lwibar) rwibar = wibar{position = "top", screen = s, height = 15, visible = true, bg = "#660000"} rwibar:setup(wdg2) + table.insert(wibars, rwibar) bwibar = wibar{position = "left", screen = s, ontop = true, width = 64, visible = true, bg = "#006600"} bwibar:setup(wdg) + table.insert(wibars, bwibar) twibar = wibar{position = "bottom", screen = s, height = 15, bg = "#666600"} twibar:setup(wdg2) + table.insert(wibars, twibar) test_workarea(s.geometry, s.workarea, 64, 0, 30, 15) validate_wibar_geometry() @@ -536,6 +556,36 @@ table.insert(steps, function() return true end) +-- Test resizing wibars. +table.insert(steps, function() + -- Make sure the placement doesn't hold a reference. + bwibar, lwibar, rwibar, twibar = nil, nil, nil, nil + + for _=1, 3 do + collectgarbage("collect") + end + + assert(not next(wibars)) + + twibar = wibar{position = "top", screen = s, height = 15, + visible = true, bg = "#660066"} + + assert(twibar.height == 15) + + twibar.height = 64 + assert(twibar.height == 64) + + twibar:geometry { height = 128 } + assert(twibar.height == 128) + + local old_width = twibar.width + twibar.width = 42 + assert(twibar.width == old_width) + + + return true +end) + require("_runner").run_steps(steps) -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 From ab977b2358913fe6ce08b4e0be9836d9ca161341 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 5 Jul 2021 15:25:57 -0700 Subject: [PATCH 04/16] placement: Fix the struts size when margins are present. Previously, it only added 1 of the 2 sides of the relevant margins to the struct size. For example, if the position was "top", then only the top margin was added, not the bottom one. --- lib/awful/placement.lua | 45 +++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/lib/awful/placement.lua b/lib/awful/placement.lua index 32ebd846..e12add91 100644 --- a/lib/awful/placement.lua +++ b/lib/awful/placement.lua @@ -280,6 +280,30 @@ local outer_positions = { bottom_middle = function(r, w, _) return {x=r.x-w/2+r.width/2, y=r.y }, "middle" end, } +-- Map the opposite side for a string +local opposites = { + top = "bottom", + bottom = "top", + left = "right", + right = "left", + width = "height", + height = "width", + x = "y", + y = "x", +} + +-- List reletvant sides for each orientation. +local struts_orientation_to_sides = { + horizontal = { "top" , "bottom" }, + vertical = { "left", "right" } +} + +-- Map orientation to the length components (width/height). +local orientation_to_length = { + horizontal = "width", + vertical = "height" +} + --- Add a context to the arguments. -- This function extend the argument table. The context is used by some -- internal helper methods. If there already is a context, it has priority and @@ -481,8 +505,8 @@ wibox_update_strut = function(d, position, args) end -- Detect horizontal or vertical drawables - local geo = area_common(d) - local vertical = geo.width < geo.height + local geo = area_common(d) + local orientation = geo.width < geo.height and "vertical" or "horizontal" -- Look into the `position` string to find the relevants sides to crop from -- the workarea @@ -490,17 +514,12 @@ wibox_update_strut = function(d, position, args) local m = get_decoration(args) - if vertical then - for _, v in ipairs {"right", "left"} do - if (not position) or position:match(v) then - struts[v] = geo.width + m[v] - end - end - else - for _, v in ipairs {"top", "bottom"} do - if (not position) or position:match(v) then - struts[v] = geo.height + m[v] - end + for _, v in ipairs(struts_orientation_to_sides[orientation]) do + if (not position) or position:match(v) then + -- Add the "short" rectangle lenght then the above and below margins. + struts[v] = geo[opposites[orientation_to_length[orientation]]] + + m[v] + + m[opposites[v]] end end From b62f343409ca00c22c8f00173921f124bad2f7ba Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 5 Jul 2021 15:49:02 -0700 Subject: [PATCH 05/16] wibar: Add margins. This is a feature request from Reddit. With this commit, the awful.placement margins are exposed to the wibar API. --- lib/awful/wibar.lua | 94 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 5 deletions(-) diff --git a/lib/awful/wibar.lua b/lib/awful/wibar.lua index 6371a7a1..d5897382 100644 --- a/lib/awful/wibar.lua +++ b/lib/awful/wibar.lua @@ -28,6 +28,7 @@ local wibox = require("wibox") local beautiful = require("beautiful") local gdebug = require("gears.debug") local placement = require("awful.placement") +local gtable = require("gears.table") local function get_screen(s) return s and capi.screen[s] @@ -39,12 +40,29 @@ local awfulwibar = { mt = {} } -- It's an array so it is ordered. local wiboxes = setmetatable({}, {__mode = "v"}) +local opposite_margin = { + top = "bottom", + bottom = "top", + left = "right", + right = "left" +} + --- If the wibar needs to be stretched to fill the screen. -- @property stretch -- @tparam boolean stretch -- @propbeautiful -- @propemits true false +--- Margins on each side of the wibar. +-- +-- It can either be a table if `top`, `bottom`, `left`, `right` or a +-- single number. +-- +-- @property margins +-- @tparam number|table margins +-- @propbeautiful +-- @propemits true false + --- If the wibar needs to be stretched to fill the screen. -- @beautiful beautiful.wibar_stretch -- @tparam boolean stretch @@ -97,6 +115,11 @@ local wiboxes = setmetatable({}, {__mode = "v"}) -- @beautiful beautiful.wibar_shape -- @tparam gears.shape shape +--- The wibar's margins. +-- @beautiful beautiful.wibar_margins +-- @tparam number|table margins + + -- Compute the margin on one side local function get_margin(w, position, auto_stop) local h_or_w = (position == "top" or position == "bottom") and "height" or "width" @@ -108,7 +131,15 @@ local function get_margin(w, position, auto_stop) if v.position == position and v.screen == w.screen and v.visible then ret = ret + v[h_or_w] + + local wb_margins = v.margins + + if wb_margins then + ret = ret + wb_margins[position] + wb_margins[opposite_margin[position]] + end + end + end return ret @@ -120,9 +151,9 @@ local function get_margins(w) local position = w.position assert(position) - local margins = {left=0, right=0, top=0, bottom=0} + local margins = gtable.clone(w._private.margins) - margins[position] = get_margin(w, position, true) + margins[position] = margins[position] + get_margin(w, position, true) -- Avoid overlapping wibars if position == "left" or position == "right" then @@ -240,6 +271,46 @@ local function set_stretch(w, value) w:emit_signal("property::stretch", value) end + +function awfulwibar.set_margins(w, value) + if type(value) == "number" then + value = { + top = value, + bottom = value, + right = value, + left = value, + } + end + + value = value or { + left = 0, + right = 0, + top = 0, + bottom = 0 + } + + w._private.margins = value + + attach(w, w.position) + + w:emit_signal("property::margins", value) +end + +-- Allow each margins to be set individually. +local function meta_margins(self) + return setmetatable({}, { + __index = self._private.margins, + __newindex = function(_, k, v) + self._private.margins[k] = v + awfulwibar.set_margins(self, self._private.margins) + end + }) +end + +function awfulwibar.get_margins(self) + return self._private.meta_margins +end + --- Remove a wibar. -- @method remove @@ -265,7 +336,7 @@ end -- @deprecated awful.wibar.get_position -- @return The wibox position. function awfulwibar.get_position(wb) - gdebug.deprecate("Use wb:get_position() instead of awful.wibar.get_position", {deprecated_in=4}) + gdebug.deprecate("Use wb.position instead of awful.wibar.get_position", {deprecated_in=4}) return get_position(wb) end @@ -275,7 +346,7 @@ end -- @param screen This argument is deprecated, use wb.screen directly. -- @deprecated awful.wibar.set_position function awfulwibar.set_position(wb, position, screen) --luacheck: no unused args - gdebug.deprecate("Use wb:set_position(position) instead of awful.wibar.set_position", {deprecated_in=4}) + gdebug.deprecate("Use `wb.position = position` instead of awful.wibar.set_position", {deprecated_in=4}) set_position(wb, position) end @@ -400,7 +471,7 @@ function awfulwibar.new(args) -- The C code scans the table directly, so metatable magic cannot be used. for _, prop in ipairs { "border_width", "border_color", "font", "opacity", "ontop", "cursor", - "bgimage", "bg", "fg", "type", "stretch", "shape" + "bgimage", "bg", "fg", "type", "stretch", "shape", "margins" } do if (args[prop] == nil) and beautiful["wibar_"..prop] ~= nil then args[prop] = beautiful["wibar_"..prop] @@ -409,6 +480,15 @@ function awfulwibar.new(args) local w = wibox(args) + w._private.margins = { + left = 0, + right = 0, + top = 0, + bottom = 0 + } + w._private.meta_margins = meta_margins(w) + + w.screen = screen w._screen = screen --HACK When a screen is removed, then getbycoords wont work w._stretch = args.stretch == nil and has_to_stretch or args.stretch @@ -420,6 +500,10 @@ function awfulwibar.new(args) w.set_stretch = set_stretch w.remove = remove + w.get_margins = awfulwibar.get_margins + w.set_margins = awfulwibar.set_margins + awfulwibar.set_margins(w, args.margins) + if args.visible == nil then w.visible = true end -- `w` needs to be inserted in `wiboxes` before reattach or its own offset From dab767af3e9726bfd4f7f0f2ba007e7d7b4f3bb0 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 5 Jul 2021 16:40:58 -0700 Subject: [PATCH 06/16] wibar: Restore the ability to align a wibar. This was lost in 3.5->4.0 update, but still had some references in the code and doc. At the time, the plan was to add it back "shortly after" based on the `awful.placement` code, but it was never merged. --- lib/awful/wibar.lua | 73 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/lib/awful/wibar.lua b/lib/awful/wibar.lua index d5897382..ac1f272b 100644 --- a/lib/awful/wibar.lua +++ b/lib/awful/wibar.lua @@ -47,11 +47,36 @@ local opposite_margin = { right = "left" } +local align_map = { + top = "left", + left = "top", + bottom = "right", + right = "bottom", + centered = "centered" +} + --- If the wibar needs to be stretched to fill the screen. -- @property stretch -- @tparam boolean stretch -- @propbeautiful -- @propemits true false +-- see align + +--- How to align non-stretched wibars. +-- +-- Values are: +-- +-- * top +-- * bottom +-- * left +-- * right +-- * centered +-- +-- @property align +-- @tparam string align +-- @propbeautiful +-- @propemits true false +-- @see stretch --- Margins on each side of the wibar. -- @@ -119,6 +144,10 @@ local opposite_margin = { -- @beautiful beautiful.wibar_margins -- @tparam number|table margins +--- The wibar's alignments. +-- @beautiful beautiful.wibar_align +-- @tparam string align + -- Compute the margin on one side local function get_margin(w, position, auto_stop) @@ -165,16 +194,30 @@ local function get_margins(w) end -- Create the placement function -local function gen_placement(position, stretch) +local function gen_placement(position, align, stretch) local maximize = (position == "right" or position == "left") and "maximize_vertically" or "maximize_horizontally" - return placement[position] + (stretch and placement[maximize] or nil) + local corner = nil + + if align ~= "centered" then + if position == "right" or position == "left" then + corner = placement[align .. "_" .. position] + or placement[align_map[align] .. "_" .. position] + else + corner = placement[position .. "_" .. align] + or placement[position .. "_" .. align_map[align]] + end + end + + corner = corner or placement[position] + + return corner + (stretch and placement[maximize] or nil) end -- Attach the placement function. -local function attach(wb, align) - gen_placement(align, wb._stretch)(wb, { +local function attach(wb, position) + gen_placement(position, wb._private.align, wb._stretch)(wb, { attach = true, update_workarea = true, margins = get_margins(wb) @@ -311,6 +354,21 @@ function awfulwibar.get_margins(self) return self._private.meta_margins end + +function awfulwibar.get_align(self) + return self._private.align +end + +function awfulwibar.set_align(self, value) + assert(align_map[value]) + + self._private.align = value + + attach(self, self.position) + + self:emit_signal("property::align", value) +end + --- Remove a wibar. -- @method remove @@ -471,7 +529,7 @@ function awfulwibar.new(args) -- The C code scans the table directly, so metatable magic cannot be used. for _, prop in ipairs { "border_width", "border_color", "font", "opacity", "ontop", "cursor", - "bgimage", "bg", "fg", "type", "stretch", "shape", "margins" + "bgimage", "bg", "fg", "type", "stretch", "shape", "margins", "align" } do if (args[prop] == nil) and beautiful["wibar_"..prop] ~= nil then args[prop] = beautiful["wibar_"..prop] @@ -480,6 +538,8 @@ function awfulwibar.new(args) local w = wibox(args) + w._private.align = (args.align and align_map[args.align]) and args.align or "centered" + w._private.margins = { left = 0, right = 0, @@ -493,6 +553,9 @@ function awfulwibar.new(args) w._screen = screen --HACK When a screen is removed, then getbycoords wont work w._stretch = args.stretch == nil and has_to_stretch or args.stretch + w.get_align = awfulwibar.get_align + w.set_align = awfulwibar.set_align + w.get_position = get_position w.set_position = set_position From 67dc36343738c308916a7706f59a40f192a9f753 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 5 Jul 2021 17:00:11 -0700 Subject: [PATCH 07/16] wibar: Modernize the module structure. Move the burdensome legacy code into local function so the normal `gears.table.crush` module setup can be used. This fixes a couple monior issues where `args` would be ignored. This also makes a minor change to the logic. Changing the position always moves to wibar to the end of the stack. Previously, there was a minor case where it would not. There was also the case when setting the same position twice would move the wibar, which was a bug. --- lib/awful/wibar.lua | 101 +++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 54 deletions(-) diff --git a/lib/awful/wibar.lua b/lib/awful/wibar.lua index ac1f272b..4a56be6b 100644 --- a/lib/awful/wibar.lua +++ b/lib/awful/wibar.lua @@ -251,11 +251,17 @@ end -- @tparam string position Either "left", right", "top" or "bottom" -- @propemits true false -local function get_position(wb) +function awfulwibar.get_position(wb) return wb._position or "top" end -local function set_position(wb, position, skip_reattach) +function awfulwibar.set_position(wb, position, screen) + if position == wb._position then return end + + if screen then + gdebug.deprecate("Use `wb.screen = screen` instead of awful.wibar.set_position", {deprecated_in=4}) + end + -- Detach first to avoid any uneeded callbacks if wb.detach_callback then wb.detach_callback() @@ -266,14 +272,12 @@ local function set_position(wb, position, skip_reattach) -- Move the wibar to the end of the list to avoid messing up the others in -- case there is stacked wibars on one side. - if wb._position then - for k, w in ipairs(wiboxes) do - if w == wb then - table.remove(wiboxes, k) - end + for k, w in ipairs(wiboxes) do + if w == wb then + table.remove(wiboxes, k) end - table.insert(wiboxes, wb) end + table.insert(wiboxes, wb) -- In case the position changed, it may be necessary to reset the size if (wb._position == "left" or wb._position == "right") @@ -292,7 +296,7 @@ local function set_position(wb, position, skip_reattach) -- A way to skip reattach is required when first adding a wibar as it's not -- in the `wiboxes` table yet and can't be added until it's attached. - if not skip_reattach then + if not wb._private.skip_reattach then -- Changing the position will also cause the other margins to be invalidated. -- For example, adding a wibar to the top will change the margins of any left -- or right wibars. To solve, this, they need to be re-attached. @@ -302,11 +306,11 @@ local function set_position(wb, position, skip_reattach) wb:emit_signal("property::position", position) end -local function get_stretch(w) +function awfulwibar.get_stretch(w) return w._stretch end -local function set_stretch(w, value) +function awfulwibar.set_stretch(w, value) w._stretch = value attach(w, w.position) @@ -359,7 +363,16 @@ function awfulwibar.get_align(self) return self._private.align end -function awfulwibar.set_align(self, value) +function awfulwibar.set_align(self, value, screen) + if value == "center" then + gdebug.deprecate("awful.wibar.align(wb, 'center' is deprecated, use 'centered'", {deprecated_in=4}) + value = "centered" + end + + if screen then + gdebug.deprecate("awful.wibar.align 'screen' argument is deprecated", {deprecated_in=4}) + end + assert(align_map[value]) self._private.align = value @@ -372,7 +385,7 @@ end --- Remove a wibar. -- @method remove -local function remove(self) +function awfulwibar.remove(self) self.visible = false if self.detach_callback then @@ -389,26 +402,6 @@ local function remove(self) self._screen = nil end ---- Get a wibox position if it has been set, or return top. --- @param wb The wibox --- @deprecated awful.wibar.get_position --- @return The wibox position. -function awfulwibar.get_position(wb) - gdebug.deprecate("Use wb.position instead of awful.wibar.get_position", {deprecated_in=4}) - return get_position(wb) -end - ---- Put a wibox on a screen at this position. --- @param wb The wibox to attach. --- @param position The position: top, bottom left or right. --- @param screen This argument is deprecated, use wb.screen directly. --- @deprecated awful.wibar.set_position -function awfulwibar.set_position(wb, position, screen) --luacheck: no unused args - gdebug.deprecate("Use `wb.position = position` instead of awful.wibar.set_position", {deprecated_in=4}) - - set_position(wb, position) -end - --- Attach a wibox to a screen. -- -- This function has been moved to the `awful.placement` module. Calling this @@ -419,7 +412,7 @@ end -- @param screen The screen to attach to -- @see awful.placement -- @deprecated awful.wibar.attach -function awfulwibar.attach(wb, position, screen) --luacheck: no unused args +local function legacy_attach(wb, position, screen) --luacheck: no unused args gdebug.deprecate("awful.wibar.attach is deprecated, use the 'attach' property".. " of awful.placement. This method doesn't do anything anymore", {deprecated_in=4} @@ -448,7 +441,7 @@ end -- directly. -- @deprecated awful.wibar.align -- @see awful.placement.align -function awfulwibar.align(wb, align, screen) --luacheck: no unused args +local function legacy_align(wb, align, screen) --luacheck: no unused args if align == "center" then gdebug.deprecate("awful.wibar.align(wb, 'center' is deprecated, use 'centered'", {deprecated_in=4}) align = "centered" @@ -548,33 +541,25 @@ function awfulwibar.new(args) } w._private.meta_margins = meta_margins(w) + -- `w` needs to be inserted in `wiboxes` before reattach or its own offset + -- will not be taken into account by the "older" wibars when `reattach` is + -- called. `skip_reattach` is required. + w._private.skip_reattach = true + w.screen = screen w._screen = screen --HACK When a screen is removed, then getbycoords wont work w._stretch = args.stretch == nil and has_to_stretch or args.stretch - w.get_align = awfulwibar.get_align - w.set_align = awfulwibar.set_align - - w.get_position = get_position - w.set_position = set_position - - w.get_stretch = get_stretch - w.set_stretch = set_stretch - w.remove = remove - - w.get_margins = awfulwibar.get_margins - w.set_margins = awfulwibar.set_margins - awfulwibar.set_margins(w, args.margins) - if args.visible == nil then w.visible = true end - -- `w` needs to be inserted in `wiboxes` before reattach or its own offset - -- will not be taken into account by the "older" wibars when `reattach` is - -- called. `skip_reattach` is required. - w:set_position(position, true) + gtable.crush(w, awfulwibar, true) + gtable.crush(w, args, false) - table.insert(wiboxes, w) + -- Now, let set_position behave normally. + w._private.skip_reattach = false + + awfulwibar.set_margins(w, args.margins) -- Force all the wibars to be moved reattach(w) @@ -602,6 +587,14 @@ function awfulwibar.mt:__call(...) return awfulwibar.new(...) end +function awfulwibar.mt:__index(_, k) + if k == "align" then + return legacy_align + elseif k == "attach" then + return legacy_attach + end +end + --@DOC_wibox_COMMON@ --@DOC_object_COMMON@ From 0828c20a5512be82c6d044a4f6f61b8975c4c9e3 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 5 Jul 2021 17:03:35 -0700 Subject: [PATCH 08/16] rc.lua: Be consistent about how the wibar is created. The syntax was a leftover from ancient time where the wibar constructor could not forward the properties to the wibox and when the wibox didn't take a `widget` argument. I make this change mostly to be consistent with the documentation examples. --- awesomerc.lua | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/awesomerc.lua b/awesomerc.lua index 411377de..5981f8a4 100644 --- a/awesomerc.lua +++ b/awesomerc.lua @@ -179,26 +179,27 @@ screen.connect_signal("request::desktop_decoration", function(s) -- @DOC_WIBAR@ -- Create the wibox - s.mywibox = awful.wibar({ position = "top", screen = s }) - - -- @DOC_SETUP_WIDGETS@ - -- Add widgets to the wibox - s.mywibox.widget = { - layout = wibox.layout.align.horizontal, - { -- Left widgets - layout = wibox.layout.fixed.horizontal, - mylauncher, - s.mytaglist, - s.mypromptbox, - }, - s.mytasklist, -- Middle widget - { -- Right widgets - layout = wibox.layout.fixed.horizontal, - mykeyboardlayout, - wibox.widget.systray(), - mytextclock, - s.mylayoutbox, - }, + s.mywibox = awful.wibar { + position = "top", + screen = s, + -- @DOC_SETUP_WIDGETS@ + widget = { + layout = wibox.layout.align.horizontal, + { -- Left widgets + layout = wibox.layout.fixed.horizontal, + mylauncher, + s.mytaglist, + s.mypromptbox, + }, + s.mytasklist, -- Middle widget + { -- Right widgets + layout = wibox.layout.fixed.horizontal, + mykeyboardlayout, + wibox.widget.systray(), + mytextclock, + s.mylayoutbox, + }, + } } end) -- }}} From 529a6c2a8d5f787c0117a4b399e9e7d54d49f0e3 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 5 Jul 2021 18:08:06 -0700 Subject: [PATCH 09/16] wibar: Expose update_workarea. It is now possible to create wibars which are not changing the tiled area. --- lib/awful/wibar.lua | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/awful/wibar.lua b/lib/awful/wibar.lua index 4a56be6b..7b326424 100644 --- a/lib/awful/wibar.lua +++ b/lib/awful/wibar.lua @@ -92,6 +92,14 @@ local align_map = { -- @beautiful beautiful.wibar_stretch -- @tparam boolean stretch +--- Allow or deny the tiled clients to cover the wibar. +-- +-- @property update_workarea +-- @tparam[opt=true] boolean update_workarea +-- @propemits true false +-- @see client.struts +-- @see screen.workarea + --- The wibar border width. -- @beautiful beautiful.wibar_border_width -- @tparam integer border_width @@ -219,7 +227,7 @@ end local function attach(wb, position) gen_placement(position, wb._private.align, wb._stretch)(wb, { attach = true, - update_workarea = true, + update_workarea = wb._private.update_workarea, margins = get_margins(wb) }) end @@ -319,6 +327,19 @@ function awfulwibar.set_stretch(w, value) end +function awfulwibar.get_update_workarea(w) + return w._private.update_workarea +end + +function awfulwibar.set_update_workarea(w, value) + w._private.update_workarea = value + + attach(w, w.position) + + w:emit_signal("property::update_workarea", value) +end + + function awfulwibar.set_margins(w, value) if type(value) == "number" then value = { @@ -541,6 +562,8 @@ function awfulwibar.new(args) } w._private.meta_margins = meta_margins(w) + w._private.update_workarea = true + -- `w` needs to be inserted in `wiboxes` before reattach or its own offset -- will not be taken into account by the "older" wibars when `reattach` is -- called. `skip_reattach` is required. From b88385527272ae279a2afb48bced4d90aa4cd163 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 5 Jul 2021 22:18:28 -0700 Subject: [PATCH 10/16] wibar: Allow to configure how conflicts between wibars are resolved. Previously, the horizontal wibars would always get priority. Now, this can be configured. --- lib/awful/wibar.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/awful/wibar.lua b/lib/awful/wibar.lua index 7b326424..1db40cd7 100644 --- a/lib/awful/wibar.lua +++ b/lib/awful/wibar.lua @@ -100,6 +100,11 @@ local align_map = { -- @see client.struts -- @see screen.workarea +--- If there is both vertical and horizontal wibar, give more space to vertical ones. +-- +-- @beautiful beautiful.wibar_favor_vertical +-- @tparam[opt=false] boolean favor_vertical + --- The wibar border width. -- @beautiful beautiful.wibar_border_width -- @tparam integer border_width @@ -193,9 +198,12 @@ local function get_margins(w) margins[position] = margins[position] + get_margin(w, position, true) -- Avoid overlapping wibars - if position == "left" or position == "right" then + if (position == "left" or position == "right") and not beautiful.wibar_favor_vertical then margins.top = get_margin(w, "top" ) margins.bottom = get_margin(w, "bottom") + elseif (position == "top" or position == "bottom") and beautiful.wibar_favor_vertical then + margins.left = get_margin(w, "left" ) + margins.right = get_margin(w, "right") end return margins From a94a4beb6f9a23cc3600965460e8f64692eb62bb Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 6 Jul 2021 00:12:54 -0700 Subject: [PATCH 11/16] doc: Add a missing DOC_HIDE which damaged the rendering. --- tests/examples/screen/struts.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/examples/screen/struts.lua b/tests/examples/screen/struts.lua index dbb46755..d8ac11db 100644 --- a/tests/examples/screen/struts.lua +++ b/tests/examples/screen/struts.lua @@ -6,7 +6,7 @@ local awful = { --DOC_HIDE wibar = require("awful.wibar"), --DOC_HIDE tag = require("awful.tag"), --DOC_HIDE tag_layout = require("awful.layout.suit.tile") --DOC_HIDE -} +} --DOC_HIDE -- Wibars and docked clients are the main users of the struts. local wibar = awful.wibar { From dd6163ffe6e676743bede9f3f5e4e9d04e89e598 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 6 Jul 2021 00:52:21 -0700 Subject: [PATCH 12/16] shims: Fix the screen workarea value. It didn't work with multiple screens. --- tests/examples/shims/screen.lua | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/examples/shims/screen.lua b/tests/examples/shims/screen.lua index b969fa3b..47a01d94 100644 --- a/tests/examples/shims/screen.lua +++ b/tests/examples/shims/screen.lua @@ -1,21 +1,35 @@ local gears_obj = require("gears.object") local gears_tab = require("gears.table") +local grect = require("gears.geometry").rectangle local screen, meta = awesome._shim_fake_class() screen._count, screen._deleted = 0, {} +local function get_drawin_screen(s, d) + return grect.area_intersect_area (s.geometry, { + x = d:geometry().x, + y = d:geometry().y, + width = 1, + height = 1 + }) +end + local function compute_workarea(s) local struts = {top=0,bottom=0,left=0,right=0} for _, c in ipairs(drawin.get()) do - for k,v in pairs(struts) do - struts[k] = v + (c:struts()[k] or 0) + if get_drawin_screen(s, c) then + for k,v in pairs(struts) do + struts[k] = v + (c:struts()[k] or 0) + end end end for _, c in ipairs(client.get()) do - for k,v in pairs(struts) do - struts[k] = v + (c:struts()[k] or 0) + if c.screen == s then + for k,v in pairs(struts) do + struts[k] = v + (c:struts()[k] or 0) + end end end From b2368c54a8e1aacf43972900717033d6cc1363ce Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 6 Jul 2021 00:53:21 -0700 Subject: [PATCH 13/16] tests: Fix the `screen` template rendering with multiple screens. It only worked for a single screen. It still isn't perfect, but much better than it was. --- tests/examples/screen/client_snap.lua | 2 +- .../screen/gap_single_client_false.lua | 2 +- .../screen/gap_single_client_true.lua | 2 +- tests/examples/screen/gaps.lua | 2 +- tests/examples/screen/gaps2.lua | 2 +- tests/examples/screen/geometry.lua | 8 +- tests/examples/screen/mfpol.lua | 4 +- tests/examples/screen/mfpol2.lua | 2 +- tests/examples/screen/mwfact.lua | 2 +- tests/examples/screen/mwfact2.lua | 2 +- tests/examples/screen/padding.lua | 8 +- tests/examples/screen/struts.lua | 4 +- tests/examples/screen/template.lua | 84 +++++++++---------- tests/examples/screen/tiled_clients.lua | 2 +- tests/examples/screen/tiling_area.lua | 2 +- tests/examples/screen/workarea.lua | 4 +- 16 files changed, 66 insertions(+), 66 deletions(-) diff --git a/tests/examples/screen/client_snap.lua b/tests/examples/screen/client_snap.lua index 25b635e6..19d97ccb 100644 --- a/tests/examples/screen/client_snap.lua +++ b/tests/examples/screen/client_snap.lua @@ -39,7 +39,7 @@ local clients = { return { factor = 2 , show_boxes = true, - draw_wibar = wibar, + draw_wibars = {wibar}, draw_clients = clients, display_screen_info = false, draw_client_snap = true, --FIXME diff --git a/tests/examples/screen/gap_single_client_false.lua b/tests/examples/screen/gap_single_client_false.lua index fd09a79e..274ac0b7 100644 --- a/tests/examples/screen/gap_single_client_false.lua +++ b/tests/examples/screen/gap_single_client_false.lua @@ -35,7 +35,7 @@ local clients = { return { factor = 2 , show_boxes = true, - draw_wibar = wibar, + draw_wibars = {wibar}, draw_clients = clients, display_screen_info = false, draw_gaps = true, diff --git a/tests/examples/screen/gap_single_client_true.lua b/tests/examples/screen/gap_single_client_true.lua index 53a75434..633ffc07 100644 --- a/tests/examples/screen/gap_single_client_true.lua +++ b/tests/examples/screen/gap_single_client_true.lua @@ -35,7 +35,7 @@ local clients = { return { factor = 2 , show_boxes = true, - draw_wibar = wibar, + draw_wibars = {wibar}, draw_clients = clients, display_screen_info = false, draw_gaps = true, diff --git a/tests/examples/screen/gaps.lua b/tests/examples/screen/gaps.lua index d8f358ca..d495a1e4 100644 --- a/tests/examples/screen/gaps.lua +++ b/tests/examples/screen/gaps.lua @@ -36,7 +36,7 @@ local clients = { return { factor = 2 , show_boxes = true, - draw_wibar = wibar, + draw_wibars = {wibar}, draw_clients = clients, display_screen_info = false, draw_gaps = true, diff --git a/tests/examples/screen/gaps2.lua b/tests/examples/screen/gaps2.lua index 544c5833..85cb5a46 100644 --- a/tests/examples/screen/gaps2.lua +++ b/tests/examples/screen/gaps2.lua @@ -36,7 +36,7 @@ local clients = { return { factor = 2 , show_boxes = true, - draw_wibar = wibar, + draw_wibars = {wibar}, draw_clients = clients, display_screen_info = false, draw_gaps = true, diff --git a/tests/examples/screen/geometry.lua b/tests/examples/screen/geometry.lua index b7765cd1..a32f6282 100644 --- a/tests/examples/screen/geometry.lua +++ b/tests/examples/screen/geometry.lua @@ -29,8 +29,8 @@ end --DOC_HIDE } return { --DOC_HIDE - factor = 2 , --DOC_HIDE - show_boxes = false, --DOC_HIDE - highlight_geometry = true , --DOC_HIDE - draw_wibar = wibar, --DOC_HIDE + factor = 2 , --DOC_HIDE + show_boxes = false , --DOC_HIDE + highlight_geometry = true , --DOC_HIDE + draw_wibars = {wibar}, --DOC_HIDE } --DOC_HIDE diff --git a/tests/examples/screen/mfpol.lua b/tests/examples/screen/mfpol.lua index 569a4962..2465526a 100644 --- a/tests/examples/screen/mfpol.lua +++ b/tests/examples/screen/mfpol.lua @@ -45,9 +45,9 @@ for _,c in ipairs(clients) do end return { - factor = 2 , + factor = 2, show_boxes = true, - draw_wibar = wibar, + draw_wibars = {wibar}, draw_clients = clients, display_screen_info = false, } diff --git a/tests/examples/screen/mfpol2.lua b/tests/examples/screen/mfpol2.lua index e096758d..8e54c8b9 100644 --- a/tests/examples/screen/mfpol2.lua +++ b/tests/examples/screen/mfpol2.lua @@ -47,7 +47,7 @@ end return { factor = 2 , show_boxes = true, - draw_wibar = wibar, + draw_wibars = {wibar}, draw_clients = clients, display_screen_info = false, } diff --git a/tests/examples/screen/mwfact.lua b/tests/examples/screen/mwfact.lua index 10767a4e..d89cb40d 100644 --- a/tests/examples/screen/mwfact.lua +++ b/tests/examples/screen/mwfact.lua @@ -48,7 +48,7 @@ end return { factor = 2 , show_boxes = true, - draw_wibar = wibar, + draw_wibars = {wibar}, draw_clients = clients, display_screen_info = false, draw_mwfact = true, diff --git a/tests/examples/screen/mwfact2.lua b/tests/examples/screen/mwfact2.lua index f44980f9..ea92fe16 100644 --- a/tests/examples/screen/mwfact2.lua +++ b/tests/examples/screen/mwfact2.lua @@ -51,7 +51,7 @@ end return { factor = 2 , show_boxes = true, - draw_wibar = wibar, + draw_wibars = {wibar}, draw_clients = clients, display_screen_info = false, draw_mwfact = true, diff --git a/tests/examples/screen/padding.lua b/tests/examples/screen/padding.lua index 3f8b54f6..32381696 100644 --- a/tests/examples/screen/padding.lua +++ b/tests/examples/screen/padding.lua @@ -32,8 +32,8 @@ end --DOC_HIDE } --DOC_HIDE return { --DOC_HIDE - factor = 2 , --DOC_HIDE - show_boxes = false, --DOC_HIDE - highlight_padding_area = true , --DOC_HIDE - draw_wibar = wibar, --DOC_HIDE + factor = 2 , --DOC_HIDE + show_boxes = false , --DOC_HIDE + highlight_padding_area = true , --DOC_HIDE + draw_wibars = {wibar}, --DOC_HIDE } --DOC_HIDE diff --git a/tests/examples/screen/struts.lua b/tests/examples/screen/struts.lua index d8ac11db..42498661 100644 --- a/tests/examples/screen/struts.lua +++ b/tests/examples/screen/struts.lua @@ -51,9 +51,9 @@ local clients = { --DOC_HIDE } --DOC_HIDE return { --DOC_HIDE - factor = 2 , --DOC_HIDE + factor = 2, --DOC_HIDE show_boxes = true, --DOC_HIDE - draw_wibar = wibar, --DOC_HIDE + draw_wibars = {wibar}, --DOC_HIDE draw_clients = clients, --DOC_HIDE display_screen_info = false, --DOC_HIDE draw_struts = true, --DOC_HIDE diff --git a/tests/examples/screen/template.lua b/tests/examples/screen/template.lua index 7a68725f..be2d8db8 100644 --- a/tests/examples/screen/template.lua +++ b/tests/examples/screen/template.lua @@ -160,11 +160,12 @@ local function draw_client(_, c, name, offset, label, alpha) end -local function compute_ruler(_, rect, name) - table.insert(hrulers, { +local function compute_ruler(s, rect, name) + hrulers[s], vrulers[s] = hrulers[s] or {}, vrulers[s] or {} + table.insert(hrulers[s], { label = name, x = rect.x, width = rect.width }) - table.insert(vrulers, { + table.insert(vrulers[s], { label = name, y = rect.y, height = rect.height }) end @@ -309,8 +310,8 @@ end local function draw_rulers(s) -- The table has a maximum of 4 entries, the sort algorithm is irrelevant. - while not bubble_sort(hrulers, "x", "width" ) do end - while not bubble_sort(vrulers, "y", "height") do end + while not bubble_sort(hrulers[s], "x", "width" ) do end + while not bubble_sort(vrulers[s], "y", "height") do end cr:set_line_width(1) cr:set_dash(nil) @@ -320,7 +321,7 @@ local function draw_rulers(s) dx = get_text_height() + 10 - for k, ruler in ipairs(vrulers) do + for k, ruler in ipairs(vrulers[s]) do draw_vruler(s, dx, sx, ruler, k) end @@ -406,10 +407,6 @@ local function evaluate_translation(draw_gaps, draw_struts, draw_mwfact, draw_cl end end -local function translate() - cr:translate(tr_x, tr_y * 0.66) -end - local function draw_gaps(s) cr:translate(-tr_x, -tr_y) @@ -473,7 +470,7 @@ local function draw_struts(s) if left > 0 then draw_hruler( s, - 0, + s.geometry.y*0.66, get_text_height(), {x = s.geometry.x+tr_x*2, width = left, color = colors.gaps.."66", align = true}, 1 @@ -484,7 +481,7 @@ local function draw_struts(s) draw_vruler( s, get_text_height()*1.5, - 0, + s.geometry.x*0.66, {y=s.geometry.y+tr_y*(1/factor), height = top, color = colors.gaps.."66", align = true}, 1 ) @@ -493,7 +490,7 @@ local function draw_struts(s) if right > 0 then draw_hruler( s, - 0, + s.geometry.y*0.66, get_text_height(), {x = s.geometry.x, width = left, color = colors.gaps.."66", align = true}, 1 @@ -504,7 +501,7 @@ local function draw_struts(s) draw_vruler( s, get_text_height()*1.5, - 0, + s.geometry.x*0.66, { y = s.geometry.y+tr_y*(1/factor)+s.geometry.height - bottom, height = bottom, @@ -667,8 +664,8 @@ local function draw_info(s) end -- Compute the rulers size. -for _=1, screen.count() do - local s = screen[1] +for k=1, screen.count() do + local s = screen[k] -- The padding. compute_ruler(s, s.tiling_area, "tiling_area") @@ -699,16 +696,15 @@ sew, seh = sew + 5*get_text_height(), seh + 5*get_text_height() img = cairo.SvgSurface.create(image_path..".svg", sew, seh) cr = cairo.Context(img) -cr:set_line_width(1.5) -cr:set_dash({10,4},1) - -- Instead of adding origin offset everywhere, translate the viewport. -translate() +cr:translate(tr_x, tr_y * 0.66) -- Draw the various areas. for k=1, screen.count() do - local s = screen[1] + local s = screen[k] + cr:set_line_width(1.5) + cr:set_dash({10,4},1) -- The outer geometry. draw_area(s, s.geometry, "geometry", (k-1)*10, args.highlight_geometry) @@ -727,8 +723,10 @@ for k=1, screen.count() do draw_rulers(s) -- Draw the wibar. - if args.draw_wibar then - draw_struct(s, args.draw_wibar, 'wibar', (k-1)*10, 'Wibar') + for _, wibar in ipairs(args.draw_wibars or {}) do + if wibar.screen == s then + draw_struct(s, wibar, 'wibar', (k-1)*10, 'Wibar') + end end local skip_gaps = s.selected_tag @@ -740,28 +738,30 @@ for k=1, screen.count() do -- Draw clients. if args.draw_clients then for label,c in pairs(args.draw_clients) do - local gap = c:tags()[1].gap - if args.draw_gaps and gap > 0 and (not c.floating) and not skip_gaps then - local proxy = { - x = c.x - gap, - y = c.y - gap, - width = c.width + 2*gap, - height = c.height + 2*gap, - } + if c.screen == s then + local gap = c:tags()[1].gap + if args.draw_gaps and gap > 0 and (not c.floating) and not skip_gaps then + local proxy = { + x = c.x - gap, + y = c.y - gap, + width = c.width + 2*gap, + height = c.height + 2*gap, + } - draw_client(s, proxy, 'gaps', (k-1)*10, nil, "11") - elseif args.draw_client_snap and c.floating then - local proxy = { - x = c.x - sd, - y = c.y - sd, - width = c.width + 2*sd, - height = c.height + 2*sd, - } + draw_client(s, proxy, 'gaps', (k-1)*10, nil, "11") + elseif args.draw_client_snap and c.floating then + local proxy = { + x = c.x - sd, + y = c.y - sd, + width = c.width + 2*sd, + height = c.height + 2*sd, + } - draw_client(s, proxy, 'gaps', (k-1)*10, nil, "11") + draw_client(s, proxy, 'gaps', (k-1)*10, nil, "11") + end + + draw_client(s, c, 'tiling_client', (k-1)*10, label) end - - draw_client(s, c, 'tiling_client', (k-1)*10, label) end end diff --git a/tests/examples/screen/tiled_clients.lua b/tests/examples/screen/tiled_clients.lua index dceff347..67794231 100644 --- a/tests/examples/screen/tiled_clients.lua +++ b/tests/examples/screen/tiled_clients.lua @@ -47,7 +47,7 @@ end return { factor = 2 , show_boxes = true, - draw_wibar = wibar, + draw_wibars = {wibar}, draw_clients = clients, display_screen_info = false, } diff --git a/tests/examples/screen/tiling_area.lua b/tests/examples/screen/tiling_area.lua index 5b80e612..4f4024fb 100644 --- a/tests/examples/screen/tiling_area.lua +++ b/tests/examples/screen/tiling_area.lua @@ -27,5 +27,5 @@ return { factor = 2 , show_boxes = false, highlight_tiling_area = true , - draw_wibar = wibar, + draw_wibars = {wibar}, } diff --git a/tests/examples/screen/workarea.lua b/tests/examples/screen/workarea.lua index 26a2266a..4f4b0e8f 100644 --- a/tests/examples/screen/workarea.lua +++ b/tests/examples/screen/workarea.lua @@ -35,8 +35,8 @@ end --DOC_HIDE } return { --DOC_HIDE - factor = 2 , --DOC_HIDE + factor = 2, --DOC_HIDE show_boxes = false, --DOC_HIDE highlight_workarea = true , --DOC_HIDE - draw_wibar = wibar, --DOC_HIDE + draw_wibars = {wibar}, --DOC_HIDE } --DOC_HIDE From d5d74e44dee9c846bef74464f7c00506ff42d26a Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 6 Jul 2021 01:19:13 -0700 Subject: [PATCH 14/16] doc: Document the wibar module. --- lib/awful/wibar.lua | 32 +++++++- tests/examples/awful/wibar/align.lua | 54 +++++++++++++ tests/examples/awful/wibar/margins.lua | 99 ++++++++++++++++++++++++ tests/examples/awful/wibar/position.lua | 36 +++++++++ tests/examples/awful/wibar/position2.lua | 38 +++++++++ tests/examples/awful/wibar/stretch.lua | 40 ++++++++++ tests/examples/screen/wibar_workarea.lua | 35 +++++++++ 7 files changed, 333 insertions(+), 1 deletion(-) create mode 100644 tests/examples/awful/wibar/align.lua create mode 100644 tests/examples/awful/wibar/margins.lua create mode 100644 tests/examples/awful/wibar/position.lua create mode 100644 tests/examples/awful/wibar/position2.lua create mode 100644 tests/examples/awful/wibar/stretch.lua create mode 100644 tests/examples/screen/wibar_workarea.lua diff --git a/lib/awful/wibar.lua b/lib/awful/wibar.lua index 1db40cd7..b816b483 100644 --- a/lib/awful/wibar.lua +++ b/lib/awful/wibar.lua @@ -1,11 +1,13 @@ --------------------------------------------------------------------------- ---- Wibox module for awful. +--- The main AwesomeWM "bar" module. +-- -- This module allows you to easily create wibox and attach them to the edge of -- a screen. -- --@DOC_awful_wibar_default_EXAMPLE@ -- -- You can even have vertical bars too. +-- --@DOC_awful_wibar_left_EXAMPLE@ -- -- @author Emmanuel Lepage Vallee <elv1313@gmail.com> @@ -56,6 +58,9 @@ local align_map = { } --- If the wibar needs to be stretched to fill the screen. +-- +-- @DOC_awful_wibar_stretch_EXAMPLE@ +-- -- @property stretch -- @tparam boolean stretch -- @propbeautiful @@ -72,6 +77,8 @@ local align_map = { -- * right -- * centered -- +-- @DOC_awful_wibar_align_EXAMPLE@ +-- -- @property align -- @tparam string align -- @propbeautiful @@ -83,17 +90,26 @@ local align_map = { -- It can either be a table if `top`, `bottom`, `left`, `right` or a -- single number. -- +-- @DOC_awful_wibar_margins_EXAMPLE@ +-- -- @property margins -- @tparam number|table margins -- @propbeautiful -- @propemits true false --- If the wibar needs to be stretched to fill the screen. +-- -- @beautiful beautiful.wibar_stretch -- @tparam boolean stretch --- Allow or deny the tiled clients to cover the wibar. -- +-- In the example below, we can see that the first screen workarea +-- shrunk by the height of the wibar while the second screen is +-- unchanged. +-- +-- @DOC_screen_wibar_workarea_EXAMPLE@ +-- -- @property update_workarea -- @tparam[opt=true] boolean update_workarea -- @propemits true false @@ -102,6 +118,15 @@ local align_map = { --- If there is both vertical and horizontal wibar, give more space to vertical ones. -- +-- By default, if multiple wibars risk overlapping, it will be resolved +-- by giving more space to the horizontal one: +-- +-- ![wibar position](../images/AUTOGEN_awful_wibar_position.svg) +-- +-- If this variable is to to `true`, it will behave like: +-- +-- @DOC_awful_wibar_position2_EXAMPLE@ +-- -- @beautiful beautiful.wibar_favor_vertical -- @tparam[opt=false] boolean favor_vertical @@ -263,6 +288,8 @@ end -- * top -- * bottom -- +-- @DOC_awful_wibar_position_EXAMPLE@ +-- -- @property position -- @tparam string position Either "left", right", "top" or "bottom" -- @propemits true false @@ -502,6 +529,9 @@ end -- @tparam[opt=nil] table args -- @tparam string args.position The position. -- @tparam string args.stretch If the wibar need to be stretched to fill the screen. +-- @tparam boolean args.update_workarea Allow or deny the tiled clients to cover the wibar. +-- @tparam string args.align How to align non-stretched wibars. +-- @tparam table|number args.margins The wibar margins. --@DOC_wibox_constructor_COMMON@ -- @return The new wibar -- @constructorfct awful.wibar diff --git a/tests/examples/awful/wibar/align.lua b/tests/examples/awful/wibar/align.lua new file mode 100644 index 00000000..4381be48 --- /dev/null +++ b/tests/examples/awful/wibar/align.lua @@ -0,0 +1,54 @@ +--DOC_GEN_IMAGE +--DOC_HIDE_START +local awful = require("awful") +local wibox = require("wibox") + +screen._track_workarea = true +screen[1]._resize {width = 360, height = 60} +screen._add_screen {x = 0, width = 360, height = 64, y = 72} --DOC_HIDE +screen._add_screen {x = 0, width = 360, height = 64, y = 144} --DOC_HIDE +screen._add_screen {x = 372, width = 64, height = 210, y = 0} --DOC_HIDE +screen._add_screen {x = 444, width = 64, height = 210, y = 0} --DOC_HIDE +screen._add_screen {x = 516, width = 64, height = 210, y = 0} --DOC_HIDE + +--DOC_HIDE_END + +for s, align in ipairs { "left", "centered", "right" } do + awful.wibar { + position = "top", + screen = screen[s], + stretch = false, + width = 196, + align = align, + widget = { + text = align, + align = "center", + widget = wibox.widget.textbox + }, + } +end + +--DOC_NEWLINE + +for s, align in ipairs { "top", "centered", "bottom" } do + awful.wibar { + position = "left", + screen = screen[s+3], + stretch = false, + height = 128, + align = align, + widget = { + { + text = align, + align = "center", + widget = wibox.widget.textbox + }, + direction = "east", + widget = wibox.container.rotate + }, + } +end + + +--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 + diff --git a/tests/examples/awful/wibar/margins.lua b/tests/examples/awful/wibar/margins.lua new file mode 100644 index 00000000..e49ca87b --- /dev/null +++ b/tests/examples/awful/wibar/margins.lua @@ -0,0 +1,99 @@ +--DOC_GEN_IMAGE +--DOC_HIDE_START +local awful = require("awful") +local wibox = require("wibox") +local beautiful = require("beautiful") + +screen._track_workarea = true +screen[1]._resize {width = 480, height = 128} +screen._add_screen {x = 0, width = 480, height = 128, y = 140} + +local t1 = awful.tag.add("1", { + screen = screen[1], + selected = true, + layout = awful.layout.suit.tile.right, + gap = 4 +}) + +local c1 = client.gen_fake {hide_first=true, screen = screen[2]} +c1:tags{t1} + +local t2 = awful.tag.add("1", { + screen = screen[2], + selected = true, + layout = awful.layout.suit.tile.right, + gap = 4 +}) + +local c2 = client.gen_fake {hide_first=true} +c2:tags{t2} + +for _, c in ipairs {c1, c2} do + local top_titlebar = awful.titlebar(c, { + size = 20, + bg_normal = beautiful.bg_highligh, + }) + 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 + +--DOC_HIDE_END + +awful.wibar { + position = "top", + screen = screen[1], + stretch = false, + width = 196, + margins = 24, + widget = { + align = "center", + text = "unform margins", + widget = wibox.widget.textbox + } +} + +--DOC_NEWLINE + +awful.wibar { + position = "top", + screen = screen[2], + stretch = false, + width = 196, + margins = { + top = 12, + bottom = 5 + }, + widget = { + align = "center", + text = "non unform margins", + widget = wibox.widget.textbox + } + +} + +awful.layout.arrange(screen[1]) --DOC_HIDE +awful.layout.arrange(screen[2]) --DOC_HIDE +c1:_hide_all() --DOC_HIDE +c2:_hide_all() --DOC_HIDE + +--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/tests/examples/awful/wibar/position.lua b/tests/examples/awful/wibar/position.lua new file mode 100644 index 00000000..f017b463 --- /dev/null +++ b/tests/examples/awful/wibar/position.lua @@ -0,0 +1,36 @@ +--DOC_GEN_IMAGE --DOC_NO_USAGE +--DOC_HIDE_START +local awful = require("awful") +local wibox = require("wibox") + +screen[1]._resize {width = 480, height = 196} +--DOC_HIDE_END + + local colors = { + top = "#ffff00", + bottom = "#ff00ff", + left = "#00ffff", + right = "#ffcc00" + } + + --DOC_NEWLINE + + for _, position in ipairs { "top", "bottom", "left", "right" } do + awful.wibar { + position = position, + bg = colors[position], + widget = { + { + text = position, + align = "center", + widget = wibox.widget.textbox + }, + direction = (position == "left" or position == "right") and + "east" or "north", + widget = wibox.container.rotate + }, + } + end + +--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 + diff --git a/tests/examples/awful/wibar/position2.lua b/tests/examples/awful/wibar/position2.lua new file mode 100644 index 00000000..7ee8df34 --- /dev/null +++ b/tests/examples/awful/wibar/position2.lua @@ -0,0 +1,38 @@ +--DOC_GEN_IMAGE --DOC_NO_USAGE --DOC_HIDE_ALL +--DOC_HIDE_START +local awful = require("awful") +local wibox = require("wibox") +local beautiful = require("beautiful") + +screen[1]._resize {width = 480, height = 196} + + local colors = { + top = "#ffff00", + bottom = "#ff00ff", + left = "#00ffff", + right = "#ffcc00" + } + +--DOC_HIDE_END + beautiful.wibar_favor_vertical = true + --DOC_NEWLINE + + for _, position in ipairs { "top", "bottom", "left", "right" } do + awful.wibar { + position = position, + bg = colors[position], + widget = { + { + text = position, + align = "center", + widget = wibox.widget.textbox + }, + direction = (position == "left" or position == "right") and + "east" or "north", + widget = wibox.container.rotate + }, + } + end + +--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 + diff --git a/tests/examples/awful/wibar/stretch.lua b/tests/examples/awful/wibar/stretch.lua new file mode 100644 index 00000000..35b5c5f8 --- /dev/null +++ b/tests/examples/awful/wibar/stretch.lua @@ -0,0 +1,40 @@ +--DOC_GEN_IMAGE +--DOC_HIDE_START +local awful = require("awful") +local wibox = require("wibox") + +screen._track_workarea = true +screen[1]._resize {width = 480, height = 60} +screen._add_screen {x = 0, width = 480, height = 64, y = 72} --DOC_HIDE + +--DOC_HIDE_END + +awful.wibar { + position = "top", + screen = screen[1], + stretch = true, + width = 196, + widget = { + text = "stretched", + align = "center", + widget = wibox.widget.textbox + }, +} + +--DOC_NEWLINE + +awful.wibar { + position = "top", + screen = screen[2], + stretch = false, + width = 196, + widget = { + text = "not stretched", + align = "center", + widget = wibox.widget.textbox + }, +} + + +--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 + diff --git a/tests/examples/screen/wibar_workarea.lua b/tests/examples/screen/wibar_workarea.lua new file mode 100644 index 00000000..8726e335 --- /dev/null +++ b/tests/examples/screen/wibar_workarea.lua @@ -0,0 +1,35 @@ +--DOC_GEN_IMAGE + +screen[1]._resize {x = 0, width = 640, height = 480} --DOC_HIDE + +screen._add_screen {x = 820, width = 640, height = 480, y = -22} --DOC_HIDE + +local awful = { --DOC_HIDE + wibar = require("awful.wibar"), --DOC_HIDE + tag = require("awful.tag"), --DOC_HIDE + tag_layout = require("awful.layout.suit.tile") --DOC_HIDE +} --DOC_HIDE + +local screen1_wibar = awful.wibar { + position = "top", + update_workarea = true, + height = 24, + screen = screen[1], +} + +--DOC_NEWLINE + +local screen2_wibar = awful.wibar { + position = "top", + update_workarea = false, + height = 24, + screen = screen[2], +} + +return { --DOC_HIDE + factor = 2 , --DOC_HIDE + show_boxes = true, --DOC_HIDE + draw_wibars = {screen1_wibar, screen2_wibar}, --DOC_HIDE + display_screen_info = false, --DOC_HIDE + draw_struts = true, --DOC_HIDE +} --DOC_HIDE From 6ad693eff00861c30a729970ac3d3f646777735f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Lepage=20Vall=C3=A9e?= Date: Wed, 7 Jul 2021 00:42:31 -0700 Subject: [PATCH 15/16] Apply suggestions from code review Co-authored-by: Aire-One --- lib/awful/wibar.lua | 18 +++++++++--------- tests/examples/screen/template.lua | 14 ++++++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/awful/wibar.lua b/lib/awful/wibar.lua index b816b483..d99e4be2 100644 --- a/lib/awful/wibar.lua +++ b/lib/awful/wibar.lua @@ -71,11 +71,11 @@ local align_map = { -- -- Values are: -- --- * top --- * bottom --- * left --- * right --- * centered +-- * `"top"` +-- * `"bottom"` +-- * `"left"` +-- * `"right"` +-- * `"centered"` -- -- @DOC_awful_wibar_align_EXAMPLE@ -- @@ -87,8 +87,8 @@ local align_map = { --- Margins on each side of the wibar. -- --- It can either be a table if `top`, `bottom`, `left`, `right` or a --- single number. +-- It can either be a table with `top`, `bottom`, `left` and `right` +-- properties, or a single number that apply to all fourth sides. -- -- @DOC_awful_wibar_margins_EXAMPLE@ -- @@ -385,12 +385,12 @@ function awfulwibar.set_margins(w, value) } end - value = value or { + value = gtable.crush({ left = 0, right = 0, top = 0, bottom = 0 - } + }, value or {}, true) w._private.margins = value diff --git a/tests/examples/screen/template.lua b/tests/examples/screen/template.lua index be2d8db8..4d6f9ed0 100644 --- a/tests/examples/screen/template.lua +++ b/tests/examples/screen/template.lua @@ -15,6 +15,8 @@ local args = loadfile(file_path)() or 10 args = args or {} args.factor = args.factor or 10 +local SCALE_FACTOR = 0.66 + local factor, img, cr = 1/args.factor require("gears.timer").run_delayed_calls_now() @@ -470,7 +472,7 @@ local function draw_struts(s) if left > 0 then draw_hruler( s, - s.geometry.y*0.66, + s.geometry.y*SCALE_FACTOR, get_text_height(), {x = s.geometry.x+tr_x*2, width = left, color = colors.gaps.."66", align = true}, 1 @@ -481,7 +483,7 @@ local function draw_struts(s) draw_vruler( s, get_text_height()*1.5, - s.geometry.x*0.66, + s.geometry.x*SCALE_FACTOR, {y=s.geometry.y+tr_y*(1/factor), height = top, color = colors.gaps.."66", align = true}, 1 ) @@ -490,7 +492,7 @@ local function draw_struts(s) if right > 0 then draw_hruler( s, - s.geometry.y*0.66, + s.geometry.y*SCALE_FACTOR, get_text_height(), {x = s.geometry.x, width = left, color = colors.gaps.."66", align = true}, 1 @@ -501,7 +503,7 @@ local function draw_struts(s) draw_vruler( s, get_text_height()*1.5, - s.geometry.x*0.66, + s.geometry.x*SCALE_FACTOR, { y = s.geometry.y+tr_y*(1/factor)+s.geometry.height - bottom, height = bottom, @@ -689,7 +691,7 @@ evaluate_translation( local sew, seh = screen._get_extents() sew, seh = sew/args.factor + (screen.count()-1)*10+2, seh/args.factor+2 -sew, seh = sew + tr_x, seh + 0.66*tr_y +sew, seh = sew + tr_x, seh + SCALE_FACTOR*tr_y sew, seh = sew + 5*get_text_height(), seh + 5*get_text_height() @@ -697,7 +699,7 @@ img = cairo.SvgSurface.create(image_path..".svg", sew, seh) cr = cairo.Context(img) -- Instead of adding origin offset everywhere, translate the viewport. -cr:translate(tr_x, tr_y * 0.66) +cr:translate(tr_x, tr_y * SCALE_FACTOR) -- Draw the various areas. for k=1, screen.count() do From 73e908ed95478486cc3766f13fa34e856c206986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Lepage=20Vall=C3=A9e?= Date: Tue, 7 Sep 2021 14:00:15 -0700 Subject: [PATCH 16/16] Apply suggestions from code review Co-authored-by: Lucas Schwiderski <4508454+sclu1034@users.noreply.github.com> --- lib/awful/wibar.lua | 30 +++++++++++++----------- tests/examples/screen/wibar_workarea.lua | 16 ++++++------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/lib/awful/wibar.lua b/lib/awful/wibar.lua index d99e4be2..ff250780 100644 --- a/lib/awful/wibar.lua +++ b/lib/awful/wibar.lua @@ -65,7 +65,7 @@ local align_map = { -- @tparam boolean stretch -- @propbeautiful -- @propemits true false --- see align +-- @see align --- How to align non-stretched wibars. -- @@ -88,7 +88,7 @@ local align_map = { --- Margins on each side of the wibar. -- -- It can either be a table with `top`, `bottom`, `left` and `right` --- properties, or a single number that apply to all fourth sides. +-- properties, or a single number that applies to all four sides. -- -- @DOC_awful_wibar_margins_EXAMPLE@ -- @@ -110,8 +110,8 @@ local align_map = { -- -- @DOC_screen_wibar_workarea_EXAMPLE@ -- --- @property update_workarea --- @tparam[opt=true] boolean update_workarea +-- @property restrict_workarea +-- @tparam[opt=true] boolean restrict_workarea -- @propemits true false -- @see client.struts -- @see screen.workarea @@ -260,7 +260,7 @@ end local function attach(wb, position) gen_placement(position, wb._private.align, wb._stretch)(wb, { attach = true, - update_workarea = wb._private.update_workarea, + update_workarea = wb._private.restrict_workarea, margins = get_margins(wb) }) end @@ -362,16 +362,16 @@ function awfulwibar.set_stretch(w, value) end -function awfulwibar.get_update_workarea(w) - return w._private.update_workarea +function awfulwibar.get_restrict_workarea(w) + return w._private.restrict_workarea end -function awfulwibar.set_update_workarea(w, value) - w._private.update_workarea = value +function awfulwibar.set_restrict_workarea(w, value) + w._private.restrict_workarea = value attach(w, w.position) - w:emit_signal("property::update_workarea", value) + w:emit_signal("property::restrict_workarea", value) end @@ -385,12 +385,14 @@ function awfulwibar.set_margins(w, value) } end - value = gtable.crush({ + local old = gtable.crush({ left = 0, right = 0, top = 0, bottom = 0 - }, value or {}, true) + }, w._private.margins or {}, true) + + value = gtable.crush(old, value or {}, true) w._private.margins = value @@ -529,7 +531,7 @@ end -- @tparam[opt=nil] table args -- @tparam string args.position The position. -- @tparam string args.stretch If the wibar need to be stretched to fill the screen. --- @tparam boolean args.update_workarea Allow or deny the tiled clients to cover the wibar. +-- @tparam boolean args.restrict_workarea Allow or deny the tiled clients to cover the wibar. -- @tparam string args.align How to align non-stretched wibars. -- @tparam table|number args.margins The wibar margins. --@DOC_wibox_constructor_COMMON@ @@ -600,7 +602,7 @@ function awfulwibar.new(args) } w._private.meta_margins = meta_margins(w) - w._private.update_workarea = true + w._private.restrict_workarea = true -- `w` needs to be inserted in `wiboxes` before reattach or its own offset -- will not be taken into account by the "older" wibars when `reattach` is diff --git a/tests/examples/screen/wibar_workarea.lua b/tests/examples/screen/wibar_workarea.lua index 8726e335..869d6dc1 100644 --- a/tests/examples/screen/wibar_workarea.lua +++ b/tests/examples/screen/wibar_workarea.lua @@ -11,19 +11,19 @@ local awful = { --DOC_HIDE } --DOC_HIDE local screen1_wibar = awful.wibar { - position = "top", - update_workarea = true, - height = 24, - screen = screen[1], + position = "top", + restrict_workarea = true, + height = 24, + screen = screen[1], } --DOC_NEWLINE local screen2_wibar = awful.wibar { - position = "top", - update_workarea = false, - height = 24, - screen = screen[2], + position = "top", + restrict_workarea = false, + height = 24, + screen = screen[2], } return { --DOC_HIDE