Last active
December 1, 2019 06:43
-
-
Save mattdangerw/df1c737acf403b8e7799 to your computer and use it in GitHub Desktop.
Gtk Webkit Overlay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Gdk = imports.gi.Gdk; | |
const Gio = imports.gi.Gio; | |
const Gtk = imports.gi.Gtk; | |
const WebKit2 = imports.gi.WebKit2; | |
Gtk.init(null, 0); | |
const HTML = '\ | |
<html>\ | |
<head>\ | |
<style type="text/css">\ | |
body {\ | |
font-size: 50px;\ | |
}\ | |
#target {\ | |
height: 100;\ | |
background-color: red;\ | |
}\ | |
</style>\ | |
</head>\ | |
<body>\ | |
<p>Web content. Web content. Web content. Web content.</p>\ | |
<p>Web content. Web content. Web content. Web content.</p>\ | |
<p>Web content. Web content. Web content. Web content.</p>\ | |
<div id="target"></div>\ | |
<p>Web content. Web content. Web content. Web content.</p>\ | |
<p>Web content. Web content. Web content. Web content.</p>\ | |
<p>Web content. Web content. Web content. Web content.</p>\ | |
</body>\ | |
</html>\ | |
'; | |
let context = WebKit2.WebContext.get_default(); | |
context.connect('initialize-web-extensions', () => { | |
context.set_web_extensions_directory('.'); | |
}); | |
let webview = new WebKit2.WebView(); | |
webview.get_settings().enable_write_console_messages_to_stdout = true; | |
webview.load_html(HTML, ''); | |
let button = new Gtk.Button({ | |
label: 'This is a gtk button. It tries to cover the red div.', | |
expand: true, | |
}); | |
let overlay = new Gtk.Overlay(); | |
overlay.add(webview); | |
overlay.add_overlay(button); | |
button.add_events(Gdk.EventMask.SCROLL_MASK); | |
button.connect('scroll-event', (widget, event) => { | |
webview.emit('scroll-event', event); | |
return Gdk.EVENT_STOP; | |
}); | |
let rect = [-999, -999, 100, 100]; | |
let connection = Gio.DBus.session; | |
connection.signal_subscribe(null, | |
'com.endlessm.WebViewDemo', | |
null, | |
null, | |
null, | |
0, | |
(one, two, three, four, five, params) => { | |
rect = params.deep_unpack()[0]; | |
overlay.queue_resize(); | |
}); | |
overlay.connect('get-child-position', (overlay, button, allocation) => { | |
printerr(rect); | |
[allocation.x, allocation.y, allocation.width, allocation.height] = rect; | |
return true; | |
}); | |
let test_window = new Gtk.Window({ | |
default_width: 1000, | |
default_height: 600, | |
}); | |
test_window.add(overlay); | |
test_window.connect('destroy', () => { | |
Gtk.main_quit(); | |
}); | |
test_window.show_all(); | |
Gtk.main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compile with | |
// gcc webkitplugin.c `pkg-config --cflags --libs webkit2gtk-web-extension-4.0` -shared -fPIC -o webkitplugin.so | |
#include <string.h> | |
#include <webkit2/webkit-web-extension.h> | |
#include <webkitdom/webkitdom.h> | |
#define BUS_INTERFACE_NAME "com.endlessm.WebViewDemo" | |
static GDBusConnection *connection; | |
static GDBusInterfaceInfo *interface; | |
static guint bus_id; | |
static WebKitWebExtension *extension; | |
static WebKitWebPage *page; | |
static guint queued_update; | |
static const gchar introspection_xml[] = | |
"<node>" | |
"<interface name='" BUS_INTERFACE_NAME "'>" | |
"<signal name='Changed'>" | |
"<arg name='dom_element_rectangle' type='(iiii)'/>" | |
"</signal>" | |
"</interface>" | |
"</node>"; | |
static gboolean | |
update_div_position (WebKitDOMDOMWindow *window) | |
{ | |
if (bus_id == 0) | |
return FALSE; | |
WebKitDOMDocument *document = webkit_web_page_get_dom_document (page); | |
WebKitDOMElement *target = webkit_dom_document_get_element_by_id (document, "target"); | |
WebKitDOMElement *body = WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document)); | |
glong scroll_left = webkit_dom_element_get_scroll_left (body); | |
glong scroll_top = webkit_dom_element_get_scroll_top (body); | |
gdouble left = webkit_dom_element_get_offset_left (target) - scroll_left; | |
gdouble top = webkit_dom_element_get_offset_top (target) - scroll_top; | |
GError *error = NULL; | |
GVariant *params = g_variant_new ("((iiii))", | |
(gint)left, | |
(gint)top, | |
(gint)webkit_dom_element_get_offset_width (target), | |
(gint)webkit_dom_element_get_offset_height (target)); | |
g_dbus_connection_emit_signal (connection, | |
NULL, | |
"/com/endlessm/webviewdemo", | |
BUS_INTERFACE_NAME, | |
"Changed", | |
params, | |
&error); | |
queued_update = 0; | |
return FALSE; | |
} | |
static void | |
on_resize (WebKitDOMDOMWindow *window) | |
{ | |
if (queued_update == 0) | |
queued_update = g_idle_add ((GSourceFunc)update_div_position, window); | |
} | |
static void | |
on_document_loaded (WebKitWebPage *p) | |
{ | |
WebKitDOMDocument *document = webkit_web_page_get_dom_document (page); | |
WebKitDOMDOMWindow *window = webkit_dom_document_get_default_view (document); | |
update_div_position (window); | |
webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (window), "resize", G_CALLBACK (on_resize), false, NULL); | |
webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (window), "scroll", G_CALLBACK (update_div_position), false, NULL); | |
} | |
static void | |
on_page_created (WebKitWebExtension *extension, | |
WebKitWebPage *p) | |
{ | |
page = p; | |
g_signal_connect (page, "document-loaded", G_CALLBACK (on_document_loaded), NULL); | |
} | |
static void | |
on_bus_acquired (GDBusConnection *con, | |
const gchar *name) | |
{ | |
GError *error = NULL; | |
connection = con; | |
GDBusNodeInfo *node = g_dbus_node_info_new_for_xml (introspection_xml, &error); | |
if (node == NULL) | |
goto fail; | |
interface = g_dbus_node_info_lookup_interface (node, | |
BUS_INTERFACE_NAME); | |
if (interface == NULL) | |
goto fail; | |
bus_id = g_dbus_connection_register_object (connection, | |
"/com/endlessm/webviewdemo", | |
interface, | |
NULL, | |
NULL, | |
NULL, | |
&error); | |
if (bus_id == 0) | |
goto fail; | |
return; | |
fail: | |
if (error != NULL) | |
{ | |
g_critical ("Error hooking up web extension DBus interface: %s", | |
error->message); | |
g_clear_error (&error); | |
} | |
else | |
{ | |
g_critical ("Unknown error hooking up web extension DBus interface"); | |
} | |
} | |
static void | |
on_name_lost (GDBusConnection *connection, | |
const gchar *name) | |
{ | |
if (connection == NULL) { | |
g_error("Couldn't connect to DBus for name %s", name); | |
return; | |
} | |
if (!g_dbus_connection_unregister_object (connection, bus_id)) | |
g_critical ("Trouble unregistering object"); | |
} | |
void | |
webkit_web_extension_initialize (WebKitWebExtension *ext) | |
{ | |
extension = ext; | |
g_print ("IN THE WEB EXTENSION!!\n"); | |
g_signal_connect (extension, "page-created", | |
G_CALLBACK (on_page_created), NULL); | |
g_bus_own_name (G_BUS_TYPE_SESSION, | |
"com.endlessm.webviewdemo", | |
G_BUS_NAME_OWNER_FLAGS_NONE, | |
(GBusAcquiredCallback) on_bus_acquired, | |
NULL, | |
(GBusNameLostCallback) on_name_lost, | |
NULL, | |
NULL); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment