From e727bdbad0b0ed74fc6c5b4b25bca837d17d700e Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Sat, 28 Mar 2026 07:28:59 +0100 Subject: [PATCH] =?UTF-8?q?wayland:=20Phase=2056=20=E2=80=94=20prop=5Fset/?= =?UTF-8?q?get=5Fwm=5Fstate=20persists=20WM=20state=20in=20view=20struct?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/backend/wayland/wl_backend.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index f829885..7617f49 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -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 */