Re: Focus weirdness



Alright I've finally solved it. I had to pass the focus manually from the
GtkDrawingArea to the embedded xterm using XSetInputFocus(). Can somebody
suggest a cleaner or a more GTK-ish way of doing this?

I've tried with GtkSocket and gtk_socket_steal() but I still had to pass the
focus manually.

The minimal working example follows.

David


-------------------------------------------------
FILE: minex.c
-------------------------------------------------

// gcc -o minex -Wall `pkg-config --cflags --libs gtk+-2.0` minex.c &&
./minex

#include <glib.h>
#include <glib/gprintf.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>

static XID
get_child_xid(GtkWidget *widget) {
    Window win = GDK_WINDOW_XID(gtk_widget_get_window(widget));
    Window root_win, parent_win, *children;
    unsigned int nchildren;
    XID child;

    if (!XQueryTree(GDK_DISPLAY(), win, &root_win, &parent_win, &children,
&nchildren))
        return 0;
    child = (nchildren > 0) ? children[0] : 0;
    XFree((char *) children);
    return child;
}

static void
destroy(GtkWidget *widget, gpointer data)
{
    gtk_main_quit();
}

static void
realize(GtkWidget *xterm_area, gpointer data)
{
    char cmd[256];
    g_sprintf(cmd, "xterm -into %lu",
GDK_WINDOW_XID(gtk_widget_get_window(xterm_area)));
    g_spawn_command_line_async(cmd, NULL);
}

static gboolean
focus_in_event(GtkWidget *xterm_area, GdkEventFocus *event, gpointer data)
{
    XID child = get_child_xid(xterm_area);
    if (child) {
        XSetInputFocus(GDK_DISPLAY(), child, RevertToParent,
GDK_CURRENT_TIME);
    }
    return TRUE;
}

int
main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *xterm_area;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy),
NULL);

    xterm_area = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER(window), xterm_area);

    gtk_widget_set_size_request(GTK_WIDGET(xterm_area), 484, 316);
    gtk_widget_show(xterm_area);

    GTK_WIDGET_SET_FLAGS(xterm_area, GTK_CAN_FOCUS);

    g_signal_connect(G_OBJECT(xterm_area), "realize", G_CALLBACK(realize),
NULL);
    g_signal_connect(G_OBJECT(xterm_area), "focus-in-event",
G_CALLBACK(focus_in_event), NULL);

    gtk_widget_show(window);
    gtk_main();

    return 0;
}



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