Commit Graph

721 Commits

Author SHA1 Message Date
lkn b9c37c6629 fix animation architecture: delegate slide/move to backend vtable
Core code must not call backend directly. misc.c:slide_windows and
move_window now delegate to wm_backend->slide_windows/move_window.
Wayland backend implements both using scene node moves + event_flush.
2026-06-24 19:41:41 +02:00
lkn 1331103ce7 perf: skip frame repaint during resize grab, paint on release
wl_frame_paint is expensive (pixman blit per motion event).
Decorations content does not change during resize, only geometry.
Skip repaint while grab_type==2; repaint once on grab release.
2026-06-24 19:28:30 +02:00
lkn 12d49c6642 perf: block event loop with -1 timeout instead of spinning
Use epoll blocking dispatch so the compositor sleeps when idle.
WINGs timers and frame callbacks still wake the loop as needed.
2026-06-24 19:26:16 +02:00
lkn 4897e1637b perf: schedule frame after every grab motion for 144Hz smoothness
Without schedule_frame, drag/resize updates sit in the scene graph
until the next natural vsync. At 144Hz this is 7ms max. Scheduling
after each motion ensures the next frame picks up the move/resize.
2026-06-24 19:22:43 +02:00
lkn c37fd28572 perf: reduce event loop timeout to 4ms, remove polling schedule_frame
The 16ms dispatch timeout added up to 16ms of input latency.
4ms reduces this to ~4ms maximum.

Removing unconditional wlr_output_schedule_frame from the main loop
stops flooding the swapchain. The output frame callback in
handle_output_frame drives rendering at vsync naturally.
2026-06-24 19:15:31 +02:00
lkn 70659969d6 debug: log xcursor output scale 2026-06-24 19:13:07 +02:00
lkn 0c295dcf09 wayland: fix shade crash and titlebar visibility when shaded
Two issues with window shading:

1. wShadeWindow resizes the frame to top_width-1 tall. wl_frame_paint
   used the unclamped fwin->top_width as titlebar blit height, writing
   one row past the pixman buffer. Heap corruption detected by glibc on
   next free (RReleaseImage) caused SIGABRT. Fix: clamp tb_h to total_h.

2. The parent frame scene_buf was only enabled when show_resizebar was
   true. When the titlebar child buffer is too narrow (falls back to
   drawing into the parent), the shaded frame had its scene_buf disabled
   and the titlebar was invisible. Fix: always commit and enable the
   parent scene_buf (cleared to transparent, so unused areas are safe).
2026-06-24 19:02:52 +02:00
lkn 144b089dff fix UAF: NULL last_hovered_view when view is destroyed
W_ViewDestroyedFn hook clears last_hovered_view when the pointed-to
view is destroyed. Prevents use-after-free in motion handler when
the hovering over a view inside a dialog that is then closed.
2026-06-24 00:20:07 +02:00
lkn 9c954de71e load xcursor manager for scale 1 and 2 2026-06-23 23:57:34 +02:00
lkn f73630be43 fix cursor: dont reset to left_ptr over WINGs/WM frame_bufs
wl_update_pointer_focus reset cursor to left_ptr on every motion
event when no Wayland surface was under the pointer. WINGs compositor
views are pixman scene nodes, not Wayland surfaces, so surface was
always NULL over dialogs. Now preserve cursor when over frame_bufs.
2026-06-23 23:54:33 +02:00
lkn 70a456b72d debug: log cursor change on view hover 2026-06-23 23:52:17 +02:00
lkn 2c3f244983 ibeam: read attribs.cursor from view on hover 2026-06-23 23:51:32 +02:00
lkn c6eba5ed58 ibeam cursor: apply view attribs.cursor when pointer enters WINGs view
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.
2026-06-23 23:50:11 +02:00
lkn 9089c3637d log xcursor theme and size at startup 2026-06-23 23:46:59 +02:00
lkn c343dfc00a text cursor: resolve WINGs target for fake_leader dialogs
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.
2026-06-23 23:44:45 +02:00
lkn 1e4d36143e fix crash: validate last_hovered_view before LEAVE event
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.
2026-06-23 23:43:32 +02:00
lkn 6d3de364f5 text fields: synthesize ENTER/LEAVE for WINGs child views
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.
2026-06-23 23:40:44 +02:00
lkn c8053b98e5 text fields: button state in motion events + i-beam cursor
- 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
2026-06-23 23:36:28 +02:00
lkn 7f5dd5f682 text fields: i-beam cursor via W_SetCursorImageFn hook
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.
2026-06-23 23:13:06 +02:00
lkn 2581233351 fix appicon state: destroy WApplication before wUnmanageWindow
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.
2026-06-23 23:01:24 +02:00
lkn 0fcbe20cad fix UAF: get WApplication before wUnmanageWindow frees wwin
wApplicationOf must be called before wUnmanageWindow because the
latter frees the WWindow struct. Accessing app->main_window_desc
afterward is a use-after-free.
2026-06-23 22:59:44 +02:00
lkn 9e91722e02 session lock: focus keyboard on lock surface
Swaylock needs keyboard focus to receive password input.
2026-06-23 22:45:49 +02:00
lkn daa08d23aa add ext-session-lock-v1 protocol support
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.
2026-06-23 22:44:38 +02:00
lkn 03eede810b fix crash: resolve frame_buf IDs via W_GetFrameBufImageFn
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().
2026-06-23 22:40:49 +02:00
lkn b20197ac91 fix memory leaks: free color description strings and icon paths
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.
2026-06-23 22:20:40 +02:00
lkn a6f43cdbe1 fix use-after-free: detach reparented children before tree destroy
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.
2026-06-23 22:16:42 +02:00
lkn 01904fdb39 fix use-after-free: destroy child tree before dropping buffer
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.
2026-06-23 22:08:29 +02:00
lkn 69b08e6cfb add wl_kaboom.c to Makefile.am 2026-06-23 22:04:03 +02:00
lkn 7f6a7b66d1 detach scene buffer before all pixman image replacements
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.
2026-06-23 21:42:00 +02:00
lkn 711ff08b57 revert unsafe titlebar resize: draw into parent frame instead
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.
2026-06-23 21:24:52 +02:00
lkn 49a0b50a6d fix widget rendering: stop polluting view_table with frame_buf IDs
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.
2026-06-23 21:22:14 +02:00
lkn f96c847cf7 workspace name: match original bold shadow text rendering
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.
2026-06-23 20:50:52 +02:00
lkn 6ae9ad3dc5 handle xdg_toplevel unset_fullscreen request
Check toplevel->requested.fullscreen to determine whether the client
wants to enter or leave fullscreen, and call wUnfullscreenWindow
accordingly.
2026-06-23 20:47:04 +02:00
lkn 321df47493 send XDG fullscreen state to Wayland clients
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.
2026-06-23 20:40:57 +02:00
lkn dd1302a711 fix titlebar resize: detach buffer from scene before replacing
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.
2026-06-23 20:35:31 +02:00
lkn c2c3bca41b kaboom: detach buffer from scene before freeing pixel data
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.
2026-06-23 20:32:28 +02:00
lkn ac74064d1c kaboom: match original X11 physics
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.
2026-06-23 20:30:52 +02:00
lkn 503cdb5dca fix crash: heap corruption from unsafe titlebar buffer resize
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.
2026-06-23 20:23:24 +02:00
lkn 146f41008d wayland: implement kaboom animation for dock icon removal
Splits icon into PIECE_SIZE tiles, animates them falling with
gravity using a wl_event_loop timer and a single scene buffer.
2026-06-23 20:16:33 +02:00
lkn 976bcce34c fix DnD: drag icon follows cursor, clean up listeners
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.
2026-06-23 20:08:39 +02:00
lkn ce696a72a0 fix DnD crash: do not double-deliver button events during drag
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.
2026-06-23 17:33:36 +02:00
lkn 467805da20 render DnD drag icon surface following cursor
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.
2026-06-23 17:32:10 +02:00
lkn b90908da6a fix DnD freeze: forward button events during active drag grab
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.
2026-06-23 17:29:39 +02:00
lkn 311ccfbdd9 fix drag freeze/crash: implicit grab with motion delivery
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.
2026-06-23 13:43:42 +02:00
lkn 10389bbba5 fix crash: only forward button events when seat has pointer focus
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.
2026-06-23 13:39:08 +02:00
lkn 8c306b3e3c ignore SIGPIPE to prevent crash on DnD/clipboard pipe close
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.
2026-06-23 13:34:07 +02:00
lkn 89393e1782 fix dockapp capture: use XSync, remove crash-prone timer
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.
2026-06-23 13:22:33 +02:00
lkn 074e9a7011 fix drawer right-click menus not responding to mouse input
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().
2026-06-23 13:01:09 +02:00
lkn b6ad1df42e wayland: implement dockapp rendering inside dock icons
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
2026-06-23 12:55:48 +02:00
lkn 1728c38fbe wayland: fix resource leaks causing freeze after extended use
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.
2026-06-22 18:59:08 +02:00