From 6244ed7c265c5eb7139307b1382a537376bc8c0c Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 24 Jun 2016 00:46:41 -0400 Subject: [PATCH] api: Update file to match new upstream Awesome APIs Also has some bug fixes mixed in the patch. The Radical placement API is now fully upstreamed. --- bar.lua | 4 +- box.lua | 6 +- context.lua | 2 +- dock.lua | 18 +- hot_corner.lua | 18 +- impl/taglist/init.lua | 14 +- impl/taglist/tracker.lua | 4 - impl/tasklist/init.lua | 6 +- init.lua | 10 +- item/common.lua | 12 +- item/layout/centerred.lua | 12 +- item/layout/horizontal.lua | 6 +- item/layout/icon.lua | 10 +- item/layout/notification.lua | 4 +- item/style/arrow_alt.lua | 2 +- item/style/classic.lua | 8 +- item/style/holo.lua | 4 +- layout/vertical.lua | 6 +- menu_template.lua.tmpl | 2 +- placement.lua | 533 ----------------------------------- radial.lua | 2 +- smart_wibox.lua | 73 ++--- style/arrow.lua | 12 +- tooltip.lua | 4 +- widgets/filter.lua | 2 +- widgets/header.lua | 3 +- widgets/scroll.lua | 4 +- widgets/table.lua | 4 +- 28 files changed, 136 insertions(+), 649 deletions(-) delete mode 100644 placement.lua diff --git a/bar.lua b/bar.lua index 308b410..d513a71 100644 --- a/bar.lua +++ b/bar.lua @@ -21,12 +21,12 @@ local function setup_drawable(data) layout = internal.layout_func or wibox.layout.fixed.horizontal }, id = "main_margin" , - layout = wibox.layout.margin, + layout = wibox.container.margin, }, shape = data.shape or shape.rectangle or nil, shape_border_width = data.border_width , shape_border_color = data.border_color , - widget = wibox.widget.background , + widget = wibox.container.background , } internal.layout = internal.widget:get_children_by_id("main_layout")[1] internal.margin = internal.widget:get_children_by_id("main_margin")[1] diff --git a/box.lua b/box.lua index 03e2a95..0284730 100644 --- a/box.lua +++ b/box.lua @@ -15,11 +15,7 @@ local function new(args) w:set_shape (shape.rounded_rect, 10) - local function f() placement.centered(w) end - - w:connect_signal("property::width" ,f) - w:connect_signal("property::height",f) - f() + w.placement = placement.centered return ret end diff --git a/context.lua b/context.lua index 48a142c..058aa70 100644 --- a/context.lua +++ b/context.lua @@ -30,7 +30,7 @@ local function setup_drawable(data) data.layout = data.layout or layout.vertical internal.layout = data.layout(data) - internal.margin = wibox.layout.margin(internal.layout) + internal.margin = wibox.container.margin(internal.layout) -- Init internal.w = smart_wibox(internal.margin, { diff --git a/dock.lua b/dock.lua index e85eff0..c0d410e 100644 --- a/dock.lua +++ b/dock.lua @@ -12,7 +12,7 @@ local hot_corner = require( "radical.hot_corner" ) local shape = require( "gears.shape" ) local common = require( "radical.common" ) local smart_wibox = require( "radical.smart_wibox" ) -local placement = require( "radical.placement" ) +local aplace = require( "awful.placement" ) local default_radius = 10 local rad = beautiful.dock_corner_radius or default_radius @@ -76,7 +76,7 @@ end local function get_wibox(data, screen) if data._internal.w then return data._internal.w end - data._internal.margin = wibox.layout.margin(data._internal.layout) + data._internal.margin = wibox.container.margin(data._internal.layout) local w = smart_wibox(data._internal.margin, { screen = screen , @@ -85,8 +85,10 @@ local function get_wibox(data, screen) shape_border_width = 1 , shape_border_color = color(data.border_color or data.fg ), bg = color(beautiful.bg_dock or beautiful.bg_normal), + placement = false , }) + data._internal.w = w data:emit_signal("visible::changed",true) @@ -95,14 +97,10 @@ local function get_wibox(data, screen) adapt_size(data, w.width, w.height, 1) end) - local f = nil - if beautiful.dock_always_show then - f = placement.attach_struts - else - f = placement.attach - end - - f(w, placement.align, "left", screen or 1) + aplace.left(w, { + attach = true, + update_workarea = beautiful.dock_always_show + }) return w end diff --git a/hot_corner.lua b/hot_corner.lua index 2337f80..ce0e1e5 100644 --- a/hot_corner.lua +++ b/hot_corner.lua @@ -2,7 +2,7 @@ local capi = {screen = screen} local wibox = require( "wibox" ) local util = require( "awful.util" ) local timer = require( "gears.timer" ) -local placement = require( "radical.placement" ) +local placement = require( "awful.placement" ) local module = {} @@ -40,12 +40,18 @@ end local function create_hot_corner(corner, s) local s = s or 1 - local s_geo = capi.screen[s].geometry - local w_geo = capi.screen[s].workarea - local size = corners_geo[corner](s_geo, w_geo) + + local size = corners_geo[corner] ( + capi.screen[s].geometry, + capi.screen[s].workarea + ) + local w = wibox(util.table.crush(size, {ontop=true, opacity = 0, visible=true})) - placement.align(w, corner, s, false, false) + placement[corner](w, { + parent = capi.screen[s], + attach = true, + }) local req = {wibox = w, screen = s, corner = corner} @@ -123,6 +129,4 @@ function module.register_wibox(corner, w, s, timeout) return req end ---TODO watch for workarea changes - return module diff --git a/impl/taglist/init.lua b/impl/taglist/init.lua index 830615e..506fcdf 100644 --- a/impl/taglist/init.lua +++ b/impl/taglist/init.lua @@ -5,7 +5,7 @@ -- @license BSD --------------------------------------------------------------------------- -local capi = {tag=tag,client=client,screen=screen} +local capi = {tag=tag,client=client,screen=screen,mouse=mouse} local radical = require( "radical" ) local tag = require( "awful.tag" ) @@ -36,7 +36,7 @@ local module,instances = {},{} local cache = setmetatable({}, { __mode = 'k' }) -module.buttons = { [1] = awful.tag.viewonly, +module.buttons = { [1] = function(t) t:view_only() end, [2] = awful.tag.viewtoggle, [3] = function(t,menu,item,button_id,mod,geo) local menu = tag_menu(t) @@ -130,7 +130,7 @@ local function create_item(t,s) end end) - item._internal.screen = s + item._internal.screen = capi.screen[s] item.state[radical.base.item_flags.SELECTED] = t.selected or nil cache[t] = item item.tag = setmetatable({}, { __mode = 'v' }) @@ -156,7 +156,7 @@ local function track_title(c) end local function tag_activated(t) - if not t.activated and cache[t] then + if (not t.activated or not t.screen) and cache[t] then instances[capi.screen[cache[t]._internal.screen]]:remove(cache[t]) cache[t] = nil end @@ -171,7 +171,7 @@ local function tag_added(t,b) -- Creating items when there is no screen cause random behaviors if not item and s then create_item(t,s or capi.mouse.screen) - elseif item._internal.screen ~= s then + elseif item._internal.screen ~= capi.screen[s] then if item._internal.screen then instances[capi.screen[item._internal.screen]]:remove(item) end @@ -180,11 +180,13 @@ local function tag_added(t,b) end --Allow nil - item._internal.screen = s + item._internal.screen = capi.screen[s] end end local function select(t) + if not t.activated then return end + local s = t.selected local item = cache[t] or create_item(t,t.screen or capi.mouse.screen) if item then diff --git a/impl/taglist/tracker.lua b/impl/taglist/tracker.lua index d2574d7..15cdc94 100644 --- a/impl/taglist/tracker.lua +++ b/impl/taglist/tracker.lua @@ -77,9 +77,5 @@ local function new(s) return tracker end - -capi.tag.add_signal("property::index2") - - return setmetatable({}, { __call = function(_, ...) return new(...) end }) -- kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/impl/tasklist/init.lua b/impl/tasklist/init.lua index 945ae74..3e6a855 100644 --- a/impl/tasklist/init.lua +++ b/impl/tasklist/init.lua @@ -45,9 +45,9 @@ module.buttons = { [3] = function(c,menu,item,button_id,mod, geo) client_menu.client = c local menu = client_menu() - menu.parent_geometry = geo +-- menu.parent_geometry = geo menu.visible = not menu.visible - menu._internal.w:move_by_parent(geo, "cursor") + menu._internal.w:move_by_parent(nil, "cursor") end, [4] = function(c,menu,item,button_id,mod, geo) client.focus.byidx(1) @@ -236,6 +236,8 @@ end -- Clear the menu and repopulate it local function load_clients(t) + if not t then return end + local screen = t.screen if not t or not screen or not instances[capi.screen[screen]] then return end local menu = instances[capi.screen[screen]].menu diff --git a/init.lua b/init.lua index ac7a6a4..fcbd608 100644 --- a/init.lua +++ b/init.lua @@ -7,7 +7,7 @@ local beautiful = require( "beautiful" ) -- Define some wibox.widget extensions local function set_tooltip(self, text, args) if not text then return end - self._tooltip = tooltip(self,text, args) + rawset(self, "_tooltip", tooltip(self,text, args)) end --- Set a menu for widget "self". @@ -82,12 +82,12 @@ end base._make_widget =base.make_widget base.make_widget = function(...) local ret = base._make_widget(...) - ret.set_tooltip = set_tooltip - ret.set_menu = set_menu + rawset(ret, "set_tooltip" , set_tooltip) + rawset(ret, "set_menu" , set_menu) -- Textboxes already have it - if not ret.get_preferred_size then - ret.get_preferred_size = get_preferred_size + if not rawget(ret, "get_preferred_size") then + rawset(ret, "get_preferred_size", get_preferred_size) end return ret diff --git a/item/common.lua b/item/common.lua index 990ffc5..a0e6831 100644 --- a/item/common.lua +++ b/item/common.lua @@ -14,9 +14,11 @@ end -- Setup the item icon function module.setup_icon(item,data) --TODO maybe create a proper widget local icon = wibox.widget.imagebox() - icon._data = data - icon._item = item - icon.set_image = set_icon + + rawset(icon, "_data" , data ) + rawset(icon, "_item" , item ) + rawset(icon, "set_image", set_icon) + if item.icon then icon:set_image(item.icon) end @@ -38,6 +40,10 @@ function module.setup_fkey(item,data) end) end item.get_f_key = function() return item._internal.f_key end + + if item._internal.f_key then + item:set_f_key(item._internal.f_key) + end end -- Proxy all events to the parent diff --git a/item/layout/centerred.lua b/item/layout/centerred.lua index ee4eeea..d676e92 100644 --- a/item/layout/centerred.lua +++ b/item/layout/centerred.lua @@ -1,8 +1,8 @@ local setmetatable = setmetatable -local wibox = require( "wibox" ) -local util = require( "awful.util" ) -local margins2 = require( "radical.margins" ) -local common = require( "radical.item.common" ) +local wibox = require( "wibox" ) +local util = require( "awful.util" ) +local margins2 = require( "radical.margins" ) +local common = require( "radical.item.common" ) local function create_item(item,data,args) @@ -20,9 +20,9 @@ local function create_item(item,data,args) layout = wibox.layout.align.horizontal, }, id = "main_margin", - layout = wibox.layout.margin + layout = wibox.container.margin }, - widget = wibox.widget.background, + widget = wibox.container.background, } item.widget = w item._internal.margin_w = item.widget:get_children_by_id("main_margin")[1] diff --git a/item/layout/horizontal.lua b/item/layout/horizontal.lua index c0944ac..2a6ac09 100644 --- a/item/layout/horizontal.lua +++ b/item/layout/horizontal.lua @@ -89,7 +89,7 @@ local function create_item(item,data,args) { icon , right = 3 , - widget = wibox.layout.margin , + widget = wibox.container.margin , }, args.prefix_widget , @@ -134,7 +134,7 @@ local function create_item(item,data,args) -- Attributes id = "main_margin" , - layout = wibox.layout.margin, + layout = wibox.container.margin, }, -- Attributes @@ -142,7 +142,7 @@ local function create_item(item,data,args) tooltip = item.tooltip , _item = item , _data = data , - widget = wibox.widget.background, + widget = wibox.container.background, } -- Make some widgets easier to access diff --git a/item/layout/icon.lua b/item/layout/icon.lua index 5321fdb..40eecac 100644 --- a/item/layout/icon.lua +++ b/item/layout/icon.lua @@ -11,7 +11,7 @@ local common = require( "radical.item.common" ) local module = {} local function after_draw_children(self, context, cr, width, height) - wibox.widget.background.after_draw_children(self, context, cr, width, height) + wibox.container.background.after_draw_children(self, context, cr, width, height) --TODO get rid of this, use the stack container if self._item.overlay_draw then self._item.overlay_draw(context,self._item,cr,width,height) @@ -67,7 +67,7 @@ local function create_item(item,data,args) if data._internal.layout.item_fit then return data._internal.layout.item_fit(data,item,box,context, w, h) else - return wibox.widget.background.fit(box,context, w,h) + return wibox.container.background.fit(box,context, w,h) end return 0,0 @@ -121,20 +121,20 @@ local function create_item(item,data,args) }, left = data.fkeys_prefix and 0 or nil, id = "main_margin", - layout = wibox.layout.margin, + layout = wibox.container.margin, }, -- Attributes fg = item._private_data.fg, _item = item, - widget = wibox.widget.background + widget = wibox.container.background } item.widget = w item._internal.icon_w = icon item._internal.margin_w = item.widget:get_children_by_id("main_margin")[1] item._internal.text_w = item.widget:get_children_by_id("main_text")[1] - item._private_data._fit = wibox.widget.background.fit + item._private_data._fit = wibox.container.background.fit w.after_draw_children = after_draw_children w.fit = bg_fit diff --git a/item/layout/notification.lua b/item/layout/notification.lua index 6529e5c..e46a574 100644 --- a/item/layout/notification.lua +++ b/item/layout/notification.lua @@ -15,10 +15,10 @@ end -- Create the actual widget local function create_item(item,data,args) -- Background - local bg = wibox.widget.background() + local bg = wibox.container.background() -- Margins - local m = wibox.layout.margin(la) + local m = wibox.container.margin(la) local mrgns = margins2(m,(item.item_style or data.item_style).margins) item.get_margins = function() return mrgns diff --git a/item/style/arrow_alt.lua b/item/style/arrow_alt.lua index 9959459..86bc216 100644 --- a/item/style/arrow_alt.lua +++ b/item/style/arrow_alt.lua @@ -79,7 +79,7 @@ module.get_beg_arrow = function(args) end local function draw_real(self, context, cr, width, height) --- wibox.widget.background.draw(self, context, cr, width, height) +-- wibox.container.background.draw(self, context, cr, width, height) cr:save() -- This item style require negative padding, this is a little dangerous to diff --git a/item/style/classic.lua b/item/style/classic.lua index fb38db2..bb93b4e 100644 --- a/item/style/classic.lua +++ b/item/style/classic.lua @@ -13,16 +13,16 @@ local module = { } local function horizontal(self, context, cr, width, height) - if self._item and self._shape_border_color then - cr:set_source(color(self._shape_border_color)) + if self._item and self._item.item_border_color then + cr:set_source(color(self._item.item_border_color)) cr:rectangle(0, height -1, width, 1) cr:fill() end end local function vertical(self, context, cr, width, height) - if self._item and self._shape_border_color then - cr:set_source(color(self._shape_border_color)) + if self._item and self._item.item_border_color then + cr:set_source(color(self._item.item_border_color)) cr:rectangle(width-1, 0, 1, height) cr:fill() end diff --git a/item/style/holo.lua b/item/style/holo.lua index 80f5847..e2fb5f6 100644 --- a/item/style/holo.lua +++ b/item/style/holo.lua @@ -19,7 +19,7 @@ end local function after_draw_children_top(self, context, cr, width, height) cr:save() - cr:set_source(color(self.background)) + cr:set_source(color(self._private.background)) cr:rectangle(0, 0, width, default_height) cr:fill() cr:restore() @@ -27,7 +27,7 @@ end local function after_draw_children_bottom(self, context, cr, width, height) cr:save() - cr:set_source(color(self.background)) + cr:set_source(color(self._private.background)) cr:rectangle(0, height -default_height, width, default_height) cr:fill() cr:restore() diff --git a/layout/vertical.lua b/layout/vertical.lua index aeec78a..008b143 100644 --- a/layout/vertical.lua +++ b/layout/vertical.lua @@ -13,14 +13,14 @@ local function item_fit(data,item,self,context, width,height) end function module:setup_item(data,item,args) - item._private_data._fit = wibox.widget.background.fit + item._private_data._fit = wibox.container.background.fit if not item._internal.margin_w then return end item._internal.margin_w.fit = function(...) return item_fit(data,item,...) end -- Compute the minimum width - if data.auto_resize then --FIXME this wont work if thext change + if data.auto_resize then --FIXME this wont work if the text change local fit_w = item._internal.margin_w:get_preferred_size() if fit_w < 1000 and (not data._internal.largest_item_w_v or data._internal.largest_item_w_v < fit_w) then @@ -42,7 +42,7 @@ local function compute_geo(data,width,height,force_values) local sw,sh = data._internal.suf_l:get_preferred_size() local pw,ph = data._internal.pref_l:get_preferred_size() if not data._internal.has_widget then - return w,(total and total > 0 and total or visblerow*data.item_height) + ph + sh + return w, visblerow*data.item_height + ph + sh else local sumh = data.widget_fit_height_sum local h = (visblerow-#data._internal.widgets)*data.item_height + sumh diff --git a/menu_template.lua.tmpl b/menu_template.lua.tmpl index ecea7ad..750da0a 100644 --- a/menu_template.lua.tmpl +++ b/menu_template.lua.tmpl @@ -27,7 +27,7 @@ local function setup_drawable(data) --Init -- internal.w = wibox({}) - internal.margin = wibox.layout.margin() + internal.margin = wibox.container.margin() if not data.layout then data.layout = layout.vertical end diff --git a/placement.lua b/placement.lua deleted file mode 100644 index 2eac868..0000000 --- a/placement.lua +++ /dev/null @@ -1,533 +0,0 @@ -local capi = {screen=screen, mouse = mouse} -local unpack = unpack or table.unpack -local mouse = require( "awful.mouse" ) -local screen = require( "awful.screen" ) -local tag = require( "awful.tag" ) --TODO do the opposite, include placement in awful.tag -local cairo = require( "lgi" ).cairo - -local module = {} - --- Compute the new `x` and `y`. --- The workarea position need to be applied by the caller -local map = { - top_left = function(sw, sh, dw, dh) return {x=0 , y=0 } end, - top_right = function(sw, sh, dw, dh) return {x=sw-dw , y=0 } end, - bottom_left = function(sw, sh, dw, dh) return {x=0 , y=sh-dh } end, - bottom_right = function(sw, sh, dw, dh) return {x=sw-dw , y=sh-dh } end, - left = function(sw, sh, dw, dh) return {x=0 , y=sh/2-dh/2} end, - right = function(sw, sh, dw, dh) return {x=sw-dw , y=sh/2-dh/2} end, - top = function(sw, sh, dw, dh) return {x=sw/2-dw/2, y=0 } end, - bottom = function(sw, sh, dw, dh) return {x=sw/2-dw/2, y=sh-dh } end, - centered = function(sw, sh, dw, dh) return {x=sw/2-dw/2, y=sh/2-dh/2} end, - center_vertical = function(sw, sh, dw, dh) return {x= nil , y=sh-dh } end, - center_horizontal = function(sw, sh, dw, dh) return {x=sw/2-dw/2, y= nil } end, -} - --- Store function -> keys -local reverse_map = {} - --- Create the geometry rectangle 1=best case, 2=fallback -local positions = { - left1 = function(r, w, h) return {x=r.x-w , y=r.y }, "down" end, - left2 = function(r, w, h) return {x=r.x-w , y=r.y-h+r.height }, "up" end, - right1 = function(r, w, h) return {x=r.x , y=r.y }, "down" end, - right2 = function(r, w, h) return {x=r.x , y=r.y-h+r.height }, "up" end, - top1 = function(r, w, h) return {x=r.x , y=r.y-h }, "right" end, - top2 = function(r, w, h) return {x=r.x-w+r.width, y=r.y-h }, "left" end, - bottom1 = function(r, w, h) return {x=r.x , y=r.y }, "right" end, - bottom2 = function(r, w, h) return {x=r.x-w+r.width, y=r.y }, "left" end, -} - --- Check if the proposed geometry fit in the screen -local function fit_in_screen(s, geo) --TODO replace by fit_in_bounding - local sgeo = capi.screen[s].geometry - local region = cairo.Region.create_rectangle(cairo.RectangleInt(sgeo)) - - region:intersect(cairo.Region.create_rectangle( - cairo.RectangleInt(geo) - )) - - local geo2 = region:get_rectangle(0) - - -- If the geometry is the same, then it fit, else, it will be cropped - --TODO in case all directions are cropped, keep the least cropped one - return geo2.width == geo.width and geo2.height == geo.height -end - -local function apply_geometry_ajustments(geo, delta) - return { - x = geo.x + (delta.left or 0), - y = geo.y + (delta.top or 0), - width = geo.width - (delta.left or 0) - (delta.right or 0), - height = geo.height - (delta.top or 0) - (delta.bottom or 0), - } -end - ---- Get a placement bounding geometry. --- This method offer a flexible way to build a customized outer geometry used --- by the various functions of this module. --- --- Valid arguments are: --- --- * honor_padding --- * honor_workarea --- * margins --- * tag --- * parent: A parent drawable to use a base geometry --- * bounding_rect: A bounding rectangle --- --- @tparam[opt=mouse.screen] screen s A screen --- @tparam[opt={}] table args The arguments -function module.get_bounding_geometry(s, args) - args = args or {} - - -- If the tag has a geometry, assume it is right - if args.tag then - local geo = tag.getproperty(args.tag, "geometry") - if geo then - return geo - end - end - - s = s or capi.mouse.screen - - local geo = args.bounding_rect or (args.parent and parent:geometry()) or - capi.screen[s][args.honor_workarea and "workarea" or "geometry"] - - if (not args.parent) and (not args.bounding_rect) and args.honor_padding then - local padding = screen.padding(s) or {} - geo = apply_geometry_ajustments(geo, padding) - end - - if args.margins then - geo = apply_geometry_ajustments(geo, - type(args.margins) == "table" and args.margins or { - left = args.margins, right = args.margins, - top = args.margins, bottom = args.margins, - } - ) - end - - return geo -end - ---- Move the drawable (client or wibox) `d` to a screen position or side. --- --- Supported positions are: --- --- * top_left --- * top_right --- * bottom_left --- * bottom_right --- * left --- * right --- * top --- * bottom --- * centered --- * center_vertical --- * center_horizontal --- --- The valid other arguments are: --- --- * *honor_workarea*: Take workarea into account when placing the drawable (default: false) --- * *honor_padding*: Take the screen padding into account (see `awful.screen.padding`) --- * *tag*: Use a tag geometry --- * *margins*: A table with left, right, top, bottom keys or a number --- * *parent*: A parent drawable to use a base geometry --- * *bounding_rect*: A bounding rectangle --- --- @tparam drawable d A drawable (like `client` or `wibox`) --- @tparam string position One of the position mentionned above --- @param[opt=d.screen or capi.mouse.screen] parent The parent geometry --- @tparam[opt={}] table args Other arguments -function module.align(d, position, parent, args) - d = d or capi.client.focus - if not d then return end - - args = args or {} - parent = parent or d.screen or capi.mouse.screen - - - -- Get the parent geometry - local parent_type = type(parent) - - local sgeo = (parent_type == "screen" or parent_type == "number") and - module.get_bounding_geometry(parent, args) or parent:geometry() - - local dgeo = d:geometry() - - local pos = map[position](sgeo.width, sgeo.height, dgeo.width, dgeo.height) - - d : geometry { - x = pos.x and math.ceil(sgeo.x + pos.x) or dgeo.x, - y = pos.y and math.ceil(sgeo.y + pos.y) or dgeo.y, - width = math.ceil(dgeo.width ) , - height = math.ceil(dgeo.height ) , - } -end - --- Add the alias functions -for k,v in pairs(map) do - module[k] = function(d, p, args) - module.align(d, k, p, args) - end - - reverse_map[module[k]] = k -end - ---- Stretch a drawable in a specific direction. --- Valid args: --- --- * *preserve_ratio*: --- * *margins*: A margin value or table --- * *honor_workarea*: --- * *honor_padding*: --- * *tag*: Use a tag geometry, this honor the workarea, padding and gaps --- * *parent*: A parent drawable to use a base geometry --- * *bounding_rect*: A bounding rectangle --- * minimim_height: --- * minimim_width: --- --- @tparam[opt=client.focus] drawable d A drawable (like `client` or `wibox`) --- @tparam string direction The stretch direction (left, right, up, down) --- @tparam[opt={}] table args The arguments -function module.stretch(d, direction, args) - d = d or capi.client.focus - if not d then return end - - --TODO maybe this could be integrated with the resize matrix? - local sgeo = module.get_bounding_geometry(d.screen, args) - local dgeo = d:geometry() - local ngeo = dgeo - - if direction == "left" then - ngeo.x = sgeo.x - ngeo.width = (sgeo.width - sgeo.x) - (ngeo.x + ngeo.width) - elseif direction == "right" then - ngeo.width = sgeo.width - ngeo.x - elseif direction == "up" then - ngeo.y = sgeo.y - ngeo.height = (sgeo.height - sgeo.y) - (ngeo.y + ngeo.height) - elseif direction == "down" then - ngeo.height = sgeo.height - dgeo.y - end - - -- Avoid negative sizes - ngeo.width = math.max(args.minimim_width or 1, ngeo.width ) - ngeo.height = math.max(args.minimim_height or 1, ngeo.height) -end - --- Add the alias functions -for k,v in ipairs {"left", "right", "up", "down"} do - module["stretch_"..v] = function(d, args) module.stretch(d, v, args) end -end - ---- Maximize a drawable horizontally, vertically or both. --- Valid args: --- --- * *preserve_ratio*: --- * *margins*: A margin value or table --- * *honor_workarea*: --- * *honor_padding*: --- * *tag*: Use a tag geometry, this honor the workarea, padding and gaps --- * *parent*: A parent drawable to use a base geometry --- * *bounding_rect*: A bounding rectangle --- --- @tparam[opt=client.focus] drawable d A drawable (like `client` or `wibox`) --- @tparam string axis The axis (vertically or horizontally) --- @tparam[opt={}] table args The arguments -function module.maximize(d, axis, args) - d = d or capi.client.focus - if not d then return end - - local sgeo = module.get_bounding_geometry(d.screen, args) - local dgeo = d:geometry() - local ngeo = dgeo - - if (not axis) or axis:match("vertical") then - ngeo.y = sgeo.y - ngeo.height = sgeo.height - end - - if (not axis) or axis:match("horizontal") then - ngeo.x = sgeo.x - ngeo.width = sgeo.width - end - - d:geometry(ngeo) -end - --- Add the alias functions -for k, v in ipairs {"vertically", "horizontally"} do - module["maximize_"..v] = function(d, args) module.maximize(d, v, args) end -end - ---- Pin a drawable to a placement function. --- Automatically update the position when the size change. --- All other arguments will be passed to the `position` function (if any) --- @tparam[opt=client.focus] drawable d A drawable (like `client` or `wibox`) --- @param position A position name (see `align`) or a position function -function module.attach(d, position, ...) - d = d or capi.client.focus - if not d then return end - - if type(position) == "string" then - position = module[position] - end - - if not position then return end - - local args = {...} - - local function tracker() - position(d, unpack(args)) - end - - d:connect_signal("property::width" , tracker) - d:connect_signal("property::height", tracker) - - tracker() -end - --- Update the workarea -local function wibox_update_strut(d, position) - -- If the drawable isn't visible, remove the struts - if not d.visible then - d:struts { left = 0, right = 0, bottom = 0, top = 0 } - return - end - - -- Detect horizontal or vertical drawables - local geo = d:geometry() - local vertical = geo.width < geo.height - - -- Look into the `position` string to find the relevants sides to crop from - -- the workarea - local struts = { left = 0, right = 0, bottom = 0, top = 0 } - - if vertical then - for k, v in ipairs {"right", "left"} do - if (not position) or position:match(v) then - struts[v] = geo.width + 2 * d.border_width - end - end - else - for k, v in ipairs {"top", "bottom"} do - if (not position) or position:match(v) then - struts[v] = geo.height + 2 * d.border_width - end - end - end - - -- Update the workarea - d:struts(struts) -end - -function module.attach_struts(d, f, ...) - module.attach(d, f, ...) - --TODO if there is multiple attach_struts, update them, see `raise_attached_struts` - - local function tracker() - wibox_update_strut(d, reverse_map[f]) - end - - d:connect_signal("property::geometry" , tracker) - d:connect_signal("property::visible" , tracker) - - tracker() -end - ---- Move a drawable to the "top priority" of attached_structs -function module.raise_attached_struts() - -end - --- Create a pair of rectangles used to set the relative areas. --- v=vertical, h=horizontal -local function get_cross_sections(abs_geo, mode) - if not mode or mode == "cursor" then - -- A 1px cross section centered around the mouse position - - local coords = capi.mouse.coords() - return { - h = { - x = abs_geo.drawable_geo.x , - y = coords.y , - width = abs_geo.drawable_geo.width , - height = 1 , - }, - v = { - x = coords.x , - y = abs_geo.drawable_geo.y , - width = 1 , - height = abs_geo.drawable_geo.height, - } - } - elseif mode == "widget" then - -- The widget geometry extended to reach the end of the drawable - - return { - h = { - x = abs_geo.drawable_geo.x , - y = abs_geo.y , - width = abs_geo.drawable_geo.width , - height = abs_geo.height , - }, - v = { - x = abs_geo.x , - y = abs_geo.drawable_geo.y , - width = abs_geo.width , - height = abs_geo.drawable_geo.height, - } - } - elseif mode == "cursor_inside" then - -- A 1x1 rectangle centered around the mouse position - - local coords = capi.mouse.coords() - coords.width,coords.height = 1,1 - return {h=coords, v=coords} - elseif mode == "widget_inside" then - -- The widget absolute geometry, unchanged - - return {h=abs_geo, v=abs_geo} - end - - assert(false) -end - ---- Get the possible 2D anchor points around a widget geometry. --- This take into account the widget drawable (wibox) and try to avoid --- overlapping. --- --- Valid arguments are: --- --- * xoffset --- * yoffset --- * margins: A table with "left", "right", "top" and "bottom" as key or a number --- --- @tparam table geo A geometry table with optional "drawable" member --- @tparam[opt="widget"] string mode TODO document --- @tparam[opt={}] table args -function module.get_relative_points(geo, mode, args) --TODO rename regions - mode = mode or "widget" - args = args or {} - - -- Use the mouse position and the wibox/client under it - if not geo then - local draw = mouse.drawin_under_pointer() - geo = draw and draw:geometry() or capi.mouse.coords() - geo.drawable = draw - elseif (not geo.drawable) and geo.x and geo.width then - local coords = capi.mouse.coords() - - -- Check id the mouse is in the rect - if coords.x > geo.x and coords.x < geo.x+geo.width and - coords.y > geo.y and coords.y < geo.y+geo.height then - geo.drawable = mouse.drawin_under_pointer() - end - end - - -- Get the drawable geometry - local dpos = geo.drawable and geo.drawable.drawable:geometry() or {x=0, y=0} - - -- Compute the absolute widget geometry - local abs_widget_geo = { - x = dpos.x + geo.x , - y = dpos.y + geo.y , - width = geo.width , - height = geo.height , - drawable = geo.drawable , - drawable_geo = geo.drawable and dpos or geo, - } - - -- Get the comparaison point - local center_point = mode:match("cursor") and capi.mouse.coords() or { - x = abs_widget_geo.x + abs_widget_geo.width / 2, - y = abs_widget_geo.y + abs_widget_geo.height / 2, - } - - -- Get widget regions for both axis - local cs = get_cross_sections(abs_widget_geo, mode) - - -- Set the offset - local xoff, yoff = args.xoffset or 0, args.yoffset or 0 --TODO add margins - - -- Get the 4 closest points from `center_point` around the wibox - local regions = { - left = {x = xoff+cs.h.x , y = yoff+cs.h.y }, - right = {x = xoff+cs.h.x+cs.h.width, y = yoff+cs.h.y }, - top = {x = xoff+cs.v.x , y = yoff+cs.v.y }, - bottom = {x = xoff+cs.v.x , y = yoff+cs.v.y+cs.v.height}, - } - - -- Assume the section is part of a single screen until someone complain. - -- It is much faster to compute and getting it wrong probably have no side - -- effects. - local s = geo.drawable and geo.drawable.screen or screen.getbycoord( - center_point.x, - center_point.y - ) - - -- Compute the distance (dp) between the `center_point` and the sides. - -- This is only relevant for "cursor" and "cursor_inside" modes. - for k, v in pairs(regions) do - local dx, dy = v.x - center_point.x, v.y - center_point.y - - v.distance = math.sqrt(dx*dx + dy*dy) - v.width = cs.v.width - v.height = cs.h.height - v.screen = s - end - - return regions -end - ---- Move a drawable to a relative position next to another one. --- @tparam drawable d A wibox or client --- @tparam table regions A table with position as key and regions (x,y,w,h) as value --- @tparam[opt={}] table preferred_positions The preferred positions (position as key, --- and index as value) --- @treturn string The choosen position --- @treturn string The choosen direction -function module.move_relative(d, regions, preferred_positions) --TODO inside/outside, replace by args, allow modes - --args.geo, args.mode, args.drawable, args.regions, args.preferred_positions - local w,h = d.width, d.height - - local pref_idx, pref_name = 99, nil - - local does_fit = {} - for k,v in pairs(regions) do - local geo, dir = positions[k..1](v, w, h) - geo.width, geo.height = w, h - local fit = fit_in_screen(v.screen, geo) - - -- Try the other compatible geometry - if not fit then - geo, dir = positions[k..2](v, w, h) - geo.width, geo.height = w, h - fit = fit_in_screen(v.screen, geo) - end - - does_fit[k] = fit and {geo, dir} or nil - - if fit and preferred_positions[k] and preferred_positions[k] < pref_idx then - pref_idx = preferred_positions[k] - pref_name = k - end - - -- No need to continue - if fit and preferred_positions[k] == 1 then break end - end - - local pos_name = pref_name or next(does_fit) - local pos, dir = unpack(does_fit[pos_name]) - - if pos then - d.x = math.ceil(pos.x) - d.y = math.ceil(pos.y) - end - - return pos_name, dir -end - -return module diff --git a/radial.lua b/radial.lua index f9ec6c1..d6dd88a 100644 --- a/radial.lua +++ b/radial.lua @@ -387,7 +387,7 @@ local function setup_drawable(data) --Init -- internal.w = wibox({}) - internal.margin = wibox.layout.margin() + internal.margin = wibox.container.margin() if not data.layout then data.layout = layout.vertical end diff --git a/smart_wibox.lua b/smart_wibox.lua index 4e28166..8754503 100644 --- a/smart_wibox.lua +++ b/smart_wibox.lua @@ -18,7 +18,7 @@ local beautiful = require( "beautiful" ) local color = require( "gears.color" ) local screen = require( "awful.screen" ) local mouse = require( "awful.mouse" ) -local placement = require( "radical.placement") +local placement = require( "awful.placement" ) local unpack = unpack or table.unpack local module = {} @@ -31,10 +31,29 @@ local main_widget = {} -- Get the optimal direction for the wibox -- This (try to) avoid going offscreen local function set_position(self) - local points = rawget(self, "possible_positions") or {} - local preferred_positions = rawget(self, "_preferred_directions") or {} + local pf = rawget(self, "_placement") - local pos_name = placement.move_relative(self, points, preferred_positions) + if pf == false then return end + + if pf then + pf(self, {bounding_rect = self.screen.geometry}) + return + end + + local geo = rawget(self, "widget_geo") + + local preferred_positions = rawget(self, "_preferred_directions") or { + "right", "left", "top", "bottom" + } + + local _, pos_name = placement.next_to(self, { + preferred_positions = preferred_positions, + geometry = geo, + offset = { + x = (rawget(self, "xoffset") or 0), + y = (rawget(self, "yoffset") or 0), + }, + }) if pos_name ~= rawget(self, "position") then self:emit_signal("property::direction", pos_name) @@ -152,12 +171,8 @@ end -- * top -- * bottom -- @tparam string ... One of more directions (in the preferred order) -function wb_func:set_preferred_positions(...) - local dirs = {} - for k, v in ipairs{...} do - dirs[v] = k - end - rawset(self, "_preferred_directions", dirs) +function wb_func:set_preferred_positions(pref_pos) + rawset(self, "_preferred_directions", pref_pos) end --- Move the wibox to a position relative to `geo`. @@ -170,13 +185,7 @@ end function wb_func:move_by_parent(geo, mode) if rawget(self, "is_relative") == false then return end - --TODO add border_width? - local dps = placement.get_relative_points(geo, mode, { - xoffset = rawget(self, "xoffset") or 0, - yoffset = rawget(self, "yoffset") or 0, - }) - - rawset(self, "possible_positions", dps) + rawset(self, "widget_geo", geo) set_position(self) end @@ -191,11 +200,6 @@ function wb_func:set_xoffset(offset) rawset(self, "xoffset", offset) - -- Update the points - for k,v in pairs(rawget(self, "possible_positions") or {}) do - v.x = v.x - old + offset - end - -- Update the position set_position(self) end @@ -206,11 +210,6 @@ function wb_func:set_yoffset(offset) rawset(self, "yoffset", offset) - -- Update the points - for k,v in pairs(rawget(self, "possible_positions") or {}) do - v.y = v.y - old + offset - end - -- Update the position set_position(self) end @@ -228,6 +227,18 @@ function wb_func:set_relative(val) rawset(self, "is_relative", val) end +--- Set the placement function. +-- @tparam[opt=next_to] function|string|boolean The placement function or name +-- (or false to disable placement) +function wb_func:set_placement(f) + + if type(f) == "string" then + f = placement[f] + end + + rawset(self, "_placement", f) +end + --- A brilliant idea to totally turn the whole hierarchy on its head -- and create a widget that own a wibox... local function create_auto_resize_widget(self, wdg, args) @@ -255,13 +266,11 @@ local function create_auto_resize_widget(self, wdg, args) w:set_shape_border_color() - w:add_signal("property::direction") - if args and args.preferred_positions then if type(args.preferred_positions) == "table" then - w:set_preferred_positions(unpack(args.preferred_positions)) - else w:set_preferred_positions(args.preferred_positions) + else + w:set_preferred_positions({args.preferred_positions}) end end @@ -273,7 +282,7 @@ local function create_auto_resize_widget(self, wdg, args) w:set_relative(args.relative) end - for k,v in ipairs{"shape_border_color", "shape_border_width"} do + for k,v in ipairs{"shape_border_color", "shape_border_width", "placement"} do if args[v] then w["set_"..v](w, args[v]) end diff --git a/style/arrow.lua b/style/arrow.lua index f8df68d..9f498a5 100644 --- a/style/arrow.lua +++ b/style/arrow.lua @@ -46,13 +46,15 @@ local arrow_height = 13 local function gen_arrow_x(data, direction, width, height) local at = data.arrow_type + local pg = data.parent_geometry + if at == base.arrow_type.PRETTY or not at then if direction == "left" then --TODO elseif direction == "right" then - data._internal.w:set_yoffset(-(20) - arrow_height) + data._internal.w:set_yoffset(-(20) + arrow_height) elseif direction == "bottom" then --- data._internal.w:set_xoffset(-(20) - arrow_height) --TODO negative are broken + data._internal.w:set_xoffset(-(20) - arrow_height) elseif direction == "top" then data._internal.w:set_xoffset(-data._internal.w.width + (20) + arrow_height) end @@ -62,7 +64,11 @@ local function gen_arrow_x(data, direction, width, height) data._internal.w:set_yoffset(data._internal.w.height/2 - arrow_height) else data._arrow_x = width/2 - arrow_height - data._internal.w:set_xoffset(data._internal.w.width/2 - arrow_height) + if pg then + data._internal.w:set_xoffset(-data._internal.w.width/2 + arrow_height + pg.width/2) + else + data._internal.w:set_xoffset(data._internal.w.width/2 - arrow_height) + end end end end diff --git a/tooltip.lua b/tooltip.lua index c7e0ceb..5b1e9f2 100644 --- a/tooltip.lua +++ b/tooltip.lua @@ -45,7 +45,7 @@ local function init(data,widget,args) -- Setup the wibox local vertical = (args.direction == "left") or (args.direction == "right") - local w,extents = data.wibox or wibox{},widget._layout:get_pixel_extents() + local w,extents = data.wibox or wibox{},widget._private.layout:get_pixel_extents() extents.width = extents.width + 60 w.visible = false w.width = extents.width @@ -131,7 +131,7 @@ local function new(widget,text, args) if data.wibox then - local l,m = wibox.layout.fixed.horizontal(),wibox.layout.margin(textw) + local l,m = wibox.layout.fixed.horizontal(),wibox.container.margin(textw) m:set_left ( 30 ) m:set_right ( 10 ) m:set_bottom ( not vertical and ((args.direction == "top") and 4 or -4) or 0 ) diff --git a/widgets/filter.lua b/widgets/filter.lua index 17bf5da..a17d6f2 100644 --- a/widgets/filter.lua +++ b/widgets/filter.lua @@ -42,7 +42,7 @@ local function new(data) widget = infoshapes , }, set_data = set_data, - widget = wibox.widget.background + widget = wibox.container.background } end diff --git a/widgets/header.lua b/widgets/header.lua index a0fef7f..91276e0 100644 --- a/widgets/header.lua +++ b/widgets/header.lua @@ -10,11 +10,12 @@ local module = {} local function new(data,text,args) local args = args or {} - local bg = wibox.widget.background() + local bg = wibox.container.background() local infoHeader = wibox.widget.textbox() infoHeader:set_font("") infoHeader:set_markup( " ".. text .." " ) local l = wibox.layout.align.horizontal() + print("\n\n\nAAAAAAAAAA",l.set_first, l.set_left) l:set_left(infoHeader) bg:set_widget(l) bg:set_bg(data.bg_header) diff --git a/widgets/scroll.lua b/widgets/scroll.lua index 09e6529..fa7f656 100644 --- a/widgets/scroll.lua +++ b/widgets/scroll.lua @@ -59,11 +59,11 @@ local function new(data) end ib.draw = function(self, context, cr, width, height) if width > 0 and height > 0 then - cr:set_source_surface(self._image, width/2 - self._image:get_width()/2, 0) + cr:set_source_surface(self._private.image, width/2 - self._private.image:get_width()/2, 0) end cr:paint() end - scroll_w[v] = wibox.widget.background() + scroll_w[v] = wibox.container.background() scroll_w[v]:set_widget(ib) scroll_w[v].visible = true data.item_style({widget=scroll_w[v]},{color=data.bg_highlight}) diff --git a/widgets/table.lua b/widgets/table.lua index d9642eb..e729da6 100644 --- a/widgets/table.lua +++ b/widgets/table.lua @@ -29,7 +29,7 @@ end local function create_h_header(main_l,cols,context,args) if args.h_header then - local bg = wibox.widget.background() + local bg = wibox.container.background() local row_l = wibox.layout.fixed.horizontal() bg:set_bg(beautiful.menu_table_bg_header or beautiful.menu_bg_header or beautiful.fg_normal) bg:set_widget(row_l) @@ -70,7 +70,7 @@ local function new(content,args) if args.v_header then local t = create_textbox(w,cols,1,args.v_header ~= nil,args.row_height) t:set_markup("".. (args.v_header[j] or "-") .."") - local bg = wibox.widget.background() + local bg = wibox.container.background() bg:set_bg(beautiful.menu_table_bg_header or beautiful.menu_bg_header or beautiful.fg_normal) bg:set_widget(t) row_l:add(bg)