2013-12-19 06:22:49 +01:00
local setmetatable , type = setmetatable , type
local ipairs , pairs = ipairs , pairs
2014-03-28 07:13:12 +01:00
local button = require ( " awful.button " )
local beautiful = require ( " beautiful " )
local tag = require ( " awful.tag " )
local client2 = require ( " awful.client " )
local radical = require ( " radical " )
local util = require ( " awful.util " )
local wibox = require ( " wibox " )
local tag_list = require ( " radical.impl.taglist " )
2013-12-20 06:25:54 +01:00
local capi = { client = client , mouse = mouse , screen = screen }
2013-12-19 06:22:49 +01:00
local module , pause_monitoring = { } , false
-- Keep its own history instead of using awful.client.focus.history
local focusIdx , focusTable = 1 , setmetatable ( { } , { __mode = ' v ' } )
local function push_focus ( c )
2013-12-31 05:53:07 +01:00
if c and not pause_monitoring then
2013-12-19 06:22:49 +01:00
focusTable [ c ] = focusIdx
focusIdx = focusIdx + 1
end
end
capi.client . connect_signal ( " focus " , push_focus )
-- Remove client when closed
client.connect_signal ( " unmanage " , function ( c )
focusTable [ c ] = nil
end )
local function compare ( a , b )
return a [ 1 ] > b [ 1 ]
end
local function get_history ( screen )
local result = { }
for k , v in pairs ( focusTable ) do
result [ # result + 1 ] = { v , k }
end
local orphanCount = - 100
for k , v in ipairs ( capi.client . get ( screen or 1 ) ) do
if not focusTable [ v ] then
result [ # result + 1 ] = setmetatable ( { orphanCount , v } , { __mode = ' v ' } )
orphanCount = orphanCount - 1
end
end
table.sort ( result , compare )
return result
end
-- Simulate a titlebar
local function button_group ( args )
local widget = wibox.widget . imagebox ( )
2013-12-20 06:25:54 +01:00
widget : set_image ( module.titlebar_path .. args.field .. " _normal_ " .. ( args.checked ( ) and " active " or " inactive " ) .. " .png " )
2013-12-19 06:22:49 +01:00
widget : buttons ( util.table . join ( button ( { } , 1 , args.onclick ) ) )
return widget
end
local function select_next ( menu )
local item = menu.next_item
item.selected = true
item.button1 ( )
return true
end
2013-12-20 06:25:54 +01:00
local function is_in_tag ( t , c )
for k , v in ipairs ( c : tags ( ) ) do if t == v then return true end end
return false
end
2014-03-28 07:13:12 +01:00
local function reload_underlay ( client , item )
local underlays = { }
for k , v in ipairs ( client : tags ( ) ) do
underlays [ # underlays + 1 ] = v.name
end
if item then
item.underlay = underlays
end
return underlays
end
local function reload_highlight ( i )
if i.selected then
local hl = { }
for k , v in ipairs ( i.client : tags ( ) ) do
hl [ # hl + 1 ] = v
end
tag_list.highlight ( hl )
end
end
2013-12-20 06:25:54 +01:00
local function new ( args )
2014-03-02 22:29:07 +01:00
local histo = get_history ( --[[screen]] )
if # histo == o then
return
end
2014-03-22 22:35:43 +01:00
2013-12-31 05:53:07 +01:00
local t , auto_release = tag.selected ( capi.client . focus and capi.client . focus.screen or capi.mouse . screen ) , args.auto_release
2014-03-22 22:35:43 +01:00
local currentMenu = radical.box ( { filter = true , show_filter = true , autodiscard = true ,
2014-02-20 04:09:19 +01:00
disable_markup = true , fkeys_prefix = not auto_release , width = ( ( ( capi.screen [ capi.client . focus and capi.client . focus.screen or capi.mouse . screen ] ) . geometry.width ) / 2 ) ,
2014-03-22 22:35:43 +01:00
icon_transformation = beautiful.alttab_icon_transformation , filter_underlay = " Use [Shift] to toggle clients " , filter_underlay_color = beautiful.menu_bg_normal ,
filter_placeholder = " <span fgcolor=' " .. ( beautiful.menu_fg_disabled or beautiful.fg_disabled or " #777777 " ) .. " '>Type to filter</span> " } )
local pref_bg = wibox.widget . background ( )
local pref_l = wibox.layout . align.horizontal ( )
pref_bg.fit = function ( s , w , h )
local w2 , h2 = wibox.widget . background.fit ( s , w , h )
return w2 , currentMenu.item_height
end
pref_bg : set_bg ( currentMenu.bg_alternate )
local tb2 = wibox.widget . textbox ( )
tb2 : set_text ( " foo!!!! " )
pref_l : set_first ( tb2 )
pref_bg : set_widget ( pref_l )
local pref_menu , pref_menu_l = radical.bar { item_style = radical.item . style.basic }
pref_menu : add_widget ( radical.widgets . separator ( pref_menu , radical.widgets . separator.VERTICAL ) )
pref_menu : add_item { text = " Exclusive " }
pref_menu : add_widget ( radical.widgets . separator ( pref_menu , radical.widgets . separator.VERTICAL ) )
pref_menu : add_item { text = " 12 clients " }
pref_menu : add_widget ( radical.widgets . separator ( pref_menu , radical.widgets . separator.VERTICAL ) )
2014-03-30 04:56:09 +02:00
pref_menu : add_item { text = " All Screens " }
2014-03-22 22:35:43 +01:00
pref_menu : add_widget ( radical.widgets . separator ( pref_menu , radical.widgets . separator.VERTICAL ) )
pref_l : set_third ( pref_menu_l )
2013-12-20 06:25:54 +01:00
2014-03-22 22:35:43 +01:00
currentMenu : add_prefix_widget ( pref_bg )
2013-12-19 06:22:49 +01:00
currentMenu : add_key_hook ( { } , " Tab " , " press " , select_next )
2013-12-20 06:25:54 +01:00
currentMenu : add_key_hook ( { } , " Shift_L " , " press " , function ( )
currentMenu._current_item . checked = not currentMenu._current_item . checked
client2.toggletag ( t , currentMenu._current_item . client )
2014-03-28 07:13:12 +01:00
reload_underlay ( currentMenu._current_item . client , currentMenu._current_item )
reload_highlight ( currentMenu._current_item )
2013-12-20 06:25:54 +01:00
return true
end )
2013-12-19 06:22:49 +01:00
if module.titlebar_path then
2014-03-02 22:29:07 +01:00
for k , v2 in ipairs ( histo ) do
2013-12-19 06:22:49 +01:00
local l , v = wibox.layout . fixed.horizontal ( ) , v2 [ 2 ]
2013-12-20 06:25:54 +01:00
l : add ( button_group ( { client = v , field = " floating " , focus = false , checked = function ( ) return v.floating end , onclick = function ( ) v.floating = not v.floating end } ) )
l : add ( button_group ( { client = v , field = " maximized " , focus = false , checked = function ( ) return v.maximized end , onclick = function ( ) v.maximized = not v.maximized end } ) )
l : add ( button_group ( { client = v , field = " sticky " , focus = false , checked = function ( ) return v.sticky end , onclick = function ( ) v.sticky = not v.sticky end } ) )
l : add ( button_group ( { client = v , field = " ontop " , focus = false , checked = function ( ) return v.ontop end , onclick = function ( ) v.ontop = not v.ontop end } ) )
l : add ( button_group ( { client = v , field = " close " , focus = false , checked = function ( ) return false end , onclick = function ( ) v : kill ( ) end } ) )
2013-12-19 06:22:49 +01:00
2014-03-28 07:13:12 +01:00
local underlays = reload_underlay ( v )
2014-01-18 08:20:07 +01:00
2013-12-19 06:22:49 +01:00
l.fit = function ( s , w , h ) return 5 * h , h end
2014-03-28 07:13:12 +01:00
local i = currentMenu : add_item ( {
2013-12-20 06:25:54 +01:00
text = v.name ,
2014-02-20 04:09:19 +01:00
icon = v.icon or module.default_icon ,
2013-12-31 05:53:07 +01:00
suffix_widget = not auto_release and l or nil ,
selected = capi.client . focus and capi.client . focus == v ,
2014-01-18 08:20:07 +01:00
underlay = underlays ,
2013-12-31 05:53:07 +01:00
checkable = not auto_release ,
checked = not auto_release and is_in_tag ( t , v ) or nil ,
2013-12-20 06:25:54 +01:00
button1 = function ( )
2013-12-19 06:22:49 +01:00
if v : tags ( ) [ 1 ] and v : tags ( ) [ 1 ] . selected == false then
tag.viewonly ( v : tags ( ) [ 1 ] )
end
capi.client . focus = v
2014-02-08 06:52:42 +01:00
v : raise ( )
2014-01-18 08:20:07 +01:00
currentMenu.visible = false
2013-12-19 06:22:49 +01:00
end ,
2014-03-28 07:13:12 +01:00
} )
i.client = v
i : connect_signal ( " selected::changed " , reload_highlight )
2013-12-19 06:22:49 +01:00
end
end
2013-12-31 05:53:07 +01:00
if auto_release then
2013-12-20 06:25:54 +01:00
currentMenu : add_key_hook ( { } , " Alt_L " , " release " , function ( _ )
currentMenu.visible = false
return false
end )
2013-12-19 06:22:49 +01:00
select_next ( currentMenu )
end
2013-12-20 06:25:54 +01:00
pause_monitoring , currentMenu.visible = true , true
2013-12-19 06:22:49 +01:00
currentMenu : connect_signal ( " visible::changed " , function ( m )
2014-03-28 07:13:12 +01:00
if not m.visible then
pause_monitoring = false
push_focus ( capi.client . focus )
tag_list.highlight ( )
end
2013-12-19 06:22:49 +01:00
end )
return currentMenu
end
function module . altTab ( args )
2013-12-20 06:25:54 +01:00
new ( { leap = 1 , auto_release = ( args or { } ) . auto_release } )
2013-12-19 06:22:49 +01:00
end
function module . altTabBack ( args )
2013-12-20 06:25:54 +01:00
new ( { leap = - 1 , auto_release = ( args or { } ) . auto_release } )
2013-12-19 06:22:49 +01:00
end
return setmetatable ( module , { __call = function ( _ , ... ) return new ( ... ) end } )
-- kate: space-indent on; indent-width 2; replace-tabs on;