placement: Re-introduce many placements features lost during the re-write
The menu can be attached to a widget or the mouse again, and more This commit also fix some tasklist/taglist issues and introduce minor features like item.shape.
This commit is contained in:
parent
ac402846a3
commit
cbc5e6919f
|
@ -13,7 +13,7 @@ local function set_visible(i, value)
|
|||
local w, pg = i.w, i.private_data.parent_geometry
|
||||
|
||||
if value then
|
||||
w:move_by_parent(pg, true)
|
||||
w:move_by_parent(pg, "widget")
|
||||
end
|
||||
|
||||
w.visible = value
|
||||
|
@ -66,7 +66,7 @@ local function new(args)
|
|||
local ret = base(args)
|
||||
|
||||
ret:connect_signal("parent_geometry::changed", function()
|
||||
args.internal.w:move_by_parent(ret.parent_geometry, true)
|
||||
args.internal.w:move_by_parent(ret.parent_geometry, "widget")
|
||||
end)
|
||||
|
||||
-- Init the style
|
||||
|
|
9
dock.lua
9
dock.lua
|
@ -95,7 +95,14 @@ local function get_wibox(data, screen)
|
|||
adapt_size(data, w.width, w.height, 1)
|
||||
end)
|
||||
|
||||
placement.pin(w, placement.corner, "left", screen or 1)
|
||||
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)
|
||||
|
||||
return w
|
||||
end
|
||||
|
|
|
@ -6,6 +6,8 @@ local placement = require( "radical.placement" )
|
|||
|
||||
local module = {}
|
||||
|
||||
--TODO add "wrap cursor mode"
|
||||
|
||||
local wibox_to_req = {}
|
||||
|
||||
local corners_geo = {
|
||||
|
@ -43,7 +45,7 @@ local function create_hot_corner(corner, s)
|
|||
local size = corners_geo[corner](s_geo, w_geo)
|
||||
local w = wibox(util.table.crush(size, {ontop=true, opacity = 0, visible=true}))
|
||||
|
||||
placement.corner(w, corner, s, false, false)
|
||||
placement.align(w, corner, s, false, false)
|
||||
|
||||
local req = {wibox = w, screen = s, corner = corner}
|
||||
|
||||
|
@ -123,4 +125,4 @@ end
|
|||
|
||||
--TODO watch for workarea changes
|
||||
|
||||
return module
|
||||
return module
|
||||
|
|
|
@ -62,7 +62,7 @@ end
|
|||
function module.screenshot(clients,geo)
|
||||
if not clients then return end
|
||||
|
||||
local prev_menu= radical.context({layout=radical.layout.horizontal,item_width=140,item_height=140,icon_size=100,
|
||||
local prev_menu= radical.context({layout=radical.layout.horizontal,item_layout=radical.item.layout.centerred,item_width=140,item_height=140,icon_size=100,
|
||||
arrow_type=radical.base.arrow_type.CENTERED,enable_keyboard=false,item_style=radical.item.style.rounded})
|
||||
local t = type(clients)
|
||||
if t == "client" then
|
||||
|
|
|
@ -8,21 +8,6 @@ local tag_list = nil
|
|||
|
||||
local module = {}
|
||||
|
||||
local fallback_layouts = {
|
||||
suits.floating,
|
||||
suits.tile,
|
||||
suits.tile.left,
|
||||
suits.tile.bottom,
|
||||
suits.tile.top,
|
||||
suits.fair,
|
||||
suits.fair.horizontal,
|
||||
suits.spiral,
|
||||
suits.spiral.dwindle,
|
||||
suits.max,
|
||||
suits.max.fullscreen,
|
||||
suits.magnifier
|
||||
}
|
||||
|
||||
local function createTagList(aScreen,args)
|
||||
if not tag_list then
|
||||
tag_list = require("radical.impl.taglist")
|
||||
|
@ -62,7 +47,8 @@ end
|
|||
function module.layouts(menu,layouts)
|
||||
local cur = awful.layout.get(awful.tag.getscreen(awful.tag.selected(capi.client.focus and capi.client.focus.screen)))
|
||||
local screenSelect = menu or radical.context {}
|
||||
local layouts = layouts or awful.layout.layouts or fallback_layouts
|
||||
|
||||
local layouts = layouts or awful.layout.layouts
|
||||
for i, layout_real in ipairs(layouts) do
|
||||
local layout2 = awful.layout.getname(layout_real)
|
||||
local is_current = cur and ((layout_real == cur) or (layout_real.name == cur.name))
|
||||
|
@ -107,14 +93,16 @@ function module.layout_item(menu,args)
|
|||
|
||||
local function update()
|
||||
local layout = awful.layout.getname(awful.layout.get(screen))
|
||||
local ic = beautiful["layout_small_" ..layout] or beautiful["layout_" ..layout]
|
||||
local ic = beautiful["layout_" ..layout]
|
||||
item.icon = ic
|
||||
end
|
||||
update()
|
||||
|
||||
awful.tag.attached_connect_signal(screen, "property::selected", update)
|
||||
awful.tag.attached_connect_signal(screen, "property::layout" , update)
|
||||
|
||||
return item
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...) return module.listTags(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
||||
|
|
|
@ -38,9 +38,11 @@ local cache = setmetatable({}, { __mode = 'k' })
|
|||
|
||||
module.buttons = { [1] = awful.tag.viewonly,
|
||||
[2] = awful.tag.viewtoggle,
|
||||
[3] = function(q,w,e,r)
|
||||
local menu = tag_menu(q)
|
||||
[3] = function(t,menu,item,button_id,mod,geo)
|
||||
local menu = tag_menu(t)
|
||||
menu.parent_geometry = geo
|
||||
menu.visible = true
|
||||
menu._internal.w:move_by_parent(geo, "cursor")
|
||||
end,
|
||||
[4] = function(t) awful.tag.viewnext(awful.tag.getscreen(t)) end,
|
||||
[5] = function(t) awful.tag.viewprev(awful.tag.getscreen(t)) end,
|
||||
|
@ -117,10 +119,10 @@ local function create_item(t,s)
|
|||
end
|
||||
-- menu:move(item,index)
|
||||
|
||||
menu:connect_signal("button::press",function(menu,item,button_id,mod)
|
||||
menu:connect_signal("button::press",function(menu,item,button_id,mod,geo)
|
||||
if module.buttons and module.buttons[button_id] then
|
||||
if item.tag[1] then
|
||||
module.buttons[button_id](item.tag[1],menu,item,button_id,mod)
|
||||
module.buttons[button_id](item.tag[1],menu,item,button_id,mod,geo)
|
||||
else
|
||||
print("Invalid tag")
|
||||
end
|
||||
|
|
|
@ -120,7 +120,7 @@ local function new(t)
|
|||
local mainMenu2 = menu{layout=radical.layout.grid,column=6,}
|
||||
|
||||
-- TODO port to async
|
||||
local f = io.popen('find '..config.iconPath .. "tags/ -maxdepth 1 -iname \"*.png\" -type f","r")
|
||||
local f = io.popen('find '..config.iconPath .. "tags_invert/ -maxdepth 1 -iname \"*.png\" -type f","r")
|
||||
local counter = 0
|
||||
while true do
|
||||
local file = f:read("*line")
|
||||
|
|
|
@ -26,7 +26,7 @@ theme.register_color(MINIMIZED , "minimized" , "tasklist_minimized" , true )
|
|||
|
||||
-- Default button implementation
|
||||
module.buttons = {
|
||||
[1] = function (c)
|
||||
[1] = function(c,menu,item,button_id,mod, geo)
|
||||
if c == capi.client.focus then
|
||||
c.minimized = true
|
||||
else
|
||||
|
@ -42,16 +42,18 @@ module.buttons = {
|
|||
c:raise()
|
||||
end
|
||||
end,
|
||||
[3] = function(c)
|
||||
[3] = function(c,menu,item,button_id,mod, geo)
|
||||
client_menu.client = c
|
||||
local menu = client_menu()
|
||||
menu.parent_geometry = geo
|
||||
menu.visible = not menu.visible
|
||||
menu._internal.w:move_by_parent(geo, "cursor")
|
||||
end,
|
||||
[4] = function ()
|
||||
[4] = function(c,menu,item,button_id,mod, geo)
|
||||
client.focus.byidx(1)
|
||||
if capi.client.focus then capi.client.focus:raise() end
|
||||
end,
|
||||
[5] = function ()
|
||||
[5] = function(c,menu,item,button_id,mod, geo)
|
||||
client.focus.byidx(-1)
|
||||
if capi.client.focus then capi.client.focus:raise() end
|
||||
end
|
||||
|
@ -203,14 +205,14 @@ local function create_client_item(c,screen)
|
|||
item.state[MINIMIZED] = true
|
||||
end
|
||||
|
||||
item:connect_signal("mouse::enter", function()
|
||||
item.infoshapes = {
|
||||
{text = "1:23:45", bg = beautiful.tasklist_bg_overlay, align = "center"},
|
||||
{text = c.pid , bg = beautiful.tasklist_bg_overlay, align = "center"}
|
||||
}
|
||||
end)
|
||||
-- item:connect_signal("mouse::enter", function()
|
||||
-- item.infoshapes = {
|
||||
-- {text = "1:23:45", bg = beautiful.tasklist_bg_overlay, align = "center"},
|
||||
-- {text = c.pid , bg = beautiful.tasklist_bg_overlay, align = "center"}
|
||||
-- }
|
||||
-- end)
|
||||
item:connect_signal("mouse::leave", function()
|
||||
item.infoshapes = {}
|
||||
-- item.infoshapes = {}
|
||||
end)
|
||||
|
||||
item.add_suffix = function(w,w2)
|
||||
|
@ -334,9 +336,9 @@ local function new(screen)
|
|||
|
||||
load_clients(tag.selected(screen))
|
||||
|
||||
menu:connect_signal("button::press",function(menu,item,button_id,mod)
|
||||
menu:connect_signal("button::press",function(menu,item,button_id,mod,geo)
|
||||
if module.buttons and module.buttons[button_id] then
|
||||
module.buttons[button_id](item.client,menu,item,button_id,mod)
|
||||
module.buttons[button_id](item.client,menu,item,button_id,mod,geo)
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -344,7 +346,7 @@ local function new(screen)
|
|||
display_screenshot(i.client,geo,true)
|
||||
end)
|
||||
|
||||
return menu,menu._internal.layout
|
||||
return menu,menu._internal.widget
|
||||
end
|
||||
|
||||
function module.item(client)
|
||||
|
|
6
init.lua
6
init.lua
|
@ -22,10 +22,12 @@ end
|
|||
-- @tparam[opt="button1::pressed"] string event The event trigger for showing
|
||||
-- the menu.
|
||||
-- @tparam[opt=1] button_id The mouse button 1 (1= left, 3=right)
|
||||
local function set_menu(self,menu, event, button_id)
|
||||
-- @tparam[opt=widget] The position mode (see `radical.placement`)
|
||||
local function set_menu(self,menu, event, button_id, mode)
|
||||
if not menu then return end
|
||||
local event = event or "button::pressed"
|
||||
local button_id = button_id or 1
|
||||
mode = mode or "widget"
|
||||
|
||||
|
||||
local function trigger(_, geo)
|
||||
|
@ -47,7 +49,7 @@ local function set_menu(self,menu, event, button_id)
|
|||
if not m then return end
|
||||
|
||||
m.parent_geometry = geo
|
||||
m._internal.w:move_by_parent(geo)
|
||||
m._internal.w:move_by_parent(geo, mode)
|
||||
|
||||
m.visible = not m.visible
|
||||
end
|
||||
|
|
|
@ -120,6 +120,7 @@ local function new_item(data,args)
|
|||
style = args.style or data.item_style ,
|
||||
layout = args.layout or args.item_layout or nil ,
|
||||
infoshapes = args.infoshapes or nil ,
|
||||
shape = args.shape or data.item_shape ,
|
||||
overlay_draw= args.overlay_draw or data.overlay_draw ,
|
||||
item_border_color = args.item_border_color or data.item_border_color or nil ,
|
||||
},
|
||||
|
|
|
@ -19,7 +19,7 @@ local function generic(_, args)
|
|||
}
|
||||
|
||||
local function draw(item)
|
||||
item.widget:set_shape(args.shape, unpack(args.shape_args or {}))
|
||||
item.widget:set_shape(args.shape or item.shape, unpack(args.shape_args or {}))
|
||||
item.widget:set_shape_border_width(item.border_width)
|
||||
theme.update_colors(item)
|
||||
end
|
||||
|
|
310
placement.lua
310
placement.lua
|
@ -9,17 +9,22 @@ local module = {}
|
|||
-- Compute the new `x` and `y`.
|
||||
-- The workarea position need to be applied by the caller
|
||||
local map = {
|
||||
-- Corners
|
||||
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,
|
||||
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(x, y, w, h) return {x = x - w, y = y , width = w, height = h} end,
|
||||
|
@ -48,115 +53,268 @@ local function fit_in_screen(s, geo)
|
|||
return geo2.width == geo.width and geo2.height == geo.height
|
||||
end
|
||||
|
||||
--- Move the drawable (client or wibox) `d` to a screen corner or side.
|
||||
function module.corner(d, corner, s, honor_wa, update_wa)
|
||||
local sgeo = capi.screen[s][honor_wa and "workarea" or "geometry"]
|
||||
local dgeo = d:geometry()
|
||||
--- 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)
|
||||
--
|
||||
-- @param drawable 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(drawable, position, parent, args)
|
||||
args = args or {}
|
||||
parent = parent or drawable.screen or capi.mouse.screen
|
||||
|
||||
local pos = map[corner](sgeo.width, sgeo.height, dgeo.width, dgeo.height)
|
||||
local sgeo = nil
|
||||
|
||||
d : geometry {
|
||||
x = math.ceil(sgeo.x + pos.x) ,
|
||||
y = math.ceil(sgeo.y + pos.y) ,
|
||||
width = math.ceil(dgeo.width ) ,
|
||||
height = math.ceil(dgeo.height ) ,
|
||||
-- Get the parent geometry
|
||||
local parent_type = type(parent)
|
||||
|
||||
if parent_type == "screen" or parent_type == "number" then
|
||||
sgeo = capi.screen[parent][args.honor_workarea and "workarea" or "geometry"]
|
||||
else
|
||||
sgeo = parent:geometry()
|
||||
end
|
||||
|
||||
local dgeo = drawable:geometry()
|
||||
|
||||
local pos = map[position](sgeo.width, sgeo.height, dgeo.width, dgeo.height)
|
||||
|
||||
drawable : 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
|
||||
|
||||
--TODO update_wa
|
||||
-- Create many placement 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
|
||||
|
||||
--- Pin a drawable to a placement function.
|
||||
-- Auto update the position when the size change
|
||||
function module.pin(d, f, ...)
|
||||
--TODO memory leak
|
||||
-- Automatically update the position when the size change.
|
||||
-- All other arguments will be passed to the `position` function (if any)
|
||||
-- @param drawable A drawable (like `client` or `wibox`)
|
||||
-- @param position A position name (see `align`) or a position function
|
||||
function module.attach(drawable, position, ...)
|
||||
if type(position) == "string" then
|
||||
position = module[position]
|
||||
end
|
||||
|
||||
if not position then return end
|
||||
|
||||
local args = {...}
|
||||
|
||||
local function tracker()
|
||||
f(d, unpack(args))
|
||||
position(drawable, unpack(args))
|
||||
end
|
||||
|
||||
d:connect_signal("property::width" , tracker)
|
||||
d:connect_signal("property::height", tracker)
|
||||
drawable:connect_signal("property::width" , tracker)
|
||||
drawable: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.
|
||||
function module.get_relative_points(geo, mode)
|
||||
local use_mouse = true --TODO support modes
|
||||
|
||||
-- The closest points around the geometry
|
||||
local dps = {}
|
||||
function module.get_relative_points(geo, mode) --TODO rename regions
|
||||
mode = mode or "widget"
|
||||
|
||||
-- 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 geo.x and geo.width then
|
||||
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
|
||||
coords.y > geo.y and coords.y < geo.y+geo.height then
|
||||
geo.drawable = mouse.drawin_under_pointer()
|
||||
end
|
||||
--TODO add drawin_at(x,y) in the C core
|
||||
end
|
||||
|
||||
if geo.drawable then
|
||||
-- Case 1: A widget
|
||||
-- Get the drawable geometry
|
||||
local dpos = geo.drawable and geo.drawable.drawable:geometry() or {x=0, y=0}
|
||||
|
||||
local dgeo = geo.drawable.drawable:geometry()
|
||||
-- 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,
|
||||
}
|
||||
|
||||
-- Compute the absolute widget geometry
|
||||
local abs_widget_geo = {
|
||||
x = dgeo.x + geo.x,
|
||||
y = dgeo.y + geo.y,
|
||||
width = geo.width ,
|
||||
height = geo.height ,
|
||||
drawable = geo.drawable ,
|
||||
}
|
||||
-- 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 the comparaison point
|
||||
local center_point = use_mouse 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)
|
||||
|
||||
-- Get the 4 cloest points from `center_point` around the wibox
|
||||
local points = {
|
||||
left = {x = dgeo.x , y = center_point.y },
|
||||
right = {x = dgeo.x + dgeo.width , y = center_point.y },
|
||||
top = {x = center_point.x , y = dgeo.y },
|
||||
bottom = {x = center_point.x , y = dgeo.y + dgeo.height },
|
||||
}
|
||||
|
||||
local s = geo.drawable.screen or screen.getbycoord(
|
||||
center_point.x,
|
||||
center_point.y
|
||||
)
|
||||
-- Get the 4 closest points from `center_point` around the wibox
|
||||
local regions = {
|
||||
left = {x = cs.h.x , y = cs.h.y },
|
||||
right = {x = cs.h.x+cs.h.width, y = cs.h.y },
|
||||
top = {x = cs.v.x , y = cs.v.y },
|
||||
bottom = {x = cs.v.x , y = cs.v.y+cs.v.height},
|
||||
}
|
||||
|
||||
-- Compute the distance (dp) between the `center_point` and the sides
|
||||
for k, v in pairs(points) do
|
||||
local dx, dy = v.x - center_point.x, v.y - center_point.y
|
||||
dps[k] = {
|
||||
distance = math.sqrt(dx*dx + dy*dy),
|
||||
x = v.x,
|
||||
y = v.y,
|
||||
screen = s
|
||||
}
|
||||
end
|
||||
-- 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
|
||||
)
|
||||
|
||||
else
|
||||
-- Case 2: A random geometry
|
||||
--TODO
|
||||
-- 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 dps
|
||||
return regions
|
||||
end
|
||||
|
||||
-- @tparam drawable d A wibox or client
|
||||
|
@ -164,7 +322,7 @@ end
|
|||
-- @tparam[opt={}] table preferred_positions The preferred positions (position as key,
|
||||
-- and index as value)
|
||||
-- @treturn string The choosen position
|
||||
function module.move_relative(d, points, preferred_positions)
|
||||
function module.move_relative(d, points, preferred_positions) --TODO inside/outside
|
||||
local w,h = d.width, d.height
|
||||
|
||||
local pref_idx, pref_name = 99, nil
|
||||
|
|
23
radial.lua
23
radial.lua
|
@ -14,6 +14,7 @@ local wibox = require( "wibox" )
|
|||
local tag = require( "awful.tag" )
|
||||
local color = require( "gears.color" )
|
||||
local cairo = require( "lgi" ).cairo
|
||||
local shape = require( "gears.shape" )
|
||||
|
||||
local default = {width=90,height=30,radius=40,base_radius=60}
|
||||
|
||||
|
@ -114,14 +115,28 @@ function module.radial_client_select(args)
|
|||
data.indicator.cr:set_operator(cairo.Operator.SOURCE)
|
||||
end
|
||||
data.indicator.cr:set_source_rgb(1,0,0)
|
||||
data.indicator.cr:arc ( data.width/2 + (default.base_radius-20)*math.cos(angle),data.width/2 + (default.base_radius-20)*math.sin(angle),5,0,2*math.pi )
|
||||
data.indicator.cr:close_path()
|
||||
|
||||
-- The Inner dot around the dotted circle
|
||||
local littledot_rad = 5
|
||||
local dot = shape.transform(shape.circle) : translate(
|
||||
data.width/2 + (default.base_radius-20)*math.cos(angle) -littledot_rad,
|
||||
data.width/2 + (default.base_radius-20)*math.sin(angle) -littledot_rad
|
||||
)
|
||||
|
||||
dot(data.indicator.cr, 2*littledot_rad, 2*littledot_rad)
|
||||
data.indicator.cr:fill()
|
||||
|
||||
-- The little arc on top of the border
|
||||
data.indicator.cr:set_line_width(4)
|
||||
data.indicator.cr:arc( data.width/2,data.height/2,default.radius + default.base_radius ,angle-0.15,angle+0.15 )
|
||||
data.indicator.cr:stroke()
|
||||
data.indicator.cr:arc ( data.width/2+170,data.height/2,10,0,2*math.pi )
|
||||
data.indicator.cr:close_path()
|
||||
|
||||
-- The Big red dot TODO make it move
|
||||
dot = shape.transform(shape.circle) : translate(
|
||||
data.width/2+170 -2*littledot_rad,
|
||||
data.height/2 -2*littledot_rad
|
||||
)
|
||||
dot(data.indicator.cr, 4*littledot_rad, 4*littledot_rad)
|
||||
data.indicator.cr:fill()
|
||||
data.angle_cache = data.angle
|
||||
end
|
||||
|
|
|
@ -162,9 +162,9 @@ end
|
|||
-- direction to avoid going off-screen.
|
||||
-- @param[opt=mouse.coords()] geo A geometry table. It is given as parameter
|
||||
-- from buttons callbacks and signals such as `mouse::enter`.
|
||||
-- @param use_mouse Use the mouse position instead of the widget center as
|
||||
-- @param mode Use the mouse position instead of the widget center as
|
||||
-- reference point.
|
||||
function wb_func:move_by_parent(geo, use_mouse)
|
||||
function wb_func:move_by_parent(geo, mode)
|
||||
if rawget(self, "is_relative") == false then return end
|
||||
|
||||
local dps = placement.get_relative_points(geo, mode)
|
||||
|
|
|
@ -41,7 +41,7 @@ end
|
|||
|
||||
local function get_extents(text, height)
|
||||
local l = init_pango(height)
|
||||
l.text = text
|
||||
l.text = text or ""
|
||||
return l:get_pixel_extents()
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue