[epiphany/pgriffis/web-extension/windows: 8/8] WebExtensions: Implement windows.onCreated and windows.onRemoved
- From: Patrick Griffis <pgriffis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/pgriffis/web-extension/windows: 8/8] WebExtensions: Implement windows.onCreated and windows.onRemoved
- Date: Wed, 8 Jun 2022 17:51:05 +0000 (UTC)
commit 9f9ad3e5bc4e5cd860a111b915fccdfa2b9309db
Author: Patrick Griffis <pgriffis igalia com>
Date: Wed Jun 8 12:31:38 2022 -0500
WebExtensions: Implement windows.onCreated and windows.onRemoved
src/webextension/api/windows.c | 29 ++++++++++-----
src/webextension/api/windows.h | 15 +++++---
src/webextension/ephy-web-extension-manager.c | 51 +++++++++++++++++++++++++++
3 files changed, 81 insertions(+), 14 deletions(-)
---
diff --git a/src/webextension/api/windows.c b/src/webextension/api/windows.c
index 7a68e8fe1..2dba0c75e 100644
--- a/src/webextension/api/windows.c
+++ b/src/webextension/api/windows.c
@@ -25,8 +25,8 @@
#include "windows.h"
#include "tabs.h"
-static EphyWindow *
-get_window_for_id (int window_id)
+EphyWindow *
+ephy_web_extension_api_windows_get_window_for_id (gint64 window_id)
{
GList *windows;
@@ -42,7 +42,7 @@ get_window_for_id (int window_id)
return window;
}
- g_debug ("Failed to find window with id %d", window_id);
+ g_debug ("Failed to find window with id %ld", window_id);
return NULL;
}
@@ -112,6 +112,21 @@ add_window_to_json (EphyWebExtension *self,
json_builder_end_object (builder);
}
+char *
+ephy_web_extension_api_windows_create_window_json (EphyWebExtension *self,
+ EphyWindow *window)
+{
+ g_autoptr (JsonBuilder) builder = json_builder_new ();
+ g_autoptr (JsonNode) root = NULL;
+ add_window_to_json (self,
+ builder,
+ window,
+ TRUE);
+ root = json_builder_get_root (builder);
+ return json_to_string (root, FALSE);
+}
+
+
static char *
windows_handler_get (EphyWebExtension *self,
char *name,
@@ -124,7 +139,6 @@ windows_handler_get (EphyWebExtension *self,
g_autoptr (JsonBuilder) builder = json_builder_new ();
g_autoptr (JsonNode) root = NULL;
EphyWindow *window;
- int window_id;
gboolean populate_tabs = FALSE;
if (!jsc_value_is_number (window_id_value)) {
@@ -132,8 +146,7 @@ windows_handler_get (EphyWebExtension *self,
return NULL;
}
- window_id = jsc_value_to_int32 (window_id_value);
- window = get_window_for_id (window_id);
+ window = ephy_web_extension_api_windows_get_window_for_id (jsc_value_to_int32 (window_id_value));
if (!window) {
g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_INVALID_ARGUMENT, "window.get():
Failed to find window by id");
@@ -312,15 +325,13 @@ windows_handler_remove (EphyWebExtension *self,
{
g_autoptr (JSCValue) window_id_value = jsc_value_object_get_property_at_index (args, 0);
EphyWindow *window;
- int window_id;
if (!jsc_value_is_number (window_id_value)) {
g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_INVALID_ARGUMENT, "window.remove():
First argument is not a windowId");
return NULL;
}
- window_id = jsc_value_to_int32 (window_id_value);
- window = get_window_for_id (window_id);
+ window = ephy_web_extension_api_windows_get_window_for_id (jsc_value_to_int32 (window_id_value));
if (!window) {
g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_INVALID_ARGUMENT, "window.remove():
Failed to find window by id");
diff --git a/src/webextension/api/windows.h b/src/webextension/api/windows.h
index e1dcbee54..a89ba50ab 100644
--- a/src/webextension/api/windows.h
+++ b/src/webextension/api/windows.h
@@ -26,10 +26,15 @@
G_BEGIN_DECLS
-void ephy_web_extension_api_windows_handler (EphyWebExtension *self,
- char *name,
- JSCValue *value,
- WebKitWebView *web_view,
- GTask *task);
+void ephy_web_extension_api_windows_handler (EphyWebExtension *self,
+ char *name,
+ JSCValue *value,
+ WebKitWebView *web_view,
+ GTask *task);
+
+char *ephy_web_extension_api_windows_create_window_json (EphyWebExtension *self,
+ EphyWindow *window);
+
+EphyWindow *ephy_web_extension_api_windows_get_window_for_id (gint64 window_id);
G_END_DECLS
diff --git a/src/webextension/ephy-web-extension-manager.c b/src/webextension/ephy-web-extension-manager.c
index fd9d331a5..e1710e472 100644
--- a/src/webextension/ephy-web-extension-manager.c
+++ b/src/webextension/ephy-web-extension-manager.c
@@ -1209,6 +1209,52 @@ extension_equal (gconstpointer a,
return g_strcmp0 (a, b) == 0;
}
+typedef struct {
+ EphyWebExtension *web_extension;
+ guint64 window_id;
+} WindowAddedCallbackData;
+
+static gboolean
+application_window_added_timeout_cb (gpointer user_data)
+{
+ WindowAddedCallbackData *data = user_data;
+ EphyWebExtensionManager *manager = ephy_web_extension_manager_get_default ();
+ EphyWindow *window = ephy_web_extension_api_windows_get_window_for_id (data->window_id);
+ g_autofree char *window_json = NULL;
+
+ /* It is possible the window was removed before this timeout. */
+ if (!window)
+ return G_SOURCE_REMOVE;
+
+ window_json = ephy_web_extension_api_windows_create_window_json (data->web_extension, window);
+ ephy_web_extension_manager_emit_in_extension_views (manager, data->web_extension, "windows.onCreated",
window_json);
+ return G_SOURCE_REMOVE;
+}
+
+static void
+application_window_added_cb (EphyShell *shell,
+ EphyWindow *window,
+ EphyWebExtension *web_extension)
+{
+ /* At this point the EphyWindow has no EphyEmbed child so we can't get information from it.
+ * We also can't really know ahead of time if multiple tabs are opening so simply adding a delay
+ * tends to give accurate results. */
+ WindowAddedCallbackData *data = g_new (WindowAddedCallbackData, 1);
+ data->window_id = ephy_window_get_uid (window);
+ data->web_extension = web_extension;
+ g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE, 1, application_window_added_timeout_cb, data, g_free);
+}
+
+static void
+application_window_removed_cb (EphyShell *shell,
+ EphyWindow *window,
+ EphyWebExtension *web_extension)
+{
+ EphyWebExtensionManager *manager = ephy_web_extension_manager_get_default ();
+ g_autofree char *window_json = g_strdup_printf ("%ld", ephy_window_get_uid (window));
+ ephy_web_extension_manager_emit_in_extension_views (manager, web_extension, "windows.onRemoved",
window_json);
+}
+
void
ephy_web_extension_manager_set_active (EphyWebExtensionManager *self,
EphyWebExtension *web_extension,
@@ -1248,9 +1294,14 @@ ephy_web_extension_manager_set_active (EphyWebExtensionManager *self,
}
if (active) {
+ g_signal_connect (shell, "window-added", G_CALLBACK (application_window_added_cb), web_extension);
+ g_signal_connect (shell, "window-removed", G_CALLBACK (application_window_removed_cb), web_extension);
+
if (ephy_web_extension_has_background_web_view (web_extension))
run_background_script (self, web_extension);
} else {
+ g_signal_handlers_disconnect_by_data (shell, web_extension);
+
g_hash_table_remove (self->browser_action_map, web_extension);
g_hash_table_remove (self->background_web_views, web_extension);
g_object_set_data (G_OBJECT (web_extension), "alarms", NULL); /* Set in alarms.c */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]