Well if I need to do something like that, probably I’ll try to think it first how should the program flow works.
Now I am not sure that I Understand what are you trying to achieve there, but from what I understand this is what you try to do:
Code:
#include <gtk/gtk.h>
#define EVENTS_MASK ( GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_SCROLL_MASK )
gulong handler_window_scroll;
gulong handler_button_scroll;
void scroll_up_func ( const gchar *const msg );
void scroll_down_func ( const gchar *const msg );
void enter_surface_func ( const gchar *const msg );
void leave_surface_func ( const gchar *const msg );
gboolean show_enter_event ( GtkWidget *widget, GdkEvent *event, gpointer data );
gboolean show_leave_event ( GtkWidget *widget, GdkEvent *event, gpointer data );
gboolean show_scroll_event ( GtkWidget *widget, GdkEvent *event, gpointer data );
int main ( int argc, char **argv )
{
GtkWidget *window;
GtkWidget *button;
/// ***
gtk_init ( &argc, &argv );
window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
gtk_window_set_default_size ( GTK_WINDOW ( window ), 200, 200 );
gtk_widget_show ( window );
/// ***
button = gtk_button_new_with_label ( "Click me" );
g_object_set ( button, "margin", 50, NULL );
gtk_container_add ( GTK_CONTAINER ( window ), button );
/// ******************************************************************************************************************************
gint window_events;
window_events = gtk_widget_get_events ( window ) | EVENTS_MASK;
gtk_widget_add_events ( window, window_events );
g_signal_connect ( window, "enter-notify-event", G_CALLBACK ( show_enter_event ), button );
g_signal_connect ( window, "leave-notify-event", G_CALLBACK ( show_leave_event ), button );
handler_window_scroll = g_signal_connect ( window, "scroll-event", G_CALLBACK ( show_scroll_event ), button );
/// ******************************************************************************************************************************
gint button_events;
button_events = gtk_widget_get_events ( button ) | EVENTS_MASK;
gtk_widget_add_events ( button, button_events );
g_signal_connect ( button, "enter-notify-event", G_CALLBACK ( show_enter_event ), window );
g_signal_connect ( button, "leave-notify-event", G_CALLBACK ( show_leave_event ), window );
handler_button_scroll = g_signal_connect ( button, "scroll-event", G_CALLBACK ( show_scroll_event ), window );
/// ******************************************************************************************************************************
g_signal_handler_block ( window, handler_window_scroll );
g_signal_handler_block ( button, handler_button_scroll );
/// ***
gtk_widget_show_all ( window );
gtk_main();
}
void enter_surface_func ( const gchar *const msg )
{
g_print ( "The mouse enter the %s area.\n", msg );
}
void leave_surface_func ( const gchar *const msg )
{
g_print ( "\tThe mouse is leaving the %s area.\n", msg );
}
void scroll_up_func ( const gchar *const msg )
{
g_print ( "%s Scroll-UP Detected\n", msg );
}
void scroll_down_func ( const gchar *const msg )
{
g_print ( "%s Scroll-Down Detected\n", msg );
}
gboolean show_enter_event ( GtkWidget *widget, GdkEvent *event, gpointer data )
{
static gboolean flag = TRUE;
if ( event->type == GDK_ENTER_NOTIFY )
{
if ( GTK_IS_BUTTON ( widget ) )
{
enter_surface_func ( "'Button'" );
if ( flag == FALSE )
{
g_signal_handler_block ( data, handler_window_scroll );
flag = TRUE;
return GDK_EVENT_PROPAGATE;
}
}
if ( GTK_IS_WINDOW ( widget ) )
{
enter_surface_func ( "'Window'" );
if ( flag == TRUE )
{
g_signal_handler_unblock ( widget, handler_window_scroll );
flag = FALSE;
return GDK_EVENT_PROPAGATE;
}
}
}
return GDK_EVENT_STOP;
}
gboolean show_leave_event ( GtkWidget *widget, GdkEvent *event, gpointer data )
{
static gboolean flag = TRUE;
if ( event->type == GDK_LEAVE_NOTIFY )
{
if ( GTK_IS_BUTTON ( widget ) )
{
leave_surface_func ( "'Button'" );
if ( flag == FALSE )
{
g_signal_handler_block ( widget, handler_button_scroll );
flag = TRUE;
return GDK_EVENT_PROPAGATE;
}
}
if ( GTK_IS_WINDOW ( widget ) )
{
leave_surface_func ( "'Window'" );
if ( flag == TRUE )
{
g_signal_handler_unblock ( data, handler_button_scroll );
flag = FALSE;
return GDK_EVENT_PROPAGATE;
}
}
}
return GDK_EVENT_STOP;
}
gboolean show_scroll_event ( GtkWidget *widget, GdkEvent *event, gpointer data )
{
if ( event->type == GDK_SCROLL )
{
if ( event->scroll.direction == GDK_SCROLL_DOWN )
{
if ( GTK_IS_WINDOW ( widget ) )
{
scroll_down_func ( "'Window'" );
}
else
{
scroll_down_func ( "'Button'" );
}
}
if ( event->scroll.direction == GDK_SCROLL_UP )
{
if ( GTK_IS_BUTTON ( data ) )
{
scroll_up_func ( "'Window'" );
}
else
{
scroll_up_func ( "'Button'" );
}
}
}
return GDK_EVENT_STOP;
}
And the program flow is like this:
The mouse enter the 'Window' area.
'Window' Scroll-Down Detected
'Window' Scroll-UP Detected
The mouse is leaving the 'Window' area.
The mouse enter the 'Button' area.
'Button' Scroll-Down Detected
'Button' Scroll-UP Detected
The mouse is leaving the 'Button' area.
The mouse enter the 'Window' area.
The mouse is leaving the 'Window' area.
It is not much to explain here, but more important is, that I am monitorin enter-notify-event
and leave-notify-event
events and based on which widget has focus I am blocking and unblocking their scroll-event
.
Now of course, the program does what you need, but there is no certitude that works at all.
More over because I did not test it enough.
Have fun with GTK.