]> git.armaanb.net Git - chorizo.git/blob - shortcuts.c
draft 8
[chorizo.git] / shortcuts.c
1 #include <webkit2/webkit2.h>
2
3 #include "config.h"
4 #include "chorizo.h"
5
6 gboolean
7 key_common(GtkWidget *widget, GdkEvent *event, gpointer data)
8 {
9         WebKitPrintOperation *operation;
10         gboolean muted;
11         struct Client *c = (struct Client *)data;
12         gdouble now;
13
14         if (event->type == GDK_KEY_PRESS) {
15                 guint mask = gtk_accelerator_get_default_mod_mask();
16                 int key = ((GdkEventKey *)event)->keyval;
17                 if ((((GdkEventKey *)event)->state & mask) ==
18                     GDK_CONTROL_MASK) {
19                         const char *uri = webkit_web_view_get_uri(
20                                 WEBKIT_WEB_VIEW(c->web_view));
21                         switch (key) {
22                         case GDK_KEY_y:
23                                 downloadmanager_show();
24                                 return TRUE;
25                         case GDK_KEY_h:
26                                 webkit_web_view_go_back(
27                                         WEBKIT_WEB_VIEW(c->web_view));
28                                 return TRUE;
29                         case GDK_KEY_l:
30                                 webkit_web_view_go_forward(
31                                         WEBKIT_WEB_VIEW(c->web_view));
32                                 return TRUE;
33                         case GDK_KEY_s:
34                                 gtk_widget_grab_focus(c->location);
35                                 return TRUE;
36                         case GDK_KEY_p:
37                                 operation = webkit_print_operation_new(
38                                         WEBKIT_WEB_VIEW(c->web_view));
39                                 GtkWidget *toplevel =
40                                         gtk_widget_get_toplevel(mw.win);
41                                 webkit_print_operation_run_dialog(
42                                         operation, GTK_WINDOW(toplevel));
43                                 return TRUE;
44                         case GDK_KEY_g:
45                                 isearch(c, 2);
46                                 gtk_widget_grab_focus(c->web_view);
47                                 if (uri)
48                                         gtk_entry_set_text(
49                                                 GTK_ENTRY(c->location), uri);
50                                 webkit_web_view_run_javascript(
51                                         WEBKIT_WEB_VIEW(c->web_view),
52                                         "window.getSelection()"
53                                         ".removeAllRanges();"
54                                         "document.activeElement.blur();",
55                                         NULL, NULL, c);
56                                 gtk_widget_hide(c->isearch_box);
57                                 gtk_editable_set_position(
58                                         GTK_EDITABLE(c->location), -1);
59                                 gtk_editable_set_position(
60                                         GTK_EDITABLE(c->wsearch), -1);
61                                 return TRUE;
62                         case GDK_KEY_r:
63                                 webkit_web_view_reload_bypass_cache(
64                                         WEBKIT_WEB_VIEW(c->web_view));
65                                 return TRUE;
66                         case GDK_KEY_j:
67                                 for (int i = 0; i <= cfg_scroll_lines - 1;
68                                      i++) {
69                                         event->key.keyval = GDK_KEY_Down;
70                                         gdk_event_put(event);
71                                 }
72                                 return TRUE;
73                         case GDK_KEY_k:
74                                 for (int i = 0; i <= cfg_scroll_lines - 1;
75                                      i++) {
76                                         event->key.keyval = GDK_KEY_Up;
77                                         gdk_event_put(event);
78                                 }
79                                 return TRUE;
80                         case GDK_KEY_f:
81                                 isearch_init(c, 1);
82                                 return TRUE;
83                         case GDK_KEY_q:
84                                 client_destroy(NULL, c);
85                                 return TRUE;
86                         case GDK_KEY_1:
87                                 change_tab(0, c);
88                                 return TRUE;
89                         case GDK_KEY_2:
90                                 change_tab(1, c);
91                                 return TRUE;
92                         case GDK_KEY_3:
93                                 change_tab(2, c);
94                                 return TRUE;
95                         case GDK_KEY_4:
96                                 change_tab(3, c);
97                                 return TRUE;
98                         case GDK_KEY_5:
99                                 change_tab(4, c);
100                                 return TRUE;
101                         case GDK_KEY_6:
102                                 change_tab(5, c);
103                                 return TRUE;
104                         case GDK_KEY_7:
105                                 change_tab(6, c);
106                                 gtk_notebook_set_current_page(
107                                         GTK_NOTEBOOK(mw.notebook), 6);
108                                 return TRUE;
109                         case GDK_KEY_8:
110                                 change_tab(7, c);
111                                 return TRUE;
112                         case GDK_KEY_9:
113                                 change_tab(8, c);
114                                 return TRUE;
115                         case GDK_KEY_u:
116                                 gtk_notebook_prev_page(
117                                         GTK_NOTEBOOK(mw.notebook));
118                                 return TRUE;
119                         case GDK_KEY_m:
120                                 muted = webkit_web_view_get_is_muted(
121                                         WEBKIT_WEB_VIEW(c->web_view));
122                                 webkit_web_view_set_is_muted(
123                                         WEBKIT_WEB_VIEW(c->web_view), !muted);
124                                 changed_title(G_OBJECT(c->web_view), NULL, c);
125                                 return TRUE;
126                         case GDK_KEY_t:
127                                 switch_tab = TRUE;
128                                 client_new(cfg_home_uri, NULL);
129                                 return TRUE;
130                         case GDK_KEY_bracketleft:
131                                 reopen_tab();
132                                 return TRUE;
133                         case GDK_KEY_i:
134                                 gtk_notebook_next_page(
135                                         GTK_NOTEBOOK(mw.notebook));
136                                 return TRUE;
137                         case GDK_KEY_d:
138                                 gtk_widget_grab_focus(c->wsearch);
139                                 return TRUE;
140                         case GDK_KEY_equal:
141                                 now = webkit_web_view_get_zoom_level(
142                                         WEBKIT_WEB_VIEW(c->web_view));
143                                 webkit_web_view_set_zoom_level(
144                                         WEBKIT_WEB_VIEW(c->web_view),
145                                         now + 0.1);
146                                 return TRUE;
147                         case GDK_KEY_minus:
148                                 now = webkit_web_view_get_zoom_level(
149                                         WEBKIT_WEB_VIEW(c->web_view));
150                                 webkit_web_view_set_zoom_level(
151                                         WEBKIT_WEB_VIEW(c->web_view),
152                                         now - 0.1);
153                                 return TRUE;
154                         case GDK_KEY_0:
155                                 webkit_web_view_set_zoom_level(
156                                         WEBKIT_WEB_VIEW(c->web_view), 1);
157                                 return TRUE;
158                         }
159                 } else if ((((GdkEventKey *)event)->state & mask) ==
160                            (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) {
161                         switch (key) {
162                         case GDK_KEY_ISO_Left_Tab:
163                                 gtk_notebook_prev_page(
164                                         GTK_NOTEBOOK(mw.notebook));
165                                 return TRUE;
166                         case GDK_KEY_T:
167                                 reopen_tab();
168                                 return TRUE;
169                         case GDK_KEY_exclam:
170                                 reorder_current_tab(1);
171                                 return TRUE;
172                         case GDK_KEY_at:
173                                 reorder_current_tab(2);
174                                 return TRUE;
175                         case GDK_KEY_numbersign:
176                                 reorder_current_tab(3);
177                                 return TRUE;
178                         case GDK_KEY_dollar:
179                                 reorder_current_tab(4);
180                                 return TRUE;
181                         case GDK_KEY_percent:
182                                 reorder_current_tab(5);
183                                 return TRUE;
184                         case GDK_KEY_asciicircum:
185                                 reorder_current_tab(6);
186                                 return TRUE;
187                         case GDK_KEY_ampersand:
188                                 reorder_current_tab(7);
189                                 return TRUE;
190                         case GDK_KEY_asterisk:
191                                 reorder_current_tab(8);
192                                 return TRUE;
193                         case GDK_KEY_parenleft:
194                                 reorder_current_tab(9);
195                                 return TRUE;
196                         }
197                 }
198         }
199         return FALSE;
200 }
201
202 void
203 change_tab(int idx, struct Client *c)
204 {
205         gtk_notebook_set_current_page(GTK_NOTEBOOK(mw.notebook), idx);
206         gtk_widget_grab_focus(GTK_WIDGET(c->web_view));
207 }
208
209 void
210 reorder_current_tab(int target)
211 {
212         gtk_notebook_reorder_child(
213                 GTK_NOTEBOOK(mw.notebook),
214                 gtk_notebook_get_nth_page(GTK_NOTEBOOK(mw.notebook),
215                                           gtk_notebook_get_current_page(
216                                                   GTK_NOTEBOOK(mw.notebook))),
217                 target - 1);
218 }
219
220 gboolean
221 key_isearch(GtkWidget *widget, GdkEvent *event, gpointer data)
222 {
223         struct Client *c = (struct Client *)data;
224         if (key_common(widget, event, data)) return TRUE;
225
226         if (event->type == GDK_KEY_PRESS) {
227                 int key = ((GdkEventKey *)event)->keyval;
228                 // clang-format off
229                 int direction =
230                         (((GdkEventKey *)event)->state & GDK_SHIFT_MASK)
231                                 ? -1 : 1;
232                 // clang-format on
233                 switch (key) {
234                 case GDK_KEY_KP_Enter:
235                 case GDK_KEY_Return:
236                         isearch(c, 0);
237                         isearch(c, -1);
238                         isearch(c, direction);
239                         return TRUE;
240                 case GDK_KEY_Escape:
241                         isearch(c, 2);
242                         gtk_widget_hide(c->isearch_box);
243                         gtk_widget_grab_focus(c->web_view);
244                         return TRUE;
245                 }
246         }
247         return FALSE;
248 }
249
250 gboolean
251 key_wsearch(GtkWidget *widget, GdkEvent *event, gpointer data)
252 {
253         struct Client *c = (struct Client *)data;
254         if (key_common(widget, event, data)) return TRUE;
255
256         if (event->type == GDK_KEY_PRESS) {
257                 guint mask = gtk_accelerator_get_default_mod_mask();
258                 gboolean shifted = ((((GdkEventKey *)event)->state & mask) ==
259                                     GDK_SHIFT_MASK);
260                 int key = ((GdkEventKey *)event)->keyval;
261                 if ((GDK_KEY_KP_Enter == key) || (GDK_KEY_Return == key)) {
262                         const gchar *t =
263                                 gtk_entry_get_text(GTK_ENTRY(c->wsearch));
264                         int len = strlen(cfg_search_engine) + strlen(t);
265                         gchar *f = malloc(len + 1);
266                         if (!f) allocfail();
267
268                         snprintf(f, len + 1, "%s%s", cfg_search_engine, t);
269                         if (shifted) {
270                                 client_new(f, NULL);
271                         } else {
272                                 webkit_web_view_load_uri(
273                                         WEBKIT_WEB_VIEW(c->web_view), f);
274                                 gtk_widget_grab_focus(c->web_view);
275                         }
276                         g_free(f);
277                         return TRUE;
278                 }
279         }
280         return FALSE;
281 }
282
283 gboolean
284 key_location(GtkWidget *widget, GdkEvent *event, gpointer data)
285 {
286         struct Client *c = (struct Client *)data;
287         const gchar *t;
288         if (key_common(widget, event, data)) return TRUE;
289
290         if (event->type == GDK_KEY_PRESS) {
291                 guint mask = gtk_accelerator_get_default_mod_mask();
292                 gboolean shifted = ((((GdkEventKey *)event)->state & mask) ==
293                                     GDK_SHIFT_MASK);
294                 int key = ((GdkEventKey *)event)->keyval;
295                 switch (key) {
296                 case GDK_KEY_KP_Enter:
297                 case GDK_KEY_Return:
298                         gtk_widget_grab_focus(c->web_view);
299                         t = gtk_entry_get_text(GTK_ENTRY(c->location));
300                         if (shifted) {
301                                 switch_tab = TRUE;
302                                 client_new(t, NULL);
303                         } else {
304                                 webkit_web_view_load_uri(
305                                         WEBKIT_WEB_VIEW(c->web_view),
306                                         ensure_uri_scheme(t));
307                         }
308                         return TRUE;
309                 case GDK_KEY_Escape:
310                         t = webkit_web_view_get_uri(
311                                 WEBKIT_WEB_VIEW(c->web_view));
312                         gtk_entry_set_text(GTK_ENTRY(c->location),
313                                            (t == NULL) ? "" : t);
314                         return TRUE;
315                 }
316         }
317         return FALSE;
318 }
319 gboolean
320 key_tablabel(GtkWidget *widget, GdkEvent *event, gpointer data)
321 {
322         GdkScrollDirection direction;
323         if (event->type == GDK_BUTTON_RELEASE) {
324                 switch (((GdkEventButton *)event)->button) {
325                 case 2:
326                         client_destroy(NULL, data);
327                         return TRUE;
328                 }
329         } else if (event->type == GDK_SCROLL) {
330                 gdk_event_get_scroll_direction(event, &direction);
331                 switch (direction) {
332                 case GDK_SCROLL_UP:
333                         gtk_notebook_prev_page(GTK_NOTEBOOK(mw.notebook));
334                         break;
335                 case GDK_SCROLL_DOWN:
336                         gtk_notebook_next_page(GTK_NOTEBOOK(mw.notebook));
337                         break;
338                 default:
339                         break;
340                 }
341                 return TRUE;
342         }
343         return FALSE;
344 }
345
346 gboolean
347 key_web_view(GtkWidget *widget, GdkEvent *event, gpointer data)
348 {
349         struct Client *c = (struct Client *)data;
350         gdouble dx, dy;
351         gfloat z;
352         if (key_common(c->web_view, event, data)) return TRUE;
353
354         if (event->type == GDK_KEY_PRESS) {
355                 if (((GdkEventKey *)event)->keyval == GDK_KEY_Escape) {
356                         webkit_web_view_stop_loading(
357                                 WEBKIT_WEB_VIEW(c->web_view));
358                         gtk_entry_set_progress_fraction(GTK_ENTRY(c->location),
359                                                         0);
360                 }
361         } else if (event->type == GDK_SCROLL) {
362                 event->scroll.delta_y *= cfg_scroll_lines;
363                 if (((GdkEventScroll *)event)->state & GDK_CONTROL_MASK) {
364                         gdk_event_get_scroll_deltas(event, &dx, &dy);
365                         z = webkit_web_view_get_zoom_level(
366                                 WEBKIT_WEB_VIEW(c->web_view));
367                         z += -dy * 0.1;
368                         z = dx != 0 ? 1 : z;
369                         webkit_web_view_set_zoom_level(
370                                 WEBKIT_WEB_VIEW(c->web_view), z);
371                         return TRUE;
372                 }
373         }
374         return FALSE;
375 }