From f25b67652343b83dadf0b7c2a34e70d3caa20126 Mon Sep 17 00:00:00 2001 From: IoIxD Date: Fri, 11 Sep 2026 21:00:38 -0700 Subject: [PATCH] and now to merge --- include/Mw/LowLevel/Wayland.h | 4 +- src/backend/wayland/interfaces.c | 141 ++++++++++++++++--------------- src/backend/wayland/wayland.c | 105 ++++++++++++++--------- 3 files changed, 141 insertions(+), 109 deletions(-) diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index c42231c..0bfe201 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -424,6 +424,8 @@ struct _MwLLWayland { MwBool force_render; MwBool did_event_loop_early; + MwBool do_cascading_draw; + int cascading_child_num; MwBool dispatching_resize; @@ -452,8 +454,6 @@ struct _MwLLWayland { MwU64 next_elapsed; long start_time; long end_time; - - MwBool on_hyprland; }; struct _MwLLWaylandColor { diff --git a/src/backend/wayland/interfaces.c b/src/backend/wayland/interfaces.c index caf62ac..43703a9 100644 --- a/src/backend/wayland/interfaces.c +++ b/src/backend/wayland/interfaces.c @@ -559,76 +559,79 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time WAYLAND_EVENT_OP_END(self); }; -// static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) { -// MwWidget h = (MwWidget)handle->common.user; -// MwLLDispatch(handle, down, p); -// if(h) { -// int i; -// for(i = 0; i < arrlen(h->children); i++) { -// MwLLDispatch(h->children[i]->lowlevel, down, p); -// if(arrlen(h->children[i]->children) > 0) { -// 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; +static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) { + MwWidget h = (MwWidget)handle->common.user; + MwLLDispatch(handle, down, p); + if(h) { + int i; + for(i = 0; i < arrlen(h->children); i++) { + MwLLDispatch(h->children[i]->lowlevel, down, p); + if(arrlen(h->children[i]->children) > 0) { + recursive_dispatch_mouse_down(h->children[i]->lowlevel, p); + } } } - - point = topmost_parent->wayland.cur_mouse_pos; - relative_pos.x = point.x - absolute_pos.x; - relative_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) { - MwMouse p; - p.point = relative_pos; - - if(down) { - MwLLDispatch(child, down, &p); - } else { - MwLLDispatch(child, up, &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 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 */ @@ -656,17 +659,15 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri break; } self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED; - switch(state) { case WL_POINTER_BUTTON_STATE_PRESSED: MwLLDispatch(self, down, &p); - MwLLWaylandChildrenIterate(self, pointer_iterate_down); break; case WL_POINTER_BUTTON_STATE_RELEASED: MwLLDispatch(self, up, &p); - MwLLWaylandChildrenIterate(self, pointer_iterate_up); break; } + mouse_dispatch(self, p, state); if(!self->wayland.has_decorations && self->wayland.do_csd) { 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); } + MwLLForceRender(self); + WAYLAND_EVENT_OP_END(self); }; diff --git a/src/backend/wayland/wayland.c b/src/backend/wayland/wayland.c index 22c5137..c8c4b01 100644 --- a/src/backend/wayland/wayland.c +++ b/src/backend/wayland/wayland.c @@ -942,6 +942,60 @@ static void detect_dark_theme(MwLL handle) { } #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) { MwLL 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) { WIDGET_CHECK(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) { case MwLL_WAYLAND_TOPLEVEL: @@ -1119,41 +1176,6 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) { 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 { double r, g, b; @@ -1317,7 +1339,7 @@ static void MwLLEndDrawImpl(MwLL handle) { } 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; } + 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(); if(handle->wayland.holding_key) { @@ -1440,6 +1468,7 @@ static int MwLLPendingImpl(MwLL handle) { static void MwLLNextEventImpl(MwLL handle) { WIDGET_CHECK(handle); + if(!MwWaylandVulkan) { if(handle->wayland.did_event_loop_early) { handle->wayland.did_event_loop_early = MwFALSE;