summaryrefslogtreecommitdiff
path: root/src/app.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/app.c')
-rw-r--r--src/app.c191
1 files changed, 97 insertions, 94 deletions
diff --git a/src/app.c b/src/app.c
index 04928b84..839e8e65 100644
--- a/src/app.c
+++ b/src/app.c
@@ -94,17 +94,20 @@ struct Impl_App {
94 iTime lastDropTime; /* for detecting drops of multiple items */ 94 iTime lastDropTime; /* for detecting drops of multiple items */
95 /* Preferences: */ 95 /* Preferences: */
96 iBool commandEcho; /* --echo */ 96 iBool commandEcho; /* --echo */
97 iBool retainWindowSize; 97 iBool forceSoftwareRender; /* --sw */
98 iRect initialWindowRect; 98 iRect initialWindowRect;
99 iPrefs prefs;
100#if 0
101 iBool retainWindowSize;
99 float uiScale; 102 float uiScale;
100 int zoomPercent; 103 int zoomPercent;
101 iBool forceWrap; 104 iBool forceWrap;
102 iBool forceSoftwareRender;
103 enum iColorTheme theme; 105 enum iColorTheme theme;
104 iBool useSystemTheme; 106 iBool useSystemTheme;
105 iString gopherProxy; 107 iString gopherProxy;
106 iString httpProxy; 108 iString httpProxy;
107 iString downloadDir; 109 iString downloadDir;
110#endif
108}; 111};
109 112
110static iApp app_; 113static iApp app_;
@@ -134,8 +137,8 @@ const iString *dateStr_(const iDate *date) {
134static iString *serializePrefs_App_(const iApp *d) { 137static iString *serializePrefs_App_(const iApp *d) {
135 iString *str = new_String(); 138 iString *str = new_String();
136 const iSidebarWidget *sidebar = findWidget_App("sidebar"); 139 const iSidebarWidget *sidebar = findWidget_App("sidebar");
137 appendFormat_String(str, "window.retain arg:%d\n", d->retainWindowSize); 140 appendFormat_String(str, "window.retain arg:%d\n", d->prefs.retainWindowSize);
138 if (d->retainWindowSize) { 141 if (d->prefs.retainWindowSize) {
139 const iBool isMaximized = (SDL_GetWindowFlags(d->window->win) & SDL_WINDOW_MAXIMIZED) != 0; 142 const iBool isMaximized = (SDL_GetWindowFlags(d->window->win) & SDL_WINDOW_MAXIMIZED) != 0;
140 int w, h, x, y; 143 int w, h, x, y;
141 x = d->window->lastRect.pos.x; 144 x = d->window->lastRect.pos.x;
@@ -155,17 +158,18 @@ static iString *serializePrefs_App_(const iApp *d) {
155 if (isVisible_Widget(sidebar)) { 158 if (isVisible_Widget(sidebar)) {
156 appendCStr_String(str, "sidebar.toggle\n"); 159 appendCStr_String(str, "sidebar.toggle\n");
157 } 160 }
158 if (d->forceWrap) { 161 if (d->prefs.forceLineWrap) {
159 appendFormat_String(str, "forcewrap.toggle\n"); 162 appendFormat_String(str, "forcewrap.toggle\n");
160 } 163 }
161 appendFormat_String(str, "sidebar.mode arg:%d\n", mode_SidebarWidget(sidebar)); 164 appendFormat_String(str, "sidebar.mode arg:%d\n", mode_SidebarWidget(sidebar));
162 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window)); 165 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window));
163 appendFormat_String(str, "zoom.set arg:%d\n", d->zoomPercent); 166 appendFormat_String(str, "zoom.set arg:%d\n", d->prefs.zoomPercent);
164 appendFormat_String(str, "theme.set arg:%d auto:1\n", d->theme); 167 appendFormat_String(str, "theme.set arg:%d auto:1\n", d->prefs.theme);
165 appendFormat_String(str, "ostheme arg:%d\n", d->useSystemTheme); 168 appendFormat_String(str, "ostheme arg:%d\n", d->prefs.useSystemTheme);
166 appendFormat_String(str, "proxy.gopher address:%s\n", cstr_String(&d->gopherProxy)); 169 appendFormat_String(str, "saturation.set arg:%d\n", (int) ((d->prefs.saturation * 100) + 0.5f));
167 appendFormat_String(str, "proxy.http address:%s\n", cstr_String(&d->httpProxy)); 170 appendFormat_String(str, "proxy.gopher address:%s\n", cstr_String(&d->prefs.gopherProxy));
168 appendFormat_String(str, "downloads path:%s\n", cstr_String(&d->downloadDir)); 171 appendFormat_String(str, "proxy.http address:%s\n", cstr_String(&d->prefs.httpProxy));
172 appendFormat_String(str, "downloads path:%s\n", cstr_String(&d->prefs.downloadDir));
169 return str; 173 return str;
170} 174}
171 175
@@ -244,7 +248,7 @@ static iBool loadState_App_(iApp *d) {
244 readData_File(f, 4, magic); 248 readData_File(f, 4, magic);
245 if (!memcmp(magic, magicTabDocument_App_, 4)) { 249 if (!memcmp(magic, magicTabDocument_App_, 4)) {
246 if (!doc) { 250 if (!doc) {
247 doc = newTab_App(NULL); 251 doc = newTab_App(NULL, iTrue);
248 } 252 }
249 if (read8_File(f)) { 253 if (read8_File(f)) {
250 current = doc; 254 current = doc;
@@ -301,24 +305,18 @@ static void init_App_(iApp *d, int argc, char **argv) {
301 d->lastTickerTime = SDL_GetTicks(); 305 d->lastTickerTime = SDL_GetTicks();
302 d->elapsedSinceLastTicker = 0; 306 d->elapsedSinceLastTicker = 0;
303 d->commandEcho = checkArgument_CommandLine(&d->args, "echo") != NULL; 307 d->commandEcho = checkArgument_CommandLine(&d->args, "echo") != NULL;
308 d->forceSoftwareRender = checkArgument_CommandLine(&d->args, "sw") != NULL;
304 d->initialWindowRect = init_Rect(-1, -1, 900, 560); 309 d->initialWindowRect = init_Rect(-1, -1, 900, 560);
305 d->theme = dark_ColorTheme; 310 init_Prefs(&d->prefs);
306 d->useSystemTheme = iTrue; 311 setCStr_String(&d->prefs.downloadDir, downloadDir_App_);
307 d->running = iFalse; 312 d->running = iFalse;
308 d->window = NULL; 313 d->window = NULL;
309 d->retainWindowSize = iTrue;
310 d->pendingRefresh = iFalse; 314 d->pendingRefresh = iFalse;
311 d->zoomPercent = 100;
312 d->forceWrap = iFalse;
313 d->forceSoftwareRender = checkArgument_CommandLine(&d->args, "sw") != NULL;
314 d->certs = new_GmCerts(dataDir_App_); 315 d->certs = new_GmCerts(dataDir_App_);
315 d->visited = new_Visited(); 316 d->visited = new_Visited();
316 d->bookmarks = new_Bookmarks(); 317 d->bookmarks = new_Bookmarks();
317 d->tabEnum = 0; /* generates unique IDs for tab pages */ 318 d->tabEnum = 0; /* generates unique IDs for tab pages */
318 init_String(&d->gopherProxy); 319 setThemePalette_Color(d->prefs.theme);
319 init_String(&d->httpProxy);
320 initCStr_String(&d->downloadDir, downloadDir_App_);
321 setThemePalette_Color(d->theme);
322#if defined (iPlatformApple) 320#if defined (iPlatformApple)
323 setupApplication_MacOS(); 321 setupApplication_MacOS();
324#endif 322#endif
@@ -392,9 +390,7 @@ static void init_App_(iApp *d, int argc, char **argv) {
392static void deinit_App(iApp *d) { 390static void deinit_App(iApp *d) {
393 saveState_App_(d); 391 saveState_App_(d);
394 savePrefs_App_(d); 392 savePrefs_App_(d);
395 deinit_String(&d->downloadDir); 393 deinit_Prefs(&d->prefs);
396 deinit_String(&d->httpProxy);
397 deinit_String(&d->gopherProxy);
398 save_Bookmarks(d->bookmarks, dataDir_App_); 394 save_Bookmarks(d->bookmarks, dataDir_App_);
399 delete_Bookmarks(d->bookmarks); 395 delete_Bookmarks(d->bookmarks);
400 save_Visited(d->visited, dataDir_App_); 396 save_Visited(d->visited, dataDir_App_);
@@ -416,7 +412,7 @@ const iString *dataDir_App(void) {
416} 412}
417 413
418const iString *downloadDir_App(void) { 414const iString *downloadDir_App(void) {
419 return collect_String(cleaned_Path(&app_.downloadDir)); 415 return collect_String(cleaned_Path(&app_.prefs.downloadDir));
420} 416}
421 417
422const iString *debugInfo_App(void) { 418const iString *debugInfo_App(void) {
@@ -540,12 +536,12 @@ uint32_t elapsedSinceLastTicker_App(void) {
540 return app_.elapsedSinceLastTicker; 536 return app_.elapsedSinceLastTicker;
541} 537}
542 538
543int zoom_App(void) { 539const iPrefs *prefs_App(void) {
544 return app_.zoomPercent; 540 return &app_.prefs;
545} 541}
546 542
547iBool forceLineWrap_App(void) { 543iBool forceLineWrap_App(void) {
548 return app_.forceWrap; 544 return app_.prefs.forceLineWrap;
549} 545}
550 546
551iBool forceSoftwareRender_App(void) { 547iBool forceSoftwareRender_App(void) {
@@ -561,16 +557,16 @@ iBool forceSoftwareRender_App(void) {
561} 557}
562 558
563enum iColorTheme colorTheme_App(void) { 559enum iColorTheme colorTheme_App(void) {
564 return app_.theme; 560 return app_.prefs.theme;
565} 561}
566 562
567const iString *schemeProxy_App(iRangecc scheme) { 563const iString *schemeProxy_App(iRangecc scheme) {
568 iApp *d = &app_; 564 iApp *d = &app_;
569 if (equalCase_Rangecc(scheme, "gopher")) { 565 if (equalCase_Rangecc(scheme, "gopher")) {
570 return &d->gopherProxy; 566 return &d->prefs.gopherProxy;
571 } 567 }
572 if (equalCase_Rangecc(scheme, "http") || equalCase_Rangecc(scheme, "https")) { 568 if (equalCase_Rangecc(scheme, "http") || equalCase_Rangecc(scheme, "https")) {
573 return &d->httpProxy; 569 return &d->prefs.httpProxy;
574 } 570 }
575 return NULL; 571 return NULL;
576} 572}
@@ -713,7 +709,7 @@ iDocumentWidget *document_Command(const char *cmd) {
713 return document_App(); 709 return document_App();
714} 710}
715 711
716iDocumentWidget *newTab_App(const iDocumentWidget *duplicateOf) { 712iDocumentWidget *newTab_App(const iDocumentWidget *duplicateOf, iBool switchToNew) {
717 iApp *d = &app_; 713 iApp *d = &app_;
718 iWidget *tabs = findWidget_App("doctabs"); 714 iWidget *tabs = findWidget_App("doctabs");
719 setFlags_Widget(tabs, hidden_WidgetFlag, iFalse); 715 setFlags_Widget(tabs, hidden_WidgetFlag, iFalse);
@@ -729,7 +725,9 @@ iDocumentWidget *newTab_App(const iDocumentWidget *duplicateOf) {
729 setId_Widget(as_Widget(doc), format_CStr("document%03d", ++d->tabEnum)); 725 setId_Widget(as_Widget(doc), format_CStr("document%03d", ++d->tabEnum));
730 appendTabPage_Widget(tabs, iClob(doc), "", 0, 0); 726 appendTabPage_Widget(tabs, iClob(doc), "", 0, 0);
731 addChild_Widget(findChild_Widget(tabs, "tabs.buttons"), iClob(newTabButton)); 727 addChild_Widget(findChild_Widget(tabs, "tabs.buttons"), iClob(newTabButton));
732 postCommandf_App("tabs.switch page:%p", doc); 728 if (switchToNew) {
729 postCommandf_App("tabs.switch page:%p", doc);
730 }
733 arrange_Widget(tabs); 731 arrange_Widget(tabs);
734 refresh_Widget(tabs); 732 refresh_Widget(tabs);
735 return doc; 733 return doc;
@@ -801,15 +799,66 @@ static iBool handleIdentityCreationCommands_(iWidget *dlg, const char *cmd) {
801iBool handleCommand_App(const char *cmd) { 799iBool handleCommand_App(const char *cmd) {
802 iApp *d = &app_; 800 iApp *d = &app_;
803 if (equal_Command(cmd, "window.retain")) { 801 if (equal_Command(cmd, "window.retain")) {
804 d->retainWindowSize = arg_Command(cmd); 802 d->prefs.retainWindowSize = arg_Command(cmd);
805 return iTrue; 803 return iTrue;
806 } 804 }
807 else if (equal_Command(cmd, "window.maximize")) { 805 else if (equal_Command(cmd, "window.maximize")) {
808 SDL_MaximizeWindow(d->window->win); 806 SDL_MaximizeWindow(d->window->win);
809 return iTrue; 807 return iTrue;
810 } 808 }
811 else if (equal_Command(cmd, "downloads")) { 809 else if (equal_Command(cmd, "zoom.set")) {
812 setCStr_String(&d->downloadDir, suffixPtr_Command(cmd, "path")); 810 setFreezeDraw_Window(get_Window(), iTrue); /* no intermediate draws before docs updated */
811 d->prefs.zoomPercent = arg_Command(cmd);
812 setContentFontSize_Text((float) d->prefs.zoomPercent / 100.0f);
813 postCommand_App("font.changed");
814 postCommand_App("window.unfreeze");
815 return iTrue;
816 }
817 else if (equal_Command(cmd, "zoom.delta")) {
818 setFreezeDraw_Window(get_Window(), iTrue); /* no intermediate draws before docs updated */
819 int delta = arg_Command(cmd);
820 if (d->prefs.zoomPercent < 100 || (delta < 0 && d->prefs.zoomPercent == 100)) {
821 delta /= 2;
822 }
823 d->prefs.zoomPercent = iClamp(d->prefs.zoomPercent + delta, 50, 200);
824 setContentFontSize_Text((float) d->prefs.zoomPercent / 100.0f);
825 postCommand_App("font.changed");
826 postCommand_App("window.unfreeze");
827 return iTrue;
828 }
829 else if (equal_Command(cmd, "forcewrap.toggle")) {
830 d->prefs.forceLineWrap = !d->prefs.forceLineWrap;
831 updateSize_DocumentWidget(document_App());
832 return iTrue;
833 }
834 else if (equal_Command(cmd, "theme.set")) {
835 const int isAuto = argLabel_Command(cmd, "auto");
836 d->prefs.theme = arg_Command(cmd);
837 if (!isAuto) {
838 postCommand_App("ostheme arg:0");
839 }
840 setThemePalette_Color(d->prefs.theme);
841 postCommandf_App("theme.changed auto:%d", isAuto);
842 return iTrue;
843 }
844 else if (equal_Command(cmd, "ostheme")) {
845 d->prefs.useSystemTheme = arg_Command(cmd);
846 return iTrue;
847 }
848 else if (equal_Command(cmd, "saturation.set")) {
849 d->prefs.saturation = (float) arg_Command(cmd) / 100.0f;
850 postCommandf_App("theme.changed auto:1");
851 return iTrue;
852 }
853 else if (equal_Command(cmd, "proxy.gopher")) {
854 setCStr_String(&d->prefs.gopherProxy, suffixPtr_Command(cmd, "address"));
855 return iTrue;
856 }
857 else if (equal_Command(cmd, "proxy.http")) {
858 setCStr_String(&d->prefs.httpProxy, suffixPtr_Command(cmd, "address"));
859 return iTrue;
860 } else if (equal_Command(cmd, "downloads")) {
861 setCStr_String(&d->prefs.downloadDir, suffixPtr_Command(cmd, "path"));
813 return iTrue; 862 return iTrue;
814 } 863 }
815 else if (equal_Command(cmd, "open")) { 864 else if (equal_Command(cmd, "open")) {
@@ -817,14 +866,15 @@ iBool handleCommand_App(const char *cmd) {
817 iUrl parts; 866 iUrl parts;
818 init_Url(&parts, url); 867 init_Url(&parts, url);
819 if (equalCase_Rangecc(parts.scheme, "mailto") || 868 if (equalCase_Rangecc(parts.scheme, "mailto") ||
820 (isEmpty_String(&d->httpProxy) && (equalCase_Rangecc(parts.scheme, "http") || 869 (isEmpty_String(&d->prefs.httpProxy) && (equalCase_Rangecc(parts.scheme, "http") ||
821 equalCase_Rangecc(parts.scheme, "https")))) { 870 equalCase_Rangecc(parts.scheme, "https")))) {
822 openInDefaultBrowser_App(url); 871 openInDefaultBrowser_App(url);
823 return iTrue; 872 return iTrue;
824 } 873 }
825 iDocumentWidget *doc = document_Command(cmd); 874 iDocumentWidget *doc = document_Command(cmd);
826 if (argLabel_Command(cmd, "newtab")) { 875 const int newTab = argLabel_Command(cmd, "newtab");
827 doc = newTab_App(NULL); 876 if (newTab) {
877 doc = newTab_App(NULL, (newTab & 1) != 0); /* newtab:2 to open in background */
828 } 878 }
829 iHistory *history = history_DocumentWidget(doc); 879 iHistory *history = history_DocumentWidget(doc);
830 const iBool isHistory = argLabel_Command(cmd, "history") != 0; 880 const iBool isHistory = argLabel_Command(cmd, "history") != 0;
@@ -859,7 +909,7 @@ iBool handleCommand_App(const char *cmd) {
859 } 909 }
860 else if (equal_Command(cmd, "tabs.new")) { 910 else if (equal_Command(cmd, "tabs.new")) {
861 const iBool isDuplicate = argLabel_Command(cmd, "duplicate") != 0; 911 const iBool isDuplicate = argLabel_Command(cmd, "duplicate") != 0;
862 newTab_App(isDuplicate ? document_App() : NULL); 912 newTab_App(isDuplicate ? document_App() : NULL, iTrue);
863 if (!isDuplicate) { 913 if (!isDuplicate) {
864 postCommand_App("navigate.home"); 914 postCommand_App("navigate.home");
865 } 915 }
@@ -908,9 +958,9 @@ iBool handleCommand_App(const char *cmd) {
908 else if (equal_Command(cmd, "preferences")) { 958 else if (equal_Command(cmd, "preferences")) {
909 iWidget *dlg = makePreferences_Widget(); 959 iWidget *dlg = makePreferences_Widget();
910 updatePrefsThemeButtons_(dlg); 960 updatePrefsThemeButtons_(dlg);
911 setText_InputWidget(findChild_Widget(dlg, "prefs.downloads"), &d->downloadDir); 961 setText_InputWidget(findChild_Widget(dlg, "prefs.downloads"), &d->prefs.downloadDir);
912 setToggle_Widget(findChild_Widget(dlg, "prefs.ostheme"), d->useSystemTheme); 962 setToggle_Widget(findChild_Widget(dlg, "prefs.ostheme"), d->prefs.useSystemTheme);
913 setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->retainWindowSize); 963 setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->prefs.retainWindowSize);
914 setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"), 964 setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"),
915 collectNewFormat_String("%g", uiScale_Window(d->window))); 965 collectNewFormat_String("%g", uiScale_Window(d->window)));
916 setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.http"), 966 setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.http"),
@@ -925,7 +975,7 @@ iBool handleCommand_App(const char *cmd) {
925 const iPtrArray *homepages = 975 const iPtrArray *homepages =
926 list_Bookmarks(d->bookmarks, NULL, filterTagsRegExp_Bookmarks, pattern); 976 list_Bookmarks(d->bookmarks, NULL, filterTagsRegExp_Bookmarks, pattern);
927 if (isEmpty_PtrArray(homepages)) { 977 if (isEmpty_PtrArray(homepages)) {
928 postCommand_App("open url:about:lagrange"); 978 postCommand_App("open url:about:lagrange");
929 } 979 }
930 else { 980 else {
931 iStringSet *urls = iClob(new_StringSet()); 981 iStringSet *urls = iClob(new_StringSet());
@@ -944,31 +994,6 @@ iBool handleCommand_App(const char *cmd) {
944 } 994 }
945 return iTrue; 995 return iTrue;
946 } 996 }
947 else if (equal_Command(cmd, "zoom.set")) {
948 setFreezeDraw_Window(get_Window(), iTrue); /* no intermediate draws before docs updated */
949 d->zoomPercent = arg_Command(cmd);
950 setContentFontSize_Text((float) d->zoomPercent / 100.0f);
951 postCommand_App("font.changed");
952 postCommand_App("window.unfreeze");
953 return iTrue;
954 }
955 else if (equal_Command(cmd, "zoom.delta")) {
956 setFreezeDraw_Window(get_Window(), iTrue); /* no intermediate draws before docs updated */
957 int delta = arg_Command(cmd);
958 if (d->zoomPercent < 100 || (delta < 0 && d->zoomPercent == 100)) {
959 delta /= 2;
960 }
961 d->zoomPercent = iClamp(d->zoomPercent + delta, 50, 200);
962 setContentFontSize_Text((float) d->zoomPercent / 100.0f);
963 postCommand_App("font.changed");
964 postCommand_App("window.unfreeze");
965 return iTrue;
966 }
967 else if (equal_Command(cmd, "forcewrap.toggle")) {
968 d->forceWrap = !d->forceWrap;
969 updateSize_DocumentWidget(document_App());
970 return iTrue;
971 }
972 else if (equal_Command(cmd, "bookmark.add")) { 997 else if (equal_Command(cmd, "bookmark.add")) {
973 iDocumentWidget *doc = document_App(); 998 iDocumentWidget *doc = document_App();
974 makeBookmarkCreation_Widget(url_DocumentWidget(doc), 999 makeBookmarkCreation_Widget(url_DocumentWidget(doc),
@@ -1003,22 +1028,8 @@ iBool handleCommand_App(const char *cmd) {
1003 postCommand_App("idents.changed"); 1028 postCommand_App("idents.changed");
1004 return iTrue; 1029 return iTrue;
1005 } 1030 }
1006 else if (equal_Command(cmd, "theme.set")) {
1007 const int isAuto = argLabel_Command(cmd, "auto");
1008 d->theme = arg_Command(cmd);
1009 if (!isAuto) {
1010 postCommand_App("ostheme arg:0");
1011 }
1012 setThemePalette_Color(d->theme);
1013 postCommandf_App("theme.changed auto:%d", isAuto);
1014 return iTrue;
1015 }
1016 else if (equal_Command(cmd, "ostheme")) {
1017 d->useSystemTheme = arg_Command(cmd);
1018 return iTrue;
1019 }
1020 else if (equal_Command(cmd, "os.theme.changed")) { 1031 else if (equal_Command(cmd, "os.theme.changed")) {
1021 if (d->useSystemTheme) { 1032 if (d->prefs.useSystemTheme) {
1022 const int dark = argLabel_Command(cmd, "dark"); 1033 const int dark = argLabel_Command(cmd, "dark");
1023 const int contrast = argLabel_Command(cmd, "contrast"); 1034 const int contrast = argLabel_Command(cmd, "contrast");
1024 postCommandf_App("theme.set arg:%d auto:1", 1035 postCommandf_App("theme.set arg:%d auto:1",
@@ -1027,14 +1038,6 @@ iBool handleCommand_App(const char *cmd) {
1027 } 1038 }
1028 return iFalse; 1039 return iFalse;
1029 } 1040 }
1030 else if (equal_Command(cmd, "proxy.gopher")) {
1031 setCStr_String(&d->gopherProxy, suffixPtr_Command(cmd, "address"));
1032 return iTrue;
1033 }
1034 else if (equal_Command(cmd, "proxy.http")) {
1035 setCStr_String(&d->httpProxy, suffixPtr_Command(cmd, "address"));
1036 return iTrue;
1037 }
1038 else { 1041 else {
1039 return iFalse; 1042 return iFalse;
1040 } 1043 }