arch: move wmspec.c (EWMH) and xdnd.c (XDND) into src/backend/x11/

Both files implement X11-specific protocols (EWMH _NET_* and XDND).
They were sitting in shared src/ because they predated the backend
split; the only remaining users in shared code were now via
wm_backend-> dispatch.

To get there, four new vtable slots replace the last direct calls
from shared src/:

  screen_get_head_usable_area  (screen.c was calling wNETWMGetUsableArea)
  window_get_icon_image        (icon.c was calling get_window_image_from_x11)
  netwm_set_frame_extents      (window.c, winspector.c were calling wNETFrameExtents)
  (window_fetch_name and window_get_icon_name extended to consult EWMH first)

Other changes:
  * get_window_image_from_x11 now takes Display* explicitly so the
    Wayland backend can pass wl_state.x_display for XWayland clients
    instead of relying on a global (which is NULL on Wayland).
  * Eight shared .c files lose their now-unused #include "wmspec.h"
    or #include "xdnd.h".
  * Makefile.am moves wmspec.{c,h} and xdnd.{c,h} into the backend/x11
    listing.
  * src/Makefile.am drops the obsolete --disable-xdnd Makefile branch
    and unconditional sources list still references the new paths.

Final state: every Xlib call in the codebase lives in src/backend/x11/
or src/backend/wayland/.  The only remaining "X*(" matches outside
backend/ are six XSetForeground/XDrawLine calls in src/moveres.c
inside an \#if 0 block (dead code; left for now).  src/ has zero
_x11_raw references.
This commit is contained in:
Window Maker 2026-05-24 09:16:39 +02:00
parent 8cb56fc141
commit a2cb136f8a
18 changed files with 145 additions and 60 deletions

View File

@ -83,8 +83,6 @@ wmaker_SOURCES = \
texture.h \
usermenu.c \
usermenu.h \
xdnd.c \
xdnd.h \
xinerama.h \
xinerama.c \
xmodifier.h \
@ -101,6 +99,10 @@ wmaker_SOURCES = \
backend/x11/x11_props.c \
backend/x11/x11_monitor.h \
backend/x11/x11_monitor.c \
backend/x11/wmspec.h \
backend/x11/wmspec.c \
backend/x11/xdnd.h \
backend/x11/xdnd.c \
geom.h \
geom.c \
wconfig.h \
@ -114,8 +116,6 @@ wmaker_SOURCES = \
winmenu.h \
winspector.h \
winspector.c \
wmspec.h \
wmspec.c \
workspace.c \
workspace.h \
wsmap.c \
@ -237,7 +237,7 @@ WM_POLICY_CLEAN_FILES = \
$(srcdir)/wsmap.c \
$(srcdir)/switchpanel.c \
$(srcdir)/properties.c \
$(srcdir)/wmspec.c \
$(srcdir)/backend/x11/wmspec.c \
$(srcdir)/application.c \
$(srcdir)/appicon.c \
$(srcdir)/dock.c \
@ -250,7 +250,7 @@ WM_POLICY_CLEAN_FILES = \
$(srcdir)/shutdown.c \
$(srcdir)/texture.c \
$(srcdir)/winspector.c \
$(srcdir)/xdnd.c \
$(srcdir)/backend/x11/xdnd.c \
$(srcdir)/rootmenu.c \
$(srcdir)/xutil.c \
$(srcdir)/misc.c \

View File

@ -49,7 +49,6 @@
#include "placement.h"
#include "misc.h"
#include "event.h"
#include "xdnd.h"
/*
* icon_file for the dock is got from the preferences file by

View File

@ -445,6 +445,29 @@ typedef struct WMBackend {
*/
Bool (*window_get_icon_name)(WNativeWindow win, char **name_out);
/*
* Compute the usable region for head `head` in the given screen,
* returning rect bounds in *x1,*y1,*x2,*y2. Returns True if struts
* narrowed the area; False if no struts apply (caller keeps using
* the full head rectangle).
*
* X11: reads EWMH _NET_WORKAREA / _NET_WM_STRUT_PARTIAL.
* Wayland: returns False (layer-shell strut tracking not yet wired).
*/
Bool (*screen_get_head_usable_area)(WScreen *scr, int head,
int *x1, int *y1, int *x2, int *y2);
/*
* Fetch the EWMH _NET_WM_ICON image (or equivalent) for the window.
* Returns a malloc'd RImage* or NULL. Caller is responsible for
* RReleaseImage'ing it.
*
* X11: parses _NET_WM_ICON (ARGB).
* Wayland: NULL for native clients (no equivalent yet); for
* XWayland clients, parses _NET_WM_ICON via wl_state.x_display.
*/
void *(*window_get_icon_image)(WNativeWindow win);
/*
* Read the _WINDOWMAKER_MENU text property from win.
* On success stores an XFreeStringList-allocated string array in *list_out,
@ -1425,6 +1448,15 @@ typedef struct WMBackend {
*/
void (*netwm_cleanup_frame_extents)(WWindow *wwin);
/*
* Set _NET_FRAME_EXTENTS on the client window so clients can query
* the frame decoration size around them.
* X11: XChangeProperty.
* Wayland: no-op (native clients are CSD; XWayland clients receive
* the property via the WMaker frame they live in).
*/
void (*netwm_set_frame_extents)(WWindow *wwin);
/* ------------------------------------------------------------------ */
/* X11 root-window properties (Phase 80) */
/* ------------------------------------------------------------------ */

View File

@ -192,7 +192,7 @@
#include "../../xinerama.h" /* Phase 16: wGetHeadForWindow */
#include "../../xmodifier.h" /* Phase 77: wSetModifierMasks */
#include "../../event.h" /* Phase 78: wWaylandKeyPress */
#include "../../wmspec.h" /* Phase 30+: get_window_image_from_x11 */
#include "../x11/wmspec.h" /* Phase 30+: get_window_image_from_x11 */
#include "../../icon.h" /* WIcon, TILE_* */
#include "../../workspace.h" /* WWorkspace */
#include "../../dock.h" /* WDock (for clip->collapsed) */
@ -3776,7 +3776,7 @@ wm_dock_load_icon(struct wl_toplevel_view *v, int *out_w, int *out_h)
if (!v->xw_surface || !wl_state.x_display)
return NULL; /* XDG native: no X11 icon path */
RImage *ri = get_window_image_from_x11((Window)v->id);
RImage *ri = get_window_image_from_x11(wl_state.x_display, (Window)v->id);
if (!ri)
return NULL;
@ -6412,6 +6412,25 @@ wl_window_get_icon_name(WNativeWindow win, char **name_out)
return False;
}
static Bool
wl_noop_screen_get_head_usable_area(WScreen *scr, int head,
int *x1, int *y1, int *x2, int *y2)
{
(void)scr; (void)head; (void)x1; (void)y1; (void)x2; (void)y2;
/* Layer-shell strut tracking not yet wired; full head is usable. */
return False;
}
static void *
wl_window_get_icon_image(WNativeWindow win)
{
/* For XWayland clients, parse _NET_WM_ICON via the Xwayland display.
* For native Wayland clients there is no equivalent (the upcoming
* xdg-toplevel-icon protocol is not yet wired). */
if (!wl_state.x_display) return NULL;
return get_window_image_from_x11(wl_state.x_display, (Window)win);
}
static int
wl_prop_get_wmaker_menu(WNativeWindow win,
char ***list_out, int *count_out)
@ -8034,6 +8053,7 @@ static void wl_noop_netwm_check_client_hints(WWindow *wwin, int *layer, int *wor
static void wl_noop_netwm_check_initial_state(WWindow *wwin) { (void)wwin; }
static int wl_noop_netwm_get_pid(WNativeWindow window) { (void)window; return 0; }
static void wl_noop_netwm_cleanup_frame_extents(WWindow *wwin) { (void)wwin; }
static void wl_noop_netwm_set_frame_extents(WWindow *wwin) { (void)wwin; }
static void wl_prop_get_protocols(WNativeWindow window, WProtocols *prots)
{
@ -9028,6 +9048,8 @@ const WMBackend wl_backend = {
.prop_get_wm_class = wl_prop_get_wm_class,
.window_fetch_name = wl_window_fetch_name,
.window_get_icon_name = wl_window_get_icon_name,
.screen_get_head_usable_area = wl_noop_screen_get_head_usable_area,
.window_get_icon_image = wl_window_get_icon_image,
.prop_get_wmaker_menu = wl_prop_get_wmaker_menu,
.prop_get_transient_for = wl_prop_get_transient_for,
.prop_has_wmaker_menu = wl_prop_has_wmaker_menu,
@ -9133,6 +9155,7 @@ const WMBackend wl_backend = {
.netwm_check_initial_state = wl_noop_netwm_check_initial_state,
.netwm_get_pid = wl_noop_netwm_get_pid,
.netwm_cleanup_frame_extents = wl_noop_netwm_cleanup_frame_extents,
.netwm_set_frame_extents = wl_noop_netwm_set_frame_extents,
.prop_get_protocols = wl_prop_get_protocols,
.prop_get_check_property = wl_noop_prop_get_check_property,
.prop_set_wmaker_protocols = wl_noop_prop_set_wmaker_protocols,

View File

@ -28,24 +28,24 @@
* return to be Success is not enough. -Dan
*/
#include "wconfig.h"
#include "../../wconfig.h"
#include <string.h>
#include <WINGs/WUtil.h>
#include "WindowMaker.h"
#include "window.h"
#include "screen.h"
#include "workspace.h"
#include "framewin.h"
#include "actions.h"
#include "client.h"
#include "appicon.h"
#include "../../WindowMaker.h"
#include "../../window.h"
#include "../../screen.h"
#include "../../workspace.h"
#include "../../framewin.h"
#include "../../actions.h"
#include "../../client.h"
#include "../../appicon.h"
#include "wmspec.h"
#include "icon.h"
#include "stacking.h"
#include "xinerama.h"
#include "properties.h"
#include "../../icon.h"
#include "../../stacking.h"
#include "../../xinerama.h"
#include "../../properties.h"
/* Root Window Properties */
@ -513,7 +513,7 @@ static RImage *findBestIcon(unsigned long *data, unsigned long items)
return ret_image;
}
RImage *get_window_image_from_x11(Window window)
RImage *get_window_image_from_x11(Display *d, Window window)
{
RImage *image;
Atom type;
@ -522,7 +522,7 @@ RImage *get_window_image_from_x11(Window window)
unsigned long *property;
/* Get the icon from X11 Window */
if (XGetWindowProperty(dpy, window, net_wm_icon, 0L, LONG_MAX,
if (XGetWindowProperty(d, window, net_wm_icon, 0L, LONG_MAX,
False, WA_CARDINAL, &type, &format, &items, &rest,
(unsigned char **)&property) != Success || !property)
return NULL;
@ -551,7 +551,7 @@ static void updateIconImage(WWindow *wwin)
RReleaseImage(wwin->net_icon_image);
/* Save the icon in the X11 icon */
wwin->net_icon_image = get_window_image_from_x11(wwin->client_win);
wwin->net_icon_image = get_window_image_from_x11(dpy, wwin->client_win);
/* Refresh the Window Icon */
if (wwin->icon)

View File

@ -24,8 +24,8 @@
#ifndef _WMSPEC_H_
#define _WMSPEC_H_
#include "screen.h"
#include "window.h"
#include "../../screen.h"
#include "../../window.h"
#include <X11/Xlib.h>
void wNETWMInitStuff(WScreen *scr);
@ -47,5 +47,5 @@ char *wNETWMGetWindowName(Window window);
void wNETFrameExtents(WWindow *wwin);
void wNETCleanupFrameExtents(WWindow *wwin);
void wNETWMUpdateWindowOpacity(WWindow *wwin);
RImage *get_window_image_from_x11(Window window);
RImage *get_window_image_from_x11(Display *d, Window window);
#endif

View File

@ -69,9 +69,9 @@
#include "../../motif.h"
#include "../../keybind.h"
#include "../../properties.h"
#include "../../wmspec.h"
#include "wmspec.h"
#include "../../colormap.h"
#include "../../xdnd.h"
#include "xdnd.h"
#include "../../client.h"
#include "../../wcore.h"
#include "../../dock.h"
@ -1260,6 +1260,11 @@ x11_prop_get_wm_class(WNativeWindow win, char **wm_class, char **wm_instance)
static Bool
x11_window_fetch_name(WNativeWindow win, char **name_out)
{
/* Prefer EWMH _NET_WM_NAME (UTF-8), fall back to ICCCM WM_NAME. */
*name_out = wNETWMGetWindowName(WNW_TO_XID(win));
if (*name_out)
return True;
XTextProperty text_prop;
char **list;
int num;
@ -1293,6 +1298,11 @@ x11_window_fetch_name(WNativeWindow win, char **name_out)
static Bool
x11_window_get_icon_name(WNativeWindow win, char **name_out)
{
/* Prefer EWMH _NET_WM_ICON_NAME (UTF-8), fall back to WM_ICON_NAME. */
*name_out = wNETWMGetIconName(WNW_TO_XID(win));
if (*name_out)
return True;
XTextProperty text_prop;
char **list;
int num;
@ -1318,6 +1328,26 @@ x11_window_get_icon_name(WNativeWindow win, char **name_out)
return False;
}
static Bool
x11_screen_get_head_usable_area(WScreen *scr, int head,
int *x1, int *y1, int *x2, int *y2)
{
WArea area;
if (!wNETWMGetUsableArea(scr, head, &area))
return False;
*x1 = area.x1;
*y1 = area.y1;
*x2 = area.x2;
*y2 = area.y2;
return True;
}
static void *
x11_window_get_icon_image(WNativeWindow win)
{
return get_window_image_from_x11(dpy, WNW_TO_XID(win));
}
static int
x11_prop_get_wmaker_menu(WNativeWindow win, char ***list_out, int *count_out)
{
@ -3105,6 +3135,7 @@ static void x11_netwm_check_client_hints(WWindow *wwin, int *layer, int *workspa
static void x11_netwm_check_initial_state(WWindow *wwin) { wNETWMCheckInitialClientState(wwin); }
static int x11_netwm_get_pid(WNativeWindow window) { return wNETWMGetPidForWindow((Window)window); }
static void x11_netwm_cleanup_frame_extents(WWindow *wwin) { wNETCleanupFrameExtents(wwin); }
static void x11_netwm_set_frame_extents(WWindow *wwin) { wNETFrameExtents(wwin); }
static void x11_netwm_update_opacity(WWindow *wwin) { wNETWMUpdateWindowOpacity(wwin); }
/* -------------------------------------------------------------------- */
@ -4512,6 +4543,8 @@ const WMBackend x11_backend = {
.prop_get_wm_class = x11_prop_get_wm_class,
.window_fetch_name = x11_window_fetch_name,
.window_get_icon_name = x11_window_get_icon_name,
.screen_get_head_usable_area = x11_screen_get_head_usable_area,
.window_get_icon_image = x11_window_get_icon_image,
.prop_get_wmaker_menu = x11_prop_get_wmaker_menu,
.monitors_query = x11_monitors_query,
.monitors_select_events = x11_monitors_select_events,
@ -4606,6 +4639,7 @@ const WMBackend x11_backend = {
.netwm_check_initial_state = x11_netwm_check_initial_state,
.netwm_get_pid = x11_netwm_get_pid,
.netwm_cleanup_frame_extents = x11_netwm_cleanup_frame_extents,
.netwm_set_frame_extents = x11_netwm_set_frame_extents,
.prop_get_protocols = x11_prop_get_protocols,
.prop_get_check_property = x11_prop_get_check_property,
.prop_set_wmaker_protocols = x11_prop_set_wmaker_protocols,

View File

@ -20,17 +20,17 @@
/* Many part of code are ripped of an example from JX's site */
#include "config.h"
#include "../../wconfig.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "WindowMaker.h"
#include "dock.h"
#include "../../WindowMaker.h"
#include "../../dock.h"
#include "xdnd.h"
#include "workspace.h"
#include "../../workspace.h"
static Atom _XA_XdndAware;

View File

@ -36,7 +36,6 @@
#include "stacking.h"
#include "appicon.h"
#include "appmenu.h"
#include "wmspec.h"
#include "misc.h"

View File

@ -51,7 +51,6 @@
#include "properties.h"
#include "balloon.h"
#include "xinerama.h"
#include "wmspec.h"
#include "rootmenu.h"
#include "colormap.h"
#include "screen.h"
@ -63,7 +62,6 @@
#include "wsmap.h"
#include "backend/x11/x11_compat.h"
#include "backend/x11/x11_event.h"
#include "xdnd.h"
#define MOD_MASK wPreferences.modifier_mask

View File

@ -40,7 +40,6 @@
#include "application.h"
#include "defaults.h"
#include "appicon.h"
#include "wmspec.h"
#include "misc.h"
#include "startup.h"
#include "event.h"
@ -322,12 +321,15 @@ void wIconChangeTitle(WIcon *icon, WWindow *wwin)
if (icon->icon_name != NULL)
wfree(icon->icon_name);
/* Set the new one, using two methods to identify
the icon name or switch back to window name */
icon->icon_name = wNETWMGetIconName(wwin->client_win);
if (!icon->icon_name)
if (!wGetIconName(dpy, wwin->client_win, &icon->icon_name))
icon->icon_name = wNETWMGetWindowName(wwin->client_win);
/* Set the new one through the backend. X11 backend tries
* EWMH _NET_WM_ICON_NAME first, falls back to ICCCM WM_ICON_NAME,
* then to WM_NAME / _NET_WM_NAME. Wayland backend returns the
* xdg_toplevel.title (which is what XWayland clients see too). */
icon->icon_name = NULL;
if (!wm_backend->window_get_icon_name(wwin->client_win, &icon->icon_name) ||
!icon->icon_name) {
wm_backend->window_fetch_name(wwin->client_win, &icon->icon_name);
}
}
RImage *wIconValidateIconSize(RImage *icon, int max_size)
@ -715,8 +717,9 @@ static void get_rimage_icon_from_icon_win(WIcon *icon)
{
RImage *image;
/* Create the new RImage */
image = get_window_image_from_x11(icon->icon_win);
/* Create the new RImage via backend (X11: parses _NET_WM_ICON via dpy;
* Wayland: parses _NET_WM_ICON via wl_state.x_display for XWayland). */
image = (RImage *)wm_backend->window_get_icon_image(icon->icon_win);
/* Free the icon info */
unset_icon_image(icon);

View File

@ -46,7 +46,6 @@
#include "session.h"
#include "balloon.h"
#include "geomview.h"
#include "wmspec.h"
#include "rootmenu.h"
#include "misc.h"
@ -237,7 +236,9 @@ void wScreenUpdateUsableArea(WScreen *scr)
scr->totalUsableArea[i].x2 = rect.pos.x + rect.size.width;
scr->totalUsableArea[i].y2 = rect.pos.y + rect.size.height;
if (wNETWMGetUsableArea(scr, i, &area)) {
if (wm_backend->screen_get_head_usable_area(scr, i,
&area.x1, &area.y1,
&area.x2, &area.y2)) {
scr->totalUsableArea[i].x1 = WMAX(scr->totalUsableArea[i].x1, area.x1);
scr->totalUsableArea[i].y1 = WMAX(scr->totalUsableArea[i].y1, area.y1);
scr->totalUsableArea[i].x2 = WMIN(scr->totalUsableArea[i].x2, area.x2);

View File

@ -32,7 +32,6 @@
#include "properties.h"
#include "session.h"
#include "winspector.h"
#include "wmspec.h"
#include "colormap.h"
#include "shutdown.h"

View File

@ -51,10 +51,8 @@
#include "backend/x11/x11_backend.h"
#include "properties.h"
#include "dialog.h"
#include "wmspec.h"
#include "event.h"
#include "switchmenu.h"
#include "xdnd.h"
#include "xutil.h"

View File

@ -63,7 +63,6 @@
#ifdef USE_MWM_HINTS
# include "motif.h"
#endif
#include "wmspec.h"
#include "geom.h"
#include "backend/x11/x11_event.h"
@ -643,11 +642,13 @@ WWindow *wManageWindow(WScreen *scr, WNativeWindow window)
wwin = wWindowCreate();
title = wNETWMGetWindowName(window);
if (title)
title = NULL;
if (wm_backend->window_fetch_name(window, &title) && title) {
/* X11 backend tries _NET_WM_NAME first; if it succeeds, mark
* net_has_title so the title is treated as UTF-8. Wayland
* backend returns the xdg_toplevel.title which is also UTF-8. */
wwin->flags.net_has_title = 1;
else if (!wFetchName(dpy, window, &title))
title = NULL;
}
wm_backend->context_save(window, WM_CTX_CLIENT_WIN, &wwin->client_descriptor);
@ -2013,7 +2014,7 @@ void wWindowConfigure(WWindow *wwin, int req_x, int req_y, int req_width, int re
if (synth_notify)
wWindowSynthConfigureNotify(wwin);
wNETFrameExtents(wwin);
wm_backend->netwm_set_frame_extents(wwin);
wm_backend->event_flush();
}

View File

@ -43,7 +43,6 @@
#include "winspector.h"
#include "dock.h"
#include "client.h"
#include "wmspec.h"
#include "misc.h"
#include "switchmenu.h"
@ -869,7 +868,7 @@ static void applySettings(WMWidget *button, void *client_data)
wfree(file);
}
wNETFrameExtents(wwin);
wm_backend->netwm_set_frame_extents(wwin);
}
static void revertSettings(WMWidget *button, void *client_data)

View File

@ -40,7 +40,6 @@
#include "actions.h"
#include "workspace.h"
#include "appicon.h"
#include "wmspec.h"
#include "xinerama.h"
#include "event.h"
#include "wsmap.h"