Skip to content

Old(ish) regression in widgets #1906

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jtappin opened this issue Nov 7, 2024 · 12 comments
Closed

Old(ish) regression in widgets #1906

jtappin opened this issue Nov 7, 2024 · 12 comments

Comments

@jtappin
Copy link

jtappin commented Nov 7, 2024

Somewhere between bc3197a (about 2 Sep) and 6c1d6bc (about 19 Sep), there seems to have been a change in the handling of widget events and the event_func seems to be ignored.

Essentially in graffer in order to allow pop-up menus to work modularly even though the main event loop is non-blocking, I use a home-brew event loop for these, e.g.:

  widget_control, base, event_func = 'grf_tlz_event', set_uvalue = $
                  uvs, /no_copy

  repeat begin
     ev = widget_event(base)
  endrep until ev.exited ne 0

and the final part of the handler routine is:

  return, {id:event.handler, $
           top:event.top, $
           handler:0l, $
           exited:iexit}

I only noticed this today when I got errors about the structure not having an EXITED tag. A little further investigation shows that the call to widget_event is returning the original widget events and is not calling the handler routine.

I need to dig a little deeper to check exactly what conditions trigger the problem. Clearly event_pro settings in groups that are handled within xmanager are not affected (otherwise I'd never have reached the pop-ups in the first place).

P.S. Sorry about the initial blank post

@GillesDuvert
Copy link
Contributor

Certainly #1882
Will have to digest this one.

@jtappin
Copy link
Author

jtappin commented Nov 14, 2024

I've now managed to generate a "distilled" code that illustrates the problem.
handlers.pro

In IDL, clicking on the "Continue" button in the sub-menu gives:

SUB_EVENT
** Structure WIDGET_BUTTON, 4 tags, length=16, data length=16:
   ID              LONG                 8
   TOP             LONG                 7
   HANDLER         LONG                 7
   SELECT          LONG                 1
SUB_MENU
** Structure <38d7b08>, 4 tags, length=16, data length=13, refs=1:
   ID              LONG                 7
   TOP             LONG                 7
   HANDLER         LONG                 0
   EXIT            BYTE         0

whereas in GDL I only see:

 SUB_MENU
** Structure WIDGET_BUTTON, 4 tags,memsize =16, data length=16/16:
   ID              LONG                54
   TOP             LONG                53
   HANDLER         LONG                 0
   SELECT          LONG                 1

Similarly, clicking on "Exit" in IDL gives:

SUB_EVENT
** Structure WIDGET_BUTTON, 4 tags, length=16, data length=16:
   ID              LONG                 9
   TOP             LONG                 7
   HANDLER         LONG                 7
   SELECT          LONG                 1
SUB_MENU
** Structure <38b6dd8>, 4 tags, length=16, data length=13, refs=1:
   ID              LONG                 7
   TOP             LONG                 7
   HANDLER         LONG                 0
   EXIT            BYTE         1
Done
IDL> 

and the sub menu is destroyed. Whereas in GDL, only:

SUB_MENU
** Structure WIDGET_BUTTON, 4 tags,memsize =16, data length=16/16:
   ID              LONG                55
   TOP             LONG                53
   HANDLER         LONG                 0
   SELECT          LONG                 1

is displayed and the sub-menu is not destroyed.

It appears to me that GDL's implementation of widget_event misses out (at least) clause 4 from the description of the behaviour of widget_event in the IDL documentation.

It does look as though it is possible to achieve the desired behaviour using xmanager (I'm guessing that either handling a mixture of blocking and non-blocking widgets didn't work in the early days (ca. 1995-7) or else the documentation was even less clear than it now is.)

@GillesDuvert
Copy link
Contributor

Rats! I've spent days checking the conformance to this accursed documentation when doing #1882. Will have to review that again!
Thanks for handler.pro

@jtappin
Copy link
Author

jtappin commented Nov 16, 2024

Possibly more serious is that it seems to break some compound widgets (cw_bgroup), I only spotted that last night while trying to update the handling in graffer and found that a radio button menu failed.

Will update once I've checked properly.

@jtappin
Copy link
Author

jtappin commented Nov 16, 2024

Possibly more serious is that it seems to break some compound widgets (cw_bgroup), I only spotted that last night while trying to update the handling in graffer and found that a radio button menu failed.

Will update once I've checked properly.

OK. Problem resolved (patch attached).
cw_bgroup.pro.diff

Radio button menus were only returning the release event. It turns out that this was a result of GDL returning the press event before the release event, (whereas IDL returns release then press) so to be able to get a reasonable behaviour for user event handlers I put in a line that threw away the second event received. Now GDL is returning the events in the sensible order, so the throwaway line can now be removed.

@GillesDuvert
Copy link
Contributor

@jtappin : Dear, I'm confused.

  1. do you mean that by changing the two lines of cw_bgroup.pro the " regression in widgets " disappears?
  2. handlers.pro generates an error in IDL and GDL:
% SUB_MENU: Ambiguous: Variable is undefined: HAS_TAG or: Function not found: HAS_TAG
% Execution halted at: SUB_MENU            29 /home/gildas/handlers.pro

@jtappin
Copy link
Author

jtappin commented Nov 28, 2024

@jtappin : Dear, I'm confused.

1. do you mean that by changing the two lines of cw_bgroup.pro the " regression in widgets " disappears?

2. handlers.pro generates an error in IDL and GDL:
% SUB_MENU: Ambiguous: Variable is undefined: HAS_TAG or: Function not found: HAS_TAG
% Execution halted at: SUB_MENU            29 /home/gildas/handlers.pro
  1. No, only that there is a possibly-related issue that the regression may have caused to disappear, namely that for EXCLUSIVE menus, in GDL the press (SELECT=1) event came first, whereas in IDL the release event from the previously-selected button came first so I had a workaround so that the release event was thrown away. Once we get to the bottom of this we may or may not need to update cw_bgroup. I suggest we lay this aside for the time being.

  2. Sorry, that's one of many routines that are in fact in various IDL tools that are in my !PATH :

function has_tag, str, tag

  t = size(str, /type)
  if t ne 8 then return, 0b

  list = tag_names(str)
  locs = where(list eq strupcase(tag), nm)
  return, nm ne 0
end

I've been digging a little deeper, in particular trying to see if it is possible to do graffer's event handling in a different way, without success. (I think it could be done if IDL pointers were real pointers as in C & Fortran, but as it is there are numerous lifecycle related issues.)

I do also see that when widget_event is used explicitly, internal event-handling in compound widgets is also broken.

@GillesDuvert
Copy link
Contributor

The point is to get GDL behave exactly as IDL in this tricky case of event handling, avoiding workarounds...

@GillesDuvert
Copy link
Contributor

@jtappin I realize that the NO_RELEASE option of WIDGET_BUTTON has never been programmed. (should be easy)
This means that a number of compound widgets (not mentioning a few other IDL procedures like ascii_template) will not work ok.

@GillesDuvert
Copy link
Contributor

Actually, NO_RELASE concerns only radiobuttons that are a special class of wxwidgets buttons, and the event is triggered by whatever wxwidgets thinks there is a new radiobutton selection. So the NO_RELEASE option is not necessary and it was not programmed.
But I see, using the procedure:
gdl/testsuite/interactive_tests/test_widgets
called as test_widgets,/col,present="BUTTON"
that with IDL, pressing a cw_bgroup exclusive button creates 2 "press" events, not one.
which is not the case with GDL. The first "press" event is a deselection of the previous button, the next is a selection of the new button.
This difference of behaviour can explain a lot.

@GillesDuvert
Copy link
Contributor

gotcha.

GillesDuvert added a commit that referenced this issue Nov 30, 2024
OK apart the usual OSX 15 ones
@GillesDuvert
Copy link
Contributor

closed with #1931

@GillesDuvert GillesDuvert reopened this Nov 30, 2024
GillesDuvert added a commit that referenced this issue Dec 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants