diff --git a/c/gtk3/click/click.c b/c/gtk3/click/click.c
new file mode 100644
index 0000000..b935bde
--- /dev/null
+++ b/c/gtk3/click/click.c
@@ -0,0 +1,119 @@
+#include <stdlib.h>
+#include <time.h>
+#include <gtk/gtk.h>
+
+#define COLS 10
+#define ROWS 20
+
+const int size = 30;
+const int colors_count = 3;
+const double colors[][3] = {
+  { 1, 1, 1 },
+  { 1, 1, 0 },
+  { 1, 0, 0 },
+  { 0, 0, 1 },
+  { 0.66, 0.66, 0.66 },
+  { 0.33, 0.33, 0.33 } };
+
+int board[COLS][ROWS];
+
+
+void new_game() {
+  srand(time(NULL));
+  for(int x = 0; x < COLS; ++x)
+    for(int y = 0; y < ROWS; ++y)
+      board[x][y] = 1 + rand()%colors_count;
+}
+
+int get_block(int x, int y) {
+  if (x < 0 || y < 0 || x >= COLS || y >= ROWS)
+    return -1;
+  return board[x][y];
+}
+
+void check(int x, int y) {
+  int color = get_block(x, y);
+  if (color > 0) {
+    if (get_block(x-1, y) == color) {
+      board[x][y] = 0;
+      check(x-1, y);
+      board[x-1][y] = 0;
+    }
+    if (get_block(x+1, y) == color) {
+      board[x][y] = 0;
+      check(x+1, y);
+      board[x+1][y] = 0;
+    }
+    if (get_block(x, y-1) == color) {
+      board[x][y] = 0;
+      check(x, y-1);
+      board[x][y-1] = 0;
+    }
+    if (get_block(x, y+1) == color) {
+      board[x][y] = 0;
+      check(x, y+1);
+      board[x][y+1] = 0;
+    }
+  }
+}
+
+void fall() {
+  int dx = 0;
+  for(int x = 0; x < COLS; ++x) {
+    int dy = 0;
+    for(int y = 0; y < ROWS; ++y) {
+      if (board[x][y] != 0) {
+        if (dx > 0 || dy > 0) {
+          board[x-dx][y-dy] = board[x][y];
+          board[x][y] = 0;
+        }
+      } else {
+        ++dy;
+      }
+    }
+    if (dy == ROWS) ++dx;
+  }
+}
+
+gboolean button_press(GtkWidget *widget, GdkEventButton *event, gpointer data) {
+  if (event->button == 1) {
+    check((int)(event->x)/size, ROWS - 1 - (int)(event->y)/size);
+    fall();
+  } else
+  if (event->button == 3) {
+    new_game();
+  }
+  gtk_widget_queue_draw(widget);
+  return TRUE;
+}
+
+gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer data) {
+  for(int x = 0; x < COLS; ++x) {
+    for(int y = 0; y < ROWS; ++y) {
+      int c = board[x][ROWS - 1 - y];
+      cairo_rectangle(cr, x*size, y*size, size, size);
+      cairo_set_source_rgb(cr, colors[c][0], colors[c][1], colors[c][2]);
+      cairo_fill(cr);
+    }
+  }
+  return TRUE;
+}
+
+void activate(GtkApplication* app, gpointer data) {
+  GtkWidget *window = gtk_application_window_new (app);
+  g_signal_connect(window, "draw", G_CALLBACK(draw), NULL);
+  g_signal_connect(window, "button-press-event", G_CALLBACK(button_press), NULL);
+  gtk_window_set_default_size(GTK_WINDOW(window), size*COLS, size*ROWS);
+  gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
+  gtk_widget_show_all(window);
+
+  new_game();
+}
+
+int main(int argc, char **argv) {
+  GtkApplication *application = gtk_application_new(NULL, 0);
+  g_signal_connect(application, "activate", G_CALLBACK(activate), NULL);
+  int status = g_application_run(G_APPLICATION(application), argc, argv);
+  g_object_unref(application);
+  return status;
+}