* BUG: Try to handle Leave/Enter events the same way as in gb.qt4.


git-svn-id: svn://localhost/gambas/trunk@4606 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2012-04-07 13:51:02 +00:00
parent 78ad25c6f7
commit d55d7f41c3
3 changed files with 102 additions and 29 deletions

View File

@ -40,6 +40,7 @@
#include "gmainwindow.h" #include "gmainwindow.h"
//#define DEBUG_IM 1 //#define DEBUG_IM 1
//#define DEBUG_ENTER_LEAVE 1
/************************************************************************* /*************************************************************************
@ -308,6 +309,20 @@ static bool raise_key_event_to_parent_window(gControl *control, int type)
return false; return false;
} }
static bool check_crossing_event(GdkEvent *event)
{
#if DEBUG_ENTER_LEAVE
fprintf(stderr, "check_crossing_event: %d / %d\n", event->crossing.detail, event->crossing.mode);
#endif
if (event->crossing.detail != GDK_NOTIFY_INFERIOR
&& (event->crossing.mode == GDK_CROSSING_NORMAL || event->crossing.mode == GDK_CROSSING_STATE_CHANGED))
// || event->crossing.mode == GDK_CROSSING_UNGRAB || event->crossing.mode == GDK_CROSSING_GTK_UNGRAB))
return true;
else
return false;
}
static void gambas_handle_event(GdkEvent *event) static void gambas_handle_event(GdkEvent *event)
{ {
GtkWidget *widget; GtkWidget *widget;
@ -431,12 +446,20 @@ static void gambas_handle_event(GdkEvent *event)
//if (group != gApplication::currentGroup()) //if (group != gApplication::currentGroup())
// goto __HANDLE_EVENT; // goto __HANDLE_EVENT;
if (event->type != GDK_ENTER_NOTIFY) if (!gdk_events_pending() && event->type != GDK_ENTER_NOTIFY && event->type != GDK_LEAVE_NOTIFY)
{ {
if (gApplication::_leave) if (gApplication::_leave)
{ {
if (event->type != GDK_LEAVE_NOTIFY || gApplication::_leave != control) //if () // || (gApplication::_leave != control && check_crossing_event(event)))
gApplication::_leave->emit(SIGNAL(gApplication::_leave->onEnterLeave), gEvent_Leave); #if DEBUG_ENTER_LEAVE
fprintf(stderr, "post leave: %s\n", gApplication::_leave->name());
#endif
if (gApplication::_enter == gApplication::_leave)
gApplication::_enter = NULL;
gApplication::_leave->emitLeaveEvent();
gApplication::_leave = NULL; gApplication::_leave = NULL;
} }
} }
@ -449,25 +472,53 @@ static void gambas_handle_event(GdkEvent *event)
{ {
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
//gApplication::dispatchEnterLeave(control);
if (gApplication::_leave == control) if (gApplication::_leave == control)
{
#if DEBUG_ENTER_LEAVE
fprintf(stderr, "enter ignored: %s\n", control->name());
#endif
gApplication::_leave = NULL; gApplication::_leave = NULL;
}
else if (gApplication::_enter != control) else if (gApplication::_enter != control)
{ {
gApplication::_enter = control; if (check_crossing_event(event))
control->emit(SIGNAL(control->onEnterLeave), gEvent_Enter); {
#if DEBUG_ENTER_LEAVE
fprintf(stderr, "enter: %s\n", control->name());
#endif
gApplication::_enter = control;
control->emitEnterEvent();
}
} }
break; break;
case GDK_LEAVE_NOTIFY: case GDK_LEAVE_NOTIFY:
if (gdk_events_pending()) if (gdk_events_pending() && gApplication::_leave == NULL)
gApplication::_leave = control;
else
{ {
if (gApplication::_enter == control) if (check_crossing_event(event))
gApplication::_enter = NULL; {
control->emit(SIGNAL(control->onEnterLeave), gEvent_Leave); #if DEBUG_ENTER_LEAVE
fprintf(stderr, "leave later: %s\n", control->name());
#endif
gApplication::_leave = control;
}
}
else if (gApplication::_leave != control)
{
if (check_crossing_event(event))
{
if (gApplication::_enter == control)
gApplication::_enter = NULL;
if (gApplication::_leave == control)
gApplication::_leave = NULL;
#if DEBUG_ENTER_LEAVE
fprintf(stderr, "leave: %s\n", control->name());
#endif
control->emitLeaveEvent();
}
} }
break; break;

View File

@ -237,6 +237,7 @@ void gControl::initAll(gContainer *parent)
_no_default_mouse_event = false; _no_default_mouse_event = false;
_proxy = _proxy_for = NULL; _proxy = _proxy_for = NULL;
_no_tab_focus = false; _no_tab_focus = false;
_inside = false;
onFinish = NULL; onFinish = NULL;
onFocusEvent = NULL; onFocusEvent = NULL;
@ -1859,3 +1860,21 @@ void gControl::setNoTabFocus(bool v)
if (pr) if (pr)
pr->updateFocusChain(); pr->updateFocusChain();
} }
void gControl::emitEnterEvent()
{
if (_inside)
return;
emit(SIGNAL(onEnterLeave), gEvent_Enter);
_inside = true;
}
void gControl::emitLeaveEvent()
{
if (!_inside)
return;
emit(SIGNAL(onEnterLeave), gEvent_Leave);
_inside = false;
}

View File

@ -186,36 +186,36 @@ public:
unsigned dsg : 1; unsigned dsg : 1;
unsigned expa : 1; unsigned expa : 1;
unsigned igno : 1; unsigned igno : 1;
unsigned _action : 1; // *reserved* unsigned _action : 1; // *reserved*
unsigned _accept_drops : 1; // If the control accepts drops unsigned _accept_drops : 1; // If the control accepts drops
unsigned _drag_get_data : 1; // If we got information on the dragged data unsigned _drag_get_data : 1; // If we got information on the dragged data
unsigned _drag_enter : 1; // If we have entered the control for drag & drop unsigned _drag_enter : 1; // If we have entered the control for drag & drop
unsigned _tracking : 1; // If we are tracking mouse move even if no mouse button is pressed unsigned _tracking : 1; // If we are tracking mouse move even if no mouse button is pressed
unsigned _old_tracking : 1; // real value when Tracking is false unsigned _old_tracking : 1; // real value when Tracking is false
unsigned _bg_set : 1; // Have a private background unsigned _bg_set : 1; // Have a private background
unsigned _fg_set : 1; // Have a private foreground unsigned _fg_set : 1; // Have a private foreground
unsigned _font_set : 1; // Have a private font unsigned _font_set : 1; // Have a private font
unsigned have_cursor : 1; // If gApplication::setBusy() must update the cursor unsigned have_cursor : 1; // If gApplication::setBusy() must update the cursor
unsigned use_base : 1; // Use base and text color for foreground and background unsigned use_base : 1; // Use base and text color for foreground and background
unsigned visible : 1; // A control can be hidden if its width or height is zero unsigned visible : 1; // A control can be hidden if its width or height is zero
unsigned _destroyed : 1; // If the control has already been added to the destroy list unsigned _destroyed : 1; // If the control has already been added to the destroy list
unsigned _locked : 4; // For locking events unsigned _locked : 4; // For locking events
unsigned frame_border : 4; unsigned frame_border : 4;
unsigned frame_padding : 8; unsigned frame_padding : 8;
unsigned _scrolled_window : 1; unsigned _scrolled_window : 1;
unsigned _dirty_pos : 1; // If the position of the widget has changed unsigned _dirty_pos : 1; // If the position of the widget has changed
unsigned _dirty_size : 1; // If the size of the widget has changed unsigned _dirty_size : 1; // If the size of the widget has changed
unsigned _no_delete : 1; // Do not delete on destroy signal unsigned _no_delete : 1; // Do not delete on destroy signal
unsigned no_input_method : 1; // No input method management unsigned no_input_method : 1; // No input method management
unsigned _no_default_mouse_event : 1; // No default mouse events unsigned _no_default_mouse_event : 1; // No default mouse events
unsigned _grab : 1; // control is currently grabbing mouse and keyboard unsigned _grab : 1; // control is currently grabbing mouse and keyboard
unsigned _has_border : 1; // if the control has a border unsigned _has_border : 1; // if the control has a border
unsigned _no_tab_focus : 1; // Don't put inside focus chain unsigned _no_tab_focus : 1; // Don't put inside focus chain
unsigned _inside : 1; // if we got an enter event, but not a leave event yet.
void removeParent() { pr = NULL; } void removeParent() { pr = NULL; }
void initSignals(); void initSignals();
@ -245,6 +245,9 @@ public:
virtual int minimumHeight(); virtual int minimumHeight();
void resolveFont(gFont *new_font); void resolveFont(gFont *new_font);
void emitEnterEvent();
void emitLeaveEvent();
/* static gControl* dragWidget(); /* static gControl* dragWidget();
static void setDragWidget(gControl *ct); static void setDragWidget(gControl *ct);
static char *dragTextBuffer(); static char *dragTextBuffer();