summaryrefslogtreecommitdiff
path: root/src/gtkext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-02-03 22:52:41 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-02-03 22:52:41 (GMT)
commitb99723a14b9bd4d81ed34fbc4195ae99f3adeabb (patch)
tree8c9cf9d410c6b60bd26ee25a7cba9626694413eb /src/gtkext
parentf6eb49749d627de7d556139a392f73f0ca2862e8 (diff)
Fixed the caret rendering for buffer displays.
Diffstat (limited to 'src/gtkext')
-rw-r--r--src/gtkext/gtkbufferdisplay.c161
1 files changed, 103 insertions, 58 deletions
diff --git a/src/gtkext/gtkbufferdisplay.c b/src/gtkext/gtkbufferdisplay.c
index d941ff2..e2335af 100644
--- a/src/gtkext/gtkbufferdisplay.c
+++ b/src/gtkext/gtkbufferdisplay.c
@@ -24,6 +24,9 @@
#include "gtkbufferdisplay.h"
+#include <assert.h>
+
+
#include "gtkbufferdisplay-int.h"
@@ -90,11 +93,17 @@ static bool _gtk_buffer_display_move_caret_to(GtkBufferDisplay *, gint, gint);
/* Déplace le curseur en effaçant son éventuelle position. */
static void gtk_buffer_display_relocate_caret(GtkBufferDisplay *, const cairo_rectangle_int_t *, const vmpa2t *);
+/* Assure le clignotement du curseur à l'emplacement courant. */
+static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *);
+
/* Redémarre l'affichage du curseur à l'emplacement courant. */
static void gtk_buffer_display_restart_caret_blinking(GtkBufferDisplay *);
-/* Bascule et relance l'affichage du curseur. */
-static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *);
+/* Prépare l'actualisation de tout ou une partie de l'affichage. */
+static void gtk_buffer_display_queue_draw_caret(GtkBufferDisplay *, cairo_rectangle_int_t *);
+
+/* Affiche le curseur à l'écran, s'il doit l'être. */
+static void gtk_buffer_display_draw_caret(GtkBufferDisplay *, cairo_t *);
@@ -252,7 +261,7 @@ static gboolean gtk_buffer_display_focus(GtkWidget *widget, GdkEventFocus *event
display->caret_timer = 0;
display->show_caret = true;
- gtk_buffer_display_refresh_caret(display);
+ gtk_buffer_display_queue_draw_caret(display, NULL);
}
@@ -342,6 +351,7 @@ static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr)
window = gtk_widget_get_window(widget);
cairo_save(cr);
+
gtk_cairo_transform_to_window(cr, widget, window);
region = gdk_window_get_clip_region(window);
@@ -435,17 +445,12 @@ static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr)
/* Curseur clignotant ? */
- /*
if (gtk_widget_is_focus(widget))
- {
- view->show_caret = !view->show_caret;
- gtk_buffer_display_refresh_caret(view);
- }
- */
+ gtk_buffer_display_draw_caret(display, cr);
cairo_restore(cr);
- return TRUE;
+ return FALSE;
}
@@ -942,19 +947,43 @@ static void gtk_buffer_display_relocate_caret(GtkBufferDisplay *display, const c
else
need_redraw = false;
+ if (!is_invalid_vmpa(&display->caret_addr))
+ gtk_buffer_display_restart_caret_blinking(display);
+
if (need_redraw)
- gtk_widget_queue_draw(GTK_WIDGET(display));
+ gtk_buffer_display_queue_draw_caret(display, NULL);
else if (clear_old)
- {
- gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(display), &old_area.x, &old_area.y);
+ gtk_buffer_display_queue_draw_caret(display, &old_area);
- gtk_widget_queue_draw_area(GTK_WIDGET(display), old_area.x, old_area.y,
- old_area.width, old_area.height);
+}
- }
- gtk_buffer_display_restart_caret_blinking(display);
+/******************************************************************************
+* *
+* Paramètres : display = composant GTK à manipuler. *
+* *
+* Description : Assure le clignotement du curseur à l'emplacement courant. *
+* *
+* Retour : TRUE pour poursuivre le clignotement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *display)
+{
+ /* Bascule l'affichage */
+ display->show_caret = !display->show_caret;
+
+ assert(!is_invalid_vmpa(&display->caret_addr));
+
+ if (!display->show_caret)
+ gtk_buffer_display_queue_draw_caret(display, &display->caret);
+ else
+ gtk_buffer_display_queue_draw_caret(display, NULL);
+
+ return TRUE;
}
@@ -985,18 +1014,17 @@ static void gtk_buffer_display_restart_caret_blinking(GtkBufferDisplay *display)
if (!is_invalid_vmpa(&display->caret_addr))
{
- display->show_caret = false;
- gtk_buffer_display_refresh_caret(display);
-
settings = gtk_settings_get_default();
g_object_get(settings, "gtk-cursor-blink-time", &interval, NULL);
+ display->show_caret = true;
+
g_object_ref(G_OBJECT(display));
- display->caret_timer = g_timeout_add_full(G_PRIORITY_DEFAULT, interval,
- (GSourceFunc)gtk_buffer_display_refresh_caret,
- display, g_object_unref);
+ display->caret_timer = gdk_threads_add_timeout_full(G_PRIORITY_DEFAULT, interval,
+ (GSourceFunc)gtk_buffer_display_refresh_caret,
+ display, g_object_unref);
}
@@ -1008,58 +1036,79 @@ static void gtk_buffer_display_restart_caret_blinking(GtkBufferDisplay *display)
/******************************************************************************
* *
* Paramètres : display = composant GTK à manipuler. *
+* area = emplacement du curseur ou NULL toute la région. *
* *
-* Description : Bascule et relance l'affichage du curseur. *
+* Description : Prépare l'actualisation de tout ou une partie de l'affichage.*
* *
-* Retour : TRUE pour poursuivre les basculements automatiques. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *display)
+static void gtk_buffer_display_queue_draw_caret(GtkBufferDisplay *display, cairo_rectangle_int_t *area)
{
GtkWidget *widget; /* Autre version du composant */
- GdkWindow *window; /* Fenêtre de support associée */
- cairo_rectangle_int_t area; /* Zone adaptée à traiter */
- cairo_region_t *region; /* Région définie associée */
- GdkDrawingContext *drawing; /* Mécanisme de dessins */
- cairo_t *cr; /* Contexte graphique */
- GdkRGBA *color; /* Couleur du curseur */
+ cairo_rectangle_int_t rect; /* Zone rectangulaire relative */
+ cairo_region_t *region; /* Zone précise à redessiner */
widget = GTK_WIDGET(display);
- window = gtk_widget_get_window(widget);
- /**
- * Si le composant n'est pas encore réalisé (ou caché, en cas de
- * basculement entre les types de vues), gdk_cairo_create() ne va
- * pas apprécier l'argument NULL. Donc on écourte l'opération.
- */
- if (window == NULL)
+ if (area == NULL)
+ gtk_widget_queue_draw(widget);
+
+ else
{
- display->show_caret = !display->show_caret;
- return TRUE;
- }
+ rect = *area;
+ gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(display), &rect.x, &rect.y);
- area = display->caret;
- gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(display), &area.x, &area.y);
+ region = cairo_region_create_rectangle(&rect);
+ gtk_widget_queue_draw_region(widget, region);
+ cairo_region_destroy(region);
- /* Réinitialisation de la surface */
- if (display->show_caret)
- {
- display->show_caret = false;
- gtk_widget_queue_draw_area(widget, area.x, area.y, area.width, area.height);
}
- /* Dessin */
- else
+ /**
+ * Pour une raison non comprise, le redessin n'est pris en compte que
+ * si le parent est concerné également...
+ */
+
+ widget = gtk_widget_get_parent(widget);
+
+ if (GTK_IS_SCROLLED_WINDOW(widget))
+ gtk_widget_queue_draw(widget);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : display = composant GTK à manipuler. *
+* cr = contexte graphique disponible pour l'opération. *
+* *
+* Description : Affiche le curseur à l'écran, s'il doit l'être. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_buffer_display_draw_caret(GtkBufferDisplay *display, cairo_t *cr)
+{
+ cairo_rectangle_int_t area; /* Zone adaptée à traiter */
+ cairo_region_t *region; /* Région définie associée */
+ GtkWidget *widget; /* Autre version du composant */
+ GdkRGBA *color; /* Couleur du curseur */
+
+ if (!is_invalid_vmpa(&display->caret_addr) && display->show_caret)
{
- display->show_caret = true;
+ area = display->caret;
+ gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(display), &area.x, &area.y);
region = cairo_region_create_rectangle(&area);
- drawing = gdk_window_begin_draw_frame(window, region);
- cr = gdk_drawing_context_get_cairo_context(drawing);
+ widget = GTK_WIDGET(display);
gtk_style_context_get(gtk_widget_get_style_context(widget),
gtk_widget_get_state_flags(widget),
@@ -1070,12 +1119,8 @@ static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *display)
cairo_rectangle(cr, area.x, area.y, area.width, area.height);
cairo_fill(cr);
- gdk_window_end_draw_frame(window, drawing);
-
cairo_region_destroy(region);
}
- return TRUE;
-
}