Skip to main content

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.

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