Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,20 @@ public ActionBar(Composite parent, int style, ChatServiceManager chatServiceMana

ChatInputTextViewer tv = new ChatInputTextViewer(borderedActionBar, chatServiceManager);
tv.setEditable(true);
// Relayout the chat view container so the new ActionBar preferred height is honored when the input grows or
// shrinks (e.g., recalling a long history entry with Up arrow, wrapping a long line, or clearing the input).
// Avoids a brittle fixed-depth parent traversal inside ChatInputTextViewer (see issue #215).
tv.setLayoutRefreshCallback(() -> {
if (ActionBar.this.isDisposed()) {
return;
}
Composite layoutTarget = ActionBar.this.getParent();
if (layoutTarget != null && !layoutTarget.isDisposed()) {
// TODO: An very interesting bug here, if we call layout(true, true), even no changes,
// The width of welcome view will become shorter and shorter, may investigate it later
layoutTarget.layout(true, false);
}
});
tv.addTextListener(new ITextListener() {
@Override
public void textChanged(TextEvent event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public class ChatInputTextViewer extends UndoableTextViewer implements PaintList

private Color placeholderColor;

private Runnable layoutRefreshCallback;

/**
* Constructs a new ChatInputTextViewer.
*
Expand All @@ -77,6 +79,17 @@ public void setSendMessageHandler(Consumer<String> handler) {
this.sendMessageHandler = handler;
}

/**
* Registers a callback invoked after the input area's preferred height changes, so the owner can relayout the
* enclosing chat view container. This avoids a brittle fixed-depth parent traversal that breaks whenever the input
* area is rewrapped in a new composite (see issue #215).
*
* @param callback the layout-refresh callback; may be {@code null} to clear
*/
public void setLayoutRefreshCallback(Runnable callback) {
this.layoutRefreshCallback = callback;
}

public String getContent() {
return this.getDocument().get();
}
Expand Down Expand Up @@ -188,15 +201,24 @@ private boolean isInsertLineBreakOnly(TextEvent event) {

private void refreshHeightLayout() {
StyledText tvw = this.getTextWidget();
if (tvw == null || tvw.isDisposed()) {
return;
}
// If the width is not initialized, use SWT.DEFAULT to compute the size
// otherwise, swt will think that each line can only have one character.
int widthHint = tvw.getSize().x == 0 ? SWT.DEFAULT : tvw.getSize().x;
Point size = tvw.computeSize(widthHint, SWT.DEFAULT);
GridData gd = (GridData) tvw.getLayoutData();
gd.heightHint = Math.min(tvw.getLineHeight() * MAX_INPUT_ROWS, size.y);
// TODO: An very interesting bug here, if we call layout(true, true), even no changes,
// The width of welcome view will become shorter and shorter, may investigate it later
ChatInputTextViewer.this.parent.getParent().getParent().layout(true, false);
int newHeightHint = Math.min(tvw.getLineHeight() * MAX_INPUT_ROWS, size.y);
if (gd.heightHint == newHeightHint) {
return;
}
gd.heightHint = newHeightHint;
// Delegate the relayout to the owner (e.g., ActionBar) so the chat view container reserves space for the
// updated input height.
if (this.layoutRefreshCallback != null) {
this.layoutRefreshCallback.run();
}
}

private void onKeyPressed(KeyEvent e) {
Expand Down
Loading