wayland: overhaul CSD, functions/looks much better.
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good

This commit is contained in:
IoIxD 2026-05-20 16:29:09 -07:00
commit 9ee96a71c4
4 changed files with 137 additions and 36 deletions

View file

@ -28,8 +28,8 @@ MWDECL int MwLLWaylandCallInit(void);
#define CSD_BORDER_FRAME_LEFT 5
#define CSD_BORDER_FRAME_RIGHT 5
#define CSD_BORDER_FRAME_TOP 24
#define CSD_BORDER_FRAME_BOTTOM 5
#define CSD_BORDER_FRAME_TOP 23
#define CSD_BORDER_FRAME_BOTTOM 4
struct _MwLLWayland;
@ -360,6 +360,7 @@ struct _MwLLWaylandTopLevel {
struct xdg_toplevel* xdg_top_level;
struct xdg_toplevel_listener xdg_toplevel_listener;
struct xdg_surface_listener xdg_surface_listener;
MwBool maxim_state;
MwBool compositor_created;
MwBool xdg_wm_base_created;
@ -555,6 +556,8 @@ struct _MwLLWayland {
struct _MwLLWaylandShmBuffer cursor;
struct _MwLLWaylandShmBuffer* icon;
MwLLPixmap icon_pixmap;
pthread_mutex_t eventsMutex;
int cancelEvent;

View file

@ -406,6 +406,10 @@ static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 seria
wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, topmost_parent->wayland.cursor.surface, 0, 0);
}
if(self->wayland.backbuffer.surface == surface) {
curSurface = surface;
}
WAYLAND_EVENT_OP_END(self);
};
@ -440,7 +444,22 @@ static void xdg_borderless_step(MwLL self, MwMouse p, MwU32 serial) {
} else if(p.point.x <= 5) {
xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_LEFT);
} else if(p.point.y <= CSD_BORDER_FRAME_TOP) {
xdg_toplevel_move(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial);
if(p.point.x >= CSD_BORDER_FRAME_LEFT && p.point.x <= CSD_BORDER_FRAME_LEFT + 18) {
MwLLDispatch(self, close, NULL);
} else if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 21) {
xdg_toplevel_set_minimized(self->wayland.toplevel->xdg_top_level);
} else if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 38) {
self->wayland.toplevel->maxim_state = !self->wayland.toplevel->maxim_state;
if(self->wayland.toplevel->maxim_state == 0) {
xdg_toplevel_unset_maximized(self->wayland.toplevel->xdg_top_level);
} else {
xdg_toplevel_set_maximized(self->wayland.toplevel->xdg_top_level);
}
self->wayland.setting_wh = 1;
MwLLWaylandRegionSetup(self);
} else {
xdg_toplevel_move(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial);
}
}
};
}

View file

@ -11,6 +11,10 @@ void MwLLWaylandRegionSetup(MwLL handle) {
int width = (handle->wayland.clipping_rect.width == 0) ? handle->wayland.ww : handle->wayland.clipping_rect.width;
int height = (handle->wayland.clipping_rect.height == 0) ? handle->wayland.wh : handle->wayland.clipping_rect.height;
if(!handle->wayland.has_decorations && handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
width += CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT;
height += CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM;
}
if(!handle->wayland.configured) {
return;
}

View file

@ -176,6 +176,12 @@ static void xdg_toplevel_configure(void* data,
MwLLWaylandRegionInvalidate(self);
self->wayland.ww = width;
self->wayland.wh = height;
if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
if(!self->wayland.has_decorations && self->wayland.toplevel->maxim_state) {
self->wayland.ww -= CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT;
self->wayland.wh -= CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM;
}
}
if(self->wayland.resizing == 0) {
xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, 0, 0, self->wayland.ww, self->wayland.wh);
@ -885,6 +891,18 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
handle->wayland.events_pending = 1;
}
typedef struct {
double r, g, b;
} float_color;
static float_color lerp_color(float_color a, float_color b, float t) {
return (float_color){
a.r + (b.r - a.r) * t,
a.g + (b.g - a.g) * t,
a.b + (b.b - a.b) * t};
}
const float_color one = {.2627451, .37254902, .49411765};
const float_color two = {.05490196, .17254902, .30588235};
static void MwLLBeginDrawImpl(MwLL handle) {
WIDGET_CHECK(handle);
cairo_save(handle->wayland.front_cairo);
@ -900,44 +918,90 @@ static void MwLLBeginDrawImpl(MwLL handle) {
}
if(!handle->wayland.has_decorations) {
int x;
MwU32 w = handle->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT;
MwU32 h = handle->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM;
cairo_set_line_width(handle->wayland.back_cairo, 4.0);
for(x = 0; x < w; x++) {
float placeholder = (float)x / (float)w;
cairo_set_source_rgb(handle->wayland.back_cairo, placeholder, 0.25, 0.25);
int y;
MwU32 w = handle->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT;
MwU32 h = handle->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM;
MwRect r;
handle->wayland.selected_cairo = handle->wayland.back_cairo;
cairo_move_to(handle->wayland.back_cairo, w - x, 0);
cairo_line_to(handle->wayland.back_cairo, w - x, CSD_BORDER_FRAME_TOP);
cairo_stroke(handle->wayland.back_cairo);
#define DO_BOX(x, y, col, w, h) \
cairo_rectangle(handle->wayland.back_cairo, x, y, w, h); \
cairo_set_source_rgb(handle->wayland.back_cairo, col, col, col); \
cairo_fill(handle->wayland.back_cairo);
cairo_move_to(handle->wayland.back_cairo, x, CSD_BORDER_FRAME_TOP);
cairo_line_to(handle->wayland.back_cairo, x, h);
#define DO_LINE(off, col) \
cairo_move_to(handle->wayland.back_cairo, off, off); \
cairo_line_to(handle->wayland.back_cairo, off, h - (off)); \
cairo_set_source_rgb(handle->wayland.back_cairo, col, col, col); \
cairo_stroke(handle->wayland.back_cairo); \
cairo_move_to(handle->wayland.back_cairo, off, off); \
cairo_line_to(handle->wayland.back_cairo, w - (off), off); \
cairo_set_source_rgb(handle->wayland.back_cairo, col, col, col); \
cairo_stroke(handle->wayland.back_cairo);
/* border */
cairo_set_antialias(handle->wayland.back_cairo, CAIRO_ANTIALIAS_NONE);
DO_BOX(0, 0, 0.14901961, w, h);
DO_BOX(1, 1, 0.55686275, w - 2, h - 2);
DO_BOX(2, 2, 0.82352941, w - 4, h - 4);
DO_BOX(3, 3, 0.93333333, w - 6, h - 6);
DO_BOX(4, 4, 1, w - 8, h - 8);
DO_BOX(4, 4, 0.14901961, w - CSD_BORDER_FRAME_LEFT - 4, h - CSD_BORDER_FRAME_BOTTOM - 4);
cairo_set_line_width(handle->wayland.back_cairo, 1.0);
DO_LINE(1, 1)
DO_LINE(2, 0.93333333)
DO_LINE(3, 0.82352941)
DO_LINE(4, 0.55686275)
DO_LINE(5, 0.14901961)
cairo_set_line_width(handle->wayland.back_cairo, 2.0);
for(y = 1; y < CSD_BORDER_FRAME_TOP - CSD_BORDER_FRAME_LEFT; y++) {
float_color c = lerp_color(one, two, (double)y / (double)(CSD_BORDER_FRAME_TOP - CSD_BORDER_FRAME_LEFT));
cairo_set_source_rgb(handle->wayland.back_cairo, c.r, c.g, c.b);
cairo_move_to(handle->wayland.back_cairo, CSD_BORDER_FRAME_LEFT, y + CSD_BORDER_FRAME_LEFT);
cairo_line_to(handle->wayland.back_cairo, w - CSD_BORDER_FRAME_RIGHT, y + CSD_BORDER_FRAME_LEFT);
cairo_stroke(handle->wayland.back_cairo);
}
cairo_set_source_rgba(handle->wayland.back_cairo, 1, 1, 1, 0.5);
cairo_move_to(handle->wayland.back_cairo, 0, 0);
cairo_line_to(handle->wayland.back_cairo, 0, h);
cairo_stroke(handle->wayland.back_cairo);
cairo_move_to(handle->wayland.back_cairo, 0, 0);
cairo_line_to(handle->wayland.back_cairo, w, 0);
cairo_stroke(handle->wayland.back_cairo);
cairo_set_source_rgba(handle->wayland.back_cairo, 0, 0, 0, 0.5);
cairo_move_to(handle->wayland.back_cairo, 0, h);
cairo_line_to(handle->wayland.back_cairo, w, h);
cairo_stroke(handle->wayland.back_cairo);
cairo_move_to(handle->wayland.back_cairo, w, 0);
cairo_line_to(handle->wayland.back_cairo, w, h);
cairo_stroke(handle->wayland.back_cairo);
/* icon */
r.x = CSD_BORDER_FRAME_LEFT + 1;
r.y = CSD_BORDER_FRAME_RIGHT + 1;
r.width = 15;
r.height = 15;
DO_BOX(5, 5, 1, 18, 18);
DO_BOX(6, 6, 0.35294118, 17, 17);
DO_BOX(6, 6, 0.82352941, 16, 16);
handle->wayland.selected_cairo = handle->wayland.back_cairo;
if(handle->wayland.icon_pixmap) {
MwLLDrawPixmap(handle, &r, handle->wayland.icon_pixmap);
}
/* close */
DO_BOX(w - 19 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 1, 1, 18, 18);
DO_BOX(w - 18 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 2, 0.35294118, 17, 17);
DO_BOX(w - 18 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 2, 0.82352941, 16, 16);
DO_BOX(w - 18 - CSD_BORDER_FRAME_LEFT + 5, CSD_BORDER_FRAME_BOTTOM + 7, 0, 6, 6);
DO_BOX(w - 18 - CSD_BORDER_FRAME_LEFT + 6, CSD_BORDER_FRAME_BOTTOM + 8, 0.82352941, 4, 4);
/* maxim */
DO_BOX(w - 37 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 1, 1, 18, 18);
DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 2, 0.35294118, 17, 17);
DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 2, 0.82352941, 16, 16);
DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT + 5, CSD_BORDER_FRAME_BOTTOM + 7, 0, 6, 6);
DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 9, 0.82352941, 16, 2);
DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT + 7, CSD_BORDER_FRAME_BOTTOM + 4, 0.82352941, 2, 14);
DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT + 6, CSD_BORDER_FRAME_BOTTOM + 8, 0.82352941, 4, 4);
/* title */
if(strlen(handle->wayland.title) != 0) {
int y, x;
int i = 0, sx = 0, sy = 0;
int tw, th;
unsigned char* px;
MwRect r;
MwLLPixmap p;
tw = strlen(handle->wayland.title) * 7;
th = 14;
@ -946,8 +1010,6 @@ static void MwLLBeginDrawImpl(MwLL handle) {
memset(px, 0, tw * th * 4);
handle->wayland.selected_cairo = handle->wayland.back_cairo;
while(handle->wayland.title[i]) {
int out;
i += MwUTF8ToUTF32(handle->wayland.title + i, &out);
@ -970,8 +1032,8 @@ static void MwLLBeginDrawImpl(MwLL handle) {
}
p = MwLLCreatePixmap(handle, px, tw, th);
r.x = 5;
r.y = 5;
r.x = 24;
r.y = 5 + 2;
r.width = tw;
r.height = th;
@ -1156,6 +1218,8 @@ static void MwLLSetTitleImpl(MwLL handle, const char* title) {
strncpy(handle->wayland.title, title, 255);
MwLLBeginDraw(handle);
MwLLEndDraw(handle);
xdg_toplevel_set_min_size(handle->wayland.toplevel->xdg_top_level, (strlen(handle->wayland.title) * 8) + 64, 64);
}
}
@ -1279,6 +1343,17 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
xdg_toplevel_icon_manager_v1_set_icon(icon_manager, handle->wayland.toplevel->xdg_top_level, icon);
}
}
if(!handle->wayland.has_decorations) {
if(handle->wayland.icon_pixmap) {
MwLLDestroyPixmap(handle->wayland.icon_pixmap);
}
handle->wayland.icon_pixmap = MwLLCreatePixmap(handle, pixmap->common.raw, pixmap->common.width, pixmap->common.height);
actually_set_wh(handle);
actually_set_wh(handle);
MwLLBeginDraw(handle);
MwLLEndDraw(handle);
}
}
static void MwLLForceRenderImpl(MwLL handle) {