-
Notifications
You must be signed in to change notification settings - Fork 230
Fix caret of raw insert mode of text editor on HiDPI screens #3230
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
base: master
Are you sure you want to change the base?
Conversation
HeikoKlare
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for proposing this fix! I have one question regarding the proposed solution, as it appears more complex to me than required.
|
|
||
| return bracketImage; | ||
| int height= styledText.getLineHeight(); | ||
| return new Image(styledText.getDisplay(), new ImageDataProvider() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason to use an ImageDataProvider rather than an ImageGcDrawer?
This requires to manually implement proper line width calculation and line rendering instead of just using gc.drawLine() like in the original code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This creates a 1-bit image as before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean with "1-bit image"? Do you mean that the line is 1 pixel wide? That's the intended behavior of setLineWidth(0). Changing that to setLineWidth(1) should resolve it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1-bit image = image with 1-bit color palette = a pixels uses 1-bit = colloquially called black-and-white image
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. But is it really necessary/beneficial to keep it like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also experimented with using ImageGcDrawer. Since the image created this way is no longer 1-bit, I had to adapt the GC drawing slightly to get the desired result. The following variant worked reliably for me:
Display display = styledText.getDisplay();
ImageGcDrawer imageGcDrawer = (gc, imageWidth, imageHeight) -> {
gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
gc.setLineWidth(1);
int h3 = imageHeight / 3;
for (int i = 0; i < imageWidth; i++) {
gc.drawLine(i, imageHeight - h3, i, imageHeight - 2 * h3);
}
};
final Image image = new Image(display, imageGcDrawer, width, styledText.getLineHeight());
I don’t have a strong opinion on ImageDataProvider vs ImageGcDrawer. From my perspective, using ImageGcDrawer allows relying on gc.drawLine(), while the ImageDataProvider approach also seems to work fine.
@wahlbrink do you see any reason why ImageDataProvider might be the better option here, or any trade-offs between the two that we should consider?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
I don’t know if there are special requirements (color depth) for cursor images on any platform
-
The ImageDataProvider works on the real monitor resolution:
- It takes advantage of higher resolutions (when dividing the height into thirds)
- You get exactly what you want at any zoom level (e.g. no rounding by drawing methods)
-
If you want to use ImageGcDrawer, your solution is not yet mature
- The two visible rectangles does not always have same height
- The drawn rectangle is fragmented at some zoom levels
Screenshot (2x): top ImageDataProvider, bottom ImageGcDrawer

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. The ImageDataProvider works on the real monitor resolution:
That's also the case for the ImageGcDrawer.
Couldn't the drawer simply be something like this?
gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
gc.fillRectangle(0, imageHeight / 3, imageWidth, imageHeight / 3);There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's also the case for the
ImageGcDrawer
The image yes, but not the GC API (when using autoscale). It works with "zoom 100" int coordinates, therefore the positioning of elements using the GC's regular drawing methods is bound to the "zoom 100" grid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The image yes, but not the GC API (when using autoscale). It works with "zoom 100" int coordinates, therefore the positioning of elements using the GC's regular drawing methods is bound to the "zoom 100" grid.
If I understand correctly, that refers to an issue to be addressed by eclipse-platform/eclipse.platform.swt#2913.
Is that relevant here? At a first glance, I don't see any drawing of the caret image with GC's drawImage() methods but only usages of OS methods taking the OS handles for drawing.
|
I’ve tested the changes in both dark and light themes, and they work as expected. and I can see the caret at multiple zooms. |
Fixes: #3010