1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-02-15 13:35:53 +01:00

added drag and drop

This commit is contained in:
kojima
2000-04-03 06:08:31 +00:00
parent 60a247f271
commit 567e53c67c
6 changed files with 383 additions and 60 deletions

View File

@@ -1,8 +1,17 @@
#include "../src/config.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#ifdef SHAPE
#include <X11/extensions/shape.h>
#endif
#include <math.h>
#include "WINGsP.h"
@@ -22,6 +31,27 @@ static Bool _XErrorOccured = False;
static unsigned defDraggingSourceOperation(WMView *self, Bool local)
{
return WDOperationCopy;
}
static void defBeganDragImage(WMView *self, WMPixmap *image, WMPoint point)
{
}
static void defEndedDragImage(WMView *self, WMPixmap *image, WMPoint point,
Bool deposited)
{
}
static WMData* defFetchDragData(WMView *self, char *type)
{
return NULL;
}
void
WMSetViewDragSourceProcs(WMView *view, WMDragSourceProcs *procs)
@@ -31,8 +61,19 @@ WMSetViewDragSourceProcs(WMView *view, WMDragSourceProcs *procs)
view->dragSourceProcs = wmalloc(sizeof(WMDragSourceProcs));
*view->dragSourceProcs = *procs;
/* XXX fill in non-implemented stuffs */
if (procs->draggingSourceOperation == NULL) {
view->dragSourceProcs->draggingSourceOperation = defDraggingSourceOperation;
}
if (procs->beganDragImage == NULL) {
view->dragSourceProcs->beganDragImage = defBeganDragImage;
}
if (procs->endedDragImage == NULL) {
view->dragSourceProcs->endedDragImage = defEndedDragImage;
}
if (procs->fetchDragData == NULL) {
view->dragSourceProcs->fetchDragData = defFetchDragData;
}
}
@@ -90,7 +131,7 @@ makeDragIcon(WMScreen *scr, WMPixmap *pixmap)
#ifdef SHAPE
if (mask) {
XShapeCombineMask(dpy, scr->balloon->window, ShapeBounding, 0, 0, mask,
XShapeCombineMask(scr->display, window, ShapeBounding, 0, 0, mask,
ShapeSet);
}
#endif
@@ -147,15 +188,16 @@ findChildInWindow(Display *dpy, Window toplevel, int x, int y)
&& attr.map_state == IsViewable
&& x >= attr.x && y >= attr.y
&& x < attr.x + attr.width && y < attr.y + attr.height) {
Window child;
Window child, tmp;
child = findChildInWindow(dpy, children[i],
x - attr.x, y - attr.y);
tmp = children[i];
child = findChildInWindow(dpy, tmp, x - attr.x, y - attr.y);
XFree(children);
if (child == None)
return toplevel;
return tmp;
else
return child;
}
@@ -172,11 +214,12 @@ findViewInToplevel(Display *dpy, Window toplevel, int x, int y)
Window child;
child = findChildInWindow(dpy, toplevel, x, y);
if (child != None)
if (child != None) {
return W_GetViewForXWindow(dpy, child);
else
} else {
return NULL;
}
}
@@ -385,29 +428,26 @@ translateCoordinates(WMScreen *scr, Window target, int fromX, int fromY,
static void
updateDraggingInfo(WMScreen *scr, WMDraggingInfo *info,
updateDraggingInfo(WMScreen *scr, WMDraggingInfo *info, WMSize offset,
XEvent *event, Window iconWindow)
{
Window toplevel;
WMSize size;
size = WMGetPixmapSize(info->image);
if (event->type == MotionNotify) {
info->imageLocation.x = event->xmotion.x_root-(int)size.width/2;
info->imageLocation.y = event->xmotion.y_root-(int)size.height/2;
info->imageLocation.x = event->xmotion.x_root-offset.width;
info->imageLocation.y = event->xmotion.y_root-offset.height;
info->location.x = event->xmotion.x_root;
info->location.y = event->xmotion.y_root;
info->timestamp = event->xmotion.time;
/* info->timestamp = event->xmotion.time;*/
} else if (event->type == ButtonRelease) {
info->imageLocation.x = event->xbutton.x_root-(int)size.width/2;
info->imageLocation.y = event->xbutton.y_root-(int)size.height/2;
info->imageLocation.x = event->xbutton.x_root-offset.width;
info->imageLocation.y = event->xbutton.y_root-offset.height;
info->location.x = event->xbutton.x_root;
info->location.y = event->xbutton.y_root;
info->timestamp = event->xbutton.time;
/* info->timestamp = event->xbutton.time;*/
}
toplevel = findToplevelUnderDragPointer(scr,
@@ -500,6 +540,7 @@ selectionLost(WMView *view, Atom selection, void *cdata)
{
if (W_VIEW_SCREEN(view)->dragSourceView == view) {
wwarning("DND selection lost during drag operation...");
W_VIEW_SCREEN(view)->dragSourceView = NULL;
}
}
@@ -573,7 +614,6 @@ WMDragImageFromView(WMView *view, WMPixmap *image, char *dataTypes[],
Display *dpy = scr->display;
Window icon;
XEvent ev;
WMSize size;
WMRect rect = {{0,0},{0,0}};
int ostate = -1;
int state;
@@ -591,7 +631,8 @@ WMDragImageFromView(WMView *view, WMPixmap *image, char *dataTypes[],
};
wassertr(scr->dragSourceView == NULL);
if (scr->dragSourceView != NULL)
return;
wassertr(view->dragSourceProcs != NULL);
@@ -600,12 +641,9 @@ WMDragImageFromView(WMView *view, WMPixmap *image, char *dataTypes[],
if (image == NULL)
image = scr->defaultObjectIcon;
size = WMGetPixmapSize(image);
icon = makeDragIcon(scr, image);
XMoveWindow(dpy, icon, event->xmotion.x_root-(int)size.width/2,
event->xmotion.y_root-(int)size.height/2);
XMoveWindow(dpy, icon, atLocation.x, atLocation.y);
XMapRaised(dpy, icon);
@@ -621,8 +659,8 @@ WMDragImageFromView(WMView *view, WMPixmap *image, char *dataTypes[],
dragInfo.destinationWindow = dragInfo.sourceWindow;
dragInfo.location.x = event->xmotion.x_root;
dragInfo.location.y = event->xmotion.y_root;
dragInfo.location.x = atLocation.x + mouseOffset.width;
dragInfo.location.y = atLocation.y + mouseOffset.height;
dragInfo.imageLocation = atLocation;
@@ -665,7 +703,7 @@ WMDragImageFromView(WMView *view, WMPixmap *image, char *dataTypes[],
oldDragInfo = dragInfo;
updateDraggingInfo(scr, &dragInfo, &ev, icon);
updateDraggingInfo(scr, &dragInfo, mouseOffset, &ev, icon);
XMoveWindow(dpy, icon, dragInfo.imageLocation.x,
dragInfo.imageLocation.y);
@@ -720,11 +758,15 @@ WMDragImageFromView(WMView *view, WMPixmap *image, char *dataTypes[],
oldDragInfo = dragInfo;
updateDraggingInfo(scr, &dragInfo, &ev, icon);
updateDraggingInfo(scr, &dragInfo, mouseOffset, &ev, icon);
XMoveWindow(dpy, icon, dragInfo.imageLocation.x,
dragInfo.imageLocation.y);
if (state == 4 || state == 1) {
dragInfo.destinationWindow = None;
dragInfo.destView = NULL;
}
processMotion(scr, &dragInfo, &oldDragInfo, &rect, action);
dragInfo.timestamp = ev.xbutton.time;
@@ -1042,10 +1084,12 @@ W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event)
source = scr->dragInfo.sourceWindow;
oldView = scr->dragInfo.destView;
if (event->message_type == scr->xdndFinishedAtom) {
WMView *view = scr->dragSourceView;
WMDeleteSelectionHandler(view, scr->xdndSelectionAtom,
scr->dragInfo.timestamp);
if (view->dragSourceProcs->endedDragImage != NULL) {
view->dragSourceProcs->endedDragImage(view,
scr->dragInfo.image,
@@ -1055,14 +1099,10 @@ W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event)
scr->dragSourceView = NULL;
WMDeleteSelectionHandler(view, scr->xdndSelectionAtom,
scr->dragInfo.timestamp);
return;
}
if (event->message_type == scr->xdndEnterAtom) {
Window foo, bar;
@@ -1099,14 +1139,16 @@ W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event)
newView = findViewInToplevel(scr->display,
scr->dragInfo.destinationWindow,
x, y);
scr->dragInfo.destinationWindow,
x, y);
} else if (event->message_type == scr->xdndPositionAtom
&& scr->dragInfo.sourceWindow == event->data.l[0]) {
scr->dragInfo.location.x = event->data.l[2] >> 16;
scr->dragInfo.location.y = event->data.l[2] & 0xffff;
scr->dragInfo.imageLocation = scr->dragInfo.location;
if (scr->dragInfo.protocolVersion >= 1) {
scr->dragInfo.timestamp = event->data.l[3];
@@ -1135,8 +1177,9 @@ W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event)
&& scr->dragInfo.sourceWindow == event->data.l[0]) {
/* drop */
what = WDrop;
if (oldView != NULL)
what = WDrop;
} else {
return;
}
@@ -1148,7 +1191,7 @@ W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event)
if (what == WNothing) {
if (IS_DROPPABLE(newView)) {
if (oldView == NULL) { /* entered */
if (!IS_DROPPABLE(oldView)) { /* entered */
what = WEnter;
} else if (oldView == newView) { /* updated */
what = WUpdate;
@@ -1156,7 +1199,7 @@ W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event)
what = WCross;
}
} else {
if (oldView != NULL) {
if (IS_DROPPABLE(oldView)) {
what = WLeave;
} else {
/* just send rejection msg */