2012-07-29 16:39:03 +02:00
|
|
|
---------------------------------------------------------------------------
|
2018-01-22 11:22:05 +01:00
|
|
|
-- 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)
|
|
|
|
--
|
2012-07-29 16:39:03 +02:00
|
|
|
-- @author Uli Schlachter
|
|
|
|
-- @copyright 2012 Uli Schlachter
|
2019-06-06 09:40:17 +02:00
|
|
|
-- @utillib gears.wallpaper
|
2012-07-29 16:39:03 +02:00
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
local cairo = require("lgi").cairo
|
|
|
|
local color = require("gears.color")
|
|
|
|
local surface = require("gears.surface")
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
local timer = require("gears.timer")
|
2017-04-24 09:10:03 +02:00
|
|
|
local debug = require("gears.debug")
|
2016-04-09 15:19:46 +02:00
|
|
|
local root = root
|
2012-07-29 16:39:03 +02:00
|
|
|
|
|
|
|
local wallpaper = { mt = {} }
|
|
|
|
|
2016-04-09 15:19:46 +02:00
|
|
|
local function root_geometry()
|
|
|
|
local width, height = root.size()
|
|
|
|
return { x = 0, y = 0, width = width, height = height }
|
|
|
|
end
|
2012-07-29 16:39:03 +02:00
|
|
|
|
2016-05-08 17:48:40 +02:00
|
|
|
-- Information about a pending wallpaper change, see prepare_context()
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
local pending_wallpaper = nil
|
|
|
|
|
2016-09-11 08:08:53 +02:00
|
|
|
local function get_screen(s)
|
|
|
|
return s and screen[s]
|
|
|
|
end
|
|
|
|
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
--- 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.
|
2012-07-29 16:39:03 +02:00
|
|
|
-- @param s The screen to set the wallpaper on or nil for all screens
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
-- @return[1] The available geometry (table with entries width and height)
|
2019-06-08 01:08:05 +02:00
|
|
|
-- @return[1] A cairo context that the wallpaper should be drawn to.
|
|
|
|
-- @staticfct gears.wallpaper.prepare_context
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
function wallpaper.prepare_context(s)
|
2016-09-11 08:08:53 +02:00
|
|
|
s = get_screen(s)
|
|
|
|
|
2016-05-08 17:48:40 +02:00
|
|
|
local root_width, root_height = root.size()
|
2016-09-11 08:08:53 +02:00
|
|
|
local geom = s and s.geometry or root_geometry()
|
2016-05-08 17:48:40 +02:00
|
|
|
local source, target, cr
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
|
|
|
|
if not pending_wallpaper then
|
|
|
|
-- Prepare a pending wallpaper
|
2016-05-08 17:48:40 +02:00
|
|
|
source = surface(root.wallpaper())
|
|
|
|
target = source:create_similar(cairo.Content.COLOR, root_width, root_height)
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
|
|
|
|
-- Set the wallpaper (delayed)
|
|
|
|
timer.delayed_call(function()
|
2016-02-07 13:29:46 +01:00
|
|
|
local paper = pending_wallpaper
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
pending_wallpaper = nil
|
2016-05-08 17:48:40 +02:00
|
|
|
wallpaper.set(paper.surface)
|
|
|
|
paper.surface:finish()
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
end)
|
2016-05-08 17:48:40 +02:00
|
|
|
elseif root_width > pending_wallpaper.width or root_height > pending_wallpaper.height then
|
|
|
|
-- The root window was resized while a wallpaper is pending
|
|
|
|
source = pending_wallpaper.surface
|
|
|
|
target = source:create_similar(cairo.Content.COLOR, root_width, root_height)
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
else
|
|
|
|
-- Draw to the already-pending wallpaper
|
2016-05-08 17:48:40 +02:00
|
|
|
source = nil
|
|
|
|
target = pending_wallpaper.surface
|
|
|
|
end
|
|
|
|
|
|
|
|
cr = cairo.Context(target)
|
|
|
|
|
|
|
|
if source then
|
|
|
|
-- Copy the old wallpaper to the new one
|
|
|
|
cr:save()
|
|
|
|
cr.operator = cairo.Operator.SOURCE
|
|
|
|
cr:set_source_surface(source, 0, 0)
|
|
|
|
cr:paint()
|
|
|
|
cr:restore()
|
2012-07-29 16:39:03 +02:00
|
|
|
end
|
|
|
|
|
2016-05-08 17:48:40 +02:00
|
|
|
pending_wallpaper = {
|
|
|
|
surface = target,
|
|
|
|
width = root_width,
|
|
|
|
height = root_height
|
|
|
|
}
|
|
|
|
|
2012-07-29 16:39:03 +02:00
|
|
|
-- Only draw to the selected area
|
|
|
|
cr:translate(geom.x, geom.y)
|
|
|
|
cr:rectangle(0, 0, geom.width, geom.height)
|
|
|
|
cr:clip()
|
|
|
|
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
return geom, cr
|
2012-07-29 16:39:03 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Set the current wallpaper.
|
|
|
|
-- @param pattern The wallpaper that should be set. This can be a cairo surface,
|
2014-05-19 15:15:39 +02:00
|
|
|
-- a description for gears.color or a cairo pattern.
|
2016-11-20 10:01:39 +01:00
|
|
|
-- @see gears.color
|
2019-06-08 01:08:05 +02:00
|
|
|
-- @staticfct gears.wallpaper.set
|
2012-07-29 16:39:03 +02:00
|
|
|
function wallpaper.set(pattern)
|
|
|
|
if cairo.Surface:is_type_of(pattern) then
|
|
|
|
pattern = cairo.Pattern.create_for_surface(pattern)
|
|
|
|
end
|
|
|
|
if type(pattern) == "string" or type(pattern) == "table" then
|
|
|
|
pattern = color(pattern)
|
|
|
|
end
|
|
|
|
if not cairo.Pattern:is_type_of(pattern) then
|
|
|
|
error("wallpaper.set() called with an invalid argument")
|
|
|
|
end
|
|
|
|
root.wallpaper(pattern._native)
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Set a centered wallpaper.
|
|
|
|
-- @param surf The wallpaper to center. Either a cairo surface or a file name.
|
|
|
|
-- @param s The screen whose wallpaper should be set. Can be nil, in which case
|
2014-05-19 15:15:39 +02:00
|
|
|
-- all screens are set.
|
2012-07-29 16:39:03 +02:00
|
|
|
-- @param background The background color that should be used. Gets handled via
|
2014-05-19 15:15:39 +02:00
|
|
|
-- gears.color. The default is black.
|
2017-03-14 20:53:27 +01:00
|
|
|
-- @param scale The scale factor for the wallpaper. Default is 1 (original size).
|
2016-11-20 10:01:39 +01:00
|
|
|
-- @see gears.color
|
2019-06-08 01:08:05 +02:00
|
|
|
-- @staticfct gears.wallpaper.centered
|
2017-03-14 20:53:27 +01:00
|
|
|
function wallpaper.centered(surf, s, background, scale)
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
local geom, cr = wallpaper.prepare_context(s)
|
2017-02-18 17:45:44 +01:00
|
|
|
local original_surf = surf
|
2016-02-28 17:24:24 +01:00
|
|
|
surf = surface.load_uncached(surf)
|
2016-02-07 13:29:46 +01:00
|
|
|
background = color(background)
|
2012-07-29 16:39:03 +02:00
|
|
|
|
2017-03-14 20:53:27 +01:00
|
|
|
-- Set default scale if unset
|
|
|
|
if not scale or scale <= 0 then
|
|
|
|
scale = 1
|
|
|
|
end
|
|
|
|
|
2012-07-29 16:39:03 +02:00
|
|
|
-- Fill the area with the background
|
|
|
|
cr.operator = cairo.Operator.SOURCE
|
|
|
|
cr.source = background
|
|
|
|
cr:paint()
|
|
|
|
|
|
|
|
-- Now center the surface
|
2014-03-16 03:00:23 +01:00
|
|
|
local w, h = surface.get_size(surf)
|
2017-03-14 20:53:27 +01:00
|
|
|
cr:translate((geom.width - (w * scale)) / 2, (geom.height - (h * scale)) / 2)
|
|
|
|
cr:rectangle(0, 0, (w * scale), (h * scale))
|
|
|
|
|
2012-07-29 16:39:03 +02:00
|
|
|
cr:clip()
|
2017-03-14 20:53:27 +01:00
|
|
|
cr:scale(scale, scale)
|
|
|
|
|
2012-07-29 16:39:03 +02:00
|
|
|
cr:set_source_surface(surf, 0, 0)
|
|
|
|
cr:paint()
|
2017-02-18 17:45:44 +01:00
|
|
|
if surf ~= original_surf then
|
|
|
|
surf:finish()
|
|
|
|
end
|
2017-04-24 09:10:03 +02:00
|
|
|
if cr.status ~= "SUCCESS" then
|
|
|
|
debug.print_warning("Cairo context entered error state: " .. cr.status)
|
|
|
|
end
|
2012-07-29 16:39:03 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Set a tiled wallpaper.
|
|
|
|
-- @param surf The wallpaper to tile. Either a cairo surface or a file name.
|
|
|
|
-- @param s The screen whose wallpaper should be set. Can be nil, in which case
|
2014-05-19 15:15:39 +02:00
|
|
|
-- all screens are set.
|
2012-07-29 16:39:03 +02:00
|
|
|
-- @param offset This can be set to a table with entries x and y.
|
2019-06-08 01:08:05 +02:00
|
|
|
-- @staticfct gears.wallpaper.tiled
|
2012-07-29 16:39:03 +02:00
|
|
|
function wallpaper.tiled(surf, s, offset)
|
2016-02-07 13:29:46 +01:00
|
|
|
local _, cr = wallpaper.prepare_context(s)
|
2012-07-29 16:39:03 +02:00
|
|
|
|
|
|
|
if offset then
|
|
|
|
cr:translate(offset.x, offset.y)
|
|
|
|
end
|
|
|
|
|
2017-02-18 17:45:44 +01:00
|
|
|
local original_surf = surf
|
2016-02-28 17:24:24 +01:00
|
|
|
surf = surface.load_uncached(surf)
|
|
|
|
local pattern = cairo.Pattern.create_for_surface(surf)
|
2012-07-29 16:39:03 +02:00
|
|
|
pattern.extend = cairo.Extend.REPEAT
|
|
|
|
cr.source = pattern
|
|
|
|
cr.operator = cairo.Operator.SOURCE
|
|
|
|
cr:paint()
|
2017-02-18 17:45:44 +01:00
|
|
|
if surf ~= original_surf then
|
|
|
|
surf:finish()
|
|
|
|
end
|
2017-04-24 09:10:03 +02:00
|
|
|
if cr.status ~= "SUCCESS" then
|
|
|
|
debug.print_warning("Cairo context entered error state: " .. cr.status)
|
|
|
|
end
|
2012-07-29 16:39:03 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Set a maximized wallpaper.
|
|
|
|
-- @param surf The wallpaper to set. Either a cairo surface or a file name.
|
|
|
|
-- @param s The screen whose wallpaper should be set. Can be nil, in which case
|
2014-05-19 15:15:39 +02:00
|
|
|
-- all screens are set.
|
2012-07-29 16:39:03 +02:00
|
|
|
-- @param ignore_aspect If this is true, the image's aspect ratio is ignored.
|
2014-05-19 15:15:39 +02:00
|
|
|
-- The default is to honor the aspect ratio.
|
2012-07-29 16:39:03 +02:00
|
|
|
-- @param offset This can be set to a table with entries x and y.
|
2019-06-08 01:08:05 +02:00
|
|
|
-- @staticfct gears.wallpaper.maximized
|
2012-07-29 16:39:03 +02:00
|
|
|
function wallpaper.maximized(surf, s, ignore_aspect, offset)
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
local geom, cr = wallpaper.prepare_context(s)
|
2017-02-18 17:45:44 +01:00
|
|
|
local original_surf = surf
|
2016-02-28 17:24:24 +01:00
|
|
|
surf = surface.load_uncached(surf)
|
2014-03-16 03:00:23 +01:00
|
|
|
local w, h = surface.get_size(surf)
|
2012-07-29 16:39:03 +02:00
|
|
|
local aspect_w = geom.width / w
|
|
|
|
local aspect_h = geom.height / h
|
|
|
|
|
|
|
|
if not ignore_aspect then
|
|
|
|
aspect_h = math.max(aspect_w, aspect_h)
|
|
|
|
aspect_w = math.max(aspect_w, aspect_h)
|
|
|
|
end
|
|
|
|
cr:scale(aspect_w, aspect_h)
|
|
|
|
|
|
|
|
if offset then
|
|
|
|
cr:translate(offset.x, offset.y)
|
2014-06-08 20:18:09 +02:00
|
|
|
elseif not ignore_aspect then
|
2014-08-24 11:54:12 +02:00
|
|
|
local scaled_width = geom.width / aspect_w
|
|
|
|
local scaled_height = geom.height / aspect_h
|
|
|
|
cr:translate((scaled_width - w) / 2, (scaled_height - h) / 2)
|
2012-07-29 16:39:03 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
cr:set_source_surface(surf, 0, 0)
|
|
|
|
cr.operator = cairo.Operator.SOURCE
|
|
|
|
cr:paint()
|
2017-02-18 17:45:44 +01:00
|
|
|
if surf ~= original_surf then
|
|
|
|
surf:finish()
|
|
|
|
end
|
2017-04-24 09:10:03 +02:00
|
|
|
if cr.status ~= "SUCCESS" then
|
|
|
|
debug.print_warning("Cairo context entered error state: " .. cr.status)
|
|
|
|
end
|
2012-07-29 16:39:03 +02:00
|
|
|
end
|
|
|
|
|
2013-01-10 13:58:40 +01:00
|
|
|
--- Set a fitting wallpaper.
|
|
|
|
-- @param surf The wallpaper to set. Either a cairo surface or a file name.
|
|
|
|
-- @param s The screen whose wallpaper should be set. Can be nil, in which case
|
2014-05-19 15:15:39 +02:00
|
|
|
-- all screens are set.
|
2013-01-10 13:58:40 +01:00
|
|
|
-- @param background The background color that should be used. Gets handled via
|
2014-05-19 15:15:39 +02:00
|
|
|
-- gears.color. The default is black.
|
2016-11-20 10:01:39 +01:00
|
|
|
-- @see gears.color
|
2019-06-08 01:08:05 +02:00
|
|
|
-- @staticfct gears.wallpaper.fit
|
2013-01-10 13:58:40 +01:00
|
|
|
function wallpaper.fit(surf, s, background)
|
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>
2015-10-14 16:28:17 +02:00
|
|
|
local geom, cr = wallpaper.prepare_context(s)
|
2017-02-18 17:45:44 +01:00
|
|
|
local original_surf = surf
|
2016-02-28 17:24:24 +01:00
|
|
|
surf = surface.load_uncached(surf)
|
2016-02-07 13:29:46 +01:00
|
|
|
background = color(background)
|
2013-01-10 13:58:40 +01:00
|
|
|
|
|
|
|
-- Fill the area with the background
|
|
|
|
cr.operator = cairo.Operator.SOURCE
|
|
|
|
cr.source = background
|
|
|
|
cr:paint()
|
|
|
|
|
|
|
|
-- Now fit the surface
|
2014-03-16 03:00:23 +01:00
|
|
|
local w, h = surface.get_size(surf)
|
2013-01-10 13:58:40 +01:00
|
|
|
local scale = geom.width / w
|
|
|
|
if h * scale > geom.height then
|
|
|
|
scale = geom.height / h
|
|
|
|
end
|
|
|
|
cr:translate((geom.width - (w * scale)) / 2, (geom.height - (h * scale)) / 2)
|
|
|
|
cr:rectangle(0, 0, w * scale, h * scale)
|
|
|
|
cr:clip()
|
|
|
|
cr:scale(scale, scale)
|
|
|
|
cr:set_source_surface(surf, 0, 0)
|
|
|
|
cr:paint()
|
2017-02-18 17:45:44 +01:00
|
|
|
if surf ~= original_surf then
|
|
|
|
surf:finish()
|
|
|
|
end
|
2017-04-24 09:10:03 +02:00
|
|
|
if cr.status ~= "SUCCESS" then
|
|
|
|
debug.print_warning("Cairo context entered error state: " .. cr.status)
|
|
|
|
end
|
2013-01-10 13:58:40 +01:00
|
|
|
end
|
|
|
|
|
2012-07-29 16:39:03 +02:00
|
|
|
return wallpaper
|
|
|
|
|
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|