Skip to main content
Version: 2.0

awful.screenshot

Screenshot capture with support for full screen, screen, client, geometry, and interactive region selection.

Upstream documentation: awful.screenshot

Usage​

local awful = require("awful")

-- Full screen screenshot
local s = awful.screenshot()
s:refresh()
s:save()

-- Interactive region selection
local s = awful.screenshot({ interactive = true })
s:refresh()
-- User draws a rectangle, screenshot auto-saves on release

Constructor​

awful.screenshot(args) -> screenshot
ArgumentTypeDefaultDescription
interactivebooleanfalseEnable mouse-driven region selection
screenscreennilCapture a specific screen
clientclientnilCapture a specific client window
geometrytablenilCapture a specific {x, y, width, height} region
directorystring$HOMESave directory
prefixstring"Screenshot-"Filename prefix
file_pathstringautoOverride full file path
file_namestringautoOverride filename (within directory)
date_formatstring"%Y%m%d%H%M%S"Date format for auto-generated filenames
cursorstring"crosshair"Cursor shape during interactive mode
frame_colorcolor"#ff0000"Selection rectangle color
frame_shapeshaperectangleSelection rectangle shape
auto_save_delayintegernilSeconds to wait before capture (nil = no delay)
auto_save_tick_durationnumber1.0Seconds between timer::tick signals
minimum_sizetable/integer{width=3, height=3}Minimum selection size (rejects smaller)
accept_buttonstable{awful.button({}, 1)}Mouse buttons to confirm selection
reject_buttonstable{awful.button({}, 3)}Mouse buttons to cancel selection

If none of screen, client, or geometry are set, captures the entire desktop via root.content().

Methods​

refresh()​

Captures the screenshot. In interactive mode, this also starts the snipping overlay.

s:refresh() -> table

Returns a table of {method = surface} pairs.

save(file_path)​

Saves the captured screenshot to disk.

s:save()                    -- Use default path
s:save("/tmp/shot.png") -- Override path

In interactive mode, save() is called automatically after accept().

accept()​

Confirms the interactive selection and saves the screenshot. Called automatically when the user releases the accept button.

s:accept() -> boolean  -- true if saved, false if rejected

Returns false if the selection is below minimum_size or empty.

reject(reason)​

Cancels the interactive selection without saving.

s:reject()               -- Manual cancel
s:reject("mouse_button") -- With reason

Properties​

Read-only​

PropertyTypeDescription
surfaceimageThe captured screenshot surface
surfacestableAll captured surfaces keyed by method
selected_geometrytableCurrent selection {x, y, width, height, surface, method}
content_widgetwibox.widget.imageboxThe screenshot as an imagebox widget
keygrabberawful.keygrabberThe keygrabber used in interactive mode

Read-write​

PropertyTypeDescription
directorystringSave directory
prefixstringFilename prefix
file_pathstringFull file path
file_namestringFilename within directory
date_formatstringDate format suffix
cursorstringInteractive cursor shape
interactivebooleanInteractive mode toggle
frame_colorcolorSelection rectangle color
frame_shapeshapeSelection rectangle shape
minimum_sizetable/integerMinimum selection dimensions
auto_save_delayintegerDelay before capture
accept_buttonstableConfirm buttons
reject_buttonstableCancel buttons

Signals​

SignalArgumentsDescription
snipping::startselfInteractive overlay is shown
snipping::successselfSelection accepted, screenshot saved
snipping::cancelledself, reasonSelection cancelled (reason: "mouse_button", "key", "no_selection", "too_small")
file::savedself, file_path, methodFile written to disk
timer::startedselfAuto-save delay timer started
timer::tickself, remainingTimer tick (seconds remaining)
timer::timeoutselfTimer expired, capture starting

All properties also emit property::<name> signals.

Theme Variables​

VariableDefaultDescription
beautiful.screenshot_frame_color"#ff0000"Default selection rectangle color
beautiful.screenshot_frame_shapegears.shape.rectangleDefault selection shape

Interactive Mode Internals​

When interactive = true and refresh() is called:

  1. The appropriate capture method runs (default: root.content() for full desktop)
  2. A fullscreen wibox is created with the captured image and a selection widget
  3. A mousegrabber tracks mouse position and button state
  4. A keygrabber handles accept/reject keys (Return/Escape by default)
  5. On accept: the captured surface is cropped to the selection and saved

Key internal fields available in signal handlers:

FieldTypeDescription
self._private.framewiboxThe fullscreen overlay wibox
self._private.imageboxwibox.widget.imageboxThe screenshot background widget
self._private.selection_widgetwibox.widget.separatorThe selection rectangle

These are used for the HiDPI performance optimization where the imagebox is hidden in snipping::start. See the Screenshots guide.

Examples​

Programmatic Screenshot​

-- Screenshot of a specific screen
local s = awful.screenshot({ screen = screen.primary })
s:refresh()
s:save("/tmp/screen.png")

Client Screenshot​

-- Screenshot of the focused client
local s = awful.screenshot({ client = client.focus })
s:refresh()
s:save("/tmp/window.png")

Geometry Screenshot​

-- Screenshot of a specific region
local s = awful.screenshot({ geometry = { x = 100, y = 100, width = 500, height = 300 } })
s:refresh()
s:save("/tmp/region.png")

Widget Integration​

-- Display screenshot in a wibox
local s = awful.screenshot({ screen = screen.primary })
s:refresh()

local popup = awful.popup {
widget = s.content_widget,
placement = awful.placement.centered,
visible = true,
}

See Also​