Merge pull request #3343 from Elv13/awful_wallpaper
Rewrite the wallpaper API
This commit is contained in:
commit
2bca64b89c
|
@ -77,7 +77,7 @@ mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
|
||||||
menubar.utils.terminal = terminal -- Set the terminal for applications that require it
|
menubar.utils.terminal = terminal -- Set the terminal for applications that require it
|
||||||
-- }}}
|
-- }}}
|
||||||
|
|
||||||
-- {{{ Tag
|
-- {{{ Tag layout
|
||||||
-- @DOC_LAYOUT@
|
-- @DOC_LAYOUT@
|
||||||
-- Table of layouts to cover with awful.layout.inc, order matters.
|
-- Table of layouts to cover with awful.layout.inc, order matters.
|
||||||
tag.connect_signal("request::default_layouts", function()
|
tag.connect_signal("request::default_layouts", function()
|
||||||
|
@ -99,6 +99,27 @@ tag.connect_signal("request::default_layouts", function()
|
||||||
end)
|
end)
|
||||||
-- }}}
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ Wallpaper
|
||||||
|
-- @DOC_WALLPAPER@
|
||||||
|
screen.connect_signal("request::wallpaper", function(s)
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
widget = {
|
||||||
|
{
|
||||||
|
image = beautiful.wallpaper,
|
||||||
|
upscale = true,
|
||||||
|
downscale = true,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
valign = "center",
|
||||||
|
halign = "center",
|
||||||
|
tiled = false,
|
||||||
|
widget = wibox.container.tile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
-- }}}
|
||||||
|
|
||||||
-- {{{ Wibar
|
-- {{{ Wibar
|
||||||
|
|
||||||
-- Keyboard map indicator and switcher
|
-- Keyboard map indicator and switcher
|
||||||
|
@ -107,19 +128,6 @@ mykeyboardlayout = awful.widget.keyboardlayout()
|
||||||
-- Create a textclock widget
|
-- Create a textclock widget
|
||||||
mytextclock = wibox.widget.textclock()
|
mytextclock = wibox.widget.textclock()
|
||||||
|
|
||||||
-- @DOC_WALLPAPER@
|
|
||||||
screen.connect_signal("request::wallpaper", function(s)
|
|
||||||
-- Wallpaper
|
|
||||||
if beautiful.wallpaper then
|
|
||||||
local wallpaper = beautiful.wallpaper
|
|
||||||
-- If wallpaper is a function, call it with the screen
|
|
||||||
if type(wallpaper) == "function" then
|
|
||||||
wallpaper = wallpaper(s)
|
|
||||||
end
|
|
||||||
gears.wallpaper.maximized(wallpaper, s, true)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- @DOC_FOR_EACH_SCREEN@
|
-- @DOC_FOR_EACH_SCREEN@
|
||||||
screen.connect_signal("request::desktop_decoration", function(s)
|
screen.connect_signal("request::desktop_decoration", function(s)
|
||||||
-- Each screen has its own tag table.
|
-- Each screen has its own tag table.
|
||||||
|
|
|
@ -124,6 +124,10 @@ to an object such as the mouse.
|
||||||
The `naughty.layout.box` allows to provide custom widgets to use within the
|
The `naughty.layout.box` allows to provide custom widgets to use within the
|
||||||
notifications.
|
notifications.
|
||||||
|
|
||||||
|
The `awful.wallpaper` provides a non-intereactive "backgroud" for one or more
|
||||||
|
`screen`. While it uses normal widget, it will not automatically be repainted
|
||||||
|
if they change. It will also not provide any mouse events.
|
||||||
|
|
||||||
Finally, the `awful.titlebar`, while not technically a real `wibox`, acts
|
Finally, the `awful.titlebar`, while not technically a real `wibox`, acts
|
||||||
exactly the same way and allows to attach widgets on each side of clients.
|
exactly the same way and allows to attach widgets on each side of clients.
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,17 @@ variables such as `bg_normal`. To get a list of all official variables, see
|
||||||
the [appearance guide](../documentation/06-appearance.md.html).
|
the [appearance guide](../documentation/06-appearance.md.html).
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
sections.DOC_WALLPAPER = [[
|
||||||
|
The AwesomeWM wallpaper module, `awful.wallpaper` support both per-screen wallpaper
|
||||||
|
and wallpaper across multiple screens. In the default configuration, the `"request::wallpaper"` signal
|
||||||
|
is emitted everytime a screen is added, moved, resized or when the bars
|
||||||
|
(`awful.wibar`) are moved.
|
||||||
|
|
||||||
|
This is will suited for single-screen wallpapers. If you wish to use multi-screen wallpaper,
|
||||||
|
it is better to create a global wallpaper object and edit it when the screen change. See
|
||||||
|
the `add_screen`/`remove_screens` methods and the `screens` property of `awful.wallpaper` for
|
||||||
|
examples.
|
||||||
|
]]
|
||||||
|
|
||||||
sections.DOC_DEFAULT_APPLICATIONS = [[
|
sections.DOC_DEFAULT_APPLICATIONS = [[
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,8 @@
|
||||||
# local use_li = ldoc.use_li
|
# local use_li = ldoc.use_li
|
||||||
# local display_name = ldoc.display_name
|
# local display_name = ldoc.display_name
|
||||||
# local iter = ldoc.modules.iter
|
# local iter = ldoc.modules.iter
|
||||||
# local function M(txt,item) return ldoc.markup(txt,item,ldoc.plain) end
|
# local function un_cmake(s) return s:gsub(";", ";"):gsub(""", '"') end
|
||||||
|
# local function M(txt,item) return ldoc.markup(txt and un_cmake(txt) or nil,item,ldoc.plain) end
|
||||||
# local nowrap = ldoc.wrap and '' or 'nowrap'
|
# local nowrap = ldoc.wrap and '' or 'nowrap'
|
||||||
# local html_space = function(s) return s:gsub(" ", "%%20") end
|
# local html_space = function(s) return s:gsub(" ", "%%20") end
|
||||||
# local no_underscores = function(s) return s:gsub("_", " ") end
|
# local no_underscores = function(s) return s:gsub("_", " ") end
|
||||||
|
@ -189,7 +190,7 @@
|
||||||
<h3>Usage:</h3>
|
<h3>Usage:</h3>
|
||||||
<ul>
|
<ul>
|
||||||
# for usage in iter(module.usage) do
|
# for usage in iter(module.usage) do
|
||||||
$(li)<pre class="example">$(ldoc.escape(usage))</pre>$(il)
|
$(li)<pre class="example">$(ldoc.escape(un_cmake(usage)))</pre>$(il)
|
||||||
# end -- for
|
# end -- for
|
||||||
</ul>
|
</ul>
|
||||||
# end -- if usage
|
# end -- if usage
|
||||||
|
@ -331,7 +332,7 @@
|
||||||
# end
|
# end
|
||||||
# if kitem.usage then
|
# if kitem.usage then
|
||||||
<h3>Usage:</h3>
|
<h3>Usage:</h3>
|
||||||
<pre class="example">$(ldoc.prettify(kitem.usage[1]))</pre>
|
<pre class="example">$(ldoc.prettify(un_cmake(kitem.usage[1])))</pre>
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
# if not kind:match("^ldoc_skip") then
|
# if not kind:match("^ldoc_skip") then
|
||||||
|
@ -450,7 +451,7 @@
|
||||||
<h3>Usage:</h3>
|
<h3>Usage:</h3>
|
||||||
<ul>
|
<ul>
|
||||||
# for usage in iter(item.usage) do
|
# for usage in iter(item.usage) do
|
||||||
$(li)<pre class="example">$(ldoc.prettify(usage))</pre>$(il)
|
$(li)<pre class="example">$(ldoc.prettify(un_cmake(usage)))</pre>$(il)
|
||||||
# end -- for
|
# end -- for
|
||||||
</ul>
|
</ul>
|
||||||
# end -- if usage
|
# end -- if usage
|
||||||
|
|
|
@ -58,6 +58,28 @@ do
|
||||||
assert(root.object == root_object)
|
assert(root.object == root_object)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- The old wallpaper only took native surfaces.
|
||||||
|
--
|
||||||
|
-- This was a problem for the test backend. The new function takes both
|
||||||
|
-- native surfaces and LGI-ified Cairo surfaces.
|
||||||
|
function root.wallpaper(pattern)
|
||||||
|
if not pattern then return root._wallpaper() end
|
||||||
|
|
||||||
|
-- Checking for type will either potentially `error()` or always
|
||||||
|
-- return `userdata`. This check will error() when the surface is
|
||||||
|
-- already native.
|
||||||
|
local err = pcall(function() return pattern._native end)
|
||||||
|
|
||||||
|
-- The presence of `root._write_string` means the test backend is
|
||||||
|
-- used. Avoid passing the native surface.
|
||||||
|
if err and not root._write_string then
|
||||||
|
return root._wallpaper(pattern._native)
|
||||||
|
else
|
||||||
|
return root._wallpaper(pattern)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- root.bottons() used to be a capi function. However this proved confusing
|
-- root.bottons() used to be a capi function. However this proved confusing
|
||||||
-- as rc.lua used `awful.button` and `root.buttons()` used capi.button. There
|
-- as rc.lua used `awful.button` and `root.buttons()` used capi.button. There
|
||||||
-- was a little documented hack to "flatten" awful.button into a pair of
|
-- was a little documented hack to "flatten" awful.button into a pair of
|
||||||
|
|
|
@ -35,6 +35,7 @@ local ret = {
|
||||||
tooltip = require("awful.tooltip");
|
tooltip = require("awful.tooltip");
|
||||||
permissions = require("awful.permissions");
|
permissions = require("awful.permissions");
|
||||||
titlebar = require("awful.titlebar");
|
titlebar = require("awful.titlebar");
|
||||||
|
wallpaper = require("awful.wallpaper");
|
||||||
rules = require("awful.rules");
|
rules = require("awful.rules");
|
||||||
popup = require("awful.popup");
|
popup = require("awful.popup");
|
||||||
spawn = require("awful.spawn");
|
spawn = require("awful.spawn");
|
||||||
|
|
|
@ -0,0 +1,862 @@
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
--- Allows to use the wibox widget system to draw the wallpaper.
|
||||||
|
--
|
||||||
|
-- Rather than simply having a function to set an image
|
||||||
|
-- (stretched, centered or tiled) like most wallpaper tools, this module
|
||||||
|
-- leverage the full widget system to draw the wallpaper. Note that the result
|
||||||
|
-- is **not** interactive. If you want an interactive wallpaper, better use
|
||||||
|
-- a `wibox` object with the `below` property set to `true` and maximized
|
||||||
|
-- using `awful.placement.maximized`.
|
||||||
|
--
|
||||||
|
-- It is possible to create an `awful.wallpaper` object from any places, but
|
||||||
|
-- it is recommanded to do it from the `request::wallpaper` signal handler.
|
||||||
|
-- That signal is called everytime something which could affect the wallpaper
|
||||||
|
-- rendering changes, such as new screens.
|
||||||
|
--
|
||||||
|
-- Single image
|
||||||
|
-- ============
|
||||||
|
--
|
||||||
|
-- This is the default `rc.lua` wallpaper format. It fills the whole screen
|
||||||
|
-- and stretches the image while keeping the aspect ratio.
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_mazimized1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- If the image aspect ratio doesn't match, the `bg` property can be used to
|
||||||
|
-- fill the empty area:
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_mazimized2_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- It is also possible to stretch the image:
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_mazimized3_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- Finally, it is also possible to use simpler "branding" in a corner using
|
||||||
|
-- `awful.placement`:
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_corner1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- Tiled
|
||||||
|
-- =====
|
||||||
|
--
|
||||||
|
-- This example tiles an image:
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_tiled1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- This one tiles a shape using the `wibox.widget.separator` widget:
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_tiled2_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- See the `wibox.container.tile` for more advanced tiling configuration
|
||||||
|
-- options.
|
||||||
|
--
|
||||||
|
-- Solid colors and gradients
|
||||||
|
-- ==========================
|
||||||
|
--
|
||||||
|
-- Solid colors can be set using the `bg` property mentionned above. It
|
||||||
|
-- is also possible to set gradients:
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_gradient1_EXAMPLE@
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_gradient2_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- Widgets
|
||||||
|
-- =======
|
||||||
|
--
|
||||||
|
-- It is possible to create a wallpaper using any widgets. However, keep
|
||||||
|
-- in mind that the wallpaper surface is not interactive, so some widgets
|
||||||
|
-- like the sliders will render, but will not behave correctly. Also, it
|
||||||
|
-- is not recommanded to update the wallpaper too often. This is very slow.
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_widget2_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- Cairo graphics API
|
||||||
|
-- ==================
|
||||||
|
--
|
||||||
|
-- AwesomeWM widgets are backed by Cairo. So it is always possible to get
|
||||||
|
-- access to the Cairo context directly to do some vector art:
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_widget1_EXAMPLE@
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- SVG vector images
|
||||||
|
-- =================
|
||||||
|
--
|
||||||
|
-- SVG are supported if `librsvg` is installed. Please note that `librsvg`
|
||||||
|
-- doesn't implement all filters you might find in the latest version of
|
||||||
|
-- your web browser. It is possible some advanced SVG will not look exactly
|
||||||
|
-- as they do in a web browser or even Inkscape. However, for most images,
|
||||||
|
-- it should look identical.
|
||||||
|
--
|
||||||
|
-- Our SVG support goes beyond simple rendering. It is possible to set a
|
||||||
|
-- custom CSS stylesheet (see `wibox.widget.imagebox.stylesheet`):
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_svg_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- Note that in the example above, it is raw SVG code, but it is also possible
|
||||||
|
-- to use a file path. If you have a `.svgz`, you need to uncompress it first
|
||||||
|
-- using `gunzip` or a software like Inkscape.
|
||||||
|
--
|
||||||
|
-- Multiple screen
|
||||||
|
-- ===============
|
||||||
|
--
|
||||||
|
-- The default `rc.lua` creates a new wallpaper everytime `request::wallpaper`
|
||||||
|
-- is emitted. This is well suited for having a single wallpaper per screen.
|
||||||
|
-- It is also much simpler to implement slideshows and add/remove screens.
|
||||||
|
--
|
||||||
|
-- However, it isn't wall suited for wallpaper rendered across multiple screens.
|
||||||
|
-- For this case, it is better to capture the return value of `awful.wallpaper {}`
|
||||||
|
-- as a global variable. Then manually call `add_screen` and `remove_screen` when
|
||||||
|
-- needed. A shortcut can be to do:
|
||||||
|
--
|
||||||
|
-- @DOC_text_awful_wallpaper_multi_screen_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- Slideshow
|
||||||
|
-- =========
|
||||||
|
--
|
||||||
|
-- Slideshows (changing the wallpaper after a few minutes) can be implemented
|
||||||
|
-- directly using a timer and callback, but it is more elegant to simply request
|
||||||
|
-- a new wallpaper, then get a random image from within the request handler. This
|
||||||
|
-- way, corner cases such as adding and removing screens are handled:
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_slideshow1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @author Emmanuel Lepage Vallee <elv1313@gmail.com>
|
||||||
|
-- @copyright 2019 Emmanuel Lepage Vallee
|
||||||
|
-- @popupmod awful.wallpaper
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
require("awful._compat")
|
||||||
|
local gtable = require( "gears.table" )
|
||||||
|
local gobject = require( "gears.object" )
|
||||||
|
local gcolor = require( "gears.color" )
|
||||||
|
local gtimer = require( "gears.timer" )
|
||||||
|
local surface = require( "gears.surface" )
|
||||||
|
local base = require( "wibox.widget.base" )
|
||||||
|
local background = require( "wibox.container.background")
|
||||||
|
local beautiful = require( "beautiful" )
|
||||||
|
local cairo = require( "lgi" ).cairo
|
||||||
|
local draw = require( "wibox.widget" ).draw_to_cairo_context
|
||||||
|
local grect = require( "gears.geometry" ).rectangle
|
||||||
|
|
||||||
|
local capi = { screen = screen, root = root }
|
||||||
|
|
||||||
|
local module = {}
|
||||||
|
|
||||||
|
local function get_screen(s)
|
||||||
|
return s and capi.screen[s]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Screen as key, wallpaper as values.
|
||||||
|
local pending_repaint = setmetatable({}, {__mode = 'k'})
|
||||||
|
|
||||||
|
local backgrounds = setmetatable({}, {__mode = 'k'})
|
||||||
|
|
||||||
|
local panning_modes = {}
|
||||||
|
|
||||||
|
-- Get a list of all screen areas.
|
||||||
|
local function get_rectangles(screens, honor_workarea, honor_padding)
|
||||||
|
local ret = {}
|
||||||
|
|
||||||
|
for _, s in ipairs(screens) do
|
||||||
|
table.insert(ret, s:get_bounding_geometry {
|
||||||
|
honor_padding = honor_padding,
|
||||||
|
honor_workarea = honor_workarea
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Outer perimeter of all rectangles.
|
||||||
|
function panning_modes.outer(self)
|
||||||
|
local rectangles = get_rectangles(self.screens, self.honor_workarea, self.honor_padding)
|
||||||
|
local p1, p2 = {x = math.huge, y = math.huge}, {x = 0, y = 0}
|
||||||
|
|
||||||
|
for _, rect in ipairs(rectangles) do
|
||||||
|
p1.x, p1.y = math.min(p1.x, rect.x), math.min(p1.y, rect.y)
|
||||||
|
p2.x, p2.y = math.max(p2.x, rect.x + rect.width), math.max(p2.y, rect.y + rect.height)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Never try to paint this, it would freeze the system.
|
||||||
|
assert(p1.x ~= math.huge and p1.y ~= math.huge, "Setting wallpaper failed"..#self.screens)
|
||||||
|
|
||||||
|
return {
|
||||||
|
x = p1.x,
|
||||||
|
y = p1.y,
|
||||||
|
width = p2.x - p1.x,
|
||||||
|
height = p2.y - p1.y,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Horizontal inner perimeter of all rectangles.
|
||||||
|
function panning_modes.inner_horizontal(self)
|
||||||
|
local rectangles = get_rectangles(self.screens, self.honor_workarea, self.honor_padding)
|
||||||
|
local p1, p2 = {x = math.huge, y = 0}, {x = 0, y = math.huge}
|
||||||
|
|
||||||
|
for _, rect in ipairs(rectangles) do
|
||||||
|
p1.x, p1.y = math.min(p1.x, rect.x), math.max(p1.y, rect.y)
|
||||||
|
p2.x, p2.y = math.max(p2.x, rect.x + rect.width), math.min(p2.y, rect.y + rect.height)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Never try to paint this, it would freeze the system.
|
||||||
|
assert(p1.x ~= math.huge and p2.y ~= math.huge, "Setting wallpaper failed")
|
||||||
|
|
||||||
|
return {
|
||||||
|
x = p1.x,
|
||||||
|
y = p1.y,
|
||||||
|
width = p2.x - p1.x,
|
||||||
|
height = p2.y - p1.y,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Vertical inner perimeter of all rectangles.
|
||||||
|
function panning_modes.inner_vertical(self)
|
||||||
|
local rectangles = get_rectangles(self.screens, self.honor_workarea, self.honor_padding)
|
||||||
|
local p1, p2 = {x = 0, y = math.huge}, {x = math.huge, y = 0}
|
||||||
|
|
||||||
|
for _, rect in ipairs(rectangles) do
|
||||||
|
p1.x, p1.y = math.max(p1.x, rect.x), math.min(p1.y, rect.y)
|
||||||
|
p2.x, p2.y = math.min(p2.x, rect.x + rect.width), math.max(p2.y, rect.y + rect.height)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Never try to paint this, it would freeze the system.
|
||||||
|
assert(p1.y ~= math.huge and p2.a ~= math.huge, "Setting wallpaper failed")
|
||||||
|
|
||||||
|
return {
|
||||||
|
x = p1.x,
|
||||||
|
y = p1.y,
|
||||||
|
width = p2.x - p1.x,
|
||||||
|
height = p2.y - p1.y,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Best or vertical and horizontal "inner" modes.
|
||||||
|
function panning_modes.inner(self)
|
||||||
|
local vert = panning_modes.inner_vertical(self)
|
||||||
|
local hori = panning_modes.inner_horizontal(self)
|
||||||
|
|
||||||
|
if vert.width <= 0 or vert.height <= 0 then return hori end
|
||||||
|
if hori.width <= 0 or hori.height <= 0 then return vert end
|
||||||
|
|
||||||
|
if vert.width * vert.height > hori.width * hori.height then
|
||||||
|
return vert
|
||||||
|
else
|
||||||
|
return hori
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function paint()
|
||||||
|
if not next(pending_repaint) then return end
|
||||||
|
|
||||||
|
local root_width, root_height = capi.root.size()
|
||||||
|
|
||||||
|
-- Get the current wallpaper content.
|
||||||
|
local source = surface(root.wallpaper())
|
||||||
|
|
||||||
|
local target, cr
|
||||||
|
|
||||||
|
-- It's possible that a wallpaper for 1 screen is set using another tool, so make
|
||||||
|
-- sure we copy the current content.
|
||||||
|
if source then
|
||||||
|
target = source:create_similar(cairo.Content.COLOR, root_width, root_height)
|
||||||
|
cr = cairo.Context(target)
|
||||||
|
|
||||||
|
-- Copy the old wallpaper to the new one
|
||||||
|
cr:save()
|
||||||
|
cr.operator = cairo.Operator.SOURCE
|
||||||
|
cr:set_source_surface(source, 0, 0)
|
||||||
|
|
||||||
|
for s in screen do
|
||||||
|
cr:rectangle(
|
||||||
|
s.geometry.x,
|
||||||
|
s.geometry.y,
|
||||||
|
s.geometry.width,
|
||||||
|
s.geometry.height
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
cr:clip()
|
||||||
|
|
||||||
|
cr:paint()
|
||||||
|
cr:restore()
|
||||||
|
else
|
||||||
|
target = cairo.ImageSurface(cairo.Format.RGB32, root_width, root_height)
|
||||||
|
cr = cairo.Context(target)
|
||||||
|
end
|
||||||
|
|
||||||
|
local walls = {}
|
||||||
|
|
||||||
|
for _, wall in pairs(backgrounds) do
|
||||||
|
walls[wall] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Not supposed to happen, but there is enough API surface for
|
||||||
|
-- it to be a side effect of some signals. Calling the panning
|
||||||
|
-- mode callback with zero screen is not supported.
|
||||||
|
if not next(walls) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for wall in pairs(walls) do
|
||||||
|
|
||||||
|
local geo = type(wall._private.panning_area) == "function" and
|
||||||
|
wall._private.panning_area(wall) or
|
||||||
|
panning_modes[wall._private.panning_area](wall)
|
||||||
|
|
||||||
|
-- If false, this panning area isn't well suited for the screen geometry.
|
||||||
|
if geo.width > 0 or geo.height > 0 then
|
||||||
|
local uncovered_areas = grect.area_remove(get_rectangles(wall.screens, false, false), geo)
|
||||||
|
|
||||||
|
cr:save()
|
||||||
|
|
||||||
|
-- Prevent overwrite then there is multiple non-continuous screens.
|
||||||
|
for _, s in ipairs(wall.screens) do
|
||||||
|
cr:rectangle(
|
||||||
|
s.geometry.x,
|
||||||
|
s.geometry.y,
|
||||||
|
s.geometry.width,
|
||||||
|
s.geometry.height
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
cr:clip()
|
||||||
|
|
||||||
|
-- The older surface might contain garbage, optionally clean it.
|
||||||
|
if wall.uncovered_areas_color then
|
||||||
|
cr:set_source(gcolor(wall.uncovered_areas_color))
|
||||||
|
|
||||||
|
for _, area in ipairs(uncovered_areas) do
|
||||||
|
cr:rectangle(area.x, area.y, area.width, area.height)
|
||||||
|
cr:fill()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if not wall._private.container then
|
||||||
|
wall._private.container = background()
|
||||||
|
wall._private.container.bg = wall._private.bg or beautiful.wallpaper_bg or "#000000"
|
||||||
|
wall._private.container.fg = wall._private.fg or beautiful.wallpaper_fg or "#ffffff"
|
||||||
|
wall._private.container.widget = wall.widget
|
||||||
|
end
|
||||||
|
|
||||||
|
local a_context = {
|
||||||
|
dpi = wall._private.context.dpi
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Pick the lowest DPI.
|
||||||
|
if not a_context.dpi then
|
||||||
|
a_context.dpi = math.huge
|
||||||
|
for _, s in ipairs(wall.screens) do
|
||||||
|
a_context.dpi = math.min(
|
||||||
|
s.dpi and s.dpi or s.preferred_dpi, a_context.dpi
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Fallback.
|
||||||
|
if not a_context.dpi then
|
||||||
|
a_context.dpi = 96
|
||||||
|
end
|
||||||
|
|
||||||
|
cr:translate(geo.x, geo.y)
|
||||||
|
draw(wall._private.container, cr, geo.width, geo.height, a_context)
|
||||||
|
cr:restore()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set the wallpaper.
|
||||||
|
local pattern = cairo.Pattern.create_for_surface(target)
|
||||||
|
capi.root.wallpaper(pattern)
|
||||||
|
|
||||||
|
-- Limit some potential GC induced increase in memory usage.
|
||||||
|
-- But really, is someone is trying to apply wallpaper changes more
|
||||||
|
-- often than the GC is executed, they are doing it wrong.
|
||||||
|
target:finish()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local mutex = false
|
||||||
|
|
||||||
|
-- Uploading the surface to X11 is *very* resource intensive. Given the updates
|
||||||
|
-- will often happen in batch (like startup), make sure to only do one "real"
|
||||||
|
-- update.
|
||||||
|
local function update()
|
||||||
|
if mutex then return end
|
||||||
|
|
||||||
|
mutex = true
|
||||||
|
|
||||||
|
gtimer.delayed_call(function()
|
||||||
|
-- Remove the mutex first in case `paint()` raises an exception.
|
||||||
|
mutex = false
|
||||||
|
paint()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
capi.screen.connect_signal("removed", function(s)
|
||||||
|
if not backgrounds[s] then return end
|
||||||
|
|
||||||
|
backgrounds[s]:remove_screen(s)
|
||||||
|
|
||||||
|
update()
|
||||||
|
end)
|
||||||
|
|
||||||
|
capi.screen.connect_signal("property::geometry", function(s)
|
||||||
|
if not backgrounds[s] then return end
|
||||||
|
|
||||||
|
backgrounds[s]:repaint()
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
--- The wallpaper widget.
|
||||||
|
--
|
||||||
|
-- When set, instead of using the `image_path` or `surface` properties, the
|
||||||
|
-- wallpaper will be defined as a normal `wibox` widget tree.
|
||||||
|
--
|
||||||
|
-- @property widget
|
||||||
|
-- @tparam wibox.widget widget
|
||||||
|
-- @see wibox.widget.imagebox
|
||||||
|
-- @see wibox.container.tile
|
||||||
|
|
||||||
|
--- The wallpaper DPI (dots per inch).
|
||||||
|
--
|
||||||
|
-- Each screen has a DPI. This value will be used by default, but sometime it
|
||||||
|
-- is useful to override the screen DPI and use a custom one. This makes
|
||||||
|
-- possible, for example, to draw the widgets bigger than they would otherwise
|
||||||
|
-- be.
|
||||||
|
--
|
||||||
|
-- If not DPI is defined, it will use the smallest DPI from any of the screen.
|
||||||
|
--
|
||||||
|
-- In this example, there is 3 screens with DPI of 100, 200 and 300. As you can
|
||||||
|
-- see, only the text size is affected. Many widgetds are DPI aware, but not all
|
||||||
|
-- of them. This is either because DPI isn't relevant to them or simply because it
|
||||||
|
-- isn't supported (like `wibox.widget.graph`).
|
||||||
|
--
|
||||||
|
-- @DOC_awful_wallpaper_dpi1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @property dpi
|
||||||
|
-- @tparam[opt=screen.dpi] number dpi
|
||||||
|
-- @see screen
|
||||||
|
-- @see screen.dpi
|
||||||
|
|
||||||
|
--- The wallpaper screen.
|
||||||
|
--
|
||||||
|
-- Note that there can only be one wallpaper per screen. If there is more, one
|
||||||
|
-- will be chosen and all other ignored.
|
||||||
|
--
|
||||||
|
-- @property screen
|
||||||
|
-- @tparam screen screen
|
||||||
|
-- @see screens
|
||||||
|
-- @see add_screen
|
||||||
|
-- @see remove_screen
|
||||||
|
|
||||||
|
--- A list of screen for this wallpaper.
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_screens1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- Some large wallpaper are made to span multiple screens.
|
||||||
|
-- @property screens
|
||||||
|
-- @tparam table screens
|
||||||
|
-- @see screen
|
||||||
|
-- @see add_screen
|
||||||
|
-- @see remove_screen
|
||||||
|
-- @see detach
|
||||||
|
|
||||||
|
--- The background color.
|
||||||
|
--
|
||||||
|
-- It will be used as the "fill" color if the `image` doesn't take all the
|
||||||
|
-- screen space. It will also be the default background for the `widget.
|
||||||
|
--
|
||||||
|
-- As usual with colors in `AwesomeWM`, it can also be a gradient or a pattern.
|
||||||
|
--
|
||||||
|
-- @property bg
|
||||||
|
-- @tparam gears.color bg
|
||||||
|
-- @see gears.color
|
||||||
|
|
||||||
|
--- The foreground color.
|
||||||
|
--
|
||||||
|
-- This will be used by the `widget` (if any).
|
||||||
|
--
|
||||||
|
-- As usual with colors in `AwesomeWM`, it can also be a gradient or a pattern.
|
||||||
|
--
|
||||||
|
-- @property fg
|
||||||
|
-- @tparam gears.color fg
|
||||||
|
-- @see gears.color
|
||||||
|
|
||||||
|
--- The default wallpaper background color.
|
||||||
|
-- @beautiful beautiful.wallpaper_bg
|
||||||
|
-- @tparam gears.color wallpaper_bg
|
||||||
|
-- @see bg
|
||||||
|
|
||||||
|
--- The default wallpaper foreground color.
|
||||||
|
--
|
||||||
|
-- This is useful when using widgets or text in the wallpaper. A wallpaper
|
||||||
|
-- created from a single image wont use this.
|
||||||
|
--
|
||||||
|
-- @beautiful beautiful.wallpaper_fg
|
||||||
|
-- @tparam gears.color wallpaper_fg
|
||||||
|
-- @see bg
|
||||||
|
|
||||||
|
--- Honor the workarea.
|
||||||
|
--
|
||||||
|
-- When set to `true`, the wallpaper will only fill the workarea space instead
|
||||||
|
-- of the entire screen. This means it wont be drawn below the `awful.wibar` or
|
||||||
|
-- docked clients. This is useful when using opaque bars. Note that it can cause
|
||||||
|
-- aspect ratio issues for the wallpaper `image` and add bars colored with the
|
||||||
|
-- `bg` color on the sides.
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_workarea1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @property honor_workarea
|
||||||
|
-- @tparam[opt=false] boolean honor_workarea
|
||||||
|
-- @see honor_padding
|
||||||
|
-- @see uncovered_areas
|
||||||
|
|
||||||
|
--- Honor the screen padding.
|
||||||
|
--
|
||||||
|
-- When set, this will look at the `screen.padding` property to restrict the
|
||||||
|
-- area where the wallpaper is rendered.
|
||||||
|
--
|
||||||
|
-- @DOC_awful_wallpaper_padding1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @property honor_padding
|
||||||
|
-- @tparam boolean honor_padding
|
||||||
|
-- @see honor_workarea
|
||||||
|
-- @see uncovered_areas
|
||||||
|
|
||||||
|
--- Returns the list of screen(s) area which won't be covered by the wallpaper.
|
||||||
|
--
|
||||||
|
-- When `honor_workarea`, `honor_padding` or panning are used, some section of
|
||||||
|
-- the screen won't have a wallpaper. This returns a list of areas tables. Each
|
||||||
|
-- table has a `x`, `y`, `width` and `height` key.
|
||||||
|
--
|
||||||
|
-- @property uncovered_areas
|
||||||
|
-- @tparam table uncovered_areas
|
||||||
|
-- @see honor_workarea
|
||||||
|
-- @see honor_padding
|
||||||
|
-- @see uncovered_areas_color
|
||||||
|
|
||||||
|
--- The color for the uncovered areas.
|
||||||
|
--
|
||||||
|
-- Some application rely on the wallpaper for "fake" transparency. Even if an
|
||||||
|
-- area is hidden under a wibar (or other clients), its background can still
|
||||||
|
-- become visible. If you use such application and change your screen geometry
|
||||||
|
-- often enough, it is possible some areas would become filled with the remains
|
||||||
|
-- of previous wallpapers. This property allows to clean those areas with a solid
|
||||||
|
-- color or a gradient.
|
||||||
|
--
|
||||||
|
-- @property uncovered_areas_color
|
||||||
|
-- @tparam gears.color uncovered_areas_color
|
||||||
|
-- @see uncovered_areas
|
||||||
|
|
||||||
|
--- Defines where the wallpaper is placed when there is multiple screens.
|
||||||
|
--
|
||||||
|
-- When there is more than 1 screen, it is possible they don't have the same
|
||||||
|
-- resolution, position or orientation. Panning the wallpaper over them may look
|
||||||
|
-- better if a continuous rectangle is used rather than creating a virtual rectangle
|
||||||
|
-- around all screens.
|
||||||
|
--
|
||||||
|
-- The default algorithms are:
|
||||||
|
--
|
||||||
|
-- **outer:** *(default)*
|
||||||
|
--
|
||||||
|
-- Draw an imaginary rectangle around all screens.
|
||||||
|
--
|
||||||
|
-- @DOC_awful_wallpaper_panning_outer_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- **inner:**
|
||||||
|
--
|
||||||
|
-- Take the largest area or either `inner_horizontal` or `inner_vertical`.
|
||||||
|
--
|
||||||
|
-- @DOC_awful_wallpaper_panning_inner_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- **inner_horizontal:**
|
||||||
|
--
|
||||||
|
-- Take the smallest `x` value, the largest `x+width`, the smallest `y`
|
||||||
|
-- and the smallest `y+height`.
|
||||||
|
--
|
||||||
|
-- @DOC_awful_wallpaper_panning_inner_horizontal_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- **inner_vertical:**
|
||||||
|
--
|
||||||
|
-- Take the smallest `y` value, the largest `y+height`, the smallest `x`
|
||||||
|
-- and the smallest `x+width`.
|
||||||
|
--
|
||||||
|
-- @DOC_awful_wallpaper_panning_inner_vertical_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- **Custom function:**
|
||||||
|
--
|
||||||
|
-- It is also possible to define a custom function.
|
||||||
|
--
|
||||||
|
-- @DOC_awful_wallpaper_panning_custom_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @property panning_area
|
||||||
|
-- @tparam function|string panning_area
|
||||||
|
-- @see uncovered_areas
|
||||||
|
|
||||||
|
function module:set_panning_area(value)
|
||||||
|
value = value or "outer"
|
||||||
|
|
||||||
|
assert(type(value) == "function" or panning_modes[value], "Invalid panning mode: "..tostring(value))
|
||||||
|
|
||||||
|
self._private.panning_area = value
|
||||||
|
|
||||||
|
self:repaint()
|
||||||
|
|
||||||
|
self:emit_signal("property::panning_area", value)
|
||||||
|
end
|
||||||
|
|
||||||
|
function module:set_widget(w)
|
||||||
|
self._private.widget = base.make_widget_from_value(w)
|
||||||
|
|
||||||
|
if self._private.container then
|
||||||
|
self._private.container.widget = self._private.widget
|
||||||
|
end
|
||||||
|
|
||||||
|
self:repaint()
|
||||||
|
end
|
||||||
|
|
||||||
|
function module:get_widget()
|
||||||
|
return self._private.widget
|
||||||
|
end
|
||||||
|
|
||||||
|
function module:set_dpi(dpi)
|
||||||
|
self._private.context.dpi = dpi
|
||||||
|
self:repaint()
|
||||||
|
end
|
||||||
|
|
||||||
|
function module:get_dpi()
|
||||||
|
return self._private.context.dpi
|
||||||
|
end
|
||||||
|
|
||||||
|
function module:set_screen(s)
|
||||||
|
if not s then return end
|
||||||
|
|
||||||
|
self:_clear()
|
||||||
|
self:add_screen(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, prop in ipairs {"bg", "fg"} do
|
||||||
|
module["set_"..prop] = function(self, color)
|
||||||
|
if self._private.container then
|
||||||
|
self._private.container[prop] = color
|
||||||
|
end
|
||||||
|
|
||||||
|
self._private[prop] = color
|
||||||
|
|
||||||
|
self:repaint()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function module:get_uncovered_areas()
|
||||||
|
local geo = type(self._private.panning_area) == "function" and
|
||||||
|
self._private.panning_area(self) or
|
||||||
|
panning_modes[self._private.panning_area](self)
|
||||||
|
|
||||||
|
return grect.area_remove(get_rectangles(self.screens, false, false), geo)
|
||||||
|
end
|
||||||
|
|
||||||
|
function module:set_screens(screens)
|
||||||
|
local to_rem = {}
|
||||||
|
|
||||||
|
-- All screens.
|
||||||
|
-- The copy is needed because it's a metatable, `ipairs` doesn't work
|
||||||
|
-- correctly in all Lua versions.
|
||||||
|
if screens == capi.screen then
|
||||||
|
screens = {}
|
||||||
|
|
||||||
|
for s in capi.screen do
|
||||||
|
table.insert(screens, s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, s in ipairs(screens) do
|
||||||
|
to_rem[get_screen(s)] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, s in ipairs(self.screens) do
|
||||||
|
to_rem[get_screen(s)] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, s in ipairs(screens) do
|
||||||
|
s = get_screen(s)
|
||||||
|
self:add_screen(s)
|
||||||
|
to_rem[s] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
for s, remove in pairs(to_rem) do
|
||||||
|
if remove then
|
||||||
|
self:remove_screen(s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function module:get_screens()
|
||||||
|
return self._private.screens
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add another screen (enable panning).
|
||||||
|
--
|
||||||
|
-- **Before:**
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_add_screen1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- **After:**
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_add_screen2_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- Also note that adding a non-continuous screen might not work well,
|
||||||
|
-- but will not automatically add the screens in between:
|
||||||
|
--
|
||||||
|
--@DOC_awful_wallpaper_add_screen3_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @method add_screen
|
||||||
|
-- @tparam screen screen The screen object.
|
||||||
|
-- @see remove_screen
|
||||||
|
function module:add_screen(s)
|
||||||
|
s = get_screen(s)
|
||||||
|
|
||||||
|
for _, s2 in ipairs(self._private.screens) do
|
||||||
|
if s == s2 then return end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(self._private.screens, s)
|
||||||
|
|
||||||
|
if backgrounds[s] and backgrounds[s] ~= self then
|
||||||
|
backgrounds[s]:remove_screen(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
backgrounds[s] = self
|
||||||
|
|
||||||
|
self:repaint()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Detach the wallpaper from all screens.
|
||||||
|
--
|
||||||
|
-- Adding a new wallpaper to a screen will automatically
|
||||||
|
-- detach the older one. However there is some case when
|
||||||
|
-- it is useful to call this manually. For example, when
|
||||||
|
-- adding a new panned wallpaper, it is possible that 2
|
||||||
|
-- wallpaper will have an overlap.
|
||||||
|
--
|
||||||
|
-- @method detach
|
||||||
|
-- @see remove_screen
|
||||||
|
-- @see add_screen
|
||||||
|
function module:detach()
|
||||||
|
local screens = gtable.clone(self.screens)
|
||||||
|
|
||||||
|
for _, s in ipairs(screens) do
|
||||||
|
self:remove_screen(s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function module:_clear()
|
||||||
|
self._private.screens = setmetatable({}, {__mode = "v"})
|
||||||
|
update()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Repaint the wallpaper.
|
||||||
|
--
|
||||||
|
-- By default, even if the widget changes, the wallpaper will **NOT** be
|
||||||
|
-- automatically repainted. Repainting the native X11 wallpaper is slow and
|
||||||
|
-- it would be too easy to accidentally cause a performance problem. If you
|
||||||
|
-- really need to repaint the wallpaper, call this method.
|
||||||
|
--
|
||||||
|
-- @method repaint
|
||||||
|
function module:repaint()
|
||||||
|
for _, s in ipairs(self._private.screens) do
|
||||||
|
pending_repaint[s] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
update()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove a screen.
|
||||||
|
--
|
||||||
|
-- Calling this will remove a screen, but will **not** repaint its area.
|
||||||
|
-- In this example, the wallpaper was spanning all 3 screens and the
|
||||||
|
-- first screen was removed:
|
||||||
|
--
|
||||||
|
-- @DOC_awful_wallpaper_remove_screen1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- As you can see, the content of screen 1 still looks like it is part of
|
||||||
|
-- the 3 screen wallpaper. The only use case for calling this method is if
|
||||||
|
-- you use a 3rd party tools to change the wallpaper.
|
||||||
|
--
|
||||||
|
-- If you wish to simply remove a screen and not have leftover content, it is
|
||||||
|
-- simpler to just create a new wallpaper for that screen:
|
||||||
|
--
|
||||||
|
-- @DOC_awful_wallpaper_remove_screen2_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @method remove_screen
|
||||||
|
-- @tparam screen screen The screen to remove.
|
||||||
|
-- @see detach
|
||||||
|
-- @see add_screen
|
||||||
|
-- @see screens
|
||||||
|
function module:remove_screen(s)
|
||||||
|
s = get_screen(s)
|
||||||
|
|
||||||
|
for k, s2 in ipairs(self._private.screens) do
|
||||||
|
if s == s2 then
|
||||||
|
table.remove(self._private.screens, k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
backgrounds[s] = nil
|
||||||
|
|
||||||
|
self:repaint()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a wallpaper.
|
||||||
|
--
|
||||||
|
-- Note that all parameters are not required. Please refer to the
|
||||||
|
-- module description and examples to understand parameters usages.
|
||||||
|
--
|
||||||
|
-- @constructorfct awful.wallpaper
|
||||||
|
-- @tparam table args
|
||||||
|
-- @tparam[opt] wibox.widget args.widget The wallpaper widget.
|
||||||
|
-- @tparam[opt] number args.dpi The wallpaper DPI (dots per inch).
|
||||||
|
-- @tparam[opt] screen args.screen The wallpaper screen.
|
||||||
|
-- @tparam[opt] table args.screens A list of screen for this wallpaper.
|
||||||
|
-- Use this parameter as a remplacement for `args.screen` to manage multiscreen wallpaper.
|
||||||
|
-- (Note: the expected table should be an array-like table `{screen1, screen2, ...}`)
|
||||||
|
-- @tparam[opt] gears.color args.bg The background color.
|
||||||
|
-- @tparam[opt] gears.color args.fg The foreground color.
|
||||||
|
-- @tparam[opt] gears.color args.uncovered_areas_color The color for the uncovered areas.
|
||||||
|
-- @tparam[opt] boolean args.honor_workarea Honor the workarea.
|
||||||
|
-- @tparam[opt] boolean args.honor_padding Honor the screen padding.
|
||||||
|
-- @tparam[opt] table args.uncovered_areas Returns the list of screen(s) area which won't be covered by the wallpaper.
|
||||||
|
-- @tparam[opt] function|string args.panning_area Defines where the wallpaper is placed when there is multiple screens.
|
||||||
|
|
||||||
|
local function new(_, args)
|
||||||
|
args = args or {}
|
||||||
|
local ret = gobject {
|
||||||
|
enable_auto_signals = true,
|
||||||
|
enable_properties = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
rawset(ret, "_private", {})
|
||||||
|
ret._private.context = {}
|
||||||
|
ret._private.panning_area = "outer"
|
||||||
|
|
||||||
|
gtable.crush(ret, module, true)
|
||||||
|
|
||||||
|
ret:_clear()
|
||||||
|
|
||||||
|
-- Set the screen or screens first to avoid a race condition
|
||||||
|
-- with the other setters.
|
||||||
|
local args_screen, args_screens = args.screen, args.screens
|
||||||
|
if args_screen then
|
||||||
|
ret.screen = args_screen
|
||||||
|
elseif args_screens then
|
||||||
|
ret.screens = args_screens
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Avoid crushing `screen` and `screens` twice.
|
||||||
|
args.screen, args.screens = nil, nil
|
||||||
|
gtable.crush(ret, args, false)
|
||||||
|
args.screen, args.screens = args_screen, args_screens
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable(module, {__call = new})
|
|
@ -172,28 +172,39 @@ end
|
||||||
-- @tparam string path The directory to search.
|
-- @tparam string path The directory to search.
|
||||||
-- @tparam[opt] table exts Specific extensions to limit the search to. eg:`{ "jpg", "png" }`
|
-- @tparam[opt] table exts Specific extensions to limit the search to. eg:`{ "jpg", "png" }`
|
||||||
-- If ommited, all files are considered.
|
-- If ommited, all files are considered.
|
||||||
|
-- @tparam[opt=false] boolean absolute_path Return the absolute path instead of the filename.
|
||||||
-- @treturn string|nil A randomly selected filename from the specified path (with
|
-- @treturn string|nil A randomly selected filename from the specified path (with
|
||||||
-- a specified extension if required) or nil if no suitable file is found.
|
-- a specified extension if required) or nil if no suitable file is found. If `absolute_path`
|
||||||
|
-- is set, then a path is returned instead of a file name.
|
||||||
-- @staticfct gears.filesystem.get_random_file_from_dir
|
-- @staticfct gears.filesystem.get_random_file_from_dir
|
||||||
function filesystem.get_random_file_from_dir(path, exts)
|
function filesystem.get_random_file_from_dir(path, exts, absolute_path)
|
||||||
local files, valid_exts = {}, {}
|
local files, valid_exts = {}, {}
|
||||||
|
|
||||||
-- Transforms { "jpg", ... } into { [jpg] = #, ... }
|
-- Transforms { "jpg", ... } into { [jpg] = #, ... }
|
||||||
if exts then for i, j in ipairs(exts) do valid_exts[j:lower()] = i end end
|
if exts then for i, j in ipairs(exts) do valid_exts[j:lower():gsub("^[.]", "")] = i end end
|
||||||
|
|
||||||
-- Build a table of files from the path with the required extensions
|
-- Build a table of files from the path with the required extensions
|
||||||
local file_list = Gio.File.new_for_path(path):enumerate_children("standard::*", 0)
|
local file_list = Gio.File.new_for_path(path):enumerate_children("standard::*", 0)
|
||||||
|
|
||||||
|
-- This will happen when the directory doesn't exist.
|
||||||
|
if not file_list then return nil end
|
||||||
|
|
||||||
for file in function() return file_list:next_file() end do
|
for file in function() return file_list:next_file() end do
|
||||||
if file:get_file_type() == "REGULAR" then
|
if file:get_file_type() == "REGULAR" then
|
||||||
local file_name = file:get_display_name()
|
local file_name = file:get_display_name()
|
||||||
|
|
||||||
if not exts or valid_exts[file_name:lower():match(".+%.(.*)$") or ""] then
|
if not exts or valid_exts[file_name:lower():match(".+%.(.*)$") or ""] then
|
||||||
table.insert(files, file_name)
|
table.insert(files, file_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if #files == 0 then return nil end
|
||||||
|
|
||||||
-- Return a randomly selected filename from the file table
|
-- Return a randomly selected filename from the file table
|
||||||
return #files > 0 and files[math.random(#files)] or nil
|
local file = files[math.random(#files)]
|
||||||
|
|
||||||
|
return absolute_path and (path:gsub("[/]*$", "") .. "/" .. file) or file
|
||||||
end
|
end
|
||||||
|
|
||||||
return filesystem
|
return filesystem
|
||||||
|
|
|
@ -1,22 +1,7 @@
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
-- Functions for setting the wallpaper.
|
-- Functions for setting the wallpaper.
|
||||||
--
|
--
|
||||||
-- There are two levels of functionality provided by this module:
|
-- This module is deprecated, please use `awful.wallpaper`.
|
||||||
--
|
|
||||||
-- The low-level functionality consists of two functions.
|
|
||||||
-- @{set} an already-prepared wallpaper on all screens and @{prepare_context}
|
|
||||||
-- prepares things to draw a new wallpaper.
|
|
||||||
--
|
|
||||||
-- The low-level API can for example be used to set solid red as a wallpaper
|
|
||||||
-- (see @{gears.color} for details on the supported syntax):
|
|
||||||
--
|
|
||||||
-- gears.wallpaper.set("#ff0000")
|
|
||||||
--
|
|
||||||
-- Ontop of these low-level functions, the remaining functions implement more
|
|
||||||
-- useful functionality. For example, given a screen object `s`, an image can be
|
|
||||||
-- set as the wallpaper as follows:
|
|
||||||
--
|
|
||||||
-- gears.wallpaper.maximized("path/to/image.png", s)
|
|
||||||
--
|
--
|
||||||
-- @author Uli Schlachter
|
-- @author Uli Schlachter
|
||||||
-- @copyright 2012 Uli Schlachter
|
-- @copyright 2012 Uli Schlachter
|
||||||
|
@ -51,8 +36,10 @@ end
|
||||||
-- @param s The screen to set the wallpaper on or nil for all screens
|
-- @param s The screen to set the wallpaper on or nil for all screens
|
||||||
-- @return[1] The available geometry (table with entries width and height)
|
-- @return[1] The available geometry (table with entries width and height)
|
||||||
-- @return[1] A cairo context that the wallpaper should be drawn to.
|
-- @return[1] A cairo context that the wallpaper should be drawn to.
|
||||||
-- @staticfct gears.wallpaper.prepare_context
|
-- @deprecated gears.wallpaper.prepare_context
|
||||||
function wallpaper.prepare_context(s)
|
function wallpaper.prepare_context(s)
|
||||||
|
debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5})
|
||||||
|
|
||||||
s = get_screen(s)
|
s = get_screen(s)
|
||||||
|
|
||||||
local root_width, root_height = root.size()
|
local root_width, root_height = root.size()
|
||||||
|
@ -110,8 +97,10 @@ end
|
||||||
-- @param pattern The wallpaper that should be set. This can be a cairo surface,
|
-- @param pattern The wallpaper that should be set. This can be a cairo surface,
|
||||||
-- a description for gears.color or a cairo pattern.
|
-- a description for gears.color or a cairo pattern.
|
||||||
-- @see gears.color
|
-- @see gears.color
|
||||||
-- @staticfct gears.wallpaper.set
|
-- @deprecated gears.wallpaper.set
|
||||||
function wallpaper.set(pattern)
|
function wallpaper.set(pattern)
|
||||||
|
debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5})
|
||||||
|
|
||||||
if cairo.Surface:is_type_of(pattern) then
|
if cairo.Surface:is_type_of(pattern) then
|
||||||
pattern = cairo.Pattern.create_for_surface(pattern)
|
pattern = cairo.Pattern.create_for_surface(pattern)
|
||||||
end
|
end
|
||||||
|
@ -121,7 +110,7 @@ function wallpaper.set(pattern)
|
||||||
if not cairo.Pattern:is_type_of(pattern) then
|
if not cairo.Pattern:is_type_of(pattern) then
|
||||||
error("wallpaper.set() called with an invalid argument")
|
error("wallpaper.set() called with an invalid argument")
|
||||||
end
|
end
|
||||||
root.wallpaper(pattern._native)
|
root.wallpaper(pattern)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set a centered wallpaper.
|
--- Set a centered wallpaper.
|
||||||
|
@ -132,8 +121,10 @@ end
|
||||||
-- gears.color. The default is black.
|
-- gears.color. The default is black.
|
||||||
-- @param scale The scale factor for the wallpaper. Default is 1 (original size).
|
-- @param scale The scale factor for the wallpaper. Default is 1 (original size).
|
||||||
-- @see gears.color
|
-- @see gears.color
|
||||||
-- @staticfct gears.wallpaper.centered
|
-- @deprecated gears.wallpaper.centered
|
||||||
function wallpaper.centered(surf, s, background, scale)
|
function wallpaper.centered(surf, s, background, scale)
|
||||||
|
debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5})
|
||||||
|
|
||||||
local geom, cr = wallpaper.prepare_context(s)
|
local geom, cr = wallpaper.prepare_context(s)
|
||||||
local original_surf = surf
|
local original_surf = surf
|
||||||
surf = surface.load_uncached(surf)
|
surf = surface.load_uncached(surf)
|
||||||
|
@ -172,8 +163,10 @@ end
|
||||||
-- @param s The screen whose wallpaper should be set. Can be nil, in which case
|
-- @param s The screen whose wallpaper should be set. Can be nil, in which case
|
||||||
-- all screens are set.
|
-- all screens are set.
|
||||||
-- @param offset This can be set to a table with entries x and y.
|
-- @param offset This can be set to a table with entries x and y.
|
||||||
-- @staticfct gears.wallpaper.tiled
|
-- @deprecated gears.wallpaper.tiled
|
||||||
function wallpaper.tiled(surf, s, offset)
|
function wallpaper.tiled(surf, s, offset)
|
||||||
|
debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5})
|
||||||
|
|
||||||
local _, cr = wallpaper.prepare_context(s)
|
local _, cr = wallpaper.prepare_context(s)
|
||||||
|
|
||||||
if offset then
|
if offset then
|
||||||
|
@ -202,8 +195,10 @@ end
|
||||||
-- @param ignore_aspect If this is true, the image's aspect ratio is ignored.
|
-- @param ignore_aspect If this is true, the image's aspect ratio is ignored.
|
||||||
-- The default is to honor the aspect ratio.
|
-- The default is to honor the aspect ratio.
|
||||||
-- @param offset This can be set to a table with entries x and y.
|
-- @param offset This can be set to a table with entries x and y.
|
||||||
-- @staticfct gears.wallpaper.maximized
|
-- @deprecated gears.wallpaper.maximized
|
||||||
function wallpaper.maximized(surf, s, ignore_aspect, offset)
|
function wallpaper.maximized(surf, s, ignore_aspect, offset)
|
||||||
|
debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5})
|
||||||
|
|
||||||
local geom, cr = wallpaper.prepare_context(s)
|
local geom, cr = wallpaper.prepare_context(s)
|
||||||
local original_surf = surf
|
local original_surf = surf
|
||||||
surf = surface.load_uncached(surf)
|
surf = surface.load_uncached(surf)
|
||||||
|
@ -243,8 +238,10 @@ end
|
||||||
-- @param background The background color that should be used. Gets handled via
|
-- @param background The background color that should be used. Gets handled via
|
||||||
-- gears.color. The default is black.
|
-- gears.color. The default is black.
|
||||||
-- @see gears.color
|
-- @see gears.color
|
||||||
-- @staticfct gears.wallpaper.fit
|
-- @deprecated gears.wallpaper.fit
|
||||||
function wallpaper.fit(surf, s, background)
|
function wallpaper.fit(surf, s, background)
|
||||||
|
debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5})
|
||||||
|
|
||||||
local geom, cr = wallpaper.prepare_context(s)
|
local geom, cr = wallpaper.prepare_context(s)
|
||||||
local original_surf = surf
|
local original_surf = surf
|
||||||
surf = surface.load_uncached(surf)
|
surf = surface.load_uncached(surf)
|
||||||
|
|
|
@ -31,6 +31,7 @@ function module:draw(context, cr, width, height)
|
||||||
if not self._private.surface then
|
if not self._private.surface then
|
||||||
self._private.surface = cairo.ImageSurface(cairo.Format.ARGB32, w+hspace, h+vspace)
|
self._private.surface = cairo.ImageSurface(cairo.Format.ARGB32, w+hspace, h+vspace)
|
||||||
self._private.cr = cairo.Context(self._private.surface)
|
self._private.cr = cairo.Context(self._private.surface)
|
||||||
|
self._private.cr:set_source(cr:get_source())
|
||||||
self._private.pattern = cairo.Pattern.create_for_surface(self._private.surface)
|
self._private.pattern = cairo.Pattern.create_for_surface(self._private.surface)
|
||||||
self._private.pattern.extend = cairo.Extend.REPEAT
|
self._private.pattern.extend = cairo.Extend.REPEAT
|
||||||
self._private.cr:translate(math.ceil(hspace), math.ceil(vspace))
|
self._private.cr:translate(math.ceil(hspace), math.ceil(vspace))
|
||||||
|
|
|
@ -48,28 +48,128 @@ end
|
||||||
|
|
||||||
local imagebox = { mt = {} }
|
local imagebox = { mt = {} }
|
||||||
|
|
||||||
local rsvg_handle_cache = setmetatable({}, { __mode = 'v' })
|
local rsvg_handle_cache = setmetatable({}, { __mode = 'k' })
|
||||||
|
|
||||||
---Load rsvg handle form image file
|
---Load rsvg handle form image file
|
||||||
---@tparam string file Path to svg file.
|
-- @tparam string file Path to svg file.
|
||||||
---@return Rsvg handle
|
-- @return Rsvg handle
|
||||||
|
-- @treturn table A table where cached data can be stored.
|
||||||
local function load_rsvg_handle(file)
|
local function load_rsvg_handle(file)
|
||||||
if not Rsvg then return end
|
if not Rsvg then return end
|
||||||
|
|
||||||
local cache = rsvg_handle_cache[file]
|
local cache = (rsvg_handle_cache[file] or {})["handle"]
|
||||||
|
|
||||||
if cache then
|
if cache then
|
||||||
return cache
|
return cache, rsvg_handle_cache[file]
|
||||||
|
end
|
||||||
|
|
||||||
|
local handle, err
|
||||||
|
|
||||||
|
if file:match("<[?]?xml") or file:match("<svg") then
|
||||||
|
handle, err = Rsvg.Handle.new_from_data(file)
|
||||||
|
else
|
||||||
|
handle, err = Rsvg.Handle.new_from_file(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
local handle, err = Rsvg.Handle.new_from_file(file)
|
|
||||||
if not err then
|
if not err then
|
||||||
rsvg_handle_cache[file] = handle
|
rsvg_handle_cache[file] = rsvg_handle_cache[file] or {}
|
||||||
return handle
|
rsvg_handle_cache[file]["handle"] = handle
|
||||||
|
return handle, rsvg_handle_cache[file]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---Apply cairo surface for given imagebox widget
|
||||||
|
local function set_surface(ib, surf)
|
||||||
|
local is_surf_valid = surf.width > 0 and surf.height > 0
|
||||||
|
if not is_surf_valid then return false end
|
||||||
|
|
||||||
|
ib._private.default = { width = surf.width, height = surf.height }
|
||||||
|
ib._private.handle = nil
|
||||||
|
ib._private.image = surf
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
---Apply RsvgHandle for given imagebox widget
|
||||||
|
local function set_handle(ib, handle, cache)
|
||||||
|
local dim = handle:get_dimensions()
|
||||||
|
local is_handle_valid = dim.width > 0 and dim.height > 0
|
||||||
|
if not is_handle_valid then return false end
|
||||||
|
|
||||||
|
ib._private.default = { width = dim.width, height = dim.height }
|
||||||
|
ib._private.handle = handle
|
||||||
|
ib._private.cache = cache
|
||||||
|
ib._private.image = nil
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
---Try to load some image object from file then apply it to imagebox.
|
||||||
|
---@tparam table ib Imagebox
|
||||||
|
---@tparam string file Image file name
|
||||||
|
---@tparam function image_loader Function to load image object from file
|
||||||
|
---@tparam function image_setter Function to set image object to imagebox
|
||||||
|
---@treturn boolean True if image was successfully applied
|
||||||
|
local function load_and_apply(ib, file, image_loader, image_setter)
|
||||||
|
local image_applied
|
||||||
|
local object, cache = image_loader(file)
|
||||||
|
|
||||||
|
if object then
|
||||||
|
image_applied = image_setter(ib, object, cache)
|
||||||
|
end
|
||||||
|
return image_applied
|
||||||
|
end
|
||||||
|
|
||||||
|
---Update the cached size depending on the stylesheet and dpi.
|
||||||
|
--
|
||||||
|
-- It's necessary because a single RSVG handle can be used by
|
||||||
|
-- many imageboxes. So DPI and Stylesheet need to be set each time.
|
||||||
|
local function update_dpi(self, ctx)
|
||||||
|
if not self._private.handle then return end
|
||||||
|
|
||||||
|
local dpi = self._private.auto_dpi and
|
||||||
|
ctx.dpi or
|
||||||
|
self._private.dpi or
|
||||||
|
nil
|
||||||
|
|
||||||
|
local need_dpi = dpi and
|
||||||
|
self._private.last_dpi ~= dpi
|
||||||
|
|
||||||
|
local need_style = self._private.handle.set_stylesheet and
|
||||||
|
self._private.stylesheet
|
||||||
|
|
||||||
|
local old_size = self._private.default and self._private.default.width
|
||||||
|
|
||||||
|
if dpi and dpi ~= self._private.cache.dpi then
|
||||||
|
if type(dpi) == "table" then
|
||||||
|
self._private.handle:set_dpi_x_y(dpi.x, dpi.y)
|
||||||
|
else
|
||||||
|
self._private.handle:set_dpi(dpi)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if need_style and self._private.cache.stylesheet ~= self._private.stylesheet then
|
||||||
|
self._private.handle:set_stylesheet(self._private.stylesheet)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Reload the size.
|
||||||
|
if need_dpi or (need_style and self._private.stylesheet ~= self._private.last_stylesheet) then
|
||||||
|
set_handle(self, self._private.handle, self._private.cache)
|
||||||
|
end
|
||||||
|
|
||||||
|
self._private.last_dpi = dpi
|
||||||
|
self._private.cache.dpi = dpi
|
||||||
|
self._private.last_stylesheet = self._private.stylesheet
|
||||||
|
self._private.cache.stylesheet = self._private.stylesheet
|
||||||
|
|
||||||
|
-- This can happen in the constructor when `dpi` is set after `image`.
|
||||||
|
if old_size and old_size ~= self._private.default.width then
|
||||||
|
self:emit_signal("widget::redraw_needed")
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Draw an imagebox with the given cairo context in the given geometry.
|
-- Draw an imagebox with the given cairo context in the given geometry.
|
||||||
function imagebox:draw(_, cr, width, height)
|
function imagebox:draw(ctx, cr, width, height)
|
||||||
if width == 0 or height == 0 or not self._private.default then return end
|
if width == 0 or height == 0 or not self._private.default then return end
|
||||||
|
|
||||||
-- For valign = "top" and halign = "left"
|
-- For valign = "top" and halign = "left"
|
||||||
|
@ -78,9 +178,11 @@ function imagebox:draw(_, cr, width, height)
|
||||||
y = 0,
|
y = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_dpi(self, ctx)
|
||||||
|
|
||||||
local w, h = self._private.default.width, self._private.default.height
|
local w, h = self._private.default.width, self._private.default.height
|
||||||
|
|
||||||
if not self._private.resize_forbidden then
|
if self._private.resize then
|
||||||
-- That's for the "fit" policy.
|
-- That's for the "fit" policy.
|
||||||
local aspects = {
|
local aspects = {
|
||||||
w = width / w,
|
w = width / w,
|
||||||
|
@ -93,10 +195,14 @@ function imagebox:draw(_, cr, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, aspect in ipairs {"w", "h"} do
|
for _, aspect in ipairs {"w", "h"} do
|
||||||
if policy[aspect] == "auto" then
|
if self._private.upscale == false and (w < width and h < height) then
|
||||||
aspects[aspect] = math.min(width / w, height / h)
|
aspects[aspect] = 1
|
||||||
|
elseif self._private.downscale == false and (w >= width and h >= height) then
|
||||||
|
aspects[aspect] = 1
|
||||||
elseif policy[aspect] == "none" then
|
elseif policy[aspect] == "none" then
|
||||||
aspects[aspect] = 1
|
aspects[aspect] = 1
|
||||||
|
elseif policy[aspect] == "auto" then
|
||||||
|
aspects[aspect] = math.min(width / w, height / h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -165,11 +271,22 @@ function imagebox:draw(_, cr, width, height)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Fit the imagebox into the given geometry
|
-- Fit the imagebox into the given geometry
|
||||||
function imagebox:fit(_, width, height)
|
function imagebox:fit(ctx, width, height)
|
||||||
if not self._private.default then return 0, 0 end
|
if not self._private.default then return 0, 0 end
|
||||||
|
|
||||||
|
update_dpi(self, ctx)
|
||||||
|
|
||||||
local w, h = self._private.default.width, self._private.default.height
|
local w, h = self._private.default.width, self._private.default.height
|
||||||
|
|
||||||
if not self._private.resize_forbidden or w > width or h > height then
|
if w <= width and h <= height and self._private.upscale == false then
|
||||||
|
return w, h
|
||||||
|
end
|
||||||
|
|
||||||
|
if (w < width or h < height) and self._private.downscale == false then
|
||||||
|
return w, h
|
||||||
|
end
|
||||||
|
|
||||||
|
if self._private.resize or w > width or h > height then
|
||||||
local aspect = math.min(width / w, height / h)
|
local aspect = math.min(width / w, height / h)
|
||||||
return w * aspect, h * aspect
|
return w * aspect, h * aspect
|
||||||
end
|
end
|
||||||
|
@ -177,44 +294,6 @@ function imagebox:fit(_, width, height)
|
||||||
return w, h
|
return w, h
|
||||||
end
|
end
|
||||||
|
|
||||||
---Apply cairo surface for given imagebox widget
|
|
||||||
local function set_surface(ib, surf)
|
|
||||||
local is_surd_valid = surf.width > 0 and surf.height > 0
|
|
||||||
if not is_surd_valid then return end
|
|
||||||
|
|
||||||
ib._private.default = { width = surf.width, height = surf.height }
|
|
||||||
ib._private.handle = nil
|
|
||||||
ib._private.image = surf
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
---Apply RsvgHandle for given imagebox widget
|
|
||||||
local function set_handle(ib, handle)
|
|
||||||
local dim = handle:get_dimensions()
|
|
||||||
local is_handle_valid = dim.width > 0 and dim.height > 0
|
|
||||||
if not is_handle_valid then return end
|
|
||||||
|
|
||||||
ib._private.default = { width = dim.width, height = dim.height }
|
|
||||||
ib._private.handle = handle
|
|
||||||
ib._private.image = nil
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
---Try to load some image object from file then apply it to imagebox.
|
|
||||||
---@tparam table ib Imagebox
|
|
||||||
---@tparam string file Image file name
|
|
||||||
---@tparam function image_loader Function to load image object from file
|
|
||||||
---@tparam function image_setter Function to set image object to imagebox
|
|
||||||
---@treturn boolean True if image was successfully applied
|
|
||||||
local function load_and_apply(ib, file, image_loader, image_setter)
|
|
||||||
local image_applied
|
|
||||||
local object = image_loader(file)
|
|
||||||
if object then
|
|
||||||
image_applied = image_setter(ib, object)
|
|
||||||
end
|
|
||||||
return image_applied
|
|
||||||
end
|
|
||||||
|
|
||||||
--- The image rendered by the `imagebox`.
|
--- The image rendered by the `imagebox`.
|
||||||
--
|
--
|
||||||
-- It can can be any of the following:
|
-- It can can be any of the following:
|
||||||
|
@ -242,7 +321,10 @@ end
|
||||||
function imagebox:set_image(image)
|
function imagebox:set_image(image)
|
||||||
local setup_succeed
|
local setup_succeed
|
||||||
|
|
||||||
if type(image) == "userdata" then
|
-- Keep the original to prevent the cache from being GCed.
|
||||||
|
self._private.original_image = image
|
||||||
|
|
||||||
|
if type(image) == "userdata" and not (Rsvg and Rsvg.Handle:is_type_of(image)) then
|
||||||
-- This function is not documented to handle userdata objects, but
|
-- This function is not documented to handle userdata objects, but
|
||||||
-- historically it did, and it did by just assuming they refer to a
|
-- historically it did, and it did by just assuming they refer to a
|
||||||
-- cairo surface.
|
-- cairo surface.
|
||||||
|
@ -259,7 +341,8 @@ function imagebox:set_image(image)
|
||||||
end
|
end
|
||||||
elseif Rsvg and Rsvg.Handle:is_type_of(image) then
|
elseif Rsvg and Rsvg.Handle:is_type_of(image) then
|
||||||
-- try to apply given rsvg handle
|
-- try to apply given rsvg handle
|
||||||
setup_succeed = set_handle(self, image)
|
rsvg_handle_cache[image] = rsvg_handle_cache[image] or {}
|
||||||
|
setup_succeed = set_handle(self, image, rsvg_handle_cache[image])
|
||||||
elseif cairo.Surface:is_type_of(image) then
|
elseif cairo.Surface:is_type_of(image) then
|
||||||
-- try to apply given cairo surface
|
-- try to apply given cairo surface
|
||||||
setup_succeed = set_surface(self, image)
|
setup_succeed = set_surface(self, image)
|
||||||
|
@ -311,23 +394,126 @@ function imagebox:set_clip_shape(clip_shape, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Should the image be resized to fit into the available space?
|
--- Should the image be resized to fit into the available space?
|
||||||
|
--
|
||||||
|
-- Note that `upscale` and `downscale` can affect the value of `resize`.
|
||||||
|
-- If conflicting values are passed to the constructor, then the result
|
||||||
|
-- is undefined.
|
||||||
|
--
|
||||||
-- @DOC_wibox_widget_imagebox_resize_EXAMPLE@
|
-- @DOC_wibox_widget_imagebox_resize_EXAMPLE@
|
||||||
-- @property resize
|
-- @property resize
|
||||||
-- @propemits true false
|
-- @propemits true false
|
||||||
-- @tparam boolean resize
|
-- @tparam boolean resize
|
||||||
|
|
||||||
--- Should the image be resized to fit into the available space?
|
--- Allow the image to be upscaled (made bigger).
|
||||||
-- @tparam boolean allowed If `false`, the image will be clipped, else it will
|
--
|
||||||
-- be resized to fit into the available space.
|
-- Note that `upscale` and `downscale` can affect the value of `resize`.
|
||||||
-- @method set_resize
|
-- If conflicting values are passed to the constructor, then the result
|
||||||
-- @hidden
|
-- is undefined.
|
||||||
|
--
|
||||||
|
-- @DOC_wibox_widget_imagebox_upscale_EXAMPLE@
|
||||||
|
-- @property upscale
|
||||||
|
-- @tparam boolean upscale
|
||||||
|
-- @see downscale
|
||||||
|
-- @see resize
|
||||||
|
|
||||||
|
--- Allow the image to be downscaled (made smaller).
|
||||||
|
--
|
||||||
|
-- Note that `upscale` and `downscale` can affect the value of `resize`.
|
||||||
|
-- If conflicting values are passed to the constructor, then the result
|
||||||
|
-- is undefined.
|
||||||
|
--
|
||||||
|
-- @DOC_wibox_widget_imagebox_downscale_EXAMPLE@
|
||||||
|
-- @property downscale
|
||||||
|
-- @tparam boolean downscale
|
||||||
|
-- @see upscale
|
||||||
|
-- @see resize
|
||||||
|
|
||||||
|
--- Set the SVG CSS stylesheet.
|
||||||
|
--
|
||||||
|
-- If the image is an SVG (vector graphics), this property allows to set
|
||||||
|
-- a CSS stylesheet. It can be used to set colors and much more.
|
||||||
|
--
|
||||||
|
-- Note that this property is a string, not a path. If the stylesheet is
|
||||||
|
-- stored on disk, read the content first.
|
||||||
|
--
|
||||||
|
--@DOC_wibox_widget_imagebox_stylesheet_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @property stylesheet
|
||||||
|
-- @tparam string stylesheet
|
||||||
|
-- @propemits true false
|
||||||
|
|
||||||
|
--- Set the SVG DPI (dot per inch).
|
||||||
|
--
|
||||||
|
-- Force a specific DPI when rendering the `.svg`. For other file formats,
|
||||||
|
-- this does nothing.
|
||||||
|
--
|
||||||
|
-- It can either be a number of a table containing the `x` and `y` keys.
|
||||||
|
--
|
||||||
|
-- Please note that DPI and `resize` can "fight" each other and end up
|
||||||
|
-- making the image smaller instead of bigger.
|
||||||
|
--
|
||||||
|
--@DOC_wibox_widget_imagebox_dpi_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @property dpi
|
||||||
|
-- @tparam number|table dpi
|
||||||
|
-- @propemits true false
|
||||||
|
-- @see auto_dpi
|
||||||
|
|
||||||
|
--- Use the object DPI when rendering the SVG.
|
||||||
|
--
|
||||||
|
-- By default, the SVG are interpreted as-is. When this property is set,
|
||||||
|
-- the screen DPI will be passed to the SVG renderer. Depending on which
|
||||||
|
-- tool was used to create the `.svg`, this may do nothing at all. However,
|
||||||
|
-- for example, if the `.svg` uses `<text>` elements and doesn't have an
|
||||||
|
-- hardcoded stylesheet, the result will differ.
|
||||||
|
--
|
||||||
|
-- @property auto_dpi
|
||||||
|
-- @tparam[opt=false] boolean auto_dpi
|
||||||
|
-- @propemits true false
|
||||||
|
-- @see dpi
|
||||||
|
|
||||||
|
for _, prop in ipairs {"stylesheet", "dpi", "auto_dpi"} do
|
||||||
|
imagebox["set_" .. prop] = function(self, value)
|
||||||
|
-- It will be set in :fit and :draw. The handle is shared
|
||||||
|
-- by multiple imagebox, so it cannot be set just once.
|
||||||
|
self._private[prop] = value
|
||||||
|
|
||||||
|
self:emit_signal("widget::redraw_needed")
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
self:emit_signal("property::" .. prop)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function imagebox:set_resize(allowed)
|
function imagebox:set_resize(allowed)
|
||||||
self._private.resize_forbidden = not allowed
|
self._private.resize = allowed
|
||||||
|
|
||||||
|
if allowed then
|
||||||
|
self._private.downscale = true
|
||||||
|
self._private.upscale = true
|
||||||
|
self:emit_signal("property::downscale", allowed)
|
||||||
|
self:emit_signal("property::upscale", allowed)
|
||||||
|
end
|
||||||
|
|
||||||
self:emit_signal("widget::redraw_needed")
|
self:emit_signal("widget::redraw_needed")
|
||||||
self:emit_signal("widget::layout_changed")
|
self:emit_signal("widget::layout_changed")
|
||||||
self:emit_signal("property::resize", allowed)
|
self:emit_signal("property::resize", allowed)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for _, prop in ipairs {"downscale", "upscale" } do
|
||||||
|
imagebox["set_" .. prop] = function(self, allowed)
|
||||||
|
self._private[prop] = allowed
|
||||||
|
|
||||||
|
if self._private.resize ~= (self._private.upscale or self._private.downscale) then
|
||||||
|
self._private.resize = self._private.upscale or self._private.downscale
|
||||||
|
self:emit_signal("property::resize", self._private.resize)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:emit_signal("widget::redraw_needed")
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
self:emit_signal("property::"..prop, allowed)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Set the horizontal fit policy.
|
--- Set the horizontal fit policy.
|
||||||
--
|
--
|
||||||
-- Valid values are:
|
-- Valid values are:
|
||||||
|
@ -506,12 +692,14 @@ local function new(image, resize_allowed, clip_shape, ...)
|
||||||
local ret = base.make_widget(nil, nil, {enable_properties = true})
|
local ret = base.make_widget(nil, nil, {enable_properties = true})
|
||||||
|
|
||||||
gtable.crush(ret, imagebox, true)
|
gtable.crush(ret, imagebox, true)
|
||||||
|
ret._private.resize = true
|
||||||
|
|
||||||
if image then
|
if image then
|
||||||
ret:set_image(image)
|
ret:set_image(image)
|
||||||
end
|
end
|
||||||
|
|
||||||
if resize_allowed ~= nil then
|
if resize_allowed ~= nil then
|
||||||
ret:set_resize(resize_allowed)
|
ret.resize = resize_allowed
|
||||||
end
|
end
|
||||||
|
|
||||||
ret._private.clip_shape = clip_shape
|
ret._private.clip_shape = clip_shape
|
||||||
|
|
7
root.c
7
root.c
|
@ -481,6 +481,11 @@ luaA_root_wallpaper(lua_State *L)
|
||||||
{
|
{
|
||||||
if(lua_gettop(L) == 1)
|
if(lua_gettop(L) == 1)
|
||||||
{
|
{
|
||||||
|
/* Avoid `error()s` down the line. If this happens during
|
||||||
|
* initialization, AwesomeWM can be stuck in an infinite loop */
|
||||||
|
if(lua_isnil(L, -1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
cairo_pattern_t *pattern = (cairo_pattern_t *)lua_touserdata(L, -1);
|
cairo_pattern_t *pattern = (cairo_pattern_t *)lua_touserdata(L, -1);
|
||||||
lua_pushboolean(L, root_set_wallpaper(pattern));
|
lua_pushboolean(L, root_set_wallpaper(pattern));
|
||||||
/* Don't return the wallpaper, it's too easy to get memleaks */
|
/* Don't return the wallpaper, it's too easy to get memleaks */
|
||||||
|
@ -602,7 +607,7 @@ const struct luaL_Reg awesome_root_methods[] =
|
||||||
{ "cursor", luaA_root_cursor },
|
{ "cursor", luaA_root_cursor },
|
||||||
{ "fake_input", luaA_root_fake_input },
|
{ "fake_input", luaA_root_fake_input },
|
||||||
{ "drawins", luaA_root_drawins },
|
{ "drawins", luaA_root_drawins },
|
||||||
{ "wallpaper", luaA_root_wallpaper },
|
{ "_wallpaper", luaA_root_wallpaper },
|
||||||
{ "size", luaA_root_size },
|
{ "size", luaA_root_size },
|
||||||
{ "size_mm", luaA_root_size_mm },
|
{ "size_mm", luaA_root_size_mm },
|
||||||
{ "tags", luaA_root_tags },
|
{ "tags", luaA_root_tags },
|
||||||
|
|
|
@ -115,22 +115,40 @@ describe("gears.filesystem", function()
|
||||||
assert.is_true(test_b == "a.png"
|
assert.is_true(test_b == "a.png"
|
||||||
or test_b == "b.jpg")
|
or test_b == "b.jpg")
|
||||||
|
|
||||||
|
-- Any file found (selected extensions)
|
||||||
|
local test_c = gfs.get_random_file_from_dir(root .. "filesystem_tests", {".png", ".jpg"})
|
||||||
|
assert.is_true(test_c == "a.png"
|
||||||
|
or test_c == "b.jpg")
|
||||||
|
|
||||||
|
-- Test absolute paths.
|
||||||
|
local test_d = gfs.get_random_file_from_dir(root .. "filesystem_tests", {".png", ".jpg"}, true)
|
||||||
|
assert.is_true(test_d == root .. "filesystem_tests/a.png"
|
||||||
|
or test_d == root .. "filesystem_tests/b.jpg")
|
||||||
|
|
||||||
|
-- Make sure the paths are generated correctly.
|
||||||
|
assert.is_nil(test_d:match("//"))
|
||||||
|
|
||||||
-- "." in filename test cases with extensions
|
-- "." in filename test cases with extensions
|
||||||
local test_c = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {"ext"})
|
local test_e = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {"ext"})
|
||||||
assert.is_true(test_c == "filename.ext"
|
assert.is_true(test_e == "filename.ext"
|
||||||
or test_c == ".filename.ext"
|
or test_e == ".filename.ext"
|
||||||
or test_c == "file.name.ext"
|
or test_e == "file.name.ext"
|
||||||
or test_c == ".file.name.ext")
|
or test_e == ".file.name.ext")
|
||||||
|
|
||||||
-- "." in filename test cases with no extensions
|
-- "." in filename test cases with no extensions
|
||||||
local test_d = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {""})
|
local test_f = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {""})
|
||||||
assert.is_true(test_d == "filename"
|
assert.is_true(test_f == "filename"
|
||||||
or test_d == "filename."
|
or test_f == "filename."
|
||||||
or test_d == "filename.ext."
|
or test_f == "filename.ext."
|
||||||
or test_d == ".filename"
|
or test_f == ".filename"
|
||||||
or test_d == ".filename."
|
or test_f == ".filename."
|
||||||
or test_d == "file.name.ext."
|
or test_f == "file.name.ext."
|
||||||
or test_d == ".file.name.ext.")
|
or test_f == ".file.name.ext.")
|
||||||
|
|
||||||
|
-- Test invalid directories.
|
||||||
|
local test_g = gfs.get_random_file_from_dir(root .. "filesystem_tests/fake_dir")
|
||||||
|
assert.is_nil(test_g)
|
||||||
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -85,7 +85,9 @@ function(escape_string variable content escaped_content line_prefix)
|
||||||
if(variable MATCHES "--DOC_HIDE_ALL")
|
if(variable MATCHES "--DOC_HIDE_ALL")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
string(REGEX REPLACE "\n" ";" var_lines "${variable}")
|
|
||||||
|
string(REGEX REPLACE ";" ";" var_lines "${variable}")
|
||||||
|
string(REGEX REPLACE "\n" ";" var_lines "${var_lines}")
|
||||||
|
|
||||||
set(tmp_output ${content})
|
set(tmp_output ${content})
|
||||||
set(section OFF)
|
set(section OFF)
|
||||||
|
@ -101,7 +103,7 @@ function(escape_string variable content escaped_content line_prefix)
|
||||||
|
|
||||||
# Pick lines that are not specified to be hidden
|
# Pick lines that are not specified to be hidden
|
||||||
if((NOT LINE MATCHES "^.*--DOC_[A-Z]+") AND (NOT section))
|
if((NOT LINE MATCHES "^.*--DOC_[A-Z]+") AND (NOT section))
|
||||||
set(tmp_output ${tmp_output}\n${DOC_LINE_PREFIX}${line_prefix}${LINE})
|
set(tmp_output "${tmp_output}\n${DOC_LINE_PREFIX}${line_prefix}${LINE}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# If we found a start marker previously, look for an end marker.
|
# If we found a start marker previously, look for an end marker.
|
||||||
|
@ -256,6 +258,12 @@ function(run_test test_path namespace escaped_content)
|
||||||
"\n${expected_output}"
|
"\n${expected_output}"
|
||||||
"${TEST_DOC_CONTENT}" TEST_DOC_CONTENT " "
|
"${TEST_DOC_CONTENT}" TEST_DOC_CONTENT " "
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add a <br/> to prevent markdown from merging the usage and output
|
||||||
|
# into a single block.
|
||||||
|
if(tmp_content MATCHES "--DOC_NO_USAGE")
|
||||||
|
set(TEST_DOC_CONTENT "${TEST_DOC_CONTENT}\n${DOC_LINE_PREFIX} **Usage example:**")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
escape_string(
|
escape_string(
|
||||||
"\n${expected_output}"
|
"\n${expected_output}"
|
||||||
|
@ -347,7 +355,7 @@ foreach(file ${test_files})
|
||||||
# variable during the pre-processing.
|
# variable during the pre-processing.
|
||||||
# While at it, replace \" created by CMake by ',
|
# While at it, replace \" created by CMake by ',
|
||||||
# " wont work in <code>.
|
# " wont work in <code>.
|
||||||
string(REPLACE "\"" "'" ${TEST_NAME} ${ESCAPED_CODE_EXAMPLE})
|
string(REPLACE "\"" """ ${TEST_NAME} ${ESCAPED_CODE_EXAMPLE})
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ local gears = require("gears")
|
||||||
local naughty = require("naughty")
|
local naughty = require("naughty")
|
||||||
local wibox = require("wibox")
|
local wibox = require("wibox")
|
||||||
local beautiful = require("beautiful") --DOC_HIDE
|
local beautiful = require("beautiful") --DOC_HIDE
|
||||||
|
local assets = require("beautiful.theme_assets")
|
||||||
local look = require("_default_look")
|
local look = require("_default_look")
|
||||||
|
|
||||||
screen[1]._resize {width = 640, height = 480}
|
screen[1]._resize {width = 640, height = 480}
|
||||||
|
@ -17,6 +18,78 @@ screen[1]._resize {width = 640, height = 480}
|
||||||
|
|
||||||
local c = client.gen_fake {hide_first=true}
|
local c = client.gen_fake {hide_first=true}
|
||||||
|
|
||||||
|
-- Don't use `awful.wallpaper` to avoid rasterizing the background.
|
||||||
|
|
||||||
|
local wallpaper = wibox {
|
||||||
|
below = true,
|
||||||
|
shape = gears.shape.octogon,
|
||||||
|
visible = true,
|
||||||
|
bg = "#00000000",
|
||||||
|
}
|
||||||
|
|
||||||
|
awful.placement.maximize(wallpaper)
|
||||||
|
|
||||||
|
wallpaper.widget = wibox.widget {
|
||||||
|
fit = function(_, _, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:translate(width - 80, 60)
|
||||||
|
assets.gen_awesome_name(
|
||||||
|
cr, height - 40, "#ffffff", beautiful.bg_normal, beautiful.bg_normal
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
}
|
||||||
|
|
||||||
|
local p = awful.popup {
|
||||||
|
widget = wibox.widget {
|
||||||
|
{ text = "Item", widget = wibox.widget.textbox },
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = "Selected",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
bg = beautiful.bg_highlight,
|
||||||
|
widget = wibox.container.background
|
||||||
|
},
|
||||||
|
{ text = "Item", widget = wibox.widget.textbox },
|
||||||
|
forced_width = 100,
|
||||||
|
widget = wibox.layout.fixed.vertical
|
||||||
|
},
|
||||||
|
border_color = beautiful.border_color,
|
||||||
|
border_width = 1,
|
||||||
|
x = 50,
|
||||||
|
y = 200,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
p:_apply_size_now()
|
||||||
|
require("gears.timer").run_delayed_calls_now()
|
||||||
|
p._drawable._do_redraw()
|
||||||
|
|
||||||
|
require("gears.timer").delayed_call(function()
|
||||||
|
-- Get the 4th textbox
|
||||||
|
local list = p:find_widgets(30, 40)
|
||||||
|
mouse.coords {x= 120, y=225}
|
||||||
|
mouse.push_history()
|
||||||
|
local textboxinstance = list[#list]
|
||||||
|
|
||||||
|
local p2 = awful.popup {
|
||||||
|
widget = wibox.widget {
|
||||||
|
text = "Submenu",
|
||||||
|
forced_height = 20,
|
||||||
|
forced_width = 70,
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
border_color = beautiful.border_color,
|
||||||
|
preferred_positions = "right",
|
||||||
|
border_width = 1,
|
||||||
|
}
|
||||||
|
p2:move_next_to(textboxinstance, "right")
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
c:geometry {
|
c:geometry {
|
||||||
x = 50,
|
x = 50,
|
||||||
y = 350,
|
y = 350,
|
||||||
|
@ -97,6 +170,7 @@ wibox {
|
||||||
width = 50,
|
width = 50,
|
||||||
height = 50,
|
height = 50,
|
||||||
shape = gears.shape.octogon,
|
shape = gears.shape.octogon,
|
||||||
|
visible = true,
|
||||||
color = "#0000ff",
|
color = "#0000ff",
|
||||||
x = 570,
|
x = 570,
|
||||||
y = 410,
|
y = 410,
|
||||||
|
@ -188,13 +262,17 @@ create_info("awful.tooltip", 30, 130, 100, 30)
|
||||||
create_info("awful.popup", 450, 240, 100, 30)
|
create_info("awful.popup", 450, 240, 100, 30)
|
||||||
create_info("naughty.layout.box", 255, 110, 130, 30)
|
create_info("naughty.layout.box", 255, 110, 130, 30)
|
||||||
create_info("Standard `wibox`", 420, 420, 130, 30)
|
create_info("Standard `wibox`", 420, 420, 130, 30)
|
||||||
|
create_info("awful.wallpaper", 420, 330, 110, 30)
|
||||||
|
create_info("awful.menu", 60, 270, 80, 30)
|
||||||
|
|
||||||
create_line(150, 10, 150, 55)
|
create_line(150, 10, 150, 55)
|
||||||
create_line(75, 100, 75, 135)
|
create_line(75, 100, 75, 135)
|
||||||
create_line(545, 432, 575, 432)
|
create_line(545, 432, 575, 432)
|
||||||
create_line(500, 165, 500, 245)
|
create_line(500, 165, 500, 245)
|
||||||
create_line(390, 250, 450, 250)
|
create_line(380, 250, 450, 250)
|
||||||
create_line(190, 365, 255, 365)
|
create_line(190, 365, 255, 365)
|
||||||
create_line(320, 60, 320, 110)
|
create_line(320, 60, 320, 110)
|
||||||
|
create_line(525, 345, 570, 345)
|
||||||
|
create_line(100, 240, 100, 270)
|
||||||
|
|
||||||
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||||
|
|
|
@ -58,11 +58,23 @@ if not rawget(screen, "no_outline") then
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Draw the wallpaper (if any).
|
||||||
|
if root._wallpaper_pattern then
|
||||||
|
cr:set_source_rgb(1,0,0)
|
||||||
|
cr:set_line_width(2)
|
||||||
|
cr:rectangle(0, 0, root.size())
|
||||||
|
cr:stroke()
|
||||||
|
cr:set_source(root._wallpaper_pattern)
|
||||||
|
cr:rectangle(0, 0, root.size())
|
||||||
|
cr:fill()
|
||||||
|
cr:paint()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
cr:set_line_width(beautiful.border_width/2)
|
cr:set_line_width(beautiful.border_width/2)
|
||||||
cr:set_source(color(beautiful.border_color))
|
cr:set_source(color(beautiful.border_color))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local rect = {x1 = 0 ,y1 = 0 , x2 = 0 , y2 = 0}
|
local rect = {x1 = 0 ,y1 = 0 , x2 = 0 , y2 = 0}
|
||||||
|
|
||||||
-- Get the region with wiboxes
|
-- Get the region with wiboxes
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE_ALL
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 161, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 322, y = 0, width = 160, height = 96}
|
||||||
|
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = screen[1],
|
||||||
|
bg = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now()
|
|
@ -0,0 +1,50 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE_ALL
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 161, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 322, y = 0, width = 160, height = 96}
|
||||||
|
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
local wall = awful.wallpaper {
|
||||||
|
screen = screen[1],
|
||||||
|
bg = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wall:add_screen(screen[2])
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,51 @@
|
||||||
|
--DOC_GEN_IMAGE
|
||||||
|
--DOC_HIDE_ALL
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 161, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 322, y = 0, width = 160, height = 96}
|
||||||
|
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
local wall = awful.wallpaper {
|
||||||
|
screen = screen[1],
|
||||||
|
bg = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wall:add_screen(screen[3])
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now()
|
|
@ -0,0 +1,30 @@
|
||||||
|
--DOC_NO_USAGE --DOC_GEN_IMAGE
|
||||||
|
local awful = { --DOC_HIDE
|
||||||
|
wallpaper = require("awful.wallpaper"), --DOC_HIDE
|
||||||
|
placement = require("awful.placement"), --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require("beautiful") --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196} --DOC_HIDE
|
||||||
|
local s = screen[1] --DOC_HIDE
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
bg = "#000000",
|
||||||
|
widget = {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
image = beautiful.awesome_icon,
|
||||||
|
resize = false,
|
||||||
|
point = awful.placement.bottom_right,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.manual,
|
||||||
|
},
|
||||||
|
margins = 5,
|
||||||
|
widget = wibox.container.margin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,57 @@
|
||||||
|
--DOC_GEN_IMAGE
|
||||||
|
--DOC_HIDE_START
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 161, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 322, y = 0, width = 160, height = 96}
|
||||||
|
require("_default_look")
|
||||||
|
--DOC_HIDE_END
|
||||||
|
|
||||||
|
for s in screen do
|
||||||
|
local dpi = s.index * 100
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
dpi = dpi,
|
||||||
|
widget = wibox.widget {
|
||||||
|
--DOC_HIDE_START
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
--DOC_HIDE_END
|
||||||
|
text = "DPI: " .. dpi,
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
}, --DOC_HIDE
|
||||||
|
widget = wibox.layout.stack --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,21 @@
|
||||||
|
--DOC_NO_USAGE --DOC_GEN_IMAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196} --DOC_HIDE
|
||||||
|
local s = screen[1] --DOC_HIDE
|
||||||
|
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
bg = {
|
||||||
|
type = "linear" ,
|
||||||
|
from = { 0, 0 },
|
||||||
|
to = { 0, 240 },
|
||||||
|
stops = {
|
||||||
|
{ 0, "#0000ff" },
|
||||||
|
{ 1, "#ff0000" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,22 @@
|
||||||
|
--DOC_NO_USAGE --DOC_GEN_IMAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196} --DOC_HIDE
|
||||||
|
local s = screen[1] --DOC_HIDE
|
||||||
|
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
bg = {
|
||||||
|
type = "radial",
|
||||||
|
from = { 160, 98, 20 },
|
||||||
|
to = { 160, 98, 120 },
|
||||||
|
stops = {
|
||||||
|
{ 0 , "#ff0000" },
|
||||||
|
{ 0.5, "#00ff00" },
|
||||||
|
{ 1 , "#0000ff" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,24 @@
|
||||||
|
--DOC_NO_USAGE --DOC_GEN_IMAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require("beautiful") --DOC_HIDE
|
||||||
|
local s = screen[1] --DOC_HIDE
|
||||||
|
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
widget = {
|
||||||
|
{
|
||||||
|
image = beautiful.wallpaper,
|
||||||
|
resize = true,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
valign = "center",
|
||||||
|
halign = "center",
|
||||||
|
tiled = false,
|
||||||
|
widget = wibox.container.tile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
--DOC_NO_USAGE --DOC_GEN_IMAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require("beautiful") --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196} --DOC_HIDE
|
||||||
|
local s = screen[1] --DOC_HIDE
|
||||||
|
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
bg = "#0000ff",
|
||||||
|
widget = {
|
||||||
|
{
|
||||||
|
image = beautiful.wallpaper,
|
||||||
|
resize = true,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
valign = "center",
|
||||||
|
halign = "center",
|
||||||
|
tiled = false,
|
||||||
|
widget = wibox.container.tile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,20 @@
|
||||||
|
--DOC_NO_USAGE --DOC_GEN_IMAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require("beautiful") --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196} --DOC_HIDE
|
||||||
|
local s = screen[1] --DOC_HIDE
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
widget = {
|
||||||
|
horizontal_fit_policy = "fit",
|
||||||
|
vertical_fit_policy = "fit",
|
||||||
|
image = beautiful.wallpaper,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_GEN_OUTPUT
|
||||||
|
--DOC_HIDE_START
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196}
|
||||||
|
require("_default_look")
|
||||||
|
--DOC_HIDE_END
|
||||||
|
|
||||||
|
-- Add some padding to the first screen.
|
||||||
|
screen[1].padding = {
|
||||||
|
left = 30,
|
||||||
|
right = 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
local wall = awful.wallpaper {
|
||||||
|
screen = screen[1],
|
||||||
|
honor_workarea = true,
|
||||||
|
honor_padding = true,
|
||||||
|
bg = "#222222",
|
||||||
|
uncovered_areas_color = "#ff0000",
|
||||||
|
widget = wibox.widget {
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
local radius = math.min(width, height)/2
|
||||||
|
cr:arc(width/2, height/2, radius, 0, 2 * math.pi)
|
||||||
|
cr:set_source(gears.color {
|
||||||
|
type = "radial",
|
||||||
|
from = { width/2, radius, 20 },
|
||||||
|
to = { width/2, radius, 120 },
|
||||||
|
stops = {
|
||||||
|
{ 0, "#0000ff" },
|
||||||
|
{ 1, "#ff0000" },
|
||||||
|
{ 1, "#000000" },
|
||||||
|
}
|
||||||
|
})
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--DOC_HIDE_START
|
||||||
|
require("gears.timer").run_delayed_calls_now()
|
||||||
|
--DOC_HIDE_END
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
-- Areas due to the padding and the wibar (workarea).
|
||||||
|
for _, area in ipairs(wall.uncovered_areas) do
|
||||||
|
print("Uncovered area:", area.x, area.y, area.width, area.height)
|
||||||
|
end
|
|
@ -0,0 +1,3 @@
|
||||||
|
Uncovered area: 0 0 30 196
|
||||||
|
Uncovered area: 0 0 320 14
|
||||||
|
Uncovered area: 310 0 10 196
|
|
@ -0,0 +1,86 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_GEN_OUTPUT --DOC_NO_USAGE
|
||||||
|
--DOC_HIDE_START
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 97, width = 96, height = 160}
|
||||||
|
screen._add_screen {x = 97, y = 129, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 258, y = 97,width = 96, height = 160}
|
||||||
|
|
||||||
|
screen._add_screen {x = 370, y = 0,width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 402, y = 97,width = 96, height = 160}
|
||||||
|
screen._add_screen {x = 370, y = 258,width = 160, height = 96}
|
||||||
|
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
local walls = {}
|
||||||
|
|
||||||
|
--DOC_HIDE_END
|
||||||
|
|
||||||
|
local function custom_panning_area(wallpaper)
|
||||||
|
return {
|
||||||
|
x = wallpaper.screens[1].geometry.x + 50,
|
||||||
|
y = wallpaper.screens[2].geometry.y + 50,
|
||||||
|
width = 96,
|
||||||
|
height = 96,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
--DOC_HIDE_START
|
||||||
|
for i=0, 1 do
|
||||||
|
walls[i+1] = awful.wallpaper {
|
||||||
|
screens = {
|
||||||
|
screen[i*3 + 1],
|
||||||
|
screen[i*3 + 2],
|
||||||
|
screen[i*3 + 3],
|
||||||
|
},
|
||||||
|
bg = "#222222",
|
||||||
|
panning_area = custom_panning_area,
|
||||||
|
uncovered_areas_color = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now()
|
||||||
|
|
||||||
|
|
||||||
|
--DOC_HIDE_END
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
-- Areas due to the padding and the wibar (workarea).
|
||||||
|
for k, wall in ipairs(walls) do
|
||||||
|
for _, area in ipairs(wall.uncovered_areas) do
|
||||||
|
print("Uncovered wallpaper #".. k .." area:", area.x, area.y, area.width, area.height)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,60 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE_ALL --DOC_NO_USAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 97, width = 96, height = 160}
|
||||||
|
screen._add_screen {x = 97, y = 129, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 258, y = 97,width = 96, height = 160}
|
||||||
|
|
||||||
|
screen._add_screen {x = 370, y = 0,width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 402, y = 97,width = 96, height = 160}
|
||||||
|
screen._add_screen {x = 370, y = 258,width = 160, height = 96}
|
||||||
|
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
for i=0, 1 do
|
||||||
|
awful.wallpaper {
|
||||||
|
screens = {
|
||||||
|
screen[i*3 + 1],
|
||||||
|
screen[i*3 + 2],
|
||||||
|
screen[i*3 + 3],
|
||||||
|
},
|
||||||
|
bg = "#222222",
|
||||||
|
panning_area = "inner",
|
||||||
|
uncovered_areas_color = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,60 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE_ALL --DOC_NO_USAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 97, width = 96, height = 160}
|
||||||
|
screen._add_screen {x = 97, y = 129, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 258, y = 97,width = 96, height = 160}
|
||||||
|
|
||||||
|
screen._add_screen {x = 370, y = 0,width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 402, y = 97,width = 96, height = 160}
|
||||||
|
screen._add_screen {x = 370, y = 258,width = 160, height = 96}
|
||||||
|
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
for i=0, 1 do
|
||||||
|
awful.wallpaper {
|
||||||
|
screens = {
|
||||||
|
screen[i*3 + 1],
|
||||||
|
screen[i*3 + 2],
|
||||||
|
screen[i*3 + 3],
|
||||||
|
},
|
||||||
|
bg = "#222222",
|
||||||
|
panning_area = "inner_horizontal",
|
||||||
|
uncovered_areas_color = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,60 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE_ALL --DOC_NO_USAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 97, width = 96, height = 160}
|
||||||
|
screen._add_screen {x = 97, y = 129, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 258, y = 97,width = 96, height = 160}
|
||||||
|
|
||||||
|
screen._add_screen {x = 370, y = 0,width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 402, y = 97,width = 96, height = 160}
|
||||||
|
screen._add_screen {x = 370, y = 258,width = 160, height = 96}
|
||||||
|
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
for i=0, 1 do
|
||||||
|
awful.wallpaper {
|
||||||
|
screens = {
|
||||||
|
screen[i*3 + 1],
|
||||||
|
screen[i*3 + 2],
|
||||||
|
screen[i*3 + 3],
|
||||||
|
},
|
||||||
|
bg = "#222222",
|
||||||
|
panning_area = "inner_vertical",
|
||||||
|
uncovered_areas_color = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,58 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE_ALL --DOC_NO_USAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 97, width = 96, height = 160}
|
||||||
|
screen._add_screen {x = 97, y = 129, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 258, y = 97,width = 96, height = 160}
|
||||||
|
|
||||||
|
screen._add_screen {x = 370, y = 0,width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 402, y = 97,width = 96, height = 160}
|
||||||
|
screen._add_screen {x = 370, y = 258,width = 160, height = 96}
|
||||||
|
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
for i=0, 1 do
|
||||||
|
awful.wallpaper {
|
||||||
|
screens = {
|
||||||
|
screen[i*3 + 1],
|
||||||
|
screen[i*3 + 2],
|
||||||
|
screen[i*3 + 3],
|
||||||
|
},
|
||||||
|
bg = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,53 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_NO_USAGE
|
||||||
|
--DOC_HIDE_START
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 161, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 322, y = 0, width = 160, height = 96}
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
-- There is 3 screens. This will add the wallpaper to the last 2.
|
||||||
|
local wall = awful.wallpaper {
|
||||||
|
screens = screen,
|
||||||
|
bg = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now()
|
||||||
|
--DOC_HIDE_END
|
||||||
|
wall:remove_screen(screen[1])
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,58 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_NO_USAGE
|
||||||
|
--DOC_HIDE_START
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 161, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 322, y = 0, width = 160, height = 96}
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
-- There is 3 screens. This will add the wallpaper to the last 2.
|
||||||
|
awful.wallpaper {
|
||||||
|
screens = screen,
|
||||||
|
bg = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now()
|
||||||
|
--DOC_HIDE_END
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = screen[1],
|
||||||
|
bg = "#00ffff",
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,54 @@
|
||||||
|
--DOC_GEN_IMAGE
|
||||||
|
--DOC_HIDE_START
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 161, y = 0, width = 160, height = 96}
|
||||||
|
screen._add_screen {x = 322, y = 0, width = 160, height = 96}
|
||||||
|
require("_default_look")
|
||||||
|
--DOC_HIDE_END
|
||||||
|
|
||||||
|
-- There is 3 screens. This will add the wallpaper to the last 2.
|
||||||
|
awful.wallpaper {
|
||||||
|
screens = {
|
||||||
|
screen[2],
|
||||||
|
screen[3],
|
||||||
|
},
|
||||||
|
bg = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color("#0000ff"))
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:line_to(0, 0)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
cr:set_source(gears.color("#ff00ff"))
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(0, height)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:close_path()
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "Center",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,45 @@
|
||||||
|
--DOC_NO_USAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local gears = {timer = require("gears.timer"), filesystem = require("gears.filesystem")}--DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196} --DOC_HIDE
|
||||||
|
|
||||||
|
-- The "request::wallpaper" section is already in the default
|
||||||
|
-- `rc.lua`, replace it with this.
|
||||||
|
screen.connect_signal("request::wallpaper", function(s)
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
bg = "#0000ff",
|
||||||
|
widget = {
|
||||||
|
{
|
||||||
|
image = gears.filesystem.get_random_file_from_dir(
|
||||||
|
"path/to/dir",
|
||||||
|
{".jpg", ".png", ".svg"},
|
||||||
|
true
|
||||||
|
),
|
||||||
|
resize = true,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
valign = "center",
|
||||||
|
halign = "center",
|
||||||
|
tiled = false,
|
||||||
|
widget = wibox.container.tile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
-- **Somewhere else** in the code, **not** in the `request::wallpaper` handler.
|
||||||
|
gears.timer {
|
||||||
|
timeout = 1800,
|
||||||
|
autostart = true,
|
||||||
|
callback = function()
|
||||||
|
for s in screen do
|
||||||
|
s:emit_signal("request::wallpaper")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,36 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_NO_USAGE --DOC_HIDE_START
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196}
|
||||||
|
--DOC_HIDE_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local image = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'..
|
||||||
|
'<svg width="190" height="60">'..
|
||||||
|
'<rect x="10" y="10" width="50" height="50" />'..
|
||||||
|
'<rect x="70" y="10" width="50" height="50" class="my_class" />'..
|
||||||
|
'<rect x="130" y="10" width="50" height="50" id="my_id" />'..
|
||||||
|
'</svg>'
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
local stylesheet = "" ..
|
||||||
|
"rect { fill: #ffff00; } "..
|
||||||
|
".my_class { fill: #00ff00; } "..
|
||||||
|
"#my_id { fill: #0000ff; }"
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = screen[1], --DOC_HIDE
|
||||||
|
widget = wibox.widget {
|
||||||
|
forced_height = 60, --DOC_HIDE
|
||||||
|
forced_width = 190, --DOC_HIDE
|
||||||
|
stylesheet = stylesheet,
|
||||||
|
image = image,
|
||||||
|
widget = wibox.widget.imagebox
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,27 @@
|
||||||
|
--DOC_NO_USAGE --DOC_GEN_IMAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require("beautiful") --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196} --DOC_HIDE
|
||||||
|
local s = screen[1] --DOC_HIDE
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
bg = "#0000ff",
|
||||||
|
widget = {
|
||||||
|
{
|
||||||
|
image = beautiful.awesome_icon,
|
||||||
|
resize = false,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
horizontal_spacing = 5,
|
||||||
|
vertical_spacing = 5,
|
||||||
|
valign = "top",
|
||||||
|
halign = "left",
|
||||||
|
tiled = true,
|
||||||
|
widget = wibox.container.tile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,30 @@
|
||||||
|
--DOC_NO_USAGE --DOC_GEN_IMAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local gears = { shape = require("gears.shape") } --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196} --DOC_HIDE
|
||||||
|
local s = screen[1] --DOC_HIDE
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
bg = "#0000ff",
|
||||||
|
widget = {
|
||||||
|
{
|
||||||
|
shape = gears.shape.star,
|
||||||
|
forced_width = 30,
|
||||||
|
forced_height = 30,
|
||||||
|
widget = wibox.widget.separator,
|
||||||
|
},
|
||||||
|
horizontal_spacing = 5,
|
||||||
|
vertical_spacing = 5,
|
||||||
|
vertical_crop = true,
|
||||||
|
horizontal_crop = true,
|
||||||
|
valign = "center",
|
||||||
|
halign = "center",
|
||||||
|
tiled = true,
|
||||||
|
widget = wibox.container.tile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,82 @@
|
||||||
|
--DOC_NO_USAGE --DOC_GEN_IMAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local gears = {color = require("gears.color") } --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196} --DOC_HIDE
|
||||||
|
local s = screen[1] --DOC_HIDE
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
widget = wibox.widget {
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
cr:set_source(gears.color {
|
||||||
|
type = 'linear',
|
||||||
|
from = { 0, 0 },
|
||||||
|
to = { 0, height },
|
||||||
|
stops = {
|
||||||
|
{ 0 , '#030d27' },
|
||||||
|
{ 0.75, '#3a183f' },
|
||||||
|
{ 0.75, '#000000' },
|
||||||
|
{ 1 , '#222222' }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
cr:paint()
|
||||||
|
|
||||||
|
-- Clip the first 33% of the screen
|
||||||
|
cr:rectangle(0,0, width, height/3)
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
-- Clip-out some increasingly large sections of add the sun "bars"
|
||||||
|
for i=0, 6 do
|
||||||
|
cr:rectangle(0, height*.28 + i*(height*.055 + i/2), width, height*.055)
|
||||||
|
end
|
||||||
|
cr:clip()
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
-- Draw the sun
|
||||||
|
cr:set_source(gears.color {
|
||||||
|
type = 'linear' ,
|
||||||
|
from = { 0, 0 },
|
||||||
|
to = { 0, height },
|
||||||
|
stops = {
|
||||||
|
{ 0, '#f0d64f' },
|
||||||
|
{ 1, '#e484c6' }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
cr:arc(width/2, height/2, height*.35, 0, math.pi*2)
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
-- Draw the grid
|
||||||
|
local lines = width/8
|
||||||
|
cr:reset_clip()
|
||||||
|
cr:set_line_width(0.5)
|
||||||
|
cr:set_source(gears.color("#8922a3"))
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
for i=1, lines do
|
||||||
|
cr:move_to((-width) + i* math.sin(i * (math.pi/(lines*2)))*30, height)
|
||||||
|
cr:line_to(width/4 + i*((width/2)/lines), height*0.75 + 2)
|
||||||
|
cr:stroke()
|
||||||
|
end
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
for i=1, 5 do
|
||||||
|
cr:move_to(0, height*0.75 + i*10 + i*2)
|
||||||
|
cr:line_to(width, height*0.75 + i*10 + i*2)
|
||||||
|
cr:stroke()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,48 @@
|
||||||
|
--DOC_NO_USAGE --DOC_GEN_IMAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
|
||||||
|
math.randomseed(1) --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196} --DOC_HIDE
|
||||||
|
|
||||||
|
local function binary()
|
||||||
|
local ret = {}
|
||||||
|
|
||||||
|
for _=1, 15 do
|
||||||
|
for _=1, 57 do
|
||||||
|
table.insert(ret, math.random() > 0.5 and 1 or 0)
|
||||||
|
end
|
||||||
|
table.insert(ret, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = screen[1], --DOC_HIDE
|
||||||
|
bg = "#000000",
|
||||||
|
fg = "#55ff5577",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
markup = "<tt><b>[SYSTEM FAILURE]</b></tt>",
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
fg = "#00ff00",
|
||||||
|
widget = wibox.container.background
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrap = "word",
|
||||||
|
text = binary(),
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now() --DOC_HIDE
|
|
@ -0,0 +1,56 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE_ALL
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") }
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gears = {color = require("gears.color") }
|
||||||
|
|
||||||
|
screen._track_workarea = true
|
||||||
|
screen[1]._resize {x = 0, y = 0, width = 320, height = 196}
|
||||||
|
screen._add_screen {x = 330, y = 0, width = 320, height = 196}
|
||||||
|
|
||||||
|
require("_default_look")
|
||||||
|
|
||||||
|
screen.connect_signal("request::wallpaper", function(s)
|
||||||
|
awful.wallpaper {
|
||||||
|
screen = s,
|
||||||
|
honor_workarea = s.index == 2,
|
||||||
|
bg = "#222222",
|
||||||
|
widget = wibox.widget {
|
||||||
|
{
|
||||||
|
fit = function(_, width, height)
|
||||||
|
return width, height
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr, width, height)
|
||||||
|
local radius = math.min(width, height)/2
|
||||||
|
cr:arc(width/2, height/2, radius, 0, 2 * math.pi)
|
||||||
|
cr:set_source(gears.color {
|
||||||
|
type = "radial",
|
||||||
|
from = { width/2, radius, 20 },
|
||||||
|
to = { width/2, radius, 120 },
|
||||||
|
stops = {
|
||||||
|
{ 0, "#0000ff" },
|
||||||
|
{ 1, "#ff0000" },
|
||||||
|
{ 1, "#000000" },
|
||||||
|
}
|
||||||
|
})
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
widget = wibox.widget.base.make_widget()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "honor_workarea = " .. (s.index == 2 and "true" or "false"),
|
||||||
|
valign = "center",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox,
|
||||||
|
},
|
||||||
|
widget = wibox.layout.stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now()
|
||||||
|
|
||||||
|
for s in screen do
|
||||||
|
s:emit_signal("request::wallpaper", s)
|
||||||
|
end
|
||||||
|
|
||||||
|
require("gears.timer").run_delayed_calls_now()
|
|
@ -3,87 +3,98 @@ local wibox = require("wibox")
|
||||||
local beautiful = require("beautiful")
|
local beautiful = require("beautiful")
|
||||||
require("_date")
|
require("_date")
|
||||||
|
|
||||||
-- Create the same number of tags as the default config
|
local ret = nil
|
||||||
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, screen[1], awful.layout.layouts[1])
|
|
||||||
local mykeyboardlayout = awful.widget.keyboardlayout()
|
|
||||||
local mytextclock = wibox.widget.textclock()
|
|
||||||
local mylayoutbox = awful.widget.layoutbox(screen[1])
|
|
||||||
local mytaglist = awful.widget.taglist(screen[1], awful.widget.taglist.filter.all, {})
|
|
||||||
local mytasklist = awful.widget.tasklist(screen[1], awful.widget.tasklist.filter.currenttags, {})
|
|
||||||
local mypromptbox = wibox.widget.textbox("")
|
|
||||||
|
|
||||||
local wb = awful.wibar { position = "top" }
|
for i = 1, screen.count() do
|
||||||
wb:setup {
|
local s = screen[i]
|
||||||
layout = wibox.layout.align.horizontal,
|
|
||||||
{
|
|
||||||
layout = wibox.layout.fixed.horizontal,
|
|
||||||
{
|
|
||||||
image = beautiful.awesome_icon,
|
|
||||||
widget = wibox.widget.imagebox,
|
|
||||||
},
|
|
||||||
mytaglist,
|
|
||||||
mypromptbox,
|
|
||||||
},
|
|
||||||
mytasklist,
|
|
||||||
{
|
|
||||||
layout = wibox.layout.fixed.horizontal,
|
|
||||||
mykeyboardlayout,
|
|
||||||
{
|
|
||||||
image = beautiful.awesome_icon,
|
|
||||||
widget = wibox.widget.imagebox,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image = beautiful.awesome_icon,
|
|
||||||
widget = wibox.widget.imagebox,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image = beautiful.awesome_icon,
|
|
||||||
widget = wibox.widget.imagebox,
|
|
||||||
},
|
|
||||||
mytextclock,
|
|
||||||
mylayoutbox,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
-- Create the same number of tags as the default config
|
||||||
|
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])
|
||||||
|
local mykeyboardlayout = awful.widget.keyboardlayout()
|
||||||
|
local mytextclock = wibox.widget.textclock()
|
||||||
|
local mylayoutbox = awful.widget.layoutbox(s)
|
||||||
|
local mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, {})
|
||||||
|
local mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, {})
|
||||||
|
local mypromptbox = wibox.widget.textbox("")
|
||||||
|
|
||||||
client.connect_signal("request::titlebars", function(c)
|
local wb = awful.wibar {
|
||||||
local top_titlebar = awful.titlebar(c, {
|
position = "top",
|
||||||
height = 20,
|
screen = s
|
||||||
bg_normal = beautiful.bg_normal,
|
|
||||||
})
|
|
||||||
|
|
||||||
top_titlebar : setup {
|
|
||||||
{ -- Left
|
|
||||||
awful.titlebar.widget.iconwidget(c),
|
|
||||||
layout = wibox.layout.fixed.horizontal
|
|
||||||
},
|
|
||||||
{ -- Middle
|
|
||||||
{ -- Title
|
|
||||||
align = "center",
|
|
||||||
widget = awful.titlebar.widget.titlewidget(c)
|
|
||||||
},
|
|
||||||
layout = wibox.layout.flex.horizontal
|
|
||||||
},
|
|
||||||
{ -- Right
|
|
||||||
awful.titlebar.widget.floatingbutton (c),
|
|
||||||
awful.titlebar.widget.maximizedbutton(c),
|
|
||||||
awful.titlebar.widget.stickybutton (c),
|
|
||||||
awful.titlebar.widget.ontopbutton (c),
|
|
||||||
awful.titlebar.widget.closebutton (c),
|
|
||||||
layout = wibox.layout.fixed.horizontal()
|
|
||||||
},
|
|
||||||
layout = wibox.layout.align.horizontal
|
|
||||||
}
|
}
|
||||||
end)
|
|
||||||
|
wb:setup {
|
||||||
|
layout = wibox.layout.align.horizontal,
|
||||||
|
{
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
{
|
||||||
|
image = beautiful.awesome_icon,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
mytaglist,
|
||||||
|
mypromptbox,
|
||||||
|
},
|
||||||
|
mytasklist,
|
||||||
|
{
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
mykeyboardlayout,
|
||||||
|
{
|
||||||
|
image = beautiful.awesome_icon,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image = beautiful.awesome_icon,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image = beautiful.awesome_icon,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
mytextclock,
|
||||||
|
mylayoutbox,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
client.connect_signal("request::titlebars", function(c)
|
||||||
|
local top_titlebar = awful.titlebar(c, {
|
||||||
|
height = 20,
|
||||||
|
bg_normal = beautiful.bg_normal,
|
||||||
|
})
|
||||||
|
|
||||||
|
top_titlebar : setup {
|
||||||
|
{ -- Left
|
||||||
|
awful.titlebar.widget.iconwidget(c),
|
||||||
|
layout = wibox.layout.fixed.horizontal
|
||||||
|
},
|
||||||
|
{ -- Middle
|
||||||
|
{ -- Title
|
||||||
|
align = "center",
|
||||||
|
widget = awful.titlebar.widget.titlewidget(c)
|
||||||
|
},
|
||||||
|
layout = wibox.layout.flex.horizontal
|
||||||
|
},
|
||||||
|
{ -- Right
|
||||||
|
awful.titlebar.widget.floatingbutton (c),
|
||||||
|
awful.titlebar.widget.maximizedbutton(c),
|
||||||
|
awful.titlebar.widget.stickybutton (c),
|
||||||
|
awful.titlebar.widget.ontopbutton (c),
|
||||||
|
awful.titlebar.widget.closebutton (c),
|
||||||
|
layout = wibox.layout.fixed.horizontal()
|
||||||
|
},
|
||||||
|
layout = wibox.layout.align.horizontal
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
ret = ret or {
|
||||||
|
mykeyboardlayout = mykeyboardlayout,
|
||||||
|
mytextclock = mytextclock ,
|
||||||
|
mylayoutbox = mylayoutbox ,
|
||||||
|
mytaglist = mytaglist ,
|
||||||
|
mytasklist = mytasklist ,
|
||||||
|
mywibox = wb ,
|
||||||
|
mypromptbox = mypromptbox ,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
require("gears.timer").run_delayed_calls_now()
|
require("gears.timer").run_delayed_calls_now()
|
||||||
|
|
||||||
return {
|
return ret
|
||||||
mykeyboardlayout = mykeyboardlayout,
|
|
||||||
mytextclock = mytextclock ,
|
|
||||||
mylayoutbox = mylayoutbox ,
|
|
||||||
mytaglist = mytaglist ,
|
|
||||||
mytasklist = mytasklist ,
|
|
||||||
mywibox = wb ,
|
|
||||||
mypromptbox = mypromptbox ,
|
|
||||||
}
|
|
||||||
|
|
|
@ -118,6 +118,10 @@ awesome._modifiers = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function awesome._get_key_name(key)
|
||||||
|
return key
|
||||||
|
end
|
||||||
|
|
||||||
awesome._active_modifiers = {}
|
awesome._active_modifiers = {}
|
||||||
|
|
||||||
return awesome
|
return awesome
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
local root = {_tags={}}
|
local root = {_tags={}}
|
||||||
|
|
||||||
local gtable = require("gears.table")
|
local gtable = require("gears.table")
|
||||||
|
local cairo = require( "lgi" ).cairo
|
||||||
|
|
||||||
|
|
||||||
function root:tags()
|
function root:tags()
|
||||||
return root._tags
|
return root._tags
|
||||||
|
@ -169,6 +171,24 @@ function root._write_string(string, c)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function root._wallpaper(pattern)
|
||||||
|
if not pattern then return root._wallpaper_surface end
|
||||||
|
|
||||||
|
-- Make a copy because `:finish()` is called by `root.wallpaper` to avoid
|
||||||
|
-- a memory leak in the "real" backend.
|
||||||
|
local target = cairo.ImageSurface(cairo.Format.RGB32, root.size())
|
||||||
|
local cr = cairo.Context(target)
|
||||||
|
|
||||||
|
cr:set_source(pattern)
|
||||||
|
cr:rectangle(0, 0, root.size())
|
||||||
|
cr:fill()
|
||||||
|
|
||||||
|
root._wallpaper_pattern = cairo.Pattern.create_for_surface(target)
|
||||||
|
root._wallpaper_surface = target
|
||||||
|
|
||||||
|
return target
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function root.set_newindex_miss_handler(h)
|
function root.set_newindex_miss_handler(h)
|
||||||
rawset(root, "_ni_handler", h)
|
rawset(root, "_ni_handler", h)
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
--DOC_NO_USAGE
|
||||||
|
local awful = { wallpaper = require("awful.wallpaper") } --DOC_HIDE
|
||||||
|
|
||||||
|
local global_wallpaper = awful.wallpaper {
|
||||||
|
-- [...] your content
|
||||||
|
}
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
screen.connect_signal("request::wallpaper", function()
|
||||||
|
-- `screen` is the global screen module. It is also a list of all screens.
|
||||||
|
global_wallpaper.screens = screen
|
||||||
|
end)
|
|
@ -0,0 +1,54 @@
|
||||||
|
--DOC_HIDE_ALL
|
||||||
|
--DOC_GEN_IMAGE
|
||||||
|
local parent = ...
|
||||||
|
local wibox = require( "wibox" )
|
||||||
|
local beautiful = require( "beautiful" )
|
||||||
|
|
||||||
|
local function cell_centered_widget(widget)
|
||||||
|
return wibox.widget {
|
||||||
|
widget,
|
||||||
|
valign = 'center',
|
||||||
|
halign = 'center',
|
||||||
|
content_fill_vertical = false,
|
||||||
|
content_fill_horizontal = false,
|
||||||
|
widget = wibox.container.place
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function build_ib(size, resize)
|
||||||
|
return cell_centered_widget(wibox.widget {
|
||||||
|
{
|
||||||
|
downscale = resize,
|
||||||
|
upscale = true,
|
||||||
|
forced_height = size,
|
||||||
|
forced_width = size,
|
||||||
|
image = beautiful.awesome_icon,
|
||||||
|
widget = wibox.widget.imagebox
|
||||||
|
},
|
||||||
|
forced_width = size + 2,
|
||||||
|
forced_height = size + 2,
|
||||||
|
color = beautiful.border_color,
|
||||||
|
margins = 1,
|
||||||
|
widget = wibox.container.margin
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local l = wibox.widget {
|
||||||
|
homogeneous = false,
|
||||||
|
spacing = 5,
|
||||||
|
layout = wibox.layout.grid,
|
||||||
|
}
|
||||||
|
parent:add(l)
|
||||||
|
|
||||||
|
l:add_widget_at(cell_centered_widget(wibox.widget.textbox('downscale = true')), 1, 1)
|
||||||
|
l:add_widget_at(cell_centered_widget(wibox.widget.textbox('downscale = false')), 2, 1)
|
||||||
|
l:add_widget_at(cell_centered_widget(wibox.widget.textbox('imagebox size')), 3, 1)
|
||||||
|
|
||||||
|
for i,size in ipairs({16, 32, 64}) do
|
||||||
|
l:add_widget_at(build_ib(size, true), 1, i + 1)
|
||||||
|
l:add_widget_at(build_ib(size, false), 2, i + 1)
|
||||||
|
l:add_widget_at(cell_centered_widget(wibox.widget.textbox(size..'x'..size)), 3, i + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,48 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE
|
||||||
|
local parent = ... --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
|
||||||
|
local l = wibox.layout { --DOC_HIDE
|
||||||
|
forced_width = 360, --DOC_HIDE
|
||||||
|
spacing = 5, --DOC_HIDE
|
||||||
|
layout = wibox.layout.flex.vertical --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local image = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'..
|
||||||
|
'<svg width="2in" height="1in">'..
|
||||||
|
'<rect height="0.1in" width="0.1in" style="fill:red;" />'..
|
||||||
|
'<text x="10" y="32" width="150" style="font-size: 0.1in;">Hello world!</text>'..
|
||||||
|
'</svg>'
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
for _, dpi in ipairs {100, 200, 300} do
|
||||||
|
local row = wibox.layout { --DOC_HIDE
|
||||||
|
spacing = 5, --DOC_HIDE
|
||||||
|
layout = wibox.layout.fixed.horizontal --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
|
||||||
|
row:add(wibox.widget { --DOC_HIDE
|
||||||
|
markup = "<b>dpi = "..dpi.."</b>", --DOC_HIDE
|
||||||
|
forced_width = 80, --DOC_HIDE
|
||||||
|
widget = wibox.widget.textbox --DOC_HIDE
|
||||||
|
}) --DOC_HIDE
|
||||||
|
|
||||||
|
local w = wibox.widget {
|
||||||
|
image = image,
|
||||||
|
dpi = dpi,
|
||||||
|
resize = false,
|
||||||
|
forced_height = 70,
|
||||||
|
forced_width = 150,
|
||||||
|
widget = wibox.widget.imagebox
|
||||||
|
}
|
||||||
|
|
||||||
|
row:add(w) --DOC_HIDE
|
||||||
|
l:add(row) --DOC_HIDE
|
||||||
|
end
|
||||||
|
|
||||||
|
parent:add(l) --DOC_HIDE
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,31 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE
|
||||||
|
local parent = ... --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
|
||||||
|
local image = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'..
|
||||||
|
'<svg width="190" height="60">'..
|
||||||
|
'<rect x="10" y="10" width="50" height="50" />'..
|
||||||
|
'<rect x="70" y="10" width="50" height="50" class="my_class" />'..
|
||||||
|
'<rect x="130" y="10" width="50" height="50" id="my_id" />'..
|
||||||
|
'</svg>'
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
local stylesheet = "" ..
|
||||||
|
"rect { fill: #ffff00; } "..
|
||||||
|
".my_class { fill: #00ff00; } "..
|
||||||
|
"#my_id { fill: #0000ff; }"
|
||||||
|
|
||||||
|
--DOC_NEWLINE
|
||||||
|
|
||||||
|
local w = wibox.widget {
|
||||||
|
forced_height = 60, --DOC_HIDE
|
||||||
|
forced_width = 190, --DOC_HIDE
|
||||||
|
stylesheet = stylesheet,
|
||||||
|
image = image,
|
||||||
|
widget = wibox.widget.imagebox
|
||||||
|
}
|
||||||
|
|
||||||
|
parent:add(w) --DOC_HIDE
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,54 @@
|
||||||
|
--DOC_HIDE_ALL
|
||||||
|
--DOC_GEN_IMAGE
|
||||||
|
local parent = ...
|
||||||
|
local wibox = require( "wibox" )
|
||||||
|
local beautiful = require( "beautiful" )
|
||||||
|
|
||||||
|
local function cell_centered_widget(widget)
|
||||||
|
return wibox.widget {
|
||||||
|
widget,
|
||||||
|
valign = 'center',
|
||||||
|
halign = 'center',
|
||||||
|
content_fill_vertical = false,
|
||||||
|
content_fill_horizontal = false,
|
||||||
|
widget = wibox.container.place
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function build_ib(size, resize)
|
||||||
|
return cell_centered_widget(wibox.widget {
|
||||||
|
{
|
||||||
|
upscale = resize,
|
||||||
|
downscale = true,
|
||||||
|
forced_height = size,
|
||||||
|
forced_width = size,
|
||||||
|
image = beautiful.awesome_icon,
|
||||||
|
widget = wibox.widget.imagebox
|
||||||
|
},
|
||||||
|
forced_width = size + 2,
|
||||||
|
forced_height = size + 2,
|
||||||
|
color = beautiful.border_color,
|
||||||
|
margins = 1,
|
||||||
|
widget = wibox.container.margin
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local l = wibox.widget {
|
||||||
|
homogeneous = false,
|
||||||
|
spacing = 5,
|
||||||
|
layout = wibox.layout.grid,
|
||||||
|
}
|
||||||
|
parent:add(l)
|
||||||
|
|
||||||
|
l:add_widget_at(cell_centered_widget(wibox.widget.textbox('upscale = true')), 1, 1)
|
||||||
|
l:add_widget_at(cell_centered_widget(wibox.widget.textbox('upscale = false')), 2, 1)
|
||||||
|
l:add_widget_at(cell_centered_widget(wibox.widget.textbox('imagebox size')), 3, 1)
|
||||||
|
|
||||||
|
for i,size in ipairs({16, 32, 64}) do
|
||||||
|
l:add_widget_at(build_ib(size, true), 1, i + 1)
|
||||||
|
l:add_widget_at(build_ib(size, false), 2, i + 1)
|
||||||
|
l:add_widget_at(cell_centered_widget(wibox.widget.textbox(size..'x'..size)), 3, i + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -68,7 +68,10 @@ local function add_client(args)
|
||||||
local c = data.c
|
local c = data.c
|
||||||
if not c then
|
if not c then
|
||||||
c = client.get()[1]
|
c = client.get()[1]
|
||||||
assert(c.name == name)
|
assert(c.name == name,
|
||||||
|
"Expected "..name.." got "..c.name.." there is "
|
||||||
|
..#client.get().." clients"
|
||||||
|
)
|
||||||
data.c = c
|
data.c = c
|
||||||
end
|
end
|
||||||
local test = args.test or default_test
|
local test = args.test or default_test
|
||||||
|
|
|
@ -5,6 +5,13 @@ local wp = require("gears.wallpaper")
|
||||||
local color = require("gears.color")
|
local color = require("gears.color")
|
||||||
local cairo = require( "lgi" ).cairo
|
local cairo = require( "lgi" ).cairo
|
||||||
local surface = require("gears.surface")
|
local surface = require("gears.surface")
|
||||||
|
local awall = require("awful.wallpaper")
|
||||||
|
local beautiful = require("beautiful")
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local gdebug = require("gears.debug")
|
||||||
|
|
||||||
|
-- This test suite is for a deprecated module.
|
||||||
|
gdebug.deprecate = function() end
|
||||||
|
|
||||||
local steps = {}
|
local steps = {}
|
||||||
|
|
||||||
|
@ -54,85 +61,236 @@ table.insert(steps, function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
table.insert(steps, function()
|
table.insert(steps, function()
|
||||||
wp.fit(img, screen[1], "#00ff00")
|
wp.fit(img, screen[1], "#00ff00")
|
||||||
|
|
||||||
-- There is a delayed call for the last call, let it be processed before
|
-- There is a delayed call for the last call, let it be processed before
|
||||||
-- adding more
|
-- adding more
|
||||||
return true
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
table.insert(steps, function()
|
table.insert(steps, function()
|
||||||
wp.centered(img, nil, nil)
|
wp.centered(img, nil, nil)
|
||||||
wp.centered(img, screen[1], nil)
|
wp.centered(img, screen[1], nil)
|
||||||
|
|
||||||
-- There is a delayed call for the last call, let it be processed before
|
-- There is a delayed call for the last call, let it be processed before
|
||||||
-- adding more
|
-- adding more
|
||||||
return true
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
table.insert(steps, function()
|
table.insert(steps, function()
|
||||||
wp.centered(img, screen[1], "#00ff00")
|
wp.centered(img, screen[1], "#00ff00")
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
table.insert(steps, function()
|
table.insert(steps, function()
|
||||||
wp.maximized(img, nil, nil, nil)
|
wp.maximized(img, nil, nil, nil)
|
||||||
|
|
||||||
-- There is a delayed call for the last call, let it be processed before
|
-- There is a delayed call for the last call, let it be processed before
|
||||||
-- adding more
|
-- adding more
|
||||||
return true
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
table.insert(steps, function()
|
table.insert(steps, function()
|
||||||
wp.maximized(img, screen[1], nil, nil)
|
wp.maximized(img, screen[1], nil, nil)
|
||||||
|
|
||||||
-- There is a delayed call for the last call, let it be processed before
|
-- There is a delayed call for the last call, let it be processed before
|
||||||
-- adding more
|
-- adding more
|
||||||
return true
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
table.insert(steps, function()
|
table.insert(steps, function()
|
||||||
|
wp.maximized(img, screen[1], false, nil)
|
||||||
|
wp.maximized(img, screen[1], true, nil)
|
||||||
|
|
||||||
wp.maximized(img, screen[1], false, nil)
|
-- There is a delayed call for the last call, let it be processed before
|
||||||
wp.maximized(img, screen[1], true, nil)
|
-- adding more
|
||||||
|
return true
|
||||||
-- There is a delayed call for the last call, let it be processed before
|
|
||||||
-- adding more
|
|
||||||
return true
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
table.insert(steps, function()
|
table.insert(steps, function()
|
||||||
|
wp.maximized(img, screen[1], false, {x=10, y= 10})
|
||||||
|
wp.maximized(img, screen[1], true, {x=10, y= 10})
|
||||||
|
|
||||||
wp.maximized(img, screen[1], false, {x=10, y= 10})
|
return true
|
||||||
wp.maximized(img, screen[1], true, {x=10, y= 10})
|
|
||||||
|
|
||||||
return true
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
table.insert(steps, function()
|
table.insert(steps, function()
|
||||||
wp.tiled(img, nil, nil)
|
wp.tiled(img, nil, nil)
|
||||||
wp.tiled(img, screen[1], nil)
|
wp.tiled(img, screen[1], nil)
|
||||||
|
|
||||||
-- There is a delayed call for the last call, let it be processed before
|
-- There is a delayed call for the last call, let it be processed before
|
||||||
-- adding more
|
-- adding more
|
||||||
return true
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
table.insert(steps, function()
|
table.insert(steps, function()
|
||||||
wp.tiled(img, screen[1], {x=10, y= 10})
|
wp.tiled(img, screen[1], {x=10, y= 10})
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
table.insert(steps, function()
|
table.insert(steps, function()
|
||||||
for _, c in ipairs(colors) do
|
for _, c in ipairs(colors) do
|
||||||
wp.set(c)
|
wp.set(c)
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- Make sure passing `nil` doesn't crash Awesome.
|
||||||
|
table.insert(steps, function()
|
||||||
|
root._wallpaper(nil)
|
||||||
|
root.wallpaper(nil)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
local walls = setmetatable({}, {__mode = "v"})
|
||||||
|
|
||||||
|
-- Test awful.wallpaper garbage collection.
|
||||||
|
table.insert(steps, function()
|
||||||
|
walls["first"] = awall {
|
||||||
|
screen = screen[1],
|
||||||
|
widget = {
|
||||||
|
{
|
||||||
|
image = beautiful.wallpaper,
|
||||||
|
upscale = true,
|
||||||
|
downscale = true,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
valign = "center",
|
||||||
|
halign = "center",
|
||||||
|
tiled = false,
|
||||||
|
widget = wibox.container.tile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collectgarbage("collect")
|
||||||
|
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
table.insert(steps, function(count)
|
||||||
|
if count < 3 then
|
||||||
|
collectgarbage("collect")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(walls["first"])
|
||||||
|
|
||||||
|
walls["second"] = awall {
|
||||||
|
screen = screen[1],
|
||||||
|
widget = {
|
||||||
|
{
|
||||||
|
image = beautiful.wallpaper,
|
||||||
|
upscale = true,
|
||||||
|
downscale = true,
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
},
|
||||||
|
valign = "center",
|
||||||
|
halign = "center",
|
||||||
|
tiled = false,
|
||||||
|
widget = wibox.container.tile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
local repaint_called, paint_width, paint_height = false, nil, nil
|
||||||
|
|
||||||
|
-- Test setting "after the fact"
|
||||||
|
table.insert(steps, function(count)
|
||||||
|
if count < 3 then
|
||||||
|
collectgarbage("collect")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(walls["second"])
|
||||||
|
assert(not walls["first"])
|
||||||
|
|
||||||
|
local real_repaint = walls["second"].repaint
|
||||||
|
|
||||||
|
walls["second"].repaint = function(self)
|
||||||
|
repaint_called = true
|
||||||
|
real_repaint(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
walls["second"].widget = wibox.widget {
|
||||||
|
fit = function(_, w, h)
|
||||||
|
return w, h
|
||||||
|
end,
|
||||||
|
draw = function(self, ctx, cr2, width, height)
|
||||||
|
cr2:set_source_rgba(1, 0, 0, 0.5)
|
||||||
|
cr2:rectangle(0, 0, width/2, height/2)
|
||||||
|
cr2:fill()
|
||||||
|
paint_width, paint_height = width, height
|
||||||
|
assert((not self.dpi) and ctx.dpi)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
walls["second"].bg = "#0000ff"
|
||||||
|
walls["second"].fg = "#00ff00"
|
||||||
|
|
||||||
|
assert(repaint_called)
|
||||||
|
|
||||||
|
-- This needs to happen after this event loop to avoid
|
||||||
|
-- painting the wallpaper many time in a row.
|
||||||
|
assert(not paint_width)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
table.insert(steps, function()
|
||||||
|
assert(walls["second"])
|
||||||
|
|
||||||
|
assert(paint_width == screen[1].geometry.width)
|
||||||
|
assert(paint_height == screen[1].geometry.height)
|
||||||
|
|
||||||
|
repaint_called = false
|
||||||
|
paint_width, paint_height = nil, nil
|
||||||
|
|
||||||
|
-- Disable new wallpaper creation to prevent request::wallpaper from
|
||||||
|
-- replacing the wall.
|
||||||
|
local constructor = getmetatable(awall).__call
|
||||||
|
setmetatable(awall, {__call = function() end})
|
||||||
|
|
||||||
|
screen[1]:fake_resize(
|
||||||
|
10, 10, math.floor(screen[1].geometry.width/2), math.floor(screen[1].geometry.height/2)
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(paint_height ~= screen[1].geometry.height)
|
||||||
|
assert(repaint_called)
|
||||||
|
setmetatable(awall, {__call = constructor})
|
||||||
|
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
table.insert(steps, function(count)
|
||||||
|
if count == 1 then return end
|
||||||
|
|
||||||
|
print(paint_width, paint_height, screen[1].geometry.width, screen[1].geometry.height)
|
||||||
|
assert(paint_width == screen[1].geometry.width)
|
||||||
|
assert(paint_height == screen[1].geometry.height)
|
||||||
|
|
||||||
|
walls["second"].dpi = 123
|
||||||
|
assert(walls["second"].dpi == 123)
|
||||||
|
walls["second"]:detach()
|
||||||
|
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
table.insert(steps, function(count)
|
||||||
|
if count < 3 then
|
||||||
|
collectgarbage("collect")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(not walls["second"])
|
||||||
|
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
runner.run_steps(steps)
|
runner.run_steps(steps)
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ local xresources = require("beautiful.xresources")
|
||||||
local rnotification = require("ruled.notification")
|
local rnotification = require("ruled.notification")
|
||||||
local dpi = xresources.apply_dpi
|
local dpi = xresources.apply_dpi
|
||||||
local xrdb = xresources.get_current_theme()
|
local xrdb = xresources.get_current_theme()
|
||||||
|
local gdebug = require("gears.debug")
|
||||||
local gfs = require("gears.filesystem")
|
local gfs = require("gears.filesystem")
|
||||||
local themes_path = gfs.get_themes_dir()
|
local themes_path = gfs.get_themes_dir()
|
||||||
|
|
||||||
|
@ -126,10 +127,40 @@ local wallpaper_alt_fg = xrdb.color12
|
||||||
if not is_dark_bg then
|
if not is_dark_bg then
|
||||||
wallpaper_bg, wallpaper_fg = wallpaper_fg, wallpaper_bg
|
wallpaper_bg, wallpaper_fg = wallpaper_fg, wallpaper_bg
|
||||||
end
|
end
|
||||||
theme.wallpaper = function(s)
|
|
||||||
return theme_assets.wallpaper(wallpaper_bg, wallpaper_fg, wallpaper_alt_fg, s)
|
local rsvg = pcall(function() return require("lgi").Rsvg end)
|
||||||
|
|
||||||
|
if rsvg then
|
||||||
|
local handle = require("lgi").Rsvg.Handle.new_from_file(
|
||||||
|
themes_path.."xresources/wallpaper.svg"
|
||||||
|
)
|
||||||
|
|
||||||
|
if handle then
|
||||||
|
handle:set_stylesheet([[
|
||||||
|
.normal {
|
||||||
|
fill: ]]..wallpaper_fg..[[;
|
||||||
|
}
|
||||||
|
.background {
|
||||||
|
fill: ]]..wallpaper_bg..[[;
|
||||||
|
stroke: ]]..wallpaper_bg..[[;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
fill: ]]..wallpaper_alt_fg..[[;
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
|
theme.wallpaper = handle
|
||||||
|
end
|
||||||
|
else
|
||||||
|
gdebug.print_warning("Could not load the wallpaper: librsvg is not installed.")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not theme.wallpaper then
|
||||||
|
theme.wallpaper = themes_path.."xresources/wallpaper.svg"
|
||||||
|
end
|
||||||
|
|
||||||
|
theme.wallpaper_bg = wallpaper_bg
|
||||||
|
|
||||||
-- Set different colors for urgent notifications.
|
-- Set different colors for urgent notifications.
|
||||||
rnotification.connect_signal('request::rules', function()
|
rnotification.connect_signal('request::rules', function()
|
||||||
rnotification.append_rule {
|
rnotification.append_rule {
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1280pt" height="720pt" viewBox="0 0 1280 720" version="1.1">
|
||||||
|
<rect x="0" y="0" width="1280" height="720" style="stroke:none;" class="background"/>
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(27.843137%,47.843137%,70.196078%);fill-opacity:1;" d="M 1152 72 L 1224 72 L 1224 144 L 1152 144 Z M 1152 72 " class="logo"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 0 24 L 48 24 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;" d="M 1152 156 L 1224 156 L 1224 228 L 1152 228 Z M 1152 156 " class="normal"/>
|
||||||
|
<path style="fill:none !important;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 24 48 L 48 48 L 48 72 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 24 84 L 24 132 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 48 84 L 48 132 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;" d="M 1152 240 L 1224 240 L 1224 312 L 1152 312 Z M 1152 240 " class="normal"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 24 192 L 72 192 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 24 216 L 72 216 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;" d="M 1152 324 L 1224 324 L 1224 396 L 1152 396 Z M 1152 324 " class="normal"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 24 276 L 72 276 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 0 300 L 48 300 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;" d="M 1152 408 L 1224 408 L 1224 480 L 1152 480 Z M 1152 408 " class="normal"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 36 360 L 36 384 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;" d="M 1152 492 L 1224 492 L 1224 564 L 1152 564 Z M 1152 492 " class="normal"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 24 444 L 24 492 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 48 444 L 48 492 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;" d="M 1152 576 L 1224 576 L 1224 648 L 1152 648 Z M 1152 576 " class="normal"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 24 528 L 72 528 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
<path style="fill:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;" d="M 24 552 L 72 552 " transform="matrix(1,0,0,1,1152,72)" class="background"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
Loading…
Reference in New Issue