Created
July 2, 2017 16:34
-
-
Save psychon/ed4436cd5ad36da57c6dd81c69ac8e1c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/awesomerc.lua b/awesomerc.lua | |
| index 00d1b6031..c9d592662 100644 | |
| --- a/awesomerc.lua | |
| +++ b/awesomerc.lua | |
| @@ -41,6 +41,214 @@ do | |
| end | |
| -- }}} | |
| +do | |
| + -- Big copy&paste (and some rewrite) of wibox.drawable | |
| + | |
| + local cairo = require("lgi").cairo | |
| + | |
| + local client_hierarchy_class = {} | |
| + | |
| + function client_hierarchy_class:_do_redraw() | |
| + self._private.redraw_pending = false | |
| + | |
| + local c = self._private.client | |
| + local geo = c:geometry() | |
| + local width = geo.width | |
| + local height = geo.height | |
| + local context = self._private.context | |
| + local top_d, top_size = c:titlebar_top() | |
| + local right_d, right_size = c:titlebar_right() | |
| + local bottom_d, bottom_size = c:titlebar_bottom() | |
| + local left_d, left_size = c:titlebar_left() | |
| + | |
| + -- Relayout | |
| + if self._private.need_relayout or self._private.need_complete_repaint then | |
| + self._private.need_relayout = false | |
| + if self._private.widget_hierarchy and self._private.widget then | |
| + self._private.widget_hierarchy:update(context, self._private.widget, width, height, self._private.dirty_area) | |
| + else | |
| + self._private.need_complete_repaint = true | |
| + if self._private.widget then | |
| + self._private.hierarchy_callback_arg = {} | |
| + self._private.widget_hierarchy = wibox.hierarchy.new(context, self._private.widget, width, height, | |
| + self._private.redraw_callback, self._private.layout_callback, self._private.hierarchy_callback_arg) | |
| + else | |
| + self._private.widget_hierarchy = nil | |
| + end | |
| + end | |
| + | |
| + if self._private.need_complete_repaint then | |
| + self._private.need_complete_repaint = false | |
| + self._private.dirty_area:union_rectangle(cairo.RectangleInt{ | |
| + x = 0, y = 0, width = width, height = height | |
| + }) | |
| + end | |
| + end | |
| + | |
| + local function do_it(d, x, y, width, height) | |
| + local surf = gears.surface.load_silently(d.surface, false) | |
| + if not surf then return end | |
| + local cr = cairo.Context(surf) | |
| + | |
| + cr:translate(-x, -y) | |
| + | |
| + for i = 0, self._private.dirty_area:num_rectangles() - 1 do | |
| + local rect = self._private.dirty_area:get_rectangle(i) | |
| + cr:rectangle(rect.x, rect.y, rect.width, rect.height) | |
| + end | |
| + cr:clip() | |
| + | |
| + -- Draw the (hardcoded) background | |
| + cr:save() | |
| + cr:set_source(gears.color("#ffffff")) | |
| + cr:paint() | |
| + cr:restore() | |
| + | |
| + -- Draw the widget | |
| + self._private.widget_hierarchy:draw(context, cr) | |
| + d:refresh() | |
| + end | |
| + do_it(top_d, 0, 0, width, top_size) | |
| + do_it(left_d, 0, top_size, left_size, height - top_size - bottom_size) | |
| + do_it(right_d, width - right_size, top_size, right_size, height - top_size - bottom_size) | |
| + do_it(bottom_d, 0, height - bottom_size, width, bottom_size) | |
| + | |
| + self._private.dirty_area = cairo.Region.create() | |
| + end | |
| + | |
| + function client_hierarchy_class:set_widget(w) | |
| + self._private.widget = w | |
| + self._private.need_relayout = true | |
| + self:draw() | |
| + end | |
| + | |
| + function client_hierarchy_class:get_widget() | |
| + return self._private.widget | |
| + end | |
| + | |
| + function client_hierarchy_class:draw() | |
| + if not self._private.redraw_pending then | |
| + self._private.redraw_pending = true | |
| + gears.timer.delayed_call(self._do_redraw, self) | |
| + end | |
| + end | |
| + | |
| + function client_hierarchy_class:_do_complete_repaint() | |
| + self._private.need_complete_repaint = true | |
| + self:draw() | |
| + end | |
| + | |
| + function create_client_hierarchy(c) | |
| + local obj = gears.object{ enable_properties = true, enable_auto_signals = true, class = client_hierarchy_class } | |
| + obj._private = { | |
| + client = c, | |
| + need_complete_repaint = true, | |
| + need_relayout = true, | |
| + dirty_area = cairo.Region.create(), | |
| + redraw_pending = false, | |
| + context = { dpi = 72, client = c }, | |
| + } | |
| + | |
| + local function cb() | |
| + obj:_do_complete_repaint() | |
| + end | |
| + | |
| + c:connect_signal("property::width", cb) | |
| + c:connect_signal("property::height", cb) | |
| + | |
| + function obj._private.redraw_callback(hierar, arg) | |
| + if not c.valid then | |
| + return | |
| + end | |
| + if obj._private.hierarchy_callback_arg ~= arg then | |
| + return | |
| + end | |
| + local m = hierar:get_matrix_to_device() | |
| + local x, y, width, height = m:transform_rectangle(hierar:get_draw_extents()) | |
| + local x1, y1 = math.floor(x), math.floor(y) | |
| + local x2, y2 = math.ceil(x + width), math.ceil(y + height) | |
| + obj._private.dirty_area:union_rectangle(cairo.RectangleInt{ | |
| + x = x1, y = y1, width = x2 - x1, height = y2 - y1 | |
| + }) | |
| + obj:draw() | |
| + end | |
| + | |
| + function obj._private.layout_callback(_, arg) | |
| + if obj._private.hierarchy_callback_arg ~= arg then | |
| + return | |
| + end | |
| + obj._private.need_relayout = true | |
| + obj:draw() | |
| + end | |
| + | |
| + obj:_do_complete_repaint() | |
| + | |
| + return obj | |
| + end | |
| + | |
| + -- No idea if this actually works, but the idea is that this is a widget | |
| + -- that you can use to embed the client as wanted | |
| + function client_widget() | |
| + local w = wibox.widget.base.make_widget() | |
| + function w:fit(_, w, h) | |
| + return w, h | |
| + end | |
| + function w:draw(context, cr, width, height) | |
| + local c = context.client | |
| + local geo = c:geometry() | |
| + local mat = gears.matrix.from_cairo_matrix(cr:get_matrix()) | |
| + local top, left = mat:transform_point(0, 0) | |
| + local bottom, right = mat:transform_point(width, height) | |
| + right = width - right | |
| + bottom = height - bottom | |
| + c:titlebar_top(top) | |
| + c:titlebar_right(right) | |
| + c:titlebar_left(left) | |
| + c:titlebar_bottom(bottom) | |
| + end | |
| + return w | |
| + end | |
| + | |
| + -- This would be code in the user config to setup things, more or less | |
| + function setup_client(c) | |
| + local obj = create_client_hierarchy(c) | |
| + local widget | |
| + | |
| + if true then | |
| + widget = wibox.widget.base.make_widget() | |
| + function widget:fit(_, w, h) | |
| + return w, h | |
| + end | |
| + function widget:draw(_, cr, width, height) | |
| + cr:set_source(gears.color{ | |
| + type = "linear", | |
| + from = { 0, 0 }, | |
| + to = { width, height }, | |
| + stops = { | |
| + { 0, "#ff0000" }, | |
| + { 0.5, "#00ff00" }, | |
| + { 1, "#0000ff" }, | |
| + }, | |
| + }) | |
| + cr:paint() | |
| + end | |
| + else | |
| + widget = wibox.widget.textbox("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz") | |
| + widget.valign = "top" | |
| + | |
| + widget = wibox.container.rotate(widget, "east") | |
| + end | |
| + | |
| + obj:set_widget(widget) | |
| + | |
| + -- Now add some titlebars | |
| + c:titlebar_top(42) | |
| + c:titlebar_bottom(42) | |
| + c:titlebar_left(42) | |
| + c:titlebar_right(42) | |
| + end | |
| +end | |
| + | |
| -- {{{ Variable definitions | |
| -- @DOC_LOAD_THEME@ | |
| -- Themes define colours, icons, font and wallpapers. | |
| @@ -502,7 +710,8 @@ awful.rules.rules = { | |
| -- @DOC_DIALOG_RULE@ | |
| -- Add titlebars to normal clients and dialogs | |
| { rule_any = {type = { "normal", "dialog" } | |
| - }, properties = { titlebars_enabled = true } | |
| + --}, properties = { titlebars_enabled = true } | |
| + }, callback = setup_client | |
| }, | |
| -- Set Firefox to always map on the tag named "2" on screen 1. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment