From 57b08d4e7f47f3b2ecaa2914062301c0f52ad22d Mon Sep 17 00:00:00 2001
From: Daniel Carl <danielcarl@gmx.de>
Date: Fri, 27 Sep 2013 01:50:19 +0200
Subject: [PATCH] Set mode according to current focused widget.

---
 src/ex.c     |  8 +++-----
 src/hints.c  |  6 ++++++
 src/main.c   |  8 +++++++-
 src/mode.c   | 16 ++++++++++++++++
 src/mode.h   |  2 ++
 src/normal.c |  9 ---------
 src/normal.h |  1 -
 7 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/src/ex.c b/src/ex.c
index f753a47..0220bbd 100644
--- a/src/ex.c
+++ b/src/ex.c
@@ -190,11 +190,9 @@ VbResult ex_keypress(unsigned int key)
     GtkTextBuffer *buffer = vb.gui.buffer;
     GtkTextMark *mark;
 
-    /* delegate call to the submode if hinting is active */
-    if (vb.mode->flags & FLAG_HINTING) {
-        if (RESULT_COMPLETE == hints_keypress(key)) {
-            return RESULT_COMPLETE;
-        }
+    /* delegate call to the submode */
+    if (RESULT_COMPLETE == hints_keypress(key)) {
+        return RESULT_COMPLETE;
     }
 
     switch (key) {
diff --git a/src/hints.c b/src/hints.c
index d49c687..e62bf63 100644
--- a/src/hints.c
+++ b/src/hints.c
@@ -51,6 +51,12 @@ void hints_init(WebKitWebFrame *frame)
 
 VbResult hints_keypress(unsigned int key)
 {
+    /* if we are not already in hint mode we expect to get a ; to start
+     * hinting */
+    if (!(vb.mode->flags & FLAG_HINTING) && key != ';') {
+        return RESULT_ERROR;
+    }
+
     if (key == '\n') {
         hints_fire();
 
diff --git a/src/main.c b/src/main.c
index 67b1aeb..b245eaa 100644
--- a/src/main.c
+++ b/src/main.c
@@ -671,7 +671,7 @@ static void init_core(void)
 
     /* initialize the modes */
     mode_init();
-    mode_add('n', normal_enter, normal_leave, normal_keypress, normal_input_changed);
+    mode_add('n', normal_enter, normal_leave, normal_keypress, NULL);
     mode_add('c', ex_enter, ex_leave, ex_keypress, ex_input_changed);
     mode_add('i', input_enter, input_leave, input_keypress, NULL);
     mode_add('p', pass_enter, pass_leave, pass_keypress, NULL);
@@ -747,6 +747,12 @@ static void setup_signals()
     g_signal_connect(
         G_OBJECT(vb.gui.window), "key-press-event", G_CALLBACK(map_keypress), NULL
     );
+    g_object_connect(
+        G_OBJECT(vb.gui.input),
+        "signal::focus-in-event", G_CALLBACK(mode_input_focusin), NULL,
+        "signal::focus-out-event", G_CALLBACK(mode_input_focusout), NULL,
+        NULL
+    );
     g_object_connect(
         G_OBJECT(vb.gui.buffer),
         "signal::changed", G_CALLBACK(mode_input_changed), NULL,
diff --git a/src/mode.c b/src/mode.c
index 7bd3f75..ae79ad2 100644
--- a/src/mode.c
+++ b/src/mode.c
@@ -114,6 +114,22 @@ VbResult mode_handle_key(unsigned int key)
     return RESULT_ERROR;
 }
 
+gboolean mode_input_focusin(GtkWidget *widget, GdkEventFocus *event, gpointer data)
+{
+    /* enter the command mode if the focus is on inputbox */
+    mode_enter('c');
+
+    return false;
+}
+
+gboolean mode_input_focusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
+{
+    /* if focus is lesft from inputbox - switch back to normal mode */
+    mode_enter('n');
+
+    return false;
+}
+
 /**
  * Process input changed event on current active mode.
  */
diff --git a/src/mode.h b/src/mode.h
index b32c870..cd50159 100644
--- a/src/mode.h
+++ b/src/mode.h
@@ -29,6 +29,8 @@ void mode_add(char id, ModeTransitionFunc enter, ModeTransitionFunc leave,
     ModeKeyFunc keypress, ModeInputChangedFunc input_changed);
 void mode_enter(char id);
 VbResult mode_handle_key(unsigned int key);
+gboolean mode_input_focusin(GtkWidget *widget, GdkEventFocus *event, gpointer data);
+gboolean mode_input_focusout(GtkWidget *widget, GdkEventFocus *event, gpointer data);
 void mode_input_changed(GtkTextBuffer* buffer, gpointer data);
 
 #endif /* end of include guard: _MODE_H */
diff --git a/src/normal.c b/src/normal.c
index 2b75240..c087a02 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -408,15 +408,6 @@ VbResult normal_keypress(unsigned int key)
     return res;
 }
 
-/**
- * Handles changes in the inputbox. If there are usergenerated changes, we
- * switch to command mode.
- */
-void normal_input_changed(const char *text)
-{
-    /*mode_enter('i');*/
-}
-
 static VbResult normal_clear_input(const NormalCmdInfo *info)
 {
     vb_set_input_text("");
diff --git a/src/normal.h b/src/normal.h
index 6fb9f3f..02a887f 100644
--- a/src/normal.h
+++ b/src/normal.h
@@ -28,6 +28,5 @@ typedef struct NormalCmdInfo_s NormalCmdInfo;
 void normal_enter(void);
 void normal_leave(void);
 VbResult normal_keypress(unsigned int key);
-void normal_input_changed(const char *text);
 
 #endif /* end of include guard: _NORMAL_H */
-- 
2.20.1