}
extern Widget engineOutputShell;
+int frameX, frameY;
void
GetActualPlacement (Widget wg, WindowPlacement *wp)
wp->y = ry - winAt.y;
wp->height = winAt.height;
wp->width = winAt.width;
+ frameX = winAt.x; frameY = winAt.y; // remember to decide if windows touch
}
void
/* end why */
XtAddEventHandler(formWidget, KeyPressMask, False,
(XtEventHandler) MoveTypeInProc, NULL);
+ XtAddEventHandler(shellWidget, StructureNotifyMask, False,
+ (XtEventHandler) EventProc, NULL);
/* [AS] Restore layout */
if( wpMoveHistory.visible ) {
}
}
+static WindowPlacement wpNew;
+
+void
+CoDrag (Widget sh, WindowPlacement *wp)
+{
+ Arg args[16];
+ int j=0, touch=0, fudge = 2;
+ GetActualPlacement(sh, wp);
+ if(abs(wpMain.x + wpMain.width + 2*frameX - wp->x) < fudge) touch = 1; else // right touch
+ if(abs(wp->x + wp->width + 2*frameX - wpMain.x) < fudge) touch = 2; else // left touch
+ if(abs(wpMain.y + wpMain.height + frameX + frameY - wp->y) < fudge) touch = 3; else // bottom touch
+ if(abs(wp->y + wp->height + frameX + frameY - wpMain.y) < fudge) touch = 4; // top touch
+ if(!touch ) return; // only windows that touch co-move
+ wp->x += wpNew.x - wpMain.x;
+ wp->y += wpNew.y - wpMain.y;
+ XtSetArg(args[j], XtNx, wp->x); j++;
+ XtSetArg(args[j], XtNy, wp->y); j++;
+ XtSetValues(sh, args, j);
+}
+
+void
+DragProc ()
+{
+ GetActualPlacement(shellWidget, &wpNew);
+ if(wpNew.x == wpMain.x && wpNew.y == wpMain.y) return; // not moved, false alarm
+ if(EngineOutputIsUp()) CoDrag(engineOutputShell, &wpEngineOutput);
+ if(MoveHistoryIsUp()) CoDrag(shells[7], &wpMoveHistory);
+ if(EvalGraphIsUp()) CoDrag(evalGraphShell, &wpEvalGraph);
+ if(GameListIsUp()) CoDrag(gameListShell, &wpGameList);
+ wpMain.x = wpNew.x; wpMain.y = wpNew.y;
+ XDrawPosition(boardWidget, True, NULL);
+}
+
+
+void
+DelayedDrag ()
+{
+ static XtIntervalId delayedDragID = 0;
+ if(delayedDragID) XtRemoveTimeOut(delayedDragID); // cancel pending
+ delayedDragID =
+ XtAppAddTimeOut(appContext, 50, (XtTimerCallbackProc) DragProc, (XtPointer) 0); // and schedule new one 50 msec later
+}
/* Why is this needed on some versions of X? */
void
{
if (!XtIsRealized(widget))
return;
-
switch (event->type) {
+ case ConfigureNotify: // main window is being dragged: drag attached windows with it
+ if(appData.useStickyWindows)
+ DelayedDrag(); // as long as events keep coming in faster than 50 msec, they destroy each other
+ break;
case Expose:
if (event->xexpose.count > 0) return; /* no clipping is done */
XDrawPosition(widget, True, NULL);
{ 0, 0, 0, NULL, (void*) &appData.showEvalInMoveHistory, "", NULL, CheckBox, N_("Scores in Move List") },
{ 0, 0, 0, NULL, (void*) &appData.showCoords, "", NULL, CheckBox, N_("Show Coordinates") },
{ 0, 0, 0, NULL, (void*) &appData.markers, "", NULL, CheckBox, N_("Show Target Squares") },
+{ 0, 0, 0, NULL, (void*) &appData.useStickyWindows, "", NULL, CheckBox, N_("Sticky Windows") },
{ 0, 0, 0, NULL, (void*) &appData.testLegality, "", NULL, CheckBox, N_("Test Legality") },
{ 0, 0, 10, NULL, (void*) &appData.flashCount, "", NULL, Spin, N_("Flash Moves (0 = no flashing):") },
{ 0, 1, 10, NULL, (void*) &appData.flashRate, "", NULL, Spin, N_("Flash Rate (high = fast):") },