Hello, I'm trying to achieve a canvas-like functionality using a GtkFixed widget. I know, there's GnomeCanvas, but I can't use it, it's buggy on win32. The problem is, when I'm trying to move a widget it starts shaking, like having a double. You can try it for yourself. Where am I doing wrong? Is there any alternative? Here's the code. Click on the label above the button and try moving it. #include <gtk/gtk.h> /* I'm going to be lazy and use some global variables to * store the position of the widget within the fixed * container */ gint x = 50; gint y = 50; /* This callback function moves the button to a new position * in the Fixed container. */ void move_button( GtkWidget *widget, GtkWidget *fixed ) { x = (x + 30) % 300; y = (y + 50) % 300; gtk_fixed_move (GTK_FIXED (fixed), widget, x, y); } int dragging, item_x, item_y, new_x, new_y; void do_move (GtkWidget *w) { GtkWidget *vbox = g_object_get_data(w, "vbox"); GtkWidget *fixed = g_object_get_data(w, "fixed"); gtk_fixed_move (GTK_FIXED (fixed), vbox, new_x, new_y); } gint img_event (GtkWidget *w, GdkEvent *ev, int where) { if (ev->type == GDK_BUTTON_PRESS || ev->type == GDK_BUTTON_RELEASE || ev->type == GDK_MOTION_NOTIFY) { } else { return FALSE; } switch (ev->type) { case GDK_BUTTON_PRESS: switch (ev->button.button) { case 1: { GtkWidget *vbox = g_object_get_data(w, "vbox"); item_x = ev->button.x; item_y = ev->button.y; gtk_grab_add (w); dragging = 1; break; } } break; case GDK_MOTION_NOTIFY: if (ev->motion.state & GDK_BUTTON1_MASK) { if (dragging) { GtkWidget *vbox = g_object_get_data(w, "vbox"); GtkWidget *fixed = g_object_get_data(w, "fixed"); GtkWidget *g = gtk_grab_get_current (); g_return_val_if_fail(vbox!=NULL, FALSE); new_x = ev->motion.x; new_y = ev->motion.y; g_idle_add (do_move, w); } } break; case GDK_BUTTON_RELEASE: gtk_grab_remove(gtk_grab_get_current ()); break; } return FALSE; } int main( int argc, char *argv[] ) { /* GtkWidget is the storage type for widgets */ GtkWidget *window; GtkWidget *fixed; GtkWidget *button, *vbox, *label; gint i; /* Initialise GTK */ gtk_init (&argc, &argv); /* Create a new window */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Fixed Container"); /* Here we connect the "destroy" event to a signal handler */ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); /* Sets the border width of the window. */ gtk_container_set_border_width (GTK_CONTAINER (window), 10); /* Create a Fixed Container */ fixed = gtk_fixed_new (); gtk_container_add (GTK_CONTAINER (window), fixed); gtk_widget_show (fixed); for (i = 1 ; i <= 3 ; i++) { /* Creates a new button with the label "Press me" */ button = gtk_button_new_with_label ("Press me"); /* When the button receives the "clicked" signal, it will call the * function move_button() passing it the Fixed Container as its * argument. */ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (move_button), (gpointer) fixed); vbox = gtk_vbox_new (FALSE,2); label = gtk_label_new ("gutfhg"); { GtkWidget *event_box = gtk_event_box_new (); gtk_container_add (GTK_CONTAINER (event_box), label); gtk_widget_add_events (event_box, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK); g_signal_connect(G_OBJECT(event_box), "event", G_CALLBACK(img_event), 0); gtk_box_pack_start (GTK_BOX (vbox), event_box, FALSE, FALSE, 0); g_object_set_data (G_OBJECT(event_box), "vbox", vbox); g_object_set_data (G_OBJECT(event_box), "fixed", fixed); } gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0); /* This packs the button into the fixed containers window. */ gtk_fixed_put (GTK_FIXED (fixed), vbox, i*50, i*50); /* The final step is to display this newly created widget. */ gtk_widget_show_all (vbox); } /* Display the window */ gtk_widget_show (window); /* Enter the event loop */ gtk_main (); return 0; } -- _______________________________________________ Get your free email from http://mymail.skim.com _______________________________________________ gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list