Project

General

Profile

Bug #2734

Bug #2677: fix drawing and functional differences between P2J GUI and 4GL GUI

button/gui_btn_test4.p abend after pause

Added by Greg Shah over 8 years ago. Updated over 7 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Start date:
Due date:
% Done:

100%

billable:
No
vendor_id:
GCD
case_num:

History

#1 Updated by Greg Shah over 8 years ago

  • Target version set to Milestone 12

This is the abend (to see it one must have the logging added to the Dispatcher.processInbound() as described in #2700):

Caused by: java.lang.IllegalStateException: Can not change window to 1 if batch is already started!
        at com.goldencode.p2j.ui.client.gui.driver.AbstractGuiDriver.selectWindow(AbstractGuiDriver.java:1515)
        at com.goldencode.p2j.ui.client.gui.driver.AbstractGuiDriver.enableEvents(AbstractGuiDriver.java:1841)
        at com.goldencode.p2j.ui.client.gui.driver.GuiOutputManager.enableOSEvents(GuiOutputManager.java:257)
        at com.goldencode.p2j.ui.chui.ThinClient.getChanges(ThinClient.java:11821)
        at com.goldencode.p2j.net.Protocol.attachChanges(Protocol.java:274)
        at com.goldencode.p2j.net.Queue.enqueueOutbound(Queue.java:810)
        at com.goldencode.p2j.net.Queue.transactImpl(Queue.java:1109)
        at com.goldencode.p2j.net.Queue.transact(Queue.java:585)
        at com.goldencode.p2j.net.BaseSession.transact(BaseSession.java:223)
        at com.goldencode.p2j.net.HighLevelObject.transact(HighLevelObject.java:163)
        at com.goldencode.p2j.net.RemoteObject$RemoteAccess.invokeCore(RemoteObject.java:1425)
        at com.goldencode.p2j.net.InvocationStub.invoke(InvocationStub.java:97)
        ... 71 more

To recreate it, just run the program and press space at the pause. This can be created on 1811q revision 11036.

#2 Updated by Greg Shah over 8 years ago

The logging is now checked into the trunk at revision 10940. The latest run of the program abends with this:

Caused by: java.lang.IllegalStateException: Can not change window to 1 if batch is already started!
        at com.goldencode.p2j.ui.client.gui.driver.AbstractGuiDriver.selectWindow(AbstractGuiDriver.java:1514)
        at com.goldencode.p2j.ui.client.gui.driver.AbstractGuiDriver.enableEvents(AbstractGuiDriver.java:1840)
        at com.goldencode.p2j.ui.client.gui.driver.GuiOutputManager.enableOSEvents(GuiOutputManager.java:257)
        at com.goldencode.p2j.ui.chui.ThinClient.getChanges(ThinClient.java:11882)
        at com.goldencode.p2j.net.Protocol.attachChanges(Protocol.java:274)
        at com.goldencode.p2j.net.Queue.enqueueOutbound(Queue.java:810)
        at com.goldencode.p2j.net.Queue.transactImpl(Queue.java:1109)
        at com.goldencode.p2j.net.Queue.transact(Queue.java:585)
        at com.goldencode.p2j.net.BaseSession.transact(BaseSession.java:223)
        at com.goldencode.p2j.net.HighLevelObject.transact(HighLevelObject.java:163)
        at com.goldencode.p2j.net.RemoteObject$RemoteAccess.invokeCore(RemoteObject.java:1425)
        at com.goldencode.p2j.net.InvocationStub.invoke(InvocationStub.java:97)
        ... 71 more

#3 Updated by Greg Shah over 8 years ago

Here is where we generate the exception (AbstractGuiImpl line 1508):

   public void selectWindow(int windowId)
   {
      if (ews == null || ews.getWindowId() != windowId)
      {
         if (ews != null && batch.peek())
         {
            throw new IllegalStateException(
               "Can not change window to " + windowId + " if batch is already started!");
         }

         direct.selectWindow(windowId);

         ews = direct.getWindowEmulator();
      }
   }   

This code is written such that window selection cannot be done while inside a batch. This concept seems sensible since all drawing ops should relate to the same window.

The problem occurs due to this code (AbstractGuiDriver line 1839, inside enableEvents()):

      // TODO: do we really need to select each window or can we just use
      //       direct.getWindowEmulator() to get each one?  
      for (int wid : windowIds)
      {
         selectWindow(wid);

         ews.enableEvents(capture);
      }

This code can never be used inside a batch. Is it time to address the TODO as a solution? If so, we also need to highlight this batch limitation in some comments so that people don't re-introduce this later.

In our case, the code is being invoked at the end of ThinClient.getChanges(), which seems to be a valid use case:

      // TODO: Disabling OS events here disables all user input on the client (while
      //       the control is on the server). This is in contrast with the original 4GL/Windows
      //       behavior where some input is processed. For example client window can be moved
      //       while the 4GL app doesn't process any user input instructions. 
      tk.enableOSEvents(WindowManager.windowIds(), false);

I guess the other question is whether it is valid to have batch still be active while returning control to the server?

#4 Updated by Constantin Asofiei over 8 years ago

Greg Shah wrote:

I guess the other question is whether it is valid to have batch still be active while returning control to the server?

Batch should never remain open after drawing is completed. I think the exception you've seen is a side effect of something else.

#5 Updated by Constantin Asofiei over 8 years ago

The P2J code fails during this invocation during drawing, as it interrogates the server-side to determine the UI theme - to me it was looking suspicious that ThinClient.getChanges gets called during drawing, but this is a valid case.

   public String getUiTheme()
   {                                                                   
      // first call, request server for current theme to use
      if (theme == null)
      {
         Directory dir = DirectoryManager.getInstance();

         theme = dir.getString(Directory.ID_RELATIVE, "windows-os-ui-theme", "classic")
                    .toLowerCase();
      }

      return theme;
   }

So, the real problem is in AbstractGuiDriver.enableEvents() - changing the loop to this (addressing the TODO) solves the abend:

      for (int wid : windowIds)
      {
         direct.getWindowEmulator(wid).enableEvents(capture);
      }

#6 Updated by Greg Shah over 8 years ago

Thank you. I'll include that change and some related comments in my next check-in.

#7 Updated by Greg Shah over 8 years ago

  • Status changed from New to Closed

Task branch 1811r revision 10942 has the fix for this issue.

#8 Updated by Greg Shah over 8 years ago

  • % Done changed from 0 to 100
  • Assignee set to Greg Shah

#9 Updated by Greg Shah over 7 years ago

  • Target version changed from Milestone 12 to GUI Support for a Complex ADM2 App

Also available in: Atom PDF