Skip to content
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

Modal window jumps #3938

Closed
s-kotte opened this issue Jul 25, 2023 · 19 comments
Closed

Modal window jumps #3938

s-kotte opened this issue Jul 25, 2023 · 19 comments
Labels
bug Something isn't working

Comments

@s-kotte
Copy link

s-kotte commented Jul 25, 2023

Describe the bug
Changing the height of a modal window at runtime sometimes causes window jumps. The window jumps only occur when the xpra window manager is used. With fluxbox or lightdm it works fine.

To Reproduce
Steps to reproduce the behavior:

  1. Check out the sample program: https://github.com/s-kotte/Xpra-ModalWindowBugExample
  2. Open dialog and spam three or more keys simultaneously in the textbox

Xpra server command:

  1. xpra start --start-child-after-connect="wine ./program/WindowsFormsApp2.exe" --bind-tcp=0.0.0.0:8085 --no-daemon -d geometry

System Information (please complete the following information):

  • Server OS: Ubuntu 20.04
  • Client OS: Windows 11
  • Xpra Server Version: 4.4.6 (with xvfb)
  • Xpra Client Version: 7.0 html5 (can also be reproduced with the xpra client)

Additional context
Log file: xpra.log

2023-07-25.10-42-13.mp4
@s-kotte s-kotte added the bug Something isn't working label Jul 25, 2023
@totaam
Copy link
Collaborator

totaam commented Jul 25, 2023

Can this be reproduced with an xpra client running on X11?

My guess is that the application is sending a configure request with the position bits set and we honour it.
Run with -d geometry to confirm.

Wayland clients are prevented from knowing the position of their window, so fixing this type of bug would be hard.

This should work with the html5 client but perhaps we're missing a geometry update following the window move.
xpra info can show you the window's geometry at any time.

@s-kotte
Copy link
Author

s-kotte commented Jul 25, 2023

Can this be reproduced with an xpra client running on X11?

  • Do you think I should try this with the xdummy driver

My guess is that the application is sending a configure request with the position bits set and we honour it.
Run with -d geometry to confirm.

@totaam
Copy link
Collaborator

totaam commented Jul 25, 2023

The dummy driver is very unlikely to make any difference.
The problem looks like a client side issue.

@totaam
Copy link
Collaborator

totaam commented Jul 25, 2023

That log file is humongous, please only include the relevant bits.

@s-kotte
Copy link
Author

s-kotte commented Jul 25, 2023

Ok this should only be the relvante part:

541 _update_client_geometry: using client-geometry=(800, 480, 858, 585)
542 _do_update_client_geometry((800, 480, 858, 585))
542 calc_constrained_size(858, 585, typedict({'position': (800, 480), 'gravity': 10}))=(858, 585) (size_constraints=(0, 0, 32767, 32767))
542 _do_update_client_geometry: size({'position': (800, 480), 'gravity': 10})=858x585
546 do_child_configure_request_event(<X11:ConfigureRequest {'send_event': '0', 'serial': '0xe6e2', 'delivered_to': '0x40002c', 'window': '0x1200005', 'x': '800', 'y': '480', 'width': '858', 'height': '522', 'border_width': '0', 'above': 'None', 'detail': '0', 'value_mask': '15'}>) client=0x1200005, corral=0x40002c, value_mask=X|Y|Width|Height, size-hints={'position': (800, 480), 'gravity': 10}
547 XpraServer._window_resized_signaled(WindowModel(0x1200005),(<GParamBoxed 'geometry'>,)) geometry=(800, 480, 858, 522), desktop manager geometry=(800, 480, 858, 585)
547 do_child_configure_request_event updated requested geometry from (800, 480, 858, 585) to  (800, 480, 858, 522)
559 WindowModel.do_xpra_configure_event(<X11:ConfigureNotify {'send_event': '0', 'serial': '0xe6f8', 'delivered_to': '0x1200005', 'window': '0x1200005', 'x': '800', 'y': '480', 'width': '858', 'height': '522', 'border_width': '0', 'above': '0'}>) corral=0x40002c, client=0x1200005, managed=True
559 calc_constrained_size(858, 522, typedict({'position': (800, 480), 'gravity': 10}))=(858, 522) (size_constraints=(0, 0, 32767, 32767))
559 resize_corral_window(800, 480, 858, 522) hints={'position': (800, 480), 'gravity': 10}, constrained size=(858, 522), geometry=(800, 480, 858, 522), resized=True, moved=True
559 resize_corral_window() move and resize from (800, 480, 858, 585) to (800, 480, 858, 522)
563 do_child_configure_request_event(<X11:ConfigureRequest {'send_event': '0', 'serial': '0xe70f', 'delivered_to': '0x40002c', 'window': '0x1200005', 'x': '800', 'y': '480', 'width': '858', 'height': '531', 'border_width': '0', 'above': 'None', 'detail': '0', 'value_mask': '15'}>) client=0x1200005, corral=0x40002c, value_mask=X|Y|Width|Height, size-hints={'position': (800, 480), 'gravity': 10}
563 XpraServer._window_resized_signaled(WindowModel(0x1200005),(<GParamBoxed 'geometry'>,)) geometry=(800, 480, 858, 531), desktop manager geometry=(800, 480, 858, 522)
563 do_child_configure_request_event updated requested geometry from (800, 480, 858, 522) to  (800, 480, 858, 531)
574 WindowModel.do_xpra_configure_event(<X11:ConfigureNotify {'send_event': '0', 'serial': '0xe72f', 'delivered_to': '0x40002c', 'window': '0x40002c', 'x': '800', 'y': '480', 'width': '858', 'height': '522', 'border_width': '0', 'above': '4194332'}>) corral=0x40002c, client=0x1200005, managed=True
574 WindowModel.do_xpra_configure_event: event is on the corral window 0x40002c, ignored
574 WindowModel.do_xpra_configure_event(<X11:ConfigureNotify {'send_event': '0', 'serial': '0xe730', 'delivered_to': '0x1200005', 'window': '0x1200005', 'x': '0', 'y': '0', 'width': '858', 'height': '522', 'border_width': '0', 'above': '0'}>) corral=0x40002c, client=0x1200005, managed=True
575 calc_constrained_size(858, 522, typedict({'position': (800, 480), 'gravity': 10}))=(858, 522) (size_constraints=(0, 0, 32767, 32767))
575 resize_corral_window(0, 0, 858, 522) hints={'position': (800, 480), 'gravity': 10}, constrained size=(858, 522), geometry=(800, 480, 858, 531), resized=False, moved=False
583 WindowModel.do_xpra_configure_event(<X11:ConfigureNotify {'send_event': '0', 'serial': '0xe745', 'delivered_to': '0x1200005', 'window': '0x1200005', 'x': '800', 'y': '480', 'width': '858', 'height': '531', 'border_width': '0', 'above': '0'}>) corral=0x40002c, client=0x1200005, managed=True
584 calc_constrained_size(858, 531, typedict({'position': (800, 480), 'gravity': 10}))=(858, 531) (size_constraints=(0, 0, 32767, 32767))
585 resize_corral_window(800, 480, 858, 531) hints={'position': (800, 480), 'gravity': 10}, constrained size=(858, 531), geometry=(800, 480, 858, 531), resized=True, moved=True
585 resize_corral_window() move and resize from (800, 480, 858, 522) to (800, 480, 858, 531)
589 _update_client_geometry: using client-geometry=(800, 480, 858, 531)
591 _do_update_client_geometry((800, 480, 858, 531))
592 calc_constrained_size(858, 531, typedict({'position': (1600, 960), 'gravity': 10}))=(858, 531) (size_constraints=(0, 0, 32767, 32767))
592 _do_update_client_geometry: size({'position': (1600, 960), 'gravity': 10})=858x531
602 do_child_configure_request_event(<X11:ConfigureRequest {'send_event': '0', 'serial': '0xe769', 'delivered_to': '0x40002c', 'window': '0x1200005', 'x': '1600', 'y': '960', 'width': '858', 'height': '537', 'border_width': '0', 'above': 'None', 'detail': '0', 'value_mask': '15'}>) client=0x1200005, corral=0x40002c, value_mask=X|Y|Width|Height, size-hints={'position': (1600, 960), 'gravity': 10}
603 XpraServer._window_resized_signaled(WindowModel(0x1200005),(<GParamBoxed 'geometry'>,)) geometry=(1600, 960, 858, 537), desktop manager geometry=(800, 480, 858, 531)
605 do_child_configure_request_event updated requested geometry from (800, 480, 858, 531) to  (1600, 960, 858, 537)
612 WindowModel.do_xpra_configure_event(<X11:ConfigureNotify {'send_event': '0', 'serial': '0xe77d', 'delivered_to': '0x40002c', 'window': '0x40002c', 'x': '800', 'y': '480', 'width': '858', 'height': '531', 'border_width': '0', 'above': '4194332'}>) corral=0x40002c, client=0x1200005, managed=True
612 WindowModel.do_xpra_configure_event: event is on the corral window 0x40002c, ignored
613 WindowModel.do_xpra_configure_event(<X11:ConfigureNotify {'send_event': '0', 'serial': '0xe77e', 'delivered_to': '0x1200005', 'window': '0x1200005', 'x': '0', 'y': '0', 'width': '858', 'height': '531', 'border_width': '0', 'above': '0'}>) corral=0x40002c, client=0x1200005, managed=True
614 calc_constrained_size(858, 531, typedict({'position': (1600, 960), 'gravity': 10}))=(858, 531) (size_constraints=(0, 0, 32767, 32767))
614 resize_corral_window(0, 0, 858, 531) hints={'position': (1600, 960), 'gravity': 10}, constrained size=(858, 531), geometry=(1600, 960, 858, 537), resized=False, moved=False
618 WindowModel.do_xpra_configure_event(<X11:ConfigureNotify {'send_event': '0', 'serial': '0xe79a', 'delivered_to': '0x1200005', 'window': '0x1200005', 'x': '1600', 'y': '960', 'width': '858', 'height': '537', 'border_width': '0', 'above': '0'}>) corral=0x40002c, client=0x1200005, managed=True
620 calc_constrained_size(858, 537, typedict({'position': (1600, 960), 'gravity': 10}))=(858, 537) (size_constraints=(0, 0, 32767, 32767))
621 resize_corral_window(1600, 960, 858, 537) hints={'position': (1600, 960), 'gravity': 10}, constrained size=(858, 537), geometry=(1600, 960, 858, 537), resized=True, moved=True
621 resize_corral_window() move and resize from (800, 480, 858, 531) to (1600, 960, 858, 537)
623 WindowModel.do_xpra_configure_event(<X11:ConfigureNotify {'send_event': '0', 'serial': '0xe7ac', 'delivered_to': '0x40002c', 'window': '0x40002c', 'x': '1600', 'y': '960', 'width': '858', 'height': '537', 'border_width': '0', 'above': '4194332'}>) corral=0x40002c, client=0x1200005, managed=True
623 WindowModel.do_xpra_configure_event: event is on the corral window 0x40002c, ignored
623 WindowModel.do_xpra_configure_event(<X11:ConfigureNotify {'send_event': '0', 'serial': '0xe7ad', 'delivered_to': '0x1200005', 'window': '0x1200005', 'x': '0', 'y': '0', 'width': '858', 'height': '537', 'border_width': '0', 'above': '0'}>) corral=0x40002c, client=0x1200005, managed=True
624 calc_constrained_size(858, 537, typedict({'position': (1600, 960), 'gravity': 10}))=(858, 537) (size_constraints=(0, 0, 32767, 32767))
624 resize_corral_window(0, 0, 858, 537) hints={'position': (1600, 960), 'gravity': 10}, constrained size=(858, 537), geometry=(1600, 960, 858, 537), resized=False, moved=False
706 size_notify_clients(WindowModel(0x1200005), 59508.29795079) last_client_configure_event=59508.29795079
715 _process_configure_window([2, 1600, 867, 858, 537, {}, 0, {}, False]) old window geometry: (1600, 960, 858, 537)
715 _update_client_geometry: using client-geometry=(1600, 867, 858, 537)
715 _do_update_client_geometry((1600, 867, 858, 537))
715 calc_constrained_size(858, 537, typedict({'position': (1600, 960), 'gravity': 10}))=(858, 537) (size_constraints=(0, 0, 32767, 32767))
715 _do_update_client_geometry: size({'position': (1600, 960), 'gravity': 10})=858x537
716 XpraServer._window_resized_signaled(WindowModel(0x1200005),(<GParamBoxed 'geometry'>,)) geometry=(1600, 867, 858, 537), desktop manager geometry=(1600, 867, 858, 537)
720 WindowModel.do_xpra_configure_event(<X11:ConfigureNotify {'send_event': '0', 'serial': '0xe7c4', 'delivered_to': '0x40002c', 'window': '0x40002c', 'x': '1600', 'y': '867', 'width': '858', 'height': '537', 'border_width': '0', 'above': '4194332'}>) corral=0x40002c, client=0x1200005, managed=True
722 WindowModel.do_xpra_configure_event: event is on the corral window 0x40002c, ignored
965 size_notify_clients(WindowModel(0x1200005), 59632.749739167) last_client_configure_event=59632.749739167

@s-kotte
Copy link
Author

s-kotte commented Jul 25, 2023

Can this be reproduced with an xpra client running on X11?

I can only reproduce this in seamless mode.
With Fluxbox or a shadow server running on X11 it works fine.

  • xpra start-desktop --start="fluxbox" --start-child-after-connect="wine WindowsFormsApp2.exe" --bind-tcp=0.0.0.0:8085 --no-daemon
  • xpra shadow --start-child-after-connect="wine WindowsFormsApp2.exe" --bind-tcp=0.0.0.0:8085 --no-daemon

@totaam
Copy link
Collaborator

totaam commented Jul 25, 2023

Please try with an xpra client running within an X11 desktop session, not Wayland, not html5.

@s-kotte
Copy link
Author

s-kotte commented Jul 25, 2023

I am having the same problem here as well, my xpra client is now running within an X11 desktop session

@totaam
Copy link
Collaborator

totaam commented Jul 25, 2023

At the end of your log:

716 XpraServer._window_resized_signaled(WindowModel(0x1200005),(<GParamBoxed 'geometry'>,)) geometry=(1600, 867, 858, 537), desktop manager geometry=(1600, 867, 858, 537)

I have no idea if this is right or wrong, but both the client and server agree on 1600x867.
This could also be similar to #1941

@s-kotte
Copy link
Author

s-kotte commented Jul 27, 2023

Kind of strange, when I add a move and resize event for a modal window, the move event also fires when I resize. Is this the normal behavior of xpra? I would expect only the resize event to fire.

@totaam
Copy link
Collaborator

totaam commented Jan 29, 2024

the move event also fires when I resize

There is no Move or Resize event in X11, only XConfigure which does both at once.

@totaam
Copy link
Collaborator

totaam commented Feb 6, 2024

@s-kotte There were some window geometry fixes in 5.0.5 - does that help?

@s-kotte
Copy link
Author

s-kotte commented Feb 6, 2024

I have tried version 5.0.5 and it does not seem to fix the problem.

totaam added a commit that referenced this issue Feb 8, 2024
and do call '_update_client_geometry' whenever the hints actually change, which means dealing with potentially uninitialized values: use the current window geometry
totaam added a commit that referenced this issue Feb 8, 2024
@totaam
Copy link
Collaborator

totaam commented Feb 8, 2024

So I managed to compile this app with VS on my win10 VM.
Running it with -d geometry,metadata sure is producing a lot more events than needed.
Typing a single character in the text box triggers (trimmed down):

Property changed on 0x1600006: WM_NORMAL_HINTS
updateprop(size-hints, {'gravity': 10}) unchanged
Property changed on 0x1600006: _MOTIF_WM_HINTS
updateprop(decorations, 122) unchanged
updateprop(geometry, (49, 118, 859, 491)) previous value=(49, 118, 859, 479)

Then again WM_NORMAL_HINTS and _MOTIF_WM_HINTS...

Property changed on 0x1600006: _NET_WM_WINDOW_TYPE
updateprop(window-type, ['NORMAL']) unchanged
Property changed on 0x1600006: WM_HINTS
updateprop(group-leader, <GdkX11.X11Window object at 0x7f0df183f7c0 (GdkX11Window at 0x558bf1498600)>) unchanged
updateprop(attention-requested, False) unchanged
Property changed on 0x1600006: _NET_WM_ICON
updating metadata on WindowModel(1600006): <GParamBoxed 'icons'>

So, most of the no-op updates are skipped, except for the icon.

The changes above fix the worst offenders.

I'm still going to look at the geometry changes to see if they're legit.
That's all with the python client, the html5 client should behave the same, if not then it will need fixing.

Window geometry documentation links:

@s-kotte
Copy link
Author

s-kotte commented Feb 8, 2024

I think the changes have fixed the bug a bit as it occurs less frequently now (tested with the master version). However, it is still reproducible if the window size is changed frequently.

2024-02-08.14-35-32.mp4

@totaam
Copy link
Collaborator

totaam commented Feb 12, 2024

The good news is that I think that I have found the problem.
The bad news is that it looks like a monster.
As per ConfigureNotify: The x and y members are set to the coordinates relative to the parent window's origin and indicate the position of the upper-left outside corner of the window

@totaam
Copy link
Collaborator

totaam commented Feb 13, 2024

Confusing, ICCCM 4.2.3. Window Move states that If the window manager moves a top-level window without changing its size, the client will receive a synthetic ConfigureNotify event following the move that describes the new location in terms of the root coordinate space
So why did I see a partial improvement when using relative coordinates?
But also: 4.2.4. Window Resize: The client can elect to receive notification of being resized by selecting for StructureNotify events on its top-level windows. It will receive a ConfigureNotify event. The size information in the event will be correct, but the location will be in the parent window (which may not be the root).
Section 4.1.5 adds: The general rule is that coordinates in real ConfigureNotify events are in the parent's space; in synthetic events, they are in the root space.

totaam added a commit that referenced this issue Feb 13, 2024
totaam added a commit that referenced this issue Feb 13, 2024
* only send a configure notify when the window as moved but not resized
* when only resized, preserve the existing position
* when handling configure requests, generate a new event mask which may ignore some unchange values (position and / or size)
@totaam
Copy link
Collaborator

totaam commented Feb 13, 2024

A massive thank you to @s-kotte for being so patient with this one.
The sample code was really helpful and uncovered some really tricksy bugs.

This will have to simmer a bit before I can backport it all to the older branches.
I also want to re-test #2600, #1941, #1975 and perhaps some others.

Since I am on a roll, I might revisit #3478

There will be builds with this fix in the beta repo soon, but not for Ubuntu Focal... which is only supported in v5 (time to upgrade?)

totaam added a commit that referenced this issue Feb 17, 2024
* only send a configure notify when the window as moved but not resized
* when only resized, preserve the existing position
* when handling configure requests, generate a new event mask which may ignore some unchange values (position and / or size)
@totaam
Copy link
Collaborator

totaam commented Feb 17, 2024

This will be included in v5.0.6

@totaam totaam closed this as completed Feb 17, 2024
totaam added a commit that referenced this issue Feb 19, 2024
* only send a configure notify when the window as moved but not resized
* when only resized, preserve the existing position
* when handling configure requests, generate a new event mask which may ignore some unchange values (position and / or size)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants