Search code examples
cgtk

how to program window to close with escape key


I've been searching all over the place to find out how to get my program to close using the escape key. Not that many people use GTK+ I assume. Also, if it's not asking too much, can some please show me how to use the Gnome developer website so I could find this stuff out on my own? Thanks. So, closing the window with escape key, here's my code:

#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <ctype.h>
#include <curses.h>

#define KEY_ESC '\033'

static GtkWidget *entry;

static gboolean kill_window(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    gtk_main_quit();
    return FALSE;
}

static void button_press(GtkWidget *widget, gpointer data)
{
    const char *text = gtk_entry_get_text(GTK_ENTRY(entry));
    //system("cd" text);
    //printf("%s\n", text);
    const char *text2 = "&";
    char *concatenation;
    concatenation = malloc(strlen(text)+2);
    strcpy(concatenation, text);
    strcat(concatenation, text2);
    system(concatenation); 
    gtk_main_quit();
}

    int main(int argc, char *argv[])
    {

GtkWidget *window;
GtkWidget *button;
GtkWidget *button1;
GtkWidget *hbox;


gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
button = gtk_button_new_with_label("Run");
button1 = gtk_button_new_with_label("Cancel");
entry = gtk_entry_new();
hbox = gtk_vbox_new(FALSE, 2);

gtk_window_set_title(GTK_WINDOW(window), "Run..");

gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
g_signal_connect(window, "delete_event", G_CALLBACK(kill_window), NULL);

g_signal_connect(button, "clicked", G_CALLBACK(button_press), NULL);

g_signal_connect(button1, "clicked", G_CALLBACK(kill_window), NULL);
g_signal_connect(entry, "activate", G_CALLBACK(button_press), NULL);
g_signal_connect(button1, "delete_event", G_CALLBACK(kill_window), NULL);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
gtk_window_set_default_size(GTK_WINDOW(window), 250, 100);
gtk_window_set_decorated(GTK_WINDOW(window), TRUE);

gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 2);

gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 2); 
gtk_box_pack_start(GTK_BOX(hbox), button1, FALSE, FALSE, 2);
gtk_container_add(GTK_CONTAINER(window), hbox);
gtk_widget_show_all(window);

gtk_main(); 

return 0;
}

Solution

  • Connect to the key_press_event signal on the top-level window:

    g_signal_connect(window, "key_press_event", G_CALLBACK(check_escape), NULL);
    

    The check_escape callback will look like this:

    #include <gdk/gdkkeysyms.h>
    ...
    static gboolean check_escape(GtkWidget *widget, GdkEventKey *event, gpointer data)
    {
      if (event->keyval == GDK_KEY_Escape) {
        gtk_main_quit();
        return TRUE;
      }
      return FALSE;
    }
    

    Also, you don't need the <curses.h> include, nor the KEY_ESC definition.

    If your top-level window is essentially a dialog, you might consider using a GtkDialog instead of a GtkWindow. A dialog provides stock responses such as "OK" and "Cancel", with enter and escape keys invoking the expected response.