Skip to main content

screen

The screen object represents a physical or virtual display. Each monitor connected to your system is a screen.

Upstream documentation: AwesomeWM screen docs

Accessing Screens

-- Primary screen
local s = screen.primary

-- Currently focused screen
local s = awful.screen.focused()

-- Iterate all screens
for s in screen do
print(s.index, s.geometry.width)
end

-- Get screen by index (1-based)
local s = screen[1]

-- Total screen count
local count = screen.count()

Properties

Geometry & Layout

PropertyTypeAccessDescription
geometrytablereadScreen bounds {x, y, width, height} in logical pixels
workareatablereadUsable area after panels/struts {x, y, width, height}
indexnumberread1-based screen index
paddingtableread/writeManual padding {top, right, bottom, left}

Output Information

PropertyTypeAccessDescription
outputstablereadPhysical output info (see below)
namestringread/writeUser-assignable screen name

The outputs table is keyed by output name:

-- Example outputs table
{
["DP-1"] = {
name = "DP-1",
mm_width = 600, -- Physical width in millimeters
mm_height = 340, -- Physical height in millimeters
viewport_id = 1,
}
}

Scaling & DPI somewm-only

PropertyTypeAccessDescription
scalenumberread/writeOutput scale factor (0.1 to 10.0)
dpinumberreadScreen DPI (computed from physical size)
minimum_dpinumberreadLowest DPI across outputs
maximum_dpinumberreadHighest DPI across outputs
preferred_dpinumberreadRecommended DPI for this screen
-- Get current scale
print(screen.primary.scale) -- e.g., 1.5

-- Set fractional scale for HiDPI display
screen.primary.scale = 1.5

-- Check DPI
print(screen.primary.dpi) -- e.g., 144

When you change scale, the geometry and workarea update to reflect logical pixel dimensions. For example, a 3840x2160 display at scale 2.0 reports geometry of 1920x1080.

Tags & Clients

PropertyTypeAccessDescription
tagstablereadAll tags on this screen
selected_tagstablereadCurrently visible tags
selected_tagtagreadFirst selected tag (or nil)
clientstablereadAll clients on this screen
tiled_clientstablereadNon-floating, non-minimized clients

Methods

Screen Management

-- Get total screen count
local count = screen.count()

-- Get bounding geometry (respects workarea and padding)
local geo = s:get_bounding_geometry({
honor_workarea = true,
honor_padding = true,
})

-- Swap two screens' positions
screen[1]:swap(screen[2])

Virtual Screens

-- Create a virtual screen
local fake = screen.fake_add(0, 0, 1920, 1080)

-- Resize a virtual screen
fake:fake_resize(0, 0, 2560, 1440)

-- Remove a virtual screen
fake:fake_remove()

Signals

SignalArgumentsDescription
addedsNew screen connected
removedsScreen disconnected
list(none)Screen list changed
primary_changed(none)Primary screen changed
property::geometrysScreen geometry changed
property::workareasWorkarea changed (panel added/removed)
property::scalesOutput scale changed somewm-only
property::outputssOutput metadata changed
property::indexsScreen index changed

Example: React to Scale Changes

screen.connect_signal("property::scale", function(s)
-- Refresh widgets when scale changes
print("Screen " .. s.index .. " scale is now " .. s.scale)
end)

Example: Handle Monitor Hotplug

screen.connect_signal("added", function(s)
-- Set up new monitor with appropriate scale
if s.geometry.width > 3000 then
s.scale = 1.5 -- 4K display
end

-- Create tags
awful.tag({ "1", "2", "3" }, s, awful.layout.layouts[1])
end)

Common Patterns

Auto-Scale Based on Resolution

awful.screen.connect_for_each_screen(function(s)
if s.geometry.width > 3000 then
s.scale = 1.5
elseif s.geometry.width > 2000 then
s.scale = 1.25
else
s.scale = 1.0
end
end)

Get Screen Under Mouse

local s = awful.screen.focused()  -- Follows focus
-- or
local s = mouse.screen -- Screen containing mouse pointer

Find Screen by Output Name

for s in screen do
for name, _ in pairs(s.outputs) do
if name == "HDMI-A-1" then
return s
end
end
end

See Also