From f07e8ae05ce51713bb7a54ea4b72a08c06688577 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Mon, 12 Jan 2026 14:52:16 +0100 Subject: [PATCH] CtrlCore: X11 refactored key compression --- uppsrc/CtrlCore/DrawTextX11.cpp | 2 +- uppsrc/CtrlCore/ImageX11.cpp | 1 + uppsrc/CtrlCore/X11Proc.cpp | 73 +++++++++++++++------------------ uppsrc/CtrlCore/X11Top.cpp | 7 ++-- 4 files changed, 39 insertions(+), 44 deletions(-) diff --git a/uppsrc/CtrlCore/DrawTextX11.cpp b/uppsrc/CtrlCore/DrawTextX11.cpp index 951b4478b..56dd5c3fe 100644 --- a/uppsrc/CtrlCore/DrawTextX11.cpp +++ b/uppsrc/CtrlCore/DrawTextX11.cpp @@ -157,7 +157,7 @@ INITBLOCK { void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) { GuiLock __; - LTIMING("DrawText"); + DTIMING("DrawText"); LLOG("DrawText " << ToUtf8(WString(text, n)) << " color:" << ink << " font:" << font); //TODO - X11 seems to crash when displaying too long strings (?) int ox = x + actual_offset.x; diff --git a/uppsrc/CtrlCore/ImageX11.cpp b/uppsrc/CtrlCore/ImageX11.cpp index aed07bde7..d87752532 100644 --- a/uppsrc/CtrlCore/ImageX11.cpp +++ b/uppsrc/CtrlCore/ImageX11.cpp @@ -152,6 +152,7 @@ static XPicture sGetSolidFill(Color c) void ImageSysData::Paint(SystemDraw& w, int x, int y, const Rect& src, Color c) { GuiLock __; + DTIMING("PAINT IMAGE"); x += w.GetOffset().x; y += w.GetOffset().y; Size sz = img.GetSize(); diff --git a/uppsrc/CtrlCore/X11Proc.cpp b/uppsrc/CtrlCore/X11Proc.cpp index 28be4f845..cd2ac409a 100644 --- a/uppsrc/CtrlCore/X11Proc.cpp +++ b/uppsrc/CtrlCore/X11Proc.cpp @@ -90,10 +90,6 @@ void Ctrl::EventProc(XWindow& w, XEvent *event) XConfigureEvent& e = event->xconfigure; int x, y; Window dummy; -// 01/12/2007 - mdelfede -// added support for windowed controls -// if(top) -// XTranslateCoordinates(Xdisplay, top->window, Xroot, 0, 0, &x, &y, &dummy); Window xwin = GetWindow(); if(xwin) { Window DestW = (GetParent() ? GetParentWindow() : Xroot); @@ -105,8 +101,6 @@ void Ctrl::EventProc(XWindow& w, XEvent *event) } // Synchronizes native windows (NOT the main one) SyncNativeWindows(); -// 01/12/2007 - END - } return; default: @@ -122,51 +116,50 @@ void Ctrl::EventProc(XWindow& w, XEvent *event) if(w.xic) XUnsetICFocus(w.xic); break; - case KeyPress: + case KeyPress: { pressed = true; LLOG("event type:" << event->type << " state:" << event->xkey.state << "keycode:" << event->xkey.keycode); + Vector events; + while(IsWaitingEvent()) + XNextEvent(Xdisplay, &events.Add()); + auto SameKey = [&](XEvent& ev) { + return ev.xkey.state == event->xkey.state && ev.xkey.keycode == event->xkey.keycode; + }; + int from = 0; for(;;) { - XEvent ev1[1], ev2[1]; - bool hasev2 = false; - if(!IsWaitingEvent()) break; - do - XNextEvent(Xdisplay, ev1); - while(ev1->type == NoExpose && IsWaitingEvent()); - LLOG("ev1 type:" << ev1->type << " state:" << ev1->xkey.state << - "keycode:" << ev1->xkey.keycode); - if(ev1->type == KeyPress) - *ev2 = *ev1; - else { - if(ev1->type != KeyRelease || - ev1->xkey.state != event->xkey.state || - ev1->xkey.keycode != event->xkey.keycode || - !IsWaitingEvent()) { - XPutBackEvent(Xdisplay, ev1); + int up_i = -1; + for(int i = from; i < events.GetCount(); i++) { + XEvent& ev = events[i]; + if(ev.type == KeyRelease) { + if(SameKey(ev)) + up_i = i; break; } - do - XNextEvent(Xdisplay, ev2); - while(ev2->type == NoExpose && IsWaitingEvent()); - LLOG("ev2 type:" << ev2->type << " state:" << ev2->xkey.state << - "keycode:" << ev2->xkey.keycode); - hasev2 = true; } - if(ev2->type != KeyPress || - ev2->xkey.state != event->xkey.state || - ev2->xkey.keycode != event->xkey.keycode) { - if(hasev2) - XPutBackEvent(Xdisplay, ev2); - XPutBackEvent(Xdisplay, ev1); + if(up_i < 0) break; + int down_i = -1; + for(int i = up_i + 1; i < events.GetCount(); i++) { + XEvent& ev = events[i]; + if(ev.type == KeyRelease) { + if(SameKey(ev)) + down_i = i; + break; + } } - else { - XFilterEvent(ev1, None); - if(hasev2) - XFilterEvent(ev2, None); - } + if(down_i < 0) + break; count++; + from = down_i + 1; + events[up_i].type = events[down_i].type = -1; } + for(int i = events.GetCount() - 1; i >= 0; i--) { + XEvent& ev = events[i]; + if(ev.type >= 0) + XPutBackEvent(Xdisplay, &ev); + } + } case KeyRelease: { mousePos = Point(event->xkey.x_root, event->xkey.y_root); char buff[128]; diff --git a/uppsrc/CtrlCore/X11Top.cpp b/uppsrc/CtrlCore/X11Top.cpp index 0fe7f0214..42a45f84e 100644 --- a/uppsrc/CtrlCore/X11Top.cpp +++ b/uppsrc/CtrlCore/X11Top.cpp @@ -43,23 +43,24 @@ void TopWindow::EventProc(XWindow& w, XEvent *event) if(event->xclient.message_type == XAtom("WM_PROTOCOLS")) { Atom a = event->xclient.data.l[0]; if(a == XAtom("WM_DELETE_WINDOW") && IsEnabled()) { - LLOG("DELETE_WINDOW " << Name()); + DLOG("DELETE_WINDOW " << Name()); WhenClose(); return; } if(a == XAtom("WM_TAKE_FOCUS")) { - LLOG("TAKE_FOCUS serial: " << event->xclient.serial); + DLOG("TAKE_FOCUS serial: " << event->xclient.serial); Xeventtime = event->xclient.data.l[1]; TakeFocus(); return; } if(a == XAtom("_NET_WM_PING")) { + DLOG("_NET_WM_PING"); XEvent ev = *event; ev.xclient.window = Xroot; XSendEvent(Xdisplay, Xroot, 0, SubstructureRedirectMask|SubstructureNotifyMask, &ev); return; } - LLOG("Unknown WM_PROTOCOLS: " << XAtomName(a)); + DLOG("Unknown WM_PROTOCOLS: " << XAtomName(a)); } } else