[1mdiff --git a/src/app.c b/src/app.c[m
[1mindex 850a9706..ec8b59b3 100644[m
[1m--- a/src/app.c[m
[1m+++ b/src/app.c[m
[36m@@ -154,7 +154,8 @@[m [mstruct Impl_App {[m
/* Preferences: */[m
iBool commandEcho; /* --echo */[m
iBool forceSoftwareRender; /* --sw */[m
[31m- iRect initialWindowRect;[m
[32m+[m[32m //iRect initialWindowRect;[m
[32m+[m[32m iArray initialWindowRects; /* one per window */[m
iPrefs prefs;[m
};[m
[m
[36m@@ -200,33 +201,43 @@[m [mstatic iString *serializePrefs_App_(const iApp *d) {[m
appendFormat_String(str, "window.retain arg:%d\n", d->prefs.retainWindowSize);[m
if (d->prefs.retainWindowSize) {[m
int w, h, x, y;[m
[31m- x = d->window->place.normalRect.pos.x;[m
[31m- y = d->window->place.normalRect.pos.y;[m
[31m- w = d->window->place.normalRect.size.x;[m
[31m- h = d->window->place.normalRect.size.y;[m
[31m- appendFormat_String(str, "window.setrect width:%d height:%d coord:%d %d\n", w, h, x, y);[m
[31m- /* On macOS, maximization should be applied at creation time or the window will take[m
[31m- a moment to animate to its maximized size. */[m
[32m+[m[32m iConstForEach(PtrArray, i, &d->mainWindows) {[m
[32m+[m[32m const iMainWindow *win = i.ptr;[m
[32m+[m[32m const size_t winIndex = index_PtrArrayConstIterator(&i);[m
[32m+[m[32m x = win->place.normalRect.pos.x;[m
[32m+[m[32m y = win->place.normalRect.pos.y;[m
[32m+[m[32m w = win->place.normalRect.size.x;[m
[32m+[m[32m h = win->place.normalRect.size.y;[m
[32m+[m[32m appendFormat_String(str,[m
[32m+[m[32m "window.setrect index:%zu width:%d height:%d coord:%d %d\n",[m
[32m+[m[32m winIndex,[m
[32m+[m[32m w,[m
[32m+[m[32m h,[m
[32m+[m[32m x,[m
[32m+[m[32m y);[m
[32m+[m[32m /* On macOS, maximization should be applied at creation time or the window will take[m
[32m+[m[32m a moment to animate to its maximized size. */[m
#if defined (LAGRANGE_ENABLE_CUSTOM_FRAME)[m
[31m- if (snap_MainWindow(d->window)) {[m
[31m- if (snap_MainWindow(d->window) == maximized_WindowSnap) {[m
[31m- appendFormat_String(str, "~window.maximize\n");[m
[31m- }[m
[31m- else if (~SDL_GetWindowFlags(d->window->base.win) & SDL_WINDOW_MINIMIZED) {[m
[31m- /* Save the actual visible window position, too, because snapped windows may[m
[31m- still be resized/moved without affecting normalRect. */[m
[31m- SDL_GetWindowPosition(d->window->base.win, &x, &y);[m
[31m- SDL_GetWindowSize(d->window->base.win, &w, &h);[m
[31m- appendFormat_String([m
[31m- str, "~window.setrect snap:%d width:%d height:%d coord:%d %d\n",[m
[31m- snap_MainWindow(d->window), w, h, x, y);[m
[32m+[m[32m if (snap_MainWindow(win)) {[m
[32m+[m[32m if (snap_MainWindow(win) == maximized_WindowSnap) {[m
[32m+[m[32m appendFormat_String(str, "~window.maximize index:%zu\n", winIndex);[m
[32m+[m[32m }[m
[32m+[m[32m else if (~SDL_GetWindowFlags(win->base.win) & SDL_WINDOW_MINIMIZED) {[m
[32m+[m[32m /* Save the actual visible window position, too, because snapped windows may[m
[32m+[m[32m still be resized/moved without affecting normalRect. */[m
[32m+[m[32m SDL_GetWindowPosition(win->base.win, &x, &y);[m
[32m+[m[32m SDL_GetWindowSize(win->base.win, &w, &h);[m
[32m+[m[32m appendFormat_String([m
[32m+[m[32m str, "~window.setrect index:%zu snap:%d width:%d height:%d coord:%d %d\n",[m
[32m+[m[32m winIndex, snap_MainWindow(d->window), w, h, x, y);[m
[32m+[m[32m }[m
}[m
[31m- }[m
#elif !defined (iPlatformApple)[m
[31m- if (snap_MainWindow(d->window) == maximized_WindowSnap) {[m
[31m- appendFormat_String(str, "~window.maximize\n");[m
[31m- }[m
[32m+[m[32m if (snap_MainWindow(win) == maximized_WindowSnap) {[m
[32m+[m[32m appendFormat_String(str, "~window.maximize index:%zu\n", winIndex);[m
[32m+[m[32m }[m
#endif[m
[32m+[m[32m }[m
}[m
appendFormat_String(str, "uilang id:%s\n", cstr_String(&d->prefs.strings[uiLanguage_PrefsString]));[m
appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(as_Window(d->window)));[m
[36m@@ -404,9 +415,14 @@[m [mstatic void loadPrefs_App_(iApp *d) {[m
d->prefs.customFrame = arg_Command(cmd);[m
}[m
else if (equal_Command(cmd, "window.setrect") && !argLabel_Command(cmd, "snap")) {[m
[31m- const iInt2 pos = coord_Command(cmd);[m
[31m- d->initialWindowRect = init_Rect([m
[32m+[m[32m const int index = argLabel_Command(cmd, "index");[m
[32m+[m[32m const iInt2 pos = coord_Command(cmd);[m
[32m+[m[32m iRect winRect = init_Rect([m
pos.x, pos.y, argLabel_Command(cmd, "width"), argLabel_Command(cmd, "height"));[m
[32m+[m[32m if (index >= 0 && index < 100) {[m
[32m+[m[32m resize_Array(&d->initialWindowRects, index + 1);[m
[32m+[m[32m set_Array(&d->initialWindowRects, index, &winRect);[m
[32m+[m[32m }[m
}[m
else if (equal_Command(cmd, "fontpack.disable")) {[m
insert_StringSet(d->prefs.disabledFontPacks,[m
[36m@@ -483,6 +499,28 @@[m [menum iWindowStateFlag {[m
current_WindowStateFlag = iBit(9),[m
};[m
[m
[32m+[m[32mstatic iRect initialWindowRect_App_(const iApp *d, size_t windowIndex) {[m
[32m+[m[32m if (windowIndex < size_Array(&d->initialWindowRects)) {[m
[32m+[m[32m return constValue_Array(&d->initialWindowRects, windowIndex, iRect);[m
[32m+[m[32m }[m
[32m+[m[32m /* The default window rectangle. */[m
[32m+[m[32m iRect rect = init_Rect(-1, -1, 900, 560);[m
[32m+[m[32m#if defined (iPlatformMsys)[m
[32m+[m[32m /* Must scale by UI scaling factor. */[m
[32m+[m[32m mulfv_I2(&rect.size, desktopDPI_Win32());[m
[32m+[m[32m#endif[m
[32m+[m[32m#if defined (iPlatformLinux) && !defined (iPlatformAndroid)[m
[32m+[m[32m /* Scale by the primary (?) monitor DPI. */[m
[32m+[m[32m if (isRunningUnderWindowSystem_App()) {[m
[32m+[m[32m float vdpi;[m
[32m+[m[32m SDL_GetDisplayDPI(0, NULL, NULL, &vdpi);[m
[32m+[m[32m const float factor = vdpi / 96.0f;[m
[32m+[m[32m mulfv_I2(&rect.size, iMax(factor, 1.0f));[m
[32m+[m[32m }[m
[32m+[m[32m#endif[m
[32m+[m[32m return rect;[m[41m [m
[32m+[m[32m}[m
[32m+[m
static iBool loadState_App_(iApp *d) {[m
iUnused(d);[m
const char *oldPath = concatPath_CStr(dataDir_App_(), oldStateFileName_App_);[m
[36m@@ -525,7 +563,7 @@[m [mstatic iBool loadState_App_(iApp *d) {[m
win = d->window;[m
}[m
else {[m
[31m- win = new_MainWindow(d->initialWindowRect);[m
[32m+[m[32m win = new_MainWindow(initialWindowRect_App_(d, numWins - 1));[m
addWindow_App(win);[m
}[m
pushBack_Array(currentTabs, &(iCurrentTabs){ { NULL, NULL } });[m
[36m@@ -819,6 +857,7 @@[m [mstatic void init_App_(iApp *d, int argc, char **argv) {[m
d->isDarkSystemTheme = iTrue; /* will be updated by system later on, if supported */[m
d->isSuspended = iFalse;[m
d->tempFilesPendingDeletion = new_StringSet();[m
[32m+[m[32m init_Array(&d->initialWindowRects, sizeof(iRect));[m
init_CommandLine(&d->args, argc, argv);[m
/* Where was the app started from? We ask SDL first because the command line alone[m
cannot be relied on (behavior differs depending on OS). */ {[m
[36m@@ -953,20 +992,6 @@[m [mstatic void init_App_(iApp *d, int argc, char **argv) {[m
d->elapsedSinceLastTicker = 0;[m
d->commandEcho = iClob(checkArgument_CommandLine(&d->args, "echo;E")) != NULL;[m
d->forceSoftwareRender = iClob(checkArgument_CommandLine(&d->args, "sw")) != NULL;[m
[31m- d->initialWindowRect = init_Rect(-1, -1, 900, 560);[m
[31m-#if defined (iPlatformMsys)[m
[31m- /* Must scale by UI scaling factor. */[m
[31m- mulfv_I2(&d->initialWindowRect.size, desktopDPI_Win32());[m
[31m-#endif[m
[31m-#if defined (iPlatformLinux) && !defined (iPlatformAndroid)[m
[31m- /* Scale by the primary (?) monitor DPI. */[m
[31m- if (isRunningUnderWindowSystem_App()) {[m
[31m- float vdpi;[m
[31m- SDL_GetDisplayDPI(0, NULL, NULL, &vdpi);[m
[31m- const float factor = vdpi / 96.0f;[m
[31m- mulfv_I2(&d->initialWindowRect.size, iMax(factor, 1.0f));[m
[31m- }[m
[31m-#endif[m
init_Prefs(&d->prefs);[m
init_SiteSpec(dataDir_App_());[m
setCStr_String(&d->prefs.strings[downloadDir_PrefsString], downloadDir_App_());[m
[36m@@ -988,22 +1013,29 @@[m [mstatic void init_App_(iApp *d, int argc, char **argv) {[m
init_Fonts(dataDir_App_());[m
loadPalette_Color(dataDir_App_());[m
setThemePalette_Color(d->prefs.theme); /* default UI colors */[m
[31m- loadPrefs_App_(d);[m
[32m+[m[32m /* Initial window rectangle of the first window. */ {[m
[32m+[m[32m iAssert(isEmpty_Array(&d->initialWindowRects));[m
[32m+[m[32m const iRect winRect = initialWindowRect_App_(d, 0); /* calculated */[m
[32m+[m[32m resize_Array(&d->initialWindowRects, 1);[m
[32m+[m[32m set_Array(&d->initialWindowRects, 0, &winRect);[m
[32m+[m[32m }[m
[32m+[m[32m loadPrefs_App_(d);[m[41m [m
updateActive_Fonts();[m
load_Keys(dataDir_App_());[m
[32m+[m[32m iRect *winRect0 = at_Array(&d->initialWindowRects, 0);[m
/* See if the user wants to override the window size. */ {[m
iCommandLineArg *arg = iClob(checkArgument_CommandLine(&d->args, windowWidth_CommandLineOption));[m
if (arg) {[m
[31m- d->initialWindowRect.size.x = toInt_String(value_CommandLineArg(arg, 0));[m
[32m+[m[32m winRect0->size.x = toInt_String(value_CommandLineArg(arg, 0));[m
}[m
arg = iClob(checkArgument_CommandLine(&d->args, windowHeight_CommandLineOption));[m
if (arg) {[m
[31m- d->initialWindowRect.size.y = toInt_String(value_CommandLineArg(arg, 0));[m
[32m+[m[32m winRect0->size.y = toInt_String(value_CommandLineArg(arg, 0));[m
}[m
}[m
init_PtrArray(&d->mainWindows);[m
init_PtrArray(&d->popupWindows);[m
[31m- d->window = new_MainWindow(d->initialWindowRect);[m
[32m+[m[32m d->window = new_MainWindow(winRect0); / first window is always created */[m
addWindow_App(d->window);[m
load_Visited(d->visited, dataDir_App_());[m
load_Bookmarks(d->bookmarks, dataDir_App_());[m
[36m@@ -1101,7 +1133,8 @@[m [mstatic void deinit_App(iApp *d) {[m
/* Delete all temporary files created while running. */[m
iConstForEach(StringSet, tmp, d->tempFilesPendingDeletion) {[m
remove(cstr_String(tmp.value));[m
[31m-}[m
[32m+[m[32m }[m
[32m+[m[32m deinit_Array(&d->initialWindowRects);[m
iRelease(d->tempFilesPendingDeletion);[m
}[m
[m
[36m@@ -3132,7 +3165,7 @@[m [miBool handleCommand_App(const char *cmd) {[m
return iFalse;[m
}[m
else if (equal_Command(cmd, "window.new")) {[m
[31m- iMainWindow *newWin = new_MainWindow(moved_Rect(d->initialWindowRect, init_I2(30, 30)));[m
[32m+[m[32m iMainWindow *newWin = new_MainWindow(initialWindowRect_App_(d, numWindows_App()));[m
addWindow_App(newWin); /* takes ownership */[m
SDL_ShowWindow(newWin->base.win);[m
setCurrent_Window(newWin);[m
[1mdiff --git a/src/ui/root.c b/src/ui/root.c[m
[1mindex eeb5956f..7e4b4863 100644[m
[1m--- a/src/ui/root.c[m
[1m+++ b/src/ui/root.c[m
[36m@@ -468,6 +468,10 @@[m [mstatic iBool handleRootCommands_(iWidget *root, const char *cmd) {[m
return iFalse;[m
}[m
else if (equal_Command(cmd, "window.setrect")) {[m
[32m+[m[32m if (hasLabel_Command(cmd, "index") &&[m
[32m+[m[32m argU32Label_Command(cmd, "index") != windowIndex_Root(root->root)) {[m
[32m+[m[32m return iFalse;[m
[32m+[m[32m }[m
const int snap = argLabel_Command(cmd, "snap");[m
if (snap) {[m
iMainWindow *window = get_MainWindow();[m
[36m@@ -1776,6 +1780,13 @@[m [mvoid showToolbar_Root(iRoot *d, iBool show) {[m
}[m
}[m
[m
[32m+[m[32msize_t windowIndex_Root(const iRoot *d) {[m
[32m+[m[32m if (type_Window(d->window) == main_WindowType) {[m
[32m+[m[32m return windowIndex_App(as_MainWindow(d->window));[m
[32m+[m[32m }[m
[32m+[m[32m return iInvalidPos;[m
[32m+[m[32m}[m
[32m+[m
iInt2 size_Root(const iRoot *d) {[m
return d && d->widget ? d->widget->rect.size : zero_I2();[m
}[m
[1mdiff --git a/src/ui/root.h b/src/ui/root.h[m
[1mindex a81ebdf7..3b053c9e 100644[m
[1m--- a/src/ui/root.h[m
[1m+++ b/src/ui/root.h[m
[36m@@ -47,6 +47,7 @@[m [mvoid showOrHideNewTabButton_Root (iRoot *);[m
[m
void notifyVisualOffsetChange_Root (iRoot *);[m
[m
[32m+[m[32msize_t windowIndex_Root (const iRoot *);[m
iInt2 size_Root (const iRoot *);[m
iRect rect_Root (const iRoot *);[m
iRect safeRect_Root (const iRoot *);[m
text/plain
This content has been proxied by September (ba2dc).