Phase 80j: clean X11 from shutdown.c, framewin.c, properties.c

- shutdown.c: RestoreDesktop/wWipeDesktop/restoreWindows moved entirely
  to x11_backend.c; policy file contains only vtable dispatch stubs
- framewin.c: wFrameWindowPaint restructured — policy logic stays,
  X11 rendering (resizebar lines, titlebar pixmap ops) dispatched through
  new frame_paint_resizebar/frame_paint_titlebar vtable slots
- properties.c: all 6 functions (PropGetProtocols, PropGetCheckProperty,
  PropSetWMakerProtocols, PropSetIconTileHint, PropGetClientLeader,
  PropGetWindowState, PropCleanUp) replaced with vtable dispatch stubs;
  X11 implementations inlined into x11_backend.c

New vtable slots: frame_paint_resizebar, frame_paint_titlebar,
prop_get_client_leader, prop_get_window_state.
All three files verified X11-free with nm.
This commit is contained in:
Levi Neely 2026-05-13 11:18:19 +02:00
parent a5d6720a1c
commit 6d4fc32b28
6 changed files with 295 additions and 346 deletions

View File

@ -1703,6 +1703,12 @@ typedef struct WMBackend {
unsigned long (*keysym_from_name)(const char *name);
void (*frame_paint_resizebar)(struct WFrameWindow *fwin);
void (*frame_paint_titlebar)(struct WFrameWindow *fwin, int state);
WNativeWindow (*prop_get_client_leader)(WNativeWindow window);
int (*prop_get_window_state)(WNativeWindow window);
} WMBackend;
/*

View File

@ -6208,6 +6208,12 @@ static unsigned long wl_keysym_from_name(const char *name)
return (unsigned long)xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
}
static void wl_noop_frame_paint_resizebar(WFrameWindow *fwin) { (void)fwin; }
static void wl_noop_frame_paint_titlebar(WFrameWindow *fwin, int state) { (void)fwin; (void)state; }
static WNativeWindow wl_noop_prop_get_client_leader(WNativeWindow window) { (void)window; return WNATIVE_NONE; }
static int wl_noop_prop_get_window_state(WNativeWindow window) { (void)window; return -1; }
/* ------------------------------------------------------------------ */
/* vtable */
/* ------------------------------------------------------------------ */
@ -6425,4 +6431,8 @@ const WMBackend wl_backend = {
.pixmap_create_from_xbm = wl_noop_pixmap_create_from_xbm,
.pixmap_create = wl_noop_pixmap_create,
.keysym_from_name = wl_keysym_from_name,
.frame_paint_resizebar = wl_noop_frame_paint_resizebar,
.frame_paint_titlebar = wl_noop_frame_paint_titlebar,
.prop_get_client_leader = wl_noop_prop_get_client_leader,
.prop_get_window_state = wl_noop_prop_get_window_state,
};

View File

@ -51,6 +51,7 @@
#include "../../resources.h"
#include "../../superfluous.h"
#include "../../shutdown.h" /* Shutdown(), WShutdownMode */
#include "../../winspector.h"
#include "../../main.h" /* Restart() */
#include "../../icon.h"
#include "../../appicon.h"
@ -2482,6 +2483,111 @@ x11_texture_free_gc(GC gc)
/* Frame decoration helpers (Phase 80) */
/* -------------------------------------------------------------------- */
static void
x11_frame_paint_resizebar(WFrameWindow *fwin)
{
Window win;
int w, h, cw;
GC light_gc, dim_gc;
WTexSolid *texture = (WTexSolid *) fwin->resizebar_texture[0];
w = fwin->resizebar->width;
h = fwin->resizebar->height;
cw = fwin->resizebar_corner_width;
light_gc = texture->light_gc;
dim_gc = texture->dim_gc;
win = fwin->resizebar->window;
XDrawLine(dpy, win, dim_gc, 0, 0, w, 0);
XDrawLine(dpy, win, light_gc, 0, 1, w, 1);
XDrawLine(dpy, win, dim_gc, cw, 2, cw, h);
XDrawLine(dpy, win, light_gc, cw + 1, 2, cw + 1, h);
XDrawLine(dpy, win, dim_gc, w - cw - 2, 2, w - cw - 2, h);
XDrawLine(dpy, win, light_gc, w - cw - 1, 2, w - cw - 1, h);
#ifdef SHADOW_RESIZEBAR
XDrawLine(dpy, win, light_gc, 0, 1, 0, h - 1);
XDrawLine(dpy, win, dim_gc, w - 1, 2, w - 1, h - 1);
XDrawLine(dpy, win, dim_gc, 1, h - 1, cw, h - 1);
XDrawLine(dpy, win, dim_gc, cw + 2, h - 1, w - cw - 2, h - 1);
XDrawLine(dpy, win, dim_gc, w - cw, h - 1, w - 1, h - 1);
#endif
}
static void
x11_frame_paint_titlebar(WFrameWindow *fwin, int state)
{
WScreen *scr = fwin->screen_ptr;
int x, y, w, h;
int lofs = 6, rofs = 6;
int titlelen;
int allButtons = 1;
if (wPreferences.new_style != TS_NEW) {
if (fwin->left_button && !fwin->flags.hide_left_button && !fwin->flags.lbutton_dont_fit)
lofs += fwin->left_button->width + 3;
else
allButtons = 0;
#ifdef XKB_BUTTON_HINT
if (fwin->language_button && !fwin->flags.hide_language_button
&& !fwin->flags.languagebutton_dont_fit)
lofs += fwin->language_button->width;
else
allButtons = 0;
#endif
if (fwin->right_button && !fwin->flags.hide_right_button && !fwin->flags.rbutton_dont_fit)
rofs += fwin->right_button->width + 3;
else
allButtons = 0;
}
#ifdef XKB_BUTTON_HINT
fwin->languagebutton_image = scr->b_pixmaps[WBUT_XKBGROUP1 + fwin->languagemode];
#endif
if (fwin->title && fwin->titlebar->window) {
Drawable buf;
char *title;
title = ShrinkString(*fwin->font, fwin->title, fwin->titlebar->width - lofs - rofs);
titlelen = strlen(title);
w = WMWidthOfString(*fwin->font, title, titlelen);
switch (fwin->flags.justification) {
case WTJ_LEFT: x = lofs; break;
case WTJ_RIGHT: x = fwin->titlebar->width - w - rofs; break;
default:
if (!allButtons)
x = lofs + (fwin->titlebar->width - w - lofs - rofs) / 2;
else
x = (fwin->titlebar->width - w) / 2;
break;
}
y = *fwin->title_clearance + TITLEBAR_EXTEND_SPACE;
h = WMFontHeight(*fwin->font);
if (y*2 + h > *fwin->title_max_height)
y = (*fwin->title_max_height - h) / 2;
if (y*2 + h < *fwin->title_min_height)
y = (*fwin->title_min_height - h) / 2;
buf = XCreatePixmap(dpy, fwin->titlebar->window, w + 2, h, scr->w_depth);
XSetClipMask(dpy, scr->copy_gc, None);
if (fwin->title_texture[state]->any.type != WTEX_SOLID) {
XCopyArea(dpy, fwin->title_back[state], buf, scr->copy_gc,
x - 1, y, w + 2, h, 0, 0);
} else {
XSetForeground(dpy, scr->copy_gc, fwin->title_texture[state]->solid.normal.pixel);
XFillRectangle(dpy, buf, scr->copy_gc, 0, 0, w + 2, h);
}
WMDrawString(scr->wmscreen, buf, fwin->title_color[state],
*fwin->font, 1, 0, title, titlelen);
XCopyArea(dpy, buf, fwin->titlebar->window, scr->copy_gc, 0, 0, w + 2, h, x - 1, y);
XFreePixmap(dpy, buf);
wfree(title);
}
}
static int
x11_frame_paint_impl(struct WFrameWindow *fwin)
{
@ -2692,7 +2798,23 @@ static void x11_netwm_update_opacity(WWindow *wwin) { wNETWMUpdateWindowOpacity(
static void x11_prop_get_protocols(WNativeWindow window, WProtocols *prots)
{
PropGetProtocols((Window)window, prots);
Atom *protocols;
int count, i;
memset(prots, 0, sizeof(WProtocols));
if (!XGetWMProtocols(dpy, (Window)window, &protocols, &count))
return;
for (i = 0; i < count; i++) {
if (protocols[i] == w_global.atom.wm.take_focus)
prots->TAKE_FOCUS = 1;
else if (protocols[i] == w_global.atom.wm.delete_window)
prots->DELETE_WINDOW = 1;
else if (protocols[i] == w_global.atom.wm.save_yourself)
prots->SAVE_YOURSELF = 1;
else if (protocols[i] == w_global.atom.gnustep.wm_miniaturize_window)
prots->MINIATURIZE_WINDOW = 1;
}
XFree(protocols);
}
static unsigned char *x11_prop_get_check_property(WNativeWindow window,
@ -2701,23 +2823,102 @@ static unsigned char *x11_prop_get_check_property(WNativeWindow window,
int format, int count,
int *ret_count)
{
return PropGetCheckProperty((Window)window, (Atom)hint, (Atom)type,
format, count, ret_count);
Atom type_ret;
int fmt_ret;
unsigned long nitems_ret, bytes_after_ret;
unsigned char *data;
int tmp = (count <= 0) ? 0xffffff : count;
if (XGetWindowProperty(dpy, (Window)window, (Atom)hint, 0, tmp, False, (Atom)type,
&type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret,
&data) != Success || !data)
return NULL;
if ((type != AnyPropertyType && (Atom)type != type_ret)
|| (count > 0 && nitems_ret != (unsigned long)count)
|| (format != 0 && format != fmt_ret)) {
XFree(data);
return NULL;
}
if (ret_count)
*ret_count = nitems_ret;
return data;
}
static void x11_prop_set_wmaker_protocols(WNativeWindow root)
{
PropSetWMakerProtocols((Window)root);
Atom protocols[3];
int count = 0;
protocols[count++] = w_global.atom.wmaker.menu;
protocols[count++] = w_global.atom.wmaker.wm_function;
protocols[count++] = w_global.atom.wmaker.noticeboard;
XChangeProperty(dpy, (Window)root, w_global.atom.wmaker.wm_protocols, WA_ATOM,
32, PropModeReplace, (unsigned char *)protocols, count);
}
static void x11_prop_set_icon_tile(WScreen *scr, RImage *image)
{
PropSetIconTileHint(scr, image);
static Atom imageAtom = 0;
unsigned char *tmp;
int x, y;
if (scr->info_window == None)
return;
if (!imageAtom)
imageAtom = XInternAtom(dpy, "_RGBA_IMAGE", False);
tmp = malloc(image->width * image->height * 4 + 4);
if (!tmp) return;
tmp[0] = image->width >> 8;
tmp[1] = image->width & 0xff;
tmp[2] = image->height >> 8;
tmp[3] = image->height & 0xff;
if (image->format == RRGBAFormat) {
memcpy(&tmp[4], image->data, image->width * image->height * 4);
} else {
char *ptr = (char *)(tmp + 4);
char *src = (char *)image->data;
for (y = 0; y < image->height; y++)
for (x = 0; x < image->width; x++) {
*ptr++ = *src++; *ptr++ = *src++; *ptr++ = *src++; *ptr++ = 255;
}
}
XChangeProperty(dpy, scr->info_window, w_global.atom.wmaker.icon_tile,
imageAtom, 8, PropModeReplace, tmp, image->width * image->height * 4 + 4);
wfree(tmp);
}
static void x11_prop_cleanup(WNativeWindow root)
{
PropCleanUp((Window)root);
XDeleteProperty(dpy, (Window)root, w_global.atom.wmaker.wm_protocols);
XDeleteProperty(dpy, (Window)root, w_global.atom.wmaker.noticeboard);
XDeleteProperty(dpy, (Window)root, WA_WM_ICON_SIZE);
}
static WNativeWindow x11_prop_get_client_leader(WNativeWindow window)
{
Window *win;
Window leader;
win = (Window *)x11_prop_get_check_property(window,
(unsigned long)w_global.atom.wm.client_leader, (unsigned long)WA_WINDOW, 32, 1, NULL);
if (!win) return WNATIVE_NONE;
leader = *win;
XFree(win);
return (WNativeWindow)leader;
}
static int x11_prop_get_window_state(WNativeWindow window)
{
long *data;
long state;
data = (long *)x11_prop_get_check_property(window,
(unsigned long)w_global.atom.wm.state, (unsigned long)w_global.atom.wm.state, 32, 1, NULL);
if (!data) return -1;
state = *data;
XFree(data);
return state;
}
/* -------------------------------------------------------------------- */
@ -2857,14 +3058,68 @@ static void x11_appicon_paint(WAppIcon *aicon)
/* Shutdown (Phase 80) */
/* -------------------------------------------------------------------- */
static void x11_colormap_install(WScreen *scr, WWindow *wwin); /* forward */
static void x11_restore_windows(WMBag *bag, WMBagIterator iter)
{
WCoreWindow *next, *core;
WWindow *wwin;
if (iter == NULL)
core = WMBagFirst(bag, &iter);
else
core = WMBagNext(bag, &iter);
if (core == NULL)
return;
x11_restore_windows(bag, iter);
while (core->stacking->under)
core = core->stacking->under;
while (core) {
next = core->stacking->above;
if (core->descriptor.parent_type == WCLASS_WINDOW) {
Window window;
wwin = core->descriptor.parent;
window = wwin->client_win;
wUnmanageWindow(wwin, !wwin->flags.internal_window, False);
XMapWindow(dpy, window);
}
core = next;
}
}
static void x11_restore_desktop(WScreen *scr)
{
RestoreDesktop(scr);
if (scr->helper_pid > 0) {
kill(scr->helper_pid, SIGTERM);
scr->helper_pid = 0;
}
XGrabServer(dpy);
wDestroyInspectorPanels();
x11_restore_windows(scr->stacking_list, NULL);
XUngrabServer(dpy);
XSetInputFocus(dpy, PointerRoot, RevertToParent, CurrentTime);
x11_colormap_install(scr, NULL);
x11_prop_cleanup((WNativeWindow)scr->root_win);
x11_netwm_cleanup(scr);
XSync(dpy, 0);
}
static void x11_wipe_desktop(WScreen *scr)
{
wWipeDesktop(scr);
WWindow *wwin = scr->focused_window;
while (wwin) {
if (wwin->protocols.DELETE_WINDOW)
wClientSendProtocol(wwin, w_global.atom.wm.delete_window,
w_global.timestamp.last_event);
else
wClientKill(wwin);
wwin = wwin->prev;
}
XSync(dpy, False);
}
/* -------------------------------------------------------------------- */
@ -3366,6 +3621,10 @@ const WMBackend x11_backend = {
.pixmap_create_from_xbm = x11_pixmap_create_from_xbm,
.pixmap_create = x11_pixmap_create,
.keysym_from_name = x11_keysym_from_name,
.frame_paint_resizebar = x11_frame_paint_resizebar,
.frame_paint_titlebar = x11_frame_paint_titlebar,
.prop_get_client_leader = x11_prop_get_client_leader,
.prop_get_window_state = x11_prop_get_window_state,
};
/*

View File

@ -870,19 +870,14 @@ void wFrameWindowPaint(WFrameWindow * fwin)
if (fwin->flags.need_texture_remake) {
int i;
fwin->flags.need_texture_remake = 0;
fwin->flags.need_texture_change = 0;
if (fwin->flags.single_texture) {
remakeTexture(fwin, 0);
updateTexture(fwin);
} else {
/* first render the texture for the current state... */
remakeTexture(fwin, state);
/* ... and paint it */
updateTexture(fwin);
for (i = 0; i < 3; i++) {
if (i != state)
remakeTexture(fwin, i);
@ -892,7 +887,6 @@ void wFrameWindowPaint(WFrameWindow * fwin)
if (fwin->flags.need_texture_change) {
fwin->flags.need_texture_change = 0;
updateTexture(fwin);
}
@ -905,129 +899,11 @@ void wFrameWindowPaint(WFrameWindow * fwin)
if (fwin->resizebar && fwin->resizebar->window
&& !fwin->flags.repaint_only_titlebar
&& fwin->resizebar_texture[0]->any.type == WTEX_SOLID) {
Window win;
int w, h;
int cw;
GC light_gc, dim_gc;
WTexSolid *texture = (WTexSolid *) fwin->resizebar_texture[0];
w = fwin->resizebar->width;
h = fwin->resizebar->height;
cw = fwin->resizebar_corner_width;
light_gc = texture->light_gc;
dim_gc = texture->dim_gc;
win = fwin->resizebar->window;
XDrawLine(dpy, win, dim_gc, 0, 0, w, 0);
XDrawLine(dpy, win, light_gc, 0, 1, w, 1);
XDrawLine(dpy, win, dim_gc, cw, 2, cw, h);
XDrawLine(dpy, win, light_gc, cw + 1, 2, cw + 1, h);
XDrawLine(dpy, win, dim_gc, w - cw - 2, 2, w - cw - 2, h);
XDrawLine(dpy, win, light_gc, w - cw - 1, 2, w - cw - 1, h);
#ifdef SHADOW_RESIZEBAR
XDrawLine(dpy, win, light_gc, 0, 1, 0, h - 1);
XDrawLine(dpy, win, dim_gc, w - 1, 2, w - 1, h - 1);
XDrawLine(dpy, win, dim_gc, 1, h - 1, cw, h - 1);
XDrawLine(dpy, win, dim_gc, cw + 2, h - 1, w - cw - 2, h - 1);
XDrawLine(dpy, win, dim_gc, w - cw, h - 1, w - 1, h - 1);
#endif /* SHADOW_RESIZEBAR */
wm_backend->frame_paint_resizebar(fwin);
}
if (fwin->titlebar && !fwin->flags.repaint_only_resizebar) {
int x, y, w, h;
int lofs = 6, rofs = 6;
int titlelen;
int allButtons = 1;
if (wPreferences.new_style != TS_NEW) {
if (fwin->left_button && !fwin->flags.hide_left_button && !fwin->flags.lbutton_dont_fit)
lofs += fwin->left_button->width + 3;
else
allButtons = 0;
#ifdef XKB_BUTTON_HINT
if (fwin->language_button && !fwin->flags.hide_language_button
&& !fwin->flags.languagebutton_dont_fit)
lofs += fwin->language_button->width;
else
allButtons = 0;
#endif
if (fwin->right_button && !fwin->flags.hide_right_button && !fwin->flags.rbutton_dont_fit)
rofs += fwin->right_button->width + 3;
else
allButtons = 0;
}
#ifdef XKB_BUTTON_HINT
fwin->languagebutton_image = scr->b_pixmaps[WBUT_XKBGROUP1 + fwin->languagemode];
#endif
if (fwin->title && fwin->titlebar->window) {
Drawable buf;
char *title;
title = ShrinkString(*fwin->font, fwin->title, fwin->titlebar->width - lofs - rofs);
titlelen = strlen(title);
w = WMWidthOfString(*fwin->font, title, titlelen);
switch (fwin->flags.justification) {
case WTJ_LEFT:
x = lofs;
break;
case WTJ_RIGHT:
x = fwin->titlebar->width - w - rofs;
break;
default:
if (!allButtons)
x = lofs + (fwin->titlebar->width - w - lofs - rofs) / 2;
else
x = (fwin->titlebar->width - w) / 2;
break;
}
y = *fwin->title_clearance + TITLEBAR_EXTEND_SPACE;
h = WMFontHeight(*fwin->font);
if (y*2 + h > *fwin->title_max_height)
y = (*fwin->title_max_height - h) / 2;
if (y*2 + h < *fwin->title_min_height)
y = (*fwin->title_min_height - h) / 2;
/* We use a w+2 buffer to have an extra pixel on the left and
* another one on the right. This is because for some odd reason,
* sometimes when using AA fonts (when libfreetype2 is compiled
* with bytecode interpreter turned off), some fonts are drawn
* starting from x = -1 not from 0 as requested. Observed with
* capital A letter on the bold 'trebuchet ms' font. -Dan
*/
buf = XCreatePixmap(dpy, fwin->titlebar->window, w + 2, h, scr->w_depth);
XSetClipMask(dpy, scr->copy_gc, None);
if (fwin->title_texture[state]->any.type != WTEX_SOLID) {
XCopyArea(dpy, fwin->title_back[state], buf, scr->copy_gc,
x - 1, y, w + 2, h, 0, 0);
} else {
XSetForeground(dpy, scr->copy_gc, fwin->title_texture[state]->solid.normal.pixel);
XFillRectangle(dpy, buf, scr->copy_gc, 0, 0, w + 2, h);
}
/*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
WMDrawString(scr->wmscreen, buf, fwin->title_color[state],
*fwin->font, 1, 0, title, titlelen);
XCopyArea(dpy, buf, fwin->titlebar->window, scr->copy_gc, 0, 0, w + 2, h, x - 1, y);
wm_backend->pixmap_free((unsigned long)buf);
wfree(title);
}
wm_backend->frame_paint_titlebar(fwin, state);
if (fwin->left_button)
handleButtonExpose(&fwin->left_button->descriptor, NULL);

View File

@ -37,161 +37,37 @@ int PropGetWMClass(Window window, char **wm_class, char **wm_instance)
void PropGetProtocols(Window window, WProtocols * prots)
{
Atom *protocols;
int count, i;
memset(prots, 0, sizeof(WProtocols));
if (!XGetWMProtocols(dpy, window, &protocols, &count)) {
return;
}
for (i = 0; i < count; i++) {
if (protocols[i] == w_global.atom.wm.take_focus)
prots->TAKE_FOCUS = 1;
else if (protocols[i] == w_global.atom.wm.delete_window)
prots->DELETE_WINDOW = 1;
else if (protocols[i] == w_global.atom.wm.save_yourself)
prots->SAVE_YOURSELF = 1;
else if (protocols[i] == w_global.atom.gnustep.wm_miniaturize_window)
prots->MINIATURIZE_WINDOW = 1;
}
XFree(protocols);
wm_backend->prop_get_protocols((WNativeWindow)window, prots);
}
unsigned char *PropGetCheckProperty(Window window, Atom hint, Atom type, int format, int count, int *retCount)
{
Atom type_ret;
int fmt_ret;
unsigned long nitems_ret;
unsigned long bytes_after_ret;
unsigned char *data;
int tmp;
if (count <= 0)
tmp = 0xffffff;
else
tmp = count;
if (XGetWindowProperty(dpy, window, hint, 0, tmp, False, type,
&type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret,
(unsigned char **)&data) != Success || !data)
return NULL;
if ((type != AnyPropertyType && type != type_ret)
|| (count > 0 && nitems_ret != count)
|| (format != 0 && format != fmt_ret)) {
XFree(data);
return NULL;
}
if (retCount)
*retCount = nitems_ret;
return data;
return wm_backend->prop_get_check_property((WNativeWindow)window,
(unsigned long)hint, (unsigned long)type, format, count, retCount);
}
void PropSetWMakerProtocols(Window root)
{
Atom protocols[3];
int count = 0;
protocols[count++] = w_global.atom.wmaker.menu;
protocols[count++] = w_global.atom.wmaker.wm_function;
protocols[count++] = w_global.atom.wmaker.noticeboard;
XChangeProperty(dpy, root, w_global.atom.wmaker.wm_protocols, WA_ATOM,
32, PropModeReplace, (unsigned char *)protocols, count);
wm_backend->prop_set_wmaker_protocols((WNativeWindow)root);
}
void PropSetIconTileHint(WScreen * scr, RImage * image)
{
static Atom imageAtom = 0;
unsigned char *tmp;
int x, y;
if (scr->info_window == None)
return;
if (!imageAtom) {
/*
* WIDTH, HEIGHT (16 bits, MSB First)
* array of R,G,B,A bytes
*/
imageAtom = XInternAtom(dpy, "_RGBA_IMAGE", False);
}
tmp = malloc(image->width * image->height * 4 + 4);
if (!tmp) {
wwarning("could not allocate memory to set _WINDOWMAKER_ICON_TILE hint");
return;
}
tmp[0] = image->width >> 8;
tmp[1] = image->width & 0xff;
tmp[2] = image->height >> 8;
tmp[3] = image->height & 0xff;
if (image->format == RRGBAFormat) {
memcpy(&tmp[4], image->data, image->width * image->height * 4);
} else {
char *ptr = (char *)(tmp + 4);
char *src = (char *)image->data;
for (y = 0; y < image->height; y++) {
for (x = 0; x < image->width; x++) {
*ptr++ = *src++;
*ptr++ = *src++;
*ptr++ = *src++;
*ptr++ = 255;
}
}
}
XChangeProperty(dpy, scr->info_window, w_global.atom.wmaker.icon_tile,
imageAtom, 8, PropModeReplace, tmp, image->width * image->height * 4 + 4);
wfree(tmp);
wm_backend->prop_set_icon_tile(scr, image);
}
Window PropGetClientLeader(Window window)
{
Window *win;
Window leader;
win = (Window *) PropGetCheckProperty(window, w_global.atom.wm.client_leader, WA_WINDOW, 32, 1, NULL);
if (!win)
return None;
leader = (Window) * win;
XFree(win);
return leader;
return (Window)wm_backend->prop_get_client_leader((WNativeWindow)window);
}
int PropGetWindowState(Window window)
{
long *data;
long state;
data = (long *)PropGetCheckProperty(window, w_global.atom.wm.state,
w_global.atom.wm.state, 32, 1, NULL);
if (!data)
return -1;
state = *data;
XFree(data);
return state;
return wm_backend->prop_get_window_state((WNativeWindow)window);
}
void PropCleanUp(Window root)
{
XDeleteProperty(dpy, root, w_global.atom.wmaker.wm_protocols);
XDeleteProperty(dpy, root, w_global.atom.wmaker.noticeboard);
XDeleteProperty(dpy, root, WA_WM_ICON_SIZE);
wm_backend->prop_cleanup((WNativeWindow)root);
}

View File

@ -37,7 +37,6 @@
#include "shutdown.h"
static void restoreWindows(WMBag *bag, WMBagIterator iter);
/*
*----------------------------------------------------------------------
@ -109,42 +108,6 @@ void Shutdown(WShutdownMode mode)
}
}
static void restoreWindows(WMBag * bag, WMBagIterator iter)
{
WCoreWindow *next;
WCoreWindow *core;
WWindow *wwin;
if (iter == NULL) {
core = WMBagFirst(bag, &iter);
} else {
core = WMBagNext(bag, &iter);
}
if (core == NULL)
return;
restoreWindows(bag, iter);
/* go to the end of the list */
while (core->stacking->under)
core = core->stacking->under;
while (core) {
next = core->stacking->above;
if (core->descriptor.parent_type == WCLASS_WINDOW) {
Window window;
wwin = core->descriptor.parent;
window = wwin->client_win;
wUnmanageWindow(wwin, !wwin->flags.internal_window, False);
XMapWindow(dpy, window);
}
core = next;
}
}
/*
*----------------------------------------------------------------------
* RestoreDesktop--
@ -159,51 +122,10 @@ static void restoreWindows(WMBag * bag, WMBagIterator iter)
*/
void RestoreDesktop(WScreen * scr)
{
if (scr->helper_pid > 0) {
kill(scr->helper_pid, SIGTERM);
scr->helper_pid = 0;
}
XGrabServer(dpy);
wDestroyInspectorPanels();
/* reparent windows back to the root window, keeping the stacking order */
restoreWindows(scr->stacking_list, NULL);
XUngrabServer(dpy);
XSetInputFocus(dpy, PointerRoot, RevertToParent, CurrentTime);
wm_backend->colormap_install(scr, NULL);
wm_backend->prop_cleanup((WNativeWindow)scr->root_win);
wm_backend->netwm_cleanup(scr);
XSync(dpy, 0);
wm_backend->restore_desktop(scr);
}
/*
*----------------------------------------------------------------------
* wipeDesktop--
* Kills all windows in a screen. Send DeleteWindow to all windows
* that support it and KillClient on all windows that don't.
*
* Side effects:
* All managed windows are closed.
*
* TODO: change to XQueryTree()
*----------------------------------------------------------------------
*/
void wWipeDesktop(WScreen * scr)
{
WWindow *wwin;
wwin = scr->focused_window;
while (wwin) {
if (wwin->protocols.DELETE_WINDOW)
wClientSendProtocol(wwin, w_global.atom.wm.delete_window,
w_global.timestamp.last_event);
else
wClientKill(wwin);
wwin = wwin->prev;
}
XSync(dpy, False);
wm_backend->wipe_desktop(scr);
}