]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkscrolledwindow.c
scrolled-window: fix rendering of scrolled window background
[~andy/gtk] / gtk / gtkscrolledwindow.c
index dd4b71f9cab102666425148877b4ebbf55e6f8d2..cd9c2666e2f9b0f6858546df437654f9c69677a8 100644 (file)
@@ -274,6 +274,10 @@ static void  gtk_scrolled_window_realize               (GtkWidget           *wid
 static void  gtk_scrolled_window_unrealize             (GtkWidget           *widget);
 static void  gtk_scrolled_window_map                   (GtkWidget           *widget);
 static void  gtk_scrolled_window_unmap                 (GtkWidget           *widget);
+static void  gtk_scrolled_window_state_flags_changed   (GtkWidget           *widget,
+                                                        GtkStateFlags        previous_state);
+static void  gtk_scrolled_window_style_updated         (GtkWidget           *widget);
+
 static void  gtk_scrolled_window_grab_notify           (GtkWidget           *widget,
                                                         gboolean             was_grabbed);
 
@@ -348,6 +352,8 @@ gtk_scrolled_window_class_init (GtkScrolledWindowClass *class)
   widget_class->unrealize = gtk_scrolled_window_unrealize;
   widget_class->map = gtk_scrolled_window_map;
   widget_class->unmap = gtk_scrolled_window_unmap;
+  widget_class->state_flags_changed = gtk_scrolled_window_state_flags_changed;
+  widget_class->style_updated = gtk_scrolled_window_style_updated;
   widget_class->grab_notify = gtk_scrolled_window_grab_notify;
 
   container_class->add = gtk_scrolled_window_add;
@@ -1433,18 +1439,45 @@ gtk_scrolled_window_draw_scrollbars_junction (GtkScrolledWindow *scrolled_window
                                               cairo_t *cr)
 {
   GtkScrolledWindowPrivate *priv = scrolled_window->priv;
+  GtkWidget *widget = GTK_WIDGET (scrolled_window);
   GtkAllocation wid_allocation, hscr_allocation, vscr_allocation;
   GtkStyleContext *context;
   GdkRectangle junction_rect;
-  gboolean is_rtl;
+  gboolean is_rtl, scrollbars_within_bevel;
 
-  is_rtl = gtk_widget_get_direction (GTK_WIDGET (scrolled_window)) == GTK_TEXT_DIR_RTL;
-  gtk_widget_get_allocation (GTK_WIDGET (scrolled_window), &wid_allocation);
+  is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+  gtk_widget_get_allocation (widget, &wid_allocation);
   gtk_widget_get_allocation (GTK_WIDGET (priv->hscrollbar), &hscr_allocation);
   gtk_widget_get_allocation (GTK_WIDGET (priv->vscrollbar), &vscr_allocation);
 
-  junction_rect.x = 0;
-  junction_rect.y = 0;
+  gtk_widget_style_get (widget,
+                        "scrollbars-within-bevel", &scrollbars_within_bevel,
+                        NULL);
+  context = gtk_widget_get_style_context (widget);
+
+  if (scrollbars_within_bevel &&
+      priv->shadow_type != GTK_SHADOW_NONE)
+    {
+      GtkStateFlags state;
+      GtkBorder padding, border;
+
+      state = gtk_widget_get_state_flags (widget);
+
+      gtk_style_context_save (context);
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_FRAME);
+      gtk_style_context_get_padding (context, state, &padding);
+      gtk_style_context_get_border (context, state, &border);
+      gtk_style_context_restore (context);
+
+      junction_rect.x = padding.left + border.left;
+      junction_rect.y = padding.top + border.top;
+    }
+  else
+    {
+      junction_rect.x = 0;
+      junction_rect.y = 0;
+    }
+
   junction_rect.width = vscr_allocation.width;
   junction_rect.height = hscr_allocation.height;
   
@@ -1454,13 +1487,12 @@ gtk_scrolled_window_draw_scrollbars_junction (GtkScrolledWindow *scrolled_window
       (!is_rtl && 
        (priv->real_window_placement == GTK_CORNER_TOP_LEFT ||
         priv->real_window_placement == GTK_CORNER_BOTTOM_LEFT)))
-    junction_rect.x = hscr_allocation.width;
+    junction_rect.x += hscr_allocation.width;
 
   if (priv->real_window_placement == GTK_CORNER_TOP_LEFT ||
       priv->real_window_placement == GTK_CORNER_TOP_RIGHT)
-    junction_rect.y = vscr_allocation.height;
+    junction_rect.y += vscr_allocation.height;
 
-  context = gtk_widget_get_style_context (GTK_WIDGET (scrolled_window));
   gtk_style_context_save (context);
   gtk_style_context_add_class (context, GTK_STYLE_CLASS_SCROLLBARS_JUNCTION);
 
@@ -1481,32 +1513,14 @@ gtk_scrolled_window_draw (GtkWidget *widget,
   GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
   GtkScrolledWindowPrivate *priv = scrolled_window->priv;
   GtkAllocation relative_allocation;
-  cairo_pattern_t *pattern = NULL;
   GtkStyleContext *context;
-  GtkWidget *child;
 
   context = gtk_widget_get_style_context (widget);
   gtk_scrolled_window_relative_allocation (widget, &relative_allocation);
 
-  /* Use child's background if possible */
-  child = gtk_bin_get_child (GTK_BIN (widget));
-
-  if (child && gtk_widget_get_has_window (child))
-    pattern = gdk_window_get_background_pattern (gtk_widget_get_window (child));
-
-  if (pattern &&
-      cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID)
-    {
-      cairo_set_source (cr, pattern);
-
-      cairo_rectangle (cr, relative_allocation.x, relative_allocation.y,
-                       relative_allocation.width, relative_allocation.height);
-      cairo_fill (cr);
-    }
-  else
-    gtk_render_background (context, cr,
-                           relative_allocation.x, relative_allocation.y,
-                           relative_allocation.width, relative_allocation.height);
+  gtk_render_background (context, cr,
+                         0, 0,
+                         gtk_widget_get_allocated_width (widget), gtk_widget_get_allocated_height (widget));
 
   if (priv->hscrollbar_visible && 
       priv->vscrollbar_visible)
@@ -2252,9 +2266,10 @@ gtk_scrolled_window_scroll_event (GtkWidget      *widget,
   gboolean handled = FALSE;
   gdouble delta_x;
   gdouble delta_y;
+  gdouble delta;
 
   g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);  
+  g_return_val_if_fail (event != NULL, FALSE);
 
   scrolled_window = GTK_SCROLLED_WINDOW (widget);
   priv = scrolled_window->priv;
@@ -2266,10 +2281,14 @@ gtk_scrolled_window_scroll_event (GtkWidget      *widget,
         {
           GtkAdjustment *adj;
           gdouble new_value;
+          gdouble page_size;
+          gdouble scroll_unit;
 
           adj = gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar));
+          page_size = gtk_adjustment_get_page_size (adj);
+          scroll_unit = pow (page_size, 2.0 / 3.0);
 
-          new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_x,
+          new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_x * scroll_unit,
                              gtk_adjustment_get_lower (adj),
                              gtk_adjustment_get_upper (adj) -
                              gtk_adjustment_get_page_size (adj));
@@ -2284,10 +2303,14 @@ gtk_scrolled_window_scroll_event (GtkWidget      *widget,
         {
           GtkAdjustment *adj;
           gdouble new_value;
+          gdouble page_size;
+          gdouble scroll_unit;
 
           adj = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar));
+          page_size = gtk_adjustment_get_page_size (adj);
+          scroll_unit = pow (page_size, 2.0 / 3.0);
 
-          new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_y,
+          new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_y * scroll_unit,
                              gtk_adjustment_get_lower (adj),
                              gtk_adjustment_get_upper (adj) -
                              gtk_adjustment_get_page_size (adj));
@@ -2309,7 +2332,7 @@ gtk_scrolled_window_scroll_event (GtkWidget      *widget,
       if (range && gtk_widget_get_visible (range))
         {
           GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (range));
-          gdouble delta, new_value;
+          gdouble new_value;
 
           delta = _gtk_range_get_wheel_delta (GTK_RANGE (range), event);
 
@@ -3410,6 +3433,37 @@ gtk_scrolled_window_unmap (GtkWidget *widget)
   GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->unmap (widget);
 }
 
+static void
+_gtk_scrolled_window_update_background (GtkScrolledWindow *scrolled_window)
+{
+  GtkWidget *widget = GTK_WIDGET (scrolled_window);
+
+  if (gtk_widget_get_realized (widget))
+    {
+      GtkStyleContext *context;
+
+      context = gtk_widget_get_style_context (widget);
+      gtk_style_context_set_background (context, scrolled_window->priv->overshoot_window);
+    }
+}
+
+static void
+gtk_scrolled_window_state_flags_changed (GtkWidget     *widget,
+                                         GtkStateFlags  previous_state)
+{
+  _gtk_scrolled_window_update_background (GTK_SCROLLED_WINDOW (widget));
+  gtk_widget_queue_draw (widget);
+}
+
+static void
+gtk_scrolled_window_style_updated (GtkWidget *widget)
+{
+  GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->style_updated (widget);
+
+  _gtk_scrolled_window_update_background (GTK_SCROLLED_WINDOW (widget));
+  gtk_widget_queue_draw (widget);
+}
+
 static void
 gtk_scrolled_window_grab_notify (GtkWidget *widget,
                                  gboolean   was_grabbed)