eclipse.platform.swt icon indicating copy to clipboard operation
eclipse.platform.swt copied to clipboard

[Win11] Layout handling is broken while a menu is shown

Open syntevo opened this issue 2 years ago • 9 comments

Describe the bug If a menu is shown, the layout handling is broken.

To Reproduce Launch this snippet 2 times:

  1. just wait 5s -> the label is replaced by a button
  2. restart and within 5s click any menu so it remains open -> the label disappears, but the button is not becoming shown
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class OpenedMenuPreventsLayout {

	private static Control visibleControl;

	public static void main(String[] args) {
		final Display display = new Display();

		final Shell shell = new Shell(display);
		setUpMenuBar(shell);

		shell.setLayout(new FillLayout());
		final Composite composite = new Composite(shell, 0);
		composite.setLayout(new Layout() {
			@Override
			protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
				return new Point(400, 300);
			}

			@Override
			protected void layout(Composite composite, boolean flushCache) {
				final Rectangle area = composite.getClientArea();
				if (visibleControl != null) {
					visibleControl.setBounds(area);
				}
			}
		});

		display.timerExec(5000, () -> {
			if (shell.isDisposed()) {
				return;
			}

			visibleControl.setVisible(false);
			final Button button = new Button(composite, SWT.PUSH);
			button.setText("Timeout");
			visibleControl = button;
			composite.requestLayout();
		});

		final Label label = new Label(composite, SWT.WRAP);
		label.setText("1. Just wait 5s -> the button occurs\n\n2. Restart and within 5 seconds open the Window menu -> no button occurs");
		visibleControl = label;

		final Point size = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		shell.setMinimumSize(size);
		shell.setSize(size);
		shell.open();

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		display.dispose();
	}

	private static void setUpMenuBar(Shell shell) {
		final Menu menuBar = new Menu(shell, SWT.BAR);
		createMenu("File", menuBar);
		createMenu("Edit", menuBar);
		createMenu("View", menuBar);
		createMenu("Window", menuBar);
		shell.setMenuBar(menuBar);
	}

	private static void createMenu(String name, Menu menuBar) {
		final MenuItem menuBarItem = new MenuItem(menuBar, SWT.CASCADE);
		menuBarItem.setText(name);

		final Menu menu = new Menu(menuBar.getShell(), SWT.DROP_DOWN);
		menuBarItem.setMenu(menu);

		new MenuItem(menu, SWT.PUSH).setText("Foo");
		new MenuItem(menu, SWT.PUSH).setText("Bar");
		new MenuItem(menu, SWT.PUSH).setText("Bazz");
	}
}

Expected behavior The button should become visible independent of a shown menu.

Screenshots

  1. just waiting default

  2. opening a menu menu-open

Environment:

  1. Select the platform(s) on which the behavior is seen:
    • [ ] All OS
    • [x] Windows
    • [ ] Linux
    • [ ] macOS
  1. Additional OS info (e.g. OS version, Linux Desktop, etc) Tried on Windows 11

syntevo avatar Aug 30 '23 09:08 syntevo

@syntevo I am able to recreate the issue on windows 11. Thanks for the recreate.

I tried on below environment. Eclipse SDK Version: 2023-12 (4.30) Build id: I20230912-1800 OS: Windows 11, v.10.0, x86_64 / win32 Java vendor: Eclipse Adoptium Java runtime version: 20+36 Java version: 20

When any of the menuitem is open, Timeout button covering area is not getting refreshed which should ideally get refreshed in the background irrespective of menuitems being open/closed.

We have also tried same on Mac but not seeing menu bar itself on mac => looks to be a different issue on Mac. Will check once again and update accordingly on it.

deepika-u avatar Sep 14 '23 08:09 deepika-u

We have also tried same on Mac but not seeing menu bar itself on mac => looks to be a different issue on Mac. Will check once again and update accordingly on it.

Timeout button covering area is coming properly once the menu item is clicked/when not opened. It is working as expected.

elsazac avatar Nov 20 '23 09:11 elsazac

I expect it to be only a problem on Windows. Hence the [Win11] in the title.

tmssngr avatar Nov 20 '23 15:11 tmssngr

@iloveeclipse @niraj-modi I feel this is a regression from => https://bugs.eclipse.org/bugs/show_bug.cgi?id=547373 Trying to understand the code, can you give some pointers to it.

I trace the problem to this point https://github.com/eclipse-platform/eclipse.platform.swt/blob/425f14e4c1725628ef99bbd483a3388b0f38356d/bundles/org.eclipse.swt/Eclipse%20SWT/win32/org/eclipse/swt/widgets/Composite.java#L841C64-L841C64

Here the variable display.externalEventLoop is having false due to this the deferredlayouts are not getting added to the display queue due to which shell is not getting refreshed.

deepika-u avatar Dec 06 '23 09:12 deepika-u

I feel this is a regression from => https://bugs.eclipse.org/bugs/show_bug.cgi?id=547373 Trying to understand the code, can you give some pointers to it.

I personally have no pointers, but I believe you've found the root cause. @SyntevoAlex: something you can look at?

iloveeclipse avatar Dec 06 '23 09:12 iloveeclipse

Unfortunately my queue is full for the next couple weeks or so.

SyntevoAlex avatar Dec 06 '23 10:12 SyntevoAlex

@SyntevoAlex For me to proceed on this fix, can you give some pointers for this issue please? Please find my analysis over here => https://github.com/eclipse-platform/eclipse.platform.swt/issues/791#issuecomment-1842503703

deepika-u avatar Jan 08 '24 09:01 deepika-u

@SyntevoAlex Sorry to bombard you again but still do you have some pointers for this issue please? Please find my analysis over here => https://github.com/eclipse-platform/eclipse.platform.swt/issues/791#issuecomment-1842503703

deepika-u avatar Feb 09 '24 07:02 deepika-u

Here the variable display.externalEventLoop is having false due to this the deferredlayouts are not getting added to the display queue due to which shell is not getting refreshed.

I don't understand. https://github.com/eclipse-platform/eclipse.platform.swt/blob/425f14e4c1725628ef99bbd483a3388b0f38356d/bundles/org.eclipse.swt/Eclipse%20SWT/win32/org/eclipse/swt/widgets/Composite.java#L841-L844

Here, if display.externalEventLoop is false, it will be added, and you're saying it's not added.

As for the reason why there's display.externalEventLoop condition, I can make a guess. Bug 547373 talks about popup menu, and I understand that while popup menu is active, externalEventLoop will be set to true, probably here: https://github.com/eclipse-platform/eclipse.platform.swt/blob/425f14e4c1725628ef99bbd483a3388b0f38356d/bundles/org.eclipse.swt/Eclipse%20SWT/win32/org/eclipse/swt/widgets/Control.java#L4957-4960

SyntevoAlex avatar Feb 12 '24 22:02 SyntevoAlex