Text fields set view->cursor = textCursor ("xterm") at creation.
When the pointer moves into a different WINGs child view, apply
the view cursor via W_SetCursorImageFn instead of waiting for
WME_MOTION with pointerGrabbed.
Motion events in dialogs (fake_leader frame_bufs with low IDs) were
not resolving the WINGs child view, so WME_ENTER was never sent to
the text field. Now look up the WINGs panel via client_leader.
When a dialog is closed, its views are freed but last_hovered_view
may still point to them. Use W_IsValidView() guard before accessing
the stale pointer.
When the pointer moves between WINGs child views (e.g. into a text
field), synthesize WME_ENTER/LEAVE events. This triggers the i-beam
cursor change in wtextfield.c which fires on WME_ENTER.
- Track current_buttons bitmask on press/release
- Set u.motion.state = current_mods | current_buttons so WINGs
text fields see WM_BUTTON1_MASK during click-drag selection
- Implement wl_set_cursor via W_SetCursorImageFn hook for i-beam
Implement wl_set_cursor() to forward cursor name strings to the
compositor via a function pointer. Initialize textCursor/defaultCursor/
invisibleCursor in wl_screen_init with xcursor name strings.
wApplicationDestroy needs main_window_desc (the wwin) to clean up
the appicon and remove the app from the screen list. Call it before
wUnmanageWindow which frees wwin. This restores the appicon to
"not running" state when a Wayland client closes.
wApplicationOf must be called before wUnmanageWindow because the
latter frees the WWindow struct. Accessing app->main_window_desc
afterward is a use-after-free.
Enables screen locker clients (swaylock, waylock) to lock the
session. On lock: confirms locked state to client. On new_surface:
configures lock surface to cover the output and adds it to the
scene overlay layer. On unlock: clears locked state.
After removing frame_bufs from the view_table, policy code like
update_icon_title still passes frame_buf IDs to WMDrawString.
These IDs (0x10000000 range) were being treated as raw pointers,
causing a segfault. Add W_GetFrameBufImageFn hook that resolves
frame_buf IDs to pixman images via frame_buf_find().
WMGetColorRGBDescription() returns wmalloc strings that were passed
directly to allocFrameBorderPixel without freeing. get_default_image()
and get_icon_image() leaked path strings from FindImage/get_icon_filename.
When destroying a frame_buf tree, any other frame_bufs whose trees
were reparented into it (e.g. fake_leaders) would have their
tree_destroy_handler fire on already-freed memory during cascade.
Detach their listeners and NULL their tree pointers before
destroying the parent tree.
When destroying child frame_bufs, the tree node was not destroyed
before wlr_buffer_drop freed the struct. Later, cascade destruction
of the parent tree would fire fb_tree_destroy_handler on the freed
child, corrupting the heap. Destroy the child tree explicitly first.
Call wlr_scene_buffer_set_buffer(NULL) before freeing the old pixman
image in every resize path (client configure, frame configure,
workspace badge, balloon). This ensures the scene graph never holds
a dangling reference to freed pixel data.
The in-place resize of titlebar pixman images continues to cause heap
corruption regardless of scene buffer detach order. Fall back to
drawing into the parent frame buffer when the titlebar is too narrow,
which is always safe since fb->image is already the correct size.
Frame_buf IDs (0x10000000-0x1FFFFFFF) were registered in the 256-entry
view_table alongside WINGs views, filling it with tombstones until
lookups failed. Now frame_buf IDs are excluded from the table; the 3
callers that passed frame_buf IDs to WMDrawString pass raw pixman
pointers instead.
Draw white text at 5x5 offsets to build a shape mask (like the
original XShape-based approach), then draw centered text at (2,2)
and apply the mask as alpha. This gives the same outlined text
appearance as the X11 version.
Add client_set_fullscreen backend vtable entry. Call
wlr_xdg_toplevel_set_fullscreen on enter/leave so clients
(e.g. Firefox) know to render content at full size.
Call wlr_scene_buffer_set_buffer(NULL) before freeing the old pixman
image so the scene graph cannot access freed data. Re-register the
backing table entry after creating the new image.
Call wlr_scene_buffer_set_buffer(NULL) before destroying the tree
and freeing the pixman images to prevent the scene graph from
accessing freed memory during its next render pass.
Use fixed-point x positions, strong upward initial velocity (-15 to
-21), gravity of 1 pixel/frame², only ~50%% of tiles, and run until
all pieces leave the screen. Full-screen scene buffer so pieces
can fly freely.
wl_frame_paint replaced the titlebar pixman image while the scene
graph could still hold a wlr_buffer reference to the old data.
Falling back to the parent frame buffer when the titlebar is too
narrow avoids the use-after-free.
Update drag_icon_tree position in handle_pointer_motion so the icon
follows the cursor during drag. Use wlr_scene_drag_icon_create for
proper lifecycle. Remove listeners in handle_drag_destroy. Always
forward button releases so drags end correctly.
When a drag grab is active, wlroots internally handles button events
via the grab mechanism. Calling wlr_seat_pointer_notify_button
manually during a drag double-delivers the release, causing an
assertion in wlr_data_source_destroy.
When a client starts a drag with an icon surface, create a
wlr_scene_subsurface_tree in the overlay layer and position it
at the cursor. Update position on drag motion, destroy on end.
When a Wayland drag is active (seat->drag), always forward button
events so wlroots can properly end the drag. Without this, the
release never reaches the drag grab, causing stuck drags and
assertion failures on client teardown.
Preserve pointer focus while buttons are held (implicit grab) to
ensure the client gets the release. Still deliver motion events to
the focused surface so drag and text selection work correctly.
wlr_seat_pointer_notify_button asserts unconditionally if no surface
has pointer focus, even for releases. Never call it without a focused
surface. This means clients may miss releases if pointer leaves their
surface during a drag, but avoids the compositor crash.
Wayland data transfers (drag-and-drop, clipboard) use pipes between
clients. If a client disconnects mid-transfer, writing to the pipe
raises SIGPIPE which kills the compositor. Ignore it.
Use XSync instead of XFlush for the initial capture to give the X
server a round-trip to process the map. Remove the deferred timer
re-capture which could crash if the icon was destroyed before firing.
findMenu() was not searching drawer menus, so pointer motion over
a drawer menu returned NULL causing the event loop to ignore input.
Add iteration over scr->drawers to findMenu().
XWayland dockapps (wmclock, etc.) now render their content inside the
dock icon tile instead of in a separate window.
Key changes:
- wl_props.c: implement wl_prop_get_wm_hints for XWayland surfaces,
reading xcb_icccm_wm_hints_t to detect WithdrawnState dockapps
- appicon.c: for is_dockapp windows, use client_win as icon_win
- icon.c: capture icon_window pixels via XGetImage with XShape mask
for transparency, skip surface embedding when image is captured
- wl_icon.c: create_rimage_from_drawable handles X11 Window IDs via
XGetImage, applies XShape bounding rectangles as alpha mask
- wl_stubs.c: pixmap_get_size returns actual view dimensions
- wl_window.c: map XWayland dockapp windows and reparent icon_window
child into main window for compositing
Three leaks identified via static analysis:
1. frame_buf_destroy never freed fb->bg_pixmap. Every window with a
textured titlebar leaked a full pixman_image_t on close.
2. handle_xwayland_destroy did not clean up frame_bufs (unlike the XDG
path). Every XWayland window close leaked 4-5 pixman images (frame +
titlebar + resizebar + buttons).
3. wl_deferred_decoration struct leaked if client disconnected before
initial_commit fired. Added destroy listener to free it.
Screenshot tools (slurp) use layer-shell overlay surfaces that need
pointer input. Check if the pointer is over a layer surface before
falling through to the toplevel/frame_buf focus logic.
wlroots 0.19 asserts that the surface is initialized before
wlr_layer_surface_v1_configure is called. Defer the configure to the
initial commit, matching the pattern used for xdg_toplevel surfaces.
Fixes screenshot tool crash.
The WINGs view_table (open-addressing hash, size 256) used id=0 as both
"empty" and "deleted". Zeroing a slot on removal broke probe chains for
entries that hashed past that slot. After two dialog open/close cycles
(~40 views created and destroyed), enough chains were broken that
W_GetViewForWindow/W_GetViewBacking returned NULL for valid IDs.
Fix: use a tombstone marker (id=1) for deleted slots. Lookups skip
tombstones (continue probing), inserts reuse them. This is the standard
approach for deletion in open-addressing hash tables (Knuth Vol.3 §6.4).
Also:
- wl_destroy now calls view_table_remove + frees backing pixman image
- wl_frame_destroy cleans up child frame_bufs
- client_reparent existing path re-links backing and recreates scene_buf
- client_reparent to root destroys the child frame_buf
Native Wayland clients have no _NET_WM_ICON or WM hints icon. Before
falling back to the default icon, search the hicolor icon theme at
/usr/share/icons/hicolor/<size>/apps/<app_id>.png and /usr/share/pixmaps/
for a matching icon based on the xdg_toplevel app_id.
wlr_xdg_surface_surface_at expects surface-local coordinates (including
the shadow region). Add geometry.x/y back when converting from screen
coords to surface-local so the hit test aligns with the actual content.
CSD clients like Firefox may not set window_geometry until after the
initial map. Update the scene node offset on every surface commit so
the content stays aligned with the frame as geometry changes.
Without this, moving a CSD client (Firefox) causes the surface to
"pop" out of the WM frame — the scene node was positioned at the
raw frame-relative coords without subtracting geometry.x/y.
Firefox and other CSD clients include invisible shadow borders in their
surface buffer. Use xdg_surface->geometry (the client-declared content
rect) for:
- reporting client width/height to the WM frame
- sizing the frame on commit
- offsetting the scene node so shadows are outside the frame bounds
Falls back to surface->current.width/height when geometry is unset.
Previously wm_instance was set to the window title, but docked icons
store app_id as their wm_instance. This mismatch caused
wDockTrackWindowLaunch to fail matching the new window to the docked
icon, resulting in a duplicate free-floating appicon being created.
Add the solid colored title background rectangle with light/dim bevel
edges that X11 draws via drawIconTitleBackground. This gives miniwindow
icons their characteristic "flat" title bar appearance, distinguishing
them from appicons which lack this bar.