Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf2022-02-22 22:15:59 +0000
committerThomas Wolf2022-02-22 22:25:38 +0000
commit4841b9f04419be9c5dfaf50ff89c5d8287bdac2d (patch)
tree01d32ef916958ca10637fd8d050fc76f8bf117d5
parent42b7f0ef61c4726e37dcb6642952382af02616b9 (diff)
downloadegit-4841b9f04419be9c5dfaf50ff89c5d8287bdac2d.tar.gz
egit-4841b9f04419be9c5dfaf50ff89c5d8287bdac2d.tar.xz
egit-4841b9f04419be9c5dfaf50ff89c5d8287bdac2d.zip
[history] Fix UI freezes and word-wrap in commit & diff viewer
Recomputing the size of the combined commit & diff container could cause extensive UI freezes and other UI lagginess if the diff was long because of several reasons: 1. The size was recomputed far too often. It was done every time the text presentation in either the commit or the diff viewer was invalidated. But even hovering over a hyperlink invalidates part of the text presentation. 2. There are two methods of computing the content size of a scrolled composite, and EGit used the one that is apparently somewhat slower. 3. Word-wrapping was on by default in these viewers, even though they didn't wrap because of a bug in the size calculation. Computing the rendered size of a text with word-wrapping is slower than without. Fix this by only recomputing the size when the input changes, using the apparently somewhat faster method of updating the scrolled composite, and switching off word-wrapping by default. When word-wrapping is on, set a fixed width and compute only the height; this makes word-wrapping work. Additionally resizing the viewer by dragging the containing sash was super slow if the diff was large because EGit recomputed the size on every ResizeEvent. SWT emits ResizeEvents continuously while the control is being resized. Switch off live re-flowing the text (through continuously recomputing the size) while the user resizes the control. Only do this once after the user has stopped resizing the control. Resizing the control with word-wrap on may still occasionally lag, but much less than before. With word-wrap off, there is no need to recompute sizes at all, so in this case resizing is now perfectly smooth. Bug: 430226 Change-Id: If6a598e0ecea437ee2c0b139371ccc148a1cb57d Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java3
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitAndDiffComponent.java104
2 files changed, 87 insertions, 20 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
index c6577f154a..19b62915ff 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
@@ -55,7 +55,8 @@ public class PluginPreferenceInitializer extends AbstractPreferenceInitializer {
store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_RELATIVE_DATE, true);
store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_EMAIL_ADDRESSES, false);
store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_NOTES, false);
- store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_COMMENT_WRAP, true);
+ store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_COMMENT_WRAP,
+ false);
store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_REV_DETAIL, true);
store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_REV_COMMENT, true);
store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_TOOLTIPS, false);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitAndDiffComponent.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitAndDiffComponent.java
index abef4748a8..e6c9f12dfb 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitAndDiffComponent.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitAndDiffComponent.java
@@ -50,6 +50,7 @@ import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PlatformUI;
@@ -80,9 +81,6 @@ public class CommitAndDiffComponent {
private Point diffCaret = new Point(0, 0);
- /** True during {@link #resizeCommentAndDiffScrolledComposite()}. */
- private volatile boolean resizing;
-
/**
* Creates a new {@link CommitAndDiffComponent}.
*
@@ -94,8 +92,6 @@ public class CommitAndDiffComponent {
public CommitAndDiffComponent(Composite parent, IWorkbenchPartSite site) {
commentAndDiffScrolledComposite = new ScrolledComposite(parent,
SWT.H_SCROLL | SWT.V_SCROLL);
- commentAndDiffScrolledComposite.setExpandHorizontal(true);
- commentAndDiffScrolledComposite.setExpandVertical(true);
commentAndDiffComposite = new Composite(commentAndDiffScrolledComposite,
SWT.NONE);
@@ -113,6 +109,7 @@ public class CommitAndDiffComponent {
public void inputDocumentChanged(IDocument oldInput,
IDocument newInput) {
commentCaret = new Point(0, 0);
+ resizeCommentAndDiffScrolledComposite();
}
@Override
@@ -121,8 +118,6 @@ public class CommitAndDiffComponent {
// Nothing
}
});
- commentViewer.addTextListener(
- event -> resizeCommentAndDiffScrolledComposite());
StyledText commentWidget = commentViewer.getTextWidget();
commentWidget.addVerifyKeyListener(event -> {
@@ -140,6 +135,8 @@ public class CommitAndDiffComponent {
commentAndDiffComposite
.setBackground(commentViewer.getControl().getBackground());
+ commentAndDiffScrolledComposite
+ .setBackground(commentViewer.getControl().getBackground());
HyperlinkSourceViewer.Configuration configuration = new HyperlinkSourceViewer.Configuration(
EditorsUI.getPreferenceStore()) {
@@ -222,6 +219,7 @@ public class CommitAndDiffComponent {
public void inputDocumentChanged(IDocument oldInput,
IDocument newInput) {
diffCaret = new Point(0, 0);
+ resizeCommentAndDiffScrolledComposite();
}
@Override
@@ -230,8 +228,6 @@ public class CommitAndDiffComponent {
// Nothing
}
});
- diffViewer.addTextListener(
- event -> resizeCommentAndDiffScrolledComposite());
ActionUtils.UpdateableAction selectAll = ActionUtils.createGlobalAction(
ActionFactory.SELECT_ALL,
@@ -271,13 +267,16 @@ public class CommitAndDiffComponent {
diffWidget.getLineHeight(event.caretOffset));
});
- commentAndDiffScrolledComposite
- .addControlListener(new ControlAdapter() {
+ // "Live" resizing the contents of the ScrolledComposite takes too long.
+ // Resize once after the resize is done. Note that resizing is needed
+ // only if word-wrap is on.
+ commentAndDiffScrolledComposite.addControlListener(
+ new Resizer(commentAndDiffScrolledComposite) {
+
@Override
public void controlResized(ControlEvent e) {
- if (!resizing && commentViewer.getTextWidget()
- .getWordWrap()) {
- resizeCommentAndDiffScrolledComposite();
+ if (commentViewer.getTextWidget().getWordWrap()) {
+ super.controlResized(e);
}
}
});
@@ -370,13 +369,32 @@ public class CommitAndDiffComponent {
* whether to word-wrap
*/
public void setWrap(boolean wrap) {
+ if (Display.getCurrent() == null) {
+ StyledText text = commentViewer.getTextWidget();
+ if (!text.isDisposed()) {
+ text.getDisplay().asyncExec(() -> {
+ if (text.isDisposed()) {
+ return;
+ }
+ internalSetWrap(wrap);
+ });
+ }
+ } else {
+ internalSetWrap(wrap);
+ }
+ }
+
+ private void internalSetWrap(boolean wrap) {
commentViewer.getTextWidget().setWordWrap(wrap);
diffViewer.getTextWidget().setWordWrap(wrap);
resizeCommentAndDiffScrolledComposite();
}
+
private void resizeCommentAndDiffScrolledComposite() {
- resizing = true;
+ if (commentAndDiffComposite.isDisposed()) {
+ return;
+ }
long start = 0;
int lines = 0;
boolean trace = GitTraceLocation.HISTORYVIEW.isActive();
@@ -391,11 +409,25 @@ public class CommitAndDiffComponent {
start = System.currentTimeMillis();
}
- Point size = commentAndDiffComposite.computeSize(SWT.DEFAULT,
+ Point oldSize = commentAndDiffComposite.getSize();
+ Rectangle minSize = commentAndDiffScrolledComposite.getClientArea();
+ Point size;
+ StyledText text = commentViewer.getTextWidget();
+ if (text == null) {
+ size = new Point(0, 0);
+ } else if (text.getWordWrap()) {
+ size = commentAndDiffComposite.computeSize(minSize.width,
+ SWT.DEFAULT);
+ } else {
+ size = commentAndDiffComposite.computeSize(SWT.DEFAULT,
SWT.DEFAULT);
- commentAndDiffComposite.layout();
- commentAndDiffScrolledComposite.setMinSize(size);
- resizing = false;
+ }
+ size.x = Math.max(minSize.width, size.x);
+ size.y = Math.max(minSize.height, size.y);
+ if (!size.equals(oldSize)) {
+ commentAndDiffComposite.setSize(size);
+ commentAndDiffComposite.layout();
+ }
if (trace) {
long stop = System.currentTimeMillis();
@@ -503,4 +535,38 @@ public class CommitAndDiffComponent {
return italicToken;
}
}
+
+ private class Resizer extends ControlAdapter implements Runnable {
+
+ private final Control control;
+
+ private long lastEventTime;
+
+ Resizer(Control control) {
+ this.control = control;
+ }
+
+ @Override
+ public void controlResized(ControlEvent e) {
+ lastEventTime = System.currentTimeMillis();
+ schedule();
+ }
+
+ private void schedule() {
+ control.getDisplay().timerExec(300, this);
+ }
+
+ @Override
+ public void run() {
+ if (control.isDisposed()) {
+ return;
+ }
+ long now = System.currentTimeMillis();
+ if (now - lastEventTime > 300) {
+ resizeCommentAndDiffScrolledComposite();
+ } else {
+ schedule();
+ }
+ }
+ }
}

Back to the top