Submitted by Anonymous (not verified) on Fri, 06/15/2012 - 12:07
I am having a problem with DND and timeouts on Linux (Red Hat Enterprise 3).
I am trying to drag and drop between two motif applications that use timers.
When a drag occurs the timer in the dropsite (registered using XtAppAddTimeOut())
often stops being called. The drop site is registered using XmDropSiteRegister().
I've cut this down to two very small test applications ("from" and "to") in which the
problem still occurs. To make things simple, the drop site just fails the
drop, which means the drag context doesn't need and convert procedure. The
TimeOut just prints the letter "A" and calls itself. I've searched through this
forum and the comp.windows.x.motif newsgroup and most of the queries on
XtAppAddTimeOut() come down to problems with XtRemoveTimeOut() being
called multiple times. However, my test application doesn't call XtRemoveTimeOut().
If I am dragging between two shells (or the same shell) in the same application
everything works fine. The problem only occurs when dragging between two different
applications.
I have compiled the same code on Irix and everything works fine.
Please find below my two test applications. Other than headers/includes, this is
basically the full code.
Any help would be appreciated...
from.c:
-------
static void
StartDrag(Widget canvas, XEvent *event, String *params, Cardinal *num_params)
{
Arg args[20];
Cardinal n;
Atom exportList[1];
Widget dc;
/* Removed convert and dragdropfinish callbacks */
exportList[0] = XA_STRING;
n = 0;
XtSetArg(args[n], XmNdragOperations, XmDROP_COPY); n++;
XtSetArg(args[n], XmNexportTargets, exportList); n++;
XtSetArg(args[n], XmNnumExportTargets, 0); n++;
dc = XmDragStart(canvas, event, args, n);
} /* End of 'StartGroupDrag()' */
int
main(int argc, char **argv)
{
Widget shell, area;
Widget button;
char transTable[] = {": Button1Input(down)"};
XtActionsRec actions[] = {{"Button1Input", StartDrag}};
XtTranslations translations;
shell = XtVaAppInitialize(&app_context, "Test",
NULL, 0,
&argc, argv,
NULL,
NULL);
area = XtVaCreateManagedWidget("From",
xmLabelWidgetClass,
shell,
NULL);
/* Translations for drag start */
XtAppAddActions(app_context, actions, XtNumber(actions));
translations = XtParseTranslationTable(transTable);
XtOverrideTranslations(area, translations);
XtRealizeWidget(shell);
XtPopup(shell, XtGrabNone);
XtAppMainLoop(app_context);
}
to:
---
static void
PanelDropProc(Widget canvas, XtPointer client_data, XtPointer app_data)
{
XmDropProcCallback cbs = (XmDropProcCallback) app_data;
Arg args[20];
/* Just fail the drop */
XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
XtSetArg(args[1], XmNnumDropTransfers, 0);
XmDropTransferStart(cbs->dragContext, args, 2);
}
static void
RegisterPanelDropSite(Widget w)
{
Arg args[20];
Cardinal n;
Atom importList[1];
Atom COMPOUND_TEXT;
COMPOUND_TEXT = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
importList[0] = COMPOUND_TEXT;
n = 0;
XtSetArg(args[n], XmNimportTargets, importList); n++;
XtSetArg(args[n], XmNnumImportTargets, 1); n++;
XtSetArg(args[n], XmNdropSiteOperations, XmDROP_COPY); n++;
XtSetArg(args[n], XmNdropProc, PanelDropProc); n++;
XmDropSiteRegister(w, args, n);
}
/* This timer *sometimes* stops being called after a drag. */
static void
Timer(XtPointer clientData, XtIntervalId id)
{
fprintf(stderr, "A");
XtAppAddTimeOut(app_context, 100, Timer, (XtPointer) NULL);
}
int
main(int argc, char **argv)
{
Widget area, shell;
shell = XtVaAppInitialize(&app_context, "Test",
NULL, 0,
&argc, argv,
NULL,
NULL);
area = XtVaCreateManagedWidget("To",
xmLabelWidgetClass,
shell,
NULL);
RegisterPanelDropSite(area);
XtAppAddTimeOut(app_context, 100, Timer, (XtPointer) NULL);
XtRealizeWidget(shell);
XtPopup(shell, XtGrabNone);
XtAppMainLoop(app_context);
}
‹ help on ada95 with motif XmTextField and wide characters. ›
Fri, 05/13/2005 - 11:16#1
Drag-n-drop is stopping timeouts
Some further thoughts on this...
I really hate to automatically assume that my code is perfect and there's a problem with the tried-and-tested system libraries and never normally jump to that conclusion. However, since my test apps are so simple and practically identical (but simplified) to the drag-n-drop examples in the Motif Programming Manual, in this case it seems the only conclusion that makes sense.
I'm sure the Xt timer stuff is okay, and think the problem must be in the drag-n-drop code. It aways happens after I call XmDropTransferStart() to fail the transfer. If I remove this call the timers are fine, but of course the drag-n-drop isn't completed. I think that somewhere within this XtRemoveTimeOut is called. My code then adds a new timeout which is given the id that has just been removed. Then the drag-n-drop code is calling XtRemoveTimeOut again and removing my timeout.
Does this sound possible? Like I said in the previous post, it only happens when the drag-n-drop is between applications, so it's probably not as obvious as this description, but I think it's in the right ballpark. Can anyone comment on this?
Cheers,
Giles
ps. please don't flame me for assuming that my code is okay and the libraries are at fault! Like I said, I don't normally do that, but in this case my test apps are so simple! But if it IS me and you can see a fault, I'd love to hear about it...