decompose wl_backend.c: extract wl_props.c

This commit is contained in:
Window Maker 2026-06-02 10:25:02 +02:00
parent 273589092d
commit 36cdc48f23
4 changed files with 182 additions and 150 deletions

View File

@ -162,7 +162,8 @@ wmaker_SOURCES += \
backend/wayland/wl_event.c \
backend/wayland/wl_stacking.c \
backend/wayland/wl_overlay.c \
backend/wayland/wl_window.c
backend/wayland/wl_window.c \
backend/wayland/wl_props.c
endif
if USE_NESTED_FUNC

View File

@ -6255,92 +6255,6 @@ wl_keyboard_ungrab(void)
/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */
/* Properties */
/* ------------------------------------------------------------------ */
static int
wl_prop_get_normal_hints(WNativeWindow win, WNormalHints *out, int *pre_icccm)
{
/* Phase 47: populate size constraints from XDG toplevel.
* Phase 17: also handles XWayland size_hints. */
struct wl_toplevel_view *v = wl_find_view_by_id(win);
memset(out, 0, sizeof(*out));
*pre_icccm = 0;
if (!v) return 0;
/* Phase 17: XWayland size_hints path. */
if (v->xw_surface) {
xcb_size_hints_t *sh = v->xw_surface->size_hints;
if (sh) {
if (sh->min_width > 0 || sh->min_height > 0) {
out->flags |= WNH_P_MIN_SIZE;
out->min_width = sh->min_width > 0 ? sh->min_width : 1;
out->min_height = sh->min_height > 0 ? sh->min_height : 1;
}
if (sh->max_width > 0 || sh->max_height > 0) {
out->flags |= WNH_P_MAX_SIZE;
out->max_width = sh->max_width;
out->max_height = sh->max_height;
}
}
if (v->xw_surface->width > 0 && v->xw_surface->height > 0) {
out->flags |= WNH_P_SIZE;
out->width = v->xw_surface->width;
out->height = v->xw_surface->height;
}
return (out->flags != 0) ? 1 : 0;
}
if (!v->xdg_surface || !v->xdg_surface->toplevel)
return 0;
struct wlr_xdg_toplevel *tl = v->xdg_surface->toplevel;
if (tl->current.min_width > 0 || tl->current.min_height > 0) {
out->flags |= WNH_P_MIN_SIZE;
out->min_width = (int)tl->current.min_width;
out->min_height = (int)tl->current.min_height;
}
if (tl->current.max_width > 0 || tl->current.max_height > 0) {
out->flags |= WNH_P_MAX_SIZE;
out->max_width = (int)tl->current.max_width;
out->max_height = (int)tl->current.max_height;
}
/* Report the current size as the base/initial size. */
if (v->xdg_surface->surface) {
int w = v->xdg_surface->surface->current.width;
int h = v->xdg_surface->surface->current.height;
if (w > 0 && h > 0) {
out->flags |= WNH_P_SIZE;
out->width = w;
out->height = h;
}
}
return (out->flags != 0) ? 1 : 0;
}
static WWMHints *
wl_prop_get_wm_hints(WNativeWindow win) { (void)win; return NULL; }
static int
wl_prop_get_wm_class(WNativeWindow win,
char **wm_class, char **wm_instance)
{
/* Phase 41: use XDG app_id / Phase 17: use XWayland WM_CLASS. */
struct wl_toplevel_view *v = wl_find_view_by_id(win);
if (v && v->xw_surface) {
*wm_class = strdup(v->xw_surface->class ? v->xw_surface->class : "x11-client");
*wm_instance = strdup(v->xw_surface->instance ? v->xw_surface->instance : "x11-client");
return 1;
}
const char *app_id = (v && v->xdg_surface && v->xdg_surface->toplevel &&
v->xdg_surface->toplevel->app_id)
? v->xdg_surface->toplevel->app_id : "wayland-client";
*wm_class = strdup(app_id);
*wm_instance = strdup(app_id);
return 1;
}
static Bool
wl_noop_screen_get_head_usable_area(WScreen *scr, int head,
int *x1, int *y1, int *x2, int *y2)
@ -6350,69 +6264,6 @@ wl_noop_screen_get_head_usable_area(WScreen *scr, int head,
return False;
}
static int
wl_prop_get_wmaker_menu(WNativeWindow win,
char ***list_out, int *count_out)
{
(void)win;
*list_out = NULL; *count_out = 0;
return 0;
}
static WNativeWindow
wl_prop_get_transient_for(WNativeWindow win)
{
/* Phase 65: return the synthetic ID of the parent XDG toplevel, or
* WNATIVE_NONE if this surface has no parent. The wlroots XDG
* implementation stores the parent as xdg_surface->toplevel->parent
* (a wlr_xdg_surface *). We walk the view list to find its ID. */
struct wl_toplevel_view *v = wl_find_view_by_id(win);
if (!v) return WNATIVE_NONE;
/* Phase 17: XWayland transient_for via parent window_id. */
if (v->xw_surface) {
struct wlr_xwayland_surface *parent = v->xw_surface->parent;
if (!parent) return WNATIVE_NONE;
return (WNativeWindow)parent->window_id;
}
if (!v->xdg_surface || !v->xdg_surface->toplevel)
return WNATIVE_NONE;
struct wlr_xdg_toplevel *ptl = v->xdg_surface->toplevel->parent;
if (!ptl || !ptl->base)
return WNATIVE_NONE;
struct wl_toplevel_view *pv = wl_find_view_by_xdg_surface(ptl->base);
if (!pv)
return WNATIVE_NONE;
return pv->id;
}
static int wl_prop_has_wmaker_menu(WNativeWindow win) { (void)win; return 0; }
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)
{
/* 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)
{
/* 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;
}
/* ------------------------------------------------------------------ */
/* WNativeWindow map / unmap / geometry */
/* ------------------------------------------------------------------ */

View File

@ -0,0 +1,169 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <stdlib.h>
#include <wayland-server-core.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/xwayland.h>
#include <xcb/xcb.h>
#include "../../screen.h"
#include "wl_types.h"
/* Forward declarations from sibling modules. */
struct wl_toplevel_view *wl_find_view_by_id(WNativeWindow id);
struct wl_toplevel_view *wl_find_view_by_xdg_surface(struct wlr_xdg_surface *surf);
/* Properties */
/* ------------------------------------------------------------------ */
int
wl_prop_get_normal_hints(WNativeWindow win, WNormalHints *out, int *pre_icccm)
{
/* Phase 47: populate size constraints from XDG toplevel.
* Phase 17: also handles XWayland size_hints. */
struct wl_toplevel_view *v = wl_find_view_by_id(win);
memset(out, 0, sizeof(*out));
*pre_icccm = 0;
if (!v) return 0;
/* Phase 17: XWayland size_hints path. */
if (v->xw_surface) {
xcb_size_hints_t *sh = v->xw_surface->size_hints;
if (sh) {
if (sh->min_width > 0 || sh->min_height > 0) {
out->flags |= WNH_P_MIN_SIZE;
out->min_width = sh->min_width > 0 ? sh->min_width : 1;
out->min_height = sh->min_height > 0 ? sh->min_height : 1;
}
if (sh->max_width > 0 || sh->max_height > 0) {
out->flags |= WNH_P_MAX_SIZE;
out->max_width = sh->max_width;
out->max_height = sh->max_height;
}
}
if (v->xw_surface->width > 0 && v->xw_surface->height > 0) {
out->flags |= WNH_P_SIZE;
out->width = v->xw_surface->width;
out->height = v->xw_surface->height;
}
return (out->flags != 0) ? 1 : 0;
}
if (!v->xdg_surface || !v->xdg_surface->toplevel)
return 0;
struct wlr_xdg_toplevel *tl = v->xdg_surface->toplevel;
if (tl->current.min_width > 0 || tl->current.min_height > 0) {
out->flags |= WNH_P_MIN_SIZE;
out->min_width = (int)tl->current.min_width;
out->min_height = (int)tl->current.min_height;
}
if (tl->current.max_width > 0 || tl->current.max_height > 0) {
out->flags |= WNH_P_MAX_SIZE;
out->max_width = (int)tl->current.max_width;
out->max_height = (int)tl->current.max_height;
}
/* Report the current size as the base/initial size. */
if (v->xdg_surface->surface) {
int w = v->xdg_surface->surface->current.width;
int h = v->xdg_surface->surface->current.height;
if (w > 0 && h > 0) {
out->flags |= WNH_P_SIZE;
out->width = w;
out->height = h;
}
}
return (out->flags != 0) ? 1 : 0;
}
WWMHints *
wl_prop_get_wm_hints(WNativeWindow win) { (void)win; return NULL; }
int
wl_prop_get_wm_class(WNativeWindow win,
char **wm_class, char **wm_instance)
{
/* Phase 41: use XDG app_id / Phase 17: use XWayland WM_CLASS. */
struct wl_toplevel_view *v = wl_find_view_by_id(win);
if (v && v->xw_surface) {
*wm_class = strdup(v->xw_surface->class ? v->xw_surface->class : "x11-client");
*wm_instance = strdup(v->xw_surface->instance ? v->xw_surface->instance : "x11-client");
return 1;
}
const char *app_id = (v && v->xdg_surface && v->xdg_surface->toplevel &&
v->xdg_surface->toplevel->app_id)
? v->xdg_surface->toplevel->app_id : "wayland-client";
*wm_class = strdup(app_id);
*wm_instance = strdup(app_id);
return 1;
}
int
wl_prop_get_wmaker_menu(WNativeWindow win,
char ***list_out, int *count_out)
{
(void)win;
*list_out = NULL; *count_out = 0;
return 0;
}
WNativeWindow
wl_prop_get_transient_for(WNativeWindow win)
{
/* Phase 65: return the synthetic ID of the parent XDG toplevel, or
* WNATIVE_NONE if this surface has no parent. The wlroots XDG
* implementation stores the parent as xdg_surface->toplevel->parent
* (a wlr_xdg_surface *). We walk the view list to find its ID. */
struct wl_toplevel_view *v = wl_find_view_by_id(win);
if (!v) return WNATIVE_NONE;
/* Phase 17: XWayland transient_for via parent window_id. */
if (v->xw_surface) {
struct wlr_xwayland_surface *parent = v->xw_surface->parent;
if (!parent) return WNATIVE_NONE;
return (WNativeWindow)parent->window_id;
}
if (!v->xdg_surface || !v->xdg_surface->toplevel)
return WNATIVE_NONE;
struct wlr_xdg_toplevel *ptl = v->xdg_surface->toplevel->parent;
if (!ptl || !ptl->base)
return WNATIVE_NONE;
struct wl_toplevel_view *pv = wl_find_view_by_xdg_surface(ptl->base);
if (!pv)
return WNATIVE_NONE;
return pv->id;
}
int wl_prop_has_wmaker_menu(WNativeWindow win) { (void)win; return 0; }
int wl_prop_has_gtk_object_path(WNativeWindow win) { (void)win; return 0; }
void
wl_prop_set_wm_state(WNativeWindow win, const long *data, int 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;
}
int
wl_prop_get_wm_state(WNativeWindow win, long **data_out)
{
/* 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;
}
/* ------------------------------------------------------------------ */

View File

@ -450,3 +450,14 @@ void wl_window_shape_clear(WWindow *wwin);
struct wl_toplevel_view *wl_find_view_by_xdg_surface(struct wlr_xdg_surface *surf);
void wmaker_popup_apply(struct wl_toplevel_view *view);
void frame_buf_update_children_abs(WNativeWindow parent_id);
/* Property module declarations (extracted to wl_props.c) */
int wl_prop_get_normal_hints(WNativeWindow win, WNormalHints *out, int *pre_icccm);
WWMHints *wl_prop_get_wm_hints(WNativeWindow win);
int wl_prop_get_wm_class(WNativeWindow win, char **wm_class, char **wm_instance);
int wl_prop_get_wmaker_menu(WNativeWindow win, char ***list_out, int *count_out);
WNativeWindow wl_prop_get_transient_for(WNativeWindow win);
int wl_prop_has_wmaker_menu(WNativeWindow win);
int wl_prop_has_gtk_object_path(WNativeWindow win);
void wl_prop_set_wm_state(WNativeWindow win, const long *data, int n);
int wl_prop_get_wm_state(WNativeWindow win, long **data_out);