344 lines
8.7 KiB
C
344 lines
8.7 KiB
C
#include "window.h"
|
|
|
|
#define LENGTH(x) ((int) (sizeof(x) / sizeof(x[0])))
|
|
|
|
struct _RoseWindow {
|
|
GtkApplicationWindow parent_instance;
|
|
guint xid;
|
|
|
|
GtkWindow *window;
|
|
GtkApplication *app;
|
|
|
|
WebKitWebView *webview[9];
|
|
WebKitWebInspector *inspector;
|
|
WebKitFindOptions *findopts;
|
|
|
|
GHashTable *action_groups;
|
|
GHashTable *action_labels;
|
|
};
|
|
|
|
enum {
|
|
PROP_ACTIVE_CHILD
|
|
};
|
|
|
|
static float zoom = 1.0;
|
|
static unsigned tabid = 0;
|
|
|
|
G_DEFINE_TYPE(RoseWindow, rose_window, GTK_TYPE_APPLICATION_WINDOW)
|
|
|
|
static void read_clipboard(GObject *object,
|
|
GAsyncResult *res,
|
|
gpointer webview)
|
|
{
|
|
GdkClipboard *clipboard = GDK_CLIPBOARD(object);
|
|
webkit_web_view_load_uri(
|
|
WEBKIT_WEB_VIEW(webview),
|
|
gdk_clipboard_read_text_finish(clipboard, res, NULL)
|
|
);
|
|
}
|
|
|
|
static void new_tab(RoseWindow *window, unsigned id)
|
|
{
|
|
window->webview[id] = WEBKIT_WEB_VIEW(webkit_web_view_new());
|
|
|
|
if (!options[HOMEPAGE])
|
|
options[HOMEPAGE] = "https://duckduckgo.com";
|
|
|
|
webkit_web_view_load_uri(WEBKIT_WEB_VIEW(window->webview[id]),
|
|
options[HOMEPAGE]);
|
|
|
|
/* gtk_widget_hide(GTK_WIDGET(window->webview[id])); */
|
|
|
|
gtk_window_set_child(
|
|
GTK_WINDOW(
|
|
gtk_widget_get_root(
|
|
GTK_WIDGET(
|
|
window->webview[tabid++]
|
|
)
|
|
)
|
|
),
|
|
GTK_WIDGET(window->webview[id])
|
|
);
|
|
|
|
gtk_widget_show(GTK_WIDGET(window->webview[tabid]));
|
|
}
|
|
|
|
static void goto_tab(RoseWindow *window, unsigned id)
|
|
{
|
|
if (!window->webview[id]) {
|
|
new_tab(window, id);
|
|
return;
|
|
}
|
|
|
|
gtk_window_set_child(
|
|
GTK_WINDOW(
|
|
gtk_widget_get_root(
|
|
GTK_WIDGET(
|
|
window->webview[tabid]
|
|
)
|
|
)
|
|
),
|
|
GTK_WIDGET(window->webview[id])
|
|
);
|
|
|
|
/* gtk_widget_hide(GTK_WIDGET(window->webview[tabid])); */
|
|
gtk_widget_show(GTK_WIDGET(window->webview[id]));
|
|
}
|
|
|
|
static gboolean key_press_callback(RoseWindow *window,
|
|
guint keyval,
|
|
guint keycode,
|
|
GdkModifierType state)
|
|
{
|
|
(void) keycode;
|
|
|
|
for (int i = 0; i < LENGTH(keys); i++) {
|
|
if (keys[i].modkey == state
|
|
&& keys[i].keycod == keyval) {
|
|
switch (keys[i].funcid) {
|
|
case goback:
|
|
webkit_web_view_go_back(window->webview[tabid]);
|
|
break;
|
|
|
|
case goforward:
|
|
webkit_web_view_go_forward(window->webview[tabid]);
|
|
break;
|
|
|
|
case copy_url: {
|
|
GdkDisplay *dpy = gdk_display_get_default();
|
|
gdk_clipboard_set_text(
|
|
gdk_display_get_clipboard(dpy),
|
|
webkit_web_view_get_uri(window->webview[tabid])
|
|
);
|
|
} break;
|
|
|
|
case paste_url: {
|
|
GdkDisplay *dpy = gdk_display_get_default();
|
|
GdkClipboard *clipboard = gdk_display_get_clipboard(dpy);
|
|
gdk_clipboard_read_text_async(clipboard, NULL, read_clipboard, window->webview[tabid]);
|
|
} break;
|
|
|
|
case fullscreen:
|
|
if (gtk_window_is_fullscreen(GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(window->webview[tabid])))))
|
|
gtk_window_unfullscreen(GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(window->webview[tabid]))));
|
|
else
|
|
gtk_window_fullscreen(GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(window->webview[tabid]))));
|
|
break;
|
|
|
|
case search: {
|
|
int id = fork();
|
|
if (id == 0) {
|
|
if (glob_dpy)
|
|
close(ConnectionNumber(glob_dpy));
|
|
setsid();
|
|
char* argument_list[] = { "/bin/sh", "-c", "dmenu_rose", NULL};
|
|
execvp("/bin/sh", argument_list);
|
|
perror(" failed");
|
|
exit(1);
|
|
} else {
|
|
wait(&id);
|
|
char *uri;
|
|
if (strcmp((uri = (char*)getatom(AtomGo)), ""))
|
|
rose_webview_load_url(window->webview[tabid], uri);
|
|
}
|
|
} break;
|
|
|
|
case find: {
|
|
int id = fork();
|
|
if (id == 0) {
|
|
if (glob_dpy)
|
|
close(ConnectionNumber(glob_dpy));
|
|
setsid();
|
|
char* argument_list[] = { "/bin/sh", "-c", "dmenu_rose\tfind", NULL};
|
|
execvp("/bin/sh", argument_list);
|
|
perror(" failed");
|
|
exit(1);
|
|
} else {
|
|
wait(&id);
|
|
WebKitFindController *finder = webkit_web_view_get_find_controller(window->webview[tabid]);
|
|
webkit_find_controller_search(
|
|
finder,
|
|
getatom(AtomFind),
|
|
WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE |
|
|
WEBKIT_FIND_OPTIONS_WRAP_AROUND, G_MAXUINT);
|
|
}
|
|
} break;
|
|
|
|
case findnext: {
|
|
WebKitFindController *finder = webkit_web_view_get_find_controller(window->webview[tabid]);
|
|
webkit_find_controller_search_next(finder);
|
|
} break;
|
|
|
|
case findprev: {
|
|
WebKitFindController *finder = webkit_web_view_get_find_controller(window->webview[tabid]);
|
|
webkit_find_controller_search_previous(finder);
|
|
} break;
|
|
|
|
case zoomin:
|
|
zoom += 0.1;
|
|
webkit_web_view_set_zoom_level(window->webview[tabid], zoom);
|
|
break;
|
|
|
|
case zoomout:
|
|
zoom -= 0.1;
|
|
webkit_web_view_set_zoom_level(window->webview[tabid], zoom);
|
|
break;
|
|
|
|
case zoomreset:
|
|
zoom = 1;
|
|
webkit_web_view_set_zoom_level(window->webview[tabid], zoom);
|
|
break;
|
|
|
|
case inspector:
|
|
window->inspector = webkit_web_view_get_inspector(window->webview[tabid]);
|
|
if (webkit_web_inspector_is_attached(window->inspector))
|
|
webkit_web_inspector_close(window->inspector);
|
|
else
|
|
webkit_web_inspector_show(window->inspector);
|
|
return GDK_EVENT_STOP;
|
|
break;
|
|
|
|
case up:
|
|
webkit_web_view_run_javascript(window->webview[tabid], "window.scrollBy(0,-100);", NULL, NULL, NULL);
|
|
break;
|
|
|
|
case down:
|
|
webkit_web_view_run_javascript(window->webview[tabid], "window.scrollBy(0,100);", NULL, NULL, NULL);
|
|
break;
|
|
|
|
case reload:
|
|
webkit_web_view_reload(window->webview[tabid]);
|
|
break;
|
|
|
|
case reloadforce:
|
|
webkit_web_view_reload_bypass_cache(window->webview[tabid]);
|
|
break;
|
|
|
|
case history: {
|
|
int id = fork();
|
|
if (id == 0) {
|
|
setsid();
|
|
char* argument_list[] = { "/bin/sh", "-c", "dmenu_rose\thistory", NULL};
|
|
execvp("/bin/sh", argument_list);
|
|
perror(" failed");
|
|
exit(1);
|
|
} else {
|
|
wait(&id);
|
|
char *uri;
|
|
if (strcmp((uri = (char*)getatom(AtomGo)), ""))
|
|
rose_webview_load_url(window->webview[tabid], uri);
|
|
}
|
|
} break;
|
|
|
|
case gotop: {
|
|
webkit_web_view_run_javascript(window->webview[tabid], "window.scrollTo(0,0);", NULL, NULL, NULL);
|
|
} break;
|
|
|
|
case gobottom: {
|
|
webkit_web_view_run_javascript(
|
|
window->webview[tabid],
|
|
"window.scrollTo(0, document.body.scrollHeight);",
|
|
NULL, NULL, NULL);
|
|
} break;
|
|
|
|
case tabnext: {
|
|
if (tabid + 1 > 9)
|
|
return GDK_EVENT_PROPAGATE;
|
|
|
|
goto_tab(window, tabid + 1);
|
|
printf("%i\n", tabid);
|
|
} break;
|
|
|
|
case tabprev: {
|
|
if (!tabid)
|
|
return GDK_EVENT_PROPAGATE;
|
|
|
|
goto_tab(window, tabid - 1);
|
|
printf("%i\n", tabid);
|
|
} break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return GDK_EVENT_PROPAGATE;
|
|
}
|
|
|
|
static void rose_window_constructed(GObject *object)
|
|
{
|
|
G_OBJECT_CLASS(rose_window_parent_class)->constructed(object);
|
|
}
|
|
|
|
static void rose_window_init(RoseWindow *window)
|
|
{
|
|
(void) window;
|
|
}
|
|
|
|
static void destroy()
|
|
{
|
|
exit(0);
|
|
}
|
|
|
|
guint rose_window_show(GtkApplication *app, RoseWindow *window, const char *url)
|
|
{
|
|
window->app = app;
|
|
window->window = GTK_WINDOW(gtk_application_window_new(window->app));
|
|
|
|
/* gtk_application_set_menubar(window->app, FALSE); */
|
|
window->webview[tabid] = WEBKIT_WEB_VIEW(rose_webview_new());
|
|
|
|
g_signal_connect(G_OBJECT(window->window), "destroy",
|
|
G_CALLBACK(destroy), NULL);
|
|
|
|
g_signal_connect(G_OBJECT(window->webview[tabid]), "web-process-terminated",
|
|
G_CALLBACK(destroy), NULL);
|
|
|
|
g_signal_connect(G_OBJECT(window->webview[tabid]), "load-changed",
|
|
G_CALLBACK(rose_load_changed_callback), window->webview[tabid]);
|
|
|
|
if (url) {
|
|
rose_webview_load_url(WEBKIT_WEB_VIEW(window->webview[tabid]), url);
|
|
setatom(AtomUri, url);
|
|
}
|
|
|
|
if (!(appearance[WIDTH] && appearance[HEIGHT])) {
|
|
appearance[WIDTH] = 1280;
|
|
appearance[HEIGHT] = 720;
|
|
}
|
|
|
|
gtk_window_set_default_size(GTK_WINDOW(window->window), appearance[WIDTH], appearance[HEIGHT]);
|
|
|
|
gtk_window_set_child(GTK_WINDOW(window->window), GTK_WIDGET(window->webview[tabid]));
|
|
|
|
GtkEventController *controller;
|
|
controller = gtk_event_controller_key_new();
|
|
g_signal_connect_swapped(controller, "key-pressed", G_CALLBACK(key_press_callback), window);
|
|
gtk_widget_add_controller(GTK_WIDGET(window->window), controller);
|
|
|
|
gtk_widget_show(GTK_WIDGET(window->window));
|
|
gtk_widget_show(GTK_WIDGET(window->webview[tabid]));
|
|
|
|
return 12;
|
|
}
|
|
|
|
void rose_window_set_webview(RoseWindow *window, GtkWidget *webview)
|
|
{
|
|
window->webview[tabid] = WEBKIT_WEB_VIEW(webview);
|
|
}
|
|
|
|
static void rose_window_class_init(RoseWindowClass *class)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS(class);
|
|
|
|
object_class->constructed = rose_window_constructed;
|
|
}
|
|
|
|
RoseWindow* rose_window_new(GtkApplication *app)
|
|
{
|
|
return g_object_new(
|
|
GTK_TYPE_APPLICATION_WINDOW,
|
|
"application", GTK_APPLICATION(app),
|
|
NULL
|
|
);
|
|
}
|