Re: CList/CTree and Pointer Grabs

Thanks, Vlad ...

Using an idle func doesn't help, unfortunately - the idle func is still
invoked while the clist holds the grab.

The problem, it turns out, is using GTK_SELECTION_BROWSE as the clist
selection mode. Browse mode makes the clist emit the signal while it
holds the grab.

The code at the end demonstrates this - if you run the progran with any
arg, it puts the clist into browse mode, otherwise leaves it in the
default "single selection" mode. The check_grab function is invoked
either immediately (from the signal handler), or via gtk_idle_add(),
depending on which row you select. In "browse" mode, both invocation
methods call check_grab() with a pointer grab set. Neither have a grab
when in single mode.

The reason I wanted to use browse mode is because you can't have a null
selection in this way, whereas GTK_SELECTION_SINGLE allows you to have a
clist with nothing highlighted. I want to have exactly one item
highlighted at all times.

I suppose I'll have to use "single" mode and code around it (I managed
to do something similar with an "Undo/Redo Special" type of dialog, so I
guess I can handle this one :-)


Vlad Harchev wrote:
>  This question is asked here about each 3 month. Solution is to add one-shot
> idle function (gtk_idle_add) in the button-press-event handler, that function
> should run anything needed (like popping up dialog) and return 0 (I don't
> remember exactly - it should return the value that causes idle function to be
> removed - find out it in the docs). When that idle function will be run,
> clist/ctree won't be holding the grab.
> > I have a signal function connected to a CTree via "tree_select_row".
> > Occasionally, this function detects an "error" and pops up a Gnome
> > message box, which it runs using gnome_dialog_run_and_close().
> >
> > Unfortunately, since the underlying CList does a grab on the button
> > press (both a GTK grab and a pointer grab), I can't OK the message box
> > (nor can I select an xterm to kill the application :-(

#include <gtk/gtk.h>

gint check_grab(gpointer data)
                printf("pointer IS grabbed\n");
                printf("pointer is NOT grabbed\n");
        return FALSE;

void cb_select(GtkWidget *w, gint row, gint col, GdkEventButton *b,
gpointer *x)
        printf("select row: row = %d\n", row);
        if(row == 0)
                check_grab(NULL); /* immediate */
                gtk_idle_add(check_grab, NULL); /* with idle */

main(int argc, char **argv)
        GtkWidget *app, *clist;
        gchar *cstr;

        gtk_init(&argc, &argv);
        app = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        clist = gtk_clist_new(1);
        gtk_signal_connect(GTK_OBJECT(clist), "select_row",
                                GTK_SIGNAL_FUNC(cb_select), NULL);
        if(argc > 1)
        cstr = "immediate";
        gtk_clist_append(GTK_CLIST(clist), &cstr);
        cstr = "with idle";
        gtk_clist_append(GTK_CLIST(clist), &cstr);
        gtk_container_add(GTK_CONTAINER(app), clist);
        return 0;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]