From cefd4f843e7c86cc7eec8abfb3f7382277054cba Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 7 Sep 2021 16:32:59 -0700 Subject: [PATCH 01/26] gears.filesystem: Improve get_random_file_from_dir. Previously, only a filename was returned. Getting the path was inconvinient when used within a declarative construct. It was also misbehaving then the directory didn't exist. Finally, the extention list now accept extension names starting with a dot. --- lib/gears/filesystem.lua | 19 +++++++++++---- spec/gears/filesystem_spec.lua | 44 ++++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/lib/gears/filesystem.lua b/lib/gears/filesystem.lua index 42f94ec7..de58e1a7 100644 --- a/lib/gears/filesystem.lua +++ b/lib/gears/filesystem.lua @@ -172,28 +172,39 @@ end -- @tparam string path The directory to search. -- @tparam[opt] table exts Specific extensions to limit the search to. eg:`{ "jpg", "png" }` -- 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 --- 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 -function filesystem.get_random_file_from_dir(path, exts) +function filesystem.get_random_file_from_dir(path, exts, absolute_path) local files, valid_exts = {}, {} -- 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 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 if file:get_file_type() == "REGULAR" then local file_name = file:get_display_name() + if not exts or valid_exts[file_name:lower():match(".+%.(.*)$") or ""] then table.insert(files, file_name) end end end + if #files == 0 then return nil end + -- 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 return filesystem diff --git a/spec/gears/filesystem_spec.lua b/spec/gears/filesystem_spec.lua index d277aeac..3ad4f25c 100644 --- a/spec/gears/filesystem_spec.lua +++ b/spec/gears/filesystem_spec.lua @@ -115,22 +115,40 @@ describe("gears.filesystem", function() assert.is_true(test_b == "a.png" 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 - local test_c = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {"ext"}) - assert.is_true(test_c == "filename.ext" - or test_c == ".filename.ext" - or test_c == "file.name.ext" - or test_c == ".file.name.ext") + local test_e = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {"ext"}) + assert.is_true(test_e == "filename.ext" + or test_e == ".filename.ext" + or test_e == "file.name.ext" + or test_e == ".file.name.ext") -- "." in filename test cases with no extensions - local test_d = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {""}) - assert.is_true(test_d == "filename" - or test_d == "filename." - or test_d == "filename.ext." - or test_d == ".filename" - or test_d == ".filename." - or test_d == "file.name.ext." - or test_d == ".file.name.ext.") + local test_f = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {""}) + assert.is_true(test_f == "filename" + or test_f == "filename." + or test_f == "filename.ext." + or test_f == ".filename" + or test_f == ".filename." + or test_f == "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) From 5212f0634a180c779819f3ccabb4547aabac5f95 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 10 Sep 2021 15:45:49 -0700 Subject: [PATCH 02/26] imagebox: Add a `downscale` and `upscale` property. Previously, it was really hard to get the image to do one *or* the other. The `resize` property set both at the same time. While it could, this does not deprecate the old `resize` property since 99% of the user wan't to lock both. --- lib/wibox/widget/imagebox.lua | 83 ++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/lib/wibox/widget/imagebox.lua b/lib/wibox/widget/imagebox.lua index 060d8c42..5daf8001 100644 --- a/lib/wibox/widget/imagebox.lua +++ b/lib/wibox/widget/imagebox.lua @@ -80,7 +80,7 @@ function imagebox:draw(_, cr, width, 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. local aspects = { w = width / w, @@ -93,10 +93,14 @@ function imagebox:draw(_, cr, width, height) } for _, aspect in ipairs {"w", "h"} do - if policy[aspect] == "auto" then - aspects[aspect] = math.min(width / w, height / h) + if self._private.upscale == false and (w < width and h < height) then + aspects[aspect] = 1 + elseif self._private.downscale == false and (w >= width and h >= height) then + aspects[aspect] = 1 elseif policy[aspect] == "none" then aspects[aspect] = 1 + elseif policy[aspect] == "auto" then + aspects[aspect] = math.min(width / w, height / h) end end @@ -169,7 +173,15 @@ function imagebox:fit(_, width, height) if not self._private.default then return 0, 0 end 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) return w * aspect, h * aspect end @@ -311,23 +323,70 @@ function imagebox:set_clip_shape(clip_shape, ...) end --- 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@ -- @property resize -- @propemits true false -- @tparam boolean resize ---- Should the image be resized to fit into the available space? --- @tparam boolean allowed If `false`, the image will be clipped, else it will --- be resized to fit into the available space. --- @method set_resize --- @hidden +--- Allow the image to be upscaled (made bigger). +-- +-- 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_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 + 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::layout_changed") self:emit_signal("property::resize", allowed) 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. -- -- Valid values are: @@ -506,12 +565,14 @@ local function new(image, resize_allowed, clip_shape, ...) local ret = base.make_widget(nil, nil, {enable_properties = true}) gtable.crush(ret, imagebox, true) + ret._private.resize = true if image then ret:set_image(image) end + if resize_allowed ~= nil then - ret:set_resize(resize_allowed) + ret.resize = resize_allowed end ret._private.clip_shape = clip_shape From aa998db6260e56261e9c246f161ae9df52c450eb Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 10 Sep 2021 15:47:24 -0700 Subject: [PATCH 03/26] tests: Test the imagebox upscale and downscale properties. --- .../wibox/widget/imagebox/downscale.lua | 54 +++++++++++++++++++ .../wibox/widget/imagebox/upscale.lua | 54 +++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 tests/examples/wibox/widget/imagebox/downscale.lua create mode 100644 tests/examples/wibox/widget/imagebox/upscale.lua diff --git a/tests/examples/wibox/widget/imagebox/downscale.lua b/tests/examples/wibox/widget/imagebox/downscale.lua new file mode 100644 index 00000000..7b0f4f2c --- /dev/null +++ b/tests/examples/wibox/widget/imagebox/downscale.lua @@ -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 diff --git a/tests/examples/wibox/widget/imagebox/upscale.lua b/tests/examples/wibox/widget/imagebox/upscale.lua new file mode 100644 index 00000000..4c0a510a --- /dev/null +++ b/tests/examples/wibox/widget/imagebox/upscale.lua @@ -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 From 98dd78b777920540bfb0204ee49af6d5e6120e3d Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sun, 28 Apr 2019 23:49:47 -0400 Subject: [PATCH 04/26] awful: Add a wallpaper module. `gears.wallpaper` is a flat API (that doesn't even belong in gears) and is neither well integrated with the other AwesomeWM concepts, nor well documented or easy to understand for newcomers. This module adds an object oriented, declarative, module with properties for the most common wallpaper types. It also integrates with `awful.placement` and the `wibox` module. The design attempts to make the wallpaper a "wibox like" object like the titlebars. It is non-interactive, but still allows the widgets. Note that this is slow and should be avoided for dynamic content. It is why the widgets are never updated unless manually reloaded. The objects also attempt to be disposable rather than persistent. Thus they are immutable by default to prevent accidental abuse. Fix #3428 #2596 --- lib/awful/init.lua | 1 + lib/awful/wallpaper.lua | 857 +++++++++++++++++++++++++++++++++ tests/test-awful-placement.lua | 5 +- 3 files changed, 862 insertions(+), 1 deletion(-) create mode 100644 lib/awful/wallpaper.lua diff --git a/lib/awful/init.lua b/lib/awful/init.lua index cff95db1..d7ebbf81 100644 --- a/lib/awful/init.lua +++ b/lib/awful/init.lua @@ -35,6 +35,7 @@ local ret = { tooltip = require("awful.tooltip"); permissions = require("awful.permissions"); titlebar = require("awful.titlebar"); + wallpaper = require("awful.wallpaper"); rules = require("awful.rules"); popup = require("awful.popup"); spawn = require("awful.spawn"); diff --git a/lib/awful/wallpaper.lua b/lib/awful/wallpaper.lua new file mode 100644 index 00000000..6a0b040b --- /dev/null +++ b/lib/awful/wallpaper.lua @@ -0,0 +1,857 @@ +--------------------------------------------------------------------------- +--- 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 ned 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. +-- +-- @constructorfct awful.wallpaper +-- @tparam table args +-- @tparam wibox.widget args.widget The wallpaper widget. +-- @tparam number args.dpi The wallpaper DPI (dots per inch). +-- @tparam screen args.screen The wallpaper screen. +-- @tparam table args.screens A list of screen for this wallpaper. +-- @tparam gears.color args.bg The background color. +-- @tparam gears.color args.fg The foreground color. +-- @tparam gears.color args.uncovered_areas_color The color for the uncovered areas. +-- @tparam boolean args.honor_workarea Honor the workarea. +-- @tparam boolean args.honor_padding Honor the screen padding. +-- @tparam table args.uncovered_areas Returns the list of screen(s) area which won't be covered by the wallpaper. +-- @tparam 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}) diff --git a/tests/test-awful-placement.lua b/tests/test-awful-placement.lua index 007766de..19bec43a 100644 --- a/tests/test-awful-placement.lua +++ b/tests/test-awful-placement.lua @@ -68,7 +68,10 @@ local function add_client(args) local c = data.c if not c then 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 end local test = args.test or default_test From 82f54ab95c09dbbacd6e24b8a1ba5b2b7590ea67 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 3 May 2021 01:09:26 -0700 Subject: [PATCH 05/26] rc.lua: Switch to awful.wallpaper --- awesomerc.lua | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/awesomerc.lua b/awesomerc.lua index 5981f8a4..bdbdbaa7 100644 --- a/awesomerc.lua +++ b/awesomerc.lua @@ -77,7 +77,7 @@ mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon, menubar.utils.terminal = terminal -- Set the terminal for applications that require it -- }}} --- {{{ Tag +-- {{{ Tag layout -- @DOC_LAYOUT@ -- Table of layouts to cover with awful.layout.inc, order matters. tag.connect_signal("request::default_layouts", function() @@ -99,6 +99,27 @@ tag.connect_signal("request::default_layouts", function() 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 -- Keyboard map indicator and switcher @@ -107,19 +128,6 @@ mykeyboardlayout = awful.widget.keyboardlayout() -- Create a textclock widget 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@ screen.connect_signal("request::desktop_decoration", function(s) -- Each screen has its own tag table. From b0a2d82d8f5fd41b61b97a6eaa06d62f232b400e Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sun, 23 May 2021 23:11:09 -0700 Subject: [PATCH 06/26] compat: Do not require to pass pattern._native to the wallpaper. It makes the shims impossible to implement without a double free, a memory leak or a crash. Using `capi` should not require to destroy the LGI wrappers. Another example, not fixed in this commit, are the client shapes. --- lib/awful/_compat.lua | 22 ++++++++++++++++++++++ lib/gears/wallpaper.lua | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/awful/_compat.lua b/lib/awful/_compat.lua index c25714f0..496b090b 100644 --- a/lib/awful/_compat.lua +++ b/lib/awful/_compat.lua @@ -58,6 +58,28 @@ do assert(root.object == root_object) 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 -- 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 diff --git a/lib/gears/wallpaper.lua b/lib/gears/wallpaper.lua index 8b3f796a..b65cdf85 100644 --- a/lib/gears/wallpaper.lua +++ b/lib/gears/wallpaper.lua @@ -121,7 +121,7 @@ function wallpaper.set(pattern) if not cairo.Pattern:is_type_of(pattern) then error("wallpaper.set() called with an invalid argument") end - root.wallpaper(pattern._native) + root.wallpaper(pattern) end --- Set a centered wallpaper. From b9971a5accf80cd94f803f9e82f0c2fb35000ad9 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sun, 23 May 2021 23:13:26 -0700 Subject: [PATCH 07/26] root: Do not end up in an infinite loop if the wallpaper is `nil`. If `root.wallpaper` was called with `nil` during initialization, AwesomeWM would get into an infinite restart loop. --- root.c | 7 ++++++- tests/test-wallpaper.lua | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/root.c b/root.c index ae683756..4b5ebfbe 100644 --- a/root.c +++ b/root.c @@ -481,6 +481,11 @@ luaA_root_wallpaper(lua_State *L) { 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); lua_pushboolean(L, root_set_wallpaper(pattern)); /* 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 }, { "fake_input", luaA_root_fake_input }, { "drawins", luaA_root_drawins }, - { "wallpaper", luaA_root_wallpaper }, + { "_wallpaper", luaA_root_wallpaper }, { "size", luaA_root_size }, { "size_mm", luaA_root_size_mm }, { "tags", luaA_root_tags }, diff --git a/tests/test-wallpaper.lua b/tests/test-wallpaper.lua index c337d9db..71c82cd0 100644 --- a/tests/test-wallpaper.lua +++ b/tests/test-wallpaper.lua @@ -133,6 +133,15 @@ end return true end) +-- Make sure passing `nil` doesn't crash Awesome. +table.insert(steps, function() + +root._wallpaper(nil) +root.wallpaper(nil) + +return true +end) + runner.run_steps(steps) From 8481af90c54ad3d8370a08885d1e0d84173efd61 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 7 Jun 2021 01:42:47 -0700 Subject: [PATCH 08/26] shims: Add a wallpaper setter. --- tests/examples/shims/root.lua | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/examples/shims/root.lua b/tests/examples/shims/root.lua index b22c878b..02e7c946 100644 --- a/tests/examples/shims/root.lua +++ b/tests/examples/shims/root.lua @@ -1,6 +1,8 @@ local root = {_tags={}} local gtable = require("gears.table") +local cairo = require( "lgi" ).cairo + function root:tags() return root._tags @@ -169,6 +171,24 @@ function root._write_string(string, c) 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) rawset(root, "_ni_handler", h) From dcdc6a1089eb1982be1e5207262361f9756b4ec4 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 14 Jun 2021 00:41:25 -0700 Subject: [PATCH 09/26] shims: Add awesome._get_key_name --- tests/examples/shims/awesome.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/examples/shims/awesome.lua b/tests/examples/shims/awesome.lua index b33d7230..40186685 100644 --- a/tests/examples/shims/awesome.lua +++ b/tests/examples/shims/awesome.lua @@ -118,6 +118,10 @@ awesome._modifiers = { }, } +function awesome._get_key_name(key) + return key +end + awesome._active_modifiers = {} return awesome From 580f16b7ffa631990a87f3f666f8e8bcff77870e Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 14 Jun 2021 00:54:50 -0700 Subject: [PATCH 10/26] tests: Draw the wallpaper in the awful template --- tests/examples/awful/template.lua | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/examples/awful/template.lua b/tests/examples/awful/template.lua index 758d2280..1a20a8b3 100644 --- a/tests/examples/awful/template.lua +++ b/tests/examples/awful/template.lua @@ -58,11 +58,23 @@ if not rawget(screen, "no_outline") then 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_source(color(beautiful.border_color)) - local rect = {x1 = 0 ,y1 = 0 , x2 = 0 , y2 = 0} -- Get the region with wiboxes From 6b7ecc51f88cca2c866178f0d0701a0632ebddf2 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 14 Jun 2021 01:09:18 -0700 Subject: [PATCH 11/26] tests: Add awful.wallpaper tests --- .../examples/awful/wallpaper/add_screen1.lua | 48 ++++ .../examples/awful/wallpaper/add_screen2.lua | 50 ++++ .../examples/awful/wallpaper/add_screen3.lua | 51 ++++ tests/examples/awful/wallpaper/corner1.lua | 30 +++ tests/examples/awful/wallpaper/dpi1.lua | 57 +++++ tests/examples/awful/wallpaper/gradient1.lua | 20 ++ tests/examples/awful/wallpaper/gradient2.lua | 21 ++ tests/examples/awful/wallpaper/mazimized1.lua | 23 ++ tests/examples/awful/wallpaper/mazimized2.lua | 25 ++ tests/examples/awful/wallpaper/mazimized3.lua | 20 ++ tests/examples/awful/wallpaper/padding1.lua | 58 +++++ .../awful/wallpaper/padding1.output.txt | 3 + .../awful/wallpaper/panning_custom.lua | 86 +++++++ .../awful/wallpaper/panning_inner.lua | 60 +++++ .../wallpaper/panning_inner_horizontal.lua | 60 +++++ .../wallpaper/panning_inner_vertical.lua | 60 +++++ .../awful/wallpaper/panning_outer.lua | 58 +++++ .../awful/wallpaper/remove_screen1.lua | 53 ++++ .../awful/wallpaper/remove_screen2.lua | 58 +++++ tests/examples/awful/wallpaper/screens1.lua | 54 ++++ tests/examples/awful/wallpaper/slideshow1.lua | 45 ++++ tests/examples/awful/wallpaper/svg.lua | 36 +++ tests/examples/awful/wallpaper/tiled1.lua | 27 ++ tests/examples/awful/wallpaper/tiled2.lua | 30 +++ tests/examples/awful/wallpaper/widget1.lua | 82 ++++++ tests/examples/awful/wallpaper/widget2.lua | 48 ++++ tests/examples/awful/wallpaper/workarea1.lua | 56 +++++ .../text/awful/wallpaper/multi_screen.lua | 13 + tests/test-wallpaper.lua | 233 ++++++++++++++---- 29 files changed, 1421 insertions(+), 44 deletions(-) create mode 100644 tests/examples/awful/wallpaper/add_screen1.lua create mode 100644 tests/examples/awful/wallpaper/add_screen2.lua create mode 100644 tests/examples/awful/wallpaper/add_screen3.lua create mode 100644 tests/examples/awful/wallpaper/corner1.lua create mode 100644 tests/examples/awful/wallpaper/dpi1.lua create mode 100644 tests/examples/awful/wallpaper/gradient1.lua create mode 100644 tests/examples/awful/wallpaper/gradient2.lua create mode 100644 tests/examples/awful/wallpaper/mazimized1.lua create mode 100644 tests/examples/awful/wallpaper/mazimized2.lua create mode 100644 tests/examples/awful/wallpaper/mazimized3.lua create mode 100644 tests/examples/awful/wallpaper/padding1.lua create mode 100644 tests/examples/awful/wallpaper/padding1.output.txt create mode 100644 tests/examples/awful/wallpaper/panning_custom.lua create mode 100644 tests/examples/awful/wallpaper/panning_inner.lua create mode 100644 tests/examples/awful/wallpaper/panning_inner_horizontal.lua create mode 100644 tests/examples/awful/wallpaper/panning_inner_vertical.lua create mode 100644 tests/examples/awful/wallpaper/panning_outer.lua create mode 100644 tests/examples/awful/wallpaper/remove_screen1.lua create mode 100644 tests/examples/awful/wallpaper/remove_screen2.lua create mode 100644 tests/examples/awful/wallpaper/screens1.lua create mode 100644 tests/examples/awful/wallpaper/slideshow1.lua create mode 100644 tests/examples/awful/wallpaper/svg.lua create mode 100644 tests/examples/awful/wallpaper/tiled1.lua create mode 100644 tests/examples/awful/wallpaper/tiled2.lua create mode 100644 tests/examples/awful/wallpaper/widget1.lua create mode 100644 tests/examples/awful/wallpaper/widget2.lua create mode 100644 tests/examples/awful/wallpaper/workarea1.lua create mode 100644 tests/examples/text/awful/wallpaper/multi_screen.lua diff --git a/tests/examples/awful/wallpaper/add_screen1.lua b/tests/examples/awful/wallpaper/add_screen1.lua new file mode 100644 index 00000000..03365a9a --- /dev/null +++ b/tests/examples/awful/wallpaper/add_screen1.lua @@ -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], --DOC_HIDE + 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() diff --git a/tests/examples/awful/wallpaper/add_screen2.lua b/tests/examples/awful/wallpaper/add_screen2.lua new file mode 100644 index 00000000..8dcfcfe1 --- /dev/null +++ b/tests/examples/awful/wallpaper/add_screen2.lua @@ -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], --DOC_HIDE + 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 diff --git a/tests/examples/awful/wallpaper/add_screen3.lua b/tests/examples/awful/wallpaper/add_screen3.lua new file mode 100644 index 00000000..81638aad --- /dev/null +++ b/tests/examples/awful/wallpaper/add_screen3.lua @@ -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], --DOC_HIDE + 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() diff --git a/tests/examples/awful/wallpaper/corner1.lua b/tests/examples/awful/wallpaper/corner1.lua new file mode 100644 index 00000000..4f036052 --- /dev/null +++ b/tests/examples/awful/wallpaper/corner1.lua @@ -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 + + + awful.wallpaper { + screen = screen[1], --DOC_HIDE + 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 diff --git a/tests/examples/awful/wallpaper/dpi1.lua b/tests/examples/awful/wallpaper/dpi1.lua new file mode 100644 index 00000000..c3e129f3 --- /dev/null +++ b/tests/examples/awful/wallpaper/dpi1.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/gradient1.lua b/tests/examples/awful/wallpaper/gradient1.lua new file mode 100644 index 00000000..fa1a7b29 --- /dev/null +++ b/tests/examples/awful/wallpaper/gradient1.lua @@ -0,0 +1,20 @@ +--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 + + + awful.wallpaper { + screen = screen[1], --DOC_HIDE + bg = { + type = "linear" , + from = { 0, 0 }, + to = { 0, 240 }, + stops = { + { 0, "#0000ff" }, + { 1, "#ff0000" } + } + } + } + +require("gears.timer").run_delayed_calls_now() --DOC_HIDE diff --git a/tests/examples/awful/wallpaper/gradient2.lua b/tests/examples/awful/wallpaper/gradient2.lua new file mode 100644 index 00000000..0946d598 --- /dev/null +++ b/tests/examples/awful/wallpaper/gradient2.lua @@ -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 + + + awful.wallpaper { + screen = screen[1], --DOC_HIDE + 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 diff --git a/tests/examples/awful/wallpaper/mazimized1.lua b/tests/examples/awful/wallpaper/mazimized1.lua new file mode 100644 index 00000000..58dbc11c --- /dev/null +++ b/tests/examples/awful/wallpaper/mazimized1.lua @@ -0,0 +1,23 @@ +--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 + + + awful.wallpaper { + screen = screen[1], --DOC_HIDE + 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 + diff --git a/tests/examples/awful/wallpaper/mazimized2.lua b/tests/examples/awful/wallpaper/mazimized2.lua new file mode 100644 index 00000000..425d2c90 --- /dev/null +++ b/tests/examples/awful/wallpaper/mazimized2.lua @@ -0,0 +1,25 @@ +--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 + + + awful.wallpaper { + screen = screen[1], --DOC_HIDE + 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 diff --git a/tests/examples/awful/wallpaper/mazimized3.lua b/tests/examples/awful/wallpaper/mazimized3.lua new file mode 100644 index 00000000..596b5ebb --- /dev/null +++ b/tests/examples/awful/wallpaper/mazimized3.lua @@ -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 + + + awful.wallpaper { + screen = screen[1], --DOC_HIDE + 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 + diff --git a/tests/examples/awful/wallpaper/padding1.lua b/tests/examples/awful/wallpaper/padding1.lua new file mode 100644 index 00000000..1e34e1be --- /dev/null +++ b/tests/examples/awful/wallpaper/padding1.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/padding1.output.txt b/tests/examples/awful/wallpaper/padding1.output.txt new file mode 100644 index 00000000..e90d2665 --- /dev/null +++ b/tests/examples/awful/wallpaper/padding1.output.txt @@ -0,0 +1,3 @@ +Uncovered area: 0 0 30 196 +Uncovered area: 0 0 320 14 +Uncovered area: 310 0 10 196 diff --git a/tests/examples/awful/wallpaper/panning_custom.lua b/tests/examples/awful/wallpaper/panning_custom.lua new file mode 100644 index 00000000..4ca2828d --- /dev/null +++ b/tests/examples/awful/wallpaper/panning_custom.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/panning_inner.lua b/tests/examples/awful/wallpaper/panning_inner.lua new file mode 100644 index 00000000..f13b585a --- /dev/null +++ b/tests/examples/awful/wallpaper/panning_inner.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/panning_inner_horizontal.lua b/tests/examples/awful/wallpaper/panning_inner_horizontal.lua new file mode 100644 index 00000000..5afc8692 --- /dev/null +++ b/tests/examples/awful/wallpaper/panning_inner_horizontal.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/panning_inner_vertical.lua b/tests/examples/awful/wallpaper/panning_inner_vertical.lua new file mode 100644 index 00000000..75bb9abc --- /dev/null +++ b/tests/examples/awful/wallpaper/panning_inner_vertical.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/panning_outer.lua b/tests/examples/awful/wallpaper/panning_outer.lua new file mode 100644 index 00000000..b1a39850 --- /dev/null +++ b/tests/examples/awful/wallpaper/panning_outer.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/remove_screen1.lua b/tests/examples/awful/wallpaper/remove_screen1.lua new file mode 100644 index 00000000..18b97b3f --- /dev/null +++ b/tests/examples/awful/wallpaper/remove_screen1.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/remove_screen2.lua b/tests/examples/awful/wallpaper/remove_screen2.lua new file mode 100644 index 00000000..7dab36b7 --- /dev/null +++ b/tests/examples/awful/wallpaper/remove_screen2.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/screens1.lua b/tests/examples/awful/wallpaper/screens1.lua new file mode 100644 index 00000000..6d3b535f --- /dev/null +++ b/tests/examples/awful/wallpaper/screens1.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/slideshow1.lua b/tests/examples/awful/wallpaper/slideshow1.lua new file mode 100644 index 00000000..2ae793d8 --- /dev/null +++ b/tests/examples/awful/wallpaper/slideshow1.lua @@ -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 diff --git a/tests/examples/awful/wallpaper/svg.lua b/tests/examples/awful/wallpaper/svg.lua new file mode 100644 index 00000000..1f7073dd --- /dev/null +++ b/tests/examples/awful/wallpaper/svg.lua @@ -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 = ''.. + ''.. + ''.. + ''.. + ''.. + '' + + --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 diff --git a/tests/examples/awful/wallpaper/tiled1.lua b/tests/examples/awful/wallpaper/tiled1.lua new file mode 100644 index 00000000..460648e7 --- /dev/null +++ b/tests/examples/awful/wallpaper/tiled1.lua @@ -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 + + + awful.wallpaper { + screen = screen[1], --DOC_HIDE + 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 diff --git a/tests/examples/awful/wallpaper/tiled2.lua b/tests/examples/awful/wallpaper/tiled2.lua new file mode 100644 index 00000000..ecb5ef7c --- /dev/null +++ b/tests/examples/awful/wallpaper/tiled2.lua @@ -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 + + + awful.wallpaper { + screen = screen[1], --DOC_HIDE + 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 diff --git a/tests/examples/awful/wallpaper/widget1.lua b/tests/examples/awful/wallpaper/widget1.lua new file mode 100644 index 00000000..c2fe6128 --- /dev/null +++ b/tests/examples/awful/wallpaper/widget1.lua @@ -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 + + + awful.wallpaper { + screen = screen[1], --DOC_HIDE + 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 diff --git a/tests/examples/awful/wallpaper/widget2.lua b/tests/examples/awful/wallpaper/widget2.lua new file mode 100644 index 00000000..adef018e --- /dev/null +++ b/tests/examples/awful/wallpaper/widget2.lua @@ -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 = "[SYSTEM FAILURE]", + 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 diff --git a/tests/examples/awful/wallpaper/workarea1.lua b/tests/examples/awful/wallpaper/workarea1.lua new file mode 100644 index 00000000..c8f7bd70 --- /dev/null +++ b/tests/examples/awful/wallpaper/workarea1.lua @@ -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() diff --git a/tests/examples/text/awful/wallpaper/multi_screen.lua b/tests/examples/text/awful/wallpaper/multi_screen.lua new file mode 100644 index 00000000..4d5c2b1e --- /dev/null +++ b/tests/examples/text/awful/wallpaper/multi_screen.lua @@ -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) diff --git a/tests/test-wallpaper.lua b/tests/test-wallpaper.lua index 71c82cd0..7882e107 100644 --- a/tests/test-wallpaper.lua +++ b/tests/test-wallpaper.lua @@ -5,6 +5,9 @@ local wp = require("gears.wallpaper") local color = require("gears.color") local cairo = require( "lgi" ).cairo local surface = require("gears.surface") +local awall = require("awful.wallpaper") +local beautiful = require("beautiful") +local wibox = require("wibox") local steps = {} @@ -54,94 +57,236 @@ table.insert(steps, function() end) 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 --- adding more -return true + -- There is a delayed call for the last call, let it be processed before + -- adding more + return true end) table.insert(steps, function() -wp.centered(img, nil, nil) -wp.centered(img, screen[1], nil) + wp.centered(img, nil, nil) + wp.centered(img, screen[1], nil) --- There is a delayed call for the last call, let it be processed before --- adding more -return true + -- There is a delayed call for the last call, let it be processed before + -- adding more + return true end) table.insert(steps, function() -wp.centered(img, screen[1], "#00ff00") + wp.centered(img, screen[1], "#00ff00") -return true + return true end) 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 --- adding more -return true + -- There is a delayed call for the last call, let it be processed before + -- adding more + return true end) 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 --- adding more -return true + -- There is a delayed call for the last call, let it be processed before + -- adding more + return true end) 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) -wp.maximized(img, screen[1], true, nil) - --- There is a delayed call for the last call, let it be processed before --- adding more -return true + -- There is a delayed call for the last call, let it be processed before + -- adding more + return true end) 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}) -wp.maximized(img, screen[1], true, {x=10, y= 10}) - -return true + return true end) table.insert(steps, function() -wp.tiled(img, nil, nil) -wp.tiled(img, screen[1], nil) + wp.tiled(img, nil, nil) + wp.tiled(img, screen[1], nil) --- There is a delayed call for the last call, let it be processed before --- adding more -return true + -- There is a delayed call for the last call, let it be processed before + -- adding more + return true end) 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) table.insert(steps, function() -for _, c in ipairs(colors) do - wp.set(c) -end + for _, c in ipairs(colors) do + wp.set(c) + end -return true + return true end) -- Make sure passing `nil` doesn't crash Awesome. table.insert(steps, function() + root._wallpaper(nil) + root.wallpaper(nil) -root._wallpaper(nil) -root.wallpaper(nil) - -return true + 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) From e55ea2b0d53e6acab97c98dfb6c0e7cb91bb8186 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 9 Sep 2021 16:44:55 -0700 Subject: [PATCH 12/26] doc: Support multiple screens in the "default look" template. --- tests/examples/shims/_default_look.lua | 165 +++++++++++++------------ 1 file changed, 88 insertions(+), 77 deletions(-) diff --git a/tests/examples/shims/_default_look.lua b/tests/examples/shims/_default_look.lua index c67927f7..3b0cee76 100644 --- a/tests/examples/shims/_default_look.lua +++ b/tests/examples/shims/_default_look.lua @@ -3,87 +3,98 @@ local wibox = require("wibox") local beautiful = require("beautiful") require("_date") --- Create the same number of tags as the default config -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 ret = nil -local wb = awful.wibar { position = "top" } -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, - }, -} +for i = 1, screen.count() do + local s = screen[i] + -- 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 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 + local wb = awful.wibar { + position = "top", + screen = s } -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() -return { - mykeyboardlayout = mykeyboardlayout, - mytextclock = mytextclock , - mylayoutbox = mylayoutbox , - mytaglist = mytaglist , - mytasklist = mytasklist , - mywibox = wb , - mypromptbox = mypromptbox , -} +return ret From 3f2db184ad13812e3d0069c841ea28649ea86de5 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 10 Sep 2021 18:19:23 -0700 Subject: [PATCH 13/26] gears.wallpaper: Deprecate. --- lib/gears/wallpaper.lua | 41 +++++++++++++++++++--------------------- tests/test-wallpaper.lua | 4 ++++ 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/lib/gears/wallpaper.lua b/lib/gears/wallpaper.lua index b65cdf85..3843a359 100644 --- a/lib/gears/wallpaper.lua +++ b/lib/gears/wallpaper.lua @@ -1,22 +1,7 @@ --------------------------------------------------------------------------- -- Functions for setting the wallpaper. -- --- There are two levels of functionality provided by this module: --- --- 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) +-- This module is deprecated, please use `awful.wallpaper`. -- -- @author 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 -- @return[1] The available geometry (table with entries width and height) -- @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) + debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5}) + s = get_screen(s) 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, -- a description for gears.color or a cairo pattern. -- @see gears.color --- @staticfct gears.wallpaper.set +-- @deprecated gears.wallpaper.set function wallpaper.set(pattern) + debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5}) + if cairo.Surface:is_type_of(pattern) then pattern = cairo.Pattern.create_for_surface(pattern) end @@ -132,8 +121,10 @@ end -- gears.color. The default is black. -- @param scale The scale factor for the wallpaper. Default is 1 (original size). -- @see gears.color --- @staticfct gears.wallpaper.centered +-- @deprecated gears.wallpaper.centered function wallpaper.centered(surf, s, background, scale) + debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5}) + local geom, cr = wallpaper.prepare_context(s) local original_surf = 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 -- all screens are set. -- @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) + debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5}) + local _, cr = wallpaper.prepare_context(s) if offset then @@ -202,8 +195,10 @@ end -- @param ignore_aspect If this is true, the image's aspect ratio is ignored. -- The default is to honor the aspect ratio. -- @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) + debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5}) + local geom, cr = wallpaper.prepare_context(s) local original_surf = surf surf = surface.load_uncached(surf) @@ -243,8 +238,10 @@ end -- @param background The background color that should be used. Gets handled via -- gears.color. The default is black. -- @see gears.color --- @staticfct gears.wallpaper.fit +-- @deprecated gears.wallpaper.fit function wallpaper.fit(surf, s, background) + debug.deprecate("Use `awful.wallpaper`", {deprecated_in=5}) + local geom, cr = wallpaper.prepare_context(s) local original_surf = surf surf = surface.load_uncached(surf) diff --git a/tests/test-wallpaper.lua b/tests/test-wallpaper.lua index 7882e107..f86f7cb3 100644 --- a/tests/test-wallpaper.lua +++ b/tests/test-wallpaper.lua @@ -8,6 +8,10 @@ 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 = {} From ddccddb6dc38f80863855d394c03798f8aaea982 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sat, 11 Sep 2021 16:27:44 -0700 Subject: [PATCH 14/26] imagebox: Allow to load SVG data without saving it. --- lib/wibox/widget/imagebox.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/wibox/widget/imagebox.lua b/lib/wibox/widget/imagebox.lua index 5daf8001..3117b897 100644 --- a/lib/wibox/widget/imagebox.lua +++ b/lib/wibox/widget/imagebox.lua @@ -57,11 +57,19 @@ local function load_rsvg_handle(file) if not Rsvg then return end local cache = rsvg_handle_cache[file] + if cache then return cache end - local handle, err = Rsvg.Handle.new_from_file(file) + local handle, err = nil, nil + + if file:match("<[?]?xml") then + handle, err = Rsvg.Handle.new_from_data(file) + else + handle, err = Rsvg.Handle.new_from_file(file) + end + if not err then rsvg_handle_cache[file] = handle return handle From 883cdb7f41c3824597b1d739a8a41a6457b6cf8f Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sat, 11 Sep 2021 18:59:46 -0700 Subject: [PATCH 15/26] doc: Fix the rendering of double quotes and semicolons CMake uses quotes and semicolon in its internal list datatype. Previously, all double quotes were converted to single quotes to avoid this problem. Semicolors were interpreted as newlines in ldoc. With this commit, both of them render fine. This was required because a new example uses CSS and XML where those symbols have a specific meanning. --- docs/ldoc.ltp | 9 +++++---- tests/examples/CMakeLists.txt | 8 +++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/ldoc.ltp b/docs/ldoc.ltp index 148ac6d2..01b260b9 100644 --- a/docs/ldoc.ltp +++ b/docs/ldoc.ltp @@ -38,7 +38,8 @@ # local use_li = ldoc.use_li # local display_name = ldoc.display_name # 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 html_space = function(s) return s:gsub(" ", "%%20") end # local no_underscores = function(s) return s:gsub("_", " ") end @@ -189,7 +190,7 @@

Usage:

    # for usage in iter(module.usage) do - $(li)
    $(ldoc.escape(usage))
    $(il) + $(li)
    $(ldoc.escape(un_cmake(usage)))
    $(il) # end -- for
# end -- if usage @@ -331,7 +332,7 @@ # end # if kitem.usage then

Usage:

-
$(ldoc.prettify(kitem.usage[1]))
+
$(ldoc.prettify(un_cmake(kitem.usage[1])))
# end # end # if not kind:match("^ldoc_skip") then @@ -450,7 +451,7 @@

Usage:

    # for usage in iter(item.usage) do - $(li)
    $(ldoc.prettify(usage))
    $(il) + $(li)
    $(ldoc.prettify(un_cmake(usage)))
    $(il) # end -- for
# end -- if usage diff --git a/tests/examples/CMakeLists.txt b/tests/examples/CMakeLists.txt index 328ad98d..83173cf6 100644 --- a/tests/examples/CMakeLists.txt +++ b/tests/examples/CMakeLists.txt @@ -85,7 +85,9 @@ function(escape_string variable content escaped_content line_prefix) if(variable MATCHES "--DOC_HIDE_ALL") return() 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(section OFF) @@ -101,7 +103,7 @@ function(escape_string variable content escaped_content line_prefix) # Pick lines that are not specified to be hidden 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() # If we found a start marker previously, look for an end marker. @@ -347,7 +349,7 @@ foreach(file ${test_files}) # variable during the pre-processing. # While at it, replace \" created by CMake by ', # " wont work in . - string(REPLACE "\"" "'" ${TEST_NAME} ${ESCAPED_CODE_EXAMPLE}) + string(REPLACE "\"" """ ${TEST_NAME} ${ESCAPED_CODE_EXAMPLE}) endif() endforeach() From d8bc791818c578b9f0a18d5a24bc3e3779f2000a Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sat, 11 Sep 2021 23:07:27 -0700 Subject: [PATCH 16/26] imagebox: Add DPI and CSS Stylesheet properties for SVG images. This exposes the `librsvg` DPI and Stylesheet properties. This is a groundwork commit to port the xresources theme to use a SVG wallpaper instead of hardcoded Cairo code to generate the colorfar logo. --- lib/wibox/widget/imagebox.lua | 218 ++++++++++++++++++++++++++-------- 1 file changed, 168 insertions(+), 50 deletions(-) diff --git a/lib/wibox/widget/imagebox.lua b/lib/wibox/widget/imagebox.lua index 3117b897..be115b98 100644 --- a/lib/wibox/widget/imagebox.lua +++ b/lib/wibox/widget/imagebox.lua @@ -48,7 +48,7 @@ end local imagebox = { mt = {} } -local rsvg_handle_cache = setmetatable({}, { __mode = 'v' }) +local rsvg_handle_cache = setmetatable({}, { __mode = 'k' }) ---Load rsvg handle form image file ---@tparam string file Path to svg file. @@ -56,28 +56,119 @@ local rsvg_handle_cache = setmetatable({}, { __mode = 'v' }) local function load_rsvg_handle(file) if not Rsvg then return end - local cache = rsvg_handle_cache[file] + local cache = (rsvg_handle_cache[file] or {})["handle"] if cache then - return cache + return cache, rsvg_handle_cache[file] end - local handle, err = nil, nil + local handle, err - if file:match("<[?]?xml") then + if file:match("<[?]?xml") or file:match(" 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, cache) + 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.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 -- 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 -- For valign = "top" and halign = "left" @@ -86,6 +177,8 @@ function imagebox:draw(_, cr, width, height) y = 0, } + update_dpi(self, ctx) + local w, h = self._private.default.width, self._private.default.height if self._private.resize then @@ -177,8 +270,11 @@ function imagebox:draw(_, cr, width, height) end -- 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 + + update_dpi(self, ctx) + local w, h = self._private.default.width, self._private.default.height if w <= width and h <= height and self._private.upscale == false then @@ -197,44 +293,6 @@ function imagebox:fit(_, width, height) return w, h 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`. -- -- It can can be any of the following: @@ -245,7 +303,7 @@ end -- * `nil`: Unset the image. -- -- @property image --- @tparam image image The image to render. +-- @tparam image image The image to render. test -- @propemits false false --- Set the `imagebox` image. @@ -262,7 +320,10 @@ end function imagebox:set_image(image) local setup_succeed - if type(image) == "userdata" then + -- Keep the original to prevent the cache from being GCed. + self._private.original_iamge = 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 -- historically it did, and it did by just assuming they refer to a -- cairo surface. @@ -279,7 +340,8 @@ function imagebox:set_image(image) end elseif Rsvg and Rsvg.Handle:is_type_of(image) then -- 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 -- try to apply given cairo surface setup_succeed = set_surface(self, image) @@ -365,6 +427,62 @@ end -- @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 `` 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) self._private.resize = allowed From bbf1c9270f8331ba270ebc5f4b86589c2db32d0e Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sun, 12 Sep 2021 00:48:59 -0700 Subject: [PATCH 17/26] tests: Test the imagebox DPI and CSS stylesheet. --- tests/examples/wibox/widget/imagebox/dpi.lua | 48 +++++++++++++++++++ .../wibox/widget/imagebox/stylesheet.lua | 31 ++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 tests/examples/wibox/widget/imagebox/dpi.lua create mode 100644 tests/examples/wibox/widget/imagebox/stylesheet.lua diff --git a/tests/examples/wibox/widget/imagebox/dpi.lua b/tests/examples/wibox/widget/imagebox/dpi.lua new file mode 100644 index 00000000..1a11f1f6 --- /dev/null +++ b/tests/examples/wibox/widget/imagebox/dpi.lua @@ -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 = ''.. + ''.. + ''.. + 'Hello world!'.. + '' + +--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 = "dpi = "..dpi.."", --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 diff --git a/tests/examples/wibox/widget/imagebox/stylesheet.lua b/tests/examples/wibox/widget/imagebox/stylesheet.lua new file mode 100644 index 00000000..59a3bd3a --- /dev/null +++ b/tests/examples/wibox/widget/imagebox/stylesheet.lua @@ -0,0 +1,31 @@ +--DOC_GEN_IMAGE --DOC_HIDE +local parent = ... --DOC_HIDE +local wibox = require("wibox") --DOC_HIDE + + local image = ''.. + ''.. + ''.. + ''.. + ''.. + '' + + --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 From 1ff860454e95930a27c0981e87c634b8823a301d Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sun, 12 Sep 2021 01:37:51 -0700 Subject: [PATCH 18/26] theme: Use a SVG wallpaper for the xresources theme. It uses a stylesheet for the colors. This is not "as good" as the old one because it only supports 16:9 aspect ratio. However, the old wallpaper function doesn't fit great in the new model. The widget doesn't know the screen, so it cannot pass it to a function. It's possible to stretch the wallpaper. --- themes/xresources/theme.lua | 35 +++++++++++++++++++++++++++++++-- themes/xresources/wallpaper.svg | 24 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 themes/xresources/wallpaper.svg diff --git a/themes/xresources/theme.lua b/themes/xresources/theme.lua index 11edfe7d..b3be3c46 100644 --- a/themes/xresources/theme.lua +++ b/themes/xresources/theme.lua @@ -8,6 +8,7 @@ local xresources = require("beautiful.xresources") local rnotification = require("ruled.notification") local dpi = xresources.apply_dpi local xrdb = xresources.get_current_theme() +local gdebug = require("gears.debug") local gfs = require("gears.filesystem") local themes_path = gfs.get_themes_dir() @@ -126,10 +127,40 @@ local wallpaper_alt_fg = xrdb.color12 if not is_dark_bg then wallpaper_bg, wallpaper_fg = wallpaper_fg, wallpaper_bg 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 +if not theme.wallpaper then + theme.wallpaper = themes_path.."xresources/wallpaper.svg" +end + +theme.wallpaper_bg = wallpaper_bg + -- Set different colors for urgent notifications. rnotification.connect_signal('request::rules', function() rnotification.append_rule { diff --git a/themes/xresources/wallpaper.svg b/themes/xresources/wallpaper.svg new file mode 100644 index 00000000..5bcbc0b1 --- /dev/null +++ b/themes/xresources/wallpaper.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + From 4a0645e942ccff4f9cd5efd7082030a04e743852 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 14 Sep 2021 15:41:43 -0700 Subject: [PATCH 19/26] doc: Correctly render --DOC_NO_USAGE + --DOC_GEN_OUTPUT. It was previously merged into a single block. --- tests/examples/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/examples/CMakeLists.txt b/tests/examples/CMakeLists.txt index 83173cf6..71befc53 100644 --- a/tests/examples/CMakeLists.txt +++ b/tests/examples/CMakeLists.txt @@ -258,6 +258,12 @@ function(run_test test_path namespace escaped_content) "\n${expected_output}" "${TEST_DOC_CONTENT}" TEST_DOC_CONTENT " " ) + + # Add a
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() escape_string( "\n${expected_output}" From 70cd293839e4a1325c4e75eea300f458dba0219b Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 16 Sep 2021 01:03:10 -0700 Subject: [PATCH 20/26] doc: Integrate `awful.wallpaper` into the guides. --- docs/03-declarative-layout.md | 4 ++ docs/05-awesomerc.md.lua | 9 +++ tests/examples/awful/popup/wiboxtypes.lua | 80 ++++++++++++++++++++++- 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/docs/03-declarative-layout.md b/docs/03-declarative-layout.md index 12143b54..1555a7c0 100644 --- a/docs/03-declarative-layout.md +++ b/docs/03-declarative-layout.md @@ -124,6 +124,10 @@ to an object such as the mouse. The `naughty.layout.box` allows to provide custom widgets to use within the 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 exactly the same way and allows to attach widgets on each side of clients. diff --git a/docs/05-awesomerc.md.lua b/docs/05-awesomerc.md.lua index 0fc005d0..783f58f8 100644 --- a/docs/05-awesomerc.md.lua +++ b/docs/05-awesomerc.md.lua @@ -72,6 +72,15 @@ variables such as `bg_normal`. To get a list of all official variables, see 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, `request::wallpaper` +is emitted everytime a screen is added, moved, resized or when the bars +(`awful.wibar`) are moved. + +This is will suited for single-screen wallpaper. If you wish to use multi-screen wallpaper, +it is better to create a global wallpaper object and edit it when the screen change. +]] sections.DOC_DEFAULT_APPLICATIONS = [[   diff --git a/tests/examples/awful/popup/wiboxtypes.lua b/tests/examples/awful/popup/wiboxtypes.lua index c6fa28d9..ccbef7ba 100644 --- a/tests/examples/awful/popup/wiboxtypes.lua +++ b/tests/examples/awful/popup/wiboxtypes.lua @@ -8,6 +8,7 @@ local gears = require("gears") local naughty = require("naughty") local wibox = require("wibox") local beautiful = require("beautiful") --DOC_HIDE +local assets = require("beautiful.theme_assets") local look = require("_default_look") 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} +-- 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 { x = 50, y = 350, @@ -97,6 +170,7 @@ wibox { width = 50, height = 50, shape = gears.shape.octogon, + visible = true, color = "#0000ff", x = 570, y = 410, @@ -188,13 +262,17 @@ create_info("awful.tooltip", 30, 130, 100, 30) create_info("awful.popup", 450, 240, 100, 30) create_info("naughty.layout.box", 255, 110, 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(75, 100, 75, 135) create_line(545, 432, 575, 432) 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(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 From 7806763667ab900e9c27e85101a2931f992674e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Lepage=20Vall=C3=A9e?= Date: Wed, 22 Sep 2021 20:50:59 -0700 Subject: [PATCH 21/26] Update docs/05-awesomerc.md.lua Co-authored-by: Aire-One --- docs/05-awesomerc.md.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/05-awesomerc.md.lua b/docs/05-awesomerc.md.lua index 783f58f8..50965a47 100644 --- a/docs/05-awesomerc.md.lua +++ b/docs/05-awesomerc.md.lua @@ -74,12 +74,14 @@ 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, `request::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 wallpaper. If you wish to use multi-screen wallpaper, -it is better to create a global wallpaper object and edit it when the screen change. +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 = [[ From 7b8426bd24fd5f367e653fcd8470e84c61f3bb8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Lepage=20Vall=C3=A9e?= Date: Wed, 22 Sep 2021 20:51:11 -0700 Subject: [PATCH 22/26] Update lib/wibox/widget/imagebox.lua Co-authored-by: Aire-One --- lib/wibox/widget/imagebox.lua | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/wibox/widget/imagebox.lua b/lib/wibox/widget/imagebox.lua index be115b98..ace4eed7 100644 --- a/lib/wibox/widget/imagebox.lua +++ b/lib/wibox/widget/imagebox.lua @@ -51,8 +51,9 @@ local imagebox = { mt = {} } local rsvg_handle_cache = setmetatable({}, { __mode = 'k' }) ---Load rsvg handle form image file ----@tparam string file Path to svg file. ----@return Rsvg handle +-- @tparam string file Path to svg file. +-- @return Rsvg handle +-- @treturn table A table where cached data can be stored. local function load_rsvg_handle(file) if not Rsvg then return end @@ -79,8 +80,8 @@ 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 + 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 @@ -92,7 +93,7 @@ end 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 end + if not is_handle_valid then return false end ib._private.default = { width = dim.width, height = dim.height } ib._private.handle = handle @@ -303,7 +304,7 @@ end -- * `nil`: Unset the image. -- -- @property image --- @tparam image image The image to render. test +-- @tparam image image The image to render. -- @propemits false false --- Set the `imagebox` image. @@ -321,7 +322,7 @@ function imagebox:set_image(image) local setup_succeed -- Keep the original to prevent the cache from being GCed. - self._private.original_iamge = image + 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 From 01ae508899e5cf18e74c3f942a83a089f8eab280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Lepage=20Vall=C3=A9e?= Date: Wed, 22 Sep 2021 20:51:54 -0700 Subject: [PATCH 23/26] Update lib/awful/wallpaper.lua Co-authored-by: Aire-One --- lib/awful/wallpaper.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/awful/wallpaper.lua b/lib/awful/wallpaper.lua index 6a0b040b..e72d6214 100644 --- a/lib/awful/wallpaper.lua +++ b/lib/awful/wallpaper.lua @@ -735,7 +735,7 @@ end -- 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 ned panned wallpaper, it is possible that 2 +-- adding a new panned wallpaper, it is possible that 2 -- wallpaper will have an overlap. -- -- @method detach From 546ac6aec9cf7a6f0d9b218ca36543e67e81db85 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 22 Sep 2021 20:49:58 -0700 Subject: [PATCH 24/26] container.tile: Correctly transfer the Cairo source to the tile. --- lib/wibox/container/tile.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/wibox/container/tile.lua b/lib/wibox/container/tile.lua index e2175cd4..46fdd391 100644 --- a/lib/wibox/container/tile.lua +++ b/lib/wibox/container/tile.lua @@ -31,6 +31,7 @@ function module:draw(context, cr, width, height) if not self._private.surface then self._private.surface = cairo.ImageSurface(cairo.Format.ARGB32, w+hspace, h+vspace) 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.extend = cairo.Extend.REPEAT self._private.cr:translate(math.ceil(hspace), math.ceil(vspace)) From eb07ca4c47c87c60d7d6eb4e405043a0e4747476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Lepage=20Vall=C3=A9e?= Date: Sat, 25 Sep 2021 12:49:19 -0700 Subject: [PATCH 25/26] Update lib/awful/wallpaper.lua Co-authored-by: Aire-One --- lib/awful/wallpaper.lua | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/awful/wallpaper.lua b/lib/awful/wallpaper.lua index e72d6214..e9374d1b 100644 --- a/lib/awful/wallpaper.lua +++ b/lib/awful/wallpaper.lua @@ -808,19 +808,24 @@ 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 wibox.widget args.widget The wallpaper widget. --- @tparam number args.dpi The wallpaper DPI (dots per inch). --- @tparam screen args.screen The wallpaper screen. --- @tparam table args.screens A list of screen for this wallpaper. --- @tparam gears.color args.bg The background color. --- @tparam gears.color args.fg The foreground color. --- @tparam gears.color args.uncovered_areas_color The color for the uncovered areas. --- @tparam boolean args.honor_workarea Honor the workarea. --- @tparam boolean args.honor_padding Honor the screen padding. --- @tparam table args.uncovered_areas Returns the list of screen(s) area which won't be covered by the wallpaper. --- @tparam function|string args.panning_area Defines where the wallpaper is placed when there is multiple screens. +-- @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 {} From c3fe4c15ed72373bdbe37d33e3d43389f4cbb6e0 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 1 Oct 2021 16:54:22 -0700 Subject: [PATCH 26/26] doc: Uncomment the wallpaper `screen` property. --- tests/examples/awful/wallpaper/add_screen1.lua | 2 +- tests/examples/awful/wallpaper/add_screen2.lua | 2 +- tests/examples/awful/wallpaper/add_screen3.lua | 2 +- tests/examples/awful/wallpaper/corner1.lua | 4 ++-- tests/examples/awful/wallpaper/gradient1.lua | 3 ++- tests/examples/awful/wallpaper/gradient2.lua | 3 ++- tests/examples/awful/wallpaper/mazimized1.lua | 3 ++- tests/examples/awful/wallpaper/mazimized2.lua | 3 ++- tests/examples/awful/wallpaper/mazimized3.lua | 4 ++-- tests/examples/awful/wallpaper/tiled1.lua | 4 ++-- tests/examples/awful/wallpaper/tiled2.lua | 4 ++-- tests/examples/awful/wallpaper/widget1.lua | 4 ++-- 12 files changed, 21 insertions(+), 17 deletions(-) diff --git a/tests/examples/awful/wallpaper/add_screen1.lua b/tests/examples/awful/wallpaper/add_screen1.lua index 03365a9a..570884d9 100644 --- a/tests/examples/awful/wallpaper/add_screen1.lua +++ b/tests/examples/awful/wallpaper/add_screen1.lua @@ -11,7 +11,7 @@ screen._add_screen {x = 322, y = 0, width = 160, height = 96} require("_default_look") awful.wallpaper { - screen = screen[1], --DOC_HIDE + screen = screen[1], bg = "#222222", widget = wibox.widget { { diff --git a/tests/examples/awful/wallpaper/add_screen2.lua b/tests/examples/awful/wallpaper/add_screen2.lua index 8dcfcfe1..b7fead0f 100644 --- a/tests/examples/awful/wallpaper/add_screen2.lua +++ b/tests/examples/awful/wallpaper/add_screen2.lua @@ -11,7 +11,7 @@ screen._add_screen {x = 322, y = 0, width = 160, height = 96} require("_default_look") local wall = awful.wallpaper { - screen = screen[1], --DOC_HIDE + screen = screen[1], bg = "#222222", widget = wibox.widget { { diff --git a/tests/examples/awful/wallpaper/add_screen3.lua b/tests/examples/awful/wallpaper/add_screen3.lua index 81638aad..b46b12ed 100644 --- a/tests/examples/awful/wallpaper/add_screen3.lua +++ b/tests/examples/awful/wallpaper/add_screen3.lua @@ -12,7 +12,7 @@ screen._add_screen {x = 322, y = 0, width = 160, height = 96} require("_default_look") local wall = awful.wallpaper { - screen = screen[1], --DOC_HIDE + screen = screen[1], bg = "#222222", widget = wibox.widget { { diff --git a/tests/examples/awful/wallpaper/corner1.lua b/tests/examples/awful/wallpaper/corner1.lua index 4f036052..1faf70e5 100644 --- a/tests/examples/awful/wallpaper/corner1.lua +++ b/tests/examples/awful/wallpaper/corner1.lua @@ -7,10 +7,10 @@ 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 = screen[1], --DOC_HIDE + screen = s, bg = "#000000", widget = { { diff --git a/tests/examples/awful/wallpaper/gradient1.lua b/tests/examples/awful/wallpaper/gradient1.lua index fa1a7b29..923739c4 100644 --- a/tests/examples/awful/wallpaper/gradient1.lua +++ b/tests/examples/awful/wallpaper/gradient1.lua @@ -2,10 +2,11 @@ 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 = screen[1], --DOC_HIDE + screen = s, bg = { type = "linear" , from = { 0, 0 }, diff --git a/tests/examples/awful/wallpaper/gradient2.lua b/tests/examples/awful/wallpaper/gradient2.lua index 0946d598..9c1f9edb 100644 --- a/tests/examples/awful/wallpaper/gradient2.lua +++ b/tests/examples/awful/wallpaper/gradient2.lua @@ -2,10 +2,11 @@ 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 = screen[1], --DOC_HIDE + screen = s, bg = { type = "radial", from = { 160, 98, 20 }, diff --git a/tests/examples/awful/wallpaper/mazimized1.lua b/tests/examples/awful/wallpaper/mazimized1.lua index 58dbc11c..36cbb4a0 100644 --- a/tests/examples/awful/wallpaper/mazimized1.lua +++ b/tests/examples/awful/wallpaper/mazimized1.lua @@ -2,10 +2,11 @@ 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 = screen[1], --DOC_HIDE + screen = s, widget = { { image = beautiful.wallpaper, diff --git a/tests/examples/awful/wallpaper/mazimized2.lua b/tests/examples/awful/wallpaper/mazimized2.lua index 425d2c90..5dd7e36e 100644 --- a/tests/examples/awful/wallpaper/mazimized2.lua +++ b/tests/examples/awful/wallpaper/mazimized2.lua @@ -4,10 +4,11 @@ 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 = screen[1], --DOC_HIDE + screen = s, bg = "#0000ff", widget = { { diff --git a/tests/examples/awful/wallpaper/mazimized3.lua b/tests/examples/awful/wallpaper/mazimized3.lua index 596b5ebb..52d35440 100644 --- a/tests/examples/awful/wallpaper/mazimized3.lua +++ b/tests/examples/awful/wallpaper/mazimized3.lua @@ -4,10 +4,10 @@ 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 = screen[1], --DOC_HIDE + screen = s, widget = { horizontal_fit_policy = "fit", vertical_fit_policy = "fit", diff --git a/tests/examples/awful/wallpaper/tiled1.lua b/tests/examples/awful/wallpaper/tiled1.lua index 460648e7..68f8e65b 100644 --- a/tests/examples/awful/wallpaper/tiled1.lua +++ b/tests/examples/awful/wallpaper/tiled1.lua @@ -4,10 +4,10 @@ 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 = screen[1], --DOC_HIDE + screen = s, bg = "#0000ff", widget = { { diff --git a/tests/examples/awful/wallpaper/tiled2.lua b/tests/examples/awful/wallpaper/tiled2.lua index ecb5ef7c..76576e78 100644 --- a/tests/examples/awful/wallpaper/tiled2.lua +++ b/tests/examples/awful/wallpaper/tiled2.lua @@ -4,10 +4,10 @@ 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 = screen[1], --DOC_HIDE + screen = s, bg = "#0000ff", widget = { { diff --git a/tests/examples/awful/wallpaper/widget1.lua b/tests/examples/awful/wallpaper/widget1.lua index c2fe6128..26228e13 100644 --- a/tests/examples/awful/wallpaper/widget1.lua +++ b/tests/examples/awful/wallpaper/widget1.lua @@ -4,10 +4,10 @@ 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 = screen[1], --DOC_HIDE + screen = s, widget = wibox.widget { fit = function(_, width, height) return width, height