jeudi 30 juillet 2020

Application aborts when webkit_web_view_run_javascript is called

I have a c++11 application that utilizes webkit and gtkmm. I've created a window application containing a container with a webview inside. I'm able to navigate to a URL without issue; however, when I attempt to call webkit_web_view_run_javascript(webview, script, NULL, web_view_javascript_finished, NULL); the application aborts. Has anyone ran into the same issue? I'm really at a loss here. I've tried everything I can think of, and searched google and bing for days.

The breakdown of how the program works is:

  • start main
    • start logic thread
    • detach logic thread
      • waits for webview to initialize
      • waits for home page to be loaded
      • runs javascript against home page
    • start webview thread
    • join webview thread

Some code is redacted and URIs are changd. I.E. https://www.google.com/ is not the actual home page and text encapsulated in [] are changed/shortened for ease of reading.

Here is the webkit code:

        WebKitWebView * webview;
        WebKitSettings * webview_settings;
        bool home_page_loaded;
        void start(const int width, const int height, const std::string name, const std::string title, const bool full_screen, const std::string uri, int argc, char** argv)
        {
            // Create application
            auto application = Gtk::Application::create(argc, argv, name);
            // Create window
            Gtk::Window window;
            window.set_default_size(width, height);
            window.set_title(title);
            // Create webview
            this->webview = WEBKIT_WEB_VIEW(webkit_web_view_new());
            // Create container and place webview inside
            Gtk::Widget * container;
            container = Glib::wrap(GTK_WIDGET(webview));
            // Add container to window
            window.add(*container);
            // Create webview settings
            this->webview_settings = webkit_settings_new();
            // Enable javascript for webview
            g_object_set(this->webview_settings, "enable-javascript", TRUE, NULL);
            // Bind load_handler to load-changed signal
            g_signal_connect(this->webview, "load-changed", G_CALLBACK(this->load_handler), NULL);
            // Apply settings to webview
            webkit_web_view_set_settings(this->webview, this->webview_settings);
            // Place window in full screen if necessary
            if (full_screen)
            {
                window.fullscreen();
            }
            // Navigate to URI
            gchar *g_uri = g_strdup_printf(uri.c_str());
            webkit_web_view_load_uri(this->webview, g_uri);
            // Show all components within window
            window.show_all();
            // Run window application
            application->run(window);
        }
        void run_javascript(const std::string script)
        {

            gchar *g_script = g_strdup_printf(script.c_str());
            webkit_web_view_run_javascript(this->webview, g_script, NULL, web_view_javascript_finished, NULL);
            std::cout << "finished running javascript" << std::endl;
        }
        static void
        web_view_javascript_finished (GObject      *object,
                                    GAsyncResult *result,
                                    gpointer      user_data)
        {
            WebKitJavascriptResult *js_result;
            JSCValue               *value;
            GError                 *error = NULL;

            js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (object), result, &error);
            if (!js_result) {
                g_warning ("Error running javascript: %s", error->message);
                g_error_free (error);
                return;
            }

            value = webkit_javascript_result_get_js_value (js_result);
            if (jsc_value_is_string (value)) {
                JSCException *exception;
                gchar        *str_value;

                str_value = jsc_value_to_string (value);
                exception = jsc_context_get_exception (jsc_value_get_context (value));
                if (exception)
                    g_warning ("Error running javascript: %s", jsc_exception_get_message (exception));
                else
                    g_print ("Script result: %s\n", str_value);
                g_free (str_value);
            } else {
                g_warning ("Error running javascript: unexpected return value");
            }
            webkit_javascript_result_unref (js_result);
        }
        static void load_handler (WebKitWebView *webview,
                                WebKitLoadEvent load_event,
                                gpointer data)
        {
            switch (load_event) {
                case WEBKIT_LOAD_STARTED:
                    // Do something here later...
                    break;
                case WEBKIT_LOAD_REDIRECTED:
                    // Do something here later...
                    break;
                case WEBKIT_LOAD_COMMITTED:
                    // Do something here later...
                    break;
                case WEBKIT_LOAD_FINISHED:
                    // Get current URI of webview
                    std::string loaded_uri = webkit_web_view_get_uri(webview);
                    // Set p_is_playing based on URI
                    if (loaded_uri == g_strdup_printf("https://www.google.com/"))
                    {
                        home_page_loaded = true;
                    }
                    else
                    {
                        home_page_loaded = false;
                    }
                    break;
            }
        }

Here is how it's implemented in main and how the run_javascript function is called:

bool web_started = false;

void web_handler(std::string uri, int argc, char** argv)
{
    web_started = true;
    //initialize
    web_helper.start(1920, 1080, "Some.Name", "Some Name", true, uri, argc, argv);
}
[some void here]
[some logic here]
    javascript = "window.document.getElementById('pop-up').style.display = 'none';";
    web_helper.run_javascript(javascript);
[end some logic here]
[end some void here]
int main(int argc, char** argv)
{
    std::string uri = "https://www.google.com/"
    std::thread logic_thread([some logic thread]);
    logic_thread.detach();
    std::thread web_thread(web_handler, uri, argc, argv);
    web_thread.join();
}

Aucun commentaire:

Enregistrer un commentaire