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 8 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 8 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 8 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 8 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 8 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 8 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 8 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 8 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 8 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 8 years ago
Sergey Ivanovskiy wrote:
Please, help to explain in general words the implementation of
draw
function 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 8 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 8 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
WindowLayout
in 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 8 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 8 years ago
Please ignore note 12.
#15 Updated by Sergey Ivanovskiy over 8 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 8 years ago
If we call doLayout
inside draw
it leads to resize events are inside drawing circles!
#17 Updated by Constantin Asofiei over 8 years ago
Sergey Ivanovskiy wrote:
If we call
doLayout
insidedraw
it 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 8 years ago
If we call
doLayout
insidedraw
it leads to resize events are inside drawing circles!Are you referring to
doLayout
called from theBorderPanel.draw
code?
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 8 years ago
Sergey Ivanovskiy wrote:
If we call
doLayout
insidedraw
it leads to resize events are inside drawing circles!Are you referring to
doLayout
called from theBorderPanel.draw
code?Yes,
draw
method ofFrameWindowGuiImpl
#note-9 invokesdoLayout
ofBorderedPanel<GuiOutputManager> contentPane
, and the resize events are inside the drawing circle due toBorderedPanel.doLayout
returns different size forModalWindow
that 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 8 years ago
Constantin Asofiei wrote:
Sergey Ivanovskiy wrote:
If we call
doLayout
insidedraw
it leads to resize events are inside drawing circles!Are you referring to
doLayout
called from theBorderPanel.draw
code?Yes,
draw
method ofFrameWindowGuiImpl
#note-9 invokesdoLayout
ofBorderedPanel<GuiOutputManager> contentPane
, and the resize events are inside the drawing circle due toBorderedPanel.doLayout
returns different size forModalWindow
that contains it.OK, I don't think this is correct. At the time
draw
is 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 8 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 fromWindow
toTopLevelWindow
(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 8 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 fromWindow
toTopLevelWindow
(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
Create a simple frame in DIALOG-BOX
and then change its size through WIDTH
/HEIGHT
attributes.
#23 Updated by Sergey Ivanovskiy over 8 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 8 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 8 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 8 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 8 years ago
Sergey Ivanovskiy wrote:
Constantin, look at this,
BorderPanel
extendsAbstractContainer
and 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 8 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 8 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
draw
method ofBorderPanel
.
Sergey, just a minor thing. In FrameWindowGuiImpl.show()
, super.doLayout()
should be doLayout()
.
#30 Updated by Sergey Ivanovskiy over 8 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 8 years ago
- Status changed from New to Closed
- Target version set to Milestone 12
#32 Updated by Greg Shah over 8 years ago
- % Done changed from 0 to 100
#33 Updated by Greg Shah over 7 years ago
- Target version changed from Milestone 12 to GUI Support for a Complex ADM2 App