# Module: `awful.wallpaper`

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.

awful.wallpaper { screen = s, widget = { { image = beautiful.wallpaper, resize = true, widget = wibox.widget.imagebox, }, valign = "center", halign = "center", tiled = false, widget = wibox.container.tile, } }

If the image aspect ratio doesn't match, the bg property can be used to fill the empty area:

awful.wallpaper { screen = s, bg = "#0000ff", widget = { { image = beautiful.wallpaper, resize = true, widget = wibox.widget.imagebox, }, valign = "center", halign = "center", tiled = false, widget = wibox.container.tile, } }

It is also possible to stretch the image:

awful.wallpaper { screen = s, widget = { horizontal_fit_policy = "fit", vertical_fit_policy = "fit", image = beautiful.wallpaper, widget = wibox.widget.imagebox, }, }

To maintain the image's aspect ratio while filling the screen, the image can be cropped using gears.surface:

awful.wallpaper { screen = s, widget = { image = gears.surface.crop_surface { surface = gears.surface.load_uncached(beautiful.wallpaper), ratio = s.geometry.width/s.geometry.height, }, widget = wibox.widget.imagebox, }, }

Finally, it is also possible to use simpler "branding" in a corner using awful.placement:

awful.wallpaper { screen = s, bg = "#000000", widget = { { { image = beautiful.awesome_icon, resize = false, point = awful.placement.bottom_right, widget = wibox.widget.imagebox, }, widget = wibox.layout.manual, }, margins = 5, widget = wibox.container.margin } }

Tiled =====

This example tiles an image:

awful.wallpaper { screen = s, bg = "#0000ff", widget = { { image = beautiful.awesome_icon, resize = false, widget = wibox.widget.imagebox, }, horizontal_spacing = 5, vertical_spacing = 5, valign = "top", halign = "left", tiled = true, widget = wibox.container.tile, } }

This one tiles a shape using the wibox.widget.separator widget:

awful.wallpaper { screen = s, bg = "#0000ff", widget = { { shape = gears.shape.star, forced_width = 30, forced_height = 30, widget = wibox.widget.separator, }, horizontal_spacing = 5, vertical_spacing = 5, vertical_crop = true, horizontal_crop = true, valign = "center", halign = "center", tiled = true, widget = wibox.container.tile, } }

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:

awful.wallpaper { screen = s, bg = { type = "linear" , from = { 0, 0 }, to = { 0, 240 }, stops = { { 0, "#0000ff" }, { 1, "#ff0000" } } } }

awful.wallpaper { screen = s, bg = { type = "radial", from = { 160, 98, 20 }, to = { 160, 98, 120 }, stops = { { 0 , "#ff0000" }, { 0.5, "#00ff00" }, { 1 , "#0000ff" }, } } }

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.

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 awful.wallpaper { bg = "#000000", fg = "#55ff5577", widget = wibox.widget { { { markup = "`[SYSTEM FAILURE]`", valign = "center", halign = "center", widget = wibox.widget.textbox }, fg = "#00ff00", widget = wibox.container.background }, { wrap = "word", text = binary(), widget = wibox.widget.textbox, }, widget = wibox.layout.stack }, }

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:

awful.wallpaper { screen = s, widget = wibox.widget { fit = function(_, width, height) return width, height end, draw = function(_, _, cr, width, height) cr:set_source(gears.color { type = 'linear', from = { 0, 0 }, to = { 0, height }, stops = { { 0 , '#030d27' }, { 0.75, '#3a183f' }, { 0.75, '#000000' }, { 1 , '#222222' } } }) cr:paint() -- Clip the first 33% of the screen cr:rectangle(0,0, width, height/3) -- Clip-out some increasingly large sections to 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() -- 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() -- Draw the grid local lines = width/8 cr:reset_clip() cr:set_line_width(0.5) cr:set_source(gears.color("#8922a3")) 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 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, } }

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):

local image = ''.. '
' local stylesheet = "" .. "rect { fill: #ffff00; } ".. ".my_class { fill: #00ff00; } ".. "#my_id { fill: #0000ff; }" awful.wallpaper { widget = wibox.widget { stylesheet = stylesheet, image = image, widget = wibox.widget.imagebox } }

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:

local global_wallpaper = awful.wallpaper { -- [...] your content } 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)

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:

-- 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) -- **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, }

### Info:

- Copyright: 2019 Emmanuel Lepage Vallee
- Originally authored by: Emmanuel Lepage Vallee <elv1313@gmail.com>
  (Full contributors list available on our github project)

## Constructors

awful.wallpaper {[args]} | Create a wallpaper. |

## Object properties

widget | widget or nil | The wallpaper widget. |
dpi | number | The wallpaper DPI (dots per inch). |
screen | screen | The wallpaper screen. |
screens | table | A list of screen for this wallpaper. |
bg | color | The background color. |
fg | color | The foreground color. |
honor_workarea | boolean | Honor the workarea. |
honor_padding | boolean | Honor the screen padding. |
uncovered_areas | table | Returns the list of screen(s) area which won't be covered by the wallpaper. |
uncovered_areas_color | color | The color for the uncovered areas. |
panning_area | function or string | Defines where the wallpaper is placed when there is multiple screens. |

## Object methods

:add_screen (screen) | Add another screen (enable panning). |
:detach () | Detach the wallpaper from all screens. |
:repaint () | Repaint the wallpaper. |
:remove_screen (screen) -> boolean | Remove a screen. |

## Theme variables

beautiful.wallpaper_bg | color | The default wallpaper background color. |
beautiful.wallpaper_fg | gears.color | The default wallpaper foreground color. |

## Constructors

🔗 awful.wallpaper {[args]}
  Create a wallpaper.

  Note that all parameters are not required. Please refer to the module description and examples to understand parameters usages.

  ### Parameters:

  Note: This constructors uses named parameters calling convention. It means you call it with `{}` and omit the parantheses. For example, calling this will all default argument would be `awful.wallpaper{}`. This is a Lua shortcut syntax equivalent to `awful.wallpaper({})`. `args` is only a placeholder name for the "lone table argument" used in named parameters calls.

  Name |  | Type(s) | Description
  --- | --- | --- | ---
  args |  | table |
  widget | Optional | wibox.widget | The wallpaper widget.
  dpi | Optional | number | The wallpaper DPI (dots per inch).
  screen | Optional | screen | The wallpaper screen.
  screens | Optional | table | 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, ...}`)
  bg | Optional | gears.color | The background color.
  fg | Optional | gears.color | The foreground color.
  uncovered_areas_color | Optional | gears.color | The color for the uncovered areas.
  honor_workarea | Optional | boolean | Honor the workarea.
  honor_padding | Optional | boolean | Honor the screen padding.
  uncovered_areas | Optional | table | Returns the list of screen(s) area which won't be covered by the wallpaper.
  panning_area | Optional | function or string | Defines where the wallpaper is placed when there is multiple screens.

## Object properties

🔗 widget widget or nil
  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.

  ### Constraints:

  Default value | : `nil`

  ### See also:

  wibox.widget.imagebox | A widget to display an image. | module
  wibox.container.tile | Replicate the content of the widget over and over. | module

🔗 dpi number
  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).

  ### Constraints:

  Default value | : `self.screen.dpi`
  Unit | : pixel\_per\_inch
  Negative allowed | : false

  ### See also:

  screen | A physical or virtual screen object. | module
  screen.dpi | The number of pixels per inch of the screen. (screen) | object properties

  ### Usage:

      for s in screen do
          local dpi = s.index * 100

          awful.wallpaper {
              screen = s,
              dpi    = dpi,
              widget = wibox.widget {
                  text   = "DPI: " .. dpi,
                  valign = "center",
                  halign = "center",
                  widget = wibox.widget.textbox,
           }
      end

🔗 screen screen
  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.

  ### Constraints:

  Default value | : Obtained from the constructor.
  Type description:
  screen | : A valid screen object such as retured by `awful.screen.focused()` or mouse.screen.
  integer | : A screen global id. Avoid using this since they are unsorted.
  string | : The `"primary"` value is also valid.

  ### See also:

  screens | A list of screen for this wallpaper. | object properties
  add_screen | Add another screen (enable panning). | object methods
  remove_screen | Remove a screen. | object methods

🔗 screens table
  A list of screen for this wallpaper.

  ### Constraints:

  Default value | : `{self.screen}`
  Table content | : A list of screen objects.

  ### See also:

  screen | A physical or virtual screen object. | module
  add_screen | Add another screen (enable panning). | object methods
  remove_screen | Remove a screen. | object methods
  detach | Detach the wallpaper from all screens. | object methods

  ### Usage:

         -- 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",
                     halign = "center",
                     widget = wibox.widget.textbox,
                 },
                 widget = wibox.layout.stack
             }
         }

      Some large wallpaper are made to span multiple screens.

🔗 bg color · 1 theme variable
  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.

  ### Constraints:

  Default value | : `beautiful.wallpaper_bg`
  Type description:
  string | : An hexadecimal color code, such as `"#ff0000"` for red.
  string | : A color name, such as `"red"`.
  table | : A [gradient table](../theme_related_libraries/gears.color.html).
  cairo.pattern | : Any valid [Cairo pattern](https://cairographics.org/manual/cairo-cairo-pattern-t.html).
  cairo.pattern | : A texture build from an image by [gears.color.create\_png\_pattern](../theme_related_libraries/gears.color.html#create_png_pattern)

  ### See also:

  gears.color | This module simplifies the creation of cairo pattern objects. | module

  Click to display more

  ### Consumed theme variables:

  Theme variable | Usage
  --- | ---
  beautiful.wallpaper_bg |
  beautiful.wallpaper_bg |

🔗 fg 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.

  ### Constraints:

  Default value | : `beautiful.wallpaper_fg`
  Type description:
  string | : An hexadecimal color code, such as `"#ff0000"` for red.
  string | : A color name, such as `"red"`.
  table | : A [gradient table](../theme_related_libraries/gears.color.html).
  cairo.pattern | : Any valid [Cairo pattern](https://cairographics.org/manual/cairo-cairo-pattern-t.html).
  cairo.pattern | : A texture build from an image by [gears.color.create\_png\_pattern](../theme_related_libraries/gears.color.html#create_png_pattern)

  ### See also:

  gears.color | This module simplifies the creation of cairo pattern objects. | module

  Click to display more

  ### Consumed theme variables:

  Theme variable | Usage
  --- | ---
  beautiful.wallpaper_fg |

🔗 honor_workarea boolean
  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.

  ### Constraints:

  Default value | : `false`
  Valid values | : `true` or `false`.

  ### See also:

  honor_padding | Honor the screen padding. | object properties
  uncovered_areas | Returns the list of screen(s) area which won't be covered by the wallpaper. | object properties

🔗 honor_padding boolean
  Honor the screen padding.

  When set, this will look at the screen.padding property to restrict the area where the wallpaper is rendered.

  **Usage example output**:

  Uncovered area: 0 0 30 196 Uncovered area: 0 0 320 14 Uncovered area: 310 0 10 196

  ### Constraints:

  Default value | : `false`
  Valid values | : `true` or `false`.

  ### See also:

  honor_workarea | Honor the workarea. | object properties
  uncovered_areas | Returns the list of screen(s) area which won't be covered by the wallpaper. | object properties

  ### Usage:

      -- Add some padding to the first screen.
      screen[1].padding = {
          left  = 30,
          right = 10,
      }

      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()
          }
      }

      -- 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

🔗 uncovered_areas table
  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.

  ### Constraints:

  Default value | : This depends on the `honor_workarea` and `honor_padding` values.
  Table content: | : A list of area tables with the following keys:
  `x` (number)
  `y` (number)
  `width` (number)
  `height` (number)

  ### See also:

  honor_workarea | Honor the workarea. | object properties
  honor_padding | Honor the screen padding. | object properties
  uncovered_areas_color | The color for the uncovered areas. | object properties

🔗 uncovered_areas_color 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.

  ### Constraints:

  Default value | : `"transparent"`
  Type description:
  string | : An hexadecimal color code, such as `"#ff0000"` for red.
  string | : A color name, such as `"red"`.
  table | : A [gradient table](../theme_related_libraries/gears.color.html).
  cairo.pattern | : Any valid [Cairo pattern](https://cairographics.org/manual/cairo-cairo-pattern-t.html).
  cairo.pattern | : A texture build from an image by [gears.color.create\_png\_pattern](../theme_related_libraries/gears.color.html#create_png_pattern)

  ### See also:

  uncovered_areas | Returns the list of screen(s) area which won't be covered by the wallpaper. | object properties

🔗 panning_area function or string
  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.

  **inner:**

  Take the largest area or either `inner_horizontal` or `inner_vertical`.

  **inner_horizontal:**

  Take the smallest `x` value, the largest `x+width`, the smallest `y` and the smallest `y+height`.

  **inner_vertical:**

  Take the smallest `y` value, the largest `y+height`, the smallest `x` and the smallest `x+width`.

  **Custom function:**

  It is also possible to define a custom function.

  **Usage example output**:

  **Usage example:**

  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 -- 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

  ### Constraints:

  Default value | : `"outer"`
  Type description:
  string | : A panning algorithm
  function: | : Custom panning function.
  Function prototype:
  Parameters:
  wallpaper (awful.wallpaper) | : The wallpaper object.
  Return (A) | : table with `x`, `y`, `width` and `height` keys,
  Valid values:
  `"outer"`
  `"inner"`
  `"inner_horizontal"`
  `"inner_vertical"`

  ### See also:

  uncovered_areas | Returns the list of screen(s) area which won't be covered by the wallpaper. | object properties

## Object methods

🔗 :add_screen (screen)
  Add another screen (enable panning).

  **Before:**

  **After:**

  Also note that adding a non-continuous screen might not work well, but will not automatically add the screens in between:

  ### Parameters:

  Name |  | Type(s) | Description
  --- | --- | --- | ---
  screen |  | screen | The screen object.

  ### See also:

  remove_screen | Remove a screen. | object methods

🔗 :detach ()
  Detach the wallpaper from all screens.

  Adding a new wallpaper to a screen will automatically detach the older one. However there is some case when it is useful to call this manually. For example, when adding a new panned wallpaper, it is possible that 2 wallpaper will have an overlap.

  ### See also:

  remove_screen | Remove a screen. | object methods
  add_screen | Add another screen (enable panning). | object methods

🔗 :repaint ()
  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.

🔗 :remove_screen (screen) -> boolean
  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:

  wall:remove_screen(screen[1])

  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:

  awful.wallpaper { screen = screen[1], bg = "#00ffff", }

  ### Parameters:

  Name |  | Type(s) | Description
  --- | --- | --- | ---
  screen |  | screen | The screen to remove.

  ### Returns:

  boolean `true` if the screen was removed and `false` if the screen wasn't found.

  ### See also:

  detach | Detach the wallpaper from all screens. | object methods
  add_screen | Add another screen (enable panning). | object methods
  screens | A list of screen for this wallpaper. | object properties

## Theme variables

🔗 beautiful.wallpaper_bg color · 1 theme variable
  The default wallpaper background color.

  ### See also:

  bg | The background color. | object properties

  Click to display more

  ### Consumed theme variables:

  Theme variable | Usage
  --- | ---
  beautiful.wallpaper_fg |

  ### Used by:

  - bg The background color.
  - bg The background color.
  - bg The background color.
🔗 beautiful.wallpaper_fg gears.color
  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.

  ### See also:

  bg | The background color. | object properties

  Click to display more

  ### Used by:

  - fg The foreground color.
  - fg The foreground color.
  - beautiful.wallpaper_bg The default wallpaper background color.

generated by LDoc 1.5.0