D&D now lets you use shaped windows for drags. As usual, see testgtk.c... Now finish GnomeMC, miguel :)

This commit is contained in:
Elliot Lee 1998-02-26 21:28:00 +00:00
parent 95efae09a7
commit a597dd9473
10 changed files with 306 additions and 91 deletions

View File

@ -9,6 +9,7 @@ libgdk_la_SOURCES = \
gdkcc.c \
gdkcolor.c \
gdkcursor.c \
gdk_dnd.c \
gdkdraw.c \
gdkfont.c \
gdkgc.c \

View File

@ -513,8 +513,8 @@ gdk_init (int *argc,
gdk_dnd.gdk_XdeRequest = gdk_atom_intern("_XDE_REQUEST", FALSE);
gdk_dnd.gdk_XdeDataAvailable = gdk_atom_intern("_XDE_DATA_AVAILABLE", FALSE);
gdk_dnd.gdk_XdeTypelist = gdk_atom_intern("_XDE_TYPELIST", FALSE);
gdk_dnd.gdk_cursor_dragdefault = XCreateFontCursor(gdk_display, XC_bogosity);
gdk_dnd.gdk_cursor_dragok = XCreateFontCursor(gdk_display, XC_heart);
gdk_dnd.c->gdk_cursor_dragdefault = XCreateFontCursor(gdk_display, XC_bogosity);
gdk_dnd.c->gdk_cursor_dragok = XCreateFontCursor(gdk_display, XC_heart);
XGetKeyboardControl (gdk_display, &keyboard_state);
autorepeat = keyboard_state.global_auto_repeat;
@ -1673,10 +1673,8 @@ gdk_event_translate (GdkEvent *event,
static GdkPoint dnd_drag_start = {0,0},
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;
static Window dnd_drag_curwin = None;
return_val = FALSE;
@ -1909,10 +1907,10 @@ gdk_event_translate (GdkEvent *event,
}
if(window_private
&& window_private->dnd_drag_enabled
&& !dnd_drag_perhaps
&& !gdk_dnd.drag_perhaps
&& !gdk_dnd.drag_really)
{
dnd_drag_perhaps = 1;
gdk_dnd.drag_perhaps = 1;
dnd_drag_start.x = xevent->xbutton.x_root;
dnd_drag_start.y = xevent->xbutton.y_root;
real_sw = window_private;
@ -1923,7 +1921,7 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd.drag_startwindows = NULL;
}
gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
dnd_grabbed = FALSE;
gdk_dnd.dnd_grabbed = FALSE;
{
/* Set motion mask for first DnD'd window, since it
@ -1976,7 +1974,7 @@ gdk_event_translate (GdkEvent *event,
event->button.source = GDK_SOURCE_MOUSE;
event->button.deviceid = GDK_CORE_POINTER;
if(dnd_drag_perhaps)
if(gdk_dnd.drag_perhaps)
{
{
XSetWindowAttributes attrs;
@ -1987,10 +1985,13 @@ gdk_event_translate (GdkEvent *event,
CWEventMask, &attrs);
}
if (dnd_grabbed)
if (gdk_dnd.dnd_grabbed)
{
gdk_dnd_display_drag_cursor(-2,
-2,
FALSE, TRUE);
XUngrabPointer(gdk_display, CurrentTime);
dnd_grabbed = FALSE;
gdk_dnd.dnd_grabbed = FALSE;
}
if(gdk_dnd.drag_really)
@ -1999,8 +2000,8 @@ gdk_event_translate (GdkEvent *event,
foo.x = xevent->xbutton.x_root;
foo.y = xevent->xbutton.y_root;
if(dnd_drag_target != None)
gdk_dnd_drag_end(dnd_drag_target, foo);
if(gdk_dnd.dnd_drag_target != None)
gdk_dnd_drag_end(gdk_dnd.dnd_drag_target, foo);
gdk_dnd.drag_really = 0;
gdk_dnd.drag_numwindows = 0;
@ -2013,7 +2014,7 @@ gdk_event_translate (GdkEvent *event,
real_sw = NULL;
}
dnd_drag_perhaps = 0;
gdk_dnd.drag_perhaps = 0;
dnd_drag_start.x = dnd_drag_start.y = 0;
dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
dnd_drag_dropzone.width = dnd_drag_dropzone.height = 0;
@ -2031,7 +2032,7 @@ gdk_event_translate (GdkEvent *event,
xevent->xmotion.window - base_id,
xevent->xmotion.x, xevent->xmotion.y,
(xevent->xmotion.is_hint) ? "true" : "false",
dnd_drag_perhaps, gdk_dnd.drag_really));
gdk_dnd.drag_perhaps, gdk_dnd.drag_really));
if (window_private &&
(window_private->extension_events != 0) &&
@ -2058,7 +2059,7 @@ gdk_event_translate (GdkEvent *event,
&& cx < (dnd_drag_dropzone.x + dnd_drag_dropzone.width) \
&& cy < (dnd_drag_dropzone.y + dnd_drag_dropzone.height))
if(dnd_drag_perhaps && gdk_dnd.drag_really)
if(gdk_dnd.drag_perhaps && gdk_dnd.drag_really)
{
/* First, we have to find what window the motion was in... */
/* XXX there has to be a better way to do this, perhaps with
@ -2067,6 +2068,13 @@ gdk_event_translate (GdkEvent *event,
static Window lastwin = None, curwin = None, twin;
Window childwin = gdk_root_window;
int x, y, ox, oy;
/* Interlude - display cursor for the drag ASAP */
gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
xevent->xmotion.y_root,
gdk_dnd.dnd_drag_target?TRUE:FALSE,
FALSE);
lastwin = curwin;
curwin = gdk_root_window;
ox = x = xevent->xmotion.x_root;
@ -2096,23 +2104,21 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd_drag_enter(dnd_drag_curwin);
dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
dnd_drag_dropzone.width = dnd_drag_dropzone.height = 0;
dnd_drag_target = None;
gdk_dnd.dnd_drag_target = None;
GDK_NOTE (DND,
g_print("curwin = %#lx, lastwin = %#lx, dnd_drag_curwin = %#lx\n",
curwin, lastwin, dnd_drag_curwin));
XChangeActivePointerGrab(gdk_display,
ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask,
gdk_dnd.gdk_cursor_dragdefault,
CurrentTime);
gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
xevent->xmotion.y_root,
FALSE, TRUE);
}
else if(dnd_drag_dropzone.width > 0
&& dnd_drag_dropzone.height > 0
&& curwin == dnd_drag_curwin)
{
/* Handle all that dropzone stuff - thanks John ;-) */
if (dnd_drag_target != None)
if (gdk_dnd.dnd_drag_target != None)
{
gboolean in_zone = IS_IN_ZONE(xevent->xmotion.x_root,
xevent->xmotion.y_root);
@ -2122,8 +2128,11 @@ gdk_event_translate (GdkEvent *event,
if (!in_zone && old_in_zone)
{
/* We were in the drop zone and moved out */
dnd_drag_target = None;
gdk_dnd.dnd_drag_target = None;
gdk_dnd_drag_leave(curwin);
gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
xevent->xmotion.y_root,
FALSE, TRUE);
}
else if (!in_zone && !old_in_zone)
{
@ -2132,7 +2141,7 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd_drag_enter(curwin);
dnd_drag_curwin = curwin;
dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
dnd_drag_target = None;
gdk_dnd.dnd_drag_target = None;
}
}
} /* else
@ -2194,7 +2203,7 @@ gdk_event_translate (GdkEvent *event,
}
#ifdef G_ENABLE_DEBUG
if ((gdk_debug_flags & GDK_DEBUG_DND) & dnd_drag_perhaps)
if ((gdk_debug_flags & GDK_DEBUG_DND) & gdk_dnd.drag_perhaps)
{
g_print("We may[%d] have a drag into %#lx = %#lx\n",
gdk_dnd.drag_really,
@ -2202,7 +2211,7 @@ gdk_event_translate (GdkEvent *event,
}
#endif /* G_ENABLE_DEBUG */
if (dnd_drag_perhaps && gdk_dnd.drag_really &&
if (gdk_dnd.drag_perhaps && gdk_dnd.drag_really &&
(xevent->xcrossing.window == real_sw->xwindow))
{
gdk_dnd.drag_really = 0;
@ -2214,7 +2223,9 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd.drag_startwindows = NULL;
/* We don't want to ungrab the pointer here, or we'll
* start getting spurious enter/leave events */
#if 0
XChangeActivePointerGrab (gdk_display, 0, None, CurrentTime);
#endif
}
return_val = window_private && !window_private->destroyed;
@ -2263,14 +2274,14 @@ gdk_event_translate (GdkEvent *event,
break;
}
#ifdef G_ENABLE_DEBUG
if ((gdk_debug_flags & GDK_DEBUG_DND) & dnd_drag_perhaps)
if ((gdk_debug_flags & GDK_DEBUG_DND) & gdk_dnd.drag_perhaps)
{
g_print("We may[%d] have a drag out of %#lx = %#lx\n",
gdk_dnd.drag_really,
xevent->xcrossing.window, real_sw->xwindow);
}
#endif /* G_ENABLE_DEBUG */
if (dnd_drag_perhaps && !gdk_dnd.drag_really &&
if (gdk_dnd.drag_perhaps && !gdk_dnd.drag_really &&
(xevent->xcrossing.window == real_sw->xwindow))
{
gdk_dnd_drag_addwindow((GdkWindow *) real_sw);
@ -2279,9 +2290,12 @@ gdk_event_translate (GdkEvent *event,
ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, gdk_root_window,
gdk_dnd.gdk_cursor_dragdefault, CurrentTime);
dnd_grabbed = TRUE;
None, CurrentTime);
gdk_dnd.dnd_grabbed = TRUE;
gdk_dnd.drag_really = 1;
gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
xevent->xmotion.y_root,
FALSE, TRUE);
}
return_val = window_private && !window_private->destroyed;
@ -2759,14 +2773,8 @@ gdk_event_translate (GdkEvent *event,
window_private->dnd_drag_data_type =
xevent->xclient.data.l[4];
dnd_drag_target = dnd_drag_curwin;
XChangeActivePointerGrab (gdk_display,
ButtonMotionMask |
ButtonPressMask |
ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
gdk_dnd.gdk_cursor_dragok,
CurrentTime);
gdk_dnd.dnd_drag_target = dnd_drag_curwin;
gdk_dnd_display_drag_cursor(-1, -1, TRUE, TRUE);
}
dnd_drag_dropzone.x = xevent->xclient.data.l[2] & 65535;
dnd_drag_dropzone.y =

View File

@ -229,7 +229,12 @@ void gdk_window_dnd_data_set (GdkWindow *window,
GdkEvent *event,
gpointer data,
gulong data_numbytes);
void gdk_dnd_set_drag_cursors(GdkCursor *default_cursor,
GdkCursor *goahead_cursor);
void gdk_dnd_set_drag_shape(GdkWindow *default_pixmapwin,
GdkPoint *default_hotspot,
GdkWindow *goahead_pixmapwin,
GdkPoint *goahead_hotspot);
void gdk_window_set_hints (GdkWindow *window,
gint x,

138
gdk/gdk_dnd.c Normal file
View File

@ -0,0 +1,138 @@
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <string.h>
#include "gdkx.h"
#include "gdk.h"
/* Nothing much here now, but we have to make a start some time ;-) */
void
gdk_dnd_set_drag_cursors(GdkCursor *default_cursor, GdkCursor *goahead_cursor)
{
gdk_dnd.c->gdk_cursor_dragdefault =
((GdkCursorPrivate *)default_cursor)->xcursor;
gdk_dnd.c->gdk_cursor_dragok = ((GdkCursorPrivate *)goahead_cursor)->xcursor;
if(gdk_dnd.dnd_grabbed)
{
if(gdk_dnd.c->drag_pm_default)
/* We were displaying pixmaps for the drag */
{
gdk_window_hide(gdk_dnd.c->drag_pm_default);
gdk_window_unref(gdk_dnd.c->drag_pm_default);
if(gdk_dnd.c->drag_pm_ok)
{
gdk_window_hide(gdk_dnd.c->drag_pm_ok);
gdk_window_unref(gdk_dnd.c->drag_pm_ok);
}
gdk_dnd.c->drag_pm_default = gdk_dnd.c->drag_pm_ok = NULL;
}
gdk_dnd_display_drag_cursor(-1, -1,
gdk_dnd.dnd_drag_target?TRUE:FALSE,
TRUE);
}
}
void
gdk_dnd_set_drag_shape(GdkWindow *default_pixmapwin,
GdkPoint *default_hotspot,
GdkWindow *goahead_pixmapwin,
GdkPoint *goahead_hotspot)
{
g_return_if_fail(default_pixmapwin != NULL);
if(gdk_dnd.c->drag_pm_default)
gdk_window_unref(gdk_dnd.c->drag_pm_default);
if(gdk_dnd.c->drag_pm_ok)
gdk_window_unref(gdk_dnd.c->drag_pm_ok);
gdk_dnd.c->drag_pm_ok = NULL;
gdk_window_ref(default_pixmapwin);
gdk_dnd.c->drag_pm_default = default_pixmapwin;
gdk_dnd.c->default_hotspot = *default_hotspot;
if(goahead_pixmapwin)
{
gdk_window_ref(goahead_pixmapwin);
gdk_dnd.c->drag_pm_ok = goahead_pixmapwin;
gdk_dnd.c->ok_hotspot = *goahead_hotspot;
}
if(gdk_dnd.dnd_grabbed)
{
gdk_dnd_display_drag_cursor(-1, -1,
gdk_dnd.dnd_drag_target?TRUE:FALSE,
TRUE);
XChangeActivePointerGrab (gdk_display,
ButtonMotionMask |
ButtonPressMask |
ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
None,
CurrentTime);
}
}
void
gdk_dnd_display_drag_cursor(gint x, gint y, gboolean drag_ok,
gboolean change_made)
{
if(!gdk_dnd.dnd_grabbed)
return;
if(gdk_dnd.c->drag_pm_default)
{
/* We're doing pixmaps here... */
GdkWindow *mypix, *opix;
GdkPoint *myhotspot;
gint itmp;
Window wtmp;
if(x == -2 && y == -2) /* Hide the cursors */
{
gdk_window_hide(gdk_dnd.c->drag_pm_ok);
gdk_window_hide(gdk_dnd.c->drag_pm_default);
return;
}
if(x == -1 && y == -1) /* We're supposed to find it out for ourselves */
XQueryPointer(gdk_display, gdk_root_window,
&wtmp, &wtmp, &x, &y, &itmp, &itmp, &itmp);
if(drag_ok)
{
mypix = gdk_dnd.c->drag_pm_ok;
opix = gdk_dnd.c->drag_pm_default;
myhotspot = &gdk_dnd.c->ok_hotspot;
}
else
{
mypix = gdk_dnd.c->drag_pm_default;
opix = gdk_dnd.c->drag_pm_ok;
myhotspot = &gdk_dnd.c->default_hotspot;
}
if(change_made)
{
gdk_window_hide(opix);
gdk_window_show(mypix); /* There ought to be a way to know if
a window is already mapped etc. */
}
gdk_window_move(mypix, x - myhotspot->x, y - myhotspot->y);
}
else if(change_made)
{
Cursor c;
/* Move cursors around */
if(drag_ok)
c = gdk_dnd.c->gdk_cursor_dragok;
else
c = gdk_dnd.c->gdk_cursor_dragdefault;
XChangeActivePointerGrab (gdk_display,
ButtonMotionMask |
ButtonPressMask |
ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
c,
CurrentTime);
}
}

View File

@ -33,12 +33,16 @@ Atom gdk_wm_take_focus;
Atom gdk_wm_protocols;
Atom gdk_wm_window_protocols[2];
Atom gdk_selection_property;
GdkDndCursorInfo gdk_dnd_cursorinfo = {None, None, NULL, NULL,
{0,0}, {0,0}};
GdkDndGlobals gdk_dnd = {None,None,None,
None,None,None,
None,
None,None,
&gdk_dnd_cursorinfo,
NULL,
0, 0,
0,
FALSE, FALSE, FALSE,
None,
{0,0}};
gchar *gdk_progname = NULL;
gchar *gdk_progclass = NULL;

View File

@ -141,14 +141,23 @@ struct _GdkCursorPrivate
Display *xdisplay;
};
struct _GdkDndCursorInfo {
Cursor gdk_cursor_dragdefault, gdk_cursor_dragok;
GdkWindow *drag_pm_default, *drag_pm_ok;
GdkPoint default_hotspot, ok_hotspot;
};
typedef struct _GdkDndCursorInfo GdkDndCursorInfo;
struct _GdkDndGlobals {
GdkAtom gdk_XdeEnter, gdk_XdeLeave, gdk_XdeRequest;
GdkAtom gdk_XdeDataAvailable, gdk_XdeDataShow, gdk_XdeCancel;
GdkAtom gdk_XdeTypelist;
Cursor gdk_cursor_dragdefault, gdk_cursor_dragok;
GdkDndCursorInfo *c;
GdkWindow **drag_startwindows;
guint drag_numwindows;
guint8 drag_really;
gboolean drag_really, drag_perhaps, dnd_grabbed;
Window dnd_drag_target;
GdkPoint drag_dropcoords;
};
typedef struct _GdkDndGlobals GdkDndGlobals;
@ -202,6 +211,16 @@ void gdk_xid_table_insert (XID *xid,
void gdk_xid_table_remove (XID xid);
gpointer gdk_xid_table_lookup (XID xid);
/* If you pass x = y = -1, it queries the pointer
to find out where it currently is.
If you pass x = y = -2, it does anything necessary
to know that the drag is ending.
*/
void gdk_dnd_display_drag_cursor(gint x,
gint y,
gboolean drag_ok,
gboolean change_made);
extern gint gdk_debug_level;
extern gint gdk_show_events;

View File

@ -33,12 +33,16 @@ Atom gdk_wm_take_focus;
Atom gdk_wm_protocols;
Atom gdk_wm_window_protocols[2];
Atom gdk_selection_property;
GdkDndCursorInfo gdk_dnd_cursorinfo = {None, None, NULL, NULL,
{0,0}, {0,0}};
GdkDndGlobals gdk_dnd = {None,None,None,
None,None,None,
None,
None,None,
&gdk_dnd_cursorinfo,
NULL,
0, 0,
0,
FALSE, FALSE, FALSE,
None,
{0,0}};
gchar *gdk_progname = NULL;
gchar *gdk_progclass = NULL;

View File

@ -513,8 +513,8 @@ gdk_init (int *argc,
gdk_dnd.gdk_XdeRequest = gdk_atom_intern("_XDE_REQUEST", FALSE);
gdk_dnd.gdk_XdeDataAvailable = gdk_atom_intern("_XDE_DATA_AVAILABLE", FALSE);
gdk_dnd.gdk_XdeTypelist = gdk_atom_intern("_XDE_TYPELIST", FALSE);
gdk_dnd.gdk_cursor_dragdefault = XCreateFontCursor(gdk_display, XC_bogosity);
gdk_dnd.gdk_cursor_dragok = XCreateFontCursor(gdk_display, XC_heart);
gdk_dnd.c->gdk_cursor_dragdefault = XCreateFontCursor(gdk_display, XC_bogosity);
gdk_dnd.c->gdk_cursor_dragok = XCreateFontCursor(gdk_display, XC_heart);
XGetKeyboardControl (gdk_display, &keyboard_state);
autorepeat = keyboard_state.global_auto_repeat;
@ -1673,10 +1673,8 @@ gdk_event_translate (GdkEvent *event,
static GdkPoint dnd_drag_start = {0,0},
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;
static Window dnd_drag_curwin = None;
return_val = FALSE;
@ -1909,10 +1907,10 @@ gdk_event_translate (GdkEvent *event,
}
if(window_private
&& window_private->dnd_drag_enabled
&& !dnd_drag_perhaps
&& !gdk_dnd.drag_perhaps
&& !gdk_dnd.drag_really)
{
dnd_drag_perhaps = 1;
gdk_dnd.drag_perhaps = 1;
dnd_drag_start.x = xevent->xbutton.x_root;
dnd_drag_start.y = xevent->xbutton.y_root;
real_sw = window_private;
@ -1923,7 +1921,7 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd.drag_startwindows = NULL;
}
gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
dnd_grabbed = FALSE;
gdk_dnd.dnd_grabbed = FALSE;
{
/* Set motion mask for first DnD'd window, since it
@ -1976,7 +1974,7 @@ gdk_event_translate (GdkEvent *event,
event->button.source = GDK_SOURCE_MOUSE;
event->button.deviceid = GDK_CORE_POINTER;
if(dnd_drag_perhaps)
if(gdk_dnd.drag_perhaps)
{
{
XSetWindowAttributes attrs;
@ -1987,10 +1985,13 @@ gdk_event_translate (GdkEvent *event,
CWEventMask, &attrs);
}
if (dnd_grabbed)
if (gdk_dnd.dnd_grabbed)
{
gdk_dnd_display_drag_cursor(-2,
-2,
FALSE, TRUE);
XUngrabPointer(gdk_display, CurrentTime);
dnd_grabbed = FALSE;
gdk_dnd.dnd_grabbed = FALSE;
}
if(gdk_dnd.drag_really)
@ -1999,8 +2000,8 @@ gdk_event_translate (GdkEvent *event,
foo.x = xevent->xbutton.x_root;
foo.y = xevent->xbutton.y_root;
if(dnd_drag_target != None)
gdk_dnd_drag_end(dnd_drag_target, foo);
if(gdk_dnd.dnd_drag_target != None)
gdk_dnd_drag_end(gdk_dnd.dnd_drag_target, foo);
gdk_dnd.drag_really = 0;
gdk_dnd.drag_numwindows = 0;
@ -2013,7 +2014,7 @@ gdk_event_translate (GdkEvent *event,
real_sw = NULL;
}
dnd_drag_perhaps = 0;
gdk_dnd.drag_perhaps = 0;
dnd_drag_start.x = dnd_drag_start.y = 0;
dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
dnd_drag_dropzone.width = dnd_drag_dropzone.height = 0;
@ -2031,7 +2032,7 @@ gdk_event_translate (GdkEvent *event,
xevent->xmotion.window - base_id,
xevent->xmotion.x, xevent->xmotion.y,
(xevent->xmotion.is_hint) ? "true" : "false",
dnd_drag_perhaps, gdk_dnd.drag_really));
gdk_dnd.drag_perhaps, gdk_dnd.drag_really));
if (window_private &&
(window_private->extension_events != 0) &&
@ -2058,7 +2059,7 @@ gdk_event_translate (GdkEvent *event,
&& cx < (dnd_drag_dropzone.x + dnd_drag_dropzone.width) \
&& cy < (dnd_drag_dropzone.y + dnd_drag_dropzone.height))
if(dnd_drag_perhaps && gdk_dnd.drag_really)
if(gdk_dnd.drag_perhaps && gdk_dnd.drag_really)
{
/* First, we have to find what window the motion was in... */
/* XXX there has to be a better way to do this, perhaps with
@ -2067,6 +2068,13 @@ gdk_event_translate (GdkEvent *event,
static Window lastwin = None, curwin = None, twin;
Window childwin = gdk_root_window;
int x, y, ox, oy;
/* Interlude - display cursor for the drag ASAP */
gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
xevent->xmotion.y_root,
gdk_dnd.dnd_drag_target?TRUE:FALSE,
FALSE);
lastwin = curwin;
curwin = gdk_root_window;
ox = x = xevent->xmotion.x_root;
@ -2096,23 +2104,21 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd_drag_enter(dnd_drag_curwin);
dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
dnd_drag_dropzone.width = dnd_drag_dropzone.height = 0;
dnd_drag_target = None;
gdk_dnd.dnd_drag_target = None;
GDK_NOTE (DND,
g_print("curwin = %#lx, lastwin = %#lx, dnd_drag_curwin = %#lx\n",
curwin, lastwin, dnd_drag_curwin));
XChangeActivePointerGrab(gdk_display,
ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask,
gdk_dnd.gdk_cursor_dragdefault,
CurrentTime);
gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
xevent->xmotion.y_root,
FALSE, TRUE);
}
else if(dnd_drag_dropzone.width > 0
&& dnd_drag_dropzone.height > 0
&& curwin == dnd_drag_curwin)
{
/* Handle all that dropzone stuff - thanks John ;-) */
if (dnd_drag_target != None)
if (gdk_dnd.dnd_drag_target != None)
{
gboolean in_zone = IS_IN_ZONE(xevent->xmotion.x_root,
xevent->xmotion.y_root);
@ -2122,8 +2128,11 @@ gdk_event_translate (GdkEvent *event,
if (!in_zone && old_in_zone)
{
/* We were in the drop zone and moved out */
dnd_drag_target = None;
gdk_dnd.dnd_drag_target = None;
gdk_dnd_drag_leave(curwin);
gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
xevent->xmotion.y_root,
FALSE, TRUE);
}
else if (!in_zone && !old_in_zone)
{
@ -2132,7 +2141,7 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd_drag_enter(curwin);
dnd_drag_curwin = curwin;
dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
dnd_drag_target = None;
gdk_dnd.dnd_drag_target = None;
}
}
} /* else
@ -2194,7 +2203,7 @@ gdk_event_translate (GdkEvent *event,
}
#ifdef G_ENABLE_DEBUG
if ((gdk_debug_flags & GDK_DEBUG_DND) & dnd_drag_perhaps)
if ((gdk_debug_flags & GDK_DEBUG_DND) & gdk_dnd.drag_perhaps)
{
g_print("We may[%d] have a drag into %#lx = %#lx\n",
gdk_dnd.drag_really,
@ -2202,7 +2211,7 @@ gdk_event_translate (GdkEvent *event,
}
#endif /* G_ENABLE_DEBUG */
if (dnd_drag_perhaps && gdk_dnd.drag_really &&
if (gdk_dnd.drag_perhaps && gdk_dnd.drag_really &&
(xevent->xcrossing.window == real_sw->xwindow))
{
gdk_dnd.drag_really = 0;
@ -2214,7 +2223,9 @@ gdk_event_translate (GdkEvent *event,
gdk_dnd.drag_startwindows = NULL;
/* We don't want to ungrab the pointer here, or we'll
* start getting spurious enter/leave events */
#if 0
XChangeActivePointerGrab (gdk_display, 0, None, CurrentTime);
#endif
}
return_val = window_private && !window_private->destroyed;
@ -2263,14 +2274,14 @@ gdk_event_translate (GdkEvent *event,
break;
}
#ifdef G_ENABLE_DEBUG
if ((gdk_debug_flags & GDK_DEBUG_DND) & dnd_drag_perhaps)
if ((gdk_debug_flags & GDK_DEBUG_DND) & gdk_dnd.drag_perhaps)
{
g_print("We may[%d] have a drag out of %#lx = %#lx\n",
gdk_dnd.drag_really,
xevent->xcrossing.window, real_sw->xwindow);
}
#endif /* G_ENABLE_DEBUG */
if (dnd_drag_perhaps && !gdk_dnd.drag_really &&
if (gdk_dnd.drag_perhaps && !gdk_dnd.drag_really &&
(xevent->xcrossing.window == real_sw->xwindow))
{
gdk_dnd_drag_addwindow((GdkWindow *) real_sw);
@ -2279,9 +2290,12 @@ gdk_event_translate (GdkEvent *event,
ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, gdk_root_window,
gdk_dnd.gdk_cursor_dragdefault, CurrentTime);
dnd_grabbed = TRUE;
None, CurrentTime);
gdk_dnd.dnd_grabbed = TRUE;
gdk_dnd.drag_really = 1;
gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
xevent->xmotion.y_root,
FALSE, TRUE);
}
return_val = window_private && !window_private->destroyed;
@ -2759,14 +2773,8 @@ gdk_event_translate (GdkEvent *event,
window_private->dnd_drag_data_type =
xevent->xclient.data.l[4];
dnd_drag_target = dnd_drag_curwin;
XChangeActivePointerGrab (gdk_display,
ButtonMotionMask |
ButtonPressMask |
ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
gdk_dnd.gdk_cursor_dragok,
CurrentTime);
gdk_dnd.dnd_drag_target = dnd_drag_curwin;
gdk_dnd_display_drag_cursor(-1, -1, TRUE, TRUE);
}
dnd_drag_dropzone.x = xevent->xclient.data.l[2] & 65535;
dnd_drag_dropzone.y =

View File

@ -21,6 +21,12 @@
#include "../gdk/gdk.h"
#include "../gdk/gdkx.h"
/* Variables used by the Drag/Drop and Shape Window demos */
static GtkWidget *modeller = NULL;
static GtkWidget *sheets = NULL;
static GtkWidget *rings = NULL;
void create_shapes(void);
void
destroy_window (GtkWidget *widget,
GtkWidget **window)
@ -3314,8 +3320,17 @@ create_dnd ()
char *possible_drag_types[] = {"text/plain"};
char *accepted_drop_types[] = {"text/plain"};
if(!modeller)
create_shapes();
if (!window)
{
GdkPoint hotspot = {5,5};
gdk_dnd_set_drag_shape(modeller->window,
&hotspot,
rings->window,
&hotspot);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
@ -3415,6 +3430,8 @@ create_dnd ()
gtk_widget_show (button);
}
gtk_widget_hide(modeller); gtk_widget_hide(rings);
if (!GTK_WIDGET_VISIBLE (window))
gtk_widget_show (window);
else
@ -3425,9 +3442,6 @@ create_dnd ()
* Shaped Windows
*/
static GdkWindow *root_win = NULL;
static GtkWidget *modeller = NULL;
static GtkWidget *sheets = NULL;
static GtkWidget *rings = NULL;
typedef struct _cursoroffset {gint x,y;} CursorOffset;

View File

@ -21,6 +21,12 @@
#include "../gdk/gdk.h"
#include "../gdk/gdkx.h"
/* Variables used by the Drag/Drop and Shape Window demos */
static GtkWidget *modeller = NULL;
static GtkWidget *sheets = NULL;
static GtkWidget *rings = NULL;
void create_shapes(void);
void
destroy_window (GtkWidget *widget,
GtkWidget **window)
@ -3314,8 +3320,17 @@ create_dnd ()
char *possible_drag_types[] = {"text/plain"};
char *accepted_drop_types[] = {"text/plain"};
if(!modeller)
create_shapes();
if (!window)
{
GdkPoint hotspot = {5,5};
gdk_dnd_set_drag_shape(modeller->window,
&hotspot,
rings->window,
&hotspot);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
@ -3415,6 +3430,8 @@ create_dnd ()
gtk_widget_show (button);
}
gtk_widget_hide(modeller); gtk_widget_hide(rings);
if (!GTK_WIDGET_VISIBLE (window))
gtk_widget_show (window);
else
@ -3425,9 +3442,6 @@ create_dnd ()
* Shaped Windows
*/
static GdkWindow *root_win = NULL;
static GtkWidget *modeller = NULL;
static GtkWidget *sheets = NULL;
static GtkWidget *rings = NULL;
typedef struct _cursoroffset {gint x,y;} CursorOffset;