Repository navigation
somewm 2.1.0
Minor release. 67 commits since 2.0.1. Every bar, popup, client and widget is declared in one Clay tree per output, which somewm solves and draws, with animation effects and an inspector. The 22 Removed entries include widget fit and draw methods and textbox:get_preferred_size. rc.lua configs that avoid the removals and the Changed cases below run unchanged.
Added
-
Client and drawin animation effects
scale,scale_top,scale_bottom,scale_leftandscale_rightscale the complete picture about its center or an edge midpoint without changing layout allocation or client configure sizes. Scale composes with fade and one slide. Grow (including its collapse alias) and the five scale effects share one size group: conflicting effects warn once and keep the first. -
The lock screen shows an image, theme.lockscreen_wallpaper and theme.lockscreen_wallpaper_overlay, or the wallpaper and wallpaper_overlay options of lockscreen.init; the image is letterboxed like the desktop wallpaper and dimmed by the overlay colour.
-
A childless wibox.container.background inside wibox.layout.stack paints its colour over the stack again, and a floating wibox.container.place keeps its whole allocation.
-
awesome._active_modifiers reports current keyboard modifiers, including root.fake_input presses, so awful.keyboard can release held modifiers.
-
client.shape: nil, a corner radius in pixels, or a gears.shape function. gears.surface.apply_shape_bounding sets it on a client as it sets wibox.shape. gears.shape.rounded_rect, or a function drawing its path, is read as that radius; any other function warns once naming the client, which stays square. A titlebar takes the corners on its edge and the surface the rest. The suite's headless runner keeps a WLR_RENDERER already set in the environment instead of forcing pixman.
-
awful.widget.calendar_popup.month and .year take a width argument, defaulting to beautiful.calendar_popup_width, and the popup is an awful.popup placed by its position inside the workarea; awful.popup gains honor_workarea.
-
screen.inspector: Clay's debug inspector on that screen, its element tree and the selected element's solved box and configuration; property::inspector fires on a change, also when the panel's close button closes it. somewm.inspector.toggle(s) flips it on s or the focused screen, and somewm.inspector.restyle() re-reads the theme: beautiful.inspector_bg, inspector_bg_alt, inspector_border, inspector_fg, inspector_bg_selected, inspector_highlight, inspector_width and inspector_font.
-
somewm-client clay tree [screen] prints what the last frame solved on every output, or on one screen: counters per band, then one line per retained node in draw order.
-
beautiful.launcher_width: the menubar launcher's width, ahead of menubar.geometry.width; without either the launcher spans the workarea.
-
Client and drawin entrances and exits accept lists such as
{"fade", "slide_left"}to compose simultaneous effects in one transition. One slide, grow and fade can run together with one duration; existing strings still work. Repeated effects and collapse-as-grow are deduplicated. Conflicting slide directions, or none with another effect, warn once and keep the first named effect so incompatible settings are not silently ignored. -
Client animation by trigger:
c.animation = {appear, disappear, tag, focus, maximize, floating}and the rule property of the same name, with the theme keys beautiful.animation_appear, animation_disappear and animation_tag (grow, slide_left, slide_right, slide_up, slide_down, fade) and the durations animation_appear_duration, animation_disappear_duration, animation_tag_duration, animation_focus_duration, animation_maximize_duration and animation_floating_duration. beautiful.animation_duration supplies the fallback for triggers without their own duration, including layout. A focus change eases the border colour. With a tag duration set, a tag switch grows clients in and out unless c.animation.tag or beautiful.animation_tag names another entrance. A client exit animates its frame only; the surface snaps. -
animation = {visible = {duration, enter, exit}}on wibox and awful.popup, with the same entrances. A drawin's exit drops its shadow at once. -
widget.animation = {property = duration}for bg, border_color, border_width, forced_width, forced_height and the progressbar and slider value, andwidget:animate{property = value, duration = d}for one change. Positions snap. Past 200 transition records per output, including configured idle records, the remaining nodes snap, with one warning. The.animationproperty stores the policy separately from the:animatemethod. Withwidget.animation = false, the method applies values immediately and remains callable. Policy changes emitproperty::animation. -
Animation policies on clients, wiboxes, popups and widgets are copied on assignment and access. Reassign an edited policy to apply it and notify observers.
animation = falsesuppresses the object and its descendant animations;nilremoves the override. The globalsomewm.animation.enabledswitch and mouse grabs also suppress drawin transitions. Active transitions finish on the next rendered frame when disabled, including retained exits.
Changed
-
wibox.layout.align with expand = "none" gives each outer widget half of what the middle widget leaves, as v2.0.0 and AwesomeWM do, so the middle stays centered. An outer widget wider than its half shrinks its contents and is cut at the half. The bundled bar's tasks shrink to share the left half, and each title ends in an ellipsis.
-
Assigning a table that is not an animation policy to widget.animation, client.animation or a wibox's animation keeps the table as the object's own field and warns once, instead of copying it. Configs that already used that name for their own objects (yoru, KwesomeDE) load again.
-
Widgets in a wibox or popup receive pointer events while its entrance animation runs; previously the entrance window swallowed them.
-
somewm always builds with XWayland support; the -Dxwayland build option is gone, and a build without it had not compiled. Building needs xcb, xcb-icccm and Xwayland installed, and running X11 applications needs the Xwayland binary.
-
Client shape masks are accepted and never read: shape_bounding, shape_clip and shape_input, and client_shape_bounding, client_shape_clip and client_shape_input, which always read nil. A client's corners come from its shape property.
-
A wibox with an opacity below 1 blends each of its fills at that opacity, so fills that overlap add up: a blue background container on a blue wibox at opacity 0.5 shows denser blue than either alone. 2.0 blended the whole wibox once.
-
A drawin's widget tree holds at most 4096 nodes; a larger tree shows nothing and the drawin warns once that it is over the output's element budget.
-
An imagebox without a forced size takes its size from the bound above it: the cross-axis bound times its aspect, lowered to the flow-axis bound when that is smaller, as 2.0's fit did. With no bound on either axis, along a flex or linear layout's flow, it declares its natural size and can leave slack or overflow its parent. An imagebox forced on one axis scales its image to that axis.
-
Hotkeys help and menubar scroll instead of paging; every key and item stays reachable. Hotkeys: one column per group, continued every
beautiful.hotkeys_rowsrows (new theme value, default 20); PgDn/PgUp scroll by one viewport; the "PgDn - Next Page"/"PgUp - Prev Page" labels are gone. Menubar:left_label/right_labelshow while items lie beyond that side. A bordered popup whose content is larger than its slot keeps its slot geometry; the content is clipped as it was already drawn. -
A non-homogeneous grid no longer sizes its columns to the widest cell across rows.
-
A homogeneous grid inside a content-sized box takes content-sized cells and warns.
-
A row span occupies its first row only and warns.
-
Grid border dashes draw as solid lines and gradient border colours are transparent, both warn.
-
A client whose protocol minimum exceeds its tiled cell overhangs the cell; the workarea and its neighbours keep their size and c:geometry() reports the cell.
-
An ontop, above or below client under a stock layout now tiles into its slot, as in AwesomeWM, instead of keeping its last box.
-
Under max and magnifier a floating client is above the layout's clients whatever the raise order, as under tile, including a floating parent whose transient is tiled under max.
-
A transient of a max or magnifier client is a root of its own above every client of that layout, not above its parent only.
-
c.size_hints now reports min_width, min_height, max_width and max_height for Wayland clients, from the toplevel's committed bounds (0 means none); property::size_hints fires when they change. A Wayland client whose min equals max now reports is_fixed and floats, as an X11 client with those hints did.
-
A client whose rules set no border_width now draws no border, as in AwesomeWM; before, the theme's border_width was applied from C and could not be read from Lua.
-
property::border_color also fires on a client when the focus recolour changes the drawn border, with c.border_color unchanged unless a config set it.
-
property::scroll_factor on wibox.layout.overflow fires once the frame has applied a change, from a setter, scroll() or the mouse wheel, with the applied factor; before, it fired inside the setter with the requested value and never for the wheel.
-
property::scroll_factor on wibox.layout.overflow also fires when a change in content or viewport size moves the factor without a scroll, and does not fire when a set leaves the applied factor unchanged.
-
A slider bar_color gradient without bar_margins is drawn in the bar's box; upstream used the widget's box. Clay centres the bar.
-
An arcchart colors gradient in a non-square box is drawn in the box; upstream used the centred square.
-
A separator color gradient on a horizontal or vertical line is drawn in the line's box; upstream used the widget's box.
-
Text under a rotate or mirror draws as one line; a textbox with more than one line under one is left out with a warning.
-
A wibox.container.scroll under a rotate or mirror, and a rotate or mirror inside another, are left out with a warning.
-
A widget under a rotate receives press coordinates relative to its rotated box; v2.0.0 mapped them through the container's matrix into the widget's own frame.
-
Setting c.shape stores it, emits property::shape and arranges the screen; a shape that is not a rounded rectangle warns once naming the client, and the client stays square.
-
The client and drawin shape mask warnings name shape_bounding, shape_clip and shape_input.
-
A layout leaf that is both placed (x or y) and sized (grow, fit or a percent) on the same axis is left out of the tree with one warning naming the client. Before, the leaf floated at x,y with its sized box and could run past the output.
-
somewm builds its own wlroots 0.20.2 and links it in; an installed wlroots is not used. The wlroots 0.19 path and
-Dwlroots_versionare gone. A distro whose wayland, libdrm, xkbcommon, pixman or wayland-protocols is older than wlroots 0.20.2 gets that library built alongside it. -
A function bgimage on a wibox or a wibox.container.background is not drawn; setting one warns and clears the image. 2.0 called it to paint the background.
-
A shape function is used as the path it traces; anything else it does, such as setting a source or painting, is dropped. 2.0 ran it on the widget's cairo context.
-
A client frame declares a transition only when the layout duration is above 0, so an output with clients solves its layout once per frame instead of twice. A client's first frame after the duration is set, or after a reload, does not animate.
-
A textbox wraps at words whatever its wrap is; wrap = "char" warns once. 2.0 broke inside a word for "char", and for the default "word_char" when a word did not fit the line.
-
wibox.container.tile with tiled true, its default, draws one copy of its widget, placed as wibox.container.place places it, and warns once. 2.0 repeated the widget across its box.
-
A fractional padding, gap, offset or border width rounds to the nearest whole pixel. 2.0 kept the fraction.
-
The interactive awful.screenshot's overlay covers the screen under the pointer when snipping starts, rather than the whole root; 2.0 drew it across every output. A drag that crosses screens still selects its root-space box, and the rectangle shows on the screen it started on.
-
somewm.layout_animationis deprecated. Layout changes animate whensomewm.animation.layout_durationorbeautiful.animation_layout_durationis above 0; requiring the old module still sets 0.15 as it always did.
Removed
-
The
fit,draw,layout,before_draw_childrenandafter_draw_childrenmethods of the stock widget, container and layout classes (73 methods over 33 classes). Clay sizes and places every widget from its description, so no stock class measures, lays out or paints itself. -
wibox.hierarchyand thewibox.hierarchyfield:new,count_widget,update,get_widget,get_matrix_to_parent,get_matrix_to_device,get_matrix_from_parent,get_matrix_from_device,get_draw_extents,get_size,get_children,get_countanddraw. The widget tree is declared to Clay; no tree of placed widgets is kept to walk. -
The
wibox.widget.baseplacement helpersfit_widget,layout_widget,place_widget_at,place_widget_via_matrixandrect_to_device_geometry. Clay places every widget. -
wibox.widget.draw_to_cairo_context,draw_to_image_surfaceanddraw_to_svg_file. Widgets no longer paint into cairo; the renderer draws their description. -
wibox:to_widgetandwibox:save_to_svg, for the same reason. -
wibox.container.border. No configuration uses it; loading it is an error. -
Properties no configuration sets:
horizontal_offset(wibox.layout.stack),minimum_column_widthandsuperpose(wibox.layout.grid, which always refuses a widget added over another),inner_fill_strategy(wibox.layout.ratio),stretch_horizontallyandstretch_vertically(wibox.container.background),paddings(wibox.container.radialprogressbar),horizontal_cropandvertical_crop(wibox.container.tile),auto_dpiandsource_width(wibox.widget.imagebox),ticks_gap(wibox.widget.progressbar),bar_border_color,bar_border_widthandhandle_margins(wibox.widget.slider),empty_cell_mode,empty_colorandempty_widget(wibox.widget.calendar), andcheck_border_color,check_border_widthandcheck_shape(wibox.widget.checkbox, whose check takesshape). Setting one warns once that it is ignored; reading one gives nil. The theme variables only they read are gone too:radialprogressbar_paddings,slider_bar_border_color,slider_bar_border_width,slider_handle_margins,calendar_empty_color,checkbox_check_border_color,checkbox_check_border_widthandcheckbox_check_shape. -
The scroll container's draw-context fields
context,first_x,first_y,fit_width,fit_height,hierarchy,surface_widthandsurface_height. The container is a Clay scroll element and no longer draws its child into a surface of its own. -
awful.wallpaperuncovered_areas_color,dpiandget_dpi. Setting one warns once: the root wallpaper shows in the uncovered areas, and the output scale applies. -
carousel.scroll_duration. Scrolling animates client slots over the layout duration. -
somewm.layout_animation.easing. Clay animates the transition; setting it warns. -
The drawin
surface_scaleproperty. A drawin has no surface of its own to scale. -
The drawable
refreshmethod andsurfaceproperty. A drawable holds no cairo surface. -
awesome.systray; usewibox.widget.systray. See the 2.0 to 2.1 upgrade guide. -
wibox.widget.textbox:get_preferred_size,wibox.widget.textbox:get_preferred_size_at_dpi,wibox.widget.textbox:get_height_for_width,wibox.widget.textbox:get_height_for_width_at_dpi,wibox.widget.textbox.get_markup_geometryandmenubar.utils.compute_text_width. Clay measures text; nothing measures it in Lua. -
awful.client.shape:get_transformed,update.all,update.bounding,update.clipandupdate.input. The shape was never applied on Wayland. -
menubar.utils.compute_textbox_width. It measured throughtextbox:get_preferred_size, which is gone. -
ruled.client.completed_with_payload_callback. It was an alias ofruled.client.execute; call that. -
The drawin
shape_borderproperty, a border surface drawn in Lua. The renderer draws the border of a shaped wibox itself. -
wibox.widget.base.no_parent_I_know_what_I_am_doing, the marker forbase.fit_widgetandbase.layout_widget, which are gone. -
The wibox
__tostring.tostring()of a wibox prints the table, where 2.0 printedwibox: <drawable> (<table>). -
awesome.start_animation. An animation is a transition on the declaration.
Fixed
-
A menu opened at a point (a tray icon's menu,
awful.menu:show) slides back inside its screen instead of opening past the edge, as on AwesomeWM. Submenus still open to the right of their item. -
Tray menu separators are a line instead of an item labelled
---. Abeautiful.systray_menu_callbacknow receives them as{ new = ... }entries. -
A tree dump taken in the last frames of a right-anchored scale animation read past its list of anchor names.
-
A tree dump taken in the same dispatch a client unmapped read freed memory. The dead client's surface now reads as
no-nodeuntil the next frame drops it. -
An explicit
disappear = "none"orexit = "none"closes without an animation instead of falling back to the tag exit. -
A bordered or shadowed wibox or popup that grows in or out shows its content inside the growing frame, instead of at its full size behind it.
-
Xwayland content-size requests are declared inside the Clay client frame, so repeated and partial requests no longer shift or shrink decorated floating windows. Geometry replies use the completed solve, with request masks, gravity, size limits and compositor allocations respected.
-
Xwayland clients default to full opacity, keeping Steam and Proton windows visible after switching tags without needing a hover to redraw them.
-
Explicitly positioned
awful.popupwindows size to their content and respect size limits when a border, shadow or visibility animation adds an outer frame, instead of remaining at their initial 1×1 geometry. -
Packages built with
--auto-features enabled, such as Arch'sarch-meson, no longer abort when the pointer moves from the bar into a menu. The renderer's debug verifier is on only in sanitizer and test builds, and therender_verifybuild option is gone. -
Nested X11 and Wayland pointers map to their host output, so multiple outputs no longer stretch absolute pointer coordinates across the whole layout.
-
client.icon rejects LGI surface records and other non-pointer values with a Lua type error instead of interpreting userdata storage as a Cairo surface. Assign awesome.load_image() or a Cairo surface's _native pointer instead.
-
Systray registrations share one pending property fetch per item, preventing duplicate icons after a reload and allowing retries when the fetch fails.
-
wibox.widget.textbox keeps its last applied font when setting a font fails, so a rejected name can be retried.
-
somewm-client tag commands use the loaded layout module, so adding a tag and setting its gap, layout or master width factor no longer fail on an undefined global.
-
A toplevel's bounds are the workarea, never the size it drew. A GTK window that drew its own size once (ghostty) was sent that size as its bounds and stayed at it, 800 wide in a full cell, whatever the compositor asked afterwards.
-
wibox.layout.grid emitted property::minimum_column_width when minimum_row_height changed.
-
A rounded background, border or clipped widget draws through somewm's wlroots build instead of a cairo raster: resizing, moving or clipping it rasters nothing, and a titlebar's or bar's corner radius is no longer cut to half the bar's height when only two corners are rounded.
-
A client shaped with a rounded rectangle (gears.surface.apply_shape_bounding with gears.shape.rounded_rect, or client.shape) draws rounded corners on Wayland, through somewm's own wlroots 0.20.2 build: the surface and the titlebar on an edge are cut by their radii under gles2 and pixman, nothing under a cut corner is culled, a click in the corner reaches what is below, and screen.content shows the cut. 2.0 accepted the shape and drew a square.
-
A client that commits a size other than the one it was configured is drawn at the committed size: its titlebar, border, shadow and corners wrap the surface, and the next configure still carries the layout's or the user's box. 2.0 drew the frame at the configured size, so a terminal keeping whole cells had its titlebar overhang the surface.
-
A slider bar_active_color gradient now draws. Upstream raised an error for a gradient string (parse_color returns nil for it and add_color_stop_rgba fails) and skipped the active part for a gradient table.
-
Every new client starts with size_hints_honor true, as the property documents and as 1.4 and AwesomeWM do; 2.0.0 started it false. A client's protocol minimum and maximum now reach the dump and the solve without a rule setting the flag. Rules that set it false keep winning.
-
client.get(), client::list, the stack and _NET_CLIENT_LIST see a client from its first map, as in AwesomeWM. Before, a surface that was created and never mapped was listed with no name, class or pid, and wlroots' no-focus window stayed listed from the first X client until exit.
-
The systray urgent, hover and overlay backgrounds and the grid hole take a gradient, filling the node's own box with its points as authored. A surface or mesh pattern warns once naming urgent_bg, hover_bg, overlay_bg or border_color, and the node stays transparent. Before, each of these drew nothing and said nothing.
-
Wrapped text with a word wider than its box, then a space, then a newline no longer crashes the compositor. That line draws as an empty line.
-
The bundled bar puts the clock between its left and right groups; before it floated over the tasklist.
-
A client that acknowledges a new size and keeps drawing its old one, as ghostty does after moving to a screen with another scale, is sent the size again up to three times a second apart and takes its cell. Before, it was sent once more and could stay at its old width beside an empty strip.
-
A client that draws larger than its cell, as a terminal moved from a bigger screen does, no longer grows the cell, the row and the screen's workarea; its drawing is cut at the cell and it is asked for the cell.
-
A Wayland window that hides by dropping its buffer and shows again is configured, maps and is managed again, as a new client object, as AwesomeWM does for a window withdrawn and mapped again. Before, it waited for a configure that never came and never showed again.
-
make install removes the installed Lua tree (somewm/lua in the install's datadir) before installing, so a module removed since the last install is gone. Before, 2.0's wibox.hierarchy and wibox.container.border stayed and loaded in place of the error a config should get.