From 4dc77c6e72e3ec99cd8a57c9442b7511c47d3dca Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Tue, 20 Mar 2012 15:30:00 +0100 Subject: [PATCH] Redo ErrorPopUp with generic dialog keeps popping down error popup.Multiple Error popups remeain tricky; add comment to describe problem with multiple ErrorPopUps. --- dialogs.c | 50 +++++++++++++++++++++++++++++++- dialogs.h | 2 + xboard.c | 95 ++---------------------------------------------------------- 3 files changed, 55 insertions(+), 92 deletions(-) diff --git a/dialogs.c b/dialogs.c index 4511e83..a2af38b 100644 --- a/dialogs.c +++ b/dialogs.c @@ -1471,7 +1471,55 @@ OutputChatMessage (int partner, char *mess) return; // dummy } -//----------------------------- Various display boxes ----------------------------- +//----------------------------- Error popup in various uses ----------------------------- + +/* + * [HGM] Note: + * XBoard has always had some pathologic behavior with multiple simultaneous error popups, + * (which can occur even for modal popups when asynchrounous events, e.g. caused by engine, request a popup), + * and this new implementation reproduces that as well: + * Only the shell of the last instance is remembered in shells[ErrorDlg] (which replaces errorShell), + * so that PopDowns ordered from the code always refer to that instance, and once that is down, + * have no clue as to how to reach the others. For the Delete Window button calling PopDown this + * has now been repaired, as the action routine assigned to it gets the shell passed as argument. + */ + +int errorUp = False; + +void +ErrorPopDown () +{ + if (!errorUp) return; + dialogError = errorUp = False; + PopDown(ErrorDlg); PopDown(FatalDlg); // on explicit request we pop down any error dialog + if (errorExitStatus != -1) ExitEvent(errorExitStatus); +} + +static int +ErrorOK (int n) +{ + dialogError = errorUp = False; + PopDown(n == 1 ? FatalDlg : ErrorDlg); // kludge: non-modal dialogs have one less (dummy) option + if (errorExitStatus != -1) ExitEvent(errorExitStatus); + return FALSE; // prevent second Popdown ! +} + +static Option errorOptions[] = { +{ 0, 0, 0, NULL, NULL, NULL, NULL, Label, NULL }, // dummy option: will never be displayed +{ 0, 0, 0, NULL, NULL, NULL, NULL, Label, NULL }, // textValue field will be set before popup +{ 0,NO_CANCEL,0, NULL, (void*) &ErrorOK, "", NULL, EndMark , "" } +}; + +void +ErrorPopUp (char *title, char *label, int modal) +{ + errorUp = True; + errorOptions[1].name = label; + if(dialogError = shellUp[TransientDlg]) + GenericPopUp(errorOptions+1, title, FatalDlg, TransientDlg, MODAL); // pop up as daughter of the transient dialog + else + GenericPopUp(errorOptions+modal, title, modal ? FatalDlg: ErrorDlg, BoardWindow, modal); // kludge: option start address indicates modality +} void DisplayError (String message, int error) diff --git a/dialogs.h b/dialogs.h index 810bf7d..74bc021 100644 --- a/dialogs.h +++ b/dialogs.h @@ -84,7 +84,9 @@ typedef enum { // identifier of dialogs done by GenericPopup TransientDlg=0, // transient: grabs mouse events and is destroyed at pop-down (so other dialog can use this ID next time) CommentDlg, TagsDlg, TextMenuDlg, InputBoxDlg, NoDlg, BrowserDlg, HistoryDlg, // persistent: no grab and reused PromoDlg, // this and beyond are destroyed at pop-down +ErrorDlg, AskDlg, // this and beyond do grab mouse events (and are destroyed) +FatalDlg, BoardWindow, NrOfDialogs // dummy for total } DialogClass; diff --git a/xboard.c b/xboard.c index 080caa8..81477c5 100644 --- a/xboard.c +++ b/xboard.c @@ -342,7 +342,7 @@ int smallLayout = 0, tinyLayout = 0, fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False, ICSInputBoxUp = False, filenameUp = False, pmFromX = -1, pmFromY = -1, - errorUp = False, errorExitStatus = -1, defaultLineGap; + errorExitStatus = -1, defaultLineGap; Dimension textHeight; Pixel timerForegroundPixel, timerBackgroundPixel; Pixel buttonForegroundPixel, buttonBackgroundPixel; @@ -522,12 +522,12 @@ XtActionsRec boardActions[] = { { "TempBackwardProc", TempBackwardProc }, { "TempForwardProc", TempForwardProc }, { "CommentClick", (XtActionProc) CommentClick }, - { "ErrorPopDown", (XtActionProc) ErrorPopDown }, { "GameListPopDown", (XtActionProc) GameListPopDown }, { "GameListOptionsPopDown", (XtActionProc) GameListOptionsPopDown }, { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown }, { "EvalGraphPopDown", (XtActionProc) EvalGraphPopDown }, { "GenericPopDown", (XtActionProc) GenericPopDown }, + { "ErrorPopDown", (XtActionProc) ErrorPopDown }, { "CopyMemoProc", (XtActionProc) CopyMemoProc }, { "SelectMove", (XtActionProc) SelectMove }, { "LoadSelectedProc", LoadSelectedProc }, @@ -645,7 +645,7 @@ char ICSInputTranslations[] = char commentTranslations[] = ": extend-end() select-start() CommentClick() \n"; String xboardResources[] = { - "*errorpopup*translations: #override\\n Return: ErrorPopDown()", + "*Error*translations: #override\\n Return: ErrorPopDown()", NULL }; @@ -3026,7 +3026,7 @@ PieceMenuPopup (Widget w, XEvent *event, String *params, Cardinal *num_params) case 0: whichMenu = params[0]; break; case 1: SetupDropMenu(); whichMenu = "menuD"; break; case 2: - case -1: if (errorUp) ErrorPopDown(); + case -1: ErrorPopDown(); default: return; } XtPopupSpringLoaded(XtNameToWidget(boardWidget, whichMenu)); @@ -3594,93 +3594,6 @@ FileNamePopUp (char *label, char *def, char *filter, FileProc proc, char *openMo } -void -ErrorCallback (Widget w, XtPointer client_data, XtPointer call_data) -{ - dialogError = errorUp = False; - XtPopdown(w = XtParent(XtParent(XtParent(w)))); - XtDestroyWidget(w); - if (errorExitStatus != -1) ExitEvent(errorExitStatus); -} - - -void -ErrorPopDown () -{ - if (!errorUp) return; - dialogError = errorUp = False; - XtPopdown(errorShell); - XtDestroyWidget(errorShell); - if (errorExitStatus != -1) ExitEvent(errorExitStatus); -} - -void -ErrorPopUp (char *title, char *label, int modal) -{ - Arg args[16]; - Widget dialog, layout; - Position x, y; - int xx, yy; - Window junk; - Dimension bw_width, pw_width; - Dimension pw_height; - int i; - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; - XtSetArg(args[i], XtNtitle, title); i++; - errorShell = - XtCreatePopupShell("errorpopup", transientShellWidgetClass, - shellUp[TransientDlg] ? (dialogError = modal = TRUE, shells[TransientDlg]) : shellWidget, args, i); - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, errorShell, - layoutArgs, XtNumber(layoutArgs)); - - i = 0; - XtSetArg(args[i], XtNlabel, label); i++; - XtSetArg(args[i], XtNborderWidth, 0); i++; - dialog = XtCreateManagedWidget("dialog", dialogWidgetClass, - layout, args, i); - - XawDialogAddButton(dialog, _("ok"), ErrorCallback, (XtPointer) dialog); - - XtRealizeWidget(errorShell); - CatchDeleteWindow(errorShell, "ErrorPopDown"); - - i = 0; - XtSetArg(args[i], XtNwidth, &bw_width); i++; - XtGetValues(boardWidget, args, i); - i = 0; - XtSetArg(args[i], XtNwidth, &pw_width); i++; - XtSetArg(args[i], XtNheight, &pw_height); i++; - XtGetValues(errorShell, args, i); - -#ifdef NOTDEF - /* This code seems to tickle an X bug if it is executed too soon - after xboard starts up. The coordinates get transformed as if - the main window was positioned at (0, 0). - */ - XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2, - 0 - pw_height + squareSize / 3, &x, &y); -#else - XTranslateCoordinates(xDisplay, XtWindow(boardWidget), - RootWindowOfScreen(XtScreen(boardWidget)), - (bw_width - pw_width) / 2, - 0 - pw_height + squareSize / 3, &xx, &yy, &junk); - x = xx; - y = yy; -#endif - if (y < 0) y = 0; /*avoid positioning top offscreen*/ - - i = 0; - XtSetArg(args[i], XtNx, x); i++; - XtSetArg(args[i], XtNy, y); i++; - XtSetValues(errorShell, args, i); - - errorUp = True; - XtPopup(errorShell, modal ? XtGrabExclusive : XtGrabNone); -} - /* Disable all user input other than deleting the window */ static int frozen = 0; -- 1.7.0.4