Dialog events fire when other code is running

Started by honkinberry, June 24, 2019, 02:28:31 PM

Previous topic - Next topic

honkinberry

Every day we get a number of errors from users, that appears to be due to a dialog event firing when other code is running.
The best example, is one dialog queries for additional cloud content, and so internet issues can cause it to take several seconds to complete.  So a hasty user clicks on buttons, which then fire additional events, yet variables are in between states, and errors result.

Here's an example from today:

[0.226] (VL-BT)
[1.222] (AXIS_ERR "bad argument type: fixnump: nil")
[2.217] (_call-err-hook # "bad argument type: fixnump: nil")
[3.211] (sys-error "bad argument type: fixnump: nil")
:ERROR-BREAK.206 nil
[4.203] (ITOA nil)
[5.198] (SAVEPREFS)
[6.194] (C:DCLACCEPTCLICKED)
[7.190] (#)
:CALLBACK-ENTRY.187 (:CALLBACK-ENTRY)
[8.184] (#)
[9.181] (_lisplet-apply # # nil :CALLBACK-ENTRY)
[10.173] (_lisplet-callback-apply # "C:DCLACCEPTCLICKED" nil)
[11.166] (#)
[12.163] (ARQ-SUBR! 3022)
:ARQ-SUBR-CALLBACK.158 (nil 3022)
[13.155] (STRCASE "21` OaCv")
[14.150] (FX:PLANTSIZESORTVAL "21` OaCv")
[15.145] (# "21` OaCv" "18` ht x 10` spd")
[16.140] (VL-SORT ("16` Ht., CT" "-" "2-3` ht." "2-4` ct." "3` Height, matching" "4`-5` overall ht." "5-6` ht. x 3-4` spd." "5` ht. x 4` spr." "5` ht. x 5` spr." "5` o.a.h." "5`-6` Ht, x 2`-3` spd." "5`-6` ht. x 3` spd." "6-15` x 4` spd" "6-8` height, 4` Spread" "6` CT - Central leader, full & matched" "6` Clear Trunk" "6` c.t." "6` ht x 6` spd" "6` ht. x 2` spd." "6` ht. x 6` spd." "6`-10` CT. Stagger Hts." "6`-8` ht. x 3`-4` spd."


In that example, the dialog box initialization is firing, which involves loading a good amount of data and preparing it.
You can see it is right in the middle of sorting a very long list, when suddenly a dialog AcceptClicked fires, and global variables it relies on have not been set yet upon completion of the Initialization.

So how, can a dialog event, interrupt already executing code?!  Doesn't it have to go to the back of the stack and wait?

I hope that's clear, happy to help explain more.  If anyone has any tips it'd be much appreciated!

--J

roy_043

IMO you should perform these lengthy operations before initialization and thereby avoid the problem altogether.

owenwengerd

Dialog events are just windows messages, and those continue to get processed (at certain points) even while lisp is running. In a case like you describe, I would disable the dialog until the operation completes.

honkinberry

Some further information, it appears some of the cases are from users mistakenly double-clicking, or hastily re-clicking, buttons.
So in which case, it seems the simplest solution, is for any of these instances, to add something like this:


; global
(setq _ODCLEVENT nil)

; button handler
(defun c:dclButtonClicked ()
    (if (not _ODCLEVENT)
        (if (and (setq _ODCLEVENT t)
                (GoEventHandler)
            ) ; and
            (setq _ODCLEVENT nil)
        ) ; if
    ) ; if
) ; ButtonClicked


Simple and effective, yes?

--J