[hotssh] Set "Copy" action sensitivity correctly, and drop some broken focus bits



commit e82d894c8ac5df78383d077f0c791674a2c4e908
Author: Colin Walters <walters verbum org>
Date:   Thu Jan 2 21:19:47 2014 -0500

    Set "Copy" action sensitivity correctly, and drop some broken focus bits
    
    I still don't fully understand focusing with respect to GtkNotebook
    and such, but this at least appears to work.

 src/hotssh-tab.c |   18 -------------
 src/hotssh-win.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+), 18 deletions(-)
---
diff --git a/src/hotssh-tab.c b/src/hotssh-tab.c
index 4edbfdb..57bb43e 100644
--- a/src/hotssh-tab.c
+++ b/src/hotssh-tab.c
@@ -159,16 +159,6 @@ set_status_printf (HotSshTab  *self,
 }
 
 static void
-reset_focus_state (HotSshTab   *self)
-{
-  HotSshTabPrivate *priv = hotssh_tab_get_instance_private (self);
-  if (gtk_entry_get_text ((GtkEntry*)priv->host_entry)[0] == '\0')
-    gtk_widget_grab_focus (priv->host_entry);
-  else
-    gtk_widget_grab_focus (priv->username_entry);
-}
-
-static void
 state_reset_for_new_connection (HotSshTab                *self)
 {
   HotSshTabPrivate *priv = hotssh_tab_get_instance_private (self);
@@ -182,7 +172,6 @@ state_reset_for_new_connection (HotSshTab                *self)
       g_object_notify ((GObject*)self, "hostname");
       vte_terminal_reset ((VteTerminal*)priv->terminal, TRUE, TRUE);
       gtk_entry_set_text ((GtkEntry*)priv->password_entry, "");
-      reset_focus_state (self);
       gtk_label_set_text ((GtkLabel*)priv->connection_text, "");
       gtk_widget_set_sensitive (priv->password_container, TRUE);
       priv->awaiting_password_entry = priv->submitted_password = FALSE;
@@ -920,12 +909,6 @@ host_entry_match (GtkEntryCompletion *completion,
 }
 
 static void
-hotssh_tab_grab_focus (GtkWidget *widget)
-{
-  reset_focus_state ((HotSshTab*)widget);
-}
-
-static void
 on_vte_realize (GtkWidget   *widget,
                 HotSshTab   *self)
 {
@@ -1166,7 +1149,6 @@ hotssh_tab_class_init (HotSshTabClass *class)
   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), HotSshTab, terminal_box);
   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), HotSshTab, terminal_vscrollbar);
 
-  GTK_WIDGET_CLASS (class)->grab_focus = hotssh_tab_grab_focus;
   GTK_WIDGET_CLASS (class)->style_updated = hotssh_tab_style_updated;
 
   g_object_class_install_property (G_OBJECT_CLASS (class),
diff --git a/src/hotssh-win.c b/src/hotssh-win.c
index 8173481..804c0c4 100644
--- a/src/hotssh-win.c
+++ b/src/hotssh-win.c
@@ -67,6 +67,11 @@ struct _HotSshWindowPrivate
   GtkWidget *terminal;
   GSettings *settings;
 
+  GtkWidget *watching_focus;
+  guint watching_focus_sigid;
+
+  gboolean indisposed;
+
   /* Bound via template */
   GtkWidget *main_notebook;
   GtkWidget *new_connection;
@@ -255,6 +260,59 @@ new_channel_activated (GSimpleAction    *action,
 }
 
 static void
+hotssh_window_update_copy_paste_sensitivity (HotSshWindow *self);
+
+static void
+on_focused_terminal_selection_changed (VteTerminal *terminal,
+                                       gpointer user_data)
+{
+  HotSshWindow *self = user_data;
+  hotssh_window_update_copy_paste_sensitivity (self);
+}
+
+static void
+hotssh_window_update_copy_paste_sensitivity (HotSshWindow *self)
+{
+  HotSshWindowPrivate *priv = hotssh_window_get_instance_private (self);
+  GtkWidget *focus = gtk_window_get_focus ((GtkWindow*)self);
+  gboolean can_copy = FALSE;
+  GAction *copy_action;
+  
+  if (focus != priv->watching_focus)
+    {
+      if (priv->watching_focus && priv->watching_focus_sigid > 0)
+        g_signal_handler_disconnect (priv->watching_focus, priv->watching_focus_sigid);
+      priv->watching_focus = NULL;
+      priv->watching_focus_sigid = 0;
+
+      if (focus && VTE_IS_TERMINAL (focus))
+        {
+          priv->watching_focus = focus;
+          g_object_add_weak_pointer ((GObject*)focus, (gpointer*)&priv->watching_focus);
+          priv->watching_focus_sigid = 
+            g_signal_connect (priv->watching_focus, "selection-changed",
+                              G_CALLBACK (on_focused_terminal_selection_changed),
+                              self);
+        }
+    }
+  
+  if (focus)
+    {
+      g_debug ("focus is a %s", g_type_name (G_TYPE_FROM_INSTANCE (focus)));
+      if (GTK_IS_EDITABLE (focus))
+        can_copy = gtk_editable_get_selection_bounds ((GtkEditable*)focus, NULL, NULL);
+      else if (VTE_IS_TERMINAL (focus))
+        can_copy = vte_terminal_get_has_selection ((VteTerminal*)focus);
+    }
+  else
+    g_debug ("focus is NULL");
+
+  copy_action = g_action_map_lookup_action ((GActionMap*)self, "copy");
+  g_assert (copy_action);
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (copy_action), can_copy); 
+}
+
+static void
 copy_activated (GSimpleAction    *action,
                 GVariant         *parameter,
                 gpointer          user_data)
@@ -317,16 +375,32 @@ hotssh_window_dispose (GObject *object)
   HotSshWindow *self = HOTSSH_WINDOW (object);
   HotSshWindowPrivate *priv = hotssh_window_get_instance_private (self);
 
+  priv->indisposed = TRUE;
+
   g_clear_object (&priv->settings);
 
   G_OBJECT_CLASS (hotssh_window_parent_class)->dispose (object);
 }
 
 static void
+hotssh_window_set_focus (GtkWindow *window,
+                         GtkWidget *focus)
+{
+  HotSshWindow *self = (HotSshWindow*)window;
+  HotSshWindowPrivate *priv = hotssh_window_get_instance_private (self);
+  GTK_WINDOW_CLASS (hotssh_window_parent_class)->set_focus (window, focus);
+
+  if (!priv->indisposed)
+    hotssh_window_update_copy_paste_sensitivity (self);
+}
+
+static void
 hotssh_window_class_init (HotSshWindowClass *class)
 {
   G_OBJECT_CLASS (class)->dispose = hotssh_window_dispose;
 
+  GTK_WINDOW_CLASS (class)->set_focus = hotssh_window_set_focus;
+
   gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
                                                "/org/gnome/hotssh/window.ui");
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]