local M = {} local awful = require("awful") local beautiful = require("beautiful") local wibox = require("wibox") local Page = {} function Page:set_visible(visible, this_screen) local border_color = nil if visible then if this_screen then border_color = beautiful.border_focus or '#ffffff' else border_color = beautiful.border_marked or '#d00000' end else border_color = beautiful.border_normal or '#000000' end self.border:set_color(border_color) end function Page:client_remove(client) wgt = self._widgets[client] if wgt then self.client_container:remove_widgets(wgt) end self._widgets[client] = nil end function Page:client_add(c) local font = beautiful.small_text_font or "sans 7" local text = c.name local bg_normal = beautiful.bg_normal or "#000000" local fg_normal = beautiful.fg_normal or "#ffffff" local bg_focus = beautiful.bg_focus or "#ffffff" local fg_focus = beautiful.fg_focus or "#000000" local bg_urgent = beautiful.bg_urgent or "#ffffff" local fg_urgent = beautiful.fg_urgent or "#d00000" local tb = wibox.widget.textbox(text, true) local bg = wibox.container.background(tb, bg) tb:set_font(font) c:connect_signal("property::name", function() tb:set_text(c.name or "") end) c:connect_signal("focus", function(c) if c.screen == self.screen then bg:set_bg(bg_focus) bg:set_fg(fg_focus) end end) c:connect_signal("unfocus", function(c) if c.screen == self.screen then bg:set_bg(bg_normal) bg:set_fg(fg_normal) end end) c:connect_signal("property::urgent", function(c) if c.urgent then bg:set_bg(bg_urgent) bg:set_fg(fg_urgent) else if c == client.focus and c.screen == self.screen then bg:set_bg(bg_focus) bg:set_fg(fg_focus) else bg:set_bg(bg_normal) bg:set_fg(fg_normal) end end end) self.client_container:add(bg) self._widgets[c] = bg end function Page:new(tag, width, height, screen) local ret = setmetatable({}, self) self.__index = self local client_container = wibox.layout.flex.vertical() local border_width = beautiful.border_width or 1 local margin = wibox.container.margin(client_container) margin:set_top(border_width) margin:set_bottom(border_width) ret.widget = wibox.container.constraint(margin, 'exact', width, height) ret.client_container = client_container ret.border = margin ret.tag = tag ret.screen = screen -- a table of mapping clients to their widgets ret._widgets = {} ret:set_visible(tag.selected, tag.screen == screen) -- add initial clients for i, client in pairs(tag:clients()) do ret:client_add(client) end tag:connect_signal('tagged', function (t, c) ret:client_add(c) end) tag:connect_signal('untagged', function (t, c) ret:client_remove(c) end) return ret end local PagerDesk = {} function PagerDesk:new(desktop, screen, width, height) local ret = setmetatable({}, self) self.__index = self local title_desk = wibox.widget.textbox() local function set_title(desktop) title_desk:set_text(string.format("[%d] %s", desktop.idx, desktop.name)) end desktop:connect_signal("desktop:name", set_title) set_title(desktop) local title_page = wibox.widget.textbox() local title_bar = wibox.layout.ratio.horizontal() title_bar:set_spacing(10) title_bar:set_spacing_widget(wibox.widget.separator()) title_bar:add(title_desk, title_page) title_bar:set_ratio(1, 0.75) local title_normal_bg = beautiful.bg_normal or "#ffffff" local title_normal_fg = beautiful.fg_normal or "#000000" local title_focus_bg = beautiful.bg_focus or "#ff0000" local title_focus_fg = beautiful.fg_focus or "#000000" local title_container = wibox.container.background(title_bar, title_normal_bg) title_container:set_fg(title_normal_fg) ret.widget = wibox.layout.fixed.vertical(title_container) local nb_pages = #desktop.pages local page_height = height / nb_pages ret.pages = {} for i = 1, nb_pages do local page = desktop.pages[i] ret.pages[i] = Page:new(page, width, page_height, screen) ret.widget:add(ret.pages[i].widget) end desktop:connect_signal("page:view", function(desktop, s, page_idx) if s == ret.screen then title_page:set_text(string.format("%d", page_idx)) end ret.pages[page_idx]:set_visible(true, s == ret.screen) end) desktop:connect_signal("page:hide", function(desktop, page_idx) ret.pages[page_idx]:set_visible(false, false) end) client.connect_signal("focus", function(c) if c.screen == ret.screen then title_container:set_fg(title_focus_fg) title_container:set_bg(title_focus_bg) else title_container:set_fg(title_normal_fg) title_container:set_bg(title_normal_bg) end end) ret.desktop = desktop ret.screen = screen return ret end local Pager = {} function Pager:set_desktop(desktop) if self._desktops[desktop] == nil then self._desktops[desktop] = PagerDesk:new(desktop, self.screen, self.width, self.height) end self.widget:set_widget(self._desktops[desktop].widget) end function Pager:new(screen, width, height) local ret = setmetatable({}, self) self.__index = self ret.widget = wibox.container.constraint() ret._desktops = {} ret.screen = screen ret.width = width ret.height = height return ret end M.Pager = Pager return M