From 8a0f287d8c67c9bd74f2479aabe15b6418ba782a Mon Sep 17 00:00:00 2001 From: Oskari Alaranta Date: Sat, 21 Feb 2026 04:32:48 +0200 Subject: [PATCH] Send NoExposure in CopyArea Im not sure if/when i should be sending GraphicsExposure but this fixes xterm hanging when scrolling --- xbanan/Base.cpp | 36 ++++++++++++++++++++++++++++++++++-- xbanan/Definitions.h | 2 ++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/xbanan/Base.cpp b/xbanan/Base.cpp index 6762caa..7c277a4 100644 --- a/xbanan/Base.cpp +++ b/xbanan/Base.cpp @@ -2466,6 +2466,7 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) uint32_t foreground = 0x000000; uint32_t background = 0x000000; uint32_t font = None; + bool graphics_exposures = true; uint32_t clip_mask = 0; int32_t clip_origin_x = 0; int32_t clip_origin_y = 0; @@ -2489,6 +2490,10 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) dprintln(" font: {}", value); font = value; break; + case 16: + dprintln(" graphics-exposures: {}", value); + graphics_exposures = value; + break; case 17: dprintln(" clip-origin-x: {}", value); clip_origin_x = value; @@ -2514,6 +2519,7 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) .foreground = foreground, .background = background, .font = font, + .graphics_exposures = graphics_exposures, .clip_mask = clip_mask, .clip_origin_x = clip_origin_x, .clip_origin_y = clip_origin_y, @@ -2557,6 +2563,10 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) dprintln(" font: {}", value); gc.font = value; break; + case 16: + dprintln(" graphics-exposures: {}", value); + gc.graphics_exposures = value; + break; case 17: dprintln(" clip-origin-x: {}", value); gc.clip_origin_x = value; @@ -2727,7 +2737,15 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) } }; - for (int32_t yoff = 0; yoff < request.height; yoff++) + const int32_t start_x = request.srcX < request.dstX ? request.width - 1 : 0; + const int32_t stop_x = request.srcX < request.dstX ? -1 : request.width; + const int32_t step_x = request.srcX < request.dstX ? -1 : 1; + + const int32_t start_y = request.srcY < request.dstY ? request.height - 1 : 0; + const int32_t stop_y = request.srcY < request.dstY ? -1 : request.height; + const int32_t step_y = request.srcY < request.dstY ? -1 : 1; + + for (int32_t yoff = start_y; yoff != stop_y; yoff += step_y) { const int32_t src_y = request.srcY + yoff; const int32_t dst_y = request.dstY + yoff; @@ -2735,7 +2753,7 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) continue; if (dst_y < 0 || dst_y >= dst_h) continue; - for (int32_t xoff = 0; xoff < request.width; xoff++) + for (int32_t xoff = start_x; xoff != stop_x; xoff += step_x) { const int32_t src_x = request.srcX + xoff; const int32_t dst_x = request.dstX + xoff; @@ -2748,6 +2766,20 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) } } + if (gc.graphics_exposures) + { + xEvent event = { .u = { + .noExposure = { + .drawable = request.dstDrawable, + .minorEvent = 0, + .majorEvent = X_CopyArea, + } + }}; + event.u.u.type = NoExpose; + event.u.u.sequenceNumber = client_info.sequence; + TRY(encode(client_info.output_buffer, event)); + } + if (dst_drawable.type == Object::Type::Window) invalidate_window(request.dstDrawable, request.dstX, request.dstY, request.width, request.height); diff --git a/xbanan/Definitions.h b/xbanan/Definitions.h index 2dc7774..dd4e6e7 100644 --- a/xbanan/Definitions.h +++ b/xbanan/Definitions.h @@ -114,6 +114,8 @@ struct Object uint32_t font; + bool graphics_exposures; + uint32_t clip_mask; int32_t clip_origin_x; int32_t clip_origin_y;