Re: how to determine if a window has been entered/exited
- From: Olivier Fourdan <fourdan xfce org>
- To: Brian Cameron <Brian Cameron sun com>
- Cc: gtk-devel-list gnome org
- Subject: Re: how to determine if a window has been entered/exited
- Date: 08 May 2003 16:21:09 +0200
Hi Brian,
You may want to check the detail field of the enter/leave notify event
in the event handler; something like this :
if (event->detail != GDK_NOTIFY_INFERIOR)
{
/* Your code here */
}
Cheers,
--
Olivier Fourdan <fourdan xfce org>
http://www.xfce.org
On Thu, 2003-05-08 at 15:31, Brian Cameron wrote:
> Gtk+ experts:
>
> For accessibility purposes, I am trying to write a GTK_MODULE that will
> detect when the mouse has crossed the border of a window. In other
> words, when the mouse moves from outside the window border to inside
> the window, or from inside the window to outside the window border.
>
> I have tried using enter-notify-event and leave-notify-event signals
> on the toplevel GtkWindows, and this does not work. The problem is
> easily explained by using the gnome-calculator as an example. The
> area around the buttons is considered a part of the GtkWindow, so
> you get window enter events each time you leave a button, and you
> get window leave events each time you enter a button.
>
> Since the GdkCrossing structure only gives you the x/y location
> at the time that the event was generated, it seems impossible to use
> this to determine if the user entered the window from outside window
> or if the user entered the window from a button (and the similar
> problem for leaving).
>
> I have attached an example program where I try and use different
> techniques to access the information from the enter/leave events.
> All approaches in this sample have the same issues.
>
> Is there any way to detect that the mouse has moved from outside the
> window border into the window, or from inside the window border to
> outside the window?
>
> Brian
>
> ______________________________________________________________________
>
> /* GDM - The Gnome Display Manager
> * Copyright (C) 1999, 2000 Martin K. Petersen <mkp mkp net>
> *
> * This file Copyright (c) 2003 Sun Microsystems Inc.
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> * the Free Software Foundation; either version 2 of the License, or
> * (at your option) any later version.
> *
> * This program is distributed in the hope that it will be useful,
> * but WITHOUT ANY WARRANTY; without even the implied warranty of
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> * GNU General Public License for more s.
> *
> * You should have received a copy of the GNU General Public License
> * along with this program; if not, write to the Free Software
> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> */
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <ctype.h>
> #include <string.h>
>
> #include <X11/Xlib.h>
> #include <X11/Xutil.h>
> #include <X11/keysym.h>
>
> #include <glib.h>
> #include <gmodule.h>
> #include <gdk/gdk.h>
> #include <gdk/gdkx.h>
> #include <gtk/gtk.h>
> #include <gnome.h>
> /*
> #include <glib-object.h>
> */
>
> #include <config.h>
>
> /*
> * Note that CONFIGFILE will have to be changed to something more generic
> * if this module is ever moved outside of gdm.
> */
>
> #define CONFIGFILE EXPANDED_SYSCONFDIR "/gdm/modules/AccessKeyMouseEvents"
> #define iseol(ch) ((ch) == '\r' || (ch) == '\f' || (ch) == '\0' || \
> (ch) == '\n')
>
> typedef enum
> {
> BINDING_TYPE_KEY = 1 << 0,
> BINDING_TYPE_MOUSE = 1 << 1
> } BindingType;
>
> typedef struct {
> guint keysym;
> GdkModifierType state;
> guint keycode;
> } Key;
>
> typedef struct {
> guint number;
> GdkModifierType state;
> } Button;
>
> union Input {
> Key key;
> Button button;
> };
>
> typedef struct {
> BindingType type;
> union Input input;
> char *binding_str;
> GSList *actions;
> guint n_times;
> guint duration;
> guint timeout;
> } Binding;
>
> static int lineno = 0;
> static GSList *binding_list = NULL;
> extern char **environ;
>
> static void create_event_watcher ();
>
> /* test using filter */
>
> GdkFilterReturn
> enter_filter (GdkXEvent *gdk_xevent,
> GdkEvent *event,
> gpointer data)
> {
> XEvent *xevent = (XEvent *)gdk_xevent;
>
> if (xevent->type != EnterNotify)
> return GDK_FILTER_CONTINUE;
>
> printf("filter: %p %p\n", xevent->xcrossing.window, xevent->xcrossing.subwindow);
> printf ("%d %d %d %d - ",
> xevent->xcrossing.x,
> xevent->xcrossing.y,
> xevent->xcrossing.x_root,
> xevent->xcrossing.y_root);
>
> if (xevent->xcrossing.detail == NotifyAncestor)
> printf("NotifyAncestor\n");
> if (xevent->xcrossing.detail == NotifyInferior)
> printf("NotifyInferior\n");
> if (xevent->xcrossing.detail == NotifyVirtual)
> printf("NotifyVirtual\n");
> if (xevent->xcrossing.detail == NotifyNonlinear)
> printf("NotifyNonlinear\n");
> if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
> printf("NotifyNonlinearVirtual\n");
>
>
>
> return GDK_FILTER_CONTINUE;
> }
>
> /* using emission-hook */
> static gboolean
> enter_emission_hook (GSignalInvocationHint *ihint,
> guint n_param_values,
> const GValue *param_values,
> gpointer data)
> {
> GObject *object;
> GtkWindow *window;
> GdkEventCrossing *event;
>
> object = g_value_get_object (param_values + 0);
> event = g_value_get_boxed (param_values + 1);
>
> if (GTK_IS_WINDOW(object) && GTK_WIDGET_TOPLEVEL(object))
> printf("window - emission-hook: %p %p %p\n", object, event->window, event->subwindow);
> else
> printf("non-window - emission-hook: %p %p %p\n", object, event->window, event->subwindow);
>
> return TRUE;
> }
>
> /* Using signal-connect */
>
> gboolean
> signal_connect_enter_cb (GtkWidget *widget,
> GdkEventCrossing *event,
> gpointer user_data)
> {
> if (GTK_IS_WINDOW(widget) && GTK_WIDGET_TOPLEVEL(widget))
> printf("window - signal-connect: %p %p %p\n", widget, event->window, event->subwindow);
> else
> printf("non-window - signal-connect: %p %p %p\n", widget, event->window, event->subwindow);
> }
>
> /* this emission hook is used to set up the signal-connect situation. It connects any
> window that is shown to the enter-notify-event signal. */
>
> static gboolean
> show_event_emission_hook (GSignalInvocationHint *ihint,
> guint n_param_values,
> const GValue *param_values,
> gpointer data)
> {
> GObject *object;
> GtkWidget *widget;
>
> object = g_value_get_object (param_values + 0);
>
> if (!GTK_IS_WINDOW (object))
> return TRUE;
>
> widget = GTK_WIDGET(object);
>
> g_signal_connect(widget, "enter-notify-event", G_CALLBACK(signal_connect_enter_cb), NULL);
> }
>
> static void create_event_watcher ()
> {
> GSList *li;
> GdkDisplay *display;
> guint signal_id;
>
> display = gdk_display_get_default();
> if (!display) {
> return;
> }
>
> /* set up filter */
> gdk_window_add_filter (NULL, enter_filter, NULL);
>
> gtk_type_class (GTK_TYPE_WIDGET);
>
> /* set up emission hook */
> g_signal_add_emission_hook(
> g_signal_lookup("enter-notify-event", GTK_TYPE_WIDGET), 0,
> enter_emission_hook, NULL, (GDestroyNotify) NULL);
>
> /* set up emission hook that will then set up the direct g_connect on the window */
> gtk_type_class (GTK_TYPE_WINDOW);
>
> signal_id = g_signal_lookup ("show", GTK_TYPE_WINDOW);
> g_signal_add_emission_hook (signal_id, 0,
> show_event_emission_hook, NULL, (GDestroyNotify) NULL);
>
> return;
> }
>
> /* The init function for this gtk module */
> G_MODULE_EXPORT void gtk_module_init(int *argc, char* argv[]);
>
> void gtk_module_init(int *argc, char* argv[])
> {
> create_event_watcher();
> }
>
> /* EOF */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]