wayland: Phase 56 — prop_set/get_wm_state persists WM state in view struct

Add wm_state/wm_state_n fields to wl_toplevel_view.  prop_set_wm_state now
stores the 10-long WM state array (workspace, miniaturized, shaded, hidden,
geometry, shortcut slots) in the view; prop_get_wm_state returns a heap
copy so wWindowGetSavedState works correctly when a Wayland client
reconnects.  handle_toplevel_destroy frees the stored state on cleanup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-03-28 07:28:59 +01:00
parent 49246f80ca
commit e727bdbad0
1 changed files with 22 additions and 2 deletions

View File

@ -37,6 +37,8 @@
* state; pointer_query/query_full return tracked coordinates.
* Phase 55: window_get_rect returns real geometry for synthetic toplevel IDs;
* window_move records WM-assigned x,y in the view struct.
* Phase 56: prop_set/get_wm_state persist WM state (workspace, miniaturized,
* shaded, etc.) in the view struct so wWindowGetSavedState works correctly.
*/
#ifdef HAVE_CONFIG_H
@ -88,6 +90,8 @@ struct wl_toplevel_view {
struct wl_listener title_listener; /* Phase 46: xdg_toplevel set_title */
WNativeWindow id; /* synthetic handle, >= 0x10000000 */
int x, y; /* Phase 55: WM-assigned position */
long *wm_state; /* Phase 56: saved WM state or NULL */
int wm_state_n; /* Phase 56: element count */
struct wl_list link; /* wl_state.toplevel_list */
};
@ -276,6 +280,7 @@ handle_toplevel_destroy(struct wl_listener *listener, void *data)
wl_list_remove(&view->title_listener.link);
wl_list_remove(&view->link);
wl_state.managed_surface_count--;
if (view->wm_state) wfree(view->wm_state); /* Phase 56 */
wfree(view);
}
@ -864,11 +869,26 @@ static int wl_prop_has_gtk_object_path(WNativeWindow win) { (void)win; return 0
static void
wl_prop_set_wm_state(WNativeWindow win, const long *data, int n)
{ (void)win; (void)data; (void)n; }
{
/* Phase 56: store WM state in the view struct for later retrieval. */
struct wl_toplevel_view *v = wl_find_view_by_id(win);
if (!v || !data || n <= 0) return;
if (v->wm_state) wfree(v->wm_state);
v->wm_state = wmalloc((size_t)n * sizeof(long));
memcpy(v->wm_state, data, (size_t)n * sizeof(long));
v->wm_state_n = n;
}
static int
wl_prop_get_wm_state(WNativeWindow win, long **data_out)
{ (void)win; *data_out = NULL; return 0; }
{
/* Phase 56: return a heap copy of the stored WM state (caller frees). */
struct wl_toplevel_view *v = wl_find_view_by_id(win);
if (!v || !v->wm_state) { *data_out = NULL; return 0; }
*data_out = wmalloc((size_t)v->wm_state_n * sizeof(long));
memcpy(*data_out, v->wm_state, (size_t)v->wm_state_n * sizeof(long));
return v->wm_state_n;
}
/* ------------------------------------------------------------------ */
/* Window map / unmap / geometry */