and now to merge
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good

This commit is contained in:
IoIxD 2026-09-11 21:00:38 -07:00
commit f25b676523
3 changed files with 138 additions and 106 deletions

View file

@ -424,6 +424,8 @@ struct _MwLLWayland {
MwBool force_render; MwBool force_render;
MwBool did_event_loop_early; MwBool did_event_loop_early;
MwBool do_cascading_draw;
int cascading_child_num;
MwBool dispatching_resize; MwBool dispatching_resize;
@ -452,8 +454,6 @@ struct _MwLLWayland {
MwU64 next_elapsed; MwU64 next_elapsed;
long start_time; long start_time;
long end_time; long end_time;
MwBool on_hyprland;
}; };
struct _MwLLWaylandColor { struct _MwLLWaylandColor {

View file

@ -559,76 +559,79 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
WAYLAND_EVENT_OP_END(self); WAYLAND_EVENT_OP_END(self);
}; };
// static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) { static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) {
// MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.user;
// MwLLDispatch(handle, down, p); MwLLDispatch(handle, down, p);
// if(h) { if(h) {
// int i; int i;
// for(i = 0; i < arrlen(h->children); i++) { for(i = 0; i < arrlen(h->children); i++) {
// MwLLDispatch(h->children[i]->lowlevel, down, p); MwLLDispatch(h->children[i]->lowlevel, down, p);
// if(arrlen(h->children[i]->children) > 0) { if(arrlen(h->children[i]->children) > 0) {
// recursive_dispatch_mouse_down(h->children[i]->lowlevel, p); recursive_dispatch_mouse_down(h->children[i]->lowlevel, p);
// } }
// }
// }
// };
// static void recursive_dispatch_mouse_up(MwLL handle, MwMouse* p) {
// MwWidget h = (MwWidget)handle->common.user;
// MwLLDispatch(handle, up, p);
// if(h) {
// int i;
// for(i = 0; i < arrlen(h->children); i++) {
// MwLLDispatch(h->children[i]->lowlevel, up, p);
// if(arrlen(h->children[i]->children) > 0) {
// recursive_dispatch_mouse_up(h->children[i]->lowlevel, p);
// }
// }
// }
// };
static void pointer_iterate_master(MwLL handle, MwLL child, MwBool down) {
MwLL topmost_parent = handle;
MwPoint point;
MwPoint relative_pos;
MwPoint absolute_pos;
absolute_pos.x = child->wayland.x;
absolute_pos.y = child->wayland.y;
while(topmost_parent->wayland.parent) {
topmost_parent = topmost_parent->wayland.parent;
if(topmost_parent) {
absolute_pos.x += topmost_parent->wayland.x;
absolute_pos.y += topmost_parent->wayland.y;
} }
} }
};
point = topmost_parent->wayland.cur_mouse_pos; static void recursive_dispatch_mouse_up(MwLL handle, MwMouse* p) {
relative_pos.x = point.x - absolute_pos.x; MwWidget h = (MwWidget)handle->common.user;
relative_pos.y = point.y - absolute_pos.y; MwLLDispatch(handle, up, p);
if(h) {
if( int i;
point.x >= absolute_pos.x && point.x <= absolute_pos.x + child->wayland.ww && for(i = 0; i < arrlen(h->children); i++) {
point.y >= absolute_pos.y && point.y <= absolute_pos.y + child->wayland.wh) { MwLLDispatch(h->children[i]->lowlevel, up, p);
MwMouse p; if(arrlen(h->children[i]->children) > 0) {
p.point = relative_pos; recursive_dispatch_mouse_up(h->children[i]->lowlevel, p);
}
if(down) { }
MwLLDispatch(child, down, &p); }
} else { };
MwLLDispatch(child, up, &p);
static void mouse_dispatch(MwLL self, MwMouse p, MwU32 state) {
switch(state) {
case WL_POINTER_BUTTON_STATE_PRESSED:
MwLLDispatch(self, down, &p);
break;
case WL_POINTER_BUTTON_STATE_RELEASED:
MwLLDispatch(self, up, &p);
break;
}
if(self->common.user) {
MwWidget w = self->common.user;
int i;
for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
MwLL child = w->children[i]->lowlevel;
MwLL topmost_parent = child;
MwPoint point;
MwPoint relative_mouse_pos;
MwPoint absolute_pos;
absolute_pos.x = child->wayland.x;
absolute_pos.y = child->wayland.y;
while(topmost_parent->wayland.parent) {
topmost_parent = topmost_parent->wayland.parent;
if(topmost_parent) {
absolute_pos.x += topmost_parent->wayland.x;
absolute_pos.y += topmost_parent->wayland.y;
}
}
point = topmost_parent->wayland.cur_mouse_pos;
relative_mouse_pos.x = point.x - absolute_pos.x;
relative_mouse_pos.y = point.y - absolute_pos.y;
if(
point.x >= absolute_pos.x && point.x <= absolute_pos.x + child->wayland.ww &&
point.y >= absolute_pos.y && point.y <= absolute_pos.y + child->wayland.wh) {
p.point = relative_mouse_pos;
mouse_dispatch(child, p, state);
}
}
} }
printf("%p %s (%d %d %d %d)\n", child, down ? "DOWN" : "UP", p.point.x, p.point.y, child->wayland.ww, child->wayland.wh);
} }
}
static void pointer_iterate_down(MwLL handle, MwLL child) {
pointer_iterate_master(handle, child, MwTRUE);
MwLLWaylandChildrenIterate(child, pointer_iterate_down);
}
static void pointer_iterate_up(MwLL handle, MwLL child) {
pointer_iterate_master(handle, child, MwFALSE);
MwLLWaylandChildrenIterate(child, pointer_iterate_up);
} }
/* `wl_pointer.button` callback */ /* `wl_pointer.button` callback */
@ -656,17 +659,15 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
break; break;
} }
self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED; self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED;
switch(state) { switch(state) {
case WL_POINTER_BUTTON_STATE_PRESSED: case WL_POINTER_BUTTON_STATE_PRESSED:
MwLLDispatch(self, down, &p); MwLLDispatch(self, down, &p);
MwLLWaylandChildrenIterate(self, pointer_iterate_down);
break; break;
case WL_POINTER_BUTTON_STATE_RELEASED: case WL_POINTER_BUTTON_STATE_RELEASED:
MwLLDispatch(self, up, &p); MwLLDispatch(self, up, &p);
MwLLWaylandChildrenIterate(self, pointer_iterate_up);
break; break;
} }
mouse_dispatch(self, p, state);
if(!self->wayland.has_decorations && self->wayland.do_csd) { if(!self->wayland.has_decorations && self->wayland.do_csd) {
if(state != WL_POINTER_BUTTON_STATE_RELEASED) if(state != WL_POINTER_BUTTON_STATE_RELEASED)
@ -675,6 +676,8 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
xdg_borderless_step_mup(self, p, serial); xdg_borderless_step_mup(self, p, serial);
} }
MwLLForceRender(self);
WAYLAND_EVENT_OP_END(self); WAYLAND_EVENT_OP_END(self);
}; };

View file

@ -942,6 +942,60 @@ static void detect_dark_theme(MwLL handle) {
} }
#endif #endif
static void draw_child(MwLL handle, MwLL child);
static void draw_children(MwLL handle);
static void draw_child(MwLL handle, MwLL child) {
cairo_t* c;
cairo_surface_t* cs;
cairo_t* selected_cairo = handle->wayland.cairo.front_cairo;
wl_surface_commit(child->wayland.framebuffer.surface);
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, child->wayland.ww, child->wayland.wh);
c = cairo_create(cs);
cairo_set_source_surface(c, child->wayland.cairo.front_cs, 0, 0);
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
cairo_set_operator(handle->wayland.cairo.front_cairo, CAIRO_OPERATOR_OVER);
cairo_paint(c);
cairo_set_source_surface(selected_cairo, cs, child->wayland.x, child->wayland.y);
cairo_paint(selected_cairo);
cairo_destroy(c);
cairo_surface_destroy(cs);
draw_children(child);
}
static void draw_children(MwLL handle) {
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
MwLLWaylandChildrenIterate(handle, draw_child);
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
handle->wayland.events_pending = MwFALSE;
}
static void cascade_child(MwLL handle, MwLL child) {
child->wayland.do_cascading_draw = 10;
}
static void count_child(MwLL handle, MwLL child) {
handle->wayland.cascading_child_num++;
}
static void cascade_children(MwLL handle) {
handle->wayland.cascading_child_num = 0;
MwLLWaylandChildrenIterate(handle, count_child);
handle->wayland.do_cascading_draw = 10;
MwLLWaylandChildrenIterate(handle, cascade_child);
}
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
MwLL r; MwLL r;
r = malloc(sizeof(*r)); r = malloc(sizeof(*r));
@ -1035,8 +1089,11 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsign
static void MwLLSetXYImpl(MwLL handle, int x, int y) { static void MwLLSetXYImpl(MwLL handle, int x, int y) {
WIDGET_CHECK(handle); WIDGET_CHECK(handle);
MwLLWaylandRegionInvalidate(handle); MwLLWaylandRegionInvalidate(handle);
handle->wayland.x = x;
handle->wayland.y = y; if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
handle->wayland.x = x;
handle->wayland.y = y;
}
switch(handle->wayland.type) { switch(handle->wayland.type) {
case MwLL_WAYLAND_TOPLEVEL: case MwLL_WAYLAND_TOPLEVEL:
@ -1119,41 +1176,6 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
handle->wayland.events_pending = 1; handle->wayland.events_pending = 1;
} }
static void draw_child(MwLL handle, MwLL child);
static void draw_children(MwLL handle);
static void draw_child(MwLL handle, MwLL child) {
cairo_t* c;
cairo_surface_t* cs;
cairo_t* selected_cairo = handle->wayland.cairo.front_cairo;
wl_surface_commit(child->wayland.framebuffer.surface);
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, child->wayland.ww, child->wayland.wh);
c = cairo_create(cs);
cairo_set_source_surface(c, child->wayland.cairo.front_cs, 0, 0);
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
cairo_set_operator(handle->wayland.cairo.front_cairo, CAIRO_OPERATOR_OVER);
cairo_paint(c);
cairo_set_source_surface(selected_cairo, cs, child->wayland.x, child->wayland.y);
cairo_paint(selected_cairo);
cairo_destroy(c);
cairo_surface_destroy(cs);
draw_children(child);
}
static void draw_children(MwLL handle) {
MwLLWaylandChildrenIterate(handle, draw_child);
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
handle->wayland.force_render = MwTRUE;
}
typedef struct { typedef struct {
double r, g, b; double r, g, b;
@ -1317,7 +1339,7 @@ static void MwLLEndDrawImpl(MwLL handle) {
} }
MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer); MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
draw_children(handle); cascade_children(handle);
} }
} }
@ -1382,6 +1404,12 @@ static int MwLLPendingImpl(MwLL handle) {
handle->wayland.setting_wh = 0; handle->wayland.setting_wh = 0;
} }
if(handle->wayland.do_cascading_draw) {
draw_children(handle);
if(handle->wayland.do_cascading_draw > 0)
handle->wayland.do_cascading_draw--;
}
handle->wayland.end_time = MwTimeGetTick(); handle->wayland.end_time = MwTimeGetTick();
if(handle->wayland.holding_key) { if(handle->wayland.holding_key) {
@ -1440,6 +1468,7 @@ static int MwLLPendingImpl(MwLL handle) {
static void MwLLNextEventImpl(MwLL handle) { static void MwLLNextEventImpl(MwLL handle) {
WIDGET_CHECK(handle); WIDGET_CHECK(handle);
if(!MwWaylandVulkan) { if(!MwWaylandVulkan) {
if(handle->wayland.did_event_loop_early) { if(handle->wayland.did_event_loop_early) {
handle->wayland.did_event_loop_early = MwFALSE; handle->wayland.did_event_loop_early = MwFALSE;