Skip to content

Instantly share code, notes, and snippets.

@vain

vain/Makefile Secret

Created May 21, 2017
Embed
What would you like to do?
webkit2gtk mouse gestures, gtk menu from webkit menu
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <webkit2/webkit2.h>
struct Client
{
GtkWidget *web_view;
GtkWidget *win;
gdouble mouse_down_x, mouse_down_y;
WebKitContextMenu *menu;
};
void
show_webkit_menu(WebKitContextMenu *webkit_menu, GdkEvent *event)
{
GtkWidget *gtk_menu;
WebKitContextMenuItem *cmi;
GtkAction *gtk_action;
GtkWidget *item_for_action;
GList *l, *p;
/* Turn a WebKitContextMenu into a Gtk menu. We have no choice but
* to use deprecated functions here. */
/* XXX Missing: Handling of submenus. */
gtk_menu = gtk_menu_new();
l = webkit_context_menu_get_items(webkit_menu);
for (p = l; p != NULL; p = p->next)
{
cmi = p->data;
gtk_action = webkit_context_menu_item_get_action(cmi);
if (gtk_action == NULL)
item_for_action = gtk_separator_menu_item_new();
else
item_for_action = gtk_action_create_menu_item(gtk_action);
gtk_menu_shell_append(GTK_MENU_SHELL(gtk_menu), item_for_action);
gtk_widget_show(item_for_action);
}
gtk_menu_popup_at_pointer(GTK_MENU(gtk_menu), event);
}
gboolean
key_web_view(GtkWidget *widget, GdkEvent *event, gpointer data)
{
struct Client *c = (struct Client *)data;
gdouble dx, dy;
gdouble rx, ry;
if (event->type == GDK_BUTTON_PRESS)
{
switch (((GdkEventButton *)event)->button)
{
case 3:
c->mouse_down_x = ((GdkEventButton *)event)->x;
c->mouse_down_y = ((GdkEventButton *)event)->y;
/* We got the mouse position and that's all we want.
* Continue as usual. */
return FALSE;
}
}
else if (event->type == GDK_BUTTON_RELEASE)
{
if ((((GdkEventButton *)event)->button) == 3)
{
rx = ((GdkEventButton *)event)->x;
ry = ((GdkEventButton *)event)->y;
dx = c->mouse_down_x - rx;
dy = c->mouse_down_y - ry;
if (abs(dx) > abs(dy))
{
if (dx > 30) /* navigate backward */
{
webkit_web_view_go_back(WEBKIT_WEB_VIEW(c->web_view));
return TRUE;
}
else if (dx < -30) /* navigate forward */
{
webkit_web_view_go_forward(WEBKIT_WEB_VIEW(c->web_view));
return TRUE;
}
}
else
{
if (dy > 30) /* reload */
{
webkit_web_view_reload_bypass_cache(WEBKIT_WEB_VIEW(c->web_view));
return TRUE;
}
else if (dy < -30) /* new tab */
{
printf("opening new tab, not implemented here\n");
return TRUE;
}
}
/* If we end up here, we should open webkit's context menu,
* because the right mouse button was released but it was
* not a valid/known gesture. */
show_webkit_menu(c->menu, event);
}
}
return FALSE;
}
gboolean
menu_web_view(WebKitWebView *web_view, WebKitContextMenu *menu, GdkEvent *ev,
WebKitHitTestResult *ht, gpointer data)
{
struct Client *c = (struct Client *)data;
g_object_ref(menu);
if (c->menu != NULL)
g_object_unref(c->menu);
c->menu = menu;
return TRUE;
}
int
main(int argc, char **argv)
{
struct Client c;
gtk_init(&argc, &argv);
c.win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
c.web_view = webkit_web_view_new();
c.menu = NULL;
g_signal_connect(G_OBJECT(c.win), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(c.web_view), "close",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(c.web_view), "context-menu",
G_CALLBACK(menu_web_view), &c);
g_signal_connect(G_OBJECT(c.web_view), "button-press-event",
G_CALLBACK(key_web_view), &c);
g_signal_connect(G_OBJECT(c.web_view), "button-release-event",
G_CALLBACK(key_web_view), &c);
gtk_container_add(GTK_CONTAINER(c.win), c.web_view);
gtk_widget_show_all(c.win);
webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c.web_view),
"https://www.google.com");
gtk_main();
exit(EXIT_SUCCESS);
}
CFLAGS += -Wall -Wextra -Wno-unused-parameter -O3
browser: browser.c
$(CC) $(CFLAGS) $(LDFLAGS) \
-o $@ $< \
`pkg-config --cflags --libs gtk+-3.0 glib-2.0 webkit2gtk-4.0`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment