Implement frame button rendering (close/iconify icons)
Add wl_frame_paint_button which renders button icons from XPM data into the parent frame buffer. Called both from the vtable slot and from wl_frame_paint during titlebar rendering. Uses PRED_CLOSE_XPM and PRED_ICONIFY_XPM parsed lazily via RGetImageFromXPMData. Also removes XEvent from all WFrameWindow callbacks (on_click_left, on_click_right, on_dblclick_right, on_mousedown_resizebar) — they now take WMEvent*.
This commit is contained in:
parent
1af95d539f
commit
784fcfbfb2
|
|
@ -203,6 +203,7 @@
|
|||
#include <WINGs/WINGsP.h>
|
||||
/* ------------------------------------------------------------------ */
|
||||
#include <WINGs/WMEvent.h>
|
||||
#include "../../def_pixmaps.h"
|
||||
struct W_Screen;
|
||||
struct W_View;
|
||||
void W_WL_EnqueueEvent(struct W_Screen *scr, const WMEvent *ev, struct W_View *target);
|
||||
|
|
@ -495,6 +496,10 @@ struct wl_compositor_state {
|
|||
* wl_event_loop_run() after the startup pump thread stops (to avoid racing
|
||||
* with the pump thread's frame-timer callback on the scene graph). */
|
||||
WScreen *dock_pending_scr;
|
||||
/* Button icon RImages (parsed from XPM on first use) */
|
||||
RImage *btn_close_img;
|
||||
RImage *btn_iconify_img;
|
||||
RImage *btn_kill_img;
|
||||
};
|
||||
|
||||
static struct wl_compositor_state wl_state;
|
||||
|
|
@ -3681,6 +3686,9 @@ wl_frame_configure(WNativeWindow win, int x, int y, int width, int height)
|
|||
}
|
||||
}
|
||||
|
||||
static void wl_frame_paint_button(WCoreWindow *button, WTexture *texture,
|
||||
unsigned long color, WPixmap *image, int pushed);
|
||||
|
||||
/*
|
||||
* wl_frame_paint — render the entire frame decoration into the pixman buffer.
|
||||
*
|
||||
|
|
@ -3781,6 +3789,22 @@ wl_frame_paint(struct WFrameWindow *fwin)
|
|||
}
|
||||
}
|
||||
|
||||
/* --- Titlebar buttons --- */
|
||||
if (fwin->titlebar && fwin->top_width > 0) {
|
||||
if (fwin->left_button && !fwin->flags.hide_left_button &&
|
||||
!fwin->flags.lbutton_dont_fit)
|
||||
wl_frame_paint_button(fwin->left_button,
|
||||
fwin->title_texture[state],
|
||||
WMColorPixel(fwin->title_color[state]),
|
||||
fwin->lbutton_image, False);
|
||||
if (fwin->right_button && !fwin->flags.hide_right_button &&
|
||||
!fwin->flags.rbutton_dont_fit)
|
||||
wl_frame_paint_button(fwin->right_button,
|
||||
fwin->title_texture[state],
|
||||
WMColorPixel(fwin->title_color[state]),
|
||||
fwin->rbutton_image, False);
|
||||
}
|
||||
|
||||
/* --- Resizebar --- */
|
||||
if (fwin->resizebar && fwin->bottom_width > 0) {
|
||||
int rb_y = total_h - fwin->bottom_width;
|
||||
|
|
@ -6209,9 +6233,72 @@ static void wl_noop_frame_alloc_border_pixel(unsigned long colormap,
|
|||
|
||||
static void wl_noop_frame_update_texture(struct WFrameWindow *fwin) { (void)fwin; }
|
||||
|
||||
static void wl_noop_frame_paint_button(WCoreWindow *button, WTexture *texture,
|
||||
static void wl_frame_paint_button(WCoreWindow *button, WTexture *texture,
|
||||
unsigned long color, WPixmap *image, int pushed)
|
||||
{ (void)button; (void)texture; (void)color; (void)image; (void)pushed; }
|
||||
{
|
||||
(void)texture; (void)color; (void)image;
|
||||
WFrameWindow *fwin = (WFrameWindow *)button->descriptor.parent;
|
||||
if (!fwin || !fwin->core)
|
||||
return;
|
||||
|
||||
struct wl_frame_buf *frame_fb = frame_buf_find(fwin->core->window);
|
||||
struct wl_frame_buf *btn_fb = frame_buf_find(button->window);
|
||||
if (!frame_fb || !frame_fb->image || !btn_fb)
|
||||
return;
|
||||
|
||||
int bx = btn_fb->rel_x;
|
||||
int by = btn_fb->rel_y;
|
||||
int bw = btn_fb->width;
|
||||
int bh = btn_fb->height;
|
||||
|
||||
/* Determine which icon to use */
|
||||
RImage *icon = NULL;
|
||||
if (button == fwin->right_button) {
|
||||
if (!wl_state.btn_close_img)
|
||||
wl_state.btn_close_img = RGetImageFromXPMData(
|
||||
button->screen_ptr->rcontext, PRED_CLOSE_XPM);
|
||||
icon = wl_state.btn_close_img;
|
||||
} else if (button == fwin->left_button) {
|
||||
if (!wl_state.btn_iconify_img)
|
||||
wl_state.btn_iconify_img = RGetImageFromXPMData(
|
||||
button->screen_ptr->rcontext, PRED_ICONIFY_XPM);
|
||||
icon = wl_state.btn_iconify_img;
|
||||
}
|
||||
if (!icon)
|
||||
return;
|
||||
|
||||
/* Blit icon centered in button area */
|
||||
uint32_t *dst = pixman_image_get_data(frame_fb->image);
|
||||
int dst_stride = pixman_image_get_stride(frame_fb->image) / 4;
|
||||
int ix = bx + (bw - icon->width) / 2 + (pushed ? 1 : 0);
|
||||
int iy = by + (bh - icon->height) / 2 + (pushed ? 1 : 0);
|
||||
|
||||
for (int y = 0; y < icon->height; y++) {
|
||||
int dy = iy + y;
|
||||
if (dy < 0 || dy >= frame_fb->height) continue;
|
||||
uint32_t *dst_row = dst + dy * dst_stride;
|
||||
for (int x = 0; x < icon->width; x++) {
|
||||
int dx = ix + x;
|
||||
if (dx < 0 || dx >= frame_fb->width) continue;
|
||||
unsigned char r, g, b, a;
|
||||
if (icon->format == RRGBAFormat) {
|
||||
int off = (y * icon->width + x) * 4;
|
||||
r = icon->data[off]; g = icon->data[off+1];
|
||||
b = icon->data[off+2]; a = icon->data[off+3];
|
||||
} else {
|
||||
int off = (y * icon->width + x) * 3;
|
||||
r = icon->data[off]; g = icon->data[off+1];
|
||||
b = icon->data[off+2]; a = 255;
|
||||
}
|
||||
if (a == 0) continue; /* transparent */
|
||||
dst_row[dx] = ((uint32_t)a << 24) | ((uint32_t)r << 16) |
|
||||
((uint32_t)g << 8) | (uint32_t)b;
|
||||
}
|
||||
}
|
||||
|
||||
if (frame_fb->scene_buf)
|
||||
wlr_scene_buffer_set_buffer(frame_fb->scene_buf, &frame_fb->base);
|
||||
}
|
||||
|
||||
static void wl_noop_netwm_init(WScreen *scr) { (void)scr; }
|
||||
static void wl_noop_netwm_cleanup(WScreen *scr) { (void)scr; }
|
||||
|
|
@ -6978,7 +7065,7 @@ const WMBackend wl_backend = {
|
|||
.texture_free_gc = wl_texture_free_gc,
|
||||
.frame_alloc_border_pixel = wl_noop_frame_alloc_border_pixel,
|
||||
.frame_update_texture = wl_noop_frame_update_texture,
|
||||
.frame_paint_button = wl_noop_frame_paint_button,
|
||||
.frame_paint_button = wl_frame_paint_button,
|
||||
.netwm_init = wl_noop_netwm_init,
|
||||
.netwm_cleanup = wl_noop_netwm_cleanup,
|
||||
.netwm_update_desktop = wl_noop_netwm_update_desktop,
|
||||
|
|
|
|||
Loading…
Reference in New Issue