]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkscrolledwindow.c
scrolledwindow: set GDK_EXPOSURE_MASK on the overshoot window
[~andy/gtk] / gtk / gtkscrolledwindow.c
index dd4b71f9cab102666425148877b4ebbf55e6f8d2..7929863a0258483ccb21e06e96e26b6a2dfe3497 100644 (file)
@@ -274,6 +274,7 @@ 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_grab_notify           (GtkWidget           *widget,
                                                         gboolean             was_grabbed);
 
@@ -1433,18 +1434,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 +1482,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 +1508,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)
@@ -1736,10 +1745,14 @@ gtk_scrolled_window_relative_allocation (GtkWidget     *widget,
   gtk_widget_get_preferred_height (priv->hscrollbar, &sb_height, NULL);
   gtk_widget_get_preferred_width (priv->vscrollbar, &sb_width, NULL);
 
-  /* Subtract some things from our available allocation size */
+  gtk_widget_get_allocation (widget, &widget_allocation);
+
   allocation->x = 0;
   allocation->y = 0;
+  allocation->width = widget_allocation.width;
+  allocation->height = widget_allocation.height;
 
+  /* Subtract some things from our available allocation size */
   if (priv->shadow_type != GTK_SHADOW_NONE)
     {
       GtkStyleContext *context;
@@ -1757,14 +1770,12 @@ gtk_scrolled_window_relative_allocation (GtkWidget     *widget,
 
       allocation->x += padding.left + border.left;
       allocation->y += padding.top + border.top;
+      allocation->width = MAX (1, allocation->width - (padding.left + border.left + padding.right + border.right));
+      allocation->height = MAX (1, allocation->height - (padding.top + border.top + padding.bottom + border.bottom));
 
       gtk_style_context_restore (context);
     }
 
-  gtk_widget_get_allocation (widget, &widget_allocation);
-  allocation->width = MAX (1, (gint) widget_allocation.width - allocation->x * 2);
-  allocation->height = MAX (1, (gint) widget_allocation.height - allocation->y * 2);
-
   if (priv->vscrollbar_visible)
     {
       gboolean is_rtl;
@@ -2158,11 +2169,9 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
          priv->real_window_placement == GTK_CORNER_TOP_RIGHT)
        child_allocation.y = (relative_allocation.y +
                              relative_allocation.height +
-                             sb_spacing +
-                             (priv->shadow_type == GTK_SHADOW_NONE ?
-                              0 : padding.top + border.top));
+                             sb_spacing);
       else
-       child_allocation.y = 0;
+       child_allocation.y = relative_allocation.y - sb_spacing - sb_height;
 
       child_allocation.width = relative_allocation.width;
       child_allocation.height = sb_height;
@@ -2175,15 +2184,12 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
             {
               child_allocation.x -= padding.left + border.left;
               child_allocation.width += padding.left + padding.right + border.left + border.right;
-            }
-          else if (GTK_CORNER_TOP_RIGHT == priv->real_window_placement ||
-                   GTK_CORNER_TOP_LEFT == priv->real_window_placement)
-            {
-              child_allocation.y -= padding.top + border.top;
-            }
-          else
-            {
-              child_allocation.y += padding.top + border.top;
+
+              if (priv->real_window_placement == GTK_CORNER_TOP_LEFT ||
+                  priv->real_window_placement == GTK_CORNER_TOP_RIGHT)
+                child_allocation.y += padding.bottom + border.bottom;
+              else
+                child_allocation.y -= padding.top + border.top;
             }
        }
 
@@ -2205,11 +2211,9 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
            priv->real_window_placement == GTK_CORNER_BOTTOM_LEFT)))
        child_allocation.x = (relative_allocation.x +
                              relative_allocation.width +
-                             sb_spacing +
-                             (priv->shadow_type == GTK_SHADOW_NONE ?
-                              0 : padding.left + border.left));
+                             sb_spacing);
       else
-       child_allocation.x = 0;
+       child_allocation.x = relative_allocation.x - sb_spacing - sb_width;
 
       child_allocation.y = relative_allocation.y;
       child_allocation.width = sb_width;
@@ -2223,17 +2227,18 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
             {
               child_allocation.y -= padding.top + border.top;
              child_allocation.height += padding.top + padding.bottom + border.top + border.bottom;
+
+              if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL &&
+                   (priv->real_window_placement == GTK_CORNER_TOP_RIGHT ||
+                    priv->real_window_placement == GTK_CORNER_BOTTOM_RIGHT)) ||
+                  (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR &&
+                   (priv->real_window_placement == GTK_CORNER_TOP_LEFT ||
+                    priv->real_window_placement == GTK_CORNER_BOTTOM_LEFT)))
+                child_allocation.x += padding.right + border.right;
+              else
+                child_allocation.x -= padding.left + border.left;
             }
-          else if (GTK_CORNER_BOTTOM_LEFT == priv->real_window_placement ||
-                   GTK_CORNER_TOP_LEFT == priv->real_window_placement)
-            {
-              child_allocation.x -= padding.left + border.left;
-            }
-          else
-            {
-              child_allocation.x += padding.left + border.left;
-            }
-       }
+        }
 
       gtk_widget_size_allocate (priv->vscrollbar, &child_allocation);
     }
@@ -2252,9 +2257,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 +2272,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 +2294,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 +2323,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);
 
@@ -2872,6 +2886,9 @@ gtk_scrolled_window_captured_event (GtkWidget *widget,
   gboolean retval = FALSE;
   GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW (widget)->priv;
 
+  if (gdk_window_get_window_type (event->any.window) == GDK_WINDOW_TEMP)
+    return FALSE;
+
   switch (event->type)
     {
     case GDK_TOUCH_BEGIN:
@@ -3357,14 +3374,13 @@ gtk_scrolled_window_realize (GtkWidget *widget)
   attributes.wclass = GDK_INPUT_OUTPUT;
   attributes.visual = gtk_widget_get_visual (widget);
   attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK |
-    GDK_BUTTON_MOTION_MASK | GDK_TOUCH_MASK;
+    GDK_BUTTON_MOTION_MASK | GDK_TOUCH_MASK | GDK_EXPOSURE_MASK;
 
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 
   scrolled_window->priv->overshoot_window =
     gdk_window_new (gtk_widget_get_parent_window (widget),
                     &attributes, attributes_mask);
-
   gdk_window_set_user_data (scrolled_window->priv->overshoot_window, widget);
 
   child_widget = gtk_bin_get_child (GTK_BIN (widget));