wl_unmap: send NULL to wl_surface when W_ViewSceneNodeSetEnabledFn unavailable
This commit is contained in:
parent
f95cd3d6d3
commit
d923d9fb83
|
|
@ -561,89 +561,24 @@ wl_client_toplevel_destroy(struct W_View *view)
|
|||
}
|
||||
|
||||
void
|
||||
wl_client_toplevel_recycle(WNativeWindow id)
|
||||
wl_client_view_unmap(WNativeWindow id)
|
||||
{
|
||||
WLClientToplevel *top = wlc_top_find(id);
|
||||
if (!top) return;
|
||||
/* Destroy the Wayland protocol objects but keep the
|
||||
* WLClientToplevel struct and its view->window mapping,
|
||||
* so the surface can be recreated cleanly on remap. */
|
||||
if (top->wmaker_popup) {
|
||||
wmaker_popup_v1_destroy(top->wmaker_popup);
|
||||
top->wmaker_popup = NULL;
|
||||
}
|
||||
if (top->xdg_toplevel) {
|
||||
xdg_toplevel_destroy(top->xdg_toplevel);
|
||||
top->xdg_toplevel = NULL;
|
||||
}
|
||||
if (top->xdg_surface) {
|
||||
xdg_surface_destroy(top->xdg_surface);
|
||||
top->xdg_surface = NULL;
|
||||
}
|
||||
if (top->surface) {
|
||||
wl_surface_destroy(top->surface);
|
||||
top->surface = NULL;
|
||||
}
|
||||
if (top->buf) {
|
||||
wlclient_destroy_shm_buffer(top->buf);
|
||||
top->buf = NULL;
|
||||
}
|
||||
top->configured = 0;
|
||||
top->mapped = 0;
|
||||
top->want_close = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
wl_client_toplevel_remap_locked(WLClientToplevel *top)
|
||||
{
|
||||
if (!top || top->surface) return; /* already mapped */
|
||||
WLClientCtx *ctx = top->ctx;
|
||||
if (!ctx || !ctx->compositor || !ctx->wm_base) return;
|
||||
|
||||
top->buf = wlclient_create_shm_buffer(ctx,
|
||||
top->pending_w, top->pending_h);
|
||||
if (!top->buf) return;
|
||||
|
||||
top->surface = wl_compositor_create_surface(ctx->compositor);
|
||||
if (!top->surface) return;
|
||||
|
||||
top->xdg_surface = xdg_wm_base_get_xdg_surface(
|
||||
ctx->wm_base, top->surface);
|
||||
if (!top->xdg_surface) return;
|
||||
xdg_surface_add_listener(top->xdg_surface,
|
||||
&xdg_surface_listener, top);
|
||||
|
||||
top->xdg_toplevel = xdg_surface_get_toplevel(
|
||||
top->xdg_surface);
|
||||
if (!top->xdg_toplevel) return;
|
||||
xdg_toplevel_add_listener(top->xdg_toplevel,
|
||||
&xdg_toplevel_listener, top);
|
||||
|
||||
if (top->view->flags.popup) {
|
||||
xdg_toplevel_set_app_id(top->xdg_toplevel, "wings-popup");
|
||||
xdg_toplevel_set_title(top->xdg_toplevel, "");
|
||||
if (ctx->wmaker_popup_mgr) {
|
||||
top->wmaker_popup =
|
||||
wmaker_popup_manager_v1_get_popup(
|
||||
ctx->wmaker_popup_mgr,
|
||||
top->xdg_toplevel);
|
||||
if (top->wmaker_popup && ctx->main_toplevel)
|
||||
wmaker_popup_v1_set_parent(
|
||||
top->wmaker_popup,
|
||||
ctx->main_toplevel);
|
||||
}
|
||||
}
|
||||
|
||||
if (!top || !top->surface) return;
|
||||
/* Attach NULL + commit: the standard Wayland way
|
||||
* for a client to hide a surface from the compositor.
|
||||
* The xdg_toplevel object stays alive for remap. */
|
||||
wl_surface_attach(top->surface, NULL, 0, 0);
|
||||
wl_surface_commit(top->surface);
|
||||
W_SetViewBacking(top->view->window, top->buf->image);
|
||||
if (top->ctx && top->ctx->display)
|
||||
wl_display_flush(top->ctx->display);
|
||||
}
|
||||
|
||||
void
|
||||
wl_client_toplevel_remap(WNativeWindow id)
|
||||
{
|
||||
WLClientToplevel *top = wlc_top_find(id);
|
||||
wl_client_toplevel_remap_locked(top);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
W_WLClientSetMinMaxSize(W_View *view)
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ static unsigned int wl_view_next_id = WL_VIEW_ID_BASE;
|
|||
void (*W_ViewCommitBackingFn)(unsigned long id) = NULL;
|
||||
/* Optional hook: destroy wl_surface + xdg_toplevel on popup unmap
|
||||
* so the compositor has no stale state. Set by the WM backend. */
|
||||
void (*W_WLClientToplevelRecycleFn)(unsigned long id) = NULL;
|
||||
void (*W_WLClientToplevelRemapFn)(unsigned long id) = NULL;
|
||||
void (*W_ViewDestroyBackingFn)(unsigned long id) = NULL;
|
||||
void (*W_ViewSceneNodeSetEnabledFn)(unsigned long id, int enabled) = NULL;
|
||||
|
||||
|
|
@ -224,12 +222,16 @@ static void wl_unmap(void *vctx, W_View *view)
|
|||
} else
|
||||
wwarning("wl_unmap: W_ViewSceneNodeSetEnabledFn is NULL");
|
||||
/* Scene node disabled in the diagnostic block above. */
|
||||
/* Destroy the WINGs client wl_surface + xdg_toplevel on unmap so
|
||||
* the compositor has no stale state for this surface. The recycle
|
||||
* function preserves the WLClientToplevel struct and ID mapping
|
||||
* so the surface can be recreated on the next map. */
|
||||
if (view->flags.topLevel && view->flags.popup && W_WLClientToplevelRecycleFn)
|
||||
W_WLClientToplevelRecycleFn((unsigned long)view->window);
|
||||
/* In client mode (e.g. WPrefs), W_ViewSceneNodeSetEnabledFn may be
|
||||
* NULL because the compositor-side function is not available in the
|
||||
* client process. Attach NULL to the wl_surface, which is the
|
||||
* standard Wayland way for a client to hide a surface. */
|
||||
if (view->flags.topLevel && view->flags.popup
|
||||
&& !W_ViewSceneNodeSetEnabledFn) {
|
||||
extern void wl_client_view_unmap(WNativeWindow id);
|
||||
wl_client_view_unmap((WNativeWindow)view->window);
|
||||
}
|
||||
|
||||
if (view->parent && view->parent->flags.mapped)
|
||||
wl_redisplay(vctx, view->parent);
|
||||
}
|
||||
|
|
@ -324,10 +326,7 @@ static void wl_map(void *vctx, W_View *view)
|
|||
child = child->nextSister;
|
||||
}
|
||||
}
|
||||
/* Re-enable scene node after unmap so the surface becomes visible again.
|
||||
* For recycled popups, recreate the wl_surface + xdg_toplevel first. */
|
||||
if (view->flags.topLevel && view->flags.popup && W_WLClientToplevelRemapFn)
|
||||
W_WLClientToplevelRemapFn((unsigned long)view->window);
|
||||
|
||||
if (W_ViewSceneNodeSetEnabledFn)
|
||||
W_ViewSceneNodeSetEnabledFn((unsigned long)view->window, 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -470,12 +470,7 @@ wl_display_open(const char *name)
|
|||
unsigned int, int, int, unsigned long);
|
||||
extern void wl_pointer_ungrab(unsigned long);
|
||||
W_WLPointerGrabFn = wl_pointer_grab;
|
||||
extern void (*W_WLClientToplevelRecycleFn)(unsigned long);
|
||||
extern void wl_client_toplevel_recycle(WNativeWindow);
|
||||
W_WLClientToplevelRecycleFn = wl_client_toplevel_recycle;
|
||||
extern void (*W_WLClientToplevelRemapFn)(unsigned long);
|
||||
extern void wl_client_toplevel_remap(WNativeWindow);
|
||||
W_WLClientToplevelRemapFn = wl_client_toplevel_remap;
|
||||
|
||||
W_WLPointerUngrabFn = wl_pointer_ungrab;
|
||||
|
||||
extern void (*W_ClipboardStoreFn)(const char *text, int len);
|
||||
|
|
|
|||
Loading…
Reference in New Issue