[hotssh] Hook GNOME Shell search provider up to tab hostnames
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [hotssh] Hook GNOME Shell search provider up to tab hostnames
- Date: Sat, 16 Nov 2013 23:40:11 +0000 (UTC)
commit e5bcc7b38780cbc53e4a0a9ec3d67104c42ff971
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Thu Nov 14 22:15:34 2013 -0500
Hook GNOME Shell search provider up to tab hostnames
Search windows and tabs for a tab with a hostname that matches the
search string, and switch to that tab and window when the search
result is activated.
Currently, when multiple tabs match, only one search result is shown
and a random tab is selected; it's probably best to switch to the
last-active tab for that hostname rather than a random one.
https://bugzilla.gnome.org/show_bug.cgi?id=712345
Makefile-src.am | 1 +
src/hotssh-search-provider.c | 148 +++++++++++++++++++++++++++++-----------
src/hotssh-search-provider.ini | 5 ++
src/hotssh-tab.c | 11 +++
src/hotssh-tab.h | 2 +
src/hotssh-win.c | 25 +++++++
src/hotssh-win.h | 6 ++
7 files changed, 159 insertions(+), 39 deletions(-)
---
diff --git a/Makefile-src.am b/Makefile-src.am
index a041221..98615fb 100644
--- a/Makefile-src.am
+++ b/Makefile-src.am
@@ -13,6 +13,7 @@ hotssh_dbus_h_files += hotssh-search-glue.h
hotssh_dbus_c_files += hotssh-search-glue.c
BUILT_SOURCES += $(hotssh_dbus_h_files) $(hotssh_dbus_c_files)
+CLEANFILES += hotssh-search-glue.h hotssh-search-glue.c
hotssh_headers = $(addprefix src/, \
hotssh-app.h \
diff --git a/src/hotssh-search-provider.c b/src/hotssh-search-provider.c
index 285e5a3..b7efd7f 100644
--- a/src/hotssh-search-provider.c
+++ b/src/hotssh-search-provider.c
@@ -23,6 +23,10 @@
#include "hotssh-search-provider.h"
#include "hotssh-search-glue.h"
+#include "hotssh-tab.h"
+#include "hotssh-win.h"
+
+#include "libgsystem.h"
struct _HotSshSearchProvider
{
@@ -46,28 +50,78 @@ struct _HotSshSearchProviderPrivate
G_DEFINE_TYPE_WITH_PRIVATE(HotSshSearchProvider, hotssh_search_provider, G_TYPE_OBJECT)
static char **
-get_results (HotSshSearchProvider *search_provider,
- char **terms)
+get_open_servers (HotSshSearchProvider *search_provider)
{
- char **term;
- gboolean match = TRUE;
-
- for (term = terms; *term; term++)
+ HotSshSearchProviderPrivate *priv = hotssh_search_provider_get_instance_private (search_provider);
+ gs_unref_hashtable GHashTable *servers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ GList *windows;
+ GList *l;
+ gchar **result;
+ GHashTableIter iter;
+ gpointer key;
+ int i;
+
+ windows = gtk_application_get_windows (GTK_APPLICATION (priv->app));
+ for (l = windows; l; l = l->next)
{
- if (strstr ("foo.example.com", *term) == NULL)
- match = FALSE;
+ if (HOTSSH_IS_WINDOW (l->data))
+ {
+ HotSshWindow *window = l->data;
+ GList *tabs = hotssh_window_get_tabs (window);
+ GList *ll;
+
+ for (ll = tabs; ll; ll = ll->next)
+ {
+ HotSshTab *tab = ll->data;
+ const char *hostname = hotssh_tab_get_hostname (tab);
+ if (hostname != NULL)
+ g_hash_table_replace (servers, g_strdup (hostname), GUINT_TO_POINTER (1));
+ }
+
+ g_list_free (tabs);
+ }
}
- if (match)
+ result = g_new (char *, g_hash_table_size (servers) + 1);
+
+ i = 0;
+ g_hash_table_iter_init (&iter, servers);
+ while (g_hash_table_iter_next (&iter, &key, NULL))
{
- const char * const results[] = { "foo.example.com", NULL };
- return g_strdupv ((char **)results);
+ result[i] = g_strdup (key);
+ i++;
}
- else
+ result[i] = NULL;
+
+ return result;
+}
+
+static char **
+get_results (HotSshSearchProvider *search_provider,
+ char **terms)
+{
+ gs_strfreev char **open_servers = get_open_servers (search_provider);
+ GPtrArray *matches = g_ptr_array_new ();
+ char **server;
+
+ for (server = open_servers; *server; server++)
{
- const char * const results[] = { NULL };
- return g_strdupv ((char **)results);
+ char **term;
+ gboolean match = TRUE;
+
+ for (term = terms; *term; term++)
+ {
+ if (strstr (*server, *term) == NULL)
+ match = FALSE;
+ }
+
+ if (match)
+ g_ptr_array_add (matches, g_strdup (*server));
}
+
+ g_ptr_array_add (matches, NULL);
+
+ return (char **)g_ptr_array_free (matches, FALSE);
}
static gboolean
@@ -76,9 +130,8 @@ handle_get_initial_result_set (HotSshSearchShellSearchProvider2 *skeleton,
char **terms,
HotSshSearchProvider *search_provider)
{
- char **results = get_results (search_provider, terms);
+ gs_strfreev char **results = get_results (search_provider, terms);
hot_ssh_search_shell_search_provider2_complete_get_initial_result_set (skeleton, invocation, (const char *
const *)results);
- g_strfreev (results);
return TRUE;
}
@@ -90,9 +143,8 @@ handle_get_subsearch_result_set (HotSshSearchShellSearchProvider2 *skeleton,
char **terms,
HotSshSearchProvider *search_provider)
{
- char **results = get_results (search_provider, terms);
+ gs_strfreev char **results = get_results (search_provider, terms);
hot_ssh_search_shell_search_provider2_complete_get_subsearch_result_set (skeleton, invocation, (const char
* const *)results);
- g_strfreev (results);
return TRUE;
}
@@ -111,30 +163,23 @@ handle_get_result_metas (HotSshSearchShellSearchProvider2 *skeleton,
for (p = identifiers; *p; p++)
{
const char *id = *p;
- if (g_strcmp0 (id, "foo.example.com") == 0)
- {
- GVariantBuilder *b2 = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
- GIcon *icon;
- GVariant *serialized_icon;
- gchar *string_icon;
-
- g_variant_builder_add (b2, "{sv}", "id", g_variant_new_string (id));
- g_variant_builder_add (b2, "{sv}", "name", g_variant_new_string ("foo.example.com"));
+ GVariantBuilder *b2 = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+ gs_unref_object GIcon *icon;
+ gs_unref_variant GVariant *serialized_icon;
+ gs_free gchar *string_icon;
- icon = g_themed_icon_new ("gnome-terminal");
+ g_variant_builder_add (b2, "{sv}", "id", g_variant_new_string (id));
+ g_variant_builder_add (b2, "{sv}", "name", g_variant_new_string (id));
- serialized_icon = g_icon_serialize (icon);
- g_variant_builder_add (b2, "{sv}", "icon", serialized_icon);
- g_variant_unref (serialized_icon);
- string_icon = g_icon_to_string (icon);
- g_variant_builder_add (b2, "{sv}", "gicon", g_variant_new_string (string_icon));
- g_free (string_icon);
+ icon = g_themed_icon_new ("hotssh");
- g_object_unref (icon);
+ serialized_icon = g_icon_serialize (icon);
+ g_variant_builder_add (b2, "{sv}", "icon", serialized_icon);
- g_variant_builder_add_value (b1, g_variant_builder_end (b2));
- }
+ string_icon = g_icon_to_string (icon);
+ g_variant_builder_add (b2, "{sv}", "gicon", g_variant_new_string (string_icon));
+ g_variant_builder_add_value (b1, g_variant_builder_end (b2));
}
metas = g_variant_builder_end (b1);
@@ -151,9 +196,34 @@ handle_activate_result (HotSshSearchShellSearchProvider2 *skeleton,
guint timestamp,
HotSshSearchProvider *search_provider)
{
- if (g_strcmp0 (identifier, "foo.example.com") == 0)
+ HotSshSearchProviderPrivate *priv = hotssh_search_provider_get_instance_private (search_provider);
+ GList *windows;
+ GList *l;
+ gboolean found = FALSE;
+
+ windows = gtk_application_get_windows (GTK_APPLICATION (priv->app));
+ for (l = windows; l && !found; l = l->next)
{
- g_print ("Open up the Foo server!\n");
+ if (HOTSSH_IS_WINDOW (l->data))
+ {
+ HotSshWindow *window = l->data;
+ GList *tabs = hotssh_window_get_tabs (window);
+ GList *ll;
+
+ for (ll = tabs; ll && !found; ll = ll->next)
+ {
+ HotSshTab *tab = ll->data;
+ const char *hostname = hotssh_tab_get_hostname (tab);
+ if (g_strcmp0 (hostname, identifier) == 0)
+ {
+ hotssh_window_activate_tab (window, tab);
+ gtk_window_present_with_time ((GtkWindow *)window, timestamp);
+ found = TRUE;
+ }
+ }
+
+ g_list_free (tabs);
+ }
}
hot_ssh_search_shell_search_provider2_complete_activate_result (skeleton, invocation);
diff --git a/src/hotssh-search-provider.ini b/src/hotssh-search-provider.ini
new file mode 100644
index 0000000..5ad7459
--- /dev/null
+++ b/src/hotssh-search-provider.ini
@@ -0,0 +1,5 @@
+[Shell Search Provider]
+DesktopId=hotssh.desktop
+BusName=org.gnome.HotSSH
+ObjectPath=/org/gnome/hotssh/SearchProvider
+Version=2
diff --git a/src/hotssh-tab.c b/src/hotssh-tab.c
index 1fc630f..1fb0b54 100644
--- a/src/hotssh-tab.c
+++ b/src/hotssh-tab.c
@@ -79,6 +79,7 @@ struct _HotSshTabPrivate
HotSshTabPage active_page;
guint authmechanism_index;
+ char *hostname;
GSocketConnectable *address;
GSshConnection *connection;
GSshChannel *channel;
@@ -119,6 +120,7 @@ state_reset_for_new_connection (HotSshTab *self)
{
HotSshTabPrivate *priv = hotssh_tab_get_instance_private (self);
g_debug ("reset state");
+ g_clear_pointer (&priv->hostname, g_free);
g_clear_object (&priv->address);
g_clear_object (&priv->connection);
g_clear_object (&priv->cancellable);
@@ -442,6 +444,8 @@ on_connect (GtkButton *button,
return;
}
+ priv->hostname = g_strdup (hostname);
+
g_clear_object (&priv->connection);
priv->connection = gssh_connection_new (priv->address, username);
gssh_connection_set_interaction (priv->connection, (GTlsInteraction*)priv->password_interaction);
@@ -746,3 +750,10 @@ hotssh_tab_disconnect (HotSshTab *self)
page_transition (self, HOTSSH_TAB_PAGE_NEW_CONNECTION);
gtk_notebook_set_current_page ((GtkNotebook*)self, 0);
}
+
+const char *
+hotssh_tab_get_hostname (HotSshTab *self)
+{
+ HotSshTabPrivate *priv = hotssh_tab_get_instance_private (self);
+ return priv->hostname;
+}
diff --git a/src/hotssh-tab.h b/src/hotssh-tab.h
index 4a5634c..5d31760 100644
--- a/src/hotssh-tab.h
+++ b/src/hotssh-tab.h
@@ -34,3 +34,5 @@ HotSshTab *hotssh_tab_new (void);
HotSshTab *hotssh_tab_new_channel (HotSshTab *source);
void hotssh_tab_disconnect (HotSshTab *source);
+
+const char * hotssh_tab_get_hostname (HotSshTab *self);
diff --git a/src/hotssh-win.c b/src/hotssh-win.c
index 09b6a9b..0712c9c 100644
--- a/src/hotssh-win.c
+++ b/src/hotssh-win.c
@@ -244,3 +244,28 @@ hotssh_window_new (HotSshApp *app)
{
return g_object_new (HOTSSH_TYPE_WINDOW, "application", app, NULL);
}
+
+GList *
+hotssh_window_get_tabs (HotSshWindow *self)
+{
+ HotSshWindowPrivate *priv = hotssh_window_get_instance_private (self);
+ GList *tabs = NULL;
+ gint n_pages, i;
+
+ n_pages = gtk_notebook_get_n_pages ((GtkNotebook*)priv->main_notebook);
+ for (i = 0; i < n_pages; i++)
+ tabs = g_list_prepend (tabs, gtk_notebook_get_nth_page ((GtkNotebook*)priv->main_notebook, i));
+
+ return g_list_reverse (tabs);
+}
+
+void
+hotssh_window_activate_tab (HotSshWindow *self,
+ HotSshTab *tab)
+{
+ HotSshWindowPrivate *priv = hotssh_window_get_instance_private (self);
+ guint index;
+
+ index = find_tab_index (self, tab);
+ gtk_notebook_set_current_page ((GtkNotebook*)priv->main_notebook, index);
+}
diff --git a/src/hotssh-win.h b/src/hotssh-win.h
index 031d3eb..bf8ce45 100644
--- a/src/hotssh-win.h
+++ b/src/hotssh-win.h
@@ -21,9 +21,11 @@
#pragma once
#include "hotssh-app.h"
+#include "hotssh-tab.h"
#define HOTSSH_TYPE_WINDOW (hotssh_window_get_type ())
#define HOTSSH_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HOTSSH_TYPE_WINDOW, HotSshWindow))
+#define HOTSSH_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HOTSSH_TYPE_WINDOW))
typedef struct _HotSshWindow HotSshWindow;
typedef struct _HotSshWindowClass HotSshWindowClass;
@@ -31,3 +33,7 @@ typedef struct _HotSshWindowClass HotSshWindowClass;
GType hotssh_window_get_type (void);
HotSshWindow *hotssh_window_new (HotSshApp *app);
+
+GList *hotssh_window_get_tabs (HotSshWindow *self);
+void hotssh_window_activate_tab (HotSshWindow *self,
+ HotSshTab *tab);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]