mirror of
https://github.com/gryf/wmaker.git
synced 2026-01-03 12:24:17 +01:00
- updated the XDND code in WINGs to work with GDK based applications.
WINGs based applications should now work with both KDE and GNOME applications (Sylvain Reynal <sreynal@nerim.net>) - better check for the XDND protocol version when interoperating with other applications. As it seems xdnd version 3 (which WINGs supports) and newer are not backward compatible with xdnd version 1 and 2. This is why WINGs applications cannot interoperate with GNUstep applications (which uses xdnd version 2). Xdnd version 4 and 5 are backwards compatible with version 3 though. (Sylvain Reynal <sreynal@nerim.net>)
This commit is contained in:
@@ -21,6 +21,15 @@ Changes since version 0.92.0:
|
|||||||
- fixed a small memory leak in WINGs/wview.c caused by not releasing the
|
- fixed a small memory leak in WINGs/wview.c caused by not releasing the
|
||||||
background color of a view (Martin Frydl <martin.frydl@systinet.com>)
|
background color of a view (Martin Frydl <martin.frydl@systinet.com>)
|
||||||
- updated estonian translation (Ivar Smolin <okul@linux.ee>)
|
- updated estonian translation (Ivar Smolin <okul@linux.ee>)
|
||||||
|
- updated the XDND code in WINGs to work with GDK based applications.
|
||||||
|
WINGs based applications should now work with both KDE and GNOME
|
||||||
|
applications (Sylvain Reynal <sreynal@nerim.net>)
|
||||||
|
- better check for the XDND protocol version when interoperating with other
|
||||||
|
applications. As it seems xdnd version 3 (which WINGs supports) and newer
|
||||||
|
are not backward compatible with xdnd version 1 and 2. This is why WINGs
|
||||||
|
applications cannot interoperate with GNUstep applications (which uses
|
||||||
|
xdnd version 2). Xdnd version 4 and 5 are backwards compatible with
|
||||||
|
version 3 though. (Sylvain Reynal <sreynal@nerim.net>)
|
||||||
|
|
||||||
|
|
||||||
Changes since version 0.91.0:
|
Changes since version 0.91.0:
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
Changes since wmaker 0.92.0:
|
||||||
|
............................
|
||||||
|
|
||||||
|
- updated the XDND code in to work with GDK based applications.
|
||||||
|
WINGs based applications should now work with both KDE and GNOME
|
||||||
|
applications (Sylvain Reynal <sreynal@nerim.net>)
|
||||||
|
- better check for the XDND protocol version when interoperating with other
|
||||||
|
applications. As it seems xdnd version 3 (which WINGs supports) and newer
|
||||||
|
are not backward compatible with xdnd version 1 and 2. This is why WINGs
|
||||||
|
applications cannot interoperate with GNUstep applications (which uses
|
||||||
|
xdnd version 2). Xdnd version 4 and 5 are backwards compatible with
|
||||||
|
version 3 though. (Sylvain Reynal <sreynal@nerim.net>)
|
||||||
|
|
||||||
|
|
||||||
Changes since wmaker 0.80.1:
|
Changes since wmaker 0.80.1:
|
||||||
............................
|
............................
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define SCROLLER_WIDTH 20
|
#define SCROLLER_WIDTH 20
|
||||||
|
|
||||||
#define XDND_VERSION 4
|
#define XDND_VERSION 3
|
||||||
|
|
||||||
|
|
||||||
typedef struct W_Application {
|
typedef struct W_Application {
|
||||||
@@ -78,7 +78,7 @@ typedef struct W_Color {
|
|||||||
|
|
||||||
typedef struct W_FocusInfo {
|
typedef struct W_FocusInfo {
|
||||||
struct W_View *toplevel;
|
struct W_View *toplevel;
|
||||||
struct W_View *focused; /* view that has the focus in this toplevel */
|
struct W_View *focused; /* view that has the focus in this toplevel */
|
||||||
struct W_FocusInfo *next;
|
struct W_FocusInfo *next;
|
||||||
} W_FocusInfo;
|
} W_FocusInfo;
|
||||||
|
|
||||||
@@ -110,8 +110,10 @@ typedef struct W_DragSourceInfo {
|
|||||||
|
|
||||||
typedef struct W_DragDestinationInfo {
|
typedef struct W_DragDestinationInfo {
|
||||||
WMView *destView;
|
WMView *destView;
|
||||||
|
WMView *xdndAwareView;
|
||||||
Window sourceWindow;
|
Window sourceWindow;
|
||||||
W_DndState *state;
|
W_DndState *state;
|
||||||
|
Bool sourceActionChanged;
|
||||||
WMArray *sourceTypes;
|
WMArray *sourceTypes;
|
||||||
WMArray *requiredTypes;
|
WMArray *requiredTypes;
|
||||||
Bool typeListAvailable;
|
Bool typeListAvailable;
|
||||||
@@ -120,7 +122,7 @@ typedef struct W_DragDestinationInfo {
|
|||||||
|
|
||||||
|
|
||||||
struct W_DraggingInfo {
|
struct W_DraggingInfo {
|
||||||
unsigned char protocolVersion;
|
unsigned char protocolVersion; /* version supported on the other side */
|
||||||
Time timestamp;
|
Time timestamp;
|
||||||
|
|
||||||
Atom sourceAction;
|
Atom sourceAction;
|
||||||
@@ -162,7 +164,7 @@ typedef struct W_Screen {
|
|||||||
|
|
||||||
struct W_Window *windowList; /* list of windows in the app */
|
struct W_Window *windowList; /* list of windows in the app */
|
||||||
|
|
||||||
Window groupLeader; /* the leader of the application */
|
Window groupLeader; /* the leader of the application */
|
||||||
/* also used for other things */
|
/* also used for other things */
|
||||||
|
|
||||||
struct W_SelectionHandlers *selectionHandlerList;
|
struct W_SelectionHandlers *selectionHandlerList;
|
||||||
@@ -195,11 +197,11 @@ typedef struct W_Screen {
|
|||||||
GC copyGC;
|
GC copyGC;
|
||||||
GC clipGC;
|
GC clipGC;
|
||||||
|
|
||||||
GC monoGC; /* GC for 1bpp visuals */
|
GC monoGC; /* GC for 1bpp visuals */
|
||||||
|
|
||||||
GC xorGC;
|
GC xorGC;
|
||||||
|
|
||||||
GC ixorGC; /* IncludeInferiors XOR */
|
GC ixorGC; /* IncludeInferiors XOR */
|
||||||
|
|
||||||
GC drawStringGC; /* for WMDrawString() */
|
GC drawStringGC; /* for WMDrawString() */
|
||||||
|
|
||||||
@@ -276,15 +278,15 @@ typedef struct W_Screen {
|
|||||||
|
|
||||||
Cursor invisibleCursor;
|
Cursor invisibleCursor;
|
||||||
|
|
||||||
Atom attribsAtom; /* GNUstepWindowAttributes */
|
Atom attribsAtom; /* GNUstepWindowAttributes */
|
||||||
|
|
||||||
Atom deleteWindowAtom; /* WM_DELETE_WINDOW */
|
Atom deleteWindowAtom; /* WM_DELETE_WINDOW */
|
||||||
|
|
||||||
Atom protocolsAtom; /* _XA_WM_PROTOCOLS */
|
Atom protocolsAtom; /* _XA_WM_PROTOCOLS */
|
||||||
|
|
||||||
Atom clipboardAtom; /* CLIPBOARD */
|
Atom clipboardAtom; /* CLIPBOARD */
|
||||||
|
|
||||||
Atom xdndAwareAtom; /* XdndAware */
|
Atom xdndAwareAtom; /* XdndAware */
|
||||||
Atom xdndSelectionAtom;
|
Atom xdndSelectionAtom;
|
||||||
Atom xdndEnterAtom;
|
Atom xdndEnterAtom;
|
||||||
Atom xdndLeaveAtom;
|
Atom xdndLeaveAtom;
|
||||||
@@ -304,7 +306,7 @@ typedef struct W_Screen {
|
|||||||
|
|
||||||
Atom wmIconDragOffsetAtom;
|
Atom wmIconDragOffsetAtom;
|
||||||
|
|
||||||
Atom wmStateAtom; /* WM_STATE */
|
Atom wmStateAtom; /* WM_STATE */
|
||||||
|
|
||||||
Atom utf8String;
|
Atom utf8String;
|
||||||
|
|
||||||
@@ -313,8 +315,8 @@ typedef struct W_Screen {
|
|||||||
Atom netwmIcon;
|
Atom netwmIcon;
|
||||||
|
|
||||||
/* stuff for detecting double-clicks */
|
/* stuff for detecting double-clicks */
|
||||||
Time lastClickTime; /* time of last mousedown event */
|
Time lastClickTime; /* time of last mousedown event */
|
||||||
Window lastClickWindow; /* window of the last mousedown */
|
Window lastClickWindow; /* window of the last mousedown */
|
||||||
|
|
||||||
struct W_View *modalView;
|
struct W_View *modalView;
|
||||||
unsigned modalLoop:1;
|
unsigned modalLoop:1;
|
||||||
@@ -341,8 +343,7 @@ typedef struct W_ViewDelegate {
|
|||||||
typedef struct W_View {
|
typedef struct W_View {
|
||||||
struct W_Screen *screen;
|
struct W_Screen *screen;
|
||||||
|
|
||||||
WMWidget *self; /* must point to the widget the
|
WMWidget *self; /* must point to the widget the view belongs to */
|
||||||
* view belongs to */
|
|
||||||
|
|
||||||
W_ViewDelegate *delegate;
|
W_ViewDelegate *delegate;
|
||||||
|
|
||||||
@@ -362,18 +363,18 @@ typedef struct W_View {
|
|||||||
|
|
||||||
struct W_View *nextResponder; /* next to receive keyboard events */
|
struct W_View *nextResponder; /* next to receive keyboard events */
|
||||||
|
|
||||||
struct W_View *parent; /* parent WMView */
|
struct W_View *parent; /* parent WMView */
|
||||||
|
|
||||||
struct W_View *childrenList; /* first in list of child windows */
|
struct W_View *childrenList; /* first in list of child windows */
|
||||||
|
|
||||||
struct W_View *nextSister; /* next on parent's children list */
|
struct W_View *nextSister; /* next on parent's children list */
|
||||||
|
|
||||||
WMArray *eventHandlers; /* event handlers for this window */
|
WMArray *eventHandlers; /* event handlers for this window */
|
||||||
|
|
||||||
unsigned long attribFlags;
|
unsigned long attribFlags;
|
||||||
XSetWindowAttributes attribs;
|
XSetWindowAttributes attribs;
|
||||||
|
|
||||||
void *hangedData; /* data holder for user program */
|
void *hangedData; /* data holder for user program */
|
||||||
|
|
||||||
WMColor *backColor;
|
WMColor *backColor;
|
||||||
|
|
||||||
@@ -391,9 +392,9 @@ typedef struct W_View {
|
|||||||
unsigned int realized:1;
|
unsigned int realized:1;
|
||||||
unsigned int mapped:1;
|
unsigned int mapped:1;
|
||||||
unsigned int parentDying:1;
|
unsigned int parentDying:1;
|
||||||
unsigned int dying:1; /* the view is being destroyed */
|
unsigned int dying:1; /* the view is being destroyed */
|
||||||
unsigned int topLevel:1; /* is a top level window */
|
unsigned int topLevel:1; /* is a top level window */
|
||||||
unsigned int root:1; /* is the root window */
|
unsigned int root:1; /* is the root window */
|
||||||
unsigned int mapWhenRealized:1; /* map the view when it's realized */
|
unsigned int mapWhenRealized:1; /* map the view when it's realized */
|
||||||
unsigned int alreadyDead:1; /* view was freed */
|
unsigned int alreadyDead:1; /* view was freed */
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
#include "WINGsP.h"
|
#include "WINGsP.h"
|
||||||
|
|
||||||
#define VERSION_INFO(dragInfo) dragInfo->protocolVersion
|
#define XDND_SOURCE_VERSION(dragInfo) dragInfo->protocolVersion
|
||||||
#define XDND_DEST_INFO(dragInfo) dragInfo->destInfo
|
#define XDND_DEST_INFO(dragInfo) dragInfo->destInfo
|
||||||
#define XDND_DEST_VIEW(dragInfo) dragInfo->destInfo->destView
|
#define XDND_DEST_VIEW(dragInfo) dragInfo->destInfo->destView
|
||||||
#define XDND_DEST_VIEW_STORED(dragInfo) ((dragInfo->destInfo) != NULL)\
|
|
||||||
&& ((dragInfo->destInfo->destView) != NULL)
|
|
||||||
|
|
||||||
|
|
||||||
static Bool _WindowExists;
|
static Bool _WindowExists;
|
||||||
@@ -151,6 +149,13 @@ W_SendDnDClientMessage(Display *dpy, Window win, Atom message,
|
|||||||
{
|
{
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
|
|
||||||
|
#ifdef XDND_DEBUG
|
||||||
|
char* msgName = XGetAtomName(dpy, message);
|
||||||
|
|
||||||
|
printf("sending message %s ... ", msgName);
|
||||||
|
XFree(msgName);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (! windowExists(dpy, win)) {
|
if (! windowExists(dpy, win)) {
|
||||||
wwarning("xdnd message target %d does no longer exist.", win);
|
wwarning("xdnd message target %d does no longer exist.", win);
|
||||||
return False; /* message not sent */
|
return False; /* message not sent */
|
||||||
@@ -170,6 +175,9 @@ W_SendDnDClientMessage(Display *dpy, Window win, Atom message,
|
|||||||
XSendEvent(dpy, win, False, 0, &ev);
|
XSendEvent(dpy, win, False, 0, &ev);
|
||||||
XFlush(dpy);
|
XFlush(dpy);
|
||||||
|
|
||||||
|
#ifdef XDND_DEBUG
|
||||||
|
printf("sent\n");
|
||||||
|
#endif
|
||||||
return True; /* message sent */
|
return True; /* message sent */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +186,9 @@ static void
|
|||||||
handleLeaveMessage(WMDraggingInfo *info)
|
handleLeaveMessage(WMDraggingInfo *info)
|
||||||
{
|
{
|
||||||
if (XDND_DEST_INFO(info) != NULL) {
|
if (XDND_DEST_INFO(info) != NULL) {
|
||||||
if (XDND_DEST_VIEW(info) != NULL) {
|
/* XDND_DEST_VIEW is never NULL (it's the xdnd aware view) */
|
||||||
|
wassertr(XDND_DEST_VIEW(info) != NULL);
|
||||||
|
if (XDND_DEST_VIEW(info)->dragDestinationProcs != NULL) {
|
||||||
XDND_DEST_VIEW(info)->dragDestinationProcs->concludeDragOperation(
|
XDND_DEST_VIEW(info)->dragDestinationProcs->concludeDragOperation(
|
||||||
XDND_DEST_VIEW(info));
|
XDND_DEST_VIEW(info));
|
||||||
}
|
}
|
||||||
@@ -216,11 +226,15 @@ W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event)
|
|||||||
|
|
||||||
/* Messages from source to destination */
|
/* Messages from source to destination */
|
||||||
if (messageType == scr->xdndEnterAtom) {
|
if (messageType == scr->xdndEnterAtom) {
|
||||||
|
Bool positionSent = (XDND_DEST_INFO(info) != NULL);
|
||||||
|
|
||||||
W_DragDestinationStopTimer();
|
W_DragDestinationStopTimer();
|
||||||
W_DragDestinationStoreEnterMsgInfo(info, toplevel, event);
|
W_DragDestinationStoreEnterMsgInfo(info, toplevel, event);
|
||||||
|
|
||||||
if (VERSION_INFO(info) <= XDND_VERSION) {
|
/* Xdnd version 3 and up are not compatible with version 1 or 2 */
|
||||||
if (XDND_DEST_VIEW_STORED(info)) {
|
if (XDND_SOURCE_VERSION(info) > 2) {
|
||||||
|
|
||||||
|
if (positionSent) {
|
||||||
/* xdndPosition previously received on xdnd aware view */
|
/* xdndPosition previously received on xdnd aware view */
|
||||||
W_DragDestinationStateHandler(info, event);
|
W_DragDestinationStateHandler(info, event);
|
||||||
return;
|
return;
|
||||||
@@ -230,7 +244,7 @@ W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wwarning("received dnd enter msg with unsupported version %i",
|
wwarning("received dnd enter msg with unsupported version %i",
|
||||||
VERSION_INFO(info));
|
XDND_SOURCE_VERSION(info));
|
||||||
W_DragDestinationCancelDropOnEnter(toplevel, info);
|
W_DragDestinationCancelDropOnEnter(toplevel, info);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,16 @@
|
|||||||
|
|
||||||
#define XDND_SOURCE_RESPONSE_MAX_DELAY 3000
|
#define XDND_SOURCE_RESPONSE_MAX_DELAY 3000
|
||||||
|
|
||||||
#define VERSION_INFO(dragInfo) dragInfo->protocolVersion
|
|
||||||
|
|
||||||
#define XDND_PROPERTY_FORMAT 32
|
#define XDND_PROPERTY_FORMAT 32
|
||||||
#define XDND_ACTION_DESCRIPTION_FORMAT 8
|
#define XDND_ACTION_DESCRIPTION_FORMAT 8
|
||||||
|
|
||||||
|
#define XDND_SOURCE_VERSION(dragInfo) dragInfo->protocolVersion
|
||||||
#define XDND_DEST_INFO(dragInfo) dragInfo->destInfo
|
#define XDND_DEST_INFO(dragInfo) dragInfo->destInfo
|
||||||
|
#define XDND_AWARE_VIEW(dragInfo) dragInfo->destInfo->xdndAwareView
|
||||||
#define XDND_SOURCE_WIN(dragInfo) dragInfo->destInfo->sourceWindow
|
#define XDND_SOURCE_WIN(dragInfo) dragInfo->destInfo->sourceWindow
|
||||||
#define XDND_DEST_VIEW(dragInfo) dragInfo->destInfo->destView
|
#define XDND_DEST_VIEW(dragInfo) dragInfo->destInfo->destView
|
||||||
#define XDND_DEST_STATE(dragInfo) dragInfo->destInfo->state
|
#define XDND_DEST_STATE(dragInfo) dragInfo->destInfo->state
|
||||||
|
#define XDND_SOURCE_ACTION_CHANGED(dragInfo) dragInfo->destInfo->sourceActionChanged
|
||||||
#define XDND_SOURCE_TYPES(dragInfo) dragInfo->destInfo->sourceTypes
|
#define XDND_SOURCE_TYPES(dragInfo) dragInfo->destInfo->sourceTypes
|
||||||
#define XDND_TYPE_LIST_AVAILABLE(dragInfo) dragInfo->destInfo->typeListAvailable
|
#define XDND_TYPE_LIST_AVAILABLE(dragInfo) dragInfo->destInfo->typeListAvailable
|
||||||
#define XDND_REQUIRED_TYPES(dragInfo) dragInfo->destInfo->requiredTypes
|
#define XDND_REQUIRED_TYPES(dragInfo) dragInfo->destInfo->requiredTypes
|
||||||
@@ -22,8 +23,8 @@
|
|||||||
#define XDND_SOURCE_OPERATIONS(dragInfo) dragInfo->destInfo->sourceOperations
|
#define XDND_SOURCE_OPERATIONS(dragInfo) dragInfo->destInfo->sourceOperations
|
||||||
#define XDND_DROP_DATAS(dragInfo) dragInfo->destInfo->dropDatas
|
#define XDND_DROP_DATAS(dragInfo) dragInfo->destInfo->dropDatas
|
||||||
#define XDND_DROP_DATA_COUNT(dragInfo) dragInfo->destInfo->dropDataCount
|
#define XDND_DROP_DATA_COUNT(dragInfo) dragInfo->destInfo->dropDataCount
|
||||||
#define XDND_DEST_VIEW_STORED(dragInfo) ((dragInfo->destInfo) != NULL)\
|
#define XDND_DEST_VIEW_IS_REGISTERED(dragInfo) ((dragInfo->destInfo) != NULL)\
|
||||||
&& ((dragInfo->destInfo->destView) != NULL)
|
&& ((dragInfo->destInfo->destView->dragDestinationProcs) != NULL)
|
||||||
|
|
||||||
|
|
||||||
static unsigned char XDNDversion = XDND_VERSION;
|
static unsigned char XDNDversion = XDND_VERSION;
|
||||||
@@ -81,7 +82,6 @@ createDropDataArray(WMArray *requiredTypes)
|
|||||||
static WMArray*
|
static WMArray*
|
||||||
getTypesFromTypeList(WMScreen *scr, Window sourceWin)
|
getTypesFromTypeList(WMScreen *scr, Window sourceWin)
|
||||||
{
|
{
|
||||||
/* // WMDraggingInfo *info = &scr->dragInfo;*/
|
|
||||||
Atom dataType;
|
Atom dataType;
|
||||||
Atom* typeAtomList;
|
Atom* typeAtomList;
|
||||||
WMArray* typeList;
|
WMArray* typeList;
|
||||||
@@ -138,22 +138,29 @@ storeRequiredTypeList(WMDraggingInfo *info)
|
|||||||
WMScreen *scr = W_VIEW_SCREEN(destView);
|
WMScreen *scr = W_VIEW_SCREEN(destView);
|
||||||
WMArray *requiredTypes;
|
WMArray *requiredTypes;
|
||||||
|
|
||||||
/* First, see if the 3 source types are enough for dest requirements */
|
/* First, see if the stored source types are enough for dest requirements */
|
||||||
requiredTypes = destView->dragDestinationProcs->requiredDataTypes(
|
requiredTypes = destView->dragDestinationProcs->requiredDataTypes(
|
||||||
destView,
|
destView,
|
||||||
W_ActionToOperation(scr, XDND_SOURCE_ACTION(info)),
|
W_ActionToOperation(scr, XDND_SOURCE_ACTION(info)),
|
||||||
XDND_SOURCE_TYPES(info));
|
XDND_SOURCE_TYPES(info));
|
||||||
|
|
||||||
if (requiredTypes == NULL && XDND_TYPE_LIST_AVAILABLE(info)) {
|
if (requiredTypes == NULL && XDND_TYPE_LIST_AVAILABLE(info)) {
|
||||||
/* None of the 3 source types fits, get the whole type list */
|
/* None of the stored source types fits, but the whole type list
|
||||||
|
hasn't been retrieved yet. */
|
||||||
|
WMFreeArray(XDND_SOURCE_TYPES(info));
|
||||||
|
XDND_SOURCE_TYPES(info) = getTypesFromTypeList(
|
||||||
|
scr,
|
||||||
|
XDND_SOURCE_WIN(info));
|
||||||
|
/* Don't retrieve the type list again */
|
||||||
|
XDND_TYPE_LIST_AVAILABLE(info) = False;
|
||||||
|
|
||||||
requiredTypes =
|
requiredTypes =
|
||||||
destView->dragDestinationProcs->requiredDataTypes(
|
destView->dragDestinationProcs->requiredDataTypes(
|
||||||
destView,
|
destView,
|
||||||
W_ActionToOperation(scr, XDND_SOURCE_ACTION(info)),
|
W_ActionToOperation(scr, XDND_SOURCE_ACTION(info)),
|
||||||
getTypesFromTypeList(scr, XDND_SOURCE_WIN(info)));
|
XDND_SOURCE_TYPES(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XDND_REQUIRED_TYPES(info) = requiredTypes;
|
XDND_REQUIRED_TYPES(info) = requiredTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,47 +256,35 @@ updateSourceWindow(WMDraggingInfo *info, XClientMessageEvent *event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Window
|
static WMView*
|
||||||
findChildInWindow(Display *dpy, Window toplevel, int x, int y)
|
findChildInView(WMView* parent, int x, int y)
|
||||||
{
|
{
|
||||||
Window foo, bar;
|
if (parent->childrenList == NULL)
|
||||||
Window *children;
|
return parent;
|
||||||
unsigned nchildren;
|
else {
|
||||||
int i;
|
WMView* child = parent->childrenList;
|
||||||
|
|
||||||
if (!XQueryTree(dpy, toplevel, &foo, &bar,
|
while (child != NULL
|
||||||
&children, &nchildren) || children == NULL) {
|
&& (! child->flags.mapped
|
||||||
return None;
|
|| x < WMGetViewPosition(child).x
|
||||||
|
|| x > WMGetViewPosition(child).x + WMGetViewSize(child).width
|
||||||
|
|| y < WMGetViewPosition(child).y
|
||||||
|
|| y > WMGetViewPosition(child).y + WMGetViewSize(child).height))
|
||||||
|
|
||||||
|
child = child->nextSister;
|
||||||
|
|
||||||
|
if (child == NULL)
|
||||||
|
return parent;
|
||||||
|
else
|
||||||
|
return findChildInView(child,
|
||||||
|
x - WMGetViewPosition(child).x,
|
||||||
|
y - WMGetViewPosition(child).y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first window that contains the point is the one */
|
|
||||||
for (i = nchildren-1; i >= 0; i--) {
|
|
||||||
XWindowAttributes attr;
|
|
||||||
|
|
||||||
if (XGetWindowAttributes(dpy, children[i], &attr)
|
|
||||||
&& attr.map_state == IsViewable
|
|
||||||
&& x >= attr.x && y >= attr.y
|
|
||||||
&& x < attr.x + attr.width && y < attr.y + attr.height) {
|
|
||||||
Window child, tmp;
|
|
||||||
|
|
||||||
tmp = children[i];
|
|
||||||
child = findChildInWindow(dpy, tmp, x - attr.x, y - attr.y);
|
|
||||||
XFree(children);
|
|
||||||
|
|
||||||
if (child == None)
|
|
||||||
return tmp;
|
|
||||||
else
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XFree(children);
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static WMView*
|
static WMView*
|
||||||
findXdndViewInToplevel(WMView* toplevel, int x, int y)
|
findDestinationViewInToplevel(WMView* toplevel, int x, int y)
|
||||||
{
|
{
|
||||||
WMScreen *scr = W_VIEW_SCREEN(toplevel);
|
WMScreen *scr = W_VIEW_SCREEN(toplevel);
|
||||||
Window toplevelWin = WMViewXID(toplevel);
|
Window toplevelWin = WMViewXID(toplevel);
|
||||||
@@ -300,20 +295,7 @@ findXdndViewInToplevel(WMView* toplevel, int x, int y)
|
|||||||
XTranslateCoordinates(scr->display, scr->rootWin, toplevelWin,
|
XTranslateCoordinates(scr->display, scr->rootWin, toplevelWin,
|
||||||
x, y, &xInToplevel, &yInToplevel,
|
x, y, &xInToplevel, &yInToplevel,
|
||||||
&foo);
|
&foo);
|
||||||
|
return findChildInView(toplevel, xInToplevel, yInToplevel);
|
||||||
child = findChildInWindow(scr->display, toplevelWin,
|
|
||||||
xInToplevel, yInToplevel);
|
|
||||||
|
|
||||||
if (child != None) {
|
|
||||||
childView = W_GetViewForXWindow(scr->display, child);
|
|
||||||
|
|
||||||
/* if childView supports Xdnd, return childView */
|
|
||||||
if (childView != NULL
|
|
||||||
&& childView->dragDestinationProcs != NULL)
|
|
||||||
return childView;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -334,6 +316,7 @@ freeDestinationViewInfos(WMDraggingInfo *info)
|
|||||||
XDND_REQUIRED_TYPES(info) = NULL;
|
XDND_REQUIRED_TYPES(info) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
W_DragDestinationInfoClear(WMDraggingInfo *info)
|
W_DragDestinationInfoClear(WMDraggingInfo *info)
|
||||||
{
|
{
|
||||||
@@ -347,15 +330,19 @@ W_DragDestinationInfoClear(WMDraggingInfo *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initDestinationDragInfo(WMDraggingInfo *info)
|
initDestinationDragInfo(WMDraggingInfo *info, WMView *destView)
|
||||||
{
|
{
|
||||||
|
wassertr(destView != NULL);
|
||||||
|
|
||||||
XDND_DEST_INFO(info) =
|
XDND_DEST_INFO(info) =
|
||||||
(W_DragDestinationInfo*) wmalloc(sizeof(W_DragDestinationInfo));
|
(W_DragDestinationInfo*) wmalloc(sizeof(W_DragDestinationInfo));
|
||||||
|
|
||||||
XDND_DEST_STATE(info) = idleState;
|
XDND_DEST_STATE(info) = idleState;
|
||||||
XDND_DEST_VIEW(info) = NULL;
|
XDND_DEST_VIEW(info) = destView;
|
||||||
|
|
||||||
|
XDND_SOURCE_ACTION_CHANGED(info) = False;
|
||||||
XDND_SOURCE_TYPES(info) = NULL;
|
XDND_SOURCE_TYPES(info) = NULL;
|
||||||
XDND_REQUIRED_TYPES(info) = NULL;
|
XDND_REQUIRED_TYPES(info) = NULL;
|
||||||
XDND_DROP_DATAS(info) = NULL;
|
XDND_DROP_DATAS(info) = NULL;
|
||||||
@@ -369,13 +356,19 @@ W_DragDestinationStoreEnterMsgInfo(WMDraggingInfo *info,
|
|||||||
WMScreen *scr = W_VIEW_SCREEN(toplevel);
|
WMScreen *scr = W_VIEW_SCREEN(toplevel);
|
||||||
|
|
||||||
if (XDND_DEST_INFO(info) == NULL)
|
if (XDND_DEST_INFO(info) == NULL)
|
||||||
initDestinationDragInfo(info);
|
initDestinationDragInfo(info, toplevel);
|
||||||
|
|
||||||
|
XDND_SOURCE_VERSION(info) = (event->data.l[1] >> 24);
|
||||||
|
XDND_AWARE_VIEW(info) = toplevel;
|
||||||
updateSourceWindow(info, event);
|
updateSourceWindow(info, event);
|
||||||
|
|
||||||
/* store xdnd version for source */
|
/*
|
||||||
info->protocolVersion = (event->data.l[1] >> 24);
|
if (event->data.l[1] & 1)
|
||||||
|
/* XdndTypeList property is available */
|
||||||
|
/* XDND_SOURCE_TYPES(info) = getTypesFromTypeList(scr, XDND_SOURCE_WIN(info));
|
||||||
|
else
|
||||||
|
XDND_SOURCE_TYPES(info) = getTypesFromThreeTypes(scr, event);
|
||||||
|
*/
|
||||||
XDND_SOURCE_TYPES(info) = getTypesFromThreeTypes(scr, event);
|
XDND_SOURCE_TYPES(info) = getTypesFromThreeTypes(scr, event);
|
||||||
|
|
||||||
/* to use if the 3 types are not enough */
|
/* to use if the 3 types are not enough */
|
||||||
@@ -383,45 +376,30 @@ W_DragDestinationStoreEnterMsgInfo(WMDraggingInfo *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
cancelDrop(WMView *destView, WMDraggingInfo *info);
|
|
||||||
|
|
||||||
static void
|
|
||||||
suspendDropAuthorization(WMView *destView, WMDraggingInfo *info);
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
W_DragDestinationStorePositionMsgInfo(WMDraggingInfo *info,
|
W_DragDestinationStorePositionMsgInfo(WMDraggingInfo *info,
|
||||||
WMView *toplevel, XClientMessageEvent *event)
|
WMView *toplevel, XClientMessageEvent *event)
|
||||||
{
|
{
|
||||||
int x = event->data.l[2] >> 16;
|
int x = event->data.l[2] >> 16;
|
||||||
int y = event->data.l[2] & 0xffff;
|
int y = event->data.l[2] & 0xffff;
|
||||||
WMView *oldDestView;
|
|
||||||
WMView *newDestView;
|
WMView *newDestView;
|
||||||
|
|
||||||
newDestView = findXdndViewInToplevel(toplevel, x, y);
|
newDestView = findDestinationViewInToplevel(toplevel, x, y);
|
||||||
|
|
||||||
if (XDND_DEST_INFO(info) == NULL) {
|
if (XDND_DEST_INFO(info) == NULL) {
|
||||||
initDestinationDragInfo(info);
|
initDestinationDragInfo(info, newDestView);
|
||||||
|
XDND_AWARE_VIEW(info) = toplevel;
|
||||||
updateSourceWindow(info, event);
|
updateSourceWindow(info, event);
|
||||||
XDND_DEST_VIEW(info) = newDestView;
|
} else {
|
||||||
}
|
if (newDestView != XDND_DEST_VIEW(info)) {
|
||||||
else {
|
|
||||||
oldDestView = XDND_DEST_VIEW(info);
|
|
||||||
|
|
||||||
if (newDestView != oldDestView) {
|
|
||||||
if (oldDestView != NULL) {
|
|
||||||
suspendDropAuthorization(oldDestView, info);
|
|
||||||
XDND_DEST_STATE(info) = dropNotAllowedState;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSourceWindow(info, event);
|
updateSourceWindow(info, event);
|
||||||
XDND_DEST_VIEW(info) = newDestView;
|
XDND_DEST_VIEW(info) = newDestView;
|
||||||
|
XDND_SOURCE_ACTION_CHANGED(info) = False;
|
||||||
|
|
||||||
if (newDestView != NULL) {
|
if (XDND_DEST_STATE(info) != waitEnterState)
|
||||||
if (XDND_DEST_STATE(info) != waitEnterState)
|
XDND_DEST_STATE(info) = idleState;
|
||||||
XDND_DEST_STATE(info) = idleState;
|
} else {
|
||||||
}
|
XDND_SOURCE_ACTION_CHANGED(info) = (XDND_SOURCE_ACTION(info) != event->data.l[4]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,27 +415,62 @@ void
|
|||||||
|
|
||||||
/* send a DnD message to the source window */
|
/* send a DnD message to the source window */
|
||||||
static void
|
static void
|
||||||
sendDnDClientMessage(WMView *destView, Atom message,
|
sendDnDClientMessage(WMDraggingInfo *info, Atom message,
|
||||||
unsigned long data1,
|
unsigned long data1,
|
||||||
unsigned long data2,
|
unsigned long data2,
|
||||||
unsigned long data3,
|
unsigned long data3,
|
||||||
unsigned long data4)
|
unsigned long data4)
|
||||||
{
|
{
|
||||||
WMScreen *scr = W_VIEW_SCREEN(destView);
|
if (! W_SendDnDClientMessage(W_VIEW_SCREEN(XDND_AWARE_VIEW(info))->display,
|
||||||
WMDraggingInfo *info = &scr->dragInfo;
|
XDND_SOURCE_WIN(info),
|
||||||
|
message,
|
||||||
|
WMViewXID(XDND_AWARE_VIEW(info)),
|
||||||
|
data1,
|
||||||
|
data2,
|
||||||
|
data3,
|
||||||
|
data4)) {
|
||||||
|
/* drop failed */
|
||||||
|
W_DragDestinationInfoClear(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (XDND_DEST_INFO(info) != NULL) {
|
|
||||||
if (! W_SendDnDClientMessage(scr->display,
|
/* send a xdndStatus message to the source, with position and size
|
||||||
XDND_SOURCE_WIN(info),
|
of the destination if it has no subwidget (requesting a position message
|
||||||
message,
|
on every move otherwise) */
|
||||||
WMViewXID(destView),
|
static void
|
||||||
data1,
|
sendStatusMessage(WMView *destView, WMDraggingInfo *info, Atom action)
|
||||||
data2,
|
{
|
||||||
data3,
|
unsigned long data1;
|
||||||
data4)) {
|
|
||||||
/* drop failed */
|
data1 = (action == None) ? 0 : 1;
|
||||||
W_DragDestinationInfoClear(info);
|
|
||||||
}
|
if (destView->childrenList == NULL) {
|
||||||
|
WMScreen *scr = W_VIEW_SCREEN(destView);
|
||||||
|
int destX, destY;
|
||||||
|
WMSize destSize = WMGetViewSize(destView);
|
||||||
|
Window foo;
|
||||||
|
|
||||||
|
XTranslateCoordinates(scr->display, WMViewXID(destView), scr->rootWin,
|
||||||
|
0, 0, &destX, &destY,
|
||||||
|
&foo);
|
||||||
|
|
||||||
|
sendDnDClientMessage(info,
|
||||||
|
W_VIEW_SCREEN(destView)->xdndStatusAtom,
|
||||||
|
data1,
|
||||||
|
(destX << 16)|destY,
|
||||||
|
(destSize.width << 16)|destSize.height,
|
||||||
|
action);
|
||||||
|
} else {
|
||||||
|
/* set bit 1 to request explicitly position message on every move */
|
||||||
|
data1 = data1 | 2;
|
||||||
|
|
||||||
|
sendDnDClientMessage(info,
|
||||||
|
W_VIEW_SCREEN(destView)->xdndStatusAtom,
|
||||||
|
data1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,31 +547,26 @@ concludeDrop(WMView *destView)
|
|||||||
static void
|
static void
|
||||||
cancelDrop(WMView *destView, WMDraggingInfo *info)
|
cancelDrop(WMView *destView, WMDraggingInfo *info)
|
||||||
{
|
{
|
||||||
/* send XdndStatus with action None */
|
sendStatusMessage(destView, info, None);
|
||||||
sendDnDClientMessage(destView,
|
|
||||||
W_VIEW_SCREEN(destView)->xdndStatusAtom,
|
|
||||||
0, 0, 0, None);
|
|
||||||
concludeDrop(destView);
|
concludeDrop(destView);
|
||||||
freeDestinationViewInfos(info);
|
freeDestinationViewInfos(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* suspend drop, when dragged icon enter an unaware subview of destView */
|
/* suspend drop, when dragged icon enter an unregistered view
|
||||||
|
or a register view that doesn't accept the drop */
|
||||||
static void
|
static void
|
||||||
suspendDropAuthorization(WMView *destView, WMDraggingInfo *info)
|
suspendDropAuthorization(WMView *destView, WMDraggingInfo *info)
|
||||||
{
|
{
|
||||||
/* free datas that depend on destination behaviour */
|
sendStatusMessage(destView, info, None);
|
||||||
/* (in short: only keep source's types) */
|
|
||||||
|
/* Free datas that depend on destination behaviour */
|
||||||
if (XDND_DROP_DATAS(info) != NULL) {
|
if (XDND_DROP_DATAS(info) != NULL) {
|
||||||
WMFreeArray(XDND_DROP_DATAS(info));
|
WMFreeArray(XDND_DROP_DATAS(info));
|
||||||
XDND_DROP_DATAS(info) = NULL;
|
XDND_DROP_DATAS(info) = NULL;
|
||||||
}
|
}
|
||||||
XDND_REQUIRED_TYPES(info) = NULL;
|
|
||||||
|
|
||||||
/* send XdndStatus with action None */
|
XDND_REQUIRED_TYPES(info) = NULL;
|
||||||
sendDnDClientMessage(destView,
|
|
||||||
W_VIEW_SCREEN(destView)->xdndStatusAtom,
|
|
||||||
0, 0, 0, None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -566,14 +574,10 @@ suspendDropAuthorization(WMView *destView, WMDraggingInfo *info)
|
|||||||
void
|
void
|
||||||
W_DragDestinationCancelDropOnEnter(WMView *toplevel, WMDraggingInfo *info)
|
W_DragDestinationCancelDropOnEnter(WMView *toplevel, WMDraggingInfo *info)
|
||||||
{
|
{
|
||||||
if (XDND_DEST_VIEW_STORED(info))
|
if (XDND_DEST_VIEW_IS_REGISTERED(info))
|
||||||
cancelDrop(XDND_DEST_VIEW(info), info);
|
cancelDrop(XDND_DEST_VIEW(info), info);
|
||||||
else {
|
else
|
||||||
/* send XdndStatus with action None */
|
sendStatusMessage(toplevel, info, None);
|
||||||
sendDnDClientMessage(toplevel,
|
|
||||||
W_VIEW_SCREEN(toplevel)->xdndStatusAtom,
|
|
||||||
0, 0, 0, None);
|
|
||||||
}
|
|
||||||
|
|
||||||
W_DragDestinationInfoClear(info);
|
W_DragDestinationInfoClear(info);
|
||||||
}
|
}
|
||||||
@@ -582,7 +586,7 @@ W_DragDestinationCancelDropOnEnter(WMView *toplevel, WMDraggingInfo *info)
|
|||||||
static void
|
static void
|
||||||
finishDrop(WMView *destView, WMDraggingInfo *info)
|
finishDrop(WMView *destView, WMDraggingInfo *info)
|
||||||
{
|
{
|
||||||
sendDnDClientMessage(destView,
|
sendDnDClientMessage(info,
|
||||||
W_VIEW_SCREEN(destView)->xdndFinishedAtom,
|
W_VIEW_SCREEN(destView)->xdndFinishedAtom,
|
||||||
0, 0, 0, 0);
|
0, 0, 0, 0);
|
||||||
concludeDrop(destView);
|
concludeDrop(destView);
|
||||||
@@ -603,31 +607,6 @@ getAllowedAction(WMView *destView, WMDraggingInfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* send the action that can be performed,
|
|
||||||
and the limits outside wich the source must re-send
|
|
||||||
its position and action */
|
|
||||||
static void
|
|
||||||
sendAllowedAction(WMView *destView, Atom action)
|
|
||||||
{
|
|
||||||
WMScreen *scr = W_VIEW_SCREEN(destView);
|
|
||||||
/* // WMPoint destPos = WMGetViewScreenPosition(destView); */
|
|
||||||
WMSize destSize = WMGetViewSize(destView);
|
|
||||||
int destX, destY;
|
|
||||||
Window foo;
|
|
||||||
|
|
||||||
XTranslateCoordinates(scr->display, scr->rootWin, WMViewXID(destView),
|
|
||||||
0, 0, &destX, &destY,
|
|
||||||
&foo);
|
|
||||||
|
|
||||||
sendDnDClientMessage(destView,
|
|
||||||
scr->xdndStatusAtom,
|
|
||||||
1,
|
|
||||||
(destX << 16)|destY,
|
|
||||||
(destSize.width << 16)|destSize.height,
|
|
||||||
action);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
checkActionAllowed(WMView *destView, WMDraggingInfo* info)
|
checkActionAllowed(WMView *destView, WMDraggingInfo* info)
|
||||||
{
|
{
|
||||||
@@ -639,10 +618,11 @@ checkActionAllowed(WMView *destView, WMDraggingInfo* info)
|
|||||||
return dropNotAllowedState;
|
return dropNotAllowedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendAllowedAction(destView, XDND_DEST_ACTION(info));
|
sendStatusMessage(destView, info, XDND_DEST_ACTION(info));
|
||||||
return dropAllowedState;
|
return dropAllowedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
checkDropAllowed(WMView *destView, XClientMessageEvent *event,
|
checkDropAllowed(WMView *destView, XClientMessageEvent *event,
|
||||||
WMDraggingInfo* info)
|
WMDraggingInfo* info)
|
||||||
@@ -670,6 +650,7 @@ checkDropAllowed(WMView *destView, XClientMessageEvent *event,
|
|||||||
return checkActionAllowed(destView, info);
|
return checkActionAllowed(destView, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static WMPoint*
|
static WMPoint*
|
||||||
getDropLocationInView(WMView *view)
|
getDropLocationInView(WMView *view)
|
||||||
{
|
{
|
||||||
@@ -690,6 +671,7 @@ getDropLocationInView(WMView *view)
|
|||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
callPerformDragOperation(WMView *destView, WMDraggingInfo *info)
|
callPerformDragOperation(WMView *destView, WMDraggingInfo *info)
|
||||||
{
|
{
|
||||||
@@ -721,21 +703,17 @@ dragSourceResponseTimeOut(void *destView)
|
|||||||
WMDraggingInfo *info;
|
WMDraggingInfo *info;
|
||||||
|
|
||||||
wwarning("delay for drag source response expired");
|
wwarning("delay for drag source response expired");
|
||||||
if (view != NULL) {
|
info = &(W_VIEW_SCREEN(view)->dragInfo);
|
||||||
info = &(W_VIEW_SCREEN(view)->dragInfo);
|
if (XDND_DEST_VIEW_IS_REGISTERED(info))
|
||||||
if (XDND_DEST_VIEW_STORED(info))
|
cancelDrop(view, info);
|
||||||
cancelDrop(view, info);
|
else {
|
||||||
else {
|
sendStatusMessage(view, info, None);
|
||||||
/* send XdndStatus with action None */
|
|
||||||
sendDnDClientMessage(view,
|
|
||||||
W_VIEW_SCREEN(view)->xdndStatusAtom,
|
|
||||||
0, 0, 0, None);
|
|
||||||
}
|
|
||||||
|
|
||||||
W_DragDestinationInfoClear(info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
W_DragDestinationInfoClear(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
W_DragDestinationStopTimer()
|
W_DragDestinationStopTimer()
|
||||||
{
|
{
|
||||||
@@ -745,21 +723,17 @@ W_DragDestinationStopTimer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
W_DragDestinationStartTimer(WMDraggingInfo *info)
|
W_DragDestinationStartTimer(WMDraggingInfo *info)
|
||||||
{
|
{
|
||||||
W_DragDestinationStopTimer();
|
W_DragDestinationStopTimer();
|
||||||
|
|
||||||
if (XDND_DEST_STATE(info) != idleState
|
if (XDND_DEST_STATE(info) != idleState)
|
||||||
|| XDND_DEST_VIEW(info) == NULL) {
|
|
||||||
/* note: info->destView == NULL means :
|
|
||||||
Enter message has been received, waiting for Position message */
|
|
||||||
|
|
||||||
dndDestinationTimer = WMAddTimerHandler(
|
dndDestinationTimer = WMAddTimerHandler(
|
||||||
XDND_SOURCE_RESPONSE_MAX_DELAY,
|
XDND_SOURCE_RESPONSE_MAX_DELAY,
|
||||||
dragSourceResponseTimeOut,
|
dragSourceResponseTimeOut,
|
||||||
XDND_DEST_VIEW(info));
|
XDND_DEST_VIEW(info));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* ----- End of Destination timer ----- */
|
/* ----- End of Destination timer ----- */
|
||||||
|
|
||||||
@@ -795,6 +769,7 @@ stateName(W_DndState *state)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
idleState(WMView *destView, XClientMessageEvent *event,
|
idleState(WMView *destView, XClientMessageEvent *event,
|
||||||
WMDraggingInfo *info)
|
WMDraggingInfo *info)
|
||||||
@@ -802,21 +777,24 @@ idleState(WMView *destView, XClientMessageEvent *event,
|
|||||||
WMScreen *scr;
|
WMScreen *scr;
|
||||||
Atom sourceMsg;
|
Atom sourceMsg;
|
||||||
|
|
||||||
scr = W_VIEW_SCREEN(destView);
|
if (destView->dragDestinationProcs != NULL) {
|
||||||
sourceMsg = event->message_type;
|
scr = W_VIEW_SCREEN(destView);
|
||||||
|
sourceMsg = event->message_type;
|
||||||
|
|
||||||
if (sourceMsg == scr->xdndPositionAtom) {
|
if (sourceMsg == scr->xdndPositionAtom) {
|
||||||
destView->dragDestinationProcs->prepareForDragOperation(destView);
|
destView->dragDestinationProcs->prepareForDragOperation(destView);
|
||||||
|
|
||||||
if (XDND_SOURCE_TYPES(info) != NULL) {
|
if (XDND_SOURCE_TYPES(info) != NULL) {
|
||||||
/* enter message infos are available */
|
/* enter message infos are available */
|
||||||
return checkDropAllowed(destView, event, info);
|
return checkDropAllowed(destView, event, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* waiting for enter message */
|
||||||
|
return waitEnterState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* waiting for enter message */
|
|
||||||
return waitEnterState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspendDropAuthorization(destView, info);
|
||||||
return idleState;
|
return idleState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,6 +859,15 @@ dropNotAllowedState(WMView *destView, XClientMessageEvent *event,
|
|||||||
return idleState;
|
return idleState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sourceMsg == scr->xdndPositionAtom) {
|
||||||
|
if (XDND_SOURCE_ACTION_CHANGED(info)) {
|
||||||
|
return checkDropAllowed(destView, event, info);
|
||||||
|
} else {
|
||||||
|
sendStatusMessage(destView, info, None);
|
||||||
|
return dropNotAllowedState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return dropNotAllowedState;
|
return dropNotAllowedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -912,6 +899,15 @@ dropAllowedState(WMView *destView, XClientMessageEvent *event,
|
|||||||
return idleState;
|
return idleState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sourceMsg == scr->xdndPositionAtom) {
|
||||||
|
if (XDND_SOURCE_ACTION_CHANGED(info)) {
|
||||||
|
return checkDropAllowed(destView, event, info);
|
||||||
|
} else {
|
||||||
|
sendStatusMessage(destView, info, XDND_DEST_ACTION(info));
|
||||||
|
return dropAllowedState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return dropAllowedState;
|
return dropAllowedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -947,29 +943,30 @@ W_DragDestinationStateHandler(WMDraggingInfo *info, XClientMessageEvent *event)
|
|||||||
WMView *destView;
|
WMView *destView;
|
||||||
W_DndState* newState;
|
W_DndState* newState;
|
||||||
|
|
||||||
if (XDND_DEST_VIEW_STORED(info)) {
|
wassertr(XDND_DEST_INFO(info) != NULL);
|
||||||
destView = XDND_DEST_VIEW(info);
|
wassertr(XDND_DEST_VIEW(info) != NULL);
|
||||||
if (XDND_DEST_STATE(info) == NULL)
|
|
||||||
XDND_DEST_STATE(info) = idleState;
|
destView = XDND_DEST_VIEW(info);
|
||||||
|
if (XDND_DEST_STATE(info) == NULL)
|
||||||
|
XDND_DEST_STATE(info) = idleState;
|
||||||
|
|
||||||
#ifdef XDND_DEBUG
|
#ifdef XDND_DEBUG
|
||||||
|
|
||||||
printf("current dest state: %s\n",
|
printf("current dest state: %s\n",
|
||||||
stateName(XDND_DEST_STATE(info)));
|
stateName(XDND_DEST_STATE(info)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
newState = (W_DndState*) XDND_DEST_STATE(info)(destView, event, info);
|
newState = (W_DndState*) XDND_DEST_STATE(info)(destView, event, info);
|
||||||
|
|
||||||
#ifdef XDND_DEBUG
|
#ifdef XDND_DEBUG
|
||||||
|
|
||||||
printf("new dest state: %s\n", stateName(newState));
|
printf("new dest state: %s\n", stateName(newState));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (XDND_DEST_INFO(info) != NULL) {
|
if (XDND_DEST_INFO(info) != NULL) {
|
||||||
XDND_DEST_STATE(info) = newState;
|
XDND_DEST_STATE(info) = newState;
|
||||||
if (XDND_DEST_STATE(info) != idleState)
|
if (XDND_DEST_STATE(info) != idleState)
|
||||||
W_DragDestinationStartTimer(info);
|
W_DragDestinationStartTimer(info);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1104,7 +1101,7 @@ defPrepareForDragOperation(WMView *self)
|
|||||||
Process drop
|
Process drop
|
||||||
dropDatas: datas (WMData*) required by destination (self)
|
dropDatas: datas (WMData*) required by destination (self)
|
||||||
(given in same order as returned by requiredDataTypes).
|
(given in same order as returned by requiredDataTypes).
|
||||||
A NULL data means it couldn't be retrivied.
|
A NULL data means it couldn't be retrieved.
|
||||||
Destroyed when drop ends.
|
Destroyed when drop ends.
|
||||||
operationList: if source operation is WDOperationAsk, contains
|
operationList: if source operation is WDOperationAsk, contains
|
||||||
operations (and associated texts) that can be asked
|
operations (and associated texts) that can be asked
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
#define MIN_Y_MOVE_OFFSET 5
|
#define MIN_Y_MOVE_OFFSET 5
|
||||||
#define MAX_SLIDEBACK_ITER 15
|
#define MAX_SLIDEBACK_ITER 15
|
||||||
|
|
||||||
#define VERSION_INFO(dragInfo) dragInfo->protocolVersion
|
|
||||||
#define XDND_PROPERTY_FORMAT 32
|
#define XDND_PROPERTY_FORMAT 32
|
||||||
#define XDND_ACTION_DESCRIPTION_FORMAT 8
|
#define XDND_ACTION_DESCRIPTION_FORMAT 8
|
||||||
|
|
||||||
|
#define XDND_DEST_VERSION(dragInfo) dragInfo->protocolVersion
|
||||||
#define XDND_SOURCE_INFO(dragInfo) dragInfo->sourceInfo
|
#define XDND_SOURCE_INFO(dragInfo) dragInfo->sourceInfo
|
||||||
#define XDND_DEST_WIN(dragInfo) dragInfo->sourceInfo->destinationWindow
|
#define XDND_DEST_WIN(dragInfo) dragInfo->sourceInfo->destinationWindow
|
||||||
#define XDND_SOURCE_ACTION(dragInfo) dragInfo->sourceAction
|
#define XDND_SOURCE_ACTION(dragInfo) dragInfo->sourceAction
|
||||||
@@ -415,21 +415,25 @@ static Bool
|
|||||||
sendEnterMessage(WMDraggingInfo *info)
|
sendEnterMessage(WMDraggingInfo *info)
|
||||||
{
|
{
|
||||||
WMScreen *scr = sourceScreen(info);
|
WMScreen *scr = sourceScreen(info);
|
||||||
unsigned long data1;
|
unsigned long version;
|
||||||
|
|
||||||
data1 = (VERSION_INFO(info) << 24)|1; /* 1: support of type list */
|
if (XDND_DEST_VERSION(info) > 2) {
|
||||||
|
if (XDND_DEST_VERSION(info) < XDND_VERSION)
|
||||||
|
version = XDND_DEST_VERSION(info);
|
||||||
|
else
|
||||||
|
version = XDND_VERSION;
|
||||||
|
} else {
|
||||||
|
version = 3;
|
||||||
|
}
|
||||||
|
|
||||||
return sendDnDClientMessage(info, scr->xdndEnterAtom,
|
return sendDnDClientMessage(info, scr->xdndEnterAtom,
|
||||||
data1,
|
(version << 24) | 1, /* 1: support of type list */
|
||||||
XDND_3_TYPES(info)[0],
|
XDND_3_TYPES(info)[0],
|
||||||
XDND_3_TYPES(info)[1],
|
XDND_3_TYPES(info)[1],
|
||||||
XDND_3_TYPES(info)[2]);
|
XDND_3_TYPES(info)[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
// this functon doesn't return something in all cases.
|
|
||||||
// control reaches end of non-void function. fix this -Dan */
|
|
||||||
static Bool
|
static Bool
|
||||||
sendPositionMessage(WMDraggingInfo *info, WMPoint *mousePos)
|
sendPositionMessage(WMDraggingInfo *info, WMPoint *mousePos)
|
||||||
{
|
{
|
||||||
@@ -440,7 +444,7 @@ sendPositionMessage(WMDraggingInfo *info, WMPoint *mousePos)
|
|||||||
if (mousePos->x < noPosZone->pos.x
|
if (mousePos->x < noPosZone->pos.x
|
||||||
|| mousePos->x > (noPosZone->pos.x + noPosZone->size.width)
|
|| mousePos->x > (noPosZone->pos.x + noPosZone->size.width)
|
||||||
|| mousePos->y < noPosZone->pos.y
|
|| mousePos->y < noPosZone->pos.y
|
||||||
|| mousePos->y > (noPosZone->pos.y + noPosZone->size.width)) {
|
|| mousePos->y > (noPosZone->pos.y + noPosZone->size.height)) {
|
||||||
/* send position if out of zone defined by destination */
|
/* send position if out of zone defined by destination */
|
||||||
return sendDnDClientMessage(info, scr->xdndPositionAtom,
|
return sendDnDClientMessage(info, scr->xdndPositionAtom,
|
||||||
0,
|
0,
|
||||||
@@ -448,14 +452,18 @@ sendPositionMessage(WMDraggingInfo *info, WMPoint *mousePos)
|
|||||||
XDND_TIMESTAMP(info),
|
XDND_TIMESTAMP(info),
|
||||||
XDND_SOURCE_ACTION(info));
|
XDND_SOURCE_ACTION(info));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
/* send position on each move */
|
/* Nothing to send, always succeed */
|
||||||
return sendDnDClientMessage(info, scr->xdndPositionAtom,
|
return True;
|
||||||
0,
|
|
||||||
mousePos->x<<16|mousePos->y,
|
|
||||||
XDND_TIMESTAMP(info),
|
|
||||||
XDND_SOURCE_ACTION(info));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send position on each move */
|
||||||
|
return sendDnDClientMessage(info, scr->xdndPositionAtom,
|
||||||
|
0,
|
||||||
|
mousePos->x<<16|mousePos->y,
|
||||||
|
XDND_TIMESTAMP(info),
|
||||||
|
XDND_SOURCE_ACTION(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -845,6 +853,30 @@ findDestination(WMDraggingInfo *info, WMPoint *mousePos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
storeDestinationProtocolVersion(WMDraggingInfo *info)
|
||||||
|
{
|
||||||
|
Atom type;
|
||||||
|
int format;
|
||||||
|
unsigned long count, remain;
|
||||||
|
unsigned char *winXdndVersion;
|
||||||
|
WMScreen *scr = W_VIEW_SCREEN(XDND_SOURCE_VIEW(info));
|
||||||
|
|
||||||
|
wassertr(XDND_DEST_WIN(info) != None);
|
||||||
|
|
||||||
|
if (XGetWindowProperty(scr->display, XDND_DEST_WIN(info),
|
||||||
|
scr->xdndAwareAtom,
|
||||||
|
0, 1, False, XA_ATOM, &type, &format,
|
||||||
|
&count, &remain, &winXdndVersion) == Success) {
|
||||||
|
XDND_DEST_VERSION(info) = *winXdndVersion;
|
||||||
|
XFree(winXdndVersion);
|
||||||
|
} else {
|
||||||
|
XDND_DEST_VERSION(info) = 0;
|
||||||
|
wwarning("failed to read XDND version of drop target");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initMotionProcess(WMView *view, WMDraggingInfo *info,
|
initMotionProcess(WMView *view, WMDraggingInfo *info,
|
||||||
XEvent *event, WMPoint *startLocation)
|
XEvent *event, WMPoint *startLocation)
|
||||||
@@ -878,9 +910,8 @@ initMotionProcess(WMView *view, WMDraggingInfo *info,
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
processMotion(WMDraggingInfo *info, Window windowUnderDrag, WMPoint *mousePos)
|
processMotion(WMDraggingInfo *info, WMPoint *mousePos)
|
||||||
{
|
{
|
||||||
/* // WMScreen *scr = sourceScreen(info); */
|
|
||||||
Window newDestination = findDestination(info, mousePos);
|
Window newDestination = findDestination(info, mousePos);
|
||||||
|
|
||||||
W_DragSourceStopTimer();
|
W_DragSourceStopTimer();
|
||||||
@@ -894,20 +925,24 @@ processMotion(WMDraggingInfo *info, Window windowUnderDrag, WMPoint *mousePos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
XDND_DEST_WIN(info) = newDestination;
|
XDND_DEST_WIN(info) = newDestination;
|
||||||
XDND_SOURCE_STATE(info) = idleState;
|
|
||||||
XDND_DEST_ACTION(info) = None;
|
XDND_DEST_ACTION(info) = None;
|
||||||
XDND_NO_POS_ZONE(info).size.width = 0;
|
XDND_NO_POS_ZONE(info).size.width = 0;
|
||||||
XDND_NO_POS_ZONE(info).size.height = 0;
|
XDND_NO_POS_ZONE(info).size.height = 0;
|
||||||
|
|
||||||
if (newDestination != None) {
|
if (newDestination != None) {
|
||||||
/* entering a xdnd window */
|
/* entering a xdnd window */
|
||||||
|
XDND_SOURCE_STATE(info) = idleState;
|
||||||
|
storeDestinationProtocolVersion(info);
|
||||||
|
|
||||||
if (! sendEnterMessage(info)) {
|
if (! sendEnterMessage(info)) {
|
||||||
XDND_DEST_WIN(info) = None;
|
XDND_DEST_WIN(info) = None;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
W_DragSourceStartTimer(info);
|
W_DragSourceStartTimer(info);
|
||||||
}
|
} else {
|
||||||
|
XDND_SOURCE_STATE(info) = NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (XDND_DEST_WIN(info) != None) {
|
if (XDND_DEST_WIN(info) != None) {
|
||||||
if (! sendPositionMessage(info, mousePos)) {
|
if (! sendPositionMessage(info, mousePos)) {
|
||||||
@@ -1010,9 +1045,7 @@ WMDragImageFromView(WMView *view, XEvent *event)
|
|||||||
mouseLocation.y - XDND_MOUSE_OFFSET(info).y;
|
mouseLocation.y - XDND_MOUSE_OFFSET(info).y;
|
||||||
|
|
||||||
refreshDragImage(view, info);
|
refreshDragImage(view, info);
|
||||||
processMotion(info,
|
processMotion(info, &mouseLocation);
|
||||||
event->xmotion.window,
|
|
||||||
&mouseLocation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1041,7 +1074,7 @@ traceStatusMsg(Display *dpy, XClientMessageEvent *statusEvent)
|
|||||||
printf("Xdnd status message:\n");
|
printf("Xdnd status message:\n");
|
||||||
|
|
||||||
if (statusEvent->data.l[1] & 0x2UL)
|
if (statusEvent->data.l[1] & 0x2UL)
|
||||||
printf("send position on every move\n");
|
printf("\tsend position on every move\n");
|
||||||
else {
|
else {
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
x = statusEvent->data.l[2] >> 16;
|
x = statusEvent->data.l[2] >> 16;
|
||||||
@@ -1049,15 +1082,15 @@ traceStatusMsg(Display *dpy, XClientMessageEvent *statusEvent)
|
|||||||
w = statusEvent->data.l[3] >> 16;
|
w = statusEvent->data.l[3] >> 16;
|
||||||
h = statusEvent->data.l[3] & 0xFFFFL;
|
h = statusEvent->data.l[3] & 0xFFFFL;
|
||||||
|
|
||||||
printf("send position out of ((%d,%d) , (%d,%d))\n",
|
printf("\tsend position out of ((%d,%d) , (%d,%d))\n",
|
||||||
x, y, x+w, y+h);
|
x, y, x+w, y+h);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statusEvent->data.l[1] & 0x1L)
|
if (statusEvent->data.l[1] & 0x1L)
|
||||||
printf("allowed action: %s\n",
|
printf("\tallowed action: %s\n",
|
||||||
XGetAtomName(dpy, statusEvent->data.l[4]));
|
XGetAtomName(dpy, statusEvent->data.l[4]));
|
||||||
else
|
else
|
||||||
printf("no action allowed\n");
|
printf("\tno action allowed\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1231,23 +1264,28 @@ W_DragSourceStateHandler(WMDraggingInfo *info, XClientMessageEvent *event)
|
|||||||
W_DndState* newState;
|
W_DndState* newState;
|
||||||
|
|
||||||
if (XDND_SOURCE_VIEW_STORED(info)) {
|
if (XDND_SOURCE_VIEW_STORED(info)) {
|
||||||
view = XDND_SOURCE_VIEW(info);
|
if (XDND_SOURCE_STATE(info) != NULL) {
|
||||||
|
view = XDND_SOURCE_VIEW(info);
|
||||||
#ifdef XDND_DEBUG
|
#ifdef XDND_DEBUG
|
||||||
|
|
||||||
printf("current source state: %s\n",
|
printf("current source state: %s\n",
|
||||||
stateName(XDND_SOURCE_STATE(info)));
|
stateName(XDND_SOURCE_STATE(info)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
newState = (W_DndState*) XDND_SOURCE_STATE(info)(view, event, info);
|
newState = (W_DndState*) XDND_SOURCE_STATE(info)(view, event, info);
|
||||||
|
|
||||||
#ifdef XDND_DEBUG
|
#ifdef XDND_DEBUG
|
||||||
|
|
||||||
printf("new source state: %s\n", stateName(newState));
|
printf("new source state: %s\n", stateName(newState));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (newState != NULL)
|
if (newState != NULL)
|
||||||
XDND_SOURCE_STATE(info) = newState;
|
XDND_SOURCE_STATE(info) = newState;
|
||||||
/* else drop finished, and info has been flushed */
|
/* else drop finished, and info has been flushed */
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
wwarning("received DnD message without having a target");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user