Transparent Window Focus



I've written a test program to teach myself gtk.  A red block appears on
the screen, 50 pixels square.  If the user moves the mouse over it, the
block will attach itself to the mouse, and when you move the mouse, the
block will follow it.  The problem is, the window focus only applies to
the red block, although the window is resized to the entire screen.
Also, if you move the mouse fast enough, it the block will detach itself
from the mouse.  (It can be reattached by moving the mouse over it
again).

I want to be able to define which areas of the window are 'focusable',
the way I can define transparency with a mask.  And I'd also, more
importantly, I'd like to fix the 'detaching' problem.

Thanks.

The source for the program follows:

#include <gtk/gtk.h>

static GdkBitmap *mask;
static GdkColor white, black; // white = opaque, black = clear
static GdkColor red;
static int x, y;
static GdkGC *gc, *maskgc;
static GdkPixmap *mask;
static GtkWidget *canvas;
static GtkWidget *window;
static int xsize, ysize;


void expose_handler(GtkWidget *widget, gpointer data) {
        gc = gdk_gc_new(widget->window);
        gdk_gc_set_foreground(gc, &red);
        gdk_draw_rectangle(widget->window, gc, TRUE, x - 25, y - 25, 50,
50);

        gdk_gc_set_foreground(maskgc, &black);
        gdk_draw_rectangle(mask, maskgc, TRUE, 0, 0, xsize, ysize);

        gdk_gc_set_foreground(maskgc, &white);
        gdk_draw_rectangle(mask, maskgc, TRUE, x - 25, y - 25, 50, 50);

        gtk_widget_shape_combine_mask(window, mask, 0, 0);


        g_print("expose handler\n");
}

gint motion_notify_event(GtkWidget *widget, GdkEventMotion *event) {
        GdkModifierType state;
        int x1, y1;

        gdk_window_get_pointer(event->window, &x1, &y1, &state);
        x = x1;
        y = y1;

        g_print("motion notify event\n");

        expose_handler(widget, NULL);
}

int main(int argc, char *argv[]) {
        gtk_init(&argc, &argv);

        xsize = gdk_screen_width();
        ysize = gdk_screen_height();

        x = y = 200;

        window = gtk_window_new(GTK_WINDOW_POPUP);
        gtk_window_set_default_size(GTK_WINDOW(window),
gdk_screen_width(), gdk_screen_height());
        gtk_container_set_border_width(GTK_CONTAINER(window), 0);

        gdk_color_parse("white", &white);
        gdk_color_alloc(gtk_widget_get_colormap(window), &white);

        gdk_color_parse("black", &black);
        gdk_color_alloc(gtk_widget_get_colormap(window), &black);

        gdk_color_parse("red", &red);
        gdk_color_alloc(gtk_widget_get_colormap(window), &red);

        canvas = gtk_drawing_area_new();
        gtk_drawing_area_size(GTK_DRAWING_AREA(canvas), xsize, ysize);
        gtk_widget_show(canvas);
        gtk_container_add(GTK_CONTAINER(window), canvas);
        gtk_signal_connect(GTK_OBJECT(canvas), "expose_event",
GTK_SIGNAL_FUNC(expose_handler), NULL);
        gtk_signal_connect(GTK_OBJECT(canvas), "motion_notify_event",
GTK_SIGNAL_FUNC(motion_notify_event), NULL);

        gtk_widget_set_events (canvas, GDK_EXPOSURE_MASK
                                            | GDK_LEAVE_NOTIFY_MASK
                                            | GDK_BUTTON_PRESS_MASK
                                            | GDK_POINTER_MOTION_MASK
                                            |
GDK_POINTER_MOTION_HINT_MASK);

        mask = gdk_pixmap_new(window->window, xsize, ysize, 1);

        maskgc = gdk_gc_new(mask);
        gc = gdk_gc_new(canvas->window);

        gdk_gc_set_foreground(maskgc, &black);
        gdk_draw_rectangle(mask, maskgc, TRUE, 0, 0, xsize, ysize);

        gdk_gc_set_foreground(maskgc, &white);
        gdk_draw_rectangle(mask, maskgc, TRUE, x - 25, y - 25, 50, 50);

        gtk_widget_shape_combine_mask(window, mask, 0, 0);

        gtk_widget_show(window);

        gtk_main();
}






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