URI: 
       webext: Exchange fd over webkit messages - surf - surf browser, a WebKit based browser
  HTML git clone git://git.suckless.org/surf
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 665a709b522a6fa18c671f1fc41297603292d0e8
   DIR parent 609ea1c8e620ed38e71bf03a46a759c042e76500
  HTML Author: Quentin Rameau <quinq@fifth.space>
       Date:   Sun, 16 Oct 2022 17:39:05 +0200
       
       webext: Exchange fd over webkit messages
       
       This is more complex, but webkit2gtk prevents passing file descriptors
       to processes in 2.38.0.
       
       Diffstat:
         M surf.c                              |      36 ++++++++++++++++++++++++-------
         M webext-surf.c                       |      42 +++++++++++++++++++++++++++----
       
       2 files changed, 65 insertions(+), 13 deletions(-)
       ---
   DIR diff --git a/surf.c b/surf.c
       @@ -214,6 +214,8 @@ static void downloadstarted(WebKitWebContext *wc, WebKitDownload *d,
                                    Client *c);
        static void responsereceived(WebKitDownload *d, GParamSpec *ps, Client *c);
        static void download(Client *c, WebKitURIResponse *r);
       +static gboolean viewusrmsgrcv(WebKitWebView *v, WebKitUserMessage *m,
       +                              gpointer u);
        static void webprocessterminated(WebKitWebView *v,
                                         WebKitWebProcessTerminationReason r,
                                         Client *c);
       @@ -1224,6 +1226,8 @@ newview(Client *c, WebKitWebView *rv)
                                 G_CALLBACK(permissionrequested), c);
                g_signal_connect(G_OBJECT(v), "ready-to-show",
                                 G_CALLBACK(showview), c);
       +        g_signal_connect(G_OBJECT(v), "user-message-received",
       +                         G_CALLBACK(viewusrmsgrcv), c);
                g_signal_connect(G_OBJECT(v), "web-process-terminated",
                                 G_CALLBACK(webprocessterminated), c);
        
       @@ -1262,14 +1266,6 @@ readsock(GIOChannel *s, GIOCondition ioc, gpointer unused)
        void
        initwebextensions(WebKitWebContext *wc, Client *c)
        {
       -        GVariant *gv;
       -
       -        if (spair[1] < 0)
       -                return;
       -
       -        gv = g_variant_new("i", spair[1]);
       -
       -        webkit_web_context_set_web_extensions_initialization_user_data(wc, gv);
                webkit_web_context_set_web_extensions_directory(wc, WEBEXTDIR);
        }
        
       @@ -1572,6 +1568,30 @@ titlechanged(WebKitWebView *view, GParamSpec *ps, Client *c)
                updatetitle(c);
        }
        
       +gboolean
       +viewusrmsgrcv(WebKitWebView *v, WebKitUserMessage *m, gpointer unused)
       +{
       +        WebKitUserMessage *r;
       +        GUnixFDList *gfd;
       +        const char *name;
       +
       +        name = webkit_user_message_get_name(m);
       +        if (strcmp(name, "page-created") != 0) {
       +                fprintf(stderr, "surf: Unknown UserMessage: %s\n", name);
       +                return TRUE;
       +        }
       +
       +        if (spair[1] < 0)
       +                return TRUE;
       +
       +        gfd = g_unix_fd_list_new_from_array(&spair[1], 1);
       +        r = webkit_user_message_new_with_fd_list("surf-pipe", NULL, gfd);
       +
       +        webkit_user_message_send_reply(m, r);
       +
       +        return TRUE;
       +}
       +
        void
        mousetargetchanged(WebKitWebView *v, WebKitHitTestResult *h, guint modifiers,
            Client *c)
   DIR diff --git a/webext-surf.c b/webext-surf.c
       @@ -87,15 +87,29 @@ readsock(GIOChannel *s, GIOCondition c, gpointer unused)
                return TRUE;
        }
        
       -G_MODULE_EXPORT void
       -webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e,
       -                                               const GVariant *gv)
       +static void
       +pageusermessagereply(GObject *o, GAsyncResult *r, gpointer page)
        {
       +        WebKitUserMessage *m;
       +        GUnixFDList *gfd;
                GIOChannel *gchansock;
       +        const char *name;
       +        int nfd;
        
       -        webext = e;
       +        m = webkit_web_page_send_message_to_view_finish(page, r, NULL);
       +        name = webkit_user_message_get_name(m);
       +        if (strcmp(name, "surf-pipe") != 0) {
       +                fprintf(stderr, "webext-surf: Unknown User Reply: %s\n", name);
       +                return;
       +        }
        
       -        g_variant_get(gv, "i", &sock);
       +        gfd = webkit_user_message_get_fd_list(m);
       +        if ((nfd = g_unix_fd_list_get_length(gfd)) != 1) {
       +                fprintf(stderr, "webext-surf: Too many file-descriptors: %d\n", nfd);
       +                return;
       +        }
       +
       +        sock = g_unix_fd_list_get(gfd, 0, NULL);
        
                gchansock = g_io_channel_unix_new(sock);
                g_io_channel_set_encoding(gchansock, NULL, NULL);
       @@ -104,3 +118,21 @@ webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e,
                g_io_channel_set_close_on_unref(gchansock, TRUE);
                g_io_add_watch(gchansock, G_IO_IN, readsock, NULL);
        }
       +
       +void
       +pagecreated(WebKitWebExtension *e, WebKitWebPage *p, gpointer unused)
       +{
       +        WebKitUserMessage *msg;
       +
       +        msg = webkit_user_message_new("page-created", NULL);
       +        webkit_web_page_send_message_to_view(p, msg, NULL, pageusermessagereply, p);
       +}
       +
       +G_MODULE_EXPORT void
       +webkit_web_extension_initialize(WebKitWebExtension *e)
       +{
       +        webext = e;
       +
       +        g_signal_connect(G_OBJECT(e), "page-created",
       +                         G_CALLBACK(pagecreated), NULL);
       +}