eclipse.platform.swt
eclipse.platform.swt copied to clipboard
[Windows 11] MenuItem with style SWT.CHECK and image doesn't show state
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:

On Windows 10 selected state looks like this:

In Windows 11 selected state looks like this:


The screenshot above shows a difference between
SWT.CHECKmenu with.setImage()- regular
SWT.CHECKmenu
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.
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?
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.
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.

It can be seen that same code, on same Windows, behaves differently based on XP theming.
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.

Conclusions: Windows theming issue, not an SWT bug.
Conclusions: Windows theming issue, not an SWT bug.
If so, should we close this?
Probably.
Closing...
Conclusions: Windows theming issue, not an SWT bug.
What does that mean? You mean it's a bug of Windows?
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
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?
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();
}
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!
Please reopen this issue and implement a solution!
Are you able to provide a solution and pull request?
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.
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!
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?
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?
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.
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?
As there is an active interest in this issue, let's re-open it so it's visible.
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.
Probably everyone uses the staging view and this is how it looks for me with Windows 10:
I'll ask Eike to show how it looks for him.
Here's the same menu on my Win11 box:
@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.
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...
Note, the blue highlight is shown on actions using IAction.AS_CHECK_BOX on toolbars such as the "Link with Editor" one.
@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.