summaryrefslogtreecommitdiff
path: root/workspace.lua
blob: d6ef0612ffa1eb46eaffea976cdf71e6f70dd0a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
local M = {}

local awful = require("awful")
local desktop = require("desktop")
local object = require("gears.object")

local Workspace = {}

function Workspace:add_desktop(idx, name, nb_pages)
    self.desktops[idx] = desktop.new(idx, name, nb_pages, self.layouts[1])
    return idx
end

function Workspace:rename_desktop(idx, name)
    local desk = self.desktops[idx]
    desk.name = name
    desk:emit_signal("desktop:name", name)
end

function Workspace:_apply_state()
    local orig_focus = mouse.screen

    for s in screen do
        if self.screen_state[s] then
            awful.tag.viewnone(s)

            local desk = self.screen_state[s].desktop
            local page = self.desktops[desk].pages[self.screen_state[s].page]
            page.screen = s
        end
    end
    for s in screen do
        local state = self.screen_state[s]
        if state then
            local desk_idx = state.desktop
            local desk     = self.desktops[desk_idx]
            local page_idx = state.page
            local page     = desk.pages[page_idx]
            print("workspace displaying: " .. s.index .. " => " .. desk_idx .. "/" .. page_idx)

            page:view_only()

            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.index .. ": view " .. desktop .. "/" .. (page_idx or "nil"))
    -- the page currently displayed on the target screen
    local 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.index .. " 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
        local page_new = self.desktops[desktop].pages[page_idx]
    end

    -- the screen on which the new page is currently displayed (if any)
    local screen_cur = nil
    if page_new and page_new.selected then
        screen_cur = page_new.screen
        print("page " .. page_idx .. " now displayed on " .. screen_cur.index)
    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
            local 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.index)

    local state = self.screen_state[screen]
    if state then
        local desk = state.desktop
        print("state " .. state.page .. " res " .. (state.page + offset) % 10)
        local 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)
    local dst_page = self.desktops[desk].pages[page]
    local dst_screen = awful.tag.getscreen(dst_page)
    awful.client.movetoscreen(client, dst_screen)
    awful.client.movetotag(dst_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