You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
391 lines
11 KiB
391 lines
11 KiB
diff --git a/src/screencast.c b/src/screencast.c
|
|
index 6b0014a..15f6a80 100644
|
|
--- a/src/screencast.c
|
|
+++ b/src/screencast.c
|
|
@@ -427,16 +427,20 @@ find_best_window_by_app_id_and_title (const char *app_id,
|
|
const char *title)
|
|
{
|
|
ShellIntrospect *shell_introspect = shell_introspect_get ();
|
|
+ GPtrArray *windows;
|
|
Window *best_match;
|
|
glong best_match_distance;
|
|
- GList *l;
|
|
|
|
best_match = NULL;
|
|
best_match_distance = G_MAXLONG;
|
|
|
|
- for (l = shell_introspect_get_windows (shell_introspect); l; l = l->next)
|
|
+ shell_introspect_ref_listeners (shell_introspect);
|
|
+ shell_introspect_wait_for_windows (shell_introspect);
|
|
+
|
|
+ windows = shell_introspect_get_windows (shell_introspect);
|
|
+ for (size_t i = 0; windows && i < windows->len; i++)
|
|
{
|
|
- Window *window = l->data;
|
|
+ Window *window = g_ptr_array_index (windows, i);
|
|
glong distance;
|
|
|
|
if (g_strcmp0 (window_get_app_id (window), app_id) != 0)
|
|
@@ -454,6 +458,8 @@ find_best_window_by_app_id_and_title (const char *app_id,
|
|
}
|
|
}
|
|
|
|
+ shell_introspect_unref_listeners (shell_introspect);
|
|
+
|
|
/* If even the best match's window title is too different, don't
|
|
* restore it.
|
|
*/
|
|
diff --git a/src/screencastwidget.c b/src/screencastwidget.c
|
|
index 9b30f2d..e95fee2 100644
|
|
--- a/src/screencastwidget.c
|
|
+++ b/src/screencastwidget.c
|
|
@@ -164,8 +164,7 @@ update_windows_list (ScreenCastWidget *widget)
|
|
GtkListBox *window_list = GTK_LIST_BOX (widget->window_list);
|
|
GtkWidget *toplevel;
|
|
GtkWidget *child;
|
|
- GList *windows;
|
|
- GList *l;
|
|
+ GPtrArray *windows;
|
|
|
|
child = gtk_widget_get_first_child (GTK_WIDGET (window_list));
|
|
while (child)
|
|
@@ -181,9 +180,9 @@ update_windows_list (ScreenCastWidget *widget)
|
|
return;
|
|
|
|
windows = shell_introspect_get_windows (widget->shell_introspect);
|
|
- for (l = windows; l; l = l->next)
|
|
+ for (size_t i = 0; windows && i < windows->len; i++)
|
|
{
|
|
- Window *window = l->data;
|
|
+ Window *window = g_ptr_array_index (windows, i);
|
|
GtkWidget *window_widget;
|
|
|
|
if (should_skip_window (window, GTK_WINDOW (toplevel)))
|
|
diff --git a/src/shellintrospect.c b/src/shellintrospect.c
|
|
index 1fa8b93..c2b288d 100644
|
|
--- a/src/shellintrospect.c
|
|
+++ b/src/shellintrospect.c
|
|
@@ -22,16 +22,6 @@
|
|
#include "shell-dbus.h"
|
|
#include "shellintrospect.h"
|
|
|
|
-enum
|
|
-{
|
|
- WINDOWS_CHANGED,
|
|
- ANIMATIONS_ENABLED_CHANGED,
|
|
-
|
|
- N_SIGNALS
|
|
-};
|
|
-
|
|
-static guint signals[N_SIGNALS];
|
|
-
|
|
struct _Window
|
|
{
|
|
uint64_t id;
|
|
@@ -50,7 +40,7 @@ struct _ShellIntrospect
|
|
|
|
unsigned int version;
|
|
|
|
- GList *windows;
|
|
+ GPtrArray *windows;
|
|
|
|
int num_listeners;
|
|
|
|
@@ -60,6 +50,16 @@ struct _ShellIntrospect
|
|
|
|
G_DEFINE_TYPE (ShellIntrospect, shell_introspect, G_TYPE_OBJECT)
|
|
|
|
+enum
|
|
+{
|
|
+ WINDOWS_CHANGED,
|
|
+ ANIMATIONS_ENABLED_CHANGED,
|
|
+
|
|
+ N_SIGNALS
|
|
+};
|
|
+
|
|
+static guint signals[N_SIGNALS];
|
|
+
|
|
static ShellIntrospect *_shell_introspect;
|
|
|
|
static void
|
|
@@ -70,50 +70,36 @@ window_free (Window *window)
|
|
g_free (window);
|
|
}
|
|
|
|
-const char *
|
|
-window_get_title (Window *window)
|
|
-{
|
|
- return window->title;
|
|
-}
|
|
-
|
|
-const char *
|
|
-window_get_app_id (Window *window)
|
|
-{
|
|
- return window->app_id;
|
|
-}
|
|
-
|
|
-const uint64_t
|
|
-window_get_id (Window *window)
|
|
-{
|
|
- return window->id;
|
|
-}
|
|
-
|
|
static void
|
|
get_windows_cb (GObject *source_object,
|
|
GAsyncResult *res,
|
|
gpointer user_data)
|
|
{
|
|
ShellIntrospect *shell_introspect = user_data;
|
|
+ g_autoptr(GPtrArray) windows = NULL;
|
|
g_autoptr(GVariant) windows_variant = NULL;
|
|
g_autoptr(GError) error = NULL;
|
|
GVariantIter iter;
|
|
uint64_t id;
|
|
GVariant *params = NULL;
|
|
- GList *windows = NULL;
|
|
|
|
- g_list_free_full (shell_introspect->windows, (GDestroyNotify) window_free);
|
|
- shell_introspect->windows = NULL;
|
|
+ g_clear_object (&shell_introspect->cancellable);
|
|
|
|
if (!org_gnome_shell_introspect_call_get_windows_finish (shell_introspect->proxy,
|
|
&windows_variant,
|
|
res,
|
|
&error))
|
|
{
|
|
- g_warning ("Failed to get window list: %s", error->message);
|
|
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
+ g_warning ("Failed to get window list: %s", error->message);
|
|
return;
|
|
}
|
|
|
|
g_variant_iter_init (&iter, windows_variant);
|
|
+
|
|
+ windows = g_ptr_array_new_full (g_variant_iter_n_children (&iter),
|
|
+ (GDestroyNotify) window_free);
|
|
+
|
|
while (g_variant_iter_loop (&iter, "{t@a{sv}}", &id, ¶ms))
|
|
{
|
|
char *app_id = NULL;
|
|
@@ -131,64 +117,30 @@ get_windows_cb (GObject *source_object,
|
|
.title = title,
|
|
.app_id = app_id
|
|
};
|
|
- windows = g_list_prepend (windows, window);
|
|
+ g_ptr_array_add (windows, window);
|
|
|
|
g_clear_pointer (¶ms, g_variant_unref);
|
|
}
|
|
|
|
- shell_introspect->windows = windows;
|
|
+ shell_introspect->windows = g_steal_pointer (&windows);
|
|
g_signal_emit (shell_introspect, signals[WINDOWS_CHANGED], 0);
|
|
}
|
|
|
|
static void
|
|
sync_state (ShellIntrospect *shell_introspect)
|
|
{
|
|
+ g_clear_pointer (&shell_introspect->windows, g_ptr_array_unref);
|
|
+
|
|
+ g_cancellable_cancel (shell_introspect->cancellable);
|
|
+ g_clear_object (&shell_introspect->cancellable);
|
|
+ shell_introspect->cancellable = g_cancellable_new ();
|
|
+
|
|
org_gnome_shell_introspect_call_get_windows (shell_introspect->proxy,
|
|
shell_introspect->cancellable,
|
|
get_windows_cb,
|
|
shell_introspect);
|
|
}
|
|
|
|
-GList *
|
|
-shell_introspect_get_windows (ShellIntrospect *shell_introspect)
|
|
-{
|
|
- return shell_introspect->windows;
|
|
-}
|
|
-
|
|
-void
|
|
-shell_introspect_ref_listeners (ShellIntrospect *shell_introspect)
|
|
-{
|
|
- shell_introspect->num_listeners++;
|
|
-
|
|
- if (shell_introspect->proxy)
|
|
- sync_state (shell_introspect);
|
|
-}
|
|
-
|
|
-void
|
|
-shell_introspect_unref_listeners (ShellIntrospect *shell_introspect)
|
|
-{
|
|
- g_return_if_fail (shell_introspect->num_listeners > 0);
|
|
-
|
|
- shell_introspect->num_listeners--;
|
|
- if (shell_introspect->num_listeners == 0)
|
|
- {
|
|
- g_list_free_full (shell_introspect->windows,
|
|
- (GDestroyNotify) window_free);
|
|
- shell_introspect->windows = NULL;
|
|
- }
|
|
-}
|
|
-
|
|
-gboolean
|
|
-shell_introspect_are_animations_enabled (ShellIntrospect *shell_introspect,
|
|
- gboolean *out_animations_enabled)
|
|
-{
|
|
- if (!shell_introspect->animations_enabled_valid)
|
|
- return FALSE;
|
|
-
|
|
- *out_animations_enabled = shell_introspect->animations_enabled;
|
|
- return TRUE;
|
|
-}
|
|
-
|
|
static void
|
|
on_windows_changed_cb (GDBusProxy *proxy,
|
|
ShellIntrospect *shell_introspect)
|
|
@@ -291,6 +243,29 @@ on_shell_introspect_name_vanished (GDBusConnection *connection,
|
|
}
|
|
}
|
|
|
|
+static void
|
|
+shell_introspect_class_init (ShellIntrospectClass *klass)
|
|
+{
|
|
+ signals[WINDOWS_CHANGED] = g_signal_new ("windows-changed",
|
|
+ G_TYPE_FROM_CLASS (klass),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ 0,
|
|
+ NULL, NULL, NULL,
|
|
+ G_TYPE_NONE, 0);
|
|
+ signals[ANIMATIONS_ENABLED_CHANGED] =
|
|
+ g_signal_new ("animations-enabled-changed",
|
|
+ G_TYPE_FROM_CLASS (klass),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ 0,
|
|
+ NULL, NULL, NULL,
|
|
+ G_TYPE_NONE, 0);
|
|
+}
|
|
+
|
|
+static void
|
|
+shell_introspect_init (ShellIntrospect *shell_introspect)
|
|
+{
|
|
+}
|
|
+
|
|
ShellIntrospect *
|
|
shell_introspect_get (void)
|
|
{
|
|
@@ -311,25 +286,67 @@ shell_introspect_get (void)
|
|
return shell_introspect;
|
|
}
|
|
|
|
-static void
|
|
-shell_introspect_init (ShellIntrospect *shell_introspect)
|
|
+GPtrArray *
|
|
+shell_introspect_get_windows (ShellIntrospect *shell_introspect)
|
|
{
|
|
+ return shell_introspect->windows;
|
|
}
|
|
|
|
-static void
|
|
-shell_introspect_class_init (ShellIntrospectClass *klass)
|
|
+void
|
|
+shell_introspect_ref_listeners (ShellIntrospect *shell_introspect)
|
|
{
|
|
- signals[WINDOWS_CHANGED] = g_signal_new ("windows-changed",
|
|
- G_TYPE_FROM_CLASS (klass),
|
|
- G_SIGNAL_RUN_LAST,
|
|
- 0,
|
|
- NULL, NULL, NULL,
|
|
- G_TYPE_NONE, 0);
|
|
- signals[ANIMATIONS_ENABLED_CHANGED] =
|
|
- g_signal_new ("animations-enabled-changed",
|
|
- G_TYPE_FROM_CLASS (klass),
|
|
- G_SIGNAL_RUN_LAST,
|
|
- 0,
|
|
- NULL, NULL, NULL,
|
|
- G_TYPE_NONE, 0);
|
|
+ shell_introspect->num_listeners++;
|
|
+
|
|
+ if (shell_introspect->proxy)
|
|
+ sync_state (shell_introspect);
|
|
+}
|
|
+
|
|
+void
|
|
+shell_introspect_unref_listeners (ShellIntrospect *shell_introspect)
|
|
+{
|
|
+ g_return_if_fail (shell_introspect->num_listeners > 0);
|
|
+
|
|
+ shell_introspect->num_listeners--;
|
|
+ if (shell_introspect->num_listeners == 0)
|
|
+ g_clear_pointer (&shell_introspect->windows, g_ptr_array_unref);
|
|
+}
|
|
+
|
|
+const char *
|
|
+window_get_title (Window *window)
|
|
+{
|
|
+ return window->title;
|
|
+}
|
|
+
|
|
+const char *
|
|
+window_get_app_id (Window *window)
|
|
+{
|
|
+ return window->app_id;
|
|
+}
|
|
+
|
|
+const uint64_t
|
|
+window_get_id (Window *window)
|
|
+{
|
|
+ return window->id;
|
|
+}
|
|
+
|
|
+gboolean
|
|
+shell_introspect_are_animations_enabled (ShellIntrospect *shell_introspect,
|
|
+ gboolean *out_animations_enabled)
|
|
+{
|
|
+ if (!shell_introspect->animations_enabled_valid)
|
|
+ return FALSE;
|
|
+
|
|
+ *out_animations_enabled = shell_introspect->animations_enabled;
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+void
|
|
+shell_introspect_wait_for_windows (ShellIntrospect *shell_introspect)
|
|
+{
|
|
+ g_assert (shell_introspect->num_listeners > 0);
|
|
+
|
|
+ sync_state (shell_introspect);
|
|
+
|
|
+ while (!shell_introspect->windows)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
}
|
|
diff --git a/src/shellintrospect.h b/src/shellintrospect.h
|
|
index b187c4d..f63ecee 100644
|
|
--- a/src/shellintrospect.h
|
|
+++ b/src/shellintrospect.h
|
|
@@ -28,19 +28,21 @@ typedef struct _Window Window;
|
|
G_DECLARE_FINAL_TYPE (ShellIntrospect, shell_introspect,
|
|
SHELL, INTROSPECT, GObject)
|
|
|
|
+ShellIntrospect * shell_introspect_get (void);
|
|
+
|
|
+void shell_introspect_ref_listeners (ShellIntrospect *shell_introspect);
|
|
+
|
|
+void shell_introspect_unref_listeners (ShellIntrospect *shell_introspect);
|
|
+
|
|
const char * window_get_app_id (Window *window);
|
|
|
|
const char * window_get_title (Window *window);
|
|
|
|
const uint64_t window_get_id (Window *window);
|
|
|
|
-GList * shell_introspect_get_windows (ShellIntrospect *shell_introspect);
|
|
+GPtrArray * shell_introspect_get_windows (ShellIntrospect *shell_introspect);
|
|
|
|
-gboolean shell_introspect_are_animations_enabled (ShellIntrospect *introspect,
|
|
+gboolean shell_introspect_are_animations_enabled (ShellIntrospect *shell_introspect,
|
|
gboolean *enable_animations);
|
|
|
|
-void shell_introspect_ref_listeners (ShellIntrospect *shell_introspect);
|
|
-
|
|
-void shell_introspect_unref_listeners (ShellIntrospect *shell_introspect);
|
|
-
|
|
-ShellIntrospect * shell_introspect_get (void);
|
|
+void shell_introspect_wait_for_windows (ShellIntrospect *shell_introspect);
|