/* This file is released into the public domain. * No rights reserved. Copy, modify, do whatever you want. */ #ifndef CONFIG_H #define CONFIG_H #include #include #include /* forward declarations from main.c */ extern void tabopen(Cinnamon* cinnamon); extern void tabclose(Cinnamon* cinnamon); extern void set_mode(Cinnamon* cinnamon, int new_mode); extern void inject_hint_mode(Cinnamon* cinnamon, void (*callback)(Cinnamon*, char hint_buffer[16])); extern void quickmark_add(Cinnamon* cinnamon, const char* name, const char* url); extern void quickmark_load(Cinnamon* cinnamon, const char* name); extern void quickmark_save_all(void); /* guard ensures config exists/enables brower */ #define CINNAMON_ENABLED /* default window width/height, can be resized after. */ #define WINDOW_WIDTH 1024 #define WINDOW_HEIGHT 768 /* searchengine/homepage */ #define SEARCH_ENGINE "https://duckduckgo.com/?q=" #define HOMEPAGE "https://start.duckduckgo.com" /* if a keybind is unbound, still don't send when not in insert mode */ #define NO_SEND_UNBOUND_KEYBINDS /* if the last tab is closed, don't quit, just make a fresh one */ #define NO_QUIT_ON_CLOSE_LAST_TAB /* hide the tab bar, unless a keybind or command shows it */ /* #define HIDE_TAB_BAR */ #define USERAGENT "Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/605.1.15 (KHTML, like Gecko) cinnamon/1.0 (git.arslaancodes.com/cinnamon-browser.git) Safari/605.1.15" /* show favicon AND title */ #define TABS_SHOW_FAVICON #define TABS_SHOW_TITLE /* quickmark filepath relative to the user data dir, usually ~/.local/share/cinnamon */ #define QUICKMARK_FILE "quickmarks.txt" /* Keybind definitions */ /* we use the _kbd prefix here just because, idk, good practice to keep keybinds isolated? in practice use whatever the hell you want as long as it doesnt interfere with builtin functions */ static void _conf_hint_callback(Cinnamon* cinnamon, char hint_buffer[16]) { if (strlen(hint_buffer) > 0) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); char js[512]; snprintf(js, sizeof(js), "(function() {if (window.__cinnamon_link_map && window.__cinnamon_link_map['%s']) { let el = window.__cinnamon_link_map['%s']; let tag = el.tagName.toLowerCase(); if (tag === 'input' || tag === 'textarea' || tag === 'select') { el.focus(); } else { el.click(); } }})();", hint_buffer, hint_buffer); webkit_web_view_run_javascript(WEBKIT_WEB_VIEW(webview), js, NULL, NULL, NULL); } } extern bool cmdbar_focused; static void _kbd_insmode(Cinnamon* cinnamon, void* arg) { set_mode(cinnamon, 1); } static void _kbd_passthru(Cinnamon* cinnamon, void* arg) { set_mode(cinnamon, 2); } static void _kbd_tabopen(Cinnamon* cinnamon, void* arg) { /* wrapper to satisfy the arg + keep keybinds isolated */ tabopen(cinnamon); } static void _kbd_scroll(Cinnamon* cinnamon, void* arg) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); const char* js; if (strcmp((const char*)arg, "left") == 0) { js = "window.scrollBy(-100, 0);"; } else if (strcmp((const char*)arg, "right") == 0) { js = "window.scrollBy(100, 0);"; } else if (strcmp((const char*)arg, "up") == 0) { js = "window.scrollBy(0, -100);"; } else if (strcmp((const char*)arg, "down") == 0) { js = "window.scrollBy(0, 100);"; } else { js = "alert(\"an unexpected error occurred in the scroll handler\");"; } /* some distros ship older versions of webkit2gtk-4.1, use the deprecated run_javascript api to ensure compatibility */ /* this entire scroll mechanism is scuffed, first of all, i should have abstracted that in main.c, second of all, we're using JS apis of all things just to scroll T_T */ /* this code sucks, * you know it, * i know it. * call me an idiot later and just use the browser. */ webkit_web_view_run_javascript(WEBKIT_WEB_VIEW(webview), js, NULL, NULL, NULL); } static void _kbd_tabsel(Cinnamon* cinnamon, void* arg) { gtk_notebook_set_current_page(GTK_NOTEBOOK(cinnamon->notebook), (int)(intptr_t)arg); } static void _kbd_tabclose(Cinnamon* cinnamon, void* arg) { tabclose(cinnamon); } static void _kbd_toggletabs(Cinnamon* cinnamon, void* arg) { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(cinnamon->notebook), !gtk_notebook_get_show_tabs(GTK_NOTEBOOK(cinnamon->notebook))); } static void _kbd_opencmd(Cinnamon* cinnamon, void* arg) { gtk_entry_set_text(GTK_ENTRY(cinnamon->cmdbar), "open "); gtk_widget_show(cinnamon->cmdbar); gtk_widget_grab_focus(cinnamon->cmdbar); gtk_editable_set_position(GTK_EDITABLE(cinnamon->cmdbar), -1); cmdbar_focused = true; set_mode(cinnamon, 1); } static void _kbd_reload(Cinnamon* cinnamon, void* arg) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); webkit_web_view_reload(WEBKIT_WEB_VIEW(webview)); } static void _kbd_hardreload(Cinnamon* cinnamon, void* arg) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); webkit_web_view_reload_bypass_cache(WEBKIT_WEB_VIEW(webview)); } static void _kbd_back(Cinnamon* cinnamon, void* arg) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); webkit_web_view_go_back(WEBKIT_WEB_VIEW(webview)); } static void _kbd_forward(Cinnamon* cinnamon, void* arg) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); webkit_web_view_go_forward(WEBKIT_WEB_VIEW(webview)); } static void _kbd_follow(Cinnamon* cinnamon, void* arg) { inject_hint_mode(cinnamon, &_conf_hint_callback); } static void _kbd_next_tab(Cinnamon* cinnamon, void* arg) { int current = gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook)); int n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(cinnamon->notebook)); int next = (current + 1) % n_pages; gtk_notebook_set_current_page(GTK_NOTEBOOK(cinnamon->notebook), next); } static void _kbd_prev_tab(Cinnamon* cinnamon, void* arg) { int current = gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook)); int n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(cinnamon->notebook)); int prev = (current - 1 + n_pages) % n_pages; gtk_notebook_set_current_page(GTK_NOTEBOOK(cinnamon->notebook), prev); } static void _kbd_qaddcmd(Cinnamon* cinnamon, void* arg) { gtk_entry_set_text(GTK_ENTRY(cinnamon->cmdbar), "qadd "); gtk_widget_show(cinnamon->cmdbar); gtk_widget_grab_focus(cinnamon->cmdbar); gtk_editable_set_position(GTK_EDITABLE(cinnamon->cmdbar), -1); cmdbar_focused = true; set_mode(cinnamon, 1); } static void _kbd_qloadcmd(Cinnamon* cinnamon, void* arg) { gtk_entry_set_text(GTK_ENTRY(cinnamon->cmdbar), "qload "); gtk_widget_show(cinnamon->cmdbar); gtk_widget_grab_focus(cinnamon->cmdbar); gtk_editable_set_position(GTK_EDITABLE(cinnamon->cmdbar), -1); cmdbar_focused = true; set_mode(cinnamon, 1); } static void _kbd_qloadtabcmd(Cinnamon* cinnamon, void* arg) { gtk_entry_set_text(GTK_ENTRY(cinnamon->cmdbar), "qloadtab "); gtk_widget_show(cinnamon->cmdbar); gtk_widget_grab_focus(cinnamon->cmdbar); gtk_editable_set_position(GTK_EDITABLE(cinnamon->cmdbar), -1); cmdbar_focused = true; set_mode(cinnamon, 1); } static const Keybind keybinds[] = { { "t", &_kbd_tabopen, NULL }, { "d", &_kbd_tabclose, NULL }, { "o", &_kbd_opencmd, NULL }, { "m", &_kbd_qaddcmd, NULL }, { "b", &_kbd_qloadcmd, NULL }, { "", &_kbd_qloadtabcmd, NULL }, { "s", &_kbd_toggletabs, NULL }, { "", &_kbd_passthru, NULL }, { "i", &_kbd_insmode, NULL }, { "j", &_kbd_scroll, "down" }, { "k", &_kbd_scroll, "up" }, { "h", &_kbd_scroll, "left" }, { "l", &_kbd_scroll, "right" }, { "r", &_kbd_reload, NULL }, { "f", &_kbd_follow, NULL }, { "", &_kbd_next_tab, NULL }, { "", &_kbd_prev_tab, NULL }, { "", &_kbd_back, NULL }, { "", &_kbd_forward, NULL }, { "", &_kbd_hardreload, NULL }, { "", &_kbd_tabsel, (void*)(intptr_t)0 }, { "", &_kbd_tabsel, (void*)(intptr_t)1 }, { "", &_kbd_tabsel, (void*)(intptr_t)2 }, { "", &_kbd_tabsel, (void*)(intptr_t)3 }, { "", &_kbd_tabsel, (void*)(intptr_t)4 }, { "", &_kbd_tabsel, (void*)(intptr_t)5 }, { "", &_kbd_tabsel, (void*)(intptr_t)6 }, { "", &_kbd_tabsel, (void*)(intptr_t)7 }, { "", &_kbd_tabsel, (void*)(intptr_t)8 }, { "", &_kbd_tabsel, (void*)(intptr_t)-1 }, }; /* Command definitions */ /* as mentioned above, prefixes like _cmd and _kbd are for good practice but in your modified configs you can do what you want. i don't care, i just make the software, do what you want with your config */ static void _cmd_open(Cinnamon* cinnamon, const char* args) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); char uri[2048]; if (strncmp(args, "http://", 7) == 0 || strncmp(args, "https://", 8) == 0) { snprintf(uri, sizeof(uri), "%s", args); } else if (strchr(args, '.') && !strchr(args, ' ')) { /* has a dot and no spaces, probably a domain */ /* if it's not, oh well, too bad so sad */ snprintf(uri, sizeof(uri), "https://%s", args); } else { /* urlencode magic */ char encoded[1024]; int j = 0; for (int i = 0; args[i] && j < (int)sizeof(encoded)-1; i++) { if (args[i] == ' ') encoded[j++] = '+'; else encoded[j++] = args[i]; } encoded[j] = '\0'; snprintf(uri, sizeof(uri), SEARCH_ENGINE "%s", encoded); } webkit_web_view_load_uri(WEBKIT_WEB_VIEW(webview), uri); } static void _cmd_reload(Cinnamon* cinnamon, const char* args) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); webkit_web_view_reload(WEBKIT_WEB_VIEW(webview)); } static void _cmd_hardreload(Cinnamon* cinnamon, const char* args) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); webkit_web_view_reload_bypass_cache(WEBKIT_WEB_VIEW(webview)); } static void _cmd_back(Cinnamon* cinnamon, const char* args) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); webkit_web_view_go_back(WEBKIT_WEB_VIEW(webview)); } static void _cmd_forward(Cinnamon* cinnamon, const char* args) { GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); webkit_web_view_go_forward(WEBKIT_WEB_VIEW(webview)); } static void _cmd_quit(Cinnamon* cinnamon, const char* args) { gtk_main_quit(); } static void _cmd_qadd(Cinnamon* cinnamon, const char* args) { if (!args || strlen(args) == 0) return; GtkWidget *webview = gtk_notebook_get_nth_page(GTK_NOTEBOOK(cinnamon->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(cinnamon->notebook))); const char *url = webkit_web_view_get_uri(WEBKIT_WEB_VIEW(webview)); quickmark_add(cinnamon, args, url); quickmark_save_all(); } static void _cmd_qload(Cinnamon* cinnamon, const char* args) { if (!args || strlen(args) == 0) return; quickmark_load(cinnamon, args); } static void _cmd_qloadtab(Cinnamon* cinnamon, const char* args) { if (!args || strlen(args) == 0) return; tabopen(cinnamon); quickmark_load(cinnamon, args); } static const Command commands[] = { { "open", &_cmd_open }, { "reload", &_cmd_reload }, { "hard_reload", &_cmd_hardreload }, { "back", &_cmd_back }, { "forward", &_cmd_forward }, { "q", &_cmd_quit }, { "quit", &_cmd_quit }, { "qadd", &_cmd_qadd }, { "qload", &_cmd_qload }, { "qloadtab", &_cmd_qloadtab }, }; /* User start/hooks * Do whatever you want here, initialize whatever custom hooks you want to your heart's content. At this point config.h can just become an extension api on crack, knock yourself out * have fun */ /* It runs just before gtk_main(), after everything prior has been initialized. */ void user_start(Cinnamon* cinnamon) { /* Function has to exist or else main.c won't compile, this code is so scuffed T_T */ /* for now just printf to see if it loads */ printf("[user_start] starting NOW!\n"); } #endif