Skip to content

Commit e07722f

Browse files
authored
Ghost text alignment fix windows linux (#287)
1 parent b11599a commit e07722f

File tree

4 files changed

+76
-18
lines changed

4 files changed

+76
-18
lines changed

plugin/src/software/aws/toolkits/eclipse/amazonq/util/IQInlineSuggestionSegmentFactory.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public static List<IQInlineSuggestionSegment> getSegmentsFromSuggestion(final QI
5353
case CLOSE:
5454
if (!unresolvedBrackets.isEmpty()) {
5555
var closeBracket = new QInlineSuggestionCloseBracketSegment(startOffset + j, i,
56-
currentLine.substring(0, j), c);
56+
currentLine.substring(0, j), c, qSes.isMacOS());
5757
var top = unresolvedBrackets.pop();
5858
if (top.isAMatch(closeBracket)) {
5959
top.pairUp(closeBracket);
@@ -70,7 +70,7 @@ public static List<IQInlineSuggestionSegment> getSegmentsFromSuggestion(final QI
7070
}
7171
distanceTraversed += sb.length() + 1; // plus one because we got rid of a \\R when we split it
7272
endOffset = startOffset + sb.length() - 1;
73-
res.add(new QInlineSuggestionNormalSegment(startOffset, endOffset, i, sb.toString()));
73+
res.add(new QInlineSuggestionNormalSegment(startOffset, endOffset, i, sb.toString(), qSes.isMacOS()));
7474
}
7575
return res;
7676
}

plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionCloseBracketSegment.java

+47-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import org.eclipse.swt.graphics.Color;
88
import org.eclipse.swt.graphics.Font;
99
import org.eclipse.swt.graphics.GC;
10+
import org.eclipse.swt.graphics.TextLayout;
11+
import org.eclipse.swt.widgets.Display;
1012

1113
public final class QInlineSuggestionCloseBracketSegment implements IQInlineSuggestionSegment, IQInlineBracket {
1214
private QInlineSuggestionOpenBracketSegment openBracket;
@@ -15,16 +17,28 @@ public final class QInlineSuggestionCloseBracketSegment implements IQInlineSugge
1517
private int lineInSuggestion;
1618
private String text;
1719
private Font adjustedTypedFont;
20+
private TextLayout layout;
21+
private TextLayout measureLayout;
22+
private boolean isMacOS;
1823

1924
public QInlineSuggestionCloseBracketSegment(final int caretOffset, final int lineInSuggestion, final String text,
20-
final char symbol) {
25+
final char symbol, final boolean isMacOS) {
2126
this.caretOffset = caretOffset;
2227
this.symbol = symbol;
2328
this.lineInSuggestion = lineInSuggestion;
2429
this.text = text;
30+
this.layout = isMacOS ? null : new TextLayout(Display.getCurrent());
31+
this.isMacOS = isMacOS;
2532

2633
var qInvocationSessionInstance = QInvocationSession.getInstance();
2734
adjustedTypedFont = qInvocationSessionInstance.getBoldInlineFont();
35+
if (!isMacOS) {
36+
int[] tabStops = qInvocationSessionInstance.getViewer().getTextWidget().getTabStops();
37+
measureLayout = new TextLayout(Display.getCurrent());
38+
measureLayout.setText(text);
39+
measureLayout.setFont(qInvocationSessionInstance.getInlineTextFont());
40+
measureLayout.setTabs(tabStops);
41+
}
2842
}
2943

3044
@Override
@@ -57,25 +71,40 @@ public void render(final GC gc, final int currentCaretOffset) {
5771
int invocationLine = widget.getLineAtOffset(invocationOffset);
5872
int lineHt = widget.getLineHeight();
5973
int fontHt = gc.getFontMetrics().getHeight();
60-
// educated guess:
61-
int endPadding = gc.getAdvanceWidth(symbol) / 4;
6274
y = (invocationLine + lineInSuggestion + 1) * lineHt - fontHt;
63-
x = gc.textExtent(text).x;
75+
x = isMacOS ? gc.textExtent(text).x : (int) measureLayout.getBounds().width;
6476
if (lineInSuggestion == 0) {
6577
x += widget.getLocationAtOffset(invocationOffset).x;
6678
}
67-
79+
int scrollOffsetY = widget.getTopPixel();
80+
y -= scrollOffsetY;
81+
String textToRender = String.valueOf(symbol);
6882
if (currentCaretOffset > openBracket.getRelevantOffset()) {
6983
Color typedColor = widget.getForeground();
70-
gc.setForeground(typedColor);
71-
gc.setFont(adjustedTypedFont);
84+
if (isMacOS) {
85+
gc.setForeground(typedColor);
86+
gc.setFont(adjustedTypedFont);
87+
gc.drawText(textToRender, x, y, false);
88+
} else {
89+
layout.setFont(adjustedTypedFont);
90+
layout.setText(textToRender);
91+
layout.setTabs(widget.getTabStops());
92+
gc.setAlpha(255);
93+
layout.draw(gc, x, y);
94+
}
7295
} else {
73-
gc.setForeground(Q_INLINE_HINT_TEXT_COLOR);
74-
gc.setFont(qInvocationSessionInstance.getInlineTextFont());
96+
if (isMacOS) {
97+
gc.setForeground(Q_INLINE_HINT_TEXT_COLOR);
98+
gc.setFont(qInvocationSessionInstance.getInlineTextFont());
99+
gc.drawText(textToRender, x, y, true);
100+
} else {
101+
layout.setFont(qInvocationSessionInstance.getInlineTextFont());
102+
layout.setText(textToRender);
103+
layout.setTabs(widget.getTabStops());
104+
gc.setAlpha(127);
105+
layout.draw(gc, x, y);
106+
}
75107
}
76-
int scrollOffsetY = widget.getTopPixel();
77-
y -= scrollOffsetY;
78-
gc.drawText(String.valueOf(symbol), x, y, true);
79108
}
80109

81110
@Override
@@ -112,5 +141,11 @@ public QInlineSuggestionOpenBracketSegment getOpenBracket() {
112141

113142
@Override
114143
public void cleanUp() {
144+
if (layout != null) {
145+
layout.dispose();
146+
}
147+
if (measureLayout != null) {
148+
measureLayout.dispose();
149+
}
115150
}
116151
}

plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionNormalSegment.java

+21-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import org.eclipse.swt.custom.StyledText;
99
import org.eclipse.swt.graphics.GC;
1010
import org.eclipse.swt.graphics.GlyphMetrics;
11+
import org.eclipse.swt.graphics.TextLayout;
12+
import org.eclipse.swt.widgets.Display;
1113

1214
import software.aws.toolkits.eclipse.amazonq.plugin.Activator;
1315

@@ -17,13 +19,17 @@ public final class QInlineSuggestionNormalSegment implements IQInlineSuggestionS
1719
private int lineInSuggestion;
1820
private String text;
1921
private StyleRange styleRange = new StyleRange();
22+
private TextLayout layout;
23+
private boolean isMacOS;
2024

2125
public QInlineSuggestionNormalSegment(final int startCaretPosition, final int endCaretPosition,
22-
final int lineInSuggestion, final String text) {
26+
final int lineInSuggestion, final String text, final boolean isMacOS) {
27+
this.isMacOS = isMacOS;
2328
this.text = text;
2429
this.startCaretOffset = startCaretPosition;
2530
this.endCaretOffset = endCaretPosition;
2631
this.lineInSuggestion = lineInSuggestion;
32+
this.layout = isMacOS ? null : new TextLayout(Display.getCurrent());
2733
}
2834

2935
@Override
@@ -73,13 +79,24 @@ public void render(final GC gc, final int currentCaretOffset) {
7379
int scrollOffsetY = widget.getTopPixel();
7480
y -= scrollOffsetY;
7581

76-
gc.setForeground(Q_INLINE_HINT_TEXT_COLOR);
77-
gc.setFont(qInvocationSessionInstance.getInlineTextFont());
78-
gc.drawText(textToRender, x, y, true);
82+
if (!isMacOS) {
83+
layout.setText(textToRender);
84+
layout.setFont(qInvocationSessionInstance.getInlineTextFont());
85+
layout.setTabs(widget.getTabStops());
86+
gc.setAlpha(127);
87+
layout.draw(gc, x, y);
88+
} else {
89+
gc.setForeground(Q_INLINE_HINT_TEXT_COLOR);
90+
gc.setFont(qInvocationSessionInstance.getInlineTextFont());
91+
gc.drawText(textToRender, x, y, true);
92+
}
7993
}
8094

8195
@Override
8296
public void cleanUp() {
97+
if (layout != null) {
98+
layout.dispose();
99+
}
83100
QInvocationSession session = QInvocationSession.getInstance();
84101
if (!session.isActive()) {
85102
return;

plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInvocationSession.java

+6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public final class QInvocationSession extends QResource {
3636
private volatile QInvocationSessionState state = QInvocationSessionState.INACTIVE;
3737
private CaretMovementReason caretMovementReason = CaretMovementReason.UNEXAMINED;
3838
private boolean suggestionAccepted = false;
39+
private boolean isMacOS;
3940

4041
private QSuggestionsContext suggestionsContext = null;
4142

@@ -60,6 +61,7 @@ public final class QInvocationSession extends QResource {
6061
// Private constructor to prevent instantiation
6162
private QInvocationSession() {
6263
// Initialization code here
64+
isMacOS = System.getProperty("os.name").toLowerCase().contains("mac");
6365
}
6466

6567
// Method to get the single instance
@@ -489,6 +491,10 @@ public Font getBoldInlineFont() {
489491
return inlineTextFontBold;
490492
}
491493

494+
public boolean isMacOS() {
495+
return isMacOS;
496+
}
497+
492498
// Additional methods for the session can be added here
493499
@Override
494500
public void dispose() {

0 commit comments

Comments
 (0)