Recognize Esc and Tab in ICS Console input
authorH.G. Muller <h.g.muller@hccnet.nl>
Tue, 4 Feb 2014 12:57:16 +0000 (13:57 +0100)
committerH.G. Muller <h.g.muller@hccnet.nl>
Sun, 2 Mar 2014 17:48:55 +0000 (18:48 +0100)
Esc is used to close the chat, or transfer focus to the board window.
Tab is used to navigate between chats (or open the first). Priority
is given to dirty chats.

dialogs.c
dialogs.h
gtk/xoptions.c
xaw/xoptions.c

index e93e736..39805c9 100644 (file)
--- a/dialogs.c
+++ b/dialogs.c
@@ -1333,7 +1333,7 @@ BoxAutoPopUp (char *buf)
                GetWidgetText(&boxOptions[INPUT], &p);
                snprintf(newText, MSG_SIZ, "%s%c", p, *buf);
                SetWidgetText(&boxOptions[INPUT], newText, InputBoxDlg);
-               if(shellUp[InputBoxDlg]) HardSetFocus (&boxOptions[INPUT]); //why???
+               if(shellUp[InputBoxDlg]) HardSetFocus (&boxOptions[INPUT], InputBoxDlg); //why???
            } else icsText = buf; // box did not exist: make sure it pops up with char in it
            ICSInputBoxPopUp();
        } else PopUpMoveDialog(*buf);
@@ -1780,17 +1780,30 @@ PutText (char *text, int pos)
     if(shellUp[InputBoxDlg]) opt = &boxOptions[INPUT], dlg = InputBoxDlg; // for the benefit of Xaw give priority to ICS Input Box
     SetWidgetText(opt, text, dlg);
     SetInsertPos(opt, pos);
-    HardSetFocus(opt);
+    HardSetFocus(opt, dlg);
     CursorAtEnd(opt);
 }
 
-void
+int
 IcsHist (int n, Option *opt, DialogClass dlg)
 {   // [HGM] input: let up-arrow recall previous line from history
     char *val = NULL; // to suppress spurious warning
+    int chat, start;
 
-    if(opt != &chatOptions[CHAT_IN]) return;
+    if(opt != &chatOptions[CHAT_IN] && !(opt == &chatOptions[CHAT_PARTNER] && n == 33)) return 0;
     switch(n) {
+      case 33: // <Esc>
+       if(hidden) BoardToTop();
+       else PaneSwitch();
+       break;
+      case 10: // <Tab>
+       chat = start = (activePartner - hidden + MAX_CHAT) % MAX_CHAT;
+        while(!dirty[chat = (chat + 1)%MAX_CHAT]) if(chat == start) break;
+       if(!dirty[chat])
+        while(!chatPartner[chat = (chat + 1)%MAX_CHAT][0]) if(chat == start) break;
+       if(chat == start && hidden) chat = 0; // if all unused, start left
+        ChatSwitch(chat + 1);
+       break;
       case 1:
        GetWidgetText(opt, &val);
        val = PrevInHistory(val);
@@ -1800,6 +1813,7 @@ IcsHist (int n, Option *opt, DialogClass dlg)
     }
     SetWidgetText(opt, val = val ? val : "", dlg);
     SetInsertPos(opt, strlen(val));
+    return 1;
 }
 
 void
@@ -1831,7 +1845,7 @@ ChatOK (int n)
        SetWidgetText(&chatOptions[CHAT_OUT], "", -1); // clear text if we alter partner
        SetWidgetText(&chatOptions[CHAT_IN], "", ChatDlg); // clear text if we alter partner
        SetWidgetLabel(&chatOptions[activePartner+1], chatPartner[activePartner][0] ? chatPartner[activePartner] : _("New Chat"));
-       HardSetFocus(&chatOptions[CHAT_IN]);
+       HardSetFocus(&chatOptions[CHAT_IN], 0);
     }
     if(line[0] || hidden) { // something was typed (for ICS commands we also allow empty line!)
        SetWidgetText(&chatOptions[CHAT_IN], "", ChatDlg);
@@ -1880,7 +1894,7 @@ ChatSwitch (int n)
        SetColor(dirty[i] ? "#FFC000" : "#FFFFFF", &chatOptions[j]);
     }
     SetWidgetText(&chatOptions[CHAT_IN], "", ChatDlg);
-    HardSetFocus(&chatOptions[strcmp(chatPartner[n], "") ? CHAT_IN : CHAT_PARTNER]);
+    HardSetFocus(&chatOptions[strcmp(chatPartner[n], "") ? CHAT_IN : CHAT_PARTNER], 0);
 }
 
 void
@@ -1912,7 +1926,7 @@ ChatProc ()
 {
     if(GenericPopUp(chatOptions, _("ICS Interaction"), ChatDlg, BoardWindow, NONMODAL, appData.topLevel))
        AddHandler(&chatOptions[CHAT_PARTNER], ChatDlg, 2), AddHandler(&chatOptions[CHAT_IN], ChatDlg, 2); // treats return as OK
-    PaneSwitch(); HardSetFocus(&chatOptions[CHAT_IN]);
+    PaneSwitch(); HardSetFocus(&chatOptions[CHAT_IN], 0);
     MarkMenu("View.OpenChatWindow", ChatDlg);
     CursorAtEnd(&chatOptions[CHAT_IN]);
 }
@@ -1927,7 +1941,7 @@ ConsoleAutoPopUp (char *buf)
                GetWidgetText(&chatOptions[CHAT_IN], &p);
                snprintf(newText, MSG_SIZ, "%s%c", p, *buf);
                SetWidgetText(&chatOptions[CHAT_IN], newText, ChatDlg);
-               if(shellUp[ChatDlg]) HardSetFocus (&boxOptions[CHAT_IN]); //why???
+               if(shellUp[ChatDlg]) HardSetFocus (&chatOptions[CHAT_IN], ChatDlg); //why???
            } else { ASSIGN(line, buf); } // box did not exist: make sure it pops up with char in it
            ChatProc();
        } else PopUpMoveDialog(*buf);
index 87be680..1a27354 100644 (file)
--- a/dialogs.h
+++ b/dialogs.h
@@ -146,7 +146,7 @@ void HighlightText P((Option *opt, int from, int to, Boolean highlight));
 void SetColor P((char *colorName, Option *box));
 //void ColorChanged P((Widget w, XtPointer data, XEvent *event, Boolean *b));
 void SetInsertPos P((Option *opt, int pos));
-void HardSetFocus P((Option *opt));
+void HardSetFocus P((Option *opt, DialogClass dlg));
 void CursorAtEnd P((Option *opt));
 void GetWidgetText  P((Option *opt, char **buf));
 void SetWidgetText  P((Option *opt, char *buf, int n));
index 04d566a..2806fb0 100644 (file)
@@ -350,6 +350,7 @@ FocusOnWidget (Option *opt, DialogClass dlg)
 #ifdef TODO_GTK
     XtSetKeyboardFocus(shells[dlg], opt->handle);
 #endif
+    if(dlg) gtk_window_present(GTK_WINDOW(shells[dlg]));
     gtk_widget_grab_focus(opt->handle);
 }
 
@@ -502,13 +503,14 @@ TypeInProc (GtkWidget *widget, GdkEventKey *event, gpointer gdata)
     shiftState = event->state & GDK_SHIFT_MASK;
     controlState = event->state & GDK_CONTROL_MASK;
     switch(event->keyval) {
+      case GDK_Tab:   IcsHist(10, opt, dlg); break;
       case GDK_Up:     IcsHist(1, opt, dlg); break;
       case GDK_Down:  IcsHist(-1, opt, dlg); break;
       case GDK_Return:
        if(GenericReadout(dialogOptions[dlg], -1)) PopDown(dlg);
        break;
       case GDK_Escape:
-       PopDown(dlg);
+       if(!IcsHist(33, opt, dlg)) PopDown(dlg);
        break;
       default:
        return FALSE;
@@ -1683,7 +1685,7 @@ SetInsertPos (Option *opt, int pos)
 }
 
 void
-HardSetFocus (Option *opt)
+HardSetFocus (Option *opt, DialogClass dlg)
 {
-    FocusOnWidget(opt, 0); // second arg not used in GDK
+    FocusOnWidget(opt, dlg);
 }
index 6231c7e..272db4c 100644 (file)
@@ -1379,7 +1379,7 @@ TypeInProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 }
 
 void
-HardSetFocus (Option *opt)
+HardSetFocus (Option *opt, DialogClass dlg)
 {
     XSetInputFocus(xDisplay, XtWindow(opt->handle), RevertToPointerRoot, CurrentTime);
 }