1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
/* This file is released into the public domain.
* No rights reserved. Copy, modify, do whatever you want. */
#ifndef CONFIG_H
#define CONFIG_H
#include <webkit2/webkit2.h>
#include <gtk/gtk.h>
/* 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]));
/* 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"
/* 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 const Keybind keybinds[] = {
{ "t", &_kbd_tabopen, NULL },
{ "d", &_kbd_tabclose, NULL },
{ "o", &_kbd_opencmd, NULL },
{ "s", &_kbd_toggletabs, NULL },
{ "<S-i>", &_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 },
{ "<S-h>", &_kbd_back, NULL },
{ "<S-l>", &_kbd_forward, NULL },
{ "<S-r>", &_kbd_hardreload, NULL },
{ "<A-1>", &_kbd_tabsel, (void*)(intptr_t)0 },
{ "<A-2>", &_kbd_tabsel, (void*)(intptr_t)1 },
{ "<A-3>", &_kbd_tabsel, (void*)(intptr_t)2 },
{ "<A-4>", &_kbd_tabsel, (void*)(intptr_t)3 },
{ "<A-5>", &_kbd_tabsel, (void*)(intptr_t)4 },
{ "<A-6>", &_kbd_tabsel, (void*)(intptr_t)5 },
{ "<A-7>", &_kbd_tabsel, (void*)(intptr_t)6 },
{ "<A-8>", &_kbd_tabsel, (void*)(intptr_t)7 },
{ "<A-9>", &_kbd_tabsel, (void*)(intptr_t)8 },
{ "<A-0>", &_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 const Command commands[] = {
{ "open", &_cmd_open },
{ "reload", &_cmd_reload },
{ "hard_reload", &_cmd_hardreload },
{ "back", &_cmd_back },
{ "forward", &_cmd_forward },
};
/* 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
|