diff --git a/awesomerc.lua b/awesomerc.lua index 411377ded..5981f8a40 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) -- }}} diff --git a/lib/awful/placement.lua b/lib/awful/placement.lua index c7599e8ae..e12add91c 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") @@ -276,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 @@ -477,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 @@ -486,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 diff --git a/lib/awful/wibar.lua b/lib/awful/wibar.lua index 6371a7a11..ff2507809 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> @@ -28,6 +30,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,16 +42,94 @@ 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" +} + +local align_map = { + top = "left", + left = "top", + bottom = "right", + right = "bottom", + centered = "centered" +} + --- If the wibar needs to be stretched to fill the screen. +-- +-- @DOC_awful_wibar_stretch_EXAMPLE@ +-- -- @property stretch -- @tparam boolean stretch -- @propbeautiful -- @propemits true false +-- @see align + +--- How to align non-stretched wibars. +-- +-- Values are: +-- +-- * `"top"` +-- * `"bottom"` +-- * `"left"` +-- * `"right"` +-- * `"centered"` +-- +-- @DOC_awful_wibar_align_EXAMPLE@ +-- +-- @property align +-- @tparam string align +-- @propbeautiful +-- @propemits true false +-- @see stretch + +--- 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 applies to all four sides. +-- +-- @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 restrict_workarea +-- @tparam[opt=true] boolean restrict_workarea +-- @propemits true false +-- @see client.struts +-- @see screen.workarea + +--- 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 + --- The wibar border width. -- @beautiful beautiful.wibar_border_width -- @tparam integer border_width @@ -97,6 +178,15 @@ 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 + +--- 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) local h_or_w = (position == "top" or position == "bottom") and "height" or "width" @@ -108,7 +198,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,32 +218,49 @@ 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 + 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 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, + update_workarea = wb._private.restrict_workarea, margins = get_margins(wb) }) end @@ -173,15 +288,23 @@ end -- * top -- * bottom -- +-- @DOC_awful_wibar_position_EXAMPLE@ +-- -- @property position -- @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() @@ -192,14 +315,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") @@ -218,7 +339,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. @@ -228,11 +349,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) @@ -240,10 +361,89 @@ local function set_stretch(w, value) w:emit_signal("property::stretch", value) end + +function awfulwibar.get_restrict_workarea(w) + return w._private.restrict_workarea +end + +function awfulwibar.set_restrict_workarea(w, value) + w._private.restrict_workarea = value + + attach(w, w.position) + + w:emit_signal("property::restrict_workarea", value) +end + + +function awfulwibar.set_margins(w, value) + if type(value) == "number" then + value = { + top = value, + bottom = value, + right = value, + left = value, + } + end + + local old = gtable.crush({ + left = 0, + right = 0, + top = 0, + bottom = 0 + }, w._private.margins or {}, true) + + value = gtable.crush(old, value or {}, true) + + 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 + + +function awfulwibar.get_align(self) + return self._private.align +end + +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 + + attach(self, self.position) + + self:emit_signal("property::align", value) +end + --- Remove a wibar. -- @method remove -local function remove(self) +function awfulwibar.remove(self) self.visible = false if self.detach_callback then @@ -260,26 +460,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:get_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:set_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 @@ -290,7 +470,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} @@ -319,7 +499,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" @@ -351,6 +531,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.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@ -- @return The new wibar -- @constructorfct awful.wibar @@ -400,7 +583,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", "align" } do if (args[prop] == nil) and beautiful["wibar_"..prop] ~= nil then args[prop] = beautiful["wibar_"..prop] @@ -409,25 +592,37 @@ function awfulwibar.new(args) local w = wibox(args) - 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._private.align = (args.align and align_map[args.align]) and args.align or "centered" - w.get_position = get_position - w.set_position = set_position + w._private.margins = { + left = 0, + right = 0, + top = 0, + bottom = 0 + } + w._private.meta_margins = meta_margins(w) - w.get_stretch = get_stretch - w.set_stretch = set_stretch - w.remove = remove - - if args.visible == nil then w.visible = true end + 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 -- called. `skip_reattach` is required. - w:set_position(position, true) + w._private.skip_reattach = true - table.insert(wiboxes, 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 + + if args.visible == nil then w.visible = true end + + gtable.crush(w, awfulwibar, true) + gtable.crush(w, args, false) + + -- 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) @@ -455,6 +650,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@ diff --git a/lib/naughty/core.lua b/lib/naughty/core.lua index da783839c..0afd55083 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) diff --git a/tests/examples/awful/wibar/align.lua b/tests/examples/awful/wibar/align.lua new file mode 100644 index 000000000..4381be485 --- /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 000000000..e49ca87b3 --- /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 000000000..f017b463b --- /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 000000000..7ee8df342 --- /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 000000000..35b5c5f88 --- /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/client_snap.lua b/tests/examples/screen/client_snap.lua index 25b635e67..19d97ccbb 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 fd09a79ee..274ac0b7b 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 53a75434c..633ffc071 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 d8f358ca4..d495a1e42 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 544c5833b..85cb5a460 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 b7765cd18..a32f62828 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 569a4962e..2465526af 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 e096758d2..8e54c8b94 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 10767a4e3..d89cb40d7 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 f44980f93..ea92fe161 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 3f8b54f67..323816966 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 dbb467556..42498661b 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 { @@ -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 7a68725fe..4d6f9ed0c 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() @@ -160,11 +162,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 +312,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 +323,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 +409,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 +472,7 @@ local function draw_struts(s) if left > 0 then draw_hruler( s, - 0, + s.geometry.y*SCALE_FACTOR, get_text_height(), {x = s.geometry.x+tr_x*2, width = left, color = colors.gaps.."66", align = true}, 1 @@ -484,7 +483,7 @@ local function draw_struts(s) draw_vruler( s, get_text_height()*1.5, - 0, + s.geometry.x*SCALE_FACTOR, {y=s.geometry.y+tr_y*(1/factor), height = top, color = colors.gaps.."66", align = true}, 1 ) @@ -493,7 +492,7 @@ local function draw_struts(s) if right > 0 then draw_hruler( s, - 0, + s.geometry.y*SCALE_FACTOR, get_text_height(), {x = s.geometry.x, width = left, color = colors.gaps.."66", align = true}, 1 @@ -504,7 +503,7 @@ local function draw_struts(s) draw_vruler( s, get_text_height()*1.5, - 0, + s.geometry.x*SCALE_FACTOR, { y = s.geometry.y+tr_y*(1/factor)+s.geometry.height - bottom, height = bottom, @@ -667,8 +666,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") @@ -692,23 +691,22 @@ 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() 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 * SCALE_FACTOR) -- 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 +725,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 +740,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 dceff3478..677942312 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 5b80e6128..4f4024fb7 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/wibar_workarea.lua b/tests/examples/screen/wibar_workarea.lua new file mode 100644 index 000000000..869d6dc1b --- /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", + restrict_workarea = true, + height = 24, + screen = screen[1], +} + +--DOC_NEWLINE + +local screen2_wibar = awful.wibar { + position = "top", + restrict_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 diff --git a/tests/examples/screen/workarea.lua b/tests/examples/screen/workarea.lua index 26a2266ae..4f4b0e8f4 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 diff --git a/tests/examples/shims/screen.lua b/tests/examples/shims/screen.lua index b969fa3b4..47a01d943 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 diff --git a/tests/test-struts.lua b/tests/test-struts.lua index 5e4e17da1..2cfee9253 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