diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c
index bc14a6d0e4fb46a718beda5aecb4a3095947ee59..d46af7b209a63a124071e4eed003dc3ba92a4fbc 100644
--- a/common/utils/T/tracer/gui/container.c
+++ b/common/utils/T/tracer/gui/container.c
@@ -164,6 +164,42 @@ printf("HINTS container horizontal %p\n", _w);
   *height = this->hint_height;
 }
 
+static void horizontal_button(gui *_g, widget *_this, int x, int y,
+    int button, int up)
+{
+printf("BUTTON container horizontal %p xy %d %d button %d up %d\n", _this, x, y, button, up);
+  struct gui *g = _g;
+  struct container_widget *this = _this;
+  struct widget_list *l;
+
+  l = this->common.children;
+  while (l) {
+    if (l->item->x <= x && x < l->item->x + l->item->width) {
+      l->item->button(g, l->item, x - l->item->x, y, button, up);
+      break;
+    }
+    l = l->next;
+  }
+}
+
+static void vertical_button(gui *_g, widget *_this, int x, int y,
+    int button, int up)
+{
+printf("BUTTON container vertical %p xy %d %d button %d up %d\n", _this, x, y, button, up);
+  struct gui *g = _g;
+  struct container_widget *this = _this;
+  struct widget_list *l;
+
+  l = this->common.children;
+  while (l) {
+    if (l->item->y <= y && y < l->item->y + l->item->height) {
+      l->item->button(g, l->item, x, y - l->item->y, button, up);
+      break;
+    }
+    l = l->next;
+  }
+}
+
 static void paint(gui *_gui, widget *_this)
 {
 printf("PAINT container\n");
@@ -197,9 +233,11 @@ widget *new_container(gui *_gui, int vertical)
   if (vertical) {
     w->common.allocate  = vertical_allocate;
     w->common.hints     = vertical_hints;
+    w->common.button    = vertical_button;
   } else {
     w->common.allocate  = horizontal_allocate;
     w->common.hints     = horizontal_hints;
+    w->common.button    = horizontal_button;
   }
 
   gunlock(g);
diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h
index 8a3e4b77018f606e2cdc68c005570316ab4787fe..8f680c95030373cae774096607d8eb64bf21cd2a 100644
--- a/common/utils/T/tracer/gui/gui_defs.h
+++ b/common/utils/T/tracer/gui/gui_defs.h
@@ -47,6 +47,8 @@ struct widget {
   void (*hints)(gui *g, widget *this, int *width, int *height);
   void (*paint)(gui *g, widget *this);
   void (*clear)(gui *g, widget *this);
+  /* user input */
+  void (*button)(gui *g, widget *this, int x, int y, int button, int up);
 };
 
 struct widget_list {
diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/text_list.c
index bd664bdb65720f6cb21c933f1bccc9873875819c..009964cdc384d0807194f9d48cde687284c60f04 100644
--- a/common/utils/T/tracer/gui/text_list.c
+++ b/common/utils/T/tracer/gui/text_list.c
@@ -44,6 +44,12 @@ static void allocate(
 printf("ALLOCATE text_list %p xywh %d %d %d %d nlines %d\n", this, x, y, width, height, this->allocated_nlines);
 }
 
+static void button(gui *g, widget *_this, int x, int y, int button, int up)
+{
+  struct text_list_widget *this = _this;
+printf("BUTTON test_list %p xy %d %d button %d up %d\n", this, x, y, button, up);
+}
+
 widget *new_text_list(gui *_gui, int width, int nlines, int bgcol)
 {
   struct gui *g = _gui;
@@ -63,6 +69,8 @@ widget *new_text_list(gui *_gui, int width, int nlines, int bgcol)
   w->common.hints = hints;
   w->common.allocate = allocate;
 
+  w->common.button = button;
+
   gunlock(g);
 
   return w;
diff --git a/common/utils/T/tracer/gui/toplevel_window.c b/common/utils/T/tracer/gui/toplevel_window.c
index 62313290777537823f68106a099af4bf1f4b4a18..fef72b32cc5299cce40c7c1bb32f911c3299ebfd 100644
--- a/common/utils/T/tracer/gui/toplevel_window.c
+++ b/common/utils/T/tracer/gui/toplevel_window.c
@@ -55,6 +55,16 @@ printf("PAINT toplevel_window (%d %d)\n", this->common.width, this->common.heigh
   g->xwin = NULL;    /* TODO: remove? it's just in case */
 }
 
+static void button(gui *_g, widget *_this, int x, int y, int button, int up)
+{
+  struct gui *g = _g;
+  struct toplevel_window_widget *this = _this;
+  g->xwin = this->x;
+  this->common.children->item->button(_g, this->common.children->item,
+      x, y, button, up);
+  g->xwin = NULL;    /* TODO: remove? it's just in case */
+}
+
 /**********************************************************************/
 /*                              creation                              */
 /**********************************************************************/
@@ -78,6 +88,8 @@ widget *new_toplevel_window(gui *_gui, int width, int height, char *title)
   w->common.allocate  = allocate;
   w->common.paint     = paint;
 
+  w->common.button    = button;
+
   gunlock(g);
 
   return w;
diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c
index 103d36d452a2d489e9d74716008a0895440ca6ae..6a34d00d068a8eb71a4e17192b8cbb095c06fef8 100644
--- a/common/utils/T/tracer/gui/widget.c
+++ b/common/utils/T/tracer/gui/widget.c
@@ -13,6 +13,8 @@ static void default_allocate(
 static void default_add_child(
     gui *_gui, widget *_this, widget *child, int position);
 static void default_hints(gui *g, widget *this, int *width, int *height);
+static void default_button(gui *gui, widget *_this, int x, int y, int button,
+    int up);
 
 static void toplevel_list_append(struct gui *g, struct widget *e)
 {
@@ -47,6 +49,7 @@ widget *new_widget(struct gui *g, enum widget_type type, int size)
   ret->add_child = default_add_child;
   ret->allocate  = default_allocate;
   ret->hints     = default_hints;
+  ret->button    = default_button;
   /* there is no default paint, on purpose */
 
   ret->type      = type;
@@ -159,6 +162,12 @@ static void default_hints(gui *g, widget *this, int *width, int *height)
   *height = 1;
 }
 
+static void default_button(gui *gui, widget *_this, int x, int y, int button,
+    int up)
+{
+  /* nothing */
+}
+
 /*************************************************************************/
 /*                             utils functions                           */
 /*************************************************************************/
diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c
index d739cc9b4f75154759b4b470b7fab87681ab2d6f..50164dce359a570a2df901b5e1c3dac46bb8dae6 100644
--- a/common/utils/T/tracer/gui/x.c
+++ b/common/utils/T/tracer/gui/x.c
@@ -158,7 +158,7 @@ printf("XEV %d\n", ev.type);
       }
       break;
     case ConfigureNotify:
-      if ((w = find_x_window(g, ev.xexpose.window)) != NULL) {
+      if ((w = find_x_window(g, ev.xconfigure.window)) != NULL) {
         struct x_window *xw = w->x;
         xw->resize = 1;
         xw->new_width = ev.xconfigure.width;
@@ -168,9 +168,21 @@ printf("XEV %d\n", ev.type);
 printf("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height);
       }
       break;
+    case ButtonPress:
+      if ((w = find_x_window(g, ev.xbutton.window)) != NULL) {
+        w->common.button(g, w, ev.xbutton.x, ev.xbutton.y,
+            ev.xbutton.button, 0);
+      }
+      break;
+    case ButtonRelease:
+      if ((w = find_x_window(g, ev.xbutton.window)) != NULL) {
+        w->common.button(g, w, ev.xbutton.x, ev.xbutton.y,
+            ev.xbutton.button, 1);
+      }
+      break;
 #if 0
     case MapNotify:
-      if ((w = find_x_window(g, ev.xexpose.window)) != NULL) {
+      if ((w = find_x_window(g, ev.xmap.window)) != NULL) {
         struct x_window *xw = w->x;
         xw->repaint = 1;
       }