Take putback events into account

* gdk/gdk.c (gdk_events_pending): Take putback events into
  account

* gdk/gdk.c (gdk_event_free): Handle dropdataavaible memory
  allocation correctly. (Incompatible change: client must
  _not_ fre event->data and event->data_type.)

* gdk/gdk.c (gdk_event_translate): Changed DND dragging
  so that we don't ungrab pointer when we reenter window
  to prevent extra Enter/Leave effects which had bad
  effects.
  Changed drag zone handling to not send uncessary
  DragEnter events.
  Fixed EnterNotify/LeaveNotify handling. (Only pay
  attention to events on window, don't specify these
  events to XGrabPointer - that isn't valid, and handle
  reverse the sense of the handling of LeaveNotify.)

* gdk/gdkwindow.c (gdk_window_remove_filter): Free removed
  filter.

* gtk/gtk.defs (GdkFont): gdk_font_free => gdk_font_unref

* gtk/gtkmain.{c,h} (gtk_events_pending): new function - apps
  should use this instead of gdk_events_pending.

* gtk/gtkvbbox.h: Fixed a duplication in the headers.

* gtk/testgtk.c (dnd_drop): Don't free the drop data,
  it belongs to the event.
This commit is contained in:
Owen Taylor 1998-01-17 23:24:09 +00:00
parent 2e99581612
commit 443648028c
10 changed files with 259 additions and 195 deletions

140
gdk/gdk.c
View File

@ -602,7 +602,19 @@ gdk_set_locale ()
gint
gdk_events_pending ()
{
return XPending (gdk_display);
gint result;
GList *tmp_list;
result = XPending (gdk_display);
tmp_list = putback_events;
while (tmp_list)
{
result++;
tmp_list = tmp_list->next;
}
return result;
}
/*
@ -824,14 +836,30 @@ gdk_event_copy (GdkEvent *event)
*new_event = *event;
gdk_window_ref (new_event->any.window);
if ((event->any.type == GDK_KEY_PRESS) ||
(event->any.type == GDK_KEY_RELEASE))
switch (event->any.type)
{
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
new_event->key.string = g_strdup (event->key.string);
break;
if (((event->any.type == GDK_ENTER_NOTIFY) ||
(event->any.type == GDK_LEAVE_NOTIFY)) &&
(event->crossing.subwindow != NULL))
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
if (event->crossing.subwindow != NULL)
gdk_window_ref (event->crossing.subwindow);
break;
case GDK_DROP_DATA_AVAIL:
new_event->dropdataavailable.data_type = g_strdup (event->dropdataavailable.data_type);
new_event->dropdataavailable.data = g_malloc (event->dropdataavailable.data_numbytes);
memcpy (new_event->dropdataavailable.data,
event->dropdataavailable.data,
event->dropdataavailable.data_numbytes);
break;
default:
break;
}
return new_event;
}
@ -860,17 +888,30 @@ gdk_event_free (GdkEvent *event)
g_assert (event_chunk != NULL);
g_return_if_fail (event != NULL);
if ((event->any.type == GDK_KEY_PRESS) ||
(event->any.type == GDK_KEY_RELEASE))
g_free (event->key.string);
if (event->any.window)
gdk_window_unref (event->any.window);
if (((event->any.type == GDK_ENTER_NOTIFY) ||
(event->any.type == GDK_LEAVE_NOTIFY)) &&
(event->crossing.subwindow != NULL))
switch (event->any.type)
{
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
g_free (event->key.string);
break;
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
if (event->crossing.subwindow != NULL)
gdk_window_unref (event->crossing.subwindow);
break;
case GDK_DROP_DATA_AVAIL:
g_free (event->dropdataavailable.data_type);
g_free (event->dropdataavailable.data);
break;
default:
break;
}
g_mem_chunk_free (event_chunk, event);
}
@ -1583,6 +1624,7 @@ gdk_event_translate (GdkEvent *event,
dnd_drag_oldpos = {0,0};
static GdkRectangle dnd_drag_dropzone = {0,0,0,0};
static gint dnd_drag_perhaps = 0;
static gboolean dnd_grabbed = FALSE;
static GdkWindowPrivate *real_sw = NULL;
static Window dnd_drag_curwin = None, dnd_drag_target = None;
@ -1829,6 +1871,7 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd.drag_startwindows = NULL;
}
gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
dnd_grabbed = FALSE;
{
/* Set motion mask for first DnD'd window, since it
@ -1891,14 +1934,19 @@ gdk_event_translate (GdkEvent *event,
XChangeWindowAttributes(gdk_display, real_sw->xwindow,
CWEventMask, &attrs);
}
if (dnd_grabbed)
{
XUngrabPointer(gdk_display, CurrentTime);
dnd_grabbed = FALSE;
}
if(gdk_dnd.drag_really)
{
GdkPoint foo;
foo.x = xevent->xbutton.x_root;
foo.y = xevent->xbutton.y_root;
XUngrabPointer(gdk_display, CurrentTime);
if(dnd_drag_target != None)
gdk_dnd_drag_end(dnd_drag_target, foo);
gdk_dnd.drag_really = 0;
@ -1977,7 +2025,8 @@ gdk_event_translate (GdkEvent *event,
curwin = childwin;
XTranslateCoordinates(gdk_display, curwin, curwin,
x, y, &x, &y, &childwin);
if(childwin != None) {
if(childwin != None)
{
XTranslateCoordinates(gdk_display, curwin, childwin,
x, y, &x, &y, &twin);
}
@ -2003,8 +2052,7 @@ gdk_event_translate (GdkEvent *event,
#endif
XChangeActivePointerGrab(gdk_display,
ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
ButtonPressMask | ButtonReleaseMask,
gdk_dnd.gdk_cursor_dragdefault,
CurrentTime);
}
@ -2013,16 +2061,20 @@ gdk_event_translate (GdkEvent *event,
&& curwin == dnd_drag_curwin)
{
/* Handle all that dropzone stuff - thanks John ;-) */
if(dnd_drag_target != None
&& IS_IN_ZONE(dnd_drag_oldpos.x, dnd_drag_oldpos.y)
&& !IS_IN_ZONE(xevent->xmotion.x_root,
xevent->xmotion.y_root))
if (dnd_drag_target != None)
{
gboolean in_zone = IS_IN_ZONE(xevent->xmotion.x_root,
xevent->xmotion.y_root);
gboolean old_in_zone = IS_IN_ZONE(dnd_drag_oldpos.x,
dnd_drag_oldpos.y);
if (!in_zone && old_in_zone)
{
/* We were in the drop zone and moved out */
dnd_drag_target = None;
gdk_dnd_drag_leave(curwin);
}
else
else if (!in_zone && !old_in_zone)
{
/* We were outside drop zone but in the window
- have to send enter events */
@ -2031,6 +2083,7 @@ gdk_event_translate (GdkEvent *event,
dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
dnd_drag_target = None;
}
}
} else
dnd_drag_curwin = None;
return_val = FALSE;
@ -2099,20 +2152,8 @@ gdk_event_translate (GdkEvent *event,
xevent->xcrossing.window, real_sw->xwindow);
}
#endif
if(dnd_drag_perhaps) {
if(!gdk_dnd.drag_really && xevent->xcrossing.window != real_sw->xwindow)
{
gdk_dnd_drag_addwindow((GdkWindow *) real_sw);
gdk_dnd_drag_begin((GdkWindow *) real_sw);
XGrabPointer(gdk_display, real_sw->xwindow, False,
ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
GrabModeAsync, GrabModeAsync, gdk_root_window,
gdk_dnd.gdk_cursor_dragdefault, CurrentTime);
gdk_dnd.drag_really = 1;
}
else if(gdk_dnd.drag_really && xevent->xcrossing.window == real_sw->xwindow)
if (dnd_drag_perhaps && gdk_dnd.drag_really &&
(xevent->xcrossing.window == real_sw->xwindow))
{
gdk_dnd.drag_really = 0;
#ifdef DEBUG_DND
@ -2121,8 +2162,9 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd.drag_numwindows = 0;
g_free(gdk_dnd.drag_startwindows);
gdk_dnd.drag_startwindows = NULL;
XUngrabPointer(gdk_display, CurrentTime);
}
/* We don't want to ungrab the pointer here, or we'll
* start getting spurious enter/leave events */
XChangeActivePointerGrab (gdk_display, 0, None, CurrentTime);
}
return_val = window_private && !window_private->destroyed;
@ -2180,31 +2222,19 @@ gdk_event_translate (GdkEvent *event,
xevent->xcrossing.window, real_sw->xwindow);
}
#endif
if(dnd_drag_perhaps) {
if(!gdk_dnd.drag_really && xevent->xcrossing.window != real_sw->xwindow)
if (dnd_drag_perhaps && !gdk_dnd.drag_really &&
(xevent->xcrossing.window == real_sw->xwindow))
{
gdk_dnd_drag_addwindow((GdkWindow *) real_sw);
gdk_dnd_drag_begin((GdkWindow *) real_sw);
XGrabPointer(gdk_display, real_sw->xwindow, False,
ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, gdk_root_window,
gdk_dnd.gdk_cursor_dragdefault, CurrentTime);
dnd_grabbed = TRUE;
gdk_dnd.drag_really = 1;
}
else if(gdk_dnd.drag_really && xevent->xcrossing.window == real_sw->xwindow)
{
gdk_dnd.drag_really = 0;
#ifdef DEBUG_DND
g_print("Ungrabbed\n");
#endif
gdk_dnd.drag_numwindows = 0;
g_free(gdk_dnd.drag_startwindows);
gdk_dnd.drag_startwindows = NULL;
XUngrabPointer(gdk_display, CurrentTime);
}
}
return_val = window_private && !window_private->destroyed;
break;

View File

@ -1444,6 +1444,7 @@ gdk_window_remove_filter (GdkWindow *window,
{
private->filters = g_list_remove_link (private->filters, tmp_list);
g_list_free_1 (tmp_list);
g_free (filter);
return;
}

View File

@ -602,7 +602,19 @@ gdk_set_locale ()
gint
gdk_events_pending ()
{
return XPending (gdk_display);
gint result;
GList *tmp_list;
result = XPending (gdk_display);
tmp_list = putback_events;
while (tmp_list)
{
result++;
tmp_list = tmp_list->next;
}
return result;
}
/*
@ -824,14 +836,30 @@ gdk_event_copy (GdkEvent *event)
*new_event = *event;
gdk_window_ref (new_event->any.window);
if ((event->any.type == GDK_KEY_PRESS) ||
(event->any.type == GDK_KEY_RELEASE))
switch (event->any.type)
{
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
new_event->key.string = g_strdup (event->key.string);
break;
if (((event->any.type == GDK_ENTER_NOTIFY) ||
(event->any.type == GDK_LEAVE_NOTIFY)) &&
(event->crossing.subwindow != NULL))
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
if (event->crossing.subwindow != NULL)
gdk_window_ref (event->crossing.subwindow);
break;
case GDK_DROP_DATA_AVAIL:
new_event->dropdataavailable.data_type = g_strdup (event->dropdataavailable.data_type);
new_event->dropdataavailable.data = g_malloc (event->dropdataavailable.data_numbytes);
memcpy (new_event->dropdataavailable.data,
event->dropdataavailable.data,
event->dropdataavailable.data_numbytes);
break;
default:
break;
}
return new_event;
}
@ -860,17 +888,30 @@ gdk_event_free (GdkEvent *event)
g_assert (event_chunk != NULL);
g_return_if_fail (event != NULL);
if ((event->any.type == GDK_KEY_PRESS) ||
(event->any.type == GDK_KEY_RELEASE))
g_free (event->key.string);
if (event->any.window)
gdk_window_unref (event->any.window);
if (((event->any.type == GDK_ENTER_NOTIFY) ||
(event->any.type == GDK_LEAVE_NOTIFY)) &&
(event->crossing.subwindow != NULL))
switch (event->any.type)
{
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
g_free (event->key.string);
break;
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
if (event->crossing.subwindow != NULL)
gdk_window_unref (event->crossing.subwindow);
break;
case GDK_DROP_DATA_AVAIL:
g_free (event->dropdataavailable.data_type);
g_free (event->dropdataavailable.data);
break;
default:
break;
}
g_mem_chunk_free (event_chunk, event);
}
@ -1583,6 +1624,7 @@ gdk_event_translate (GdkEvent *event,
dnd_drag_oldpos = {0,0};
static GdkRectangle dnd_drag_dropzone = {0,0,0,0};
static gint dnd_drag_perhaps = 0;
static gboolean dnd_grabbed = FALSE;
static GdkWindowPrivate *real_sw = NULL;
static Window dnd_drag_curwin = None, dnd_drag_target = None;
@ -1829,6 +1871,7 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd.drag_startwindows = NULL;
}
gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
dnd_grabbed = FALSE;
{
/* Set motion mask for first DnD'd window, since it
@ -1891,14 +1934,19 @@ gdk_event_translate (GdkEvent *event,
XChangeWindowAttributes(gdk_display, real_sw->xwindow,
CWEventMask, &attrs);
}
if (dnd_grabbed)
{
XUngrabPointer(gdk_display, CurrentTime);
dnd_grabbed = FALSE;
}
if(gdk_dnd.drag_really)
{
GdkPoint foo;
foo.x = xevent->xbutton.x_root;
foo.y = xevent->xbutton.y_root;
XUngrabPointer(gdk_display, CurrentTime);
if(dnd_drag_target != None)
gdk_dnd_drag_end(dnd_drag_target, foo);
gdk_dnd.drag_really = 0;
@ -1977,7 +2025,8 @@ gdk_event_translate (GdkEvent *event,
curwin = childwin;
XTranslateCoordinates(gdk_display, curwin, curwin,
x, y, &x, &y, &childwin);
if(childwin != None) {
if(childwin != None)
{
XTranslateCoordinates(gdk_display, curwin, childwin,
x, y, &x, &y, &twin);
}
@ -2003,8 +2052,7 @@ gdk_event_translate (GdkEvent *event,
#endif
XChangeActivePointerGrab(gdk_display,
ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
ButtonPressMask | ButtonReleaseMask,
gdk_dnd.gdk_cursor_dragdefault,
CurrentTime);
}
@ -2013,16 +2061,20 @@ gdk_event_translate (GdkEvent *event,
&& curwin == dnd_drag_curwin)
{
/* Handle all that dropzone stuff - thanks John ;-) */
if(dnd_drag_target != None
&& IS_IN_ZONE(dnd_drag_oldpos.x, dnd_drag_oldpos.y)
&& !IS_IN_ZONE(xevent->xmotion.x_root,
xevent->xmotion.y_root))
if (dnd_drag_target != None)
{
gboolean in_zone = IS_IN_ZONE(xevent->xmotion.x_root,
xevent->xmotion.y_root);
gboolean old_in_zone = IS_IN_ZONE(dnd_drag_oldpos.x,
dnd_drag_oldpos.y);
if (!in_zone && old_in_zone)
{
/* We were in the drop zone and moved out */
dnd_drag_target = None;
gdk_dnd_drag_leave(curwin);
}
else
else if (!in_zone && !old_in_zone)
{
/* We were outside drop zone but in the window
- have to send enter events */
@ -2031,6 +2083,7 @@ gdk_event_translate (GdkEvent *event,
dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
dnd_drag_target = None;
}
}
} else
dnd_drag_curwin = None;
return_val = FALSE;
@ -2099,20 +2152,8 @@ gdk_event_translate (GdkEvent *event,
xevent->xcrossing.window, real_sw->xwindow);
}
#endif
if(dnd_drag_perhaps) {
if(!gdk_dnd.drag_really && xevent->xcrossing.window != real_sw->xwindow)
{
gdk_dnd_drag_addwindow((GdkWindow *) real_sw);
gdk_dnd_drag_begin((GdkWindow *) real_sw);
XGrabPointer(gdk_display, real_sw->xwindow, False,
ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
GrabModeAsync, GrabModeAsync, gdk_root_window,
gdk_dnd.gdk_cursor_dragdefault, CurrentTime);
gdk_dnd.drag_really = 1;
}
else if(gdk_dnd.drag_really && xevent->xcrossing.window == real_sw->xwindow)
if (dnd_drag_perhaps && gdk_dnd.drag_really &&
(xevent->xcrossing.window == real_sw->xwindow))
{
gdk_dnd.drag_really = 0;
#ifdef DEBUG_DND
@ -2121,8 +2162,9 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd.drag_numwindows = 0;
g_free(gdk_dnd.drag_startwindows);
gdk_dnd.drag_startwindows = NULL;
XUngrabPointer(gdk_display, CurrentTime);
}
/* We don't want to ungrab the pointer here, or we'll
* start getting spurious enter/leave events */
XChangeActivePointerGrab (gdk_display, 0, None, CurrentTime);
}
return_val = window_private && !window_private->destroyed;
@ -2180,31 +2222,19 @@ gdk_event_translate (GdkEvent *event,
xevent->xcrossing.window, real_sw->xwindow);
}
#endif
if(dnd_drag_perhaps) {
if(!gdk_dnd.drag_really && xevent->xcrossing.window != real_sw->xwindow)
if (dnd_drag_perhaps && !gdk_dnd.drag_really &&
(xevent->xcrossing.window == real_sw->xwindow))
{
gdk_dnd_drag_addwindow((GdkWindow *) real_sw);
gdk_dnd_drag_begin((GdkWindow *) real_sw);
XGrabPointer(gdk_display, real_sw->xwindow, False,
ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, gdk_root_window,
gdk_dnd.gdk_cursor_dragdefault, CurrentTime);
dnd_grabbed = TRUE;
gdk_dnd.drag_really = 1;
}
else if(gdk_dnd.drag_really && xevent->xcrossing.window == real_sw->xwindow)
{
gdk_dnd.drag_really = 0;
#ifdef DEBUG_DND
g_print("Ungrabbed\n");
#endif
gdk_dnd.drag_numwindows = 0;
g_free(gdk_dnd.drag_startwindows);
gdk_dnd.drag_startwindows = NULL;
XUngrabPointer(gdk_display, CurrentTime);
}
}
return_val = window_private && !window_private->destroyed;
break;

View File

@ -1444,6 +1444,7 @@ gdk_window_remove_filter (GdkWindow *window,
{
private->filters = g_list_remove_link (private->filters, tmp_list);
g_list_free_1 (tmp_list);
g_free (filter);
return;
}

View File

@ -375,7 +375,7 @@
(define-boxed GdkFont
gdk_font_ref
gdk_font_free)
gdk_font_unref)
(define-boxed GdkWindow
gdk_window_ref

View File

@ -222,7 +222,14 @@ gtk_main_quit ()
done = TRUE;
}
gint gtk_main_iteration ()
gint
gtk_events_pending (void)
{
return gdk_events_pending() + (next_event != NULL) ? 1 : 0;
}
gint
gtk_main_iteration ()
{
return gtk_main_iteration_do (TRUE);
}

View File

@ -34,6 +34,7 @@ void gtk_init (int *argc,
char ***argv);
void gtk_exit (gint error_code);
gchar* gtk_set_locale (void);
gint gtk_events_pending (void);
void gtk_main (void);
guint gtk_main_level (void);
void gtk_main_quit (void);

View File

@ -54,7 +54,7 @@ GtkWidget *gtk_vbutton_box_new (void);
gint gtk_vbutton_box_get_spacing_default (void);
void gtk_vbutton_box_set_spacing_default (gint spacing);
void gtk_vbutton_box_set_spacing_default (gint spacing);
gint gtk_vbutton_box_get_layout_default (void);
void gtk_vbutton_box_set_layout_default (gint layout);

View File

@ -2591,9 +2591,6 @@ dnd_drop (GtkWidget *button, GdkEvent *event)
gtk_widget_show(vbox);
gtk_grab_add(window);
gtk_widget_show(window);
g_free (event->dropdataavailable.data);
g_free (event->dropdataavailable.data_type);
}
void

View File

@ -2591,9 +2591,6 @@ dnd_drop (GtkWidget *button, GdkEvent *event)
gtk_widget_show(vbox);
gtk_grab_add(window);
gtk_widget_show(window);
g_free (event->dropdataavailable.data);
g_free (event->dropdataavailable.data_type);
}
void