summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2022-02-18 14:59:03 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2022-02-18 14:59:03 +0200
commitbef61b34d8a23e2e8594207c2876ce982fe0e15f (patch)
tree1f9f0a408dfb1b707321e1a8bb387750f26e510d
parent5f1b30cafcf251d52550915e3880609c099095ed (diff)
Basic opening and closing of new windows
One can create a new window with `window.new` and close it with the window close button.
-rw-r--r--src/app.c71
-rw-r--r--src/app.h5
-rw-r--r--src/ui/window.c16
3 files changed, 86 insertions, 6 deletions
diff --git a/src/app.c b/src/app.c
index d47c6ef1..686d8b82 100644
--- a/src/app.c
+++ b/src/app.c
@@ -125,7 +125,8 @@ struct Impl_App {
125 iGmCerts * certs; 125 iGmCerts * certs;
126 iVisited * visited; 126 iVisited * visited;
127 iBookmarks * bookmarks; 127 iBookmarks * bookmarks;
128 iMainWindow *window; 128 iMainWindow *window; /* currently active MainWindow */
129 iPtrArray mainWindows;
129 iPtrArray popupWindows; 130 iPtrArray popupWindows;
130 iSortedArray tickers; /* per-frame callbacks, used for animations */ 131 iSortedArray tickers; /* per-frame callbacks, used for animations */
131 uint32_t lastTickerTime; 132 uint32_t lastTickerTime;
@@ -474,7 +475,7 @@ static const char *magicTabDocument_App_ = "tabd";
474static const char *magicSidebar_App_ = "side"; 475static const char *magicSidebar_App_ = "side";
475 476
476enum iDocumentStateFlag { 477enum iDocumentStateFlag {
477 current_DocumentStateFlag = iBit(1), 478 current_DocumentStateFlag = iBit(1),
478 rootIndex1_DocumentStateFlag = iBit(2) 479 rootIndex1_DocumentStateFlag = iBit(2)
479}; 480};
480 481
@@ -946,8 +947,10 @@ static void init_App_(iApp *d, int argc, char **argv) {
946 d->initialWindowRect.size.y = toInt_String(value_CommandLineArg(arg, 0)); 947 d->initialWindowRect.size.y = toInt_String(value_CommandLineArg(arg, 0));
947 } 948 }
948 } 949 }
950 init_PtrArray(&d->mainWindows);
949 init_PtrArray(&d->popupWindows); 951 init_PtrArray(&d->popupWindows);
950 d->window = new_MainWindow(d->initialWindowRect); 952 d->window = new_MainWindow(d->initialWindowRect);
953 addWindow_App(d->window);
951 load_Visited(d->visited, dataDir_App_()); 954 load_Visited(d->visited, dataDir_App_());
952 load_Bookmarks(d->bookmarks, dataDir_App_()); 955 load_Bookmarks(d->bookmarks, dataDir_App_());
953 load_MimeHooks(d->mimehooks, dataDir_App_()); 956 load_MimeHooks(d->mimehooks, dataDir_App_());
@@ -1012,7 +1015,11 @@ static void deinit_App(iApp *d) {
1012 SDL_RemoveTimer(d->autoReloadTimer); 1015 SDL_RemoveTimer(d->autoReloadTimer);
1013 saveState_App_(d); 1016 saveState_App_(d);
1014 savePrefs_App_(d); 1017 savePrefs_App_(d);
1015 delete_MainWindow(d->window); 1018 iReverseForEach(PtrArray, j, &d->mainWindows) {
1019 delete_MainWindow(j.ptr);
1020 }
1021 iAssert(isEmpty_PtrArray(&d->mainWindows));
1022 deinit_PtrArray(&d->mainWindows);
1016 d->window = NULL; 1023 d->window = NULL;
1017 deinit_Feeds(); 1024 deinit_Feeds();
1018 save_Keys(dataDir_App_()); 1025 save_Keys(dataDir_App_());
@@ -1027,7 +1034,6 @@ static void deinit_App(iApp *d) {
1027 delete_GmCerts(d->certs); 1034 delete_GmCerts(d->certs);
1028 save_MimeHooks(d->mimehooks); 1035 save_MimeHooks(d->mimehooks);
1029 delete_MimeHooks(d->mimehooks); 1036 delete_MimeHooks(d->mimehooks);
1030 d->window = NULL;
1031 deinit_CommandLine(&d->args); 1037 deinit_CommandLine(&d->args);
1032 iRelease(d->launchCommands); 1038 iRelease(d->launchCommands);
1033 delete_String(d->execPath); 1039 delete_String(d->execPath);
@@ -1286,7 +1292,14 @@ static iPtrArray *listWindows_App_(const iApp *d, iPtrArray *windows) {
1286 iReverseConstForEach(PtrArray, i, &d->popupWindows) { 1292 iReverseConstForEach(PtrArray, i, &d->popupWindows) {
1287 pushBack_PtrArray(windows, i.ptr); 1293 pushBack_PtrArray(windows, i.ptr);
1288 } 1294 }
1289 pushBack_PtrArray(windows, d->window); 1295 if (d->window) {
1296 pushBack_PtrArray(windows, d->window);
1297 }
1298 iConstForEach(PtrArray, j, &d->mainWindows) {
1299 if (j.ptr != d->window) {
1300 pushBack_PtrArray(windows, j.ptr);
1301 }
1302 }
1290 return windows; 1303 return windows;
1291} 1304}
1292 1305
@@ -1843,6 +1856,26 @@ void removeTicker_App(iTickerFunc ticker, iAny *context) {
1843 remove_SortedArray(&d->tickers, &(iTicker){ context, NULL, ticker }); 1856 remove_SortedArray(&d->tickers, &(iTicker){ context, NULL, ticker });
1844} 1857}
1845 1858
1859void addWindow_App(iMainWindow *win) {
1860 iApp *d = &app_;
1861 pushBack_PtrArray(&d->mainWindows, win);
1862}
1863
1864void removeWindow_App(iMainWindow *win) {
1865 iApp *d = &app_;
1866 removeOne_PtrArray(&d->mainWindows, win);
1867}
1868
1869size_t numWindows_App(void) {
1870 return size_PtrArray(&app_.mainWindows);
1871}
1872
1873void setActiveWindow_App(iMainWindow *win) {
1874 iApp *d = &app_;
1875 d->window = win;
1876 printf("Active window: %p\n", win); fflush(stdout);
1877}
1878
1846void addPopup_App(iWindow *popup) { 1879void addPopup_App(iWindow *popup) {
1847 iApp *d = &app_; 1880 iApp *d = &app_;
1848 pushBack_PtrArray(&d->popupWindows, popup); 1881 pushBack_PtrArray(&d->popupWindows, popup);
@@ -2121,6 +2154,22 @@ iDocumentWidget *newTab_App(const iDocumentWidget *duplicateOf, iBool switchToNe
2121 return doc; 2154 return doc;
2122} 2155}
2123 2156
2157void closeWindow_App(iMainWindow *win) {
2158 iApp *d = &app_;
2159 delete_MainWindow(win);
2160 if (d->window == win) {
2161 /* Activate another window. */
2162 iForEach(PtrArray, i, &d->mainWindows) {
2163 if (i.ptr != d->window) {
2164 SDL_RaiseWindow(i.ptr);
2165 setActiveWindow_App(i.ptr);
2166 setCurrent_Window(i.ptr);
2167 break;
2168 }
2169 }
2170 }
2171}
2172
2124static iBool handleIdentityCreationCommands_(iWidget *dlg, const char *cmd) { 2173static iBool handleIdentityCreationCommands_(iWidget *dlg, const char *cmd) {
2125 iApp *d = &app_; 2174 iApp *d = &app_;
2126 if (equal_Command(cmd, "ident.showmore")) { 2175 if (equal_Command(cmd, "ident.showmore")) {
@@ -3016,6 +3065,15 @@ iBool handleCommand_App(const char *cmd) {
3016#endif 3065#endif
3017 return iFalse; 3066 return iFalse;
3018 } 3067 }
3068 else if (equal_Command(cmd, "window.new")) {
3069 iMainWindow *newWin = new_MainWindow(moved_Rect(d->initialWindowRect, init_I2(20, 20)));
3070 addWindow_App(newWin);
3071 SDL_ShowWindow(newWin->base.win);
3072 setCurrent_Window(newWin);
3073 postCommand_Root(newWin->base.roots[0], "navigate.home");
3074 postCommand_Root(newWin->base.roots[0], "window.unfreeze");
3075 return iTrue;
3076 }
3019 else if (equal_Command(cmd, "tabs.new")) { 3077 else if (equal_Command(cmd, "tabs.new")) {
3020 const iBool isDuplicate = argLabel_Command(cmd, "duplicate") != 0; 3078 const iBool isDuplicate = argLabel_Command(cmd, "duplicate") != 0;
3021 newTab_App(isDuplicate ? document_App() : NULL, iTrue); 3079 newTab_App(isDuplicate ? document_App() : NULL, iTrue);
@@ -3076,6 +3134,9 @@ iBool handleCommand_App(const char *cmd) {
3076 } 3134 }
3077 } 3135 }
3078 } 3136 }
3137 else if (numWindows_App() > 1) {
3138 closeWindow_App(d->window);
3139 }
3079 else { 3140 else {
3080 postCommand_App("quit"); 3141 postCommand_App("quit");
3081 } 3142 }
diff --git a/src/app.h b/src/app.h
index 22fe5d46..74a5429b 100644
--- a/src/app.h
+++ b/src/app.h
@@ -122,6 +122,11 @@ iAny * findWidget_App (const char *id);
122void addTicker_App (iTickerFunc ticker, iAny *context); 122void addTicker_App (iTickerFunc ticker, iAny *context);
123void addTickerRoot_App (iTickerFunc ticker, iRoot *root, iAny *context); 123void addTickerRoot_App (iTickerFunc ticker, iRoot *root, iAny *context);
124void removeTicker_App (iTickerFunc ticker, iAny *context); 124void removeTicker_App (iTickerFunc ticker, iAny *context);
125void addWindow_App (iMainWindow *win);
126void removeWindow_App (iMainWindow *win);
127void setActiveWindow_App (iMainWindow *win);
128void closeWindow_App (iMainWindow *win);
129size_t numWindows_App (void);
125void addPopup_App (iWindow *popup); 130void addPopup_App (iWindow *popup);
126void removePopup_App (iWindow *popup); 131void removePopup_App (iWindow *popup);
127void postRefresh_App (void); 132void postRefresh_App (void);
diff --git a/src/ui/window.c b/src/ui/window.c
index 47abf878..bc32e479 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -80,6 +80,7 @@ iDefineTypeConstructionArgs(MainWindow, (iRect rect), rect)
80#if defined (iHaveNativeMenus) 80#if defined (iHaveNativeMenus)
81/* Using native menus. */ 81/* Using native menus. */
82static const iMenuItem fileMenuItems_[] = { 82static const iMenuItem fileMenuItems_[] = {
83 { "${menu.newwindow}", SDLK_n, KMOD_PRIMARY, "window.new" },
83 { "${menu.newtab}", SDLK_t, KMOD_PRIMARY, "tabs.new" }, 84 { "${menu.newtab}", SDLK_t, KMOD_PRIMARY, "tabs.new" },
84 { "${menu.openlocation}", SDLK_l, KMOD_PRIMARY, "navigate.focus" }, 85 { "${menu.openlocation}", SDLK_l, KMOD_PRIMARY, "navigate.focus" },
85 { "---", 0, 0, NULL }, 86 { "---", 0, 0, NULL },
@@ -210,7 +211,9 @@ static void windowSizeChanged_MainWindow_(iMainWindow *d) {
210 211
211static void setupUserInterface_MainWindow(iMainWindow *d) { 212static void setupUserInterface_MainWindow(iMainWindow *d) {
212#if defined (iHaveNativeMenus) 213#if defined (iHaveNativeMenus)
213 insertMacMenus_(); 214 if (numWindows_App() == 0) {
215 insertMacMenus_(); /* TODO: Shouldn't this be in the App? */
216 }
214#endif 217#endif
215 /* One root is created by default. */ 218 /* One root is created by default. */
216 d->base.roots[0] = new_Root(); 219 d->base.roots[0] = new_Root();
@@ -246,6 +249,7 @@ static void updateSize_MainWindow_(iMainWindow *d, iBool notifyAlways) {
246 249
247void drawWhileResizing_MainWindow(iMainWindow *d, int w, int h) { 250void drawWhileResizing_MainWindow(iMainWindow *d, int w, int h) {
248 if (!isDrawing_) { 251 if (!isDrawing_) {
252 setCurrent_Window(d);
249 draw_MainWindow(d); 253 draw_MainWindow(d);
250 } 254 }
251} 255}
@@ -647,6 +651,7 @@ void init_MainWindow(iMainWindow *d, iRect rect) {
647} 651}
648 652
649void deinit_MainWindow(iMainWindow *d) { 653void deinit_MainWindow(iMainWindow *d) {
654 removeWindow_App(d);
650 if (d->backBuf) { 655 if (d->backBuf) {
651 SDL_DestroyTexture(d->backBuf); 656 SDL_DestroyTexture(d->backBuf);
652 } 657 }
@@ -830,6 +835,9 @@ static void savePlace_MainWindow_(iAny *mainWindow) {
830} 835}
831 836
832static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent *ev) { 837static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent *ev) {
838 if (ev->windowID != SDL_GetWindowID(d->base.win)) {
839 return iFalse;
840 }
833 switch (ev->event) { 841 switch (ev->event) {
834#if defined(iPlatformDesktop) 842#if defined(iPlatformDesktop)
835 case SDL_WINDOWEVENT_EXPOSED: 843 case SDL_WINDOWEVENT_EXPOSED:
@@ -953,6 +961,7 @@ static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent
953 setCapsLockDown_Keys(iFalse); 961 setCapsLockDown_Keys(iFalse);
954 postCommand_App("window.focus.gained"); 962 postCommand_App("window.focus.gained");
955 d->base.isExposed = iTrue; 963 d->base.isExposed = iTrue;
964 setActiveWindow_App(d);
956#if !defined (iPlatformDesktop) 965#if !defined (iPlatformDesktop)
957 /* Returned to foreground, may have lost buffered content. */ 966 /* Returned to foreground, may have lost buffered content. */
958 invalidate_MainWindow_(d, iTrue); 967 invalidate_MainWindow_(d, iTrue);
@@ -970,6 +979,11 @@ static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent
970 SDL_SetWindowInputFocus(d->base.win); 979 SDL_SetWindowInputFocus(d->base.win);
971 postRefresh_App(); 980 postRefresh_App();
972 return iTrue; 981 return iTrue;
982 case SDL_WINDOWEVENT_CLOSE:
983 if (numWindows_App() > 1) {
984 closeWindow_App(d);
985 }
986 return iTrue;
973 default: 987 default:
974 break; 988 break;
975 } 989 }