From 44214359c0f95dcce3a1390506e9fd74202d5ae7 Mon Sep 17 00:00:00 2001

From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= jaakko.keranen@iki.fi

Date: Sat, 19 Feb 2022 15:16:51 +0200

Subject: [PATCH 1/1] Fixed several event handling issues

Events are expected to have a valid windowID now, and the current window also has to be correct when dispatching or processing any events.


src/app.c | 38 ++++++++++++++++++++++--------

src/app.h | 2 ++

src/macos.m | 51 ++++++++++++++---------------------------

src/periodic.c | 19 ++++++++-------

src/ui/documentwidget.c | 2 +-

src/ui/touch.c | 3 ++-

src/ui/widget.c | 3 ++-

src/ui/window.c | 10 ++++----

src/ui/window.h | 2 +-

9 files changed, 69 insertions(+), 61 deletions(-)

diff --git a/src/app.c b/src/app.c

index ec8b59b3..010c6d74 100644

--- a/src/app.c

+++ b/src/app.c

@@ -559,6 +559,7 @@ static iBool loadState_App_(iApp *d) {

             const int   winState  = read32_File(f);

             const int   keyRoot   = (winState & 1);

             const iBool isCurrent = (winState & current_WindowStateFlag) != 0;

+// printf("[State] '%.4s' split:%d state:%x\n", magic, splitMode, winState);

             if (numWins == 1) {

                 win = d->window;

             }

@@ -575,7 +576,7 @@ static iBool loadState_App_(iApp *d) {

             setCurrent_Root(NULL);

             win->pendingSplitMode = splitMode;

             setSplitMode_MainWindow(win, splitMode | noEvents_WindowSplit);

         }

         else if (!memcmp(magic, magicSidebar_App_, 4)) {

             if (!win) {

@@ -1061,8 +1062,8 @@ static void init_App_(iApp *d, int argc, char **argv) {

 }

 postCommand_App("~navbar.actions.changed");

 postCommand_App("~toolbar.actions.changed");

 d->autoReloadTimer = SDL_AddTimer(60 * 1000, postAutoReloadCommand_App_, NULL);

 postCommand_Root(NULL, "document.autoreload");

#if defined (LAGRANGE_ENABLE_IDLE_SLEEP)

@@ -1390,6 +1391,12 @@ static iPtrArray *listWindows_App_(const iApp *d, iPtrArray *windows) {

 return windows;

}

+iPtrArray *listWindows_App(void) {

+}

void processEvents_App(enum iAppEventMode eventMode) {

 iApp *d = &app_;

 iRoot *oldCurrentRoot = current_Root(); /* restored afterwards */

@@ -1672,6 +1679,9 @@ static void runTickers_App_(iApp *d) {

 iConstForEach(Array, i, &pending->values) {

     const iTicker *ticker = i.value;

     if (ticker->callback) {

         setCurrent_Root(ticker->root); /* root might be NULL */

         ticker->callback(ticker->context);

     }

@@ -1864,9 +1874,9 @@ void postCommand_Root(iRoot *d, const char *command) {

 }

 SDL_Event ev = { .type = SDL_USEREVENT };

 ev.user.code = command_UserEventCode;

-// ev.user.windowID = id_Window(get_Window());

 ev.user.data1 = strdup(command);

 ev.user.data2 = d; /* all events are root-specific */

 SDL_PushEvent(&ev);

 iWindow *win = get_Window();

#if defined (iPlatformAndroid)

@@ -1969,6 +1979,10 @@ size_t windowIndex_App(const iMainWindow *win) {

 return indexOf_PtrArray(&app_.mainWindows, win); 

}

+const iPtrArray *mainWindows_App(void) {

+}

void setActiveWindow_App(iMainWindow *win) {

 iApp *d = &app_;

 d->window = win;

@@ -2527,12 +2541,16 @@ iBool handleCommand_App(const char *cmd) {

     return iTrue;

 }

 else if (equal_Command(cmd, "window.maximize")) {

     }

     return iTrue;

 }

diff --git a/src/app.h b/src/app.h

index dd24ec8e..63a477a5 100644

--- a/src/app.h

+++ b/src/app.h

@@ -98,6 +98,7 @@ iPeriodic * periodic_App (void);

iDocumentWidget * document_App (void);

iObjectList * listDocuments_App (const iRoot rootOrNull); / NULL for all roots */

iStringSet * listOpenURLs_App (void); /* all tabs */

+iPtrArray * listWindows_App (void);

iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew);

void trimCache_App (void);

void trimMemory_App (void);

@@ -128,6 +129,7 @@ void setActiveWindow_App (iMainWindow *win);

void closeWindow_App (iMainWindow *win);

size_t numWindows_App (void);

size_t windowIndex_App (const iMainWindow *win);

+const iPtrArray *mainWindows_App(void);

void addPopup_App (iWindow *popup);

void removePopup_App (iWindow *popup);

void postRefresh_App (void);

diff --git a/src/macos.m b/src/macos.m

index 7b248c3b..5f376874 100644

--- a/src/macos.m

+++ b/src/macos.m

@@ -83,7 +83,9 @@ static void ignoreImmediateKeyDownEvents_(void) {

    However, we shouldn't double-activate menu items when a shortcut key is used in our

    widgets. Quite a kludge: take advantage of Window's focus-acquisition threshold to

    ignore the immediately following key down events. */

}

/----------------------------------------------------------------------------------------------/

@@ -435,9 +437,17 @@ static iBool processScrollWheelEvent_(NSEvent *event) {

 const iBool isPerPixel = (event.hasPreciseScrollingDeltas != 0);

 const iBool isInertia  = (event.momentumPhase & (NSEventPhaseBegan | NSEventPhaseChanged)) != 0;

 const iBool isEnded    = event.scrollingDeltaX == 0.0f && event.scrollingDeltaY == 0.0f && !isInertia;

     return iFalse;

 }

 if (isPerPixel) {

@@ -478,16 +488,18 @@ static iBool processScrollWheelEvent_(NSEvent *event) {

 else {

     SDL_MouseWheelEvent e = { .type = SDL_MOUSEWHEEL };

     e.timestamp = SDL_GetTicks();

     e.which = 1; /* Distinction between trackpad and regular mouse. */

     /* Disregard any wheel acceleration. */

     e.x = event.scrollingDeltaX > 0 ? 1 : event.scrollingDeltaX < 0 ? -1 : 0;

     SDL_PushEvent((SDL_Event *) &e);

     return iTrue;

 }                

 /* Post corresponding MOUSEWHEEL events. */

 SDL_MouseWheelEvent e = { .type = SDL_MOUSEWHEEL };

 e.timestamp = SDL_GetTicks();

 e.which = isPerPixel ? 0 : 1; /* Distinction between trackpad and regular mouse. */

 setPerPixel_MouseWheelEvent(&e, isPerPixel);

 if (isPerPixel) {

@@ -517,28 +529,6 @@ static iBool processScrollWheelEvent_(NSEvent *event) {

 // printf("#### [%d] dx:%d dy:%d phase:%ld inertia:%d end:%d\n", preventTapGlitch_, e.x, e.y, (long) event.momentumPhase,

 //        isInertia, isEnded); fflush(stdout);

 SDL_PushEvent((SDL_Event *) &e);

-#if 0

-#endif

 return iTrue;        

}

@@ -565,13 +555,6 @@ void setupApplication_MacOS(void) {

 windowCloseItem.action = @selector(closeTab);

 [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskScrollWheel

                                       handler:^NSEvent*(NSEvent *event){

-// printf("event type: %lu\n", (unsigned long) event.type);

-// fflush(stdout);

-// if (event.type == NSEventTypeGesture) {

-// trackSwipe_(event);

-// printf("GESTURE phase:%lu\n", (unsigned long) event.phase);

-//fflush(stdout);

-// }

                                         if (event.type == NSEventTypeScrollWheel &&

                                             processScrollWheelEvent_(event)) {

                                             return nil; /* was eaten */                                                

diff --git a/src/periodic.c b/src/periodic.c

index b4f51ed3..0558ed50 100644

--- a/src/periodic.c

+++ b/src/periodic.c

@@ -107,14 +107,17 @@ iBool dispatchCommands_Periodic(iPeriodic *d) {

 iConstForEach(Array, i, &d->commands.values) {

     const iPeriodicCommand *pc = i.value;

     iAssert(isInstance_Object(pc->context, &Class_Widget));

         dispatchEvent_Widget(pc->context, (const SDL_Event *) &ev);

         wasPosted = iTrue;

     }

diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c

index f8cc10b9..76c26e27 100644

--- a/src/ui/documentwidget.c

+++ b/src/ui/documentwidget.c

@@ -5582,7 +5582,7 @@ static void prerender_DocumentWidget_(iAny *context) {

     .vis             = visibleRange_DocumentView_(&d->view),

     .showLinkNumbers = (d->flags & showLinkNumbers_DocumentWidgetFlag) != 0

 };

 if (d->view.visBuf->buffers[0].texture) {

     makePaletteGlobal_GmDocument(d->view.doc);

     if (render_DocumentView_(&d->view, &ctx, iTrue /* just fill up progressively */)) {

diff --git a/src/ui/touch.c b/src/ui/touch.c

index a178a913..21a92b80 100644

--- a/src/ui/touch.c

+++ b/src/ui/touch.c

@@ -244,7 +244,8 @@ static void dispatchNotification_Touch_(const iTouch *d, int code) {

         .timestamp = SDL_GetTicks(),

         .code = code,

         .data1 = d->affinity,

     });

     setCurrent_Root(oldRoot);

 }

diff --git a/src/ui/widget.c b/src/ui/widget.c

index fc754b7a..2e878878 100644

--- a/src/ui/widget.c

+++ b/src/ui/widget.c

@@ -168,7 +168,8 @@ void deinit_Widget(iWidget *d) {

 if (d->flags & visualOffset_WidgetFlag) {

     removeTicker_App(visualOffsetAnimation_Widget_, d);

 }

 if (win->lastHover == d) {

     win->lastHover = NULL;

 }

diff --git a/src/ui/window.c b/src/ui/window.c

index 0a97b97c..6f680cd4 100644

--- a/src/ui/window.c

+++ b/src/ui/window.c

@@ -682,6 +682,7 @@ iBool isFullscreen_MainWindow(const iMainWindow *d) {

}

iRoot *findRoot_Window(const iWindow *d, const iWidget *widget) {

 while (widget->parent) {

     widget = widget->parent;

 }

@@ -1023,7 +1024,7 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) {

         }

     }

     case SDL_RENDER_TARGETS_RESET:

         if (mw) {

             invalidate_MainWindow_(mw, iTrue /* force full reset */);

         }

@@ -1109,7 +1110,7 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) {

             event.type == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEBUTTONDOWN) {

             if (mouseGrab_Widget()) {

                 iWidget *grabbed = mouseGrab_Widget();

                 wasUsed = dispatchEvent_Widget(grabbed, &event);

             }

         }

@@ -1200,13 +1201,11 @@ static uint32_t windowId_SDLEvent_(const SDL_Event *ev) {

}

iBool dispatchEvent_Window(iWindow *d, const SDL_Event *ev) {

-#if 0

 /* For the right window? */    

 const uint32_t evWin = windowId_SDLEvent_(ev);

 if (evWin && evWin != id_Window(d)) {

     return iFalse; /* Meant for a different window. */

 }

-#endif

 if (ev->type == SDL_MOUSEMOTION) {

     /* Hover widget may change. */

     setHover_Widget(NULL);

@@ -1591,6 +1590,7 @@ void setSplitMode_MainWindow(iMainWindow *d, int splitFlags) {

 }

 iWindow *w = as_Window(d);

 iAssert(current_Root() == NULL);

 if (d->splitMode != splitMode) {

     int oldCount = numRoots_Window(w);

     setFreezeDraw_MainWindow(d, iTrue);

@@ -1619,8 +1619,8 @@ void setSplitMode_MainWindow(iMainWindow *d, int splitFlags) {

         /* The last child is the [+] button for adding a tab. */

         moveTabButtonToEnd_Widget(findChild_Widget(docTabs, "newtab"));

         setFlags_Widget(findWidget_Root("navbar.unsplit"), hidden_WidgetFlag, iTrue);

         postCommandf_App("tabs.switch id:%s", cstr_String(id_Widget(constAs_Widget(curPage))));

     }

     else if (oldCount == 1 && splitMode) {

         /* Add a second root. */

diff --git a/src/ui/window.h b/src/ui/window.h

index 5abf23eb..c7d59380 100644

--- a/src/ui/window.h

+++ b/src/ui/window.h

@@ -139,7 +139,7 @@ iAnyObject * hitChild_Window (const iWindow *, iInt2 coord);

uint32_t frameTime_Window (const iWindow *);

SDL_Renderer * renderer_Window (const iWindow *);

int numRoots_Window (const iWindow *);

-iRoot * findRoot_Window (const iWindow *, const iWidget *widget);

+//iRoot * findRoot_Window (const iWindow *, const iWidget *widget);

iRoot * otherRoot_Window (const iWindow *, iRoot *root);

iBool processEvent_Window (iWindow *, const SDL_Event *);

--

2.25.1

Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/work%2Fv1.11/patch/44214359c0f95dcce3a1390506e9fd74202d5ae7.patch
Status Code
Success (20)
Meta
text/plain
Capsule Response Time
104.908141 milliseconds
Gemini-to-HTML Time
6.763813 milliseconds

This content has been proxied by September (3851b).