Phase 80m: clean X11 from appicon.c

- wAppIconPaint: X11 rendering (dock dots, corner triangle, stipple)
  moved to new appicon_paint_dock_dots vtable slot
- XGrabPointer -> pointer_grab vtable
- XChangeActivePointerGrab -> new pointer_change_cursor vtable slot
- drawCorner removed (inlined into x11 backend)

New vtable slots: pointer_change_cursor, appicon_paint_dock_dots.
appicon.o verified X11-free with nm.
This commit is contained in:
Levi Neely 2026-05-13 11:31:31 +02:00
parent 40ac4f252b
commit 2bb40cf9fa
4 changed files with 58 additions and 48 deletions

View File

@ -351,23 +351,6 @@ void wAppIconDestroy(WAppIcon * aicon)
wrelease(aicon);
}
static void drawCorner(WIcon * icon)
{
WScreen *scr = icon->core->screen_ptr;
XPoint points[3];
points[0].x = 1;
points[0].y = 1;
points[1].x = 12;
points[1].y = 1;
points[2].x = 1;
points[2].y = 12;
XFillPolygon(dpy, icon->core->window, scr->icon_title_texture->normal_gc,
points, 3, Convex, CoordModeOrigin);
XDrawLine(dpy, icon->core->window, scr->icon_title_texture->light_gc, 0, 0, 0, 12);
XDrawLine(dpy, icon->core->window, scr->icon_title_texture->light_gc, 0, 0, 12, 0);
}
void wAppIconMove(WAppIcon * aicon, int x, int y)
{
wm_backend->window_move(aicon->icon->core->window, x, y);
@ -405,35 +388,14 @@ void wAppIconPaint(WAppIcon *aicon)
else
wapp = NULL;
wIconPaint(aicon->icon);
# ifdef WS_INDICATOR
if (aicon->docked && scr->dock && scr->dock == aicon->dock && aicon->yindex == 0)
updateDockNumbers(scr);
# endif
if (aicon->docked && !aicon->running && aicon->command != NULL) {
XSetClipMask(dpy, scr->copy_gc, scr->dock_dots->mask);
XSetClipOrigin(dpy, scr->copy_gc, 0, 0);
XCopyArea(dpy, scr->dock_dots->image, aicon->icon->core->window,
scr->copy_gc, 0, 0, scr->dock_dots->width, scr->dock_dots->height, 0, 0);
}
#ifdef HIDDENDOT
if (wapp && wapp->flags.hidden) {
XSetClipMask(dpy, scr->copy_gc, scr->dock_dots->mask);
XSetClipOrigin(dpy, scr->copy_gc, 0, 0);
XCopyArea(dpy, scr->dock_dots->image,
aicon->icon->core->window, scr->copy_gc, 0, 0, 7, scr->dock_dots->height, 0, 0);
}
#endif /* HIDDENDOT */
if (aicon->omnipresent)
drawCorner(aicon->icon);
XSetClipMask(dpy, scr->copy_gc, None);
if (aicon->launching)
XFillRectangle(dpy, aicon->icon->core->window, scr->stipple_gc,
0, 0, wPreferences.icon_size, wPreferences.icon_size);
wm_backend->appicon_paint_dock_dots(aicon, wapp);
}
/* Save the application icon, if it's a dockapp then use it with dock = True */
@ -720,9 +682,9 @@ void appIconMouseDown(WObjDescriptor * desc, WBackendEvent * event)
return;
if (event->u.button.send_event &&
XGrabPointer(dpy, aicon->icon->core->window, True, ButtonMotionMask
| ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
GrabModeAsync, None, None, CurrentTime) != GrabSuccess) {
!wm_backend->pointer_grab((WNativeWindow)aicon->icon->core->window, WNATIVE_NONE,
ButtonMotionMask | ButtonReleaseMask | ButtonPressMask,
WCUR_NORMAL, True, 0)) {
wwarning("pointer grab failed for appicon menu");
return;
}
@ -784,9 +746,9 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
wLowerFrame(icon->core);
}
if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask
| ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
GrabModeAsync, None, None, CurrentTime) != GrabSuccess) {
if (!wm_backend->pointer_grab((WNativeWindow)icon->core->window, WNATIVE_NONE,
ButtonMotionMask | ButtonReleaseMask | ButtonPressMask,
WCUR_NORMAL, True, 0)) {
wwarning("Pointer grab failed in wHandleAppIconMove");
}
@ -861,9 +823,7 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
if (!grabbed) {
if (abs(ofs_x - ev.u.motion.x) >= MOVE_THRESHOLD
|| abs(ofs_y - ev.u.motion.y) >= MOVE_THRESHOLD) {
XChangeActivePointerGrab(dpy, ButtonMotionMask
| ButtonReleaseMask | ButtonPressMask,
wPreferences.cursor[WCUR_MOVE], CurrentTime);
wm_backend->pointer_change_cursor(WCUR_MOVE);
grabbed = 1;
} else {
break;

View File

@ -1724,6 +1724,8 @@ typedef struct WMBackend {
const char *mask_path, Cursor *cursor_out);
void (*cursor_free)(Cursor cursor);
void (*cursor_set)(WNativeWindow window, Cursor cursor);
void (*pointer_change_cursor)(int cursor_id);
void (*appicon_paint_dock_dots)(struct WAppIcon *aicon, void *wapp);
} WMBackend;

View File

@ -6241,6 +6241,9 @@ static int wl_noop_cursor_create_from_files(WScreen *scr, const char *bitmap_pat
{ (void)scr; (void)bitmap_path; (void)mask_path; (void)cursor_out; return 0; }
static void wl_noop_cursor_free(Cursor cursor) { (void)cursor; }
static void wl_noop_cursor_set(WNativeWindow window, Cursor cursor) { (void)window; (void)cursor; }
static void wl_noop_pointer_change_cursor(int cursor_id) { (void)cursor_id; }
static void wl_noop_appicon_paint_dock_dots(WAppIcon *aicon, void *wapp)
{ (void)aicon; (void)wapp; }
/* ------------------------------------------------------------------ */
/* vtable */
@ -6473,4 +6476,6 @@ const WMBackend wl_backend = {
.cursor_create_from_files = wl_noop_cursor_create_from_files,
.cursor_free = wl_noop_cursor_free,
.cursor_set = wl_noop_cursor_set,
.pointer_change_cursor = wl_noop_pointer_change_cursor,
.appicon_paint_dock_dots = wl_noop_appicon_paint_dock_dots,
};

View File

@ -3080,6 +3080,47 @@ static void x11_cursor_set(WNativeWindow window, Cursor cursor)
XDefineCursor(dpy, (Window)window, cursor);
}
static void x11_pointer_change_cursor(int cursor_id)
{
XChangeActivePointerGrab(dpy, ButtonMotionMask | ButtonReleaseMask | ButtonPressMask,
wPreferences.cursor[cursor_id], CurrentTime);
}
static void x11_appicon_paint_dock_dots(WAppIcon *aicon, void *wapp_ptr)
{
WApplication *wapp = (WApplication *)wapp_ptr;
WScreen *scr = aicon->icon->core->screen_ptr;
if (aicon->docked && !aicon->running && aicon->command != NULL) {
XSetClipMask(dpy, scr->copy_gc, scr->dock_dots->mask);
XSetClipOrigin(dpy, scr->copy_gc, 0, 0);
XCopyArea(dpy, scr->dock_dots->image, aicon->icon->core->window,
scr->copy_gc, 0, 0, scr->dock_dots->width, scr->dock_dots->height, 0, 0);
}
#ifdef HIDDENDOT
if (wapp && wapp->flags.hidden) {
XSetClipMask(dpy, scr->copy_gc, scr->dock_dots->mask);
XSetClipOrigin(dpy, scr->copy_gc, 0, 0);
XCopyArea(dpy, scr->dock_dots->image,
aicon->icon->core->window, scr->copy_gc, 0, 0, 7, scr->dock_dots->height, 0, 0);
}
#endif
if (aicon->omnipresent) {
XPoint points[3];
points[0].x = 1; points[0].y = 1;
points[1].x = 12; points[1].y = 1;
points[2].x = 1; points[2].y = 12;
XFillPolygon(dpy, aicon->icon->core->window, scr->icon_title_texture->normal_gc,
points, 3, Convex, CoordModeOrigin);
XDrawLine(dpy, aicon->icon->core->window, scr->icon_title_texture->light_gc, 0, 0, 0, 12);
XDrawLine(dpy, aicon->icon->core->window, scr->icon_title_texture->light_gc, 0, 0, 12, 0);
}
XSetClipMask(dpy, scr->copy_gc, None);
if (aicon->launching)
XFillRectangle(dpy, aicon->icon->core->window, scr->stipple_gc,
0, 0, wPreferences.icon_size, wPreferences.icon_size);
}
/* -------------------------------------------------------------------- */
/* Client operations (Phase 80) */
/* -------------------------------------------------------------------- */
@ -3794,6 +3835,8 @@ const WMBackend x11_backend = {
.cursor_create_from_files = x11_cursor_create_from_files,
.cursor_free = x11_cursor_free,
.cursor_set = x11_cursor_set,
.pointer_change_cursor = x11_pointer_change_cursor,
.appicon_paint_dock_dots = x11_appicon_paint_dock_dots,
};
/*