Set the wallpaper more intelligently
Usually users want a wallpaper on all their screens. With the current code, this resulted in a loop of upload-wallpaper, {download-wallpaper, add-new-part, upload-wallpaper}*. Fix this by being more intelligent: Instead of setting the wallpaper immediately, this now uses gears.timer.delayed_call() to set the wallpaper. All following modifications which come in before the delayed call runs will still be part of the current update. This should mean that during startup, there is just a single upload of a wallpaper. (The above is what happens if there is no wallpaper yet. If there is already one, we use :create_similar() and thus should only upload the part of the wallpaper that changed, but this doesn't really make a difference.) As a side-effect, the new code no longer draws to the old wallpaper to modify it, but always creates a copy of it. This means that: Fixes https://github.com/awesomeWM/awesome/issues/288. Closes https://github.com/awesomeWM/awesome/pull/530. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
57e3927cbd
commit
112ce3b419
|
@ -8,6 +8,7 @@
|
||||||
local cairo = require("lgi").cairo
|
local cairo = require("lgi").cairo
|
||||||
local color = require("gears.color")
|
local color = require("gears.color")
|
||||||
local surface = require("gears.surface")
|
local surface = require("gears.surface")
|
||||||
|
local timer = require("gears.timer")
|
||||||
|
|
||||||
local wallpaper = { mt = {} }
|
local wallpaper = { mt = {} }
|
||||||
|
|
||||||
|
@ -27,29 +28,56 @@ do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Prepare the needed state for setting a wallpaper
|
-- A cairo surface that we still want to set as the wallpaper
|
||||||
|
local pending_wallpaper = nil
|
||||||
|
|
||||||
|
--- Prepare the needed state for setting a wallpaper.
|
||||||
|
-- This function returns a cairo context through which a wallpaper can be drawn.
|
||||||
|
-- The context is only valid for a short time and should not be saved in a
|
||||||
|
-- global variable.
|
||||||
-- @param s The screen to set the wallpaper on or nil for all screens
|
-- @param s The screen to set the wallpaper on or nil for all screens
|
||||||
-- @return The available geometry (table with entries width and height), a
|
-- @return[1] The available geometry (table with entries width and height)
|
||||||
-- that should be used for setting the wallpaper and a cairo context for
|
-- @return[1] A cairo context that the wallpaper should be drawn to
|
||||||
-- drawing to this surface
|
function wallpaper.prepare_context(s)
|
||||||
local function prepare_wallpaper(s)
|
|
||||||
local geom = s and screen[s].geometry or root_geom
|
local geom = s and screen[s].geometry or root_geom
|
||||||
local img = surface(root.wallpaper())
|
local cr
|
||||||
|
|
||||||
if not img then
|
if not pending_wallpaper then
|
||||||
-- No wallpaper yet, create an image surface for just the part we need
|
-- Prepare a pending wallpaper
|
||||||
img = cairo.ImageSurface(cairo.Format.RGB24, geom.width, geom.height)
|
local wp = surface(root.wallpaper())
|
||||||
img:set_device_offset(-geom.x, -geom.y)
|
|
||||||
|
if not wp then
|
||||||
|
-- No wallpaper yet
|
||||||
|
wp = cairo.ImageSurface(cairo.Format.RGB24, 0, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
pending_wallpaper = wp:create_similar(cairo.Content.COLOR, root_geom.width, root_geom.height)
|
||||||
|
|
||||||
|
-- Copy the old wallpaper to the new one
|
||||||
|
cr = cairo.Context(pending_wallpaper)
|
||||||
|
cr:save()
|
||||||
|
cr.operator = cairo.Operator.SOURCE
|
||||||
|
cr:set_source_surface(wp, 0, 0)
|
||||||
|
cr:paint()
|
||||||
|
cr:restore()
|
||||||
|
|
||||||
|
-- Set the wallpaper (delayed)
|
||||||
|
timer.delayed_call(function()
|
||||||
|
local wp = pending_wallpaper
|
||||||
|
pending_wallpaper = nil
|
||||||
|
wallpaper.set(wp)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
-- Draw to the already-pending wallpaper
|
||||||
|
cr = cairo.Context(pending_wallpaper)
|
||||||
end
|
end
|
||||||
|
|
||||||
local cr = cairo.Context(img)
|
|
||||||
|
|
||||||
-- Only draw to the selected area
|
-- Only draw to the selected area
|
||||||
cr:translate(geom.x, geom.y)
|
cr:translate(geom.x, geom.y)
|
||||||
cr:rectangle(0, 0, geom.width, geom.height)
|
cr:rectangle(0, 0, geom.width, geom.height)
|
||||||
cr:clip()
|
cr:clip()
|
||||||
|
|
||||||
return geom, img, cr
|
return geom, cr
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set the current wallpaper.
|
--- Set the current wallpaper.
|
||||||
|
@ -75,7 +103,7 @@ end
|
||||||
-- @param background The background color that should be used. Gets handled via
|
-- @param background The background color that should be used. Gets handled via
|
||||||
-- gears.color. The default is black.
|
-- gears.color. The default is black.
|
||||||
function wallpaper.centered(surf, s, background)
|
function wallpaper.centered(surf, s, background)
|
||||||
local geom, img, cr = prepare_wallpaper(s)
|
local geom, cr = wallpaper.prepare_context(s)
|
||||||
local surf = surface(surf)
|
local surf = surface(surf)
|
||||||
local background = color(background)
|
local background = color(background)
|
||||||
|
|
||||||
|
@ -91,8 +119,6 @@ function wallpaper.centered(surf, s, background)
|
||||||
cr:clip()
|
cr:clip()
|
||||||
cr:set_source_surface(surf, 0, 0)
|
cr:set_source_surface(surf, 0, 0)
|
||||||
cr:paint()
|
cr:paint()
|
||||||
|
|
||||||
wallpaper.set(img)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set a tiled wallpaper.
|
--- Set a tiled wallpaper.
|
||||||
|
@ -101,7 +127,7 @@ end
|
||||||
-- all screens are set.
|
-- all screens are set.
|
||||||
-- @param offset This can be set to a table with entries x and y.
|
-- @param offset This can be set to a table with entries x and y.
|
||||||
function wallpaper.tiled(surf, s, offset)
|
function wallpaper.tiled(surf, s, offset)
|
||||||
local geom, img, cr = prepare_wallpaper(s)
|
local geom, cr = wallpaper.prepare_context(s)
|
||||||
|
|
||||||
if offset then
|
if offset then
|
||||||
cr:translate(offset.x, offset.y)
|
cr:translate(offset.x, offset.y)
|
||||||
|
@ -112,8 +138,6 @@ function wallpaper.tiled(surf, s, offset)
|
||||||
cr.source = pattern
|
cr.source = pattern
|
||||||
cr.operator = cairo.Operator.SOURCE
|
cr.operator = cairo.Operator.SOURCE
|
||||||
cr:paint()
|
cr:paint()
|
||||||
|
|
||||||
wallpaper.set(img)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set a maximized wallpaper.
|
--- Set a maximized wallpaper.
|
||||||
|
@ -124,7 +148,7 @@ end
|
||||||
-- The default is to honor the aspect ratio.
|
-- The default is to honor the aspect ratio.
|
||||||
-- @param offset This can be set to a table with entries x and y.
|
-- @param offset This can be set to a table with entries x and y.
|
||||||
function wallpaper.maximized(surf, s, ignore_aspect, offset)
|
function wallpaper.maximized(surf, s, ignore_aspect, offset)
|
||||||
local geom, img, cr = prepare_wallpaper(s)
|
local geom, cr = wallpaper.prepare_context(s)
|
||||||
local surf = surface(surf)
|
local surf = surface(surf)
|
||||||
local w, h = surface.get_size(surf)
|
local w, h = surface.get_size(surf)
|
||||||
local aspect_w = geom.width / w
|
local aspect_w = geom.width / w
|
||||||
|
@ -147,8 +171,6 @@ function wallpaper.maximized(surf, s, ignore_aspect, offset)
|
||||||
cr:set_source_surface(surf, 0, 0)
|
cr:set_source_surface(surf, 0, 0)
|
||||||
cr.operator = cairo.Operator.SOURCE
|
cr.operator = cairo.Operator.SOURCE
|
||||||
cr:paint()
|
cr:paint()
|
||||||
|
|
||||||
wallpaper.set(img)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set a fitting wallpaper.
|
--- Set a fitting wallpaper.
|
||||||
|
@ -158,7 +180,7 @@ end
|
||||||
-- @param background The background color that should be used. Gets handled via
|
-- @param background The background color that should be used. Gets handled via
|
||||||
-- gears.color. The default is black.
|
-- gears.color. The default is black.
|
||||||
function wallpaper.fit(surf, s, background)
|
function wallpaper.fit(surf, s, background)
|
||||||
local geom, img, cr = prepare_wallpaper(s)
|
local geom, cr = wallpaper.prepare_context(s)
|
||||||
local surf = surface(surf)
|
local surf = surface(surf)
|
||||||
local background = color(background)
|
local background = color(background)
|
||||||
|
|
||||||
|
@ -179,8 +201,6 @@ function wallpaper.fit(surf, s, background)
|
||||||
cr:scale(scale, scale)
|
cr:scale(scale, scale)
|
||||||
cr:set_source_surface(surf, 0, 0)
|
cr:set_source_surface(surf, 0, 0)
|
||||||
cr:paint()
|
cr:paint()
|
||||||
|
|
||||||
wallpaper.set(img)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return wallpaper
|
return wallpaper
|
||||||
|
|
Loading…
Reference in New Issue