summaryrefslogtreecommitdiff
path: root/src/ui/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/window.c')
-rw-r--r--src/ui/window.c75
1 files changed, 67 insertions, 8 deletions
diff --git a/src/ui/window.c b/src/ui/window.c
index 47abf878..b0de0557 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 }
@@ -677,6 +682,7 @@ iBool isFullscreen_MainWindow(const iMainWindow *d) {
677} 682}
678 683
679iRoot *findRoot_Window(const iWindow *d, const iWidget *widget) { 684iRoot *findRoot_Window(const iWindow *d, const iWidget *widget) {
685
680 while (widget->parent) { 686 while (widget->parent) {
681 widget = widget->parent; 687 widget = widget->parent;
682 } 688 }
@@ -830,6 +836,9 @@ static void savePlace_MainWindow_(iAny *mainWindow) {
830} 836}
831 837
832static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent *ev) { 838static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent *ev) {
839 if (ev->windowID != SDL_GetWindowID(d->base.win)) {
840 return iFalse;
841 }
833 switch (ev->event) { 842 switch (ev->event) {
834#if defined(iPlatformDesktop) 843#if defined(iPlatformDesktop)
835 case SDL_WINDOWEVENT_EXPOSED: 844 case SDL_WINDOWEVENT_EXPOSED:
@@ -857,7 +866,7 @@ static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent
857 if (d->base.isMinimized) { 866 if (d->base.isMinimized) {
858 return iFalse; 867 return iFalse;
859 } 868 }
860 closePopups_App(); 869 closePopups_App(iFalse);
861 checkPixelRatioChange_Window_(as_Window(d)); 870 checkPixelRatioChange_Window_(as_Window(d));
862 const iInt2 newPos = init_I2(ev->data1, ev->data2); 871 const iInt2 newPos = init_I2(ev->data1, ev->data2);
863 if (isEqual_I2(newPos, init1_I2(-32000))) { /* magic! */ 872 if (isEqual_I2(newPos, init1_I2(-32000))) { /* magic! */
@@ -907,7 +916,7 @@ static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent
907 // updateSize_Window_(d, iTrue); 916 // updateSize_Window_(d, iTrue);
908 return iTrue; 917 return iTrue;
909 } 918 }
910 closePopups_App(); 919 closePopups_App(iFalse);
911 if (unsnap_MainWindow_(d, NULL)) { 920 if (unsnap_MainWindow_(d, NULL)) {
912 return iTrue; 921 return iTrue;
913 } 922 }
@@ -929,7 +938,7 @@ static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent
929 return iTrue; 938 return iTrue;
930 case SDL_WINDOWEVENT_MINIMIZED: 939 case SDL_WINDOWEVENT_MINIMIZED:
931 d->base.isMinimized = iTrue; 940 d->base.isMinimized = iTrue;
932 closePopups_App(); 941 closePopups_App(iTrue);
933 return iTrue; 942 return iTrue;
934#else /* if defined (!iPlatformDesktop) */ 943#else /* if defined (!iPlatformDesktop) */
935 case SDL_WINDOWEVENT_RESIZED: 944 case SDL_WINDOWEVENT_RESIZED:
@@ -953,6 +962,7 @@ static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent
953 setCapsLockDown_Keys(iFalse); 962 setCapsLockDown_Keys(iFalse);
954 postCommand_App("window.focus.gained"); 963 postCommand_App("window.focus.gained");
955 d->base.isExposed = iTrue; 964 d->base.isExposed = iTrue;
965 setActiveWindow_App(d);
956#if !defined (iPlatformDesktop) 966#if !defined (iPlatformDesktop)
957 /* Returned to foreground, may have lost buffered content. */ 967 /* Returned to foreground, may have lost buffered content. */
958 invalidate_MainWindow_(d, iTrue); 968 invalidate_MainWindow_(d, iTrue);
@@ -964,12 +974,17 @@ static iBool handleWindowEvent_MainWindow_(iMainWindow *d, const SDL_WindowEvent
964#if !defined (iPlatformDesktop) 974#if !defined (iPlatformDesktop)
965 setFreezeDraw_MainWindow(d, iTrue); 975 setFreezeDraw_MainWindow(d, iTrue);
966#endif 976#endif
967 closePopups_App(); 977 closePopups_App(iTrue);
968 return iFalse; 978 return iFalse;
969 case SDL_WINDOWEVENT_TAKE_FOCUS: 979 case SDL_WINDOWEVENT_TAKE_FOCUS:
970 SDL_SetWindowInputFocus(d->base.win); 980 SDL_SetWindowInputFocus(d->base.win);
971 postRefresh_App(); 981 postRefresh_App();
972 return iTrue; 982 return iTrue;
983 case SDL_WINDOWEVENT_CLOSE:
984 if (numWindows_App() > 1) {
985 closeWindow_App(d);
986 }
987 return iTrue;
973 default: 988 default:
974 break; 989 break;
975 } 990 }
@@ -1009,7 +1024,7 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) {
1009 } 1024 }
1010 } 1025 }
1011 case SDL_RENDER_TARGETS_RESET: 1026 case SDL_RENDER_TARGETS_RESET:
1012 case SDL_RENDER_DEVICE_RESET: { 1027 case SDL_RENDER_DEVICE_RESET: {
1013 if (mw) { 1028 if (mw) {
1014 invalidate_MainWindow_(mw, iTrue /* force full reset */); 1029 invalidate_MainWindow_(mw, iTrue /* force full reset */);
1015 } 1030 }
@@ -1095,7 +1110,7 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) {
1095 event.type == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEBUTTONDOWN) { 1110 event.type == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEBUTTONDOWN) {
1096 if (mouseGrab_Widget()) { 1111 if (mouseGrab_Widget()) {
1097 iWidget *grabbed = mouseGrab_Widget(); 1112 iWidget *grabbed = mouseGrab_Widget();
1098 setCurrent_Root(findRoot_Window(d, grabbed)); 1113 setCurrent_Root(grabbed->root /* findRoot_Window(d, grabbed)*/);
1099 wasUsed = dispatchEvent_Widget(grabbed, &event); 1114 wasUsed = dispatchEvent_Widget(grabbed, &event);
1100 } 1115 }
1101 } 1116 }
@@ -1164,7 +1179,33 @@ iLocalDef iBool isEscapeKeypress_(const SDL_Event *ev) {
1164 return (ev->type == SDL_KEYDOWN || ev->type == SDL_KEYUP) && ev->key.keysym.sym == SDLK_ESCAPE; 1179 return (ev->type == SDL_KEYDOWN || ev->type == SDL_KEYUP) && ev->key.keysym.sym == SDLK_ESCAPE;
1165} 1180}
1166 1181
1182static uint32_t windowId_SDLEvent_(const SDL_Event *ev) {
1183 switch (ev->type) {
1184 case SDL_MOUSEBUTTONDOWN:
1185 case SDL_MOUSEBUTTONUP:
1186 return ev->button.windowID;
1187 case SDL_MOUSEMOTION:
1188 return ev->motion.windowID;
1189 case SDL_MOUSEWHEEL:
1190 return ev->wheel.windowID;
1191 case SDL_KEYDOWN:
1192 case SDL_KEYUP:
1193 return ev->key.windowID;
1194 case SDL_TEXTINPUT:
1195 return ev->text.windowID;
1196 case SDL_USEREVENT:
1197 return ev->user.windowID;
1198 default:
1199 return 0;
1200 }
1201}
1202
1167iBool dispatchEvent_Window(iWindow *d, const SDL_Event *ev) { 1203iBool dispatchEvent_Window(iWindow *d, const SDL_Event *ev) {
1204 /* For the right window? */
1205 const uint32_t evWin = windowId_SDLEvent_(ev);
1206 if (evWin && evWin != id_Window(d)) {
1207 return iFalse; /* Meant for a different window. */
1208 }
1168 if (ev->type == SDL_MOUSEMOTION) { 1209 if (ev->type == SDL_MOUSEMOTION) {
1169 /* Hover widget may change. */ 1210 /* Hover widget may change. */
1170 setHover_Widget(NULL); 1211 setHover_Widget(NULL);
@@ -1526,6 +1567,23 @@ void setKeyboardHeight_MainWindow(iMainWindow *d, int height) {
1526 } 1567 }
1527} 1568}
1528 1569
1570iObjectList *listDocuments_MainWindow(iMainWindow *d, const iRoot *rootOrNull) {
1571 iObjectList *docs = new_ObjectList();
1572 iForIndices(i, d->base.roots) {
1573 iRoot *root = d->base.roots[i];
1574 if (!root) continue;
1575 if (!rootOrNull || root == rootOrNull) {
1576 const iWidget *tabs = findChild_Widget(root->widget, "doctabs");
1577 iForEach(ObjectList, i, children_Widget(findChild_Widget(tabs, "tabs.pages"))) {
1578 if (isInstance_Object(i.object, &Class_DocumentWidget)) {
1579 pushBack_ObjectList(docs, i.object);
1580 }
1581 }
1582 }
1583 }
1584 return docs;
1585}
1586
1529void checkPendingSplit_MainWindow(iMainWindow *d) { 1587void checkPendingSplit_MainWindow(iMainWindow *d) {
1530 if (d->splitMode != d->pendingSplitMode) { 1588 if (d->splitMode != d->pendingSplitMode) {
1531 setSplitMode_MainWindow(d, d->pendingSplitMode); 1589 setSplitMode_MainWindow(d, d->pendingSplitMode);
@@ -1549,6 +1607,7 @@ void setSplitMode_MainWindow(iMainWindow *d, int splitFlags) {
1549 } 1607 }
1550 iWindow *w = as_Window(d); 1608 iWindow *w = as_Window(d);
1551 iAssert(current_Root() == NULL); 1609 iAssert(current_Root() == NULL);
1610 setCurrent_Window(w);
1552 if (d->splitMode != splitMode) { 1611 if (d->splitMode != splitMode) {
1553 int oldCount = numRoots_Window(w); 1612 int oldCount = numRoots_Window(w);
1554 setFreezeDraw_MainWindow(d, iTrue); 1613 setFreezeDraw_MainWindow(d, iTrue);
@@ -1577,8 +1636,8 @@ void setSplitMode_MainWindow(iMainWindow *d, int splitFlags) {
1577 /* The last child is the [+] button for adding a tab. */ 1636 /* The last child is the [+] button for adding a tab. */
1578 moveTabButtonToEnd_Widget(findChild_Widget(docTabs, "newtab")); 1637 moveTabButtonToEnd_Widget(findChild_Widget(docTabs, "newtab"));
1579 setFlags_Widget(findWidget_Root("navbar.unsplit"), hidden_WidgetFlag, iTrue); 1638 setFlags_Widget(findWidget_Root("navbar.unsplit"), hidden_WidgetFlag, iTrue);
1580 iRelease(tabs);
1581 postCommandf_App("tabs.switch id:%s", cstr_String(id_Widget(constAs_Widget(curPage)))); 1639 postCommandf_App("tabs.switch id:%s", cstr_String(id_Widget(constAs_Widget(curPage))));
1640 iRelease(tabs);
1582 } 1641 }
1583 else if (oldCount == 1 && splitMode) { 1642 else if (oldCount == 1 && splitMode) {
1584 /* Add a second root. */ 1643 /* Add a second root. */