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

[Windows 11] MenuItem with style SWT.CHECK and image doesn't show state

Open Phillipus opened this issue 2 years ago • 75 comments

Windows 11 Eclipse 4.26

Run this Snippet on Windows 10 and Window 11 and compare the drop down menu after selecting it:

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;

public class MenuImageTest {
    
	public static void main(String[] args) {
		final Display display = new Display();
		Shell shell = new Shell(display);
		shell.setText("Menu Image Test");
		
		Menu appMenuBar = display.getMenuBar();
		if(appMenuBar == null) {
			appMenuBar = new Menu(shell, SWT.BAR);
			shell.setMenuBar(appMenuBar);
		}
		
		MenuItem file = new MenuItem(appMenuBar, SWT.CASCADE);
		file.setText("File");
		
		Menu dropdown = new Menu(appMenuBar);
		file.setMenu(dropdown);
		
		MenuItem testMenu = new MenuItem(dropdown, SWT.CHECK);
		testMenu.setImage(new Image(display, MenuImageTest.class.getResourceAsStream("image.png")));
		testMenu.setText("Test Menu");
		
		shell.open();
		
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
}

Use an image for image.png such as:

image

On Windows 10 selected state looks like this:

menu

In Windows 11 selected state looks like this:

menu 2

Phillipus avatar Dec 14 '22 21:12 Phillipus

image

SyntevoAlex avatar Dec 24 '22 15:12 SyntevoAlex

The screenshot above shows a difference between

  • SWT.CHECK menu with .setImage()
  • regular SWT.CHECK menu

It seems that on Win11, theme decided to no longer paint blue square around the icon, hence the difference. I would say that the other problem here is that the image is always painted, whether checked or not.

SyntevoAlex avatar Dec 24 '22 15:12 SyntevoAlex

I would say that the other problem here is that the image is always painted, whether checked or not.

Isn't that the expected behaviour?

Phillipus avatar Dec 24 '22 15:12 Phillipus

Looking at the default check mark (in regular SWT.CHECK menu without .setImage()) I would say that check image shall only appear when item is checked.

SyntevoAlex avatar Dec 24 '22 15:12 SyntevoAlex

Studied the code more. It turns out that check and image are independent things. SWT even tries to manipulate MNS_CHECKORBMP style in attempt to save space when menu only has images and no checks.

However, since XP theming, Windows seems to ignore that; it always paints check and image at the same spot.

Here's a screenshot of a native snippet on Win7, using disable visual themes compatibility flag. On the left, flag is enabled (that is, XP theming disabled). On the right, flag is disabled (that is, XP theming enabled). The "up arrow" image is just a random image I grabbed. image

It can be seen that same code, on same Windows, behaves differently based on XP theming.

SyntevoAlex avatar Dec 24 '22 17:12 SyntevoAlex

For comparison, same native snippet on Win11. It can be seen that checked image item looks the same as non-checked image item. Just like in SWT.

image

SyntevoAlex avatar Dec 24 '22 17:12 SyntevoAlex

Conclusions: Windows theming issue, not an SWT bug.

SyntevoAlex avatar Dec 24 '22 17:12 SyntevoAlex

Conclusions: Windows theming issue, not an SWT bug.

If so, should we close this?

Phillipus avatar Jan 15 '23 16:01 Phillipus

Probably.

SyntevoAlex avatar Jan 15 '23 17:01 SyntevoAlex

Closing...

Phillipus avatar Jan 15 '23 17:01 Phillipus

Conclusions: Windows theming issue, not an SWT bug.

What does that mean? You mean it's a bug of Windows?

BeckerWdf avatar Jun 21 '23 13:06 BeckerWdf

It's hard to say if it's a "bug" or "design decision". SWT relies on how Windows styled things, but Windows decided to style it differently in Win11. Will that decision be reverted in Win11? Who knows

SyntevoAlex avatar Jun 21 '23 15:06 SyntevoAlex

It's hard to say if it's a "bug" or "design decision". SWT relies on how Windows styled things, but Windows decided to style it differently in Win11. Will that decision be reverted in Win11? Who knows

Could we "work around" this in SWT? Or can we open a bug report at MS?

BeckerWdf avatar Jun 22 '23 07:06 BeckerWdf

It should be easy to work around (not perfectly, but good enough) using this (partly) pseudo-code

final int margin = getDpiScalingFactor(display);
final Rectangle size = image.getBounds();
final Image selectedImage = new Image(image.getDevice(), size.width + 2 * margin, size.height + 2 * margin);
final GC gc = new GC(selectedImage);
try {
	final Color background = createBlendedColor(image.getDevice().getSystemColor(SWT.COLOR_LIST_BACKGROUND),
	                                            image.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION), 0.25);
	gc.setBackground(background);
	gc.fillRectangle(0, 0, size.width + 2 * margin, size.height + 2 * margin);
	gc.drawImage(image, margin, margin);
}
finally {
	gc.dispose();
}

tmssngr avatar Jun 22 '23 09:06 tmssngr

It is very easy to say that this is a bug! Even if you like to call it "design decision" to hide important information, it is still a bug. For example in the junit view it is not possible to see any more which layout (horizontally, vertically or automatically) is currently applied. Please reopen this issue and implement a solution!

Gudi-24 avatar Jun 22 '23 09:06 Gudi-24

Please reopen this issue and implement a solution!

Are you able to provide a solution and pull request?

Phillipus avatar Jun 22 '23 09:06 Phillipus

Please reopen this issue and implement a solution!

Maybe you misunderstood Alex. He told that the problem occurs with pure native code, too, so this is no bug in SWT, but rather in Windows (if Microsoft not intentionally changed this). You need to send your request for a solution to Microsoft!

Alternatively, SWT is open source - please feel free to send a pull request with the solution.

tmssngr avatar Jun 22 '23 09:06 tmssngr

Please reopen this issue and implement a solution!

Maybe you misunderstood Alex. He told that the problem occurs with pure native code, too, so this is no bug in SWT, but rather in Windows (if Microsoft not intentionally changed this). You need to send your request for a solution to Microsoft!

One thing is for sure: There is a bug in Eclipse! And this is independent from the fact if I send a pull request or not!

Gudi-24 avatar Jun 22 '23 10:06 Gudi-24

One thing is for sure: There is a bug in Eclipse! And this is independent from the fact if I send a pull request or not!

What part of "this is no bug in SWT, but rather in Windows" do you not understand?

Phillipus avatar Jun 22 '23 10:06 Phillipus

One thing is for sure: There is a bug in Eclipse! And this is independent from the fact if I send a pull request or not!

What part of "this is no bug in SWT, but rather in Windows" do you not understand?

Well, I understand that, but it doesn't help. Because most probably it won't be fixed by Windows and then the bug will stay in many eclipse views. And this is a major problem. Or do you have a different opinion?

Gudi-24 avatar Jun 22 '23 10:06 Gudi-24

Or do you have a different opinion?

If this is how it is because of a change in Windows 11, as @SyntevoAlex explains above, then you're out of luck. However, if you want to implement a workaround then I suggest to follow the suggested code hint from @tmssngr in the comment above.

Phillipus avatar Jun 22 '23 10:06 Phillipus

It should be easy to work around (not perfectly, but good enough) using this (partly) pseudo-code

final int margin = getDpiScalingFactor(display);
final Rectangle size = image.getBounds();
final Image selectedImage = new Image(image.getDevice(), size.width + 2 * margin, size.height + 2 * margin);
final GC gc = new GC(selectedImage);
try {
	final Color background = createBlendedColor(image.getDevice().getSystemColor(SWT.COLOR_LIST_BACKGROUND),
	                                            image.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION), 0.25);
	gc.setBackground(background);
	gc.fillRectangle(0, 0, size.width + 2 * margin, size.height + 2 * margin);
	gc.drawImage(image, margin, margin);
}
finally {
	gc.dispose();
}

Can we put this into SWT? I understand that this is a bug or design decision of MS but I also see that Eclipse (and other SWT-based apps really have an issue with it. So I think it's work to fix this in SWT. What do you think?

BeckerWdf avatar Jun 22 '23 10:06 BeckerWdf

As there is an active interest in this issue, let's re-open it so it's visible.

Phillipus avatar Jun 22 '23 18:06 Phillipus

I don’t think anybody will care whose fault the problem is. If I can’t tell whether a menu item in my Eclipse application is checked or not then my perception will be that it’s a bug and a really bad one at that. We could tell 100,000 users it’s someone else’s fault but do we want to tell them we can’t do anything about it? Or worse that we don’t want to do anything about it. Of course it’s free so no one is obligated to do anything.

merks avatar Jun 22 '23 18:06 merks

Probably everyone uses the staging view and this is how it looks for me with Windows 10:

image

I'll ask Eike to show how it looks for him.

merks avatar Jun 23 '23 12:06 merks

Here's the same menu on my Win11 box:

image

estepper avatar Jun 23 '23 12:06 estepper

@merks : I believe we've had some connections to Microsoft in Foundation. Wouldn't be possible to ping them and ask for a fix? I'm not familiar with Windows UI API / UX guidelines, but it looks like a bad regression.

It should be easy to work around (not perfectly, but good enough) using this (partly) pseudo-code

@tmssngr : could you please provide a PR with the proposed "pseudo-code" change? Even if MS would fix that I guess it will take some time to reach end users.

iloveeclipse avatar Jun 23 '23 12:06 iloveeclipse

This pretty much makes such things unusable. I'll be holding off updating to Windows 11 for a bit longer for sure.

The folks I know generally are not involved in such aspects at Microsoft. It's a really big company of course. But it doesn't hurt to chat...

merks avatar Jun 23 '23 13:06 merks

Note, the blue highlight is shown on actions using IAction.AS_CHECK_BOX on toolbars such as the "Link with Editor" one.

Phillipus avatar Jun 23 '23 13:06 Phillipus

@tmssngr : could you please provide a PR with the proposed "pseudo-code" change? Even if MS would fix that I guess it will take some time to reach end users.

Sorry, I won't be able to provide such a pull request anytime soon.

tmssngr avatar Jun 23 '23 13:06 tmssngr