Skip to content

Instantly share code, notes, and snippets.

@psychon
Created October 7, 2016 08:53
Show Gist options
  • Save psychon/903f276deb89feeec11f7a9b01f0678b to your computer and use it in GitHub Desktop.
Save psychon/903f276deb89feeec11f7a9b01f0678b to your computer and use it in GitHub Desktop.
diff --git a/awesomerc.lua b/awesomerc.lua
index 87d9da7..b578996 100755
--- a/awesomerc.lua
+++ b/awesomerc.lua
@@ -231,6 +231,105 @@ awful.screen.connect_for_each_screen(function(s)
s.mylayoutbox,
},
}
+
+local function powerline_fit(self, context, width, height)
+ local old_spacing = self._private.spacing
+ local spacing = self._private.dir == "x" and height/2 or width/2
+ self._private.spacing = self._private.dir == "x" and height/2 or width/2
+ local w, h = self:original_fit(context, width, height)
+ self._private.spacing = old_spacing
+ if self._private.dir == "x" then
+ return w + spacing, h
+ else
+ return w, h + spacing
+ end
+end
+
+local function powerline_layout(self, context, width, height)
+ local old_spacing = self._private.spacing
+ local spacing = self._private.dir == "x" and height/2 or width/2
+ self._private.spacing = self._private.dir == "x" and height/2 or width/2
+ local result = self:original_layout(context, width, height)
+ self._private.spacing = old_spacing
+ return result
+end
+
+local function powerline_before_draw_children(self, context, cr, width, height)
+ -- Normally it is a baaad idea to call a :layout() function directly.
+ -- However, since I'm calling "my own" :layout(), it's ok.
+ local layout = self:layout(context, width, height) or {}
+ local colors = self.colors or {
+ "#0000ff80",
+ "#ff0000e0",
+ "#00ff0060"
+ }
+ local cairo = require("lgi").cairo
+ local spacing = self._private.dir == "x" and height/2 or width/2
+
+ -- TODO: Support all directions
+ assert(self.direction == "right", "A psychon-is-lazy-assert failed")
+ cr:save()
+ cr:push_group_with_content(cairo.Content.COLOR_ALPHA)
+ cr.operator = cairo.Operator.SOURCE
+ -- Go through all widgets (ignoring the spacers added in powerline_add())
+ for i = #layout, 1, -1 do
+ -- This accesses quite some implementation details for which we have no
+ -- proper API. Baaaaaaad.
+ -- Get the positions of the two spacers. However, there is no spacer
+ -- before the first widget!
+ local begin_x = layout[i]._matrix.x0 - spacing
+ local end_x = layout[i]._matrix.x0 + layout[i]._width + spacing
+ local color = gears.color(colors[i%#colors+1])
+ assert(color)
+
+ cr:move_to(begin_x, height)
+ cr:line_to(begin_x, 0)
+
+ cr:line_to(end_x-spacing, 0)
+ cr:rel_line_to(spacing, height/2)
+ cr:rel_line_to(-spacing, height/2)
+ cr:close_path()
+ cr:set_source(color)
+ cr:fill()
+ end
+ cr:pop_group_to_source()
+ cr.operator = cairo.Operator.OVER
+ cr:paint()
+ cr:restore()
+end
+
+local function powerline()
+ local l = wibox.layout.fixed.horizontal()
+ rawset(l, "original_fit", l.fit)
+ rawset(l, "original_layout", l.layout)
+ rawset(l, "fit", powerline_fit)
+ rawset(l, "layout", powerline_layout)
+ rawset(l, "before_draw_children", powerline_before_draw_children)
+ l:connect_signal("widget::layout_changed", function() l:emit_signal("widget::redraw_needed") end)
+ return l
+end
+
+s.mywibox:setup{
+ {
+ {
+ widget = wibox.widget.base.make_widget(),
+ forced_width= 0.5
+ },
+ wibox.widget.textbox "one",
+ wibox.widget.textbox "two",
+ wibox.widget.textbox "three",
+ wibox.widget.textbox "four",
+ wibox.widget.textbox "five",
+ direction = "right",
+ widget = powerline
+ },
+ widget = wibox.container.background,
+ bg = gears.color.create_linear_pattern{
+ from = { 0, 0 },
+ to = { s.mywibox:geometry().width, 0 },
+ stops = { { 0, "#ffff00" }, { 0.2, "#00ff00" }, { 0.4, "#00ffff" } }
+ }
+}
end)
-- }}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment