Bug #2772
Bug #2677: fix drawing and functional differences between P2J GUI and 4GL GUI
the ask-gui.p testcase doesn't show the message update dialog.
100%
History
#1 Updated by Sergey Ivanovskiy over 10 years ago
The JS web client doesn't display "Try another program?: yes/No" dialog and the browser console produces
17:43:56.911 Window ids must be non-positive integers.1 p2j.screen.js:1840:7 me.error() p2j.screen.js:1840 me.createWindow() p2j.screen.js:1524 me.createChildWindow() p2j.screen.js:1574 me.init/ws.onmessage() p2j.socket.js:440
#2 Updated by Greg Shah over 10 years ago
Please note that on the Java side this seems to be related to the use of Window.tinyInput(). I think this is the same cause of the problem in message-update6.p.
#3 Updated by Sergey Ivanovskiy over 10 years ago
Please note that on the Java side this seems to be related to the use of
Window.tinyInput(). I think this is the same cause of the problem inmessage-update6.p.
The JS client expects the child window id is a positive number. But the ModalWindow can have a unique id from the negative range of the signed integer type.
#4 Updated by Sergey Ivanovskiy over 10 years ago
- File MessageUpdate.png added
If we permit negative numbers for window ids, then the message update dialog appears and looks like in the attached screen with a broken layout.
Constantin, do you have any objections to accept negative window ids? It needs only to change
function isValidWindowId(wid)
{
return (typeof wid === 'number') /*&& (wid % 1 === 0) && wid > 0*/;
};
#5 Updated by Constantin Asofiei over 10 years ago
Sergey Ivanovskiy wrote:
If we permit negative numbers for window ids, then the message update dialog appears and looks like in the attached screen with a broken layout.
Constantin, do you have any objections to accept negative window ids? It needs only to change
[...]
I'm OK with the change. Also, update the javadoc for the function, too.
#6 Updated by Sergey Ivanovskiy over 10 years ago
Checked that the icon if it would be defined for ModalWindow
public ModalWindow(String title)
{
super(title);
id = WidgetId.nextID();
gd = (GuiDriver<?,?>) OutputManager.getDriver();
// the modal window is parented to the active top-level window, not the focus owner
setOwner(WindowManager.getActiveTopLevelWindow());
setLayout(new WindowLayout());
titleBar = new WindowTitleBar(WidgetId.nextID(),
true, // tested the icon coordinates
new CaptionButtonType[] {CaptionButtonType.CLOSE},
title);
...................
}
were located correctly within ModalWindow dialog, but the dialog title and its background displayed lower. The web log probably had correct coordinates to draw the title. Thus
WindowTitleBar of ModalWindow works properly for icon but not for the title.PaintPrimitives.CLIP 3; x = 0; y = 0; width = 17; height = 17 PaintPrimitives.DRAW_IMAGE x = 0; y = 0; width = 16; height = 16 PaintPrimitives.NO_CLIP 2 PaintPrimitives.TRANSLATE_POP 1; x = -2; y = -1 PaintPrimitives.TRANSLATE_PUSH 2; x = 19; y = 1 PaintPrimitives.CLIP 3; x = 0; y = 0; width = 95; height = 19 PaintPrimitives.SET_COLOR r = 10; g = 36; b = 106 PaintPrimitives.FILL_RECT x = 0; y = 0; width = 94; height = 17 PaintPrimitives.SET_COLOR r = 255; g = 255; b = 255 PaintPrimitives.SET_FONT PaintPrimitives.DRAW_STRING text = Message Update; x = 0; y = 18; centered = true
It is unclear for me what happens.
#7 Updated by Greg Shah over 10 years ago
Have you compared the JS logs to the Swing logs? Since Swing is working, you should be able to see which operation gets the wrong coordinates.
#8 Updated by Sergey Ivanovskiy over 10 years ago
Have you compared the JS logs to the Swing logs? Since Swing is working, you should be able to see which operation gets the wrong coordinates.
There is a definite issue with resize sequences in the web java log and the JS client log. They are different and for JS side there is interleaves. For example, this JS drawing circle don't match the web java log. It needs to investigate what happens.
START DRAWING CYCLE FOR WINDOW -44
PaintPrimitives.CLIP 1; x = 0; y = 0; width = 141; height = 48
PaintPrimitives.SET_COLOR r = 212; g = 208; b = 200
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 141; height = 48
PaintPrimitives.TRANSLATE_PUSH 1; x = 4; y = 4
PaintPrimitives.CLIP 2; x = 0; y = 0; width = 134; height = 20
PaintPrimitives.SET_COLOR r = 128; g = 128; b = 128
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 133; height = 18
PaintPrimitives.SET_ICON x = 0; y = 0; width = 16; height = 16
PaintPrimitives.TRANSLATE_PUSH 2; x = 2; y = 1
PaintPrimitives.CLIP 3; x = 0; y = 0; width = 17; height = 17
PaintPrimitives.DRAW_IMAGE x = 0; y = 0; width = 16; height = 16
PaintPrimitives.NO_CLIP 2
PaintPrimitives.TRANSLATE_POP 1; x = -2; y = -1
PaintPrimitives.SET_TITLE title = Message Update
PaintPrimitives.TRANSLATE_PUSH 2; x = 19; y = 1
PaintPrimitives.CLIP 3; x = 0; y = 0; width = 95; height = 19
PaintPrimitives.SET_COLOR r = 128; g = 128; b = 128
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 94; height = 17
PaintPrimitives.SET_COLOR r = 255; g = 255; b = 255
PaintPrimitives.SET_FONT
PaintPrimitives.DRAW_STRING text = Message Update; x = 0; y = 18; centered = true
PaintPrimitives.NO_CLIP 2
PaintPrimitives.TRANSLATE_POP 1; x = -19; y = -1
PaintPrimitives.TRANSLATE_PUSH 2; x = 115; y = 2
PaintPrimitives.CLIP 3; x = 0; y = 0; width = 17; height = 15
PaintPrimitives.SET_COLOR r = 212; g = 208; b = 200
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 16; height = 14
PaintPrimitives.SET_COLOR r = 255; g = 255; b = 255
PaintPrimitives.DRAW_LINE x1 = 0; y1 = 0; x2 = 0; y2 = 12
PaintPrimitives.DRAW_LINE x1 = 1; y1 = 0; x2 = 14; y2 = 0
PaintPrimitives.SET_COLOR r = 64; g = 64; b = 64
PaintPrimitives.DRAW_LINE x1 = 15; y1 = 0; x2 = 15; y2 = 13
PaintPrimitives.DRAW_LINE x1 = 0; y1 = 13; x2 = 15; y2 = 13
PaintPrimitives.SET_COLOR r = 128; g = 128; b = 128
PaintPrimitives.DRAW_LINE x1 = 14; y1 = 1; x2 = 14; y2 = 12
PaintPrimitives.DRAW_LINE x1 = 1; y1 = 12; x2 = 13; y2 = 12
PaintPrimitives.DRAW_IMAGE x = 0; y = 0; width = 16; height = 14
PaintPrimitives.NO_CLIP 2
PaintPrimitives.TRANSLATE_POP 1; x = -115; y = -2
PaintPrimitives.NO_CLIP 1
PaintPrimitives.TRANSLATE_POP 0; x = -4; y = -4
PaintPrimitives.TRANSLATE_PUSH 1; x = 4; y = 23
PaintPrimitives.CLIP 2; x = 0; y = 0; width = 133; height = 21
PaintPrimitives.SET_COLOR r = 212; g = 208; b = 200
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 133; height = 21
PaintPrimitives.RESIZE_WINDOW id = -44; width = 8; height = 27
PaintPrimitives.RESIZE_WINDOW id = -44; width = 141; height = 48
PaintPrimitives.NO_CLIP 1
PaintPrimitives.TRANSLATE_POP 0; x = -4; y = -23
PaintPrimitives.NO_CLIP 0
PaintPrimitives.SET_COLOR r = 212; g = 208; b = 200
PaintPrimitives.FILL_RECT x = 137; y = 0; width = 4; height = 48
PaintPrimitives.FILL_RECT x = 0; y = 44; width = 141; height = 4
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 4; height = 48
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 141; height = 4
PaintPrimitives.SET_COLOR r = 255; g = 255; b = 255
PaintPrimitives.DRAW_LINE x1 = 1; y1 = 1; x2 = 1; y2 = 45
PaintPrimitives.DRAW_LINE x1 = 2; y1 = 1; x2 = 138; y2 = 1
PaintPrimitives.SET_COLOR r = 128; g = 128; b = 128
PaintPrimitives.DRAW_LINE x1 = 1; y1 = 46; x2 = 139; y2 = 46
PaintPrimitives.DRAW_LINE x1 = 139; y1 = 1; x2 = 139; y2 = 46
PaintPrimitives.SET_COLOR r = 64; g = 64; b = 64
PaintPrimitives.DRAW_LINE x1 = 0; y1 = 47; x2 = 140; y2 = 47
PaintPrimitives.DRAW_LINE x1 = 140; y1 = 0; x2 = 140; y2 = 46
END DRAWING CYCLE FOR WINDOW -44
#9 Updated by Sergey Ivanovskiy over 10 years ago
Committed revision 11012 only changes to accept negative window ids and to log drawing circles.
Please, help to explain in general words the implementation of draw function of FrameWindowGuiImpl? There are contentPane.doLayout(); and doLayout(); invocations
/**
* Draw widget.
*/
@Override
public void draw()
{
contentPane.doLayout();
doLayout();
super.draw();
}
#10 Updated by Hynek Cihlar over 10 years ago
Sergey Ivanovskiy wrote:
Please, help to explain in general words the implementation of
drawfunction ofFrameWindowGuiImpl? There arecontentPane.doLayout();anddoLayout();invocations
doLayout() layouts the window itself - window title, etc. contentPane.doLayout() layouts the content.
#11 Updated by Sergey Ivanovskiy over 10 years ago
- File dialog_title.png added
I have some troubles, the JS client can't handle correctly resizes requests in the middle of the drawings. It leads to position previously drawings incorrectly. But all resizes requests are from WindowLayout in our case of ModalWindow (see usages of gd.resizeWindow) I blocked the JS resize for the particular unfitted values in order to produce this screen.
#12 Updated by Hynek Cihlar over 10 years ago
Sergey Ivanovskiy wrote:
I have some troubles, the JS client can't handle correctly resizes requests in the middle of the drawings. It leads to position previously drawings incorrectly. But all resizes requests are from
WindowLayoutin our case ofModalWindow(see usages ofgd.resizeWindow) I blocked the JS resize for the particular unfitted values in order to produce this screen.
How come the title is drawn? Do we have any logic that assumes window title is always visible?
#13 Updated by Sergey Ivanovskiy over 10 years ago
How come the title is drawn? Do we have any logic that assumes window title is always visible?
WindowTitleBar is responsible for drawing WindowTitle and it seems that there are no implementations of visibility logic by WindowTitle and WindowTitleBar.
#14 Updated by Hynek Cihlar over 10 years ago
Please ignore note 12.
#15 Updated by Sergey Ivanovskiy over 10 years ago
Please ignore note 12.
Debugging this method
public MessageReturnValue tinyInput(String text,
int row,
BaseDataType var,
String format,
boolean auto,
boolean set)
of
Window leads ModalWindow.doLayout and contentPane.doLayout(); are called several times from line 1569Frame frame = (Frame) screen.getRegistry().getComponent(id0);, from line 1598 of Window.java : frame.doLayout(); and third time from line 1621 of Window.java : tc.enable(id0, null, sb, true, wndId);. The last one invokes contentPane.doLayout(); and here it is set the old size for our modal window. It looks private void fillSpace(Container<O> container, Widget<O> innerPane) of BorderLayout calls WindowLayout but the caller class has no knowledge about the size is already calculated. Thus these invocations lead these resize events16:21:47.136 !!!! w = 8 h = 27 p2j.screen.js:591:10
16:21:47.139 !!!! w = 141 h = 48 p2j.screen.js:591:10
16:21:47.244 !!!! w = 8 h = 27 p2j.screen.js:591:10
16:21:47.248 !!!! w = 141 h = 48
on the JS side. It only explains an overview due to the complexity of the invoked code.
#16 Updated by Sergey Ivanovskiy over 10 years ago
If we call doLayout inside draw it leads to resize events are inside drawing circles!
#17 Updated by Constantin Asofiei over 10 years ago
Sergey Ivanovskiy wrote:
If we call
doLayoutinsidedrawit leads to resize events are inside drawing circles!
Are you referring to doLayout called from the BorderPanel.draw code?
#18 Updated by Sergey Ivanovskiy over 10 years ago
If we call
doLayoutinsidedrawit leads to resize events are inside drawing circles!Are you referring to
doLayoutcalled from theBorderPanel.drawcode?
Yes, draw method of FrameWindowGuiImpl #note-9 invokes doLayout of BorderedPanel<GuiOutputManager> contentPane, and the resize events are inside the drawing circle due to BorderedPanel.doLayout returns different size for ModalWindow that contains it.
#19 Updated by Constantin Asofiei over 10 years ago
Sergey Ivanovskiy wrote:
If we call
doLayoutinsidedrawit leads to resize events are inside drawing circles!Are you referring to
doLayoutcalled from theBorderPanel.drawcode?Yes,
drawmethod ofFrameWindowGuiImpl#note-9 invokesdoLayoutofBorderedPanel<GuiOutputManager> contentPane, and the resize events are inside the drawing circle due toBorderedPanel.doLayoutreturns different size forModalWindowthat contains it.
OK, I don't think this is correct. At the time draw is called, all PaintEvent's are posted with the widget's coordinates/dimensions as at the time of the repaint. So, all clipping rectangles will be forced to draw using that dimensions... and calling doLayout() again in draw() might modify the widget's dimension/location, which in turn will no longer match its associated PaintEvent (and bitmap rectangles added to the ScreenBitmap).
Hynek, do you think is OK to move the doLayout() calls from FrameWindowGuiImpl.draw() to its show() method? Also, shouldn't the layout code from BorderedPanel.draw() be in its own doLayout() method?
#20 Updated by Hynek Cihlar over 10 years ago
Constantin Asofiei wrote:
Sergey Ivanovskiy wrote:
If we call
doLayoutinsidedrawit leads to resize events are inside drawing circles!Are you referring to
doLayoutcalled from theBorderPanel.drawcode?Yes,
drawmethod ofFrameWindowGuiImpl#note-9 invokesdoLayoutofBorderedPanel<GuiOutputManager> contentPane, and the resize events are inside the drawing circle due toBorderedPanel.doLayoutreturns different size forModalWindowthat contains it.OK, I don't think this is correct. At the time
drawis called, allPaintEvent's are posted with the widget's coordinates/dimensions as at the time of the repaint. So, all clipping rectangles will be forced to draw using that dimensions... and callingdoLayout()again indraw()might modify the widget's dimension/location, which in turn will no longer match its associatedPaintEvent(and bitmap rectangles added to theScreenBitmap).Hynek, do you think is OK to move the
doLayout()calls fromFrameWindowGuiImpl.draw()to itsshow()method?
I think I put doLayout() into draw() to cover the window resize case. But since, window resize events moved from Window to TopLevelWindow (and cover FrameWindowGuiImpl), so it shoud be ok to move to show().
Also, shouldn't the layout code from
BorderedPanel.draw()be in its owndoLayout()method?
Probably should. I never investigated this code in more detail. Also some caution should be taken, this is common to both ChUI and GUI
#21 Updated by Constantin Asofiei over 10 years ago
Hynek Cihlar wrote:
Hynek, do you think is OK to move the
doLayout()calls fromFrameWindowGuiImpl.draw()to itsshow()method?I think I put
doLayout()intodraw()to cover the window resize case. But since window resize events moved fromWindowtoTopLevelWindow(and coverFrameWindowGuiImpl), so it shoud be ok to move toshow().Also, shouldn't the layout code from
BorderedPanel.draw()be in its owndoLayout()method?Probably should. I never investigated this code in more detail. Also some caution should be taken, this is common to both ChUI and GUI
Sergey, please test the FrameWindowGuiImpl change as described above and leave the BorderedPanel.draw() as is for now (BorderedPanel change has a more chance at regressions, so if it works with changing only FrameWindowGuiImpl, we will check BorderedPanel after 1811s).
#22 Updated by Hynek Cihlar over 10 years ago
Constantin Asofiei wrote:
Hynek Cihlar wrote:
Hynek, do you think is OK to move the
doLayout()calls fromFrameWindowGuiImpl.draw()to itsshow()method?I think I put
doLayout()intodraw()to cover the window resize case. But since window resize events moved fromWindowtoTopLevelWindow(and coverFrameWindowGuiImpl), so it shoud be ok to move toshow().Also, shouldn't the layout code from
BorderedPanel.draw()be in its owndoLayout()method?Probably should. I never investigated this code in more detail. Also some caution should be taken, this is common to both ChUI and GUI
Sergey, please test the
FrameWindowGuiImplchange as described above
Create a simple frame in DIALOG-BOX and then change its size through WIDTH/HEIGHT attributes.
#23 Updated by Sergey Ivanovskiy over 10 years ago
It doesn't help because of this stack trace
BorderLayout<O>.fillSpace(Container<O>, Widget<O>) line: 135 BorderLayout<O>.doLayout(Container<O>) line: 93 BorderedPanelGuiImpl(BorderedPanel<O>).draw() line: 136 BorderedPanelGuiImpl.access$501(BorderedPanelGuiImpl) line: 37 BorderedPanelGuiImpl$1$1.run() line: 200 GuiWebDriver(AbstractGuiDriver<F>).draw(NativePoint, NativeRectangle, Runnable) line: 1923 BorderedPanelGuiImpl$1.run() line: 189 GuiWebDriver(AbstractGuiDriver<F>).draw(NativePoint, NativeRectangle, Runnable) line: 1923 BorderedPanelGuiImpl.draw() line: 136 BorderedPanelGuiImpl(AbstractContainer<O>).draw() line: 326 BorderedPanelGuiImpl(BorderedPanel<O>).draw() line: 139 BorderedPanelGuiImpl.access$501(BorderedPanelGuiImpl) line: 37 BorderedPanelGuiImpl$1$1.run() line: 200 GuiWebDriver(AbstractGuiDriver<F>).draw(NativePoint, NativeRectangle, Runnable) line: 1923 BorderedPanelGuiImpl$1.run() line: 189 GuiWebDriver(AbstractGuiDriver<F>).draw(NativePoint, NativeRectangle, Runnable) line: 1923 BorderedPanelGuiImpl.draw() line: 136 FrameWindowGuiImpl(AbstractContainer<O>).draw() line: 326 FrameWindowGuiImpl(TitledWindow<O>).draw() line: 100 FrameWindowGuiImpl(OuterFrame<O>).drawInt() line: 98 FrameWindowGuiImpl(OuterFrame<O>).draw() line: 90 FrameWindowGuiImpl(ModalWindow).draw() line: 159 FrameWindowGuiImpl.draw() line: 159 GuiOutputManager(OutputManager<P>).setInvalidate(Widget<?>, boolean, boolean) line: 1275 ThinClient.eventDrawingBracket(Widget<?>, boolean, boolean, Runnable) line: 13653 ThinClient.independentEventDrawingBracket(Widget, Runnable) line: 13519 ThinClient.viewWorker(Widget, ScreenBuffer, int[], boolean, int) line: 9285 ThinClient.enableWorker(int[], ScreenBuffer, boolean, Widget, Frame, boolean, int) line: 4346 ThinClient.enable(int, int[], ScreenBuffer, boolean, int, boolean) line: 4213 ThinClient.enable(int, int[], ScreenBuffer, boolean, int) line: 4119 WindowGuiImpl(Window<O>).tinyInput(String, int, BaseDataType, String, boolean, boolean) line: 1621
It needs somehow to work around
BorderedPanelGuiImpl(BorderedPanel<O>).draw()#24 Updated by Sergey Ivanovskiy over 10 years ago
But if we comment this code
/**
* Draw widget.
*/
@Override
public void draw()
{
// LayoutManager<O> layout = getLayout();
// if (layout != null)
// {
// layout.doLayout(this);
// }
super.draw();
}
then we fix the issue.
#25 Updated by Constantin Asofiei over 10 years ago
Sergey Ivanovskiy wrote:
But if we comment this code
[...]
then we fix the issue.
Try creating a BorderedPanel.doLayout() method and move the code there.
#26 Updated by Sergey Ivanovskiy over 10 years ago
Constantin, look at this, BorderPanel extends AbstractContainer and it already has doLayout.
/**
* Lay out container.
*/
@Override
public void doLayout()
{
if (layoutManager != null)
layoutManager.doLayout(this);
}
How to check inside BorderPanel that chui mode is on?
#27 Updated by Constantin Asofiei over 10 years ago
Sergey Ivanovskiy wrote:
Constantin, look at this,
BorderPanelextendsAbstractContainerand it already hasdoLayout.
[...]
How to check inside BorderPanel that chui mode is on?
There are ChUI and GUI specific sub-classes - BorderPanelImpl and BorderedPanelGuiImpl, so you don't need to explicitly check.
#28 Updated by Sergey Ivanovskiy over 10 years ago
- File resize_issue_2.txt
added
Thanks Constantin and Hynek, committed revision 11016 (branch 1811) should fix the issue. Committed revision 11017 adds comments and removes draw method of BorderPanel.
#29 Updated by Hynek Cihlar over 10 years ago
Sergey Ivanovskiy wrote:
Thanks Constantin and Hynek, committed revision 11016 (branch 1811) should fix the issue. Committed revision 11017 adds comments and removes
drawmethod ofBorderPanel.
Sergey, just a minor thing. In FrameWindowGuiImpl.show(), super.doLayout() should be doLayout().
#30 Updated by Sergey Ivanovskiy over 10 years ago
Sergey, just a minor thing. In
FrameWindowGuiImpl.show(),super.doLayout()should bedoLayout().
Committed revision 11019 fixes this issue.
#31 Updated by Greg Shah over 10 years ago
- Status changed from New to Closed
- Target version set to Milestone 12
#32 Updated by Greg Shah over 10 years ago
- % Done changed from 0 to 100
#33 Updated by Greg Shah over 9 years ago
- Target version changed from Milestone 12 to GUI Support for a Complex ADM2 App