[1mdiff --git a/src/app.c b/src/app.c[m
[1mindex ec8b59b3..010c6d74 100644[m
[1m--- a/src/app.c[m
[1m+++ b/src/app.c[m
[36m@@ -559,6 +559,7 @@[m [mstatic iBool loadState_App_(iApp *d) {[m
const int winState = read32_File(f);[m
const int keyRoot = (winState & 1);[m
const iBool isCurrent = (winState & current_WindowStateFlag) != 0;[m
[32m+[m[32m// printf("[State] '%.4s' split:%d state:%x\n", magic, splitMode, winState);[m
if (numWins == 1) {[m
win = d->window;[m
}[m
[36m@@ -575,7 +576,7 @@[m [mstatic iBool loadState_App_(iApp *d) {[m
setCurrent_Root(NULL);[m
win->pendingSplitMode = splitMode;[m
setSplitMode_MainWindow(win, splitMode | noEvents_WindowSplit);[m
[31m- win->base.keyRoot = d->window->base.roots[keyRoot];[m
[32m+[m[32m win->base.keyRoot = win->base.roots[keyRoot];[m
}[m
else if (!memcmp(magic, magicSidebar_App_, 4)) {[m
if (!win) {[m
[36m@@ -1061,8 +1062,8 @@[m [mstatic void init_App_(iApp *d, int argc, char **argv) {[m
}[m
postCommand_App("~navbar.actions.changed");[m
postCommand_App("~toolbar.actions.changed");[m
[31m- postCommand_Root(NULL, "~window.unfreeze");[m
[31m- postCommand_Root(NULL, "font.reset");[m
[32m+[m[32m postCommand_App("~window.unfreeze");[m
[32m+[m[32m postCommand_App("font.reset");[m
d->autoReloadTimer = SDL_AddTimer(60 * 1000, postAutoReloadCommand_App_, NULL);[m
postCommand_Root(NULL, "document.autoreload");[m
#if defined (LAGRANGE_ENABLE_IDLE_SLEEP)[m
[36m@@ -1390,6 +1391,12 @@[m [mstatic iPtrArray *listWindows_App_(const iApp *d, iPtrArray *windows) {[m
return windows;[m
}[m
[m
[32m+[m[32miPtrArray *listWindows_App(void) {[m
[32m+[m[32m iPtrArray *wins = new_PtrArray();[m
[32m+[m[32m listWindows_App_(&app_, wins);[m
[32m+[m[32m return wins;[m
[32m+[m[32m}[m
[32m+[m
void processEvents_App(enum iAppEventMode eventMode) {[m
iApp *d = &app_;[m
iRoot *oldCurrentRoot = current_Root(); /* restored afterwards */[m
[36m@@ -1672,6 +1679,9 @@[m [mstatic void runTickers_App_(iApp *d) {[m
iConstForEach(Array, i, &pending->values) {[m
const iTicker *ticker = i.value;[m
if (ticker->callback) {[m
[32m+[m[32m if (ticker->root) {[m
[32m+[m[32m setCurrent_Window(ticker->root->window);[m
[32m+[m[32m }[m
setCurrent_Root(ticker->root); /* root might be NULL */[m
ticker->callback(ticker->context);[m
}[m
[36m@@ -1864,9 +1874,9 @@[m [mvoid postCommand_Root(iRoot *d, const char *command) {[m
}[m
SDL_Event ev = { .type = SDL_USEREVENT };[m
ev.user.code = command_UserEventCode;[m
[31m-// ev.user.windowID = id_Window(get_Window());[m
ev.user.data1 = strdup(command);[m
ev.user.data2 = d; /* all events are root-specific */[m
[32m+[m[32m ev.user.windowID = d ? id_Window(d->window) : 0; /* root-specific means window-specific */[m
SDL_PushEvent(&ev);[m
iWindow *win = get_Window();[m
#if defined (iPlatformAndroid)[m
[36m@@ -1969,6 +1979,10 @@[m [msize_t windowIndex_App(const iMainWindow *win) {[m
return indexOf_PtrArray(&app_.mainWindows, win); [m
}[m
[m
[32m+[m[32mconst iPtrArray *mainWindows_App(void) {[m
[32m+[m[32m return &app_.mainWindows;[m
[32m+[m[32m}[m
[32m+[m
void setActiveWindow_App(iMainWindow *win) {[m
iApp *d = &app_;[m
d->window = win;[m
[36m@@ -2527,12 +2541,16 @@[m [miBool handleCommand_App(const char *cmd) {[m
return iTrue;[m
}[m
else if (equal_Command(cmd, "window.maximize")) {[m
[31m- if (!argLabel_Command(cmd, "toggle")) {[m
[31m- setSnap_MainWindow(d->window, maximized_WindowSnap);[m
[31m- }[m
[31m- else {[m
[31m- setSnap_MainWindow(d->window, snap_MainWindow(d->window) == maximized_WindowSnap ? 0 :[m
[31m- maximized_WindowSnap);[m
[32m+[m[32m const size_t winIndex = argU32Label_Command(cmd, "index");[m
[32m+[m[32m if (winIndex < size_PtrArray(&d->mainWindows)) {[m
[32m+[m[32m iMainWindow *win = at_PtrArray(&d->mainWindows, winIndex);[m
[32m+[m[32m if (!argLabel_Command(cmd, "toggle")) {[m
[32m+[m[32m setSnap_MainWindow(win, maximized_WindowSnap);[m
[32m+[m[32m }[m
[32m+[m[32m else {[m
[32m+[m[32m setSnap_MainWindow([m
[32m+[m[32m win, snap_MainWindow(win) == maximized_WindowSnap ? 0 : maximized_WindowSnap);[m
[32m+[m[32m }[m
}[m
return iTrue;[m
}[m
[1mdiff --git a/src/app.h b/src/app.h[m
[1mindex dd24ec8e..63a477a5 100644[m
[1m--- a/src/app.h[m
[1m+++ b/src/app.h[m
[36m@@ -98,6 +98,7 @@[m [miPeriodic * periodic_App (void);[m
iDocumentWidget * document_App (void);[m
iObjectList * listDocuments_App (const iRoot rootOrNull); / NULL for all roots */[m
iStringSet * listOpenURLs_App (void); /* all tabs */[m
[32m+[m[32miPtrArray * listWindows_App (void);[m
iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew);[m
void trimCache_App (void);[m
void trimMemory_App (void);[m
[36m@@ -128,6 +129,7 @@[m [mvoid setActiveWindow_App (iMainWindow *win);[m
void closeWindow_App (iMainWindow *win);[m
size_t numWindows_App (void);[m
size_t windowIndex_App (const iMainWindow *win);[m
[32m+[m[32mconst iPtrArray *mainWindows_App(void);[m
void addPopup_App (iWindow *popup);[m
void removePopup_App (iWindow *popup);[m
void postRefresh_App (void);[m
[1mdiff --git a/src/macos.m b/src/macos.m[m
[1mindex 7b248c3b..5f376874 100644[m
[1m--- a/src/macos.m[m
[1m+++ b/src/macos.m[m
[36m@@ -83,7 +83,9 @@[m [mstatic void ignoreImmediateKeyDownEvents_(void) {[m
However, we shouldn't double-activate menu items when a shortcut key is used in our[m
widgets. Quite a kludge: take advantage of Window's focus-acquisition threshold to[m
ignore the immediately following key down events. */[m
[31m- get_Window()->focusGainedAt = SDL_GetTicks();[m
[32m+[m[32m iForEach(PtrArray, w, collect_PtrArray(listWindows_App())) {[m
[32m+[m[32m as_Window(w.ptr)->focusGainedAt = SDL_GetTicks();[m
[32m+[m[32m }[m
}[m
[m
/----------------------------------------------------------------------------------------------/[m
[36m@@ -435,9 +437,17 @@[m [mstatic iBool processScrollWheelEvent_(NSEvent *event) {[m
const iBool isPerPixel = (event.hasPreciseScrollingDeltas != 0);[m
const iBool isInertia = (event.momentumPhase & (NSEventPhaseBegan | NSEventPhaseChanged)) != 0;[m
const iBool isEnded = event.scrollingDeltaX == 0.0f && event.scrollingDeltaY == 0.0f && !isInertia;[m
[31m- const iWindow *win = &get_MainWindow()->base;[m
[31m- if (event.window != nsWindow_(win->win)) {[m
[31m- /* Not the main window. */[m
[32m+[m[32m const iWindow *win = NULL; //&get_MainWindow()->base;[m
[32m+[m[32m /* If this event belongs to one of the MainWindows, handle it and mark it for that window.[m[41m [m
[32m+[m[32m If it's for an auxiliary window, let the system handle it. */[m
[32m+[m[32m iConstForEach(PtrArray, i, mainWindows_App()) {[m
[32m+[m[32m if (event.window == nsWindow_(as_Window(i.ptr)->win)) {[m
[32m+[m[32m win = i.ptr;[m
[32m+[m[32m break;[m
[32m+[m[32m }[m[41m [m
[32m+[m[32m }[m
[32m+[m[32m if (!win) { //event.window != nsWindow_(win->win)) {[m
[32m+[m[32m /* Not a main window. */[m
return iFalse;[m
}[m
if (isPerPixel) {[m
[36m@@ -478,16 +488,18 @@[m [mstatic iBool processScrollWheelEvent_(NSEvent *event) {[m
else {[m
SDL_MouseWheelEvent e = { .type = SDL_MOUSEWHEEL };[m
e.timestamp = SDL_GetTicks();[m
[32m+[m[32m e.windowID = id_Window(win);[m
e.which = 1; /* Distinction between trackpad and regular mouse. */[m
/* Disregard any wheel acceleration. */[m
e.x = event.scrollingDeltaX > 0 ? 1 : event.scrollingDeltaX < 0 ? -1 : 0;[m
[31m- e.y = event.scrollingDeltaY > 0 ? 1 : event.scrollingDeltaY < 0 ? -1 : 0;[m
[32m+[m[32m e.y = event.scrollingDeltaY > 0 ? 1 : event.scrollingDeltaY < 0 ? -1 : 0;[m[41m [m
SDL_PushEvent((SDL_Event *) &e);[m
return iTrue;[m
} [m
/* Post corresponding MOUSEWHEEL events. */[m
SDL_MouseWheelEvent e = { .type = SDL_MOUSEWHEEL };[m
e.timestamp = SDL_GetTicks();[m
[32m+[m[32m e.windowID = id_Window(win);[m
e.which = isPerPixel ? 0 : 1; /* Distinction between trackpad and regular mouse. */[m
setPerPixel_MouseWheelEvent(&e, isPerPixel);[m
if (isPerPixel) {[m
[36m@@ -517,28 +529,6 @@[m [mstatic iBool processScrollWheelEvent_(NSEvent *event) {[m
// printf("#### [%d] dx:%d dy:%d phase:%ld inertia:%d end:%d\n", preventTapGlitch_, e.x, e.y, (long) event.momentumPhase,[m
// isInertia, isEnded); fflush(stdout);[m
SDL_PushEvent((SDL_Event *) &e);[m
[31m-#if 0[m
[31m- /* On macOS, we handle both trackpad and mouse events. We expect SDL to identify[m
[31m- which device is sending the event. */[m
[31m- if (ev.wheel.which == 0) {[m
[31m- /* Trackpad with precise scrolling w/inertia (points). */[m
[31m- setPerPixel_MouseWheelEvent(&ev.wheel, iTrue);[m
[31m- ev.wheel.x *= -d->window->base.pixelRatio;[m
[31m- ev.wheel.y *= d->window->base.pixelRatio;[m
[31m- /* Only scroll on one axis at a time. */[m
[31m- if (iAbs(ev.wheel.x) > iAbs(ev.wheel.y)) {[m
[31m- ev.wheel.y = 0;[m
[31m- }[m
[31m- else {[m
[31m- ev.wheel.x = 0;[m
[31m- }[m
[31m- }[m
[31m- else {[m
[31m- /* Disregard wheel acceleration applied by the OS. */[m
[31m- ev.wheel.x = -ev.wheel.x;[m
[31m- ev.wheel.y = iSign(ev.wheel.y);[m
[31m- }[m
[31m-#endif[m
return iTrue; [m
}[m
[m
[36m@@ -565,13 +555,6 @@[m [mvoid setupApplication_MacOS(void) {[m
windowCloseItem.action = @selector(closeTab);[m
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskScrollWheel[m
handler:^NSEvent*(NSEvent *event){[m
[31m-// printf("event type: %lu\n", (unsigned long) event.type);[m
[31m-// fflush(stdout);[m
[31m-// if (event.type == NSEventTypeGesture) {[m
[31m-// trackSwipe_(event);[m
[31m-// printf("GESTURE phase:%lu\n", (unsigned long) event.phase);[m
[31m-//fflush(stdout);[m
[31m-// }[m
if (event.type == NSEventTypeScrollWheel &&[m
processScrollWheelEvent_(event)) {[m
return nil; /* was eaten */ [m
[1mdiff --git a/src/periodic.c b/src/periodic.c[m
[1mindex b4f51ed3..0558ed50 100644[m
[1m--- a/src/periodic.c[m
[1m+++ b/src/periodic.c[m
[36m@@ -107,14 +107,17 @@[m [miBool dispatchCommands_Periodic(iPeriodic *d) {[m
iConstForEach(Array, i, &d->commands.values) {[m
const iPeriodicCommand *pc = i.value;[m
iAssert(isInstance_Object(pc->context, &Class_Widget));[m
[31m- const SDL_UserEvent ev = {[m
[31m- .type = SDL_USEREVENT,[m
[31m- .code = command_UserEventCode,[m
[31m- .data1 = (void *) cstr_String(&pc->command),[m
[31m- .data2 = findRoot_Window(get_Window(), pc->context)[m
[31m- };[m
[31m- if (ev.data2) {[m
[31m- setCurrent_Root(ev.data2);[m
[32m+[m[32m iRoot *root = constAs_Widget(pc->context)->root;[m
[32m+[m[32m if (root) {[m
[32m+[m[32m const SDL_UserEvent ev = {[m
[32m+[m[32m .type = SDL_USEREVENT,[m
[32m+[m[32m .code = command_UserEventCode,[m
[32m+[m[32m .data1 = (void *) cstr_String(&pc->command),[m
[32m+[m[32m .data2 = root,[m
[32m+[m[32m .windowID = id_Window(root->window),[m
[32m+[m[32m };[m
[32m+[m[32m setCurrent_Window(root->window);[m
[32m+[m[32m setCurrent_Root(root);[m
dispatchEvent_Widget(pc->context, (const SDL_Event *) &ev);[m
wasPosted = iTrue;[m
}[m
[1mdiff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c[m
[1mindex f8cc10b9..76c26e27 100644[m
[1m--- a/src/ui/documentwidget.c[m
[1m+++ b/src/ui/documentwidget.c[m
[36m@@ -5582,7 +5582,7 @@[m [mstatic void prerender_DocumentWidget_(iAny *context) {[m
.vis = visibleRange_DocumentView_(&d->view),[m
.showLinkNumbers = (d->flags & showLinkNumbers_DocumentWidgetFlag) != 0[m
};[m
[31m- // printf("%u prerendering\n", SDL_GetTicks());[m
[32m+[m[32m // printf("%u prerendering\n", SDL_GetTicks());[m[41m [m
if (d->view.visBuf->buffers[0].texture) {[m
makePaletteGlobal_GmDocument(d->view.doc);[m
if (render_DocumentView_(&d->view, &ctx, iTrue /* just fill up progressively */)) {[m
[1mdiff --git a/src/ui/touch.c b/src/ui/touch.c[m
[1mindex a178a913..21a92b80 100644[m
[1m--- a/src/ui/touch.c[m
[1m+++ b/src/ui/touch.c[m
[36m@@ -244,7 +244,8 @@[m [mstatic void dispatchNotification_Touch_(const iTouch *d, int code) {[m
.timestamp = SDL_GetTicks(),[m
.code = code,[m
.data1 = d->affinity,[m
[31m- .data2 = d->affinity->root[m
[32m+[m[32m .data2 = d->affinity->root,[m
[32m+[m[32m .windowID = id_Window(window_Widget(d->affinity)),[m
});[m
setCurrent_Root(oldRoot);[m
}[m
[1mdiff --git a/src/ui/widget.c b/src/ui/widget.c[m
[1mindex fc754b7a..2e878878 100644[m
[1m--- a/src/ui/widget.c[m
[1m+++ b/src/ui/widget.c[m
[36m@@ -168,7 +168,8 @@[m [mvoid deinit_Widget(iWidget *d) {[m
if (d->flags & visualOffset_WidgetFlag) {[m
removeTicker_App(visualOffsetAnimation_Widget_, d);[m
}[m
[31m- iWindow *win = get_Window();[m
[32m+[m[32m iWindow *win = d->root->window;[m
[32m+[m[32m iAssert(win);[m
if (win->lastHover == d) {[m
win->lastHover = NULL;[m
}[m
[1mdiff --git a/src/ui/window.c b/src/ui/window.c[m
[1mindex 0a97b97c..6f680cd4 100644[m
[1m--- a/src/ui/window.c[m
[1m+++ b/src/ui/window.c[m
[36m@@ -682,6 +682,7 @@[m [miBool isFullscreen_MainWindow(const iMainWindow *d) {[m
}[m
[m
iRoot *findRoot_Window(const iWindow *d, const iWidget *widget) {[m
[32m+[m[41m [m
while (widget->parent) {[m
widget = widget->parent;[m
}[m
[36m@@ -1023,7 +1024,7 @@[m [miBool processEvent_Window(iWindow *d, const SDL_Event *ev) {[m
}[m
}[m
case SDL_RENDER_TARGETS_RESET:[m
[31m- case SDL_RENDER_DEVICE_RESET: {[m
[32m+[m[32m case SDL_RENDER_DEVICE_RESET: {[m[41m [m
if (mw) {[m
invalidate_MainWindow_(mw, iTrue /* force full reset */);[m
}[m
[36m@@ -1109,7 +1110,7 @@[m [miBool processEvent_Window(iWindow *d, const SDL_Event *ev) {[m
event.type == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEBUTTONDOWN) {[m
if (mouseGrab_Widget()) {[m
iWidget *grabbed = mouseGrab_Widget();[m
[31m- setCurrent_Root(findRoot_Window(d, grabbed));[m
[32m+[m[32m setCurrent_Root(grabbed->root /* findRoot_Window(d, grabbed)*/);[m
wasUsed = dispatchEvent_Widget(grabbed, &event);[m
}[m
}[m
[36m@@ -1200,13 +1201,11 @@[m [mstatic uint32_t windowId_SDLEvent_(const SDL_Event *ev) {[m
}[m
[m
iBool dispatchEvent_Window(iWindow *d, const SDL_Event *ev) {[m
[31m-#if 0[m
/* For the right window? */ [m
const uint32_t evWin = windowId_SDLEvent_(ev);[m
if (evWin && evWin != id_Window(d)) {[m
return iFalse; /* Meant for a different window. */[m
}[m
[31m-#endif[m
if (ev->type == SDL_MOUSEMOTION) {[m
/* Hover widget may change. */[m
setHover_Widget(NULL);[m
[36m@@ -1591,6 +1590,7 @@[m [mvoid setSplitMode_MainWindow(iMainWindow *d, int splitFlags) {[m
}[m
iWindow *w = as_Window(d);[m
iAssert(current_Root() == NULL);[m
[32m+[m[32m setCurrent_Window(w);[m
if (d->splitMode != splitMode) {[m
int oldCount = numRoots_Window(w);[m
setFreezeDraw_MainWindow(d, iTrue);[m
[36m@@ -1619,8 +1619,8 @@[m [mvoid setSplitMode_MainWindow(iMainWindow *d, int splitFlags) {[m
/* The last child is the [+] button for adding a tab. */[m
moveTabButtonToEnd_Widget(findChild_Widget(docTabs, "newtab"));[m
setFlags_Widget(findWidget_Root("navbar.unsplit"), hidden_WidgetFlag, iTrue);[m
[31m- iRelease(tabs);[m
postCommandf_App("tabs.switch id:%s", cstr_String(id_Widget(constAs_Widget(curPage))));[m
[32m+[m[32m iRelease(tabs);[m
}[m
else if (oldCount == 1 && splitMode) {[m
/* Add a second root. */[m
[1mdiff --git a/src/ui/window.h b/src/ui/window.h[m
[1mindex 5abf23eb..c7d59380 100644[m
[1m--- a/src/ui/window.h[m
[1m+++ b/src/ui/window.h[m
[36m@@ -139,7 +139,7 @@[m [miAnyObject * hitChild_Window (const iWindow *, iInt2 coord);[m
uint32_t frameTime_Window (const iWindow *);[m
SDL_Renderer * renderer_Window (const iWindow *);[m
int numRoots_Window (const iWindow *);[m
[31m-iRoot * findRoot_Window (const iWindow *, const iWidget *widget);[m
[32m+[m[32m//iRoot * findRoot_Window (const iWindow *, const iWidget *widget);[m
iRoot * otherRoot_Window (const iWindow *, iRoot *root);[m
[m
iBool processEvent_Window (iWindow *, const SDL_Event *);[m
text/plain
This content has been proxied by September (3851b).