summaryrefslogtreecommitdiff
path: root/lib/beautiful/init.lua
blob: 0e72cbcec02d95515d521345e30a23c2cfacb701 (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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
----------------------------------------------------------------------------
--- Theme library.
--
-- @author Damien Leone <damien.leone@gmail.com>
-- @author Julien Danjou <julien@danjou.info>
-- @copyright 2008-2009 Damien Leone, Julien Danjou
-- @module beautiful
----------------------------------------------------------------------------

-- Grab environment
local os = os
local pairs = pairs
local type = type
local dofile = dofile
local setmetatable = setmetatable
local lgi = require("lgi")
local Pango = lgi.Pango
local PangoCairo = lgi.PangoCairo
local gears_debug = require("gears.debug")
local protected_call = require("gears.protected_call")

local xresources = require("beautiful.xresources")

local beautiful = { xresources = xresources, mt = {} }

-- Local data
local theme = {}
local descs = setmetatable({}, { __mode = 'k' })
local fonts = setmetatable({}, { __mode = 'v' })
local active_font

--- The default font.
-- @beautiful beautiful.font

-- The default background color.
-- @beautiful beautiful.bg_normal

-- The default focused element background color.
-- @beautiful beautiful.bg_focus

-- The default urgent element background color.
-- @beautiful beautiful.bg_urgent

-- The default minimized element background color.
-- @beautiful beautiful.bg_minimize

-- The system tray background color.
-- Please note that only solid colors are currently supported.
-- @beautiful beautiful.bg_systray

-- The default focused element foreground (text) color.
-- @beautiful beautiful.fg_normal

-- The default focused element foreground (text) color.
-- @beautiful beautiful.fg_focus

-- The default urgent element foreground (text) color.
-- @beautiful beautiful.fg_urgent

-- The default minimized element foreground (text) color.
-- @beautiful beautiful.fg_minimize

--- The gap between clients.
-- @beautiful beautiful.useless_gap
-- @param[opt=0] number

--- The client border width.
-- @beautiful beautiful.border_width

--- The default clients border width.
-- Note that only solid colors are supported.
-- @beautiful beautiful.border_normal

--- The focused client border width.
-- Note that only solid colors are supported.
-- @beautiful beautiful.border_focus

--- The marked clients border width.
-- Note that only solid colors are supported.
-- @beautiful beautiful.border_marked

--- The wallpaper path.
-- @beautiful beautiful.wallpaper

-- The icon theme name.
-- It has to be a directory in `/usr/share/icons` or an XDG icon folder.
-- @beautiful beautiful.icon_theme

--- The Awesome icon path.
-- @beautiful beautiful.awesome_icon

--- Load a font from a string or a font description.
--
-- @see https://developer.gnome.org/pango/stable/pango-Fonts.html#pango-font-description-from-string
-- @tparam string|lgi.Pango.FontDescription name Font, which can be a
--   string or a lgi.Pango.FontDescription.
-- @treturn table A table with `name`, `description` and `height`.
local function load_font(name)
    name = name or active_font
    if name and type(name) ~= "string" then
        if descs[name] then
            name = descs[name]
        else
            name = name:to_string()
        end
    end
    if fonts[name] then
        return fonts[name]
    end

    -- Load new font
    local desc = Pango.FontDescription.from_string(name)
    local ctx = PangoCairo.font_map_get_default():create_context()
    ctx:set_resolution(beautiful.xresources.get_dpi())

    -- Apply default values from the context (e.g. a default font size)
    desc:merge(ctx:get_font_description(), false)

    -- Calculate font height.
    local metrics = ctx:get_metrics(desc, nil)
    local height = math.ceil((metrics:get_ascent() + metrics:get_descent()) / Pango.SCALE)

    local font = { name = name, description = desc, height = height }
    fonts[name] = font
    descs[desc] = name
    return font
end

--- Set an active font
--
-- @param name The font
local function set_font(name)
    active_font = load_font(name).name
end

--- Get a font description.
--
-- See https://developer.gnome.org/pango/stable/pango-Fonts.html#PangoFontDescription.
-- @tparam string|lgi.Pango.FontDescription name The name of the font.
-- @treturn lgi.Pango.FontDescription
function beautiful.get_font(name)
    return load_font(name).description
end

--- Get a new font with merged attributes, based on another one.
--
-- See https://developer.gnome.org/pango/stable/pango-Fonts.html#pango-font-description-from-string.
-- @tparam string|Pango.FontDescription name The base font.
-- @tparam string merge Attributes that should be merged, e.g. "bold".
-- @treturn lgi.Pango.FontDescription
function beautiful.get_merged_font(name, merge)
    local font = beautiful.get_font(name)
    merge = Pango.FontDescription.from_string(merge)
    local merged = font:copy_static()
    merged:merge(merge, true)
    return beautiful.get_font(merged:to_string())
end

--- Get the height of a font.
--
-- @param name Name of the font
function beautiful.get_font_height(name)
    return load_font(name).height
end

--- Init function, should be runned at the beginning of configuration file.
-- @tparam string|table config The theme to load. It can be either the path to
--   the theme file (returning a table) or directly the table
--   containing all the theme values.
function beautiful.init(config)
    if config then
        local homedir = os.getenv("HOME")

        -- If `config` is the path to a theme file, run this file,
        -- otherwise if it is a theme table, save it.
        if type(config) == 'string' then
            -- Expand the '~' $HOME shortcut
            config = config:gsub("^~/", homedir .. "/")
            theme = protected_call(dofile, config)
        elseif type(config) == 'table' then
            theme = config
        end

        if theme then
            -- expand '~'
            if homedir then
                for k, v in pairs(theme) do
                    if type(v) == "string" then theme[k] = v:gsub("^~/", homedir .. "/") end
                end
            end

            if theme.font then set_font(theme.font) end
        else
            return gears_debug.print_error("beautiful: error loading theme file " .. config)
        end
    else
        return gears_debug.print_error("beautiful: error loading theme: no theme specified")
    end
end

--- Get the current theme.
--
-- @treturn table The current theme table.
function beautiful.get()
    return theme
end

function beautiful.mt:__index(k)
    return theme[k]
end

-- Set the default font
set_font("sans 8")

return setmetatable(beautiful, beautiful.mt)

-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80