Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Pun2017-01-25 18:44:40 +0000
committerAlexander Kurtakov2017-02-16 07:33:47 +0000
commitb3374a13114f858a723270acab708020b66f5103 (patch)
tree7025b82e2274f12758ae8186b0e9e693c270252a
parent2ac039d764313b3a3e5665602468c11db274d599 (diff)
downloadeclipse.platform.swt-b3374a13114f858a723270acab708020b66f5103.tar.gz
eclipse.platform.swt-b3374a13114f858a723270acab708020b66f5103.tar.xz
eclipse.platform.swt-b3374a13114f858a723270acab708020b66f5103.zip
Bug 500013 - [Wayland] Keyboard Left and Right Arrow keys are very slow
or unresponsive The Caret drawing mechanism was originally implemented to be done using a generated cairo from parent window using gdk_cairo_create(). This is now deprecated and not working in Wayland. Drawing of the caret is now handled in a draw signal which is triggered by a queue_draw() call. Change-Id: I0b6e50140b4e104e13ca2e6cbc1d97c8488e1b2c Signed-off-by: Ian Pun <ipun@redhat.com> Signed-off-by: Alexander Kurtakov <akurtako@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java59
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Caret.java109
2 files changed, 115 insertions, 53 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java
index 8843f9148d..242d395b7e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java
@@ -42,6 +42,7 @@ import org.eclipse.swt.internal.gtk.*;
public class Canvas extends Composite {
Caret caret;
IME ime;
+ private boolean drawFlag;
Canvas () {}
@@ -167,13 +168,63 @@ long /*int*/ gtk_commit (long /*int*/ imcontext, long /*int*/ text) {
@Override
long /*int*/ gtk_draw (long /*int*/ widget, long /*int*/ cairo) {
if ((state & OBSCURED) != 0) return 0;
- boolean isFocus = caret != null && caret.isFocusCaret ();
- if (isFocus) caret.killFocus ();
- long /*int*/ result = super.gtk_draw (widget, cairo);
- if (isFocus) caret.setFocus ();
+ long /*int*/ result;
+ if ( OS.GTK_VERSION < OS.VERSION(3, 22, 0)) {
+ boolean isFocus = caret != null && caret.isFocusCaret ();
+ if (isFocus) caret.killFocus ();
+ result = super.gtk_draw (widget, cairo);
+ if (isFocus) caret.setFocus ();
+ } else {
+ result = super.gtk_draw (widget, cairo);
+ if (caret != null && caret.isDrawing) {
+ drawCaret(widget,cairo);
+ caret.isDrawing = false;
+ }
+ }
return result;
}
+private void drawCaret (long /*int*/ widget, long /*int*/ cairo) {
+ if(this.isDisposed()) return;
+ if (cairo == 0) error(SWT.ERROR_NO_HANDLES);
+ if (!drawFlag) {
+ Cairo.cairo_save(cairo);
+ if (caret.image != null && !caret.image.isDisposed() && caret.image.mask == 0) {
+ Cairo.cairo_set_source_rgb(cairo, 1, 1, 1);
+ Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_DIFFERENCE);
+ long /*int*/ surface = Cairo.cairo_get_target(cairo);
+ int nWidth = 0;
+ switch (Cairo.cairo_surface_get_type(surface)) {
+ case Cairo.CAIRO_SURFACE_TYPE_IMAGE:
+ nWidth = Cairo.cairo_image_surface_get_width(surface);
+ break;
+ case Cairo.CAIRO_SURFACE_TYPE_XLIB:
+ nWidth = Cairo.cairo_xlib_surface_get_width(surface);
+ break;
+ }
+ int nX = caret.x;
+ if ((style & SWT.MIRRORED) != 0) nX = getClientWidth () - nWidth - nX;
+ Cairo.cairo_translate(cairo, nX, caret.y);
+ Cairo.cairo_set_source_surface(cairo, caret.image.surface, 0, 0);
+ Cairo.cairo_paint(cairo);
+ } else {
+ Cairo.cairo_set_source_rgb(cairo, 1, 1, 1);
+ Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_DIFFERENCE);
+ int nWidth = caret.width, nHeight = caret.height;
+ if (nWidth <= 0) nWidth = Caret.DEFAULT_WIDTH;
+ int nX = caret.x;
+ if ((style & SWT.MIRRORED) != 0) nX = getClientWidth () - nWidth - nX;
+ Cairo.cairo_rectangle(cairo, nX, caret.y, nWidth, nHeight);
+ }
+ Cairo.cairo_fill(cairo);
+ Cairo.cairo_restore(cairo);
+ drawFlag = true;
+ } else {
+ drawFlag = false;
+ }
+ return;
+}
+
@Override
long /*int*/ gtk_expose_event (long /*int*/ widget, long /*int*/ event) {
if ((state & OBSCURED) != 0) return 0;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Caret.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Caret.java
index be0015207c..bceeec6637 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Caret.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Caret.java
@@ -38,7 +38,7 @@ import org.eclipse.swt.internal.gtk.*;
public class Caret extends Widget {
Canvas parent;
int x, y, width, height;
- boolean isVisible, isShowing;
+ boolean isVisible, isShowing, isDrawing;
int blinkRate;
Image image;
Font font;
@@ -99,64 +99,75 @@ void createWidget (int index) {
boolean drawCaret () {
if (parent == null) return false;
if (parent.isDisposed ()) return false;
- long /*int*/ window = parent.paintWindow ();
- if (OS.USE_CAIRO) {
- long /*int*/ cairo = OS.gdk_cairo_create(window);
- if (cairo == 0) error(SWT.ERROR_NO_HANDLES);
- Cairo.cairo_set_source_rgb(cairo, 1, 1, 1);
- Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_DIFFERENCE);
- if (image != null && !image.isDisposed() && image.mask == 0) {
- long /*int*/ surface = Cairo.cairo_get_target(cairo);
- int nWidth = 0;
- switch (Cairo.cairo_surface_get_type(surface)) {
- case Cairo.CAIRO_SURFACE_TYPE_IMAGE:
- nWidth = Cairo.cairo_image_surface_get_width(surface);
- break;
- case Cairo.CAIRO_SURFACE_TYPE_XLIB:
- nWidth = Cairo.cairo_xlib_surface_get_width(surface);
- break;
+ if (OS.GTK_VERSION < OS.VERSION (3, 22, 0)) {
+ long /*int*/ window = parent.paintWindow ();
+ if (OS.USE_CAIRO) {
+ long /*int*/ cairo = OS.gdk_cairo_create(window);
+ if (cairo == 0) error(SWT.ERROR_NO_HANDLES);
+ Cairo.cairo_set_source_rgb(cairo, 1, 1, 1);
+ Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_DIFFERENCE);
+ if (image != null && !image.isDisposed() && image.mask == 0) {
+ long /*int*/ surface = Cairo.cairo_get_target(cairo);
+ int nWidth = 0;
+ switch (Cairo.cairo_surface_get_type(surface)) {
+ case Cairo.CAIRO_SURFACE_TYPE_IMAGE:
+ nWidth = Cairo.cairo_image_surface_get_width(surface);
+ break;
+ case Cairo.CAIRO_SURFACE_TYPE_XLIB:
+ nWidth = Cairo.cairo_xlib_surface_get_width(surface);
+ break;
+ }
+ int nX = x;
+ if ((parent.style & SWT.MIRRORED) != 0) nX = parent.getClientWidth () - nWidth - nX;
+ Cairo.cairo_translate(cairo, nX, y);
+ Cairo.cairo_set_source_surface(cairo, image.surface, 0, 0);
+ Cairo.cairo_paint(cairo);
+ } else {
+ int nWidth = width, nHeight = height;
+ if (nWidth <= 0) nWidth = DEFAULT_WIDTH;
+ int nX = x;
+ if ((parent.style & SWT.MIRRORED) != 0) nX = parent.getClientWidth () - nWidth - nX;
+ Cairo.cairo_rectangle(cairo, nX, y, nWidth, nHeight);
+
}
- int nX = x;
- if ((parent.style & SWT.MIRRORED) != 0) nX = parent.getClientWidth () - nWidth - nX;
- Cairo.cairo_translate(cairo, nX, y);
- Cairo.cairo_set_source_surface(cairo, image.surface, 0, 0);
- Cairo.cairo_paint(cairo);
+ Cairo.cairo_fill(cairo);
+ Cairo.cairo_destroy(cairo);
+ return true;
+ }
+ long /*int*/ gc = OS.gdk_gc_new (window);
+ GdkColor color = new GdkColor ();
+ color.red = (short) 0xffff;
+ color.green = (short) 0xffff;
+ color.blue = (short) 0xffff;
+ long /*int*/ colormap = OS.gdk_colormap_get_system ();
+ OS.gdk_colormap_alloc_color (colormap, color, true, true);
+ OS.gdk_gc_set_foreground (gc, color);
+ OS.gdk_gc_set_function (gc, OS.GDK_XOR);
+ if (image != null && !image.isDisposed() && image.mask == 0) {
+ int[] width = new int[1]; int[] height = new int[1];
+ OS.gdk_pixmap_get_size (image.pixmap, width, height);
+ int nX = x;
+ if ((parent.style & SWT.MIRRORED) != 0) nX = parent.getClientWidth () - width[0] - nX;
+ OS.gdk_draw_drawable(window, gc, image.pixmap, 0, 0, nX, y, width[0], height[0]);
} else {
int nWidth = width, nHeight = height;
if (nWidth <= 0) nWidth = DEFAULT_WIDTH;
int nX = x;
if ((parent.style & SWT.MIRRORED) != 0) nX = parent.getClientWidth () - nWidth - nX;
- Cairo.cairo_rectangle(cairo, nX, y, nWidth, nHeight);
+ OS.gdk_draw_rectangle (window, gc, 1, nX, y, nWidth, nHeight);
}
- Cairo.cairo_fill(cairo);
- Cairo.cairo_destroy(cairo);
+ OS.g_object_unref (gc);
+ OS.gdk_colormap_free_colors (colormap, color, 1);
return true;
- }
- long /*int*/ gc = OS.gdk_gc_new (window);
- GdkColor color = new GdkColor ();
- color.red = (short) 0xffff;
- color.green = (short) 0xffff;
- color.blue = (short) 0xffff;
- long /*int*/ colormap = OS.gdk_colormap_get_system ();
- OS.gdk_colormap_alloc_color (colormap, color, true, true);
- OS.gdk_gc_set_foreground (gc, color);
- OS.gdk_gc_set_function (gc, OS.GDK_XOR);
- if (image != null && !image.isDisposed() && image.mask == 0) {
- int[] width = new int[1]; int[] height = new int[1];
- OS.gdk_pixmap_get_size (image.pixmap, width, height);
- int nX = x;
- if ((parent.style & SWT.MIRRORED) != 0) nX = parent.getClientWidth () - width[0] - nX;
- OS.gdk_draw_drawable(window, gc, image.pixmap, 0, 0, nX, y, width[0], height[0]);
} else {
- int nWidth = width, nHeight = height;
- if (nWidth <= 0) nWidth = DEFAULT_WIDTH;
- int nX = x;
- if ((parent.style & SWT.MIRRORED) != 0) nX = parent.getClientWidth () - nWidth - nX;
- OS.gdk_draw_rectangle (window, gc, 1, nX, y, nWidth, nHeight);
+ if (isDrawing) {
+ return false;
+ } else {
+ isDrawing = true;
+ OS.gtk_widget_queue_draw(parent.handle);
+ return true;
+ }
}
- OS.g_object_unref (gc);
- OS.gdk_colormap_free_colors (colormap, color, 1);
- return true;
}
/**

Back to the top