[gtksourceview/wip/chergert/minimap-cleanup] more modernization to GtkSourceMap



commit 3d5474facee87a6196fc75a111c523b9b9ef8135
Author: Christian Hergert <christian hergert me>
Date:   Wed May 20 18:51:42 2015 -0700

    more modernization to GtkSourceMap

 gtksourceview/gtksourcemap.c |  443 +++++++++++++++++++++++++-----------------
 1 files changed, 268 insertions(+), 175 deletions(-)
---
diff --git a/gtksourceview/gtksourcemap.c b/gtksourceview/gtksourcemap.c
index 161dfed..63f8b67 100644
--- a/gtksourceview/gtksourcemap.c
+++ b/gtksourceview/gtksourcemap.c
@@ -18,11 +18,11 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-
 #include "gtksourcemap.h"
 #include "gtksourceview-utils.h"
 
 #include <glib/gi18n.h>
+#include <string.h>
 
 /**
  * SECTION:map
@@ -44,6 +44,13 @@
  * #GtkSourceMap derives from #GtkBin only as an implementation detail. Applications
  * should not use any API specific to #GtkBin to operate on this object. It should
  * be treated as a normal #GtkWidget.
+ *
+ * Additionally, it is desirable to match the font of the #GtkSourceMap and
+ * the #GtkSourceView used for editing. Therefore, #GtkSourceMap:font-desc
+ * should be used to set the target font. You will need to adjust this to the
+ * desired font size for the map. A 1pt generally seems to be an appropriate
+ * font size. See pango_font_description_set_size() for how to alter the size
+ * of an existing #PangoFontDescription.
  */
 
 /*
@@ -79,55 +86,80 @@
  * GtkTextView::draw_layer() vfunc. The problem with this approach is that
  * the scrubber contents are actually pixel cached. So every time the scrubber
  * moves we have to invalidate the GtkTextLayout and redraw cached contents.
- * Where as using an overlay widget allows us to simply perform an alpha blend
- * during the composite phase. The pixel cache'd GtkSourceView contents remain
- * unchanged, and there continue to essentially be a memcpy().
+ * Where as drawing in the GtkTextView::draw() vfunc, after the pixel cache
+ * contents have been drawn results in only a composite blend, not
+ * invalidating any of the pixel cached text layouts.
  *
  * In the future, we might consider bundling a custom font for the source map.
  * Other overview maps have used a "block" font. However, they typically do
  * that because of the glyph rendering cost. Since we have pixel cache, that
  * deficiency is largely a non-issue. But Pango recently got support for
  * embedding fonts in the application, so it is at least possible to bundle
- * our own font.
+ * our own font as a resource.
  *
  * -- Christian
  */
 
-#define DEFAULT_WIDTH        100
-#define CONCEAL_TIMEOUT      2000
+#define DEFAULT_WIDTH 100
+#define CSS_PRIORITY (GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - 1)
 
 typedef struct
 {
+       /*
+        * By default, we use "Monospace 1pt". However, most text editing
+        * applications will have a custom font, so we allow them to set
+        * that here. Generally speaking, you will want to continue using
+        * a 1pt font, but if they set GtkSourceMap:font-desc, then they
+        * should also shrink the font to the desired size.
+        *
+        * For example:
+        *   pango_font_description_set_size(font_desc, 1 * PANGO_SCALE);
+        *
+        * Would set a 1pt font on whatever PangoFontDescription you have
+        * in your text editor.
+        */
        PangoFontDescription *font_desc;
 
        /*
-        * We use a separate CSS provider for the view (controlling the font)
-        * and the overlay box due to the inability to get both styled
-        * correctly from the same CSS provider. If someone can determine
-        * the cause of this, we should merge them into a single provider.
+        * The easiest way to style the scrubber and the sourceview is
+        * by using CSS. This is necessary since we can't mess with the
+         * fonts used in the textbuffer (as one might using GtkTextTag).
         */
        GtkCssProvider *css_provider;
 
        /*
-        * This is our minimap widget. We adjust the font to be a 1pt font
-        * but otherwise try to render things as close to the same as the
-        * view we are providing a map of. We do not render the background
-        * grid as it requires a lot of cpu time and isn't visible anyway.
-        * The width of the view is controlled by "right-margin-position"
-        * multiplied by the size of a single character. Content that wraps
-        * beyond right-margin-position is not displayed.
+        * This is our minimap widget. By default we use a 1pt Monospace
+        * font. However, if the Gtksourcemap:font-desc property is set,
+        * we will use that instead.
+        *
+        * We do not render the background grid as it requires a bunch of
+        * cpu time for something that will essentially just create a solid
+        * color background.
+        *
+        * The width of the view is determined by the
+        * #GtkSourceView:right-margin-position. We cache the width of a
+        * single "X" character and multiple that by the right-margin-position.
+        * That becomes our size-request width.
+        *
+        * We do not allow horizontal scrolling so that the overflow text
+        * is simply not visible in the minimap.
         */
        GtkSourceView *child_view;
 
        /* The GtkSourceView we are providing a map of */
        GtkSourceView *view;
 
-       /*
-        * The location of the scrubber in widget coordinate space.
-        */
+       /* The location of the scrubber in widget coordinate space. */
        GdkRectangle scrubber_area;
 
-       gboolean in_press : 1;
+       /* Our signal handler for buffer changes */
+       gulong view_notify_buffer_handler;
+
+       /* Our signal handler for style-scheme changes */
+       gulong buffer_notify_style_scheme_handler;
+
+       /* Denotes if we are in a grab from button press */
+       guint in_press : 1;
 } GtkSourceMapPrivate;
 
 enum
@@ -148,11 +180,12 @@ update_scrubber_position (GtkSourceMap *map)
        GtkSourceMapPrivate *priv;
        GtkTextIter iter;
        GdkRectangle visible_area;
-       GdkRectangle loc;
-       GtkAllocation our_alloc;
-        GdkRectangle old_pos;
+       GdkRectangle iter_area;
+        GdkRectangle scrubber_area;
+       GtkAllocation alloc;
        gint child_height;
        gint view_height;
+        gint y;
 
        priv = gtk_source_map_get_instance_private (map);
 
@@ -161,33 +194,30 @@ update_scrubber_position (GtkSourceMap *map)
                return;
        }
 
-       old_pos = priv->scrubber_area;
-
-       gtk_widget_get_preferred_height (GTK_WIDGET (priv->view),
-                                        NULL, &view_height);
-       gtk_widget_get_preferred_height (GTK_WIDGET (priv->child_view),
-                                        NULL, &child_height);
-
-       gtk_widget_get_allocation (GTK_WIDGET (map), &our_alloc);
+       gtk_widget_get_allocation (GTK_WIDGET (map), &alloc);
 
-       priv->scrubber_area.x = 0;
-       priv->scrubber_area.width = our_alloc.width;
-       priv->scrubber_area.height = (our_alloc.height / (gdouble)view_height) * child_height;
+       gtk_widget_get_preferred_height (GTK_WIDGET (priv->view), NULL, &view_height);
+       gtk_widget_get_preferred_height (GTK_WIDGET (priv->child_view), NULL, &child_height);
 
-       gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (priv->view),
-                                       &visible_area);
-       gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (priv->view),
-                                           &iter, visible_area.x,
-                                           visible_area.y);
-       gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->child_view),
-                                        &iter, &loc);
+       gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (priv->view), &visible_area);
+       gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (priv->view), &iter,
+                                           visible_area.x, visible_area.y);
+       gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->child_view), &iter, &iter_area);
        gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (priv->child_view),
                                               GTK_TEXT_WINDOW_WIDGET,
-                                              loc.x, loc.y,
-                                              NULL, &priv->scrubber_area.y);
+                                              iter_area.x, iter_area.y,
+                                              NULL, &y);
 
-       if (memcmp (&old_pos, &priv->scrubber_area, sizeof old_pos) != 0)
+       scrubber_area.x = 0;
+       scrubber_area.width = alloc.width;
+       scrubber_area.y = y;
+       scrubber_area.height = (alloc.height / (gdouble)view_height) * child_height;
+
+       if (memcmp (&scrubber_area, &priv->scrubber_area, sizeof scrubber_area) != 0)
+       {
+               priv->scrubber_area = scrubber_area;
                gtk_widget_queue_draw (GTK_WIDGET (map));
+       }
 }
 
 static void
@@ -195,10 +225,11 @@ gtk_source_map_rebuild_css (GtkSourceMap *map)
 {
        GtkSourceMapPrivate *priv;
        GtkSourceStyleScheme *style_scheme;
+       GtkSourceStyle *style = NULL;
        GtkTextBuffer *buffer;
        GString *gstr;
-
-       g_print ("rebuild css\n");
+       gboolean alter_alpha = TRUE;
+       gchar *background = NULL;
 
        priv = gtk_source_map_get_instance_private (map);
 
@@ -207,8 +238,34 @@ gtk_source_map_rebuild_css (GtkSourceMap *map)
                return;
        }
 
+       /*
+        * This is where we calculate the CSS that maps the font for the
+        * minimap as well as the styling for the scrubber.
+        *
+        * The font is calculated from #GtkSourceMap:font-desc. We convert this
+        * to CSS using _gtk_source_pango_font_description_to_css(). It gets
+        * applied to the minimap widget via the CSS style provider which we
+        * attach to the child widget in gtk_source_map_init().
+        *
+        * The rules for calculating the style for the scrubber are as follows.
+        *
+        * If the current style scheme provides a background color for the
+        * scrubber using the "map-overlay" style name, we use that without
+        * any transformations.
+        *
+        * If the style scheme contains a "selection" style scheme, used for
+        * selected text, we use that with a 0.45 alpha value.
+        *
+        * If none of these are met, we take the background from the
+        * #GtkStyleContext using the deprecated
+        * gtk_style_context_get_background_color(). This is non-ideal, but
+        * currently required since we cannot indicate that we want to
+        * alter the alpha for gtk_render_background().
+        */
+
        gstr = g_string_new (NULL);
 
+       /* Calculate the font if one has been set */
        if (priv->font_desc != NULL)
        {
                gchar *css;
@@ -223,70 +280,86 @@ gtk_source_map_rebuild_css (GtkSourceMap *map)
 
        if (style_scheme != NULL)
        {
-               gchar *background = NULL;
-               GtkSourceStyle *style;
-               gboolean change_alpha = FALSE;
 
                style = gtk_source_style_scheme_get_style (style_scheme, "map-overlay");
-               if (style == NULL)
-               {
-                       style = gtk_source_style_scheme_get_style (style_scheme, "selection");
-                       change_alpha = TRUE;
-               }
-               if (style == NULL)
+
+               if (style != NULL)
                {
-                       GtkStyleContext *context;
-                       GdkRGBA color;
-
-                       context = gtk_widget_get_style_context (GTK_WIDGET (priv->view));
-                       gtk_style_context_save (context);
-                       gtk_style_context_add_class (context, "view");
-                       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
-                       gtk_style_context_get_background_color (context,
-                                                               GTK_STATE_FLAG_SELECTED,
-                                                               &color);
-                       G_GNUC_END_IGNORE_DEPRECATIONS;
-                       gtk_style_context_restore (context);
-                       background = gdk_rgba_to_string (&color);
+                       /* styling is taking as is only if we found a "map-overlay". */
+                       alter_alpha = FALSE;
                }
                else
                {
-                       g_object_get (style,
-                                     "background", &background,
-                                     NULL);
+                       style = gtk_source_style_scheme_get_style (style_scheme, "selection");
                }
+       }
 
-               if (change_alpha)
-               {
-                       GdkRGBA color;
-                       gdk_rgba_parse (&color, background);
-                       color.alpha = 0.45;
-                       g_free (background);
-                       background = gdk_rgba_to_string (&color);
-               }
+       if (style != NULL)
+       {
+               g_object_get (style,
+                             "background", &background,
+                             NULL);
+       }
 
+       if (background == NULL)
+       {
+               GtkStyleContext *context;
+               GdkRGBA color;
+
+               /*
+                * We failed to locate a style for both "map-overlay" and for
+                * "selection". That means we need to fallback to using the
+                * selected color for the gtk+ theme. This uses deprecated
+                * API because we have no way to tell gtk_render_background()
+                * to render with an alpha.
+                */
+
+               context = gtk_widget_get_style_context (GTK_WIDGET (priv->view));
+               gtk_style_context_save (context);
+               gtk_style_context_add_class (context, "view");
+               G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+               gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED, &color);
+               G_GNUC_END_IGNORE_DEPRECATIONS;
+               gtk_style_context_restore (context);
+               background = gdk_rgba_to_string (&color);
+
+               /*
+                * Make sure we alter the alpha. It is possible this could be
+                * FALSE here if we found a style for map-overlay but it did
+                * not contain a background color.
+                */
+               alter_alpha = TRUE;
+       }
 
-               if (background != NULL)
-               {
-                       g_string_append_printf (gstr,
-                                               "GtkSourceMap.scrubber {\n"
-                                               "\tbackground-color: %s;\n"
-                                               "\tborder-top: 1px solid shade(%s,0.9);\n"
-                                               "\tborder-bottom: 1px solid shade(%s,0.9);\n"
-                                               "}\n",
-                                               background,
-                                               background,
-                                               background);
-               }
+       if (alter_alpha)
+       {
+               GdkRGBA color;
 
+               gdk_rgba_parse (&color, background);
+               color.alpha = 0.45;
                g_free (background);
+               background = gdk_rgba_to_string (&color);
+       }
+
+
+       if (background != NULL)
+       {
+               g_string_append_printf (gstr,
+                                       "GtkSourceMap.scrubber {\n"
+                                       "\tbackground-color: %s;\n"
+                                       "\tborder-top: 1px solid shade(%s,0.9);\n"
+                                       "\tborder-bottom: 1px solid shade(%s,0.9);\n"
+                                       "}\n",
+                                       background,
+                                       background,
+                                       background);
        }
 
+       g_free (background);
+
        if (gstr->len > 0)
        {
-               gtk_css_provider_load_from_data (priv->css_provider,
-                                                gstr->str, gstr->len, NULL);
-g_print ("%s\n", gstr->str);
+               gtk_css_provider_load_from_data (priv->css_provider, gstr->str, gstr->len, NULL);
        }
 
        g_string_free (gstr, TRUE);
@@ -301,7 +374,6 @@ update_child_vadjustment (GtkSourceMap *map)
        gdouble value;
        gdouble upper;
        gdouble page_size;
-       gdouble child_value;
        gdouble child_upper;
        gdouble child_page_size;
        gdouble new_value = 0.0;
@@ -309,22 +381,21 @@ update_child_vadjustment (GtkSourceMap *map)
        priv = gtk_source_map_get_instance_private (map);
 
        vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (priv->view));
-       child_vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (priv->child_view));
-
        g_object_get (vadj,
                      "upper", &upper,
                      "value", &value,
                      "page-size", &page_size,
                      NULL);
 
+       child_vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (priv->child_view));
        g_object_get (child_vadj,
                      "upper", &child_upper,
-                     "value", &child_value,
                      "page-size", &child_page_size,
                      NULL);
 
        /*
-        * TODO: Technically we should take into account lower here, but in practice
+        * FIXME:
+         * Technically we should take into account lower here, but in practice
         *       it is always 0.0.
         */
        if (child_page_size < child_upper)
@@ -356,7 +427,6 @@ buffer_notify_style_scheme (GtkSourceMap  *map,
                             GParamSpec    *pspec,
                             GtkTextBuffer *buffer)
 {
-g_print ("Notify style scheme\n");
        gtk_source_map_rebuild_css (map);
 }
 
@@ -367,7 +437,6 @@ view_notify_buffer (GtkSourceMap  *map,
 {
        GtkTextBuffer *buffer;
 
-  g_print ("view_notify_buffer\n");
        buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
        g_signal_connect_object (buffer,
                                 "notify::style-scheme",
@@ -423,7 +492,6 @@ gtk_source_map_get_preferred_width (GtkWidget *widget,
        GtkSourceMap *map = GTK_SOURCE_MAP (widget);
        GtkSourceMapPrivate *priv;
        PangoLayout *layout;
-       guint right_margin_position;
        gint height;
        gint width;
 
@@ -435,12 +503,18 @@ gtk_source_map_get_preferred_width (GtkWidget *widget,
                return;
        }
 
+       /*
+        * FIXME:
+        *
+        * This seems like the type of thing we should calculate when
+        * rebuilding our CSS since it gets used a bunch and changes
+        * very little.
+        */
        layout = gtk_widget_create_pango_layout (GTK_WIDGET (priv->child_view), "X");
        pango_layout_get_pixel_size (layout, &width, &height);
        g_object_unref (layout);
 
-       right_margin_position = gtk_source_view_get_right_margin_position (priv->view);
-       width *= right_margin_position;
+       width *= gtk_source_view_get_right_margin_position (priv->view);
 
        *mininum_width = *natural_width = width;
 }
@@ -467,10 +541,14 @@ gtk_source_map_get_preferred_height (GtkWidget *widget,
        *minimum_height = 0;
 }
 
-static gboolean
-child_view_button_press_event (GtkSourceMap   *map,
-                               GdkEventButton *event,
-                               GtkSourceView  *child_view)
+/*
+ * This scrolls using buffer coordinates.
+ * Translate your event location to a buffer coordinate before
+ * calling this function.
+ */
+static void
+scroll_to_child_point (GtkSourceMap   *map,
+                       const GdkPoint *point)
 {
        GtkSourceMapPrivate *priv;
 
@@ -478,20 +556,17 @@ child_view_button_press_event (GtkSourceMap   *map,
 
        if (priv->view != NULL)
        {
+               GtkAllocation alloc;
                GtkTextIter iter;
-               gint x;
-               gint y;
-
-               gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (child_view),
-                                                      GTK_TEXT_WINDOW_WIDGET,
-                                                      event->x, event->y, &x, &y);
-               gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (child_view),
-                                                   &iter, x, y);
+
+               gtk_widget_get_allocation (GTK_WIDGET (map), &alloc);
+
+               gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (priv->child_view),
+                                                   &iter, point->x, point->y);
+
                gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->view), &iter,
                                              0.0, TRUE, 1.0, 0.5);
        }
-
-       return GDK_EVENT_STOP;
 }
 
 static void
@@ -517,41 +592,52 @@ child_view_realize_after (GtkWidget *widget,
 }
 
 static gboolean
-overlay_box_button_press_event (GtkSourceMap   *map,
-                                GdkEventButton *event,
-                                GtkEventBox    *overlay_box)
+child_view_button_press_event (GtkSourceMap   *map,
+                               GdkEventButton *event,
+                               GtkSourceView  *child_view)
 {
        GtkSourceMapPrivate *priv;
+       GdkPoint point;
 
        priv = gtk_source_map_get_instance_private (map);
 
-       gtk_grab_add (GTK_WIDGET (overlay_box));
+       point.x = event->x;
+       point.y = event->y;
+
+       gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (priv->child_view),
+                                              GTK_TEXT_WINDOW_WIDGET,
+                                              event->x, event->y,
+                                              &point.x, &point.y);
+
+       scroll_to_child_point (map, &point);
+
+       gtk_grab_add (GTK_WIDGET (child_view));
 
        priv->in_press = TRUE;
 
-       return GDK_EVENT_PROPAGATE;
+       return GDK_EVENT_STOP;
 }
 
 static gboolean
-overlay_box_button_release_event (GtkSourceMap   *map,
-                                  GdkEventButton *event,
-                                  GtkEventBox    *overlay_box)
+child_view_button_release_event (GtkSourceMap   *map,
+                                 GdkEventButton *event,
+                                 GtkSourceView  *child_view)
 {
        GtkSourceMapPrivate *priv;
 
        priv = gtk_source_map_get_instance_private (map);
 
-       priv->in_press = FALSE;
+       gtk_grab_remove (GTK_WIDGET (child_view));
 
-       gtk_grab_remove (GTK_WIDGET (overlay_box));
+       priv->in_press = FALSE;
 
-       return GDK_EVENT_PROPAGATE;
+       return GDK_EVENT_STOP;
 }
 
 static gboolean
-overlay_box_motion_notify_event (GtkSourceMap   *map,
-                                 GdkEventMotion *event,
-                                 GtkEventBox    *overlay_box)
+child_view_motion_notify_event (GtkSourceMap   *map,
+                                GdkEventMotion *event,
+                                GtkSourceView  *child_view)
 {
        GtkSourceMapPrivate *priv;
 
@@ -559,42 +645,28 @@ overlay_box_motion_notify_event (GtkSourceMap   *map,
 
        if (priv->in_press && (priv->view != NULL))
        {
-               GtkAllocation alloc;
-               GtkAllocation child_alloc;
                GtkTextBuffer *buffer;
-               GdkRectangle rect;
+               GtkAllocation alloc;
+               GdkRectangle area;
                GtkTextIter iter;
-               gdouble ratio;
-               gint child_height;
-               gint x;
-               gint y;
+               GdkPoint point;
+               gdouble yratio;
 
-               gtk_widget_get_allocation (GTK_WIDGET (overlay_box), &alloc);
-               gtk_widget_get_allocation (GTK_WIDGET (priv->child_view), &child_alloc);
+               gtk_widget_get_allocation (GTK_WIDGET (child_view), &alloc);
 
-               gtk_widget_translate_coordinates (GTK_WIDGET (overlay_box),
-                                                 GTK_WIDGET (priv->child_view),
-                                                 event->x, event->y, &x, &y);
-
-               buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->child_view));
+               buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (child_view));
                gtk_text_buffer_get_end_iter (buffer, &iter);
-               gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->child_view),
-                                                &iter, &rect);
-
-               child_height = MIN (child_alloc.height, (rect.y + rect.height));
+               gtk_text_view_get_iter_location (GTK_TEXT_VIEW (child_view), &iter, &area);
 
-               y = CLAMP (y, child_alloc.y, child_alloc.y + child_height) - child_alloc.y;
-               ratio = (gdouble)y / (gdouble)child_height;
-               y = (rect.y + rect.height) * ratio;
+                yratio = CLAMP (event->y - alloc.y, 0, alloc.height) / (gdouble)alloc.height;
 
-               gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (priv->child_view),
-                                                   &iter, x, y);
+               point.x = 0;
+               point.y = (area.y + area.height) * yratio;
 
-               gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->view), &iter,
-                                             0.0, TRUE, 1.0, 0.5);
+               scroll_to_child_point (map, &point);
        }
 
-       return GDK_EVENT_PROPAGATE;
+       return GDK_EVENT_STOP;
 }
 
 static void
@@ -609,9 +681,9 @@ gtk_source_map_size_allocate (GtkWidget     *widget,
 }
 
 static gboolean
-gtk_source_map_do_scroll_event (GtkSourceMap   *map,
-                                GdkEventScroll *event,
-                                GtkWidget      *widget)
+child_view_scroll_event (GtkSourceMap   *map,
+                         GdkEventScroll *event,
+                         GtkWidget      *widget)
 {
        GtkSourceMapPrivate *priv;
        static const gint scroll_acceleration = 4;
@@ -619,8 +691,10 @@ gtk_source_map_do_scroll_event (GtkSourceMap   *map,
        priv = gtk_source_map_get_instance_private (map);
 
        /*
-        * TODO: This doesn't propagate kinetic scrolling or anything.
-        *       We should probably make something that does that.
+        * FIXME:
+        *
+        * This doesn't propagate kinetic scrolling or anything.
+        * We should probably make something that does that.
         */
        if (priv->view != NULL)
        {
@@ -654,6 +728,7 @@ gtk_source_map_do_scroll_event (GtkSourceMap   *map,
                {
                        g_signal_emit_by_name (priv->view, "move-viewport",
                                               GTK_SCROLL_STEPS, count);
+                       return GDK_EVENT_STOP;
                }
        }
 
@@ -798,6 +873,13 @@ gtk_source_map_init (GtkSourceMap *map)
 
        priv = gtk_source_map_get_instance_private (map);
 
+       priv->css_provider = gtk_css_provider_new ();
+
+       context = gtk_widget_get_style_context (GTK_WIDGET (map));
+       gtk_style_context_add_provider (context,
+                                       GTK_STYLE_PROVIDER (priv->css_provider),
+                                       CSS_PRIORITY);
+
        priv->child_view = g_object_new (GTK_SOURCE_TYPE_VIEW,
                                         "auto-indent", FALSE,
                                         "can-focus", FALSE,
@@ -811,6 +893,11 @@ gtk_source_map_init (GtkSourceMap *map)
                                         "visible", TRUE,
                                         NULL);
 
+       context = gtk_widget_get_style_context (GTK_WIDGET (priv->child_view));
+       gtk_style_context_add_provider (context,
+                                       GTK_STYLE_PROVIDER (priv->css_provider),
+                                       CSS_PRIORITY);
+
        g_signal_connect_object (priv->child_view,
                                 "button-press-event",
                                 G_CALLBACK (child_view_button_press_event),
@@ -819,7 +906,7 @@ gtk_source_map_init (GtkSourceMap *map)
        gtk_widget_add_events (GTK_WIDGET (priv->child_view), GDK_SCROLL_MASK);
        g_signal_connect_object (priv->child_view,
                                 "scroll-event",
-                                G_CALLBACK (gtk_source_map_do_scroll_event),
+                                G_CALLBACK (child_view_scroll_event),
                                 map,
                                 G_CONNECT_SWAPPED);
        g_signal_connect_object (priv->child_view,
@@ -832,16 +919,22 @@ gtk_source_map_init (GtkSourceMap *map)
                                 G_CALLBACK (child_view_realize_after),
                                 map,
                                 G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+       g_signal_connect_object (priv->child_view,
+                                "button-press-event",
+                                G_CALLBACK (child_view_button_press_event),
+                                map,
+                                G_CONNECT_SWAPPED);
+       g_signal_connect_object (priv->child_view,
+                                "button-release-event",
+                                G_CALLBACK (child_view_button_release_event),
+                                map,
+                                G_CONNECT_SWAPPED);
+       g_signal_connect_object (priv->child_view,
+                                "motion-notify-event",
+                                G_CALLBACK (child_view_motion_notify_event),
+                                map,
+                                G_CONNECT_SWAPPED);
 
-       priv->css_provider = gtk_css_provider_new ();
-       context = gtk_widget_get_style_context (GTK_WIDGET (map));
-       gtk_style_context_add_provider (context,
-                                       GTK_STYLE_PROVIDER (priv->css_provider),
-                                       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-       context = gtk_widget_get_style_context (GTK_WIDGET (priv->child_view));
-       gtk_style_context_add_provider (context,
-                                       GTK_STYLE_PROVIDER (priv->css_provider),
-                                       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
        gtk_container_add (GTK_CONTAINER (map), GTK_WIDGET (priv->child_view));
 
        completion = gtk_source_view_get_completion (priv->child_view);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]