summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2017-01-26 12:25:52 +0100
committerAnton Khirnov <anton@khirnov.net>2017-01-26 12:25:52 +0100
commit9b322660ee6b7640af24def50a7fb8615a8ab126 (patch)
treea3064adc789a0ed91149432a15b86c66d7967c35
parente8bb1f4a1844f07fc2f6973f2e7b400f2ddf2f3d (diff)
Basic support for desktops/pages.
-rw-r--r--bindings.lua275
-rw-r--r--desktop.lua42
-rw-r--r--pager.lua147
-rw-r--r--rc.lua48
-rw-r--r--theme.lua94
-rw-r--r--workspace.lua127
6 files changed, 530 insertions, 203 deletions
diff --git a/bindings.lua b/bindings.lua
index 87b1a76..3dd4f21 100644
--- a/bindings.lua
+++ b/bindings.lua
@@ -1,144 +1,145 @@
+local M = {}
+
local awful = require("awful")
local commondefs = require("commondefs")
local utils = require("utils")
-local modkey = commondefs.modkey
-
-local globalkeys = awful.util.table.join(
- awful.key({ modkey, "Mod1" }, "Delete", awesome.restart),
- awful.key({ modkey }, "Pause", function () awful.util.spawn("xscreensaver-command -lock") end),
-
- -- program launching
- awful.key({ modkey, }, "t", function () awful.util.spawn(commondefs.terminal) end),
- awful.key({ modkey, }, "v", function () awful.util.spawn(commondefs.terminal .. " -e alsamixer") end),
- awful.key({ modkey, }, "Escape", function () awful.util.spawn(commondefs.terminal .. " -e htop") end),
-
- -- audio control
- awful.key({ modkey }, "Prior", function () utils.vol_control(1) end),
- awful.key({ modkey }, "Next", function () utils.vol_control(-1) end),
- awful.key({ modkey }, "grave", function () awful.util.spawn("mpc toggle") end),
- awful.key({ modkey }, "b", function () awful.util.spawn("mpc next") end),
- awful.key({ modkey }, "p", function () awful.util.spawn("mpc prev") end),
-
- -- focus/screen switching
- awful.key({ modkey, }, "q", function() utils.screen_focus_physical(1) end),
- awful.key({ modkey, }, "w", function() utils.screen_focus_physical(2) end),
- awful.key({ modkey, }, "e", function() utils.screen_focus_physical(3) end),
-
- awful.key({ modkey, }, "Left", awful.tag.viewprev ),
- awful.key({ modkey, }, "Right", awful.tag.viewnext ),
-
- awful.key({ modkey, }, "Tab",
- function ()
- awful.client.focus.byidx(1)
- if client.focus then client.focus:raise() end
- end),
- awful.key({ modkey, "Shift" }, "Tab",
- function ()
- awful.client.focus.byidx(-1)
- if client.focus then client.focus:raise() end
- end),
- awful.key({ modkey, "Mod1" }, "Tab",
- function ()
- awful.client.focus.history.previous()
- if client.focus then
- client.focus:raise()
- end
- end),
-
- -- Layout manipulation
- awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end),
- awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end),
- awful.key({ modkey, }, "u", awful.client.urgent.jumpto),
-
-
- awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),
- awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
- awful.key({ modkey, }, ",", function () awful.tag.incnmaster( 1) end),
- awful.key({ modkey, }, ".", function () awful.tag.incnmaster(-1) end),
- awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
- awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end),
-
- awful.key({ modkey, "Control" }, "n", awful.client.restore),
-
- -- Prompt
- awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end),
-
- awful.key({ modkey }, "x",
- function ()
- awful.prompt.run({ prompt = "Run Lua code: " },
- mypromptbox[mouse.screen].widget,
- awful.util.eval, nil,
- awful.util.getdir("cache") .. "/history_eval")
- end)
-)
-
--- Bind all key numbers to tags.
--- Be careful: we use keycodes to make it works on any keyboard layout.
--- This should map on the top row of your keyboard, usually 1 to 9.
-for i = 1, 9 do
- globalkeys = awful.util.table.join(globalkeys,
- -- View tag only.
- awful.key({ modkey }, "#" .. i + 9,
- function ()
- local screen = mouse.screen
- local tag = awful.tag.gettags(screen)[i]
- if tag then
- awful.tag.viewonly(tag)
- end
- end),
- -- Toggle tag.
- awful.key({ modkey, "Control" }, "#" .. i + 9,
- function ()
- local screen = mouse.screen
- local tag = awful.tag.gettags(screen)[i]
- if tag then
- awful.tag.viewtoggle(tag)
- end
- end),
- -- Move client to tag.
- awful.key({ modkey, "Shift" }, "#" .. i + 9,
- function ()
- if client.focus then
- local tag = awful.tag.gettags(client.focus.screen)[i]
- if tag then
- awful.client.movetotag(tag)
- end
- end
- end),
- -- Toggle tag.
- awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
+function M.create(workspace)
+ local modkey = commondefs.modkey
+
+ local globalkeys = awful.util.table.join(
+ awful.key({ modkey, "Mod1" }, "Delete", awesome.restart),
+ awful.key({ modkey }, "Pause", function () awful.util.spawn("xscreensaver-command -lock") end),
+
+ -- program launching
+ awful.key({ modkey, }, "t", function () awful.util.spawn(commondefs.terminal) end),
+ awful.key({ modkey, }, "v", function () awful.util.spawn(commondefs.terminal .. " -e alsamixer") end),
+ awful.key({ modkey, }, "Escape", function () awful.util.spawn(commondefs.terminal .. " -e htop") end),
+
+ -- audio control
+ awful.key({ modkey }, "Prior", function () utils.vol_control(1) end),
+ awful.key({ modkey }, "Next", function () utils.vol_control(-1) end),
+ awful.key({ modkey }, "grave", function () awful.util.spawn("mpc toggle") end),
+ awful.key({ modkey }, "b", function () awful.util.spawn("mpc next") end),
+ awful.key({ modkey }, "p", function () awful.util.spawn("mpc prev") end),
+
+ -- focus/screen switching
+ awful.key({ modkey, }, "q", function() utils.screen_focus_physical(1) end),
+ awful.key({ modkey, }, "w", function() utils.screen_focus_physical(2) end),
+ awful.key({ modkey, }, "e", function() utils.screen_focus_physical(3) end),
+
+ awful.key({ modkey, }, "Up", function() workspace:view_relative(-1) end ),
+ awful.key({ modkey, }, "Down", function() workspace:view_relative(1) end ),
+
+ awful.key({ modkey, }, "Tab",
+ function ()
+ awful.client.focus.byidx(1)
+ if client.focus then client.focus:raise() end
+ end),
+ awful.key({ modkey, "Shift" }, "Tab",
+ function ()
+ awful.client.focus.byidx(-1)
+ if client.focus then client.focus:raise() end
+ end),
+ awful.key({ modkey, "Mod1" }, "Tab",
+ function ()
+ awful.client.focus.history.previous()
+ if client.focus then
+ client.focus:raise()
+ end
+ end),
+
+ -- Layout manipulation
+ awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end),
+ awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end),
+ awful.key({ modkey, }, "u", awful.client.urgent.jumpto),
+
+
+ awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),
+ awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
+ awful.key({ modkey, }, ",", function () awful.tag.incnmaster( 1) end),
+ awful.key({ modkey, }, ".", function () awful.tag.incnmaster(-1) end),
+ awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
+ awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end),
+
+ awful.key({ modkey, "Control" }, "n", awful.client.restore),
+
+ -- Prompt
+ awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end),
+
+ awful.key({ modkey }, "x",
function ()
- if client.focus then
- local tag = awful.tag.gettags(client.focus.screen)[i]
- if tag then
- awful.client.toggletag(tag)
- end
- end
- end))
+ awful.prompt.run({ prompt = "Run Lua code: " },
+ mypromptbox[mouse.screen].widget,
+ awful.util.eval, nil,
+ awful.util.getdir("cache") .. "/history_eval")
+ end)
+ )
+
+ -- Bind all key numbers to tags.
+ -- Be careful: we use keycodes to make it works on any keyboard layout.
+ -- This should map on the top row of your keyboard, usually 1 to 9.
+ for i = 1, 10 do
+ globalkeys = awful.util.table.join(globalkeys,
+ -- View tag only.
+ awful.key({ modkey }, "#" .. i + 9,
+ function ()
+ local screen = mouse.screen
+
+ local state = workspace.screen_state[screen]
+ local desk = 1
+ if state then
+ desk = state.desktop
+ end
+
+ workspace:view(screen, desk, i)
+ end),
+ -- Move client to tag.
+ awful.key({ modkey, "Shift" }, "#" .. i + 9,
+ function ()
+ if client.focus then
+ local c = client.focus
+ workspace:move_client(c, workspace.screen_state[c.screen].desktop, i)
+ end
+ end))
+ end
+
+ for i = 1, 12 do
+ globalkeys = awful.util.table.join(globalkeys,
+ -- View tag only.
+ awful.key({ modkey }, "#" .. i + 66,
+ function ()
+ local screen = mouse.screen
+ if workspace.desktops[i] == nil then
+ workspace:add_desktop("Desktop " .. i, 10)
+ end
+ workspace:view(screen, i)
+ end),
+ -- Move client to tag.
+ awful.key({ modkey, "Shift" }, "#" .. i + 9,
+ function ()
+ if client.focus then
+ local c = client.focus
+ workspace:move_client(c, workspace.screen_state[c.screen].desktop, i)
+ end
+ end))
+ end
+
+ local clientkeys = awful.util.table.join(
+ awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end),
+ awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end),
+ awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ),
+ awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
+ awful.key({ modkey, }, "o", awful.client.movetoscreen ),
+ awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end),
+ awful.key({ modkey, }, "m",
+ function (c)
+ c.maximized_horizontal = not c.maximized_horizontal
+ c.maximized_vertical = not c.maximized_vertical
+ end)
+ )
+
+ return globalkeys, clientkeys
end
-local clientkeys = awful.util.table.join(
- awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end),
- awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end),
- awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ),
- awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
- awful.key({ modkey, }, "o", awful.client.movetoscreen ),
- awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end),
- awful.key({ modkey, }, "n",
- function (c)
- -- The client currently has the input focus, so it cannot be
- -- minimized, since minimized clients can't have the focus.
- c.minimized = true
- end),
- awful.key({ modkey, }, "m",
- function (c)
- c.maximized_horizontal = not c.maximized_horizontal
- c.maximized_vertical = not c.maximized_vertical
- end)
-)
-
-return {
- globalkeys = globalkeys,
- clientkeys = clientkeys,
-}
+return M
diff --git a/desktop.lua b/desktop.lua
index 376410b..d714dc9 100644
--- a/desktop.lua
+++ b/desktop.lua
@@ -1,22 +1,46 @@
local M = {}
-local awful = require("awful")
+local awful = require("awful")
+local object = require("gears.object")
+
+local function desktop_show(self, screen, page_idx)
+ if page_idx == nil then
+ page_hist = self.page_history[screen]
+ if page_hist ~= nil then
+ page_idx = page_hist
+ else
+ page_idx = 1
+ end
+ end
+
+ page = self.pages[page_idx]
-local Desktop = {}
+ if page then
+ self.page_history[screen] = page_idx
+ end
+ return page_idx
+end
-function Desktop:new(name, nb_pages)
- o = setmetatable({}, self)
+local function desktop_new(idx, name, nb_pages, layout)
+ local ret = object()
- o.name = name
+ ret:add_signal("page:view")
- o.pages = {}
+ ret.show = desktop_show
+
+ ret.name = name
+
+ ret.pages = {}
for i = 1, nb_pages do
- o.pages[i] = awful.tag.add(name .. i)
+ ret.pages[i] = awful.tag.add(name .. i, { layout = layout })
end
- return o
+ -- page_history[i] is the last page viewed on screen i
+ ret.page_history = {}
+
+ return ret
end
-M.Desktop = Desktop
+M.new = desktop_new
return M
diff --git a/pager.lua b/pager.lua
index 867b09b..1cef725 100644
--- a/pager.lua
+++ b/pager.lua
@@ -1,47 +1,138 @@
local M = {}
-local wibox = require("wibox")
+local awful = require("awful")
+local beautiful = require("beautiful")
+local wibox = require("wibox")
-local Pager = {}
+local Page = {}
-local function pager_fit(pager, width, height)
- return width, width * #pager.desktop.pages
+function Page:set_active(active)
+ local border_color = nil
+ if active then
+ border_color = beautiful.border_focus or '#ffffff'
+ else
+ border_color = beautiful.border_normal or '#000000'
+ end
+ self.border:set_color(border_color)
end
-local function pager_draw(pager, wibox, cr, width, height)
- if pager.desktop == nil then
- return
+function Page:update()
+ local font = beautiful.small_text_font or "sans 7"
+
+ self.client_container:reset()
+ for i, client in pairs(self.tag:clients()) do
+ local text = client.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 tb = wibox.widget.textbox(text, true)
+ local bg = wibox.widget.background(tb, bg)
+
+ tb:set_font(font)
+
+ client:connect_signal("property::name", function() tb:set_text(client.name) end)
+ client:connect_signal("focus",
+ function(c)
+ if c.screen == self.pager.init_data.screen then
+ bg:set_bg(bg_focus)
+ bg:set_fg(fg_focus)
+ end
+ end)
+ client:connect_signal("unfocus",
+ function(c)
+ if c.screen == self.pager.init_data.screen then
+ bg:set_bg(bg_normal)
+ bg:set_fg(fg_normal)
+ end
+ end)
+
+ self.client_container:add(bg)
end
+end
- local nb_pages = #pager.desktop.pages
- local page_height = height / nb_pages
+function Page:new(tag, index, width, height, pager)
+ local ret = setmetatable({}, self)
+ self.__index = self
- for i = 1, nb_pages do
- local page = pager.desktop.pages[i]
- local draw_h_start = (i - 1) * page_height
-
- for j, client in pairs(page:clients()) do
- local text = client.name
- local extents = cr:text_extents(text)
- cr:move_to(0, draw_h_start)
- cr:show_text(text)
- draw_h_start = draw_h_start + extents.height
+ local client_container = wibox.layout.flex.vertical()
+
+ local border_width = beautiful.border_width or 1
+ local margin = wibox.layout.margin(client_container)
+ margin:set_top(border_width)
+ margin:set_bottom(border_width)
+
+ ret.widget = wibox.layout.constraint(margin, 'exact', width, height)
+
+ ret.client_container = client_container
+ ret.border = margin
+ ret.tag = tag
+ ret.pager = pager
+
+ tag:connect_signal('tagged', function (c) ret:update() end)
+ tag:connect_signal('untagged', function (c) ret:update() end)
+
+ ret:set_active(false)
+ ret:update()
+
+ return ret
+end
+
+local function pager_set_active(self, screen, page_idx)
+ if self.init_data.screen == screen then
+ if self.active_page then
+ self.active_page:set_active(false)
end
+ self.pages[page_idx]:set_active(true)
+ self.active_page = self.pages[page_idx]
end
- cr:set_line_width(3)
- cr:stroke()
end
-local function pager_set_desktop(pager, desktop)
- pager.desktop = desktop
- pager:emit_signal("widget::updated")
+local function pager_set_desktop(self, desktop)
+ init_data = self.init_data
+
+ print("pager " .. init_data.screen .. " set desktop")
+
+ self:reset()
+
+ self.init_data = init_data
+ self.set_desktop = pager_set_desktop
+
+ self.active_page = nil
+ self.pages = {}
+
+ self.desktop = desktop
+
+ local nb_pages = #self.desktop.pages
+ local page_height = self.init_data.height / nb_pages
+
+ local title = wibox.widget.textbox(desktop.name, false)
+ title:set_align("center")
+ local title_bg = beautiful.bg_focus or "#ffffff"
+ local title_fg = beautiful.fg_focus or "#000000"
+ local title_container = wibox.widget.background(title, title_bg)
+ title_container:set_fg(title_fg)
+ self:add(title_container)
+
+ for i = 1, nb_pages do
+ local page = self.desktop.pages[i]
+ self.pages[i] = Page:new(page, i, self.init_data.width, page_height, self)
+ self:add(self.pages[i].widget)
+ end
+
+ self.desktop:connect_signal("page:view",
+ function(desktop, s, page_idx)
+ pager_set_active(self, s, page_idx) end)
end
-function Pager:new()
- local pager = wibox.widget.base.make_widget()
+local Pager = {}
+
+function Pager:new(screen, width, height)
+ local pager = wibox.layout.fixed.vertical()
- pager.fit = pager_fit
- pager.draw = pager_draw
+ pager.init_data = { screen = screen, width = width, height = height }
pager.set_desktop = pager_set_desktop
return pager
diff --git a/rc.lua b/rc.lua
index aef7510..eaf9de0 100644
--- a/rc.lua
+++ b/rc.lua
@@ -13,8 +13,8 @@ local menubar = require("menubar")
local bindings = require("bindings")
local commondefs = require("commondefs")
-local desktop = require("desktop")
local pager = require("pager")
+local workspace = require("workspace")
-- {{{ Error handling
-- Check if awesome encountered an error during startup and fell back to
@@ -43,7 +43,7 @@ end
-- {{{ Variable definitions
-- Themes define colours, icons, font and wallpapers.
-beautiful.init("/usr/share/awesome/themes/default/theme.lua")
+beautiful.init(awful.util.getdir("config") .. "/theme.lua")
-- Table of layouts to cover with awful.layout.inc, order matters.
local layouts =
@@ -54,16 +54,8 @@ local layouts =
-- }}}
-- {{{ Tags
--- Define a tag table which hold all screen tags.
-tags = {}
-for s = 1, screen.count() do
- -- Each screen has its own tag table.
- tags[s] = awful.tag({ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, s, layouts[1])
-end
-
-desktops = {}
-
-desktops[1] = desktop.Desktop:new("main", 10)
+workspace = workspace.Workspace:new(layouts)
+workspace:add_desktop("main", 10)
-- }}}
-- Menubar configuration
@@ -78,15 +70,7 @@ mytextclock = awful.widget.textclock()
mywibox = {}
mypromptbox = {}
mylayoutbox = {}
-mytaglist = {}
-mytaglist.buttons = awful.util.table.join(
- awful.button({ }, 1, awful.tag.viewonly),
- awful.button({ commondefs.modkey }, 1, awful.client.movetotag),
- awful.button({ }, 3, awful.tag.viewtoggle),
- awful.button({ commondefs.modkey }, 3, awful.client.toggletag),
- awful.button({ }, 4, function(t) awful.tag.viewnext(awful.tag.getscreen(t)) end),
- awful.button({ }, 5, function(t) awful.tag.viewprev(awful.tag.getscreen(t)) end)
- )
+
mytasklist = {}
mytasklist.buttons = awful.util.table.join(
awful.button({ }, 1, function (c)
@@ -136,18 +120,22 @@ for s = 1, screen.count() do
awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end),
awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end)))
- -- Create a taglist widget
- mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.filter.all, mytaglist.buttons, nil, nil, wibox.layout.fixed.vertical())
-
-- Create a tasklist widget
--mytasklist[s] = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, mytasklist.buttons, nil, nil, wibox.layout.fixed.vertical())
- pgr = pager.Pager:new(desktops[1])
- pgr:set_desktop(desktops[1])
+ local pgr = pager.Pager:new(s, 128, 800)
+ pgr:set_desktop(workspace.desktops[1])
mytasklist[s] = pgr
+ workspace.signals:connect_signal("desktop:view",
+ function(signals, screen_idx, desktop)
+ print("desktop:view " .. desktop .. " on " .. screen_idx)
+ if screen_idx == s then
+ pgr:set_desktop(workspace.desktops[desktop])
+ end
+ end)
+
-- Widgets that are aligned to the left
local left_layout = wibox.layout.fixed.vertical()
- left_layout:add(mytaglist[s])
left_layout:add(mypromptbox[s])
-- Widgets that are aligned to the right
@@ -181,8 +169,10 @@ clientbuttons = awful.util.table.join(
awful.button({ commondefs.modkey }, 1, awful.mouse.client.move),
awful.button({ commondefs.modkey }, 3, awful.mouse.client.resize))
+local globalkeys, clientkeys = bindings.create(workspace)
+
-- Set keys
-root.keys(bindings.globalkeys)
+root.keys(globalkeys)
-- {{{ Rules
-- Rules to apply to new clients (through the "manage" signal).
@@ -193,7 +183,7 @@ awful.rules.rules = {
border_color = "#000000",
focus = awful.client.focus.filter,
raise = true,
- keys = bindings.clientkeys,
+ keys = clientkeys,
buttons = clientbuttons } },
{ rule = { class = "MPlayer" },
properties = { floating = true } },
diff --git a/theme.lua b/theme.lua
new file mode 100644
index 0000000..0b25eab
--- /dev/null
+++ b/theme.lua
@@ -0,0 +1,94 @@
+local theme = {}
+
+theme.font = "sans 8"
+
+theme.bg_normal = "#000000"
+theme.bg_focus = "#535d6c"
+theme.bg_urgent = "#ff0000"
+theme.bg_minimize = "#444444"
+theme.bg_systray = theme.bg_normal
+
+theme.fg_normal = "#b0e2ff"
+theme.fg_focus = "#ffffff"
+theme.fg_urgent = "#ffffff"
+theme.fg_minimize = "#ffffff"
+
+theme.border_width = 3
+theme.border_normal = "#4f4f4f"
+theme.border_focus = "#b0e2ff"
+theme.border_marked = "#91231c"
+
+-- There are other variable sets
+-- overriding the default one when
+-- defined, the sets are:
+-- taglist_[bg|fg]_[focus|urgent|occupied|empty]
+-- tasklist_[bg|fg]_[focus|urgent]
+-- titlebar_[bg|fg]_[normal|focus]
+-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
+-- mouse_finder_[color|timeout|animate_timeout|radius|factor]
+-- Example:
+--theme.taglist_bg_focus = "#ff0000"
+
+-- Display the taglist squares
+theme.taglist_squares_sel = "/usr/share/awesome/themes/default/taglist/squarefw.png"
+theme.taglist_squares_unsel = "/usr/share/awesome/themes/default/taglist/squarew.png"
+
+-- Variables set for theming the menu:
+-- menu_[bg|fg]_[normal|focus]
+-- menu_[border_color|border_width]
+theme.menu_submenu_icon = "/usr/share/awesome/themes/default/submenu.png"
+theme.menu_height = 15
+theme.menu_width = 100
+
+-- You can add as many variables as
+-- you wish and access them by using
+-- beautiful.variable in your rc.lua
+--theme.bg_widget = "#cc0000"
+
+-- Define the image to load
+theme.titlebar_close_button_normal = "/usr/share/awesome/themes/default/titlebar/close_normal.png"
+theme.titlebar_close_button_focus = "/usr/share/awesome/themes/default/titlebar/close_focus.png"
+
+theme.titlebar_ontop_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/ontop_normal_inactive.png"
+theme.titlebar_ontop_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/ontop_focus_inactive.png"
+theme.titlebar_ontop_button_normal_active = "/usr/share/awesome/themes/default/titlebar/ontop_normal_active.png"
+theme.titlebar_ontop_button_focus_active = "/usr/share/awesome/themes/default/titlebar/ontop_focus_active.png"
+
+theme.titlebar_sticky_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/sticky_normal_inactive.png"
+theme.titlebar_sticky_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/sticky_focus_inactive.png"
+theme.titlebar_sticky_button_normal_active = "/usr/share/awesome/themes/default/titlebar/sticky_normal_active.png"
+theme.titlebar_sticky_button_focus_active = "/usr/share/awesome/themes/default/titlebar/sticky_focus_active.png"
+
+theme.titlebar_floating_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/floating_normal_inactive.png"
+theme.titlebar_floating_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/floating_focus_inactive.png"
+theme.titlebar_floating_button_normal_active = "/usr/share/awesome/themes/default/titlebar/floating_normal_active.png"
+theme.titlebar_floating_button_focus_active = "/usr/share/awesome/themes/default/titlebar/floating_focus_active.png"
+
+theme.titlebar_maximized_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/maximized_normal_inactive.png"
+theme.titlebar_maximized_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/maximized_focus_inactive.png"
+theme.titlebar_maximized_button_normal_active = "/usr/share/awesome/themes/default/titlebar/maximized_normal_active.png"
+theme.titlebar_maximized_button_focus_active = "/usr/share/awesome/themes/default/titlebar/maximized_focus_active.png"
+
+theme.wallpaper = "/usr/share/awesome/themes/default/background.png"
+
+-- You can use your own layout icons like this:
+theme.layout_fairh = "/usr/share/awesome/themes/default/layouts/fairhw.png"
+theme.layout_fairv = "/usr/share/awesome/themes/default/layouts/fairvw.png"
+theme.layout_floating = "/usr/share/awesome/themes/default/layouts/floatingw.png"
+theme.layout_magnifier = "/usr/share/awesome/themes/default/layouts/magnifierw.png"
+theme.layout_max = "/usr/share/awesome/themes/default/layouts/maxw.png"
+theme.layout_fullscreen = "/usr/share/awesome/themes/default/layouts/fullscreenw.png"
+theme.layout_tilebottom = "/usr/share/awesome/themes/default/layouts/tilebottomw.png"
+theme.layout_tileleft = "/usr/share/awesome/themes/default/layouts/tileleftw.png"
+theme.layout_tile = "/usr/share/awesome/themes/default/layouts/tilew.png"
+theme.layout_tiletop = "/usr/share/awesome/themes/default/layouts/tiletopw.png"
+theme.layout_spiral = "/usr/share/awesome/themes/default/layouts/spiralw.png"
+theme.layout_dwindle = "/usr/share/awesome/themes/default/layouts/dwindlew.png"
+
+theme.awesome_icon = "/usr/share/awesome/icons/awesome16.png"
+
+-- Define the icon theme for application icons. If not set then the icons
+-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
+theme.icon_theme = nil
+
+return theme
diff --git a/workspace.lua b/workspace.lua
new file mode 100644
index 0000000..537345d
--- /dev/null
+++ b/workspace.lua
@@ -0,0 +1,127 @@
+local M = {}
+
+local awful = require("awful")
+local desktop = require("desktop")
+local object = require("gears.object")
+
+local Workspace = {}
+
+function Workspace:add_desktop(name, nb_pages)
+ idx = #self.desktops + 1
+ self.desktops[idx] = desktop.new(idx, name, nb_pages, self.layouts[1])
+ return idx
+end
+
+function Workspace:_apply_state()
+ orig_focus = mouse.screen
+
+ for s = 1, screen.count() do
+ if self.screen_state[s] then
+ awful.tag.viewnone(s)
+
+ desk = self.screen_state[s].desktop
+ page = self.desktops[desk].pages[self.screen_state[s].page]
+ awful.tag.setscreen(page, s)
+ end
+ end
+ for s = 1, screen.count() do
+ state = self.screen_state[s]
+ if state then
+ desk_idx = state.desktop
+ desk = self.desktops[desk_idx]
+ page_idx = state.page
+ page = desk.pages[page_idx]
+ print("workspace displaying: " .. s .. " => " .. desk_idx .. "/" .. page_idx)
+
+ awful.tag.viewonly(page)
+
+ desk:emit_signal("page:view", s, page_idx)
+ end
+ end
+
+ awful.screen.focus(orig_focus)
+end
+
+function Workspace:view(screen, desktop, page_idx)
+ print("workspace: " .. screen .. ": view " .. desktop .. "/" .. (page_idx or "nil"))
+ -- the page currently displayed on the target screen
+ old = {}
+ if self.screen_state[screen] then
+ old.desk = self.screen_state[screen].desktop
+ old.page_idx = self.screen_state[screen].page
+ old.page = self.desktops[old.desk].pages[page_old_idx]
+ print(screen .. " now showing " .. old.desk .. "/" .. old.page_idx)
+ end
+
+ -- the page to display on the target screen
+ page_idx = self.desktops[desktop]:show(screen, page_idx)
+ if page_idx then
+ page_new = self.desktops[desktop].pages[page_idx]
+ end
+
+ -- the screen on which the new page is currently displayed (if any)
+ screen_cur = nil
+ if page_new and page_new.selected then
+ screen_cur = awful.tag.getscreen(page_new)
+ print("page " .. page_idx .. " now displayed on " .. screen_cur)
+ end
+
+ if old.page ~= page_new or page_new == nil then
+ self.screen_state[screen] = { page = page_idx, desktop = desktop }
+ if desktop ~= old.desk then
+ self.signals:emit_signal("desktop:view", screen, desktop)
+ end
+
+ if screen_cur then
+ desk_prev = self.screen_state[screen_cur].desktop
+ old.page_idx = self.desktops[old.desk]:show(screen_cur, old.page_idx)
+
+ self.screen_state[screen_cur] = { page = old.page_idx, desktop = old.desk }
+ if desk_prev ~= old.desk then
+ self.signals:emit_signal("desktop:view", screen_cur, old.desk)
+ end
+ end
+
+
+ self:_apply_state()
+ end
+end
+
+function Workspace:view_relative(offset, screen)
+ screen = screen or mouse.screen
+ print("view relative " .. offset .. " on " .. screen)
+
+ state = self.screen_state[screen]
+ if state then
+ desk = state.desktop
+ print("state " .. state.page .. " res " .. (state.page + offset) % 10)
+ page = 1 + ((state.page - 1 + offset) % #self.desktops[desk].pages)
+ print("desk " .. desk .. " " .. #self.desktops[desk].pages)
+ print("view relative switch to " .. page)
+
+ self:view(screen, desk, page)
+ end
+end
+
+function Workspace:move_client(client, desk, page)
+ print("move to " .. desk .. "/" .. page)
+ awful.client.movetotag(self.desktops[desk].pages[page], client)
+end
+
+function Workspace:new(layouts)
+ local o = setmetatable({}, self)
+ self.__index = self
+
+ o.desktops = {}
+ o.screen_state = {}
+ o.layouts = layouts
+
+ o.signals = object()
+ o.signals:add_signal("desktop:view")
+
+ return o
+end
+
+M.Workspace = Workspace
+
+return M