diff --git a/cfg.fnl b/cfg.fnl
index 8e92d3d..d595347 100644
--- a/cfg.fnl
+++ b/cfg.fnl
@@ -5,7 +5,7 @@
(local naughty (require :naughty))
(local beautiful (require :beautiful))
-(beautiful.init (require :conf.theme))
+(beautiful.init (require :theme))
(require :module.decorate)
(require :module.sidebar)
@@ -36,7 +36,7 @@
:unfocus (lambda [c] (set c.border_color beautiful.border_normal))}
(fun.each (fn [event callback] (client.connect_signal event callback))))
-(awful.spawn.with_shell "~/.config/awesome/autostart")
+;; (awful.spawn.with_shell "~/.config/awesome/autostart")
;; Empty return
{}
diff --git a/conf/tags.fnl b/conf/tags.fnl
index 80513af..6686315 100644
--- a/conf/tags.fnl
+++ b/conf/tags.fnl
@@ -3,6 +3,7 @@
;;; Code:
(local awful (require :awful))
+(local beautiful (require :beautiful))
;;;
;; Configuration
@@ -12,10 +13,21 @@
(set awful.layout.layouts layouts)
-(awful.screen.connect_for_each_screen
- (lambda [s]
- (awful.tag ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
- s (. layouts 1))))
+;; TODO Rasterize?
+(local tags [:firefox.png :code.png :code.svg])
+
+(let [icon-path (.. (os.getenv "HOME") "/.config/awesome/theme/icons/tag/")]
+ (awful.screen.connect_for_each_screen
+ (lambda [s]
+ (each [n tag (ipairs tags)]
+ (awful.tag.add
+ n {:icon (.. icon-path tag)
+ :icon_only true
+ :layout (. layouts 1)
+ :gap_single_client false
+ :gap beautiful.useless_gap
+ :screen s
+ :selected (= n 1)})))))
{}
;;; conf/tags.fnl ends here
diff --git a/lib/std.fnl b/lib/std.fnl
index 97bf29c..18650aa 100644
--- a/lib/std.fnl
+++ b/lib/std.fnl
@@ -13,5 +13,12 @@
(fn std.zero? [n]
(= 0 n))
+(fn std.fn? [f]
+ (= (type f) :function))
+
+(fn std.s-empty? [s]
+ (or (= nil s)
+ (= "" s)))
+
std
;;; std.fnl ends here
diff --git a/module/sidebar.fnl b/module/sidebar.fnl
index 896e6ba..4c1ad66 100644
--- a/module/sidebar.fnl
+++ b/module/sidebar.fnl
@@ -8,46 +8,49 @@
(local tag-list (require :widget.tag-list))
(local task-list (require :widget.task-list))
-
-(local sb-clock (wibox.widget.textclock "%H\n%M"))
-(local sb-systray (doto (wibox.widget.systray)
- (: :set_base_size 24)))
-(local fill-width (doto (wibox.layout.fixed.horizontal)
- (: :fill_space true)
- (: :set_spacing 10)))
-
-(local bounding (wibox.container.margin
- (wibox.container.place
- (wibox.container.margin
- nil
- 10 10 10 10 beautiful.sidebar_subbox))
- 1 1 1 1 beautiful.sidebar_bg))
+(local textclock (require :widget.textclock))
;;;
;; Functions
-(fn draw-sidebar [s]
- (set s.sb-tag (tag-list s))
- (set s.sb-tasks (task-list s))
+(fn border [t margin]
+ (let [side (or margin 2)
+ end (+ side 1)]
+ {1 t
+ :bottom end
+ :left side
+ :right side
+ :top end
+ :widget wibox.container.margin} ))
+(local sb-clock (textclock "%H\n%M"))
+(local sb-systray (doto (wibox.widget.systray)
+ (: :set_base_size 24)))
+
+(fn draw-sidebar [s]
(set s.sb (awful.wibar {:position beautiful.sidebar_position
:width beautiful.sidebar_width
:screen s}))
(: s.sb :setup
{:layout wibox.layout.align.vertical
- 1 {:layout wibox.layout.fixed.vertical
- 1 {1 s.sb-tag
- :halign "center"
- :layout (wibox.container.margin nil 10 10 10 10)}
- 2 s.sb-tasks}
+ 1 {1 (border (tag-list s))
+ ;; 2 (task-list s)
+ :layout wibox.layout.fixed.vertical}
2 {:layout wibox.layout.fixed.vertical}
- 3 {:layout wibox.layout.fixed.vertical
- 1 sb-systray
- 2 {1 sb-clock
- :valign "center"
- :halign "center"
- :layout bounding}}}))
+ 3 {1 sb-systray
+ 2 {1 (border
+ {1 {1 {1 sb-clock
+ :valign "center"
+ :halign "center"
+ :widget wibox.container.place}
+ :top 2
+ :bottom 2
+ :widget wibox.container.margin}
+ :widget wibox.container.background
+ :bg beautiful.sidebar_bg_info})
+ :layout wibox.layout.fixed.vertical}
+ :layout wibox.layout.fixed.vertical}}))
;;;
;; Configuration
diff --git a/theme/icons/tag-list/occupied-border.png b/theme/icons/tag-list/occupied-border.png
new file mode 100644
index 0000000..8960968
Binary files /dev/null and b/theme/icons/tag-list/occupied-border.png differ
diff --git a/theme/icons/tag-list/occupied.png b/theme/icons/tag-list/occupied.png
new file mode 100644
index 0000000..7ed9710
Binary files /dev/null and b/theme/icons/tag-list/occupied.png differ
diff --git a/theme/icons/tag-list/panel.png b/theme/icons/tag-list/panel.png
new file mode 100644
index 0000000..40d09df
Binary files /dev/null and b/theme/icons/tag-list/panel.png differ
diff --git a/theme/icons/tag-list/selected.png b/theme/icons/tag-list/selected.png
new file mode 100644
index 0000000..3204030
Binary files /dev/null and b/theme/icons/tag-list/selected.png differ
diff --git a/theme/icons/tag-list/unselected.png b/theme/icons/tag-list/unselected.png
new file mode 100644
index 0000000..9959194
Binary files /dev/null and b/theme/icons/tag-list/unselected.png differ
diff --git a/theme/icons/tag-list/urgent.png b/theme/icons/tag-list/urgent.png
new file mode 100644
index 0000000..2c2b87e
Binary files /dev/null and b/theme/icons/tag-list/urgent.png differ
diff --git a/theme/icons/tag/code.png b/theme/icons/tag/code.png
new file mode 100644
index 0000000..9d7728c
Binary files /dev/null and b/theme/icons/tag/code.png differ
diff --git a/theme/icons/tag/code.svg b/theme/icons/tag/code.svg
new file mode 100644
index 0000000..bf03e30
--- /dev/null
+++ b/theme/icons/tag/code.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/theme/icons/tag/firefox.png b/theme/icons/tag/firefox.png
new file mode 100644
index 0000000..0d191a8
Binary files /dev/null and b/theme/icons/tag/firefox.png differ
diff --git a/theme/icons/tag/firefox.svg b/theme/icons/tag/firefox.svg
new file mode 100644
index 0000000..3bc709a
--- /dev/null
+++ b/theme/icons/tag/firefox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/theme/init.fnl b/theme/init.fnl
index 75f73b4..b6e6616 100644
--- a/theme/init.fnl
+++ b/theme/init.fnl
@@ -1,35 +1,42 @@
;; Have to use underscores for `beautiful' compat.
;; Non-beautiful variables are commented with an asterisk.
-{
- :font "Sarasa Mono J"
- :variable_font "Sarasa UI J"
+(let [theme-dir (.. (os.getenv "HOME") "/.config/awesome/theme")
+ icon-dir (.. theme-dir "/icons/")]
+ {
+ :font "Sarasa Mono J"
+ :variable_font "Sarasa UI J"
+ :textclock_font "Sarasa UI J"
- :sidebar_position :left ;; *
- :sidebar_width 36 ;; *
- :sidebar_bg "#1a1e24" ;; *
- :sidebar_subbox "#252b33" ;; *
+ :sidebar_position :left ;; *
+ :sidebar_width 36 ;; *
+ :sidebar_bg_info "#252b33" ;; *
- :bg_focus "#252b33"
- :bg_normal "#1a1e24"
- :fg_focus "#cfcfcf"
- :fg_normal "#cfcfcf"
+ :bg_focus "#252b33"
+ :bg_normal "#1a1e24"
+ :fg_focus "#cfcfcf"
+ :fg_normal "#cfcfcf"
- :useless_gap 0
- :border_width 0
- :border_focus "#5bb3b4"
- :border_normal "#1a1e24"
- :use_titlebars_for_borders nil ;; *
- :titlebar_border_width 1 ;; *
+ :useless_gap 0
+ :border_width 0
+ :border_focus "#5bb3b4"
+ :border_normal "#1a1e24"
+ :use_titlebars_for_borders nil ;; *
+ :titlebar_border_width 1 ;; *
- :titlebar_position :left ;; *
- :titlebar_size 15 ;; *
- :titlebar_bg_focus "#926b3e"
- :titlebar_bg_normal "#252b33"
- :titlebar_fg_focus "#1a1e24"
- :titlebar_fg_normal "#cfcfcf"
+ :titlebar_position :left ;; *
+ :titlebar_size 15 ;; *
+ :titlebar_bg_focus "#926b3e"
+ :titlebar_bg_normal "#252b33"
+ :titlebar_fg_focus "#1a1e24"
+ :titlebar_fg_normal "#cfcfcf"
- :icon_theme "Vertex Maia"
- :notification_icon_size 48
- :notification_border_width 0
- :notification_bg "#252b33"
- }
+ :icon_theme "Vertex Maia"
+ :notification_icon_size 48
+ :notification_border_width 0
+ :notification_bg "#252b33"
+
+ :taglist_bg_empty (.. "png:" icon-dir "tag-list/unselected.png")
+ :taglist_bg_focus (.. "png:" icon-dir "tag-list/selected.png")
+ :taglist_bg_occupied (.. "png:" icon-dir "tag-list/occupied.png")
+ :taglist_bg_urgent (.. "png:" icon-dir "tag-list/urgent.png")
+ })
diff --git a/widget/clickable-container.fnl b/widget/clickable-container.fnl
new file mode 100644
index 0000000..b3c85d2
--- /dev/null
+++ b/widget/clickable-container.fnl
@@ -0,0 +1,52 @@
+;;; widget/clickable-container.fnl --- Clickable container
+
+;;; Commentary:
+;; From https://github.com/PapyElGringo/material-awesome/blob/57116136a904560e8626b673370d2130b40dc62a/widgets/clickable-container.lua
+
+;;; Code:
+
+(local wibox (require :wibox))
+(local naughty (require :naughty))
+(local awful (require :awful))
+
+;;;
+;; Functions
+
+(fn build [widget]
+ (let [container (wibox.container.background widget)]
+ (var old-cursor {})
+ (var old-wibox {})
+
+ (: container :connect_signal
+ :mouse::enter
+ (lambda []
+ (let [cw _G.mouse.current_wibox]
+ (tset container :bg "#ffffff11")
+ ;; Hm, no idea how to get the wibox from this signal's arguments...
+ (when cw
+ (set old-cursor cw.cursor)
+ (set old-wibox cw)
+ (tset cw :cursor :hand1)))))
+
+ (: container :connect_signal
+ :mouse::leave
+ (lambda []
+ (tset container :bg "#ffffff00")
+ (when old-wibox
+ (tset old-wibox :cursor old-cursor)
+ (set old-wibox nil))))
+
+ (: container :connect_signal
+ :button::press
+ (lambda []
+ (tset container :bg "#ffffff22")))
+
+ (: container :connect_signal
+ :button::release
+ (lambda []
+ (tset container :bg "#ffffff11")))
+
+ container))
+
+build
+;;; widget/clickable-container.fnl ends here
diff --git a/widget/list_update.lua b/widget/list_update.lua
new file mode 100644
index 0000000..03f1c3d
--- /dev/null
+++ b/widget/list_update.lua
@@ -0,0 +1,80 @@
+local common = require("awful.widget.common")
+local dpi = require("beautiful").xresources.apply_dpi
+local wibox = require("wibox")
+local clickable_container = require("widget.clickable-container")
+
+function list_update(w, buttons, label, data, objects)
+ -- update the widgets, creating them if needed
+ w:reset()
+ for i, o in ipairs(objects) do
+ local cache = data[o]
+ local ib, tb, bgb, tbm, ibm, l
+ if cache then
+ ib = cache.ib
+ tb = cache.tb
+ bgb = cache.bgb
+ tbm = cache.tbm
+ ibm = cache.ibm
+ else
+ ib = wibox.widget.imagebox()
+ tb = wibox.widget.textbox()
+ bgb = wibox.container.background()
+ tbm = wibox.container.margin(tb, dpi(4), dpi(4))
+ ibm = wibox.container.margin(ib, dpi(10), dpi(8), dpi(8), dpi(8))
+ -- ibm = wibox.container.margin(ib, dpi(4))
+ l = wibox.layout.fixed.horizontal()
+ bg_clickable = clickable_container()
+
+ -- All of this is added in a fixed widget
+ l:fill_space(true)
+ l:add(ibm)
+ -- l:add(tbm)
+ bg_clickable:set_widget(l)
+
+ -- And all of this gets a background
+ -- bgb:set_widget(l)
+ bgb:set_widget(bg_clickable)
+
+ bgb:buttons(common.create_buttons(buttons, o))
+
+ data[o] = {
+ ib = ib,
+ tb = tb,
+ bgb = bgb,
+ tbm = tbm,
+ ibm = ibm,
+ }
+ end
+
+ local text, bg, bg_image, icon, args = label(o, tb)
+ args = args or {}
+
+ -- The text might be invalid, so use pcall.
+ if text == nil or text == "" then
+ tbm:set_margins(0)
+ else
+ if not tb:set_markup_silently(text) then
+ tb:set_markup("<Invalid text>")
+ end
+ end
+ bgb:set_bg(bg)
+ if type(bg_image) == "function" then
+ -- TODO: Why does this pass nil as an argument?
+ bg_image = bg_image(tb,o,nil,objects,i)
+ end
+ bgb:set_bgimage(bg_image)
+ if icon then
+ ib:set_image(icon)
+ else
+ ibm:set_margins(0)
+ end
+
+ bgb.shape = args.shape
+ bgb.shape_border_width = args.shape_border_width
+ bgb.shape_border_color = args.shape_border_color
+
+ w:add(bgb)
+ end
+end
+
+return list_update
diff --git a/widget/tag-list.fnl b/widget/tag-list.fnl
index 29f1f4a..c0b73e5 100644
--- a/widget/tag-list.fnl
+++ b/widget/tag-list.fnl
@@ -5,17 +5,101 @@
(local awful (require :awful))
(local beautiful (require :beautiful))
(local wibox (require :wibox))
+(local common (require :awful.widget.common))
+(local dpi (. (require :beautiful) :xresources :apply_dpi))
+
+(local std (require :lib.std))
;;;
;; Functions
+(fn update-tag-list [w buttons label data objects]
+ (: w :reset)
+ (each [i o (ipairs objects)]
+ (let [cache (. data o)]
+ (var ib nil)
+ (var tb nil)
+ (var bgb nil)
+ (var tbm nil)
+ (var ibm nil)
+ (var l nil)
+ (if cache
+ (do
+ (set ib cache.ib)
+ (set tb cache.tb)
+ (set bgb cache.bgb)
+ (set tbm cache.tbm)
+ (set ibm cache.ibm))
+ (do
+ (set ib (wibox.widget.imagebox))
+ (set tb (wibox.widget.textbox))
+ (set bgb (wibox.container.background))
+ (set tbm (wibox.container.margin tb (dpi 4) (dpi 4)))
+ ;; (set ibm (wibox.container.margin ib (dpi 12) (dpi 12) (dpi 12) (dpi 12)))
+ (set ibm (wibox.container.margin ib (dpi 4)))
+ (set l (wibox.layout.fixed.horizontal))
+
+ ;; All of this is added in a fixed widget
+ (doto l
+ (: :fill_space true)
+ (: :add ibm)
+ (: :add tbm))
+
+ ;; And all of this gets a background
+ (: bgb :set_widget l)
+
+ (: bgb :buttons (common.create_buttons buttons o))
+
+ (tset data o {:ib ib :tb tb :bgb bgb :tbm tbm :ibm ibm})))
+
+ (let [[text bg bg-image icon args] (label o tb)]
+ ;; The text might be invalid, so use pcall.
+ (if (std.s-empty? text)
+ (: tbm :set_margins 0)
+ (when (not (: tb :set_markup_silently text))
+ (: tb :set_markup "<Invalid text>")))
+ (: bgb :set_bg bg)
+
+ (: bgb :set_bgimage (if (std.fn? bg-image)
+ ;; TODO: Why does this pass nil as an argument?
+ (bg-image tb o nil objects i)
+ bg-image))
+
+ (if icon
+ (: ib :set_image icon)
+ (: ibm :set_margins 0))
+
+ (let [args (or args {})]
+ (doto bgb
+ (tset :shape args.shape)
+ (tset :shape_border_width args.shape_border_width)
+ (tset :shape_border_color args.shape_border_color)))
+
+ (: w :add bgb)))))
+
+(fn container []
+ (let [l (wibox.layout.fixed.vertical)]
+ ;; Wishlist: let*
+ (local innerm (wibox.container.margin nil 10 10))
+ (local bg (wibox.container.background innerm "#faa"))
+ (local outerm (wibox.container.margin bg 4 4))
+
+ (: l :fill_space true)
+ (: l :add outerm)
+
+ l))
+
(fn tag-list [s]
(awful.widget.taglist
s
- awful.widget.taglist.filter.selected
+ awful.widget.taglist.filter.all
{}
- {:font (.. beautiful.font " Bold 10")}
- nil
+ {:font (.. beautiful.font " Bold 10")
+ :spacing 2}
+ ;; update-tag-list
+ (require :widget.list_update)
+ ;; awful.widget.common.list_update
+ ;; (container)
(wibox.layout.fixed.vertical)
))
diff --git a/widget/textclock.fnl b/widget/textclock.fnl
new file mode 100644
index 0000000..95f57ee
--- /dev/null
+++ b/widget/textclock.fnl
@@ -0,0 +1,43 @@
+;;; widget/textclock.fnl --- Configurable text clock widget
+
+;;; Commentary:
+;; More modular than the standard library
+
+;;; Code:
+
+(local beautiful (require :beautiful))
+(local gears (require :gears))
+(local glib (. (require :lgi) :GLib))
+(local wibox (require :wibox))
+(local DateTime glib.DateTime)
+(local TimeZone glib.TimeZone)
+
+;;;
+;; Functions
+
+(fn calc-timeout [real-timeout]
+ (% (- real-timeout (os.time)) real-timeout))
+
+(fn textclock [format timeout timezone font]
+ (let [format (or format " %a %b %d, %H:%M ")
+ timeout (or timeout 60)
+ timezone (or (and timezone (TimeZone.new timezone))
+ (TimeZone.new_local))
+ font (or font beautiful.textclock_font)
+ w (wibox.widget.textbox)]
+ (var t nil)
+
+ (tset w :font font)
+
+ (fn w._private.textclock_update_cb []
+ (: w :set_markup (: (DateTime.new_now timezone) :format format))
+ (tset t :timeout (calc-timeout timeout))
+ (: t :again)
+ true)
+
+ (set t (gears.timer.weak_start_new timeout w._private.textclock_update_cb))
+ (: t :emit_signal :timeout)
+ w))
+
+textclock
+;;; widget/textclock.fnl ends here