From 99a256a218cce5d4a81ffa45369410b1ef67cdd4 Mon Sep 17 00:00:00 2001
From: Alexandre Savard <alexandre.savard@savoirfairelinux.net>
Date: Thu, 14 May 2009 14:12:54 -0400
Subject: [PATCH] [#1343] Gnome: Implement a callback system to handle focus on
 different widgets

---
 sflphone-client-gnome/src/contacts/calltree.c | 42 +++++++++++---
 sflphone-client-gnome/src/contacts/calltree.h |  2 +-
 .../src/contacts/searchbar.c                  | 37 ++++++++++--
 .../src/contacts/searchbar.h                  |  1 +
 sflphone-client-gnome/src/mainwindow.c        | 57 ++++++++++---------
 sflphone-client-gnome/src/mainwindow.h        |  9 +++
 6 files changed, 109 insertions(+), 39 deletions(-)

diff --git a/sflphone-client-gnome/src/contacts/calltree.c b/sflphone-client-gnome/src/contacts/calltree.c
index 3d56e847c0..01d6d6960d 100644
--- a/sflphone-client-gnome/src/contacts/calltree.c
+++ b/sflphone-client-gnome/src/contacts/calltree.c
@@ -25,6 +25,12 @@
 #include <toolbar.h>
 #include <mainwindow.h>
 
+
+GtkWidget *sw;
+GtkCellRenderer *rend;
+GtkTreeViewColumn *col;
+GtkTreeSelection *sel;
+
 /**
  * Show popup menu
  */
@@ -141,6 +147,7 @@ button_pressed(GtkWidget* widget, GdkEventButton *event, gpointer user_data UNUS
     return FALSE;
 }
 
+
     static gboolean
 on_key_released (GtkWidget   *widget UNUSED,
         GdkEventKey *event,
@@ -175,13 +182,27 @@ calltree_reset (calltab_t* tab)
     gtk_list_store_clear (tab->store);
 }
 
+void
+focus_on_calltree_out(){
+  DEBUG("set_focus_on_calltree_out \n");
+  // gtk_widget_grab_focus(GTK_WIDGET(sw));
+  focus_is_on_calltree = FALSE;
+}
+
+void
+focus_on_calltree_in(){
+  DEBUG("set_focus_on_calltree_in \n");
+  // gtk_widget_grab_focus(GTK_WIDGET(sw));
+  focus_is_on_calltree = TRUE;
+}
+
     void
 calltree_create (calltab_t* tab, gchar* searchbar_type)
 {
-    GtkWidget *sw;
-    GtkCellRenderer *rend;
-    GtkTreeViewColumn *col;
-    GtkTreeSelection *sel;
+    // GtkWidget *sw;
+    // GtkCellRenderer *rend;
+    // GtkTreeViewColumn *col;
+    // GtkTreeSelection *sel;
 
     tab->tree = gtk_vbox_new(FALSE, 10);
 
@@ -207,7 +228,8 @@ calltree_create (calltab_t* tab, gchar* searchbar_type)
             G_CALLBACK (row_activated),
             NULL);
 
-    // GTK_WIDGET_SET_FLAGS (GTK_WIDGET(sw),GTK_CAN_FOCUS);
+    GTK_WIDGET_SET_FLAGS (GTK_WIDGET(sw),GTK_CAN_FOCUS);
+    gtk_widget_grab_focus (GTK_WIDGET(sw));
 
     // Connect the popup menu
     g_signal_connect (G_OBJECT (tab->view), "popup-menu",
@@ -217,9 +239,15 @@ calltree_create (calltab_t* tab, gchar* searchbar_type)
             G_CALLBACK (button_pressed),
             NULL);
 
-    g_signal_connect (G_OBJECT (sw), "key-release-event",
-                    G_CALLBACK (on_key_released), NULL);
+    // g_signal_connect (G_OBJECT (sw), "key-release-event",
+    //                   G_CALLBACK (on_key_released), NULL);
+
+    g_signal_connect_after (G_OBJECT (tab->view), "focus-in-event",
+                      G_CALLBACK (focus_on_calltree_in), NULL);
+    g_signal_connect_after (G_OBJECT (tab->view), "focus-out-event",
+                      G_CALLBACK (focus_on_calltree_out), NULL);
 
+    gtk_widget_grab_focus(GTK_WIDGET(tab->view));
 
     rend = gtk_cell_renderer_pixbuf_new();
     col = gtk_tree_view_column_new_with_attributes ("Icon",
diff --git a/sflphone-client-gnome/src/contacts/calltree.h b/sflphone-client-gnome/src/contacts/calltree.h
index 1dd57d2d28..09d5ad6887 100644
--- a/sflphone-client-gnome/src/contacts/calltree.h
+++ b/sflphone-client-gnome/src/contacts/calltree.h
@@ -23,7 +23,7 @@
 #include <gtk/gtk.h>
 #include <calltab.h>
 #include <timestamp.h>
-
+#include <mainwindow.h>
 
 /** @file calltree.h
   * @brief The GtkTreeView that list calls in the main window.
diff --git a/sflphone-client-gnome/src/contacts/searchbar.c b/sflphone-client-gnome/src/contacts/searchbar.c
index f83d72381a..4d4a133182 100644
--- a/sflphone-client-gnome/src/contacts/searchbar.c
+++ b/sflphone-client-gnome/src/contacts/searchbar.c
@@ -26,6 +26,7 @@
 const GdkColor BLACK_COLOR = { 0, 0, 0, 0 };
 const GdkColor GRAY_COLOR = { 0, 30000, 30000, 30000 };
 
+GtkWidget * searchbox;
 
 void searchbar_entry_changed (GtkEntry* entry, gchar* arg1 UNUSED, gpointer data UNUSED) {
     // gtk_widget_grab_focus (GTK_WIDGET(searchbox));
@@ -39,17 +40,40 @@ void searchbar_entry_changed (GtkEntry* entry, gchar* arg1 UNUSED, gpointer data
 
 }
 
+//   static void
+// focus_in_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
+// {
+    
+// }
+
+
 void searchbar_clear_entry_if_default (GtkWidget* widget, gpointer user_data UNUSED) {
 
+    DEBUG("searchbar_clear_entry_if_default\n");
     gtk_widget_modify_text(widget, GTK_STATE_NORMAL, &BLACK_COLOR); 
     if(g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(widget)), "Search history", 14) == 0
             || g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(widget)), "Search contact", 14) == 0 )
         gtk_entry_set_text(GTK_ENTRY(widget), "");
 
-    // gtk_widget_grab_focus (GTK_WIDGET(searchbox));
+    // gtk_widget_grab_focus (GTK_WIDGET(searchbox));1
 
 }
 
+void
+focus_on_searchbar_out(){
+  DEBUG("set_focus_on_searchbar_out \n");
+  // gtk_widget_grab_focus(GTK_WIDGET(sw));
+  focus_is_on_searchbar = FALSE;
+}
+
+void
+focus_on_searchbar_in(){
+  DEBUG("set_focus_on_searchbar_in \n");
+  // gtk_widget_grab_focus(GTK_WIDGET(sw));
+  focus_is_on_searchbar = TRUE;
+}
+
+
 void
 searchbar_init(calltab_t *tab)
 {
@@ -63,7 +87,7 @@ searchbar_init(calltab_t *tab)
 
 GtkWidget* searchbar_new(gchar* searchbar_type) {
 
-  GtkWidget * searchbox;
+  // GtkWidget * searchbox;
   GtkWidget* image;
   GtkWidget* ret = gtk_hbox_new(FALSE, 0);
 
@@ -84,8 +108,13 @@ GtkWidget* searchbar_new(gchar* searchbar_type) {
   gtk_widget_modify_text(searchbox, GTK_STATE_NORMAL, &GRAY_COLOR); 
 
   gtk_entry_set_text(GTK_ENTRY(searchbox), _("Search contact"));
-  g_signal_connect(GTK_ENTRY(searchbox), "changed", G_CALLBACK(searchbar_entry_changed), NULL);
-  g_signal_connect(GTK_ENTRY(searchbox), "grab-focus", G_CALLBACK(searchbar_clear_entry_if_default), NULL);
+  g_signal_connect_after(GTK_ENTRY(searchbox), "changed", G_CALLBACK(searchbar_entry_changed), NULL);
+  g_signal_connect_after(GTK_ENTRY(searchbox), "grab-focus", G_CALLBACK(searchbar_clear_entry_if_default), NULL);
+
+  g_signal_connect_after (G_OBJECT (searchbox), "focus-in-event",
+                      G_CALLBACK (focus_on_searchbar_in), NULL);
+  g_signal_connect_after (G_OBJECT (searchbox), "focus-out-event",
+                      G_CALLBACK (focus_on_searchbar_out), NULL);
 
   gtk_box_pack_start(GTK_BOX(ret), searchbox, TRUE, TRUE, 0);
 
diff --git a/sflphone-client-gnome/src/contacts/searchbar.h b/sflphone-client-gnome/src/contacts/searchbar.h
index aabe3ea411..f7ed303520 100644
--- a/sflphone-client-gnome/src/contacts/searchbar.h
+++ b/sflphone-client-gnome/src/contacts/searchbar.h
@@ -30,6 +30,7 @@
 
 #include <calllist.h>
 #include <gtk/gtk.h>
+#include <mainwindow.h>
 
 // From version 2.16, gtk provides the functionalities libsexy used to provide
 #if GTK_CHECK_VERSION(2,16,0)
diff --git a/sflphone-client-gnome/src/mainwindow.c b/sflphone-client-gnome/src/mainwindow.c
index c4a28e6d7b..1db50d7282 100644
--- a/sflphone-client-gnome/src/mainwindow.c
+++ b/sflphone-client-gnome/src/mainwindow.c
@@ -98,25 +98,14 @@ main_window_ask_quit(){
 }
 
 
-/*
+
 static gboolean
-on_key_released (GtkWidget   *widget,
-        GdkEventKey *event,
-        gpointer     user_data UNUSED)
+on_key_released (GtkWidget *widget, GdkEventKey *event, gpointer user_data UNUSED)
 {
-  printf("On key released from Main Window : %s\n", gtk_widget_get_name(widget));
+  DEBUG("On key released from Main Window : %s\n", gtk_widget_get_name(widget));
 
-  // if ((active_calltree != contacts) && (active_calltree != history)) {
-  if (gtk_widget_is_focus(window)){
-      printf("Focus is on main window \n");
-  }
 
-  if (!GTK_WIDGET_CAN_FOCUS(widget)){
-       printf("Widget can't focus \n");
-       gtk_widget_grab_focus(GTK_WIDGET(window));
-  }
-
-  if (gtk_widget_is_focus (window)) {
+  if (focus_is_on_searchbar == FALSE) {
         // If a modifier key is pressed, it's a shortcut, pass along
         if(event->state & GDK_CONTROL_MASK ||
                 event->state & GDK_MOD1_MASK    ||
@@ -131,24 +120,34 @@ on_key_released (GtkWidget   *widget,
             return FALSE;
         else
             sflphone_keypad(event->keyval, event->string);
-        }
+        
    }
+
    return TRUE;
 }
 
+void
+focus_on_mainwindow_out(){
+  DEBUG("focus_on_mainwindow_out \n");
+  //  gtk_widget_grab_focus(GTK_WIDGET(window));
+  
+}
 
 void
-set_focus_on_mainwindow(){
-  DEBUG("set_focus_on_mainwindow \n");
-  gtk_widget_grab_focus(GTK_WIDGET(window));
+focus_on_mainwindow_in(){
+  DEBUG("focus_on_mainwindow_in \n");
+  //  gtk_widget_grab_focus(GTK_WIDGET(window));
 }
-*/
+
 
 void
 create_main_window ()
 {
   GtkWidget *widget;
 
+  focus_is_on_calltree = FALSE;
+  focus_is_on_searchbar = FALSE;
+
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_container_set_border_width (GTK_CONTAINER (window), 0);
   gtk_window_set_title (GTK_WINDOW (window), PACKAGE);
@@ -161,17 +160,21 @@ create_main_window ()
   // gtk_widget_grab_focus (GTK_WIDGET(window));
 
   /* Connect the destroy event of the window with our on_destroy function
-    * When the window is about to be destroyed we get a notificaiton and
-    * stop the main GTK loop
-    */
+   * When the window is about to be destroyed we get a notificaiton and
+   * stop the main GTK loop
+   */
   g_signal_connect (G_OBJECT (window), "delete-event",
                     G_CALLBACK (on_delete), NULL);
 
-  // g_signal_connect (G_OBJECT (window), "key-release-event",
-  //                   G_CALLBACK (on_key_released), NULL);
+  g_signal_connect (G_OBJECT (window), "key-release-event",
+                     G_CALLBACK (on_key_released), NULL);
+
+  g_signal_connect_after (G_OBJECT (window), "focus-in-event",
+                    G_CALLBACK (focus_on_mainwindow_in), NULL);
 
-  // g_signal_connect (G_OBJECT (window), "client-event",
-  //                   G_CALLBACK (set_focus_on_mainwindow), NULL);
+  g_signal_connect_after (G_OBJECT (window), "focus-out-event",
+                    G_CALLBACK (focus_on_mainwindow_out), NULL);
+  
 
   gtk_widget_set_name (window, "mainwindow");
 
diff --git a/sflphone-client-gnome/src/mainwindow.h b/sflphone-client-gnome/src/mainwindow.h
index 956f982c0c..bdf3c0af12 100644
--- a/sflphone-client-gnome/src/mainwindow.h
+++ b/sflphone-client-gnome/src/mainwindow.h
@@ -21,6 +21,7 @@
 #define __MAINWINDOW_H__
 
 #include <calllist.h>
+#include <calltree.h>
 
 /** @file mainwindow.h
   * @brief The main window of the client.
@@ -91,5 +92,13 @@ void statusbar_pop_message( guint id );
 
 void main_window_searchbar( gboolean *state );
 
+//static gboolean
+//on_key_released (GtkWidget *widget, GdkEventKey *event,
+//                 gpointer user_data);
 // void set_focus_on_mainwindow();
+
+gboolean focus_is_on_calltree;
+
+gboolean focus_is_on_searchbar;
+
 #endif
-- 
GitLab