5a037458021b283adca6c8e87218a9dac40c643a
[mono.git] / bockbuild / mac-sdk / patches / gtk / 0026-gtk-port-overlay-scrollbars-to-native-CALayers.patch
1 From 756b650315bed2426bd7f1e0525a10b707c868e6 Mon Sep 17 00:00:00 2001
2 From: Michael Natterer <mitch@gimp.org>
3 Date: Thu, 27 Sep 2012 17:03:47 +0200
4 Subject: [PATCH 26/68] gtk: port overlay scrollbars to native CALayers
5
6 ---
7  gtk/gtkscrolledwindow.c |  679 ++++++++++++++++++++++++++---------------------
8  1 file changed, 379 insertions(+), 300 deletions(-)
9
10 diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
11 index ab3df16..1fba87b 100644
12 --- a/gtk/gtkscrolledwindow.c
13 +++ b/gtk/gtkscrolledwindow.c
14 @@ -36,8 +36,12 @@
15  #include "gtkintl.h"
16  #include "gtkmain.h"
17  #include "gtkdnd.h"
18 +#include "gtktreeview.h"
19  #include "gtkalias.h"
20
21 +#include "gdk/quartz/gdkquartz.h"
22 +#include <Cocoa/Cocoa.h>
23 +
24
25  /* scrolled window policy and size requisition handling:
26   *
27 @@ -117,6 +121,12 @@ typedef struct {
28    gdouble                unclamped_hadj_value;
29    gdouble                unclamped_vadj_value;
30
31 +  GtkAllocation  viewport_allocation;
32 +  CALayer       *vbar_layer;
33 +  CALayer       *hbar_layer;
34 +  CALayer       *vslider_layer;
35 +  CALayer       *hslider_layer;
36 +
37    GtkAdjustment *opacity;
38    GbAnimation   *opacity_anim;
39
40 @@ -243,29 +253,23 @@ static void gtk_scrolled_window_start_fade_out_timeout (GtkScrolledWindow *scrol
41  static void gtk_scrolled_window_stop_fade_out_timeout (GtkScrolledWindow *scrolled_window);
42  static void gtk_scrolled_window_start_fade_in_animation  (GtkScrolledWindow *scrolled_window);
43  static void gtk_scrolled_window_start_fade_out_animation (GtkScrolledWindow *scrolled_window);
44 -static gboolean
45 -           gtk_scrolled_window_over_child_scroll_areas (GtkScrolledWindow *scrolled_window,
46 -                                                        GdkEvent          *event,
47 +static gboolean  gtk_scrolled_window_over_scroll_areas (GtkScrolledWindow *scrolled_window,
48                                                          gint               x,
49                                                          gint               y,
50                                                          gboolean          *over_vscroll,
51                                                          gboolean          *over_hscroll);
52 -static void gtk_scrolled_window_get_child_scroll_areas (GtkScrolledWindow *scrolled_window,
53 -                                                        GtkWidget         *child,
54 -                                                        GdkWindow         *child_window,
55 +static void      gtk_scrolled_window_get_scroll_areas  (GtkScrolledWindow *scrolled_window,
56                                                          GdkRectangle      *vbar_rect,
57                                                          GdkRectangle      *vslider_rect,
58                                                          GdkRectangle      *hbar_rect,
59                                                          GdkRectangle      *hslider_rect);
60 -static gboolean gtk_scrolled_window_child_expose (GtkWidget         *widget,
61 -                                                  GdkEventExpose    *eevent,
62 -                                                  GtkScrolledWindow *scrolled_window);
63 -static void  gtk_scrolled_window_expose_scrollbars (GtkAdjustment     *adj,
64 -                                                    GtkScrolledWindow *scrolled_window);
65 +static void  gtk_scrolled_window_update_scrollbars (GtkScrolledWindow *scrolled_window);
66
67  static void gtk_scrolled_window_overlay_scrollbars_changed (GtkSettings *settings,
68                                                              GParamSpec  *arg,
69                                                              gpointer     user_data);
70 +static void gtk_scrolled_window_map_layers                 (GtkScrolledWindow *scrolled_window);
71 +static void gtk_scrolled_window_unmap_layers               (GtkScrolledWindow *scrolled_window);
72
73
74  static void gtk_scrolled_window_start_snap_back         (GtkScrolledWindow *scrolled_window);
75 @@ -536,9 +540,9 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
76    priv->sb_width = 6;
77    priv->sb_fade_out_delay = 1000;
78
79 -  g_signal_connect (priv->opacity, "value-changed",
80 -                    G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
81 -                    scrolled_window);
82 +  g_signal_connect_swapped (priv->opacity, "value-changed",
83 +                            G_CALLBACK (gtk_scrolled_window_update_scrollbars),
84 +                            scrolled_window);
85  }
86
87  /**
88 @@ -587,7 +591,6 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
89                                      GtkAdjustment     *hadjustment)
90  {
91    GtkBin *bin;
92 -  GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
93
94    g_return_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window));
95    if (hadjustment)
96 @@ -623,7 +626,7 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
97                                              gtk_scrolled_window_adjustment_value_changed,
98                                              scrolled_window);
99        g_signal_handlers_disconnect_by_func (old_adjustment,
100 -                                            gtk_scrolled_window_expose_scrollbars,
101 +                                            gtk_scrolled_window_update_scrollbars,
102                                              scrolled_window);
103
104        gtk_range_set_adjustment (GTK_RANGE (scrolled_window->hscrollbar),
105 @@ -641,18 +644,12 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
106    gtk_scrolled_window_adjustment_changed (hadjustment, scrolled_window);
107    gtk_scrolled_window_adjustment_value_changed (hadjustment, scrolled_window);
108
109 -#if 0
110 -  g_signal_connect (hadjustment, "value-changed",
111 -                    G_CALLBACK (gtk_scrolled_window_adjustment_value_changed),
112 -                    scrolled_window);
113 -#endif
114 -
115 -  g_signal_connect (hadjustment, "changed",
116 -                    G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
117 -                    scrolled_window);
118 -  g_signal_connect (hadjustment, "value-changed",
119 -                    G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
120 -                    scrolled_window);
121 +  g_signal_connect_swapped (hadjustment, "changed",
122 +                            G_CALLBACK (gtk_scrolled_window_update_scrollbars),
123 +                            scrolled_window);
124 +  g_signal_connect_swapped (hadjustment, "value-changed",
125 +                            G_CALLBACK (gtk_scrolled_window_update_scrollbars),
126 +                            scrolled_window);
127
128    if (bin->child)
129      gtk_widget_set_scroll_adjustments (bin->child,
130 @@ -711,7 +708,7 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window,
131                                              gtk_scrolled_window_adjustment_value_changed,
132                                              scrolled_window);
133        g_signal_handlers_disconnect_by_func (old_adjustment,
134 -                                            gtk_scrolled_window_expose_scrollbars,
135 +                                            gtk_scrolled_window_update_scrollbars,
136                                              scrolled_window);
137
138        gtk_range_set_adjustment (GTK_RANGE (scrolled_window->vscrollbar),
139 @@ -729,19 +726,12 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window,
140    gtk_scrolled_window_adjustment_changed (vadjustment, scrolled_window);
141    gtk_scrolled_window_adjustment_value_changed (vadjustment, scrolled_window);
142
143 -#if 0
144 -  g_signal_connect (vadjustment,
145 -                    "value-changed",
146 -                    G_CALLBACK (gtk_scrolled_window_adjustment_value_changed),
147 -                    scrolled_window);
148 -#endif
149 -
150 -  g_signal_connect (vadjustment, "changed",
151 -                    G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
152 -                    scrolled_window);
153 -  g_signal_connect (vadjustment, "value-changed",
154 -                    G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
155 -                    scrolled_window);
156 +  g_signal_connect_swapped (vadjustment, "changed",
157 +                            G_CALLBACK (gtk_scrolled_window_update_scrollbars),
158 +                            scrolled_window);
159 +  g_signal_connect_swapped (vadjustment, "value-changed",
160 +                            G_CALLBACK (gtk_scrolled_window_update_scrollbars),
161 +                            scrolled_window);
162
163    if (bin->child)
164      gtk_widget_set_scroll_adjustments (bin->child,
165 @@ -1081,7 +1071,7 @@ gtk_scrolled_window_destroy (GtkObject *object)
166                                              gtk_scrolled_window_adjustment_value_changed,
167                                              scrolled_window);
168        g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)),
169 -                                            gtk_scrolled_window_expose_scrollbars,
170 +                                            gtk_scrolled_window_update_scrollbars,
171                                              scrolled_window);
172
173        gtk_widget_unparent (scrolled_window->hscrollbar);
174 @@ -1098,7 +1088,7 @@ gtk_scrolled_window_destroy (GtkObject *object)
175                                              gtk_scrolled_window_adjustment_value_changed,
176                                              scrolled_window);
177        g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)),
178 -                                            gtk_scrolled_window_expose_scrollbars,
179 +                                            gtk_scrolled_window_update_scrollbars,
180                                              scrolled_window);
181
182        gtk_widget_unparent (scrolled_window->vscrollbar);
183 @@ -1276,10 +1266,11 @@ gtk_scrolled_window_screen_changed (GtkWidget *widget,
184  }
185
186  static void
187 -gtk_scrolled_window_paint (GtkWidget    *widget,
188 -                          GdkRectangle *area)
189 +gtk_scrolled_window_paint (GtkWidget      *widget,
190 +                          GdkEventExpose *event)
191  {
192    GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
193 +  GdkRectangle *area = &event->area;
194    GtkAllocation relative_allocation;
195
196    if (scrolled_window->shadow_type != GTK_SHADOW_NONE)
197 @@ -1317,6 +1308,116 @@ gtk_scrolled_window_paint (GtkWidget    *widget,
198      }
199  }
200
201 +static void
202 +gtk_scrolled_window_update_scrollbars (GtkScrolledWindow *scrolled_window)
203 +{
204 +  GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
205 +  GtkWidget *widget = GTK_WIDGET (scrolled_window);
206 +  GdkWindow *window;
207 +  gint window_height;
208 +  GdkRectangle vbar_rect;
209 +  GdkRectangle vslider_rect;
210 +  GdkRectangle hbar_rect;
211 +  GdkRectangle hslider_rect;
212 +  CGRect rect;
213 +
214 +  if (!priv->overlay_scrollbars || !gtk_widget_get_realized (widget))
215 +    return;
216 +
217 +  window = gtk_widget_get_window (gtk_widget_get_toplevel (widget));
218 +  window_height = gdk_window_get_height (window);
219 +
220 +  gtk_scrolled_window_get_scroll_areas (scrolled_window,
221 +                                        &vbar_rect, &vslider_rect,
222 +                                        &hbar_rect, &hslider_rect);
223 +
224 +  if (priv->sb_visible && scrolled_window->vscrollbar && vbar_rect.width > 0)
225 +    {
226 +      rect.origin.x = priv->viewport_allocation.x + vbar_rect.x;
227 +      rect.origin.y = priv->viewport_allocation.y + vbar_rect.y;
228 +      rect.size.width = vbar_rect.width;
229 +      rect.size.height = vbar_rect.height;
230 +
231 +      rect.origin.y = window_height - rect.origin.y - rect.size.height;
232 +
233 +      priv->vbar_layer.frame = rect;
234 +      priv->vbar_layer.opacity = gtk_adjustment_get_value (priv->opacity) / 2.0;
235 +    }
236 +  else
237 +    {
238 +      priv->vbar_layer.opacity = 0.0;
239 +    }
240 +
241 +  if (priv->sb_visible && scrolled_window->hscrollbar && hbar_rect.width > 0)
242 +    {
243 +      rect.origin.x = priv->viewport_allocation.x + hbar_rect.x;
244 +      rect.origin.y = priv->viewport_allocation.y + hbar_rect.y;
245 +      rect.size.width = hbar_rect.width;
246 +      rect.size.height = hbar_rect.height;
247 +
248 +      /* don't overlap in the corner */
249 +      if (scrolled_window->vscrollbar && vbar_rect.width > 0)
250 +        rect.size.width -= vbar_rect.width;
251 +
252 +      rect.origin.y = window_height - rect.origin.y - rect.size.height;
253 +
254 +      priv->hbar_layer.frame = rect;
255 +      priv->hbar_layer.opacity = gtk_adjustment_get_value (priv->opacity) / 2.0;
256 +    }
257 +  else
258 +    {
259 +      priv->hbar_layer.opacity = 0.0;
260 +    }
261 +
262 +  if (scrolled_window->vscrollbar && vslider_rect.width > 0)
263 +    {
264 +      rect.origin.x = priv->viewport_allocation.x + vslider_rect.x;
265 +      rect.origin.y = priv->viewport_allocation.y + vslider_rect.y;
266 +      rect.size.width = vslider_rect.width;
267 +      rect.size.height = vslider_rect.height;
268 +
269 +      rect.origin.y = window_height - rect.origin.y - rect.size.height;
270 +
271 +      priv->vslider_layer.frame = rect;
272 +      priv->vslider_layer.cornerRadius = priv->sb_radius;
273 +      priv->vslider_layer.opacity = gtk_adjustment_get_value (priv->opacity);
274 +    }
275 +  else
276 +    {
277 +      priv->vslider_layer.opacity = 0.0;
278 +    }
279 +
280 +  if (scrolled_window->hscrollbar && hslider_rect.width > 0)
281 +    {
282 +      rect.origin.x = priv->viewport_allocation.x + hslider_rect.x;
283 +      rect.origin.y = priv->viewport_allocation.y + hslider_rect.y;
284 +      rect.size.width = hslider_rect.width;
285 +      rect.size.height = hslider_rect.height;
286 +
287 +      rect.origin.y = window_height - rect.origin.y - rect.size.height;
288 +
289 +      priv->hslider_layer.frame = rect;
290 +      priv->hslider_layer.cornerRadius = priv->sb_radius;
291 +      priv->hslider_layer.opacity = gtk_adjustment_get_value (priv->opacity);
292 +    }
293 +  else
294 +    {
295 +      priv->hslider_layer.opacity = 0.0;
296 +    }
297 +
298 +  [priv->vbar_layer removeAllAnimations];
299 +  [priv->vbar_layer setNeedsDisplay];
300 +
301 +  [priv->vslider_layer removeAllAnimations];
302 +  [priv->vslider_layer setNeedsDisplay];
303 +
304 +  [priv->hbar_layer removeAllAnimations];
305 +  [priv->hbar_layer setNeedsDisplay];
306 +
307 +  [priv->hslider_layer removeAllAnimations];
308 +  [priv->hslider_layer setNeedsDisplay];
309 +}
310 +
311  static gboolean
312  gtk_scrolled_window_expose (GtkWidget      *widget,
313                             GdkEventExpose *event)
314 @@ -1326,23 +1427,11 @@ gtk_scrolled_window_expose (GtkWidget      *widget,
315
316    if (gtk_widget_is_drawable (widget))
317      {
318 -      GdkWindow *hscrollbar_window = NULL;
319 -      GdkWindow *vscrollbar_window = NULL;
320 +      gtk_scrolled_window_paint (widget, event);
321
322 -      if (scrolled_window->hscrollbar)
323 -        hscrollbar_window = gtk_widget_get_window (scrolled_window->hscrollbar);
324 +      GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->expose_event (widget, event);
325
326 -      if (scrolled_window->vscrollbar)
327 -        vscrollbar_window = gtk_widget_get_window (scrolled_window->vscrollbar);
328 -
329 -      if (event->window == priv->overshoot_window ||
330 -          event->window == priv->vbackground_window ||
331 -          event->window == priv->hbackground_window ||
332 -          event->window == hscrollbar_window ||
333 -          event->window == vscrollbar_window)
334 -        GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->expose_event (widget, event);
335 -      else
336 -        gtk_scrolled_window_paint (widget, &event->area);
337 +      gtk_scrolled_window_update_scrollbars (scrolled_window);
338      }
339
340    return FALSE;
341 @@ -1554,6 +1643,8 @@ gtk_scrolled_window_size_request (GtkWidget      *widget,
342           else
343             requisition->width += vscrollbar_requisition.width;
344         }
345 +      else
346 +        requisition->width += priv->sb_width + 2 * priv->sb_padding;
347
348        if (scrolled_window->vscrollbar_policy == GTK_POLICY_NEVER)
349         requisition->height += child_requisition.height;
350 @@ -1569,6 +1660,8 @@ gtk_scrolled_window_size_request (GtkWidget      *widget,
351           else
352             requisition->height += hscrollbar_requisition.height;
353         }
354 +      else
355 +        requisition->height += priv->sb_width + 2 * priv->sb_padding;
356      }
357
358    if (! priv->overlay_scrollbars)
359 @@ -1785,6 +1878,12 @@ _gtk_scrolled_window_allocate_overshoot_window (GtkScrolledWindow *scrolled_wind
360      }
361    else
362      gdk_window_hide (priv->hbackground_window);
363 +
364 +  if (priv->overlay_scrollbars)
365 +    {
366 +      gtk_scrolled_window_start_fade_in_animation (scrolled_window);
367 +      gtk_scrolled_window_update_scrollbars (scrolled_window);
368 +    }
369  }
370
371  static void
372 @@ -1811,6 +1910,35 @@ gtk_scrolled_window_allocate_child (GtkScrolledWindow *swindow,
373  }
374
375  static void
376 +gtk_scrolled_window_compute_viewport_allocation (GtkScrolledWindow *scrolled_window)
377 +{
378 +  GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
379 +  GtkWidget *widget = GTK_WIDGET (scrolled_window);
380 +  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
381 +  gint toplevel_alloc_x, toplevel_alloc_y;
382 +
383 +  /* Translate the viewport_allocation coordinates to coordinates relative to
384 +   * the toplevel. Then set these coordinates as viewport_allocation, which
385 +   * will be used to draw the scrollbars to the CALayer.
386 +   */
387 +  gtk_scrolled_window_relative_allocation (widget, &priv->viewport_allocation);
388 +  if (gtk_widget_translate_coordinates (widget, toplevel,
389 +                                        priv->viewport_allocation.x,
390 +                                        priv->viewport_allocation.y,
391 +                                        &toplevel_alloc_x, &toplevel_alloc_y))
392 +    {
393 +      priv->viewport_allocation.x = toplevel_alloc_x;
394 +      priv->viewport_allocation.y = toplevel_alloc_y;
395 +    }
396 +  else
397 +    {
398 +      /* Fallback using only the widget's allocation. */
399 +      priv->viewport_allocation.x += widget->allocation.x;
400 +      priv->viewport_allocation.y += widget->allocation.y;
401 +    }
402 +}
403 +
404 +static void
405  gtk_scrolled_window_size_allocate (GtkWidget     *widget,
406                                    GtkAllocation *allocation)
407  {
408 @@ -1829,8 +1957,6 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
409    priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
410    bin = GTK_BIN (scrolled_window);
411
412 -  gtk_scrolled_window_expose_scrollbars (NULL, scrolled_window);
413 -
414    scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window);
415    gtk_widget_style_get (widget, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL);
416
417 @@ -1879,6 +2005,9 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
418         }
419        while (previous_hvis != scrolled_window->hscrollbar_visible ||
420              previous_vvis != scrolled_window->vscrollbar_visible);
421 +
422 +      if (gtk_widget_get_realized (widget))
423 +        gtk_scrolled_window_compute_viewport_allocation (scrolled_window);
424      }
425    else
426      {
427 @@ -2166,6 +2295,10 @@ gtk_scrolled_window_scroll_event (GtkWidget      *widget,
428             priv->y_force = 0.0;
429           }
430
431 +       /* Stop fade out timeout while we're overshot */
432 +       if (new_overshoot_x != 0 || new_overshoot_y != 0)
433 +         gtk_scrolled_window_stop_fade_out_timeout (scrolled_window);
434 +
435        /* If we should start a snap back and no current deceleration
436         * is active, start the snap back.
437         */
438 @@ -2343,6 +2476,10 @@ scrolled_window_snap_back_cb (gpointer user_data)
439    else
440      {
441        priv->deceleration_id = 0;
442 +
443 +      /* Snap back has finished, make sure the scrollbars will fade out */
444 +      gtk_scrolled_window_start_fade_out_timeout (scrolled_window);
445 +
446        return FALSE;
447      }
448  }
449 @@ -2445,6 +2582,25 @@ static gboolean
450  gtk_scrolled_window_captured_motion_notify_scrollbar (GtkWidget *widget,
451                                                        GdkEvent  *event);
452
453 +static void
454 +gtk_scrolled_window_translate_coordinates (GtkWidget  *src_widget,
455 +                                           GtkWidget  *dest_widget,
456 +                                           gint        src_x,
457 +                                           gint        src_y,
458 +                                           gint       *dest_x,
459 +                                           gint       *dest_y)
460 +{
461 +  if (GTK_IS_TREE_VIEW (src_widget))
462 +    {
463 +      gtk_tree_view_convert_bin_window_to_widget_coords (GTK_TREE_VIEW (src_widget),
464 +                                                         src_x, src_y,
465 +                                                         &src_x, &src_y);
466 +    }
467 +
468 +  gtk_widget_translate_coordinates (src_widget, dest_widget,
469 +                                    src_x, src_y, dest_x, dest_y);
470 +}
471 +
472  static gboolean
473  gtk_scrolled_window_captured_button_press_scrollbar (GtkWidget *widget,
474                                                       GdkEvent  *event)
475 @@ -2452,14 +2608,19 @@ gtk_scrolled_window_captured_button_press_scrollbar (GtkWidget *widget,
476    GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
477    GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
478    GdkEventButton *bevent = (GdkEventButton *) event;
479 +  GtkWidget *event_widget = gtk_get_event_widget (event);
480 +  gint x, y;
481
482    if (bevent->button != 1)
483      return FALSE;
484
485 -  if (gtk_scrolled_window_over_child_scroll_areas (scrolled_window, event,
486 -                                                   bevent->x, bevent->y,
487 -                                                   &priv->sb_grab_vscroll,
488 -                                                   &priv->sb_grab_hscroll))
489 +  gtk_scrolled_window_translate_coordinates (event_widget, widget,
490 +                                             bevent->x, bevent->y, &x, &y);
491 +
492 +  if (gtk_scrolled_window_over_scroll_areas (scrolled_window,
493 +                                             x, y,
494 +                                             &priv->sb_grab_vscroll,
495 +                                             &priv->sb_grab_hscroll))
496      {
497        GdkRectangle vbar_rect;
498        GdkRectangle vslider_rect;
499 @@ -2469,11 +2630,9 @@ gtk_scrolled_window_captured_button_press_scrollbar (GtkWidget *widget,
500        priv->sb_pointer_grabbed = TRUE;
501        gtk_grab_add (widget);
502
503 -      gtk_scrolled_window_get_child_scroll_areas (scrolled_window,
504 -                                                  gtk_bin_get_child (GTK_BIN (widget)),
505 -                                                  bevent->window,
506 -                                                  &vbar_rect, &vslider_rect,
507 -                                                  &hbar_rect, &hslider_rect);
508 +      gtk_scrolled_window_get_scroll_areas (scrolled_window,
509 +                                            &vbar_rect, &vslider_rect,
510 +                                            &hbar_rect, &hslider_rect);
511
512        if (priv->sb_grab_vscroll)
513          {
514 @@ -2481,20 +2640,20 @@ gtk_scrolled_window_captured_button_press_scrollbar (GtkWidget *widget,
515            vslider_rect.x = vbar_rect.x;
516            vslider_rect.width = vbar_rect.width;
517
518 -          if (bevent->x >= vslider_rect.x &&
519 -              bevent->x < (vslider_rect.x + vslider_rect.width) &&
520 -              bevent->y >= vslider_rect.y &&
521 -              bevent->y < (vslider_rect.y + vslider_rect.height))
522 +          if (x >= vslider_rect.x &&
523 +              x < (vslider_rect.x + vslider_rect.width) &&
524 +              y >= vslider_rect.y &&
525 +              y < (vslider_rect.y + vslider_rect.height))
526              {
527                priv->sb_drag_slider = TRUE;
528 -              priv->sb_grab_offset_y = bevent->y - vslider_rect.y;
529 +              priv->sb_grab_offset_y = y - vslider_rect.y;
530              }
531            else
532              {
533                priv->sb_drag_slider = FALSE;
534 -              priv->sb_grab_offset_y = bevent->y - vbar_rect.y;
535 +              priv->sb_grab_offset_y = y - vbar_rect.y;
536
537 -              if (bevent->y < vslider_rect.y)
538 +              if (y < vslider_rect.y)
539                  priv->sb_scroll_direction = -1;
540                else
541                  priv->sb_scroll_direction = 1;
542 @@ -2506,20 +2665,20 @@ gtk_scrolled_window_captured_button_press_scrollbar (GtkWidget *widget,
543            hslider_rect.y = hbar_rect.y;
544            hslider_rect.height = hbar_rect.height;
545
546 -          if (bevent->x >= hslider_rect.x &&
547 -              bevent->x < (hslider_rect.x + hslider_rect.width) &&
548 -              bevent->y >= hslider_rect.y &&
549 -              bevent->y < (hslider_rect.y + hslider_rect.height))
550 +          if (x >= hslider_rect.x &&
551 +              x < (hslider_rect.x + hslider_rect.width) &&
552 +              y >= hslider_rect.y &&
553 +              y < (hslider_rect.y + hslider_rect.height))
554              {
555                priv->sb_drag_slider = TRUE;
556 -              priv->sb_grab_offset_x = bevent->x - hslider_rect.x;
557 +              priv->sb_grab_offset_x = x - hslider_rect.x;
558              }
559            else
560              {
561                priv->sb_drag_slider = FALSE;
562 -              priv->sb_grab_offset_x = bevent->x - hbar_rect.x;
563 +              priv->sb_grab_offset_x = x - hbar_rect.x;
564
565 -              if (bevent->x < hslider_rect.x)
566 +              if (x < hslider_rect.x)
567                  priv->sb_scroll_direction = -1;
568                else
569                  priv->sb_scroll_direction = 1;
570 @@ -2597,6 +2756,11 @@ gtk_scrolled_window_captured_motion_notify_scrollbar (GtkWidget *widget,
571    GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
572    GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
573    GdkEventMotion *mevent = (GdkEventMotion *) event;
574 +  GtkWidget *event_widget = gtk_get_event_widget (event);
575 +  gint x, y;
576 +
577 +  gtk_scrolled_window_translate_coordinates (event_widget, widget,
578 +                                             mevent->x, mevent->y, &x, &y);
579
580    if (priv->sb_pointer_grabbed)
581      {
582 @@ -2611,22 +2775,20 @@ gtk_scrolled_window_captured_motion_notify_scrollbar (GtkWidget *widget,
583            gint visible_range;
584            gdouble value;
585
586 -          gtk_scrolled_window_get_child_scroll_areas (scrolled_window,
587 -                                                      gtk_bin_get_child (GTK_BIN (widget)),
588 -                                                      mevent->window,
589 -                                                      &vbar_rect, &vslider_rect,
590 -                                                      &hbar_rect, &hslider_rect);
591 +          gtk_scrolled_window_get_scroll_areas (scrolled_window,
592 +                                                &vbar_rect, &vslider_rect,
593 +                                                &hbar_rect, &hslider_rect);
594
595            if (priv->sb_grab_vscroll)
596              {
597                adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar));
598 -              pos = mevent->y - priv->sb_grab_offset_y - vbar_rect.y;
599 +              pos = y - priv->sb_grab_offset_y - vbar_rect.y;
600                visible_range = vbar_rect.height - vslider_rect.height;
601              }
602            else if (priv->sb_grab_hscroll)
603              {
604                adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar));
605 -              pos = mevent->x - priv->sb_grab_offset_x - hbar_rect.x;
606 +              pos = x - priv->sb_grab_offset_x - hbar_rect.x;
607                visible_range = hbar_rect.width - hslider_rect.width;
608              }
609
610 @@ -2641,9 +2803,9 @@ gtk_scrolled_window_captured_motion_notify_scrollbar (GtkWidget *widget,
611      }
612    else
613      {
614 -      if (gtk_scrolled_window_over_child_scroll_areas (scrolled_window, event,
615 -                                                       mevent->x, mevent->y,
616 -                                                       NULL, NULL))
617 +      if (gtk_scrolled_window_over_scroll_areas (scrolled_window,
618 +                                                 x, y,
619 +                                                 NULL, NULL))
620          {
621            priv->sb_hovering = TRUE;
622            priv->sb_visible = TRUE;
623 @@ -2652,7 +2814,7 @@ gtk_scrolled_window_captured_motion_notify_scrollbar (GtkWidget *widget,
624            gtk_scrolled_window_stop_fade_out_timeout (scrolled_window);
625
626            /* needed when entering the scrollbar */
627 -          gtk_scrolled_window_expose_scrollbars (NULL, scrolled_window);
628 +          gtk_scrolled_window_update_scrollbars (scrolled_window);
629
630            return TRUE;
631          }
632 @@ -2839,10 +3001,6 @@ gtk_scrolled_window_add (GtkContainer *container,
633                                            gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar))))
634      g_warning ("gtk_scrolled_window_add(): cannot add non scrollable widget "
635                "use gtk_scrolled_window_add_with_viewport() instead");
636 -
637 -  g_signal_connect_after (child, "expose-event",
638 -                          G_CALLBACK (gtk_scrolled_window_child_expose),
639 -                          container);
640  }
641
642  static void
643 @@ -2857,10 +3015,6 @@ gtk_scrolled_window_remove (GtkContainer *container,
644
645    priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (container);
646
647 -  g_signal_handlers_disconnect_by_func (child,
648 -                                        gtk_scrolled_window_child_expose,
649 -                                        container);
650 -
651    gtk_widget_set_scroll_adjustments (child, NULL, NULL);
652
653    /* chain parent class handler to remove child */
654 @@ -3033,6 +3187,37 @@ gtk_scrolled_window_realize (GtkWidget *widget)
655                                    priv->overshoot_window);
656
657    GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->realize (widget);
658 +
659 +  gtk_scrolled_window_compute_viewport_allocation (scrolled_window);
660 +
661 +  GdkWindow *parent_window = gtk_widget_get_window (gtk_widget_get_toplevel (widget));
662 +  NSView    *layer_view;
663 +  CALayer   *parent_layer;
664 +
665 +  layer_view = gdk_quartz_window_get_layer_view (parent_window);
666 +  parent_layer = [layer_view layer];
667 +
668 +  priv->vbar_layer = [[CALayer layer] retain];
669 +  priv->vbar_layer.backgroundColor = CGColorCreateGenericRGB (0.0, 0.0, 0.0, 0.5);
670 +  priv->vbar_layer.hidden = YES;
671 +
672 +  priv->vslider_layer = [[CALayer layer] retain];
673 +  priv->vslider_layer.backgroundColor = CGColorCreateGenericRGB (0.0, 0.0, 0.0, 1.0);
674 +  priv->vslider_layer.hidden = YES;
675 +
676 +  priv->hbar_layer = [[CALayer layer] retain];
677 +  priv->hbar_layer.backgroundColor = CGColorCreateGenericRGB (0.0, 0.0, 0.0, 0.5);
678 +  priv->hbar_layer.hidden = YES;
679 +
680 +  priv->hslider_layer = [[CALayer layer] retain];
681 +  priv->hslider_layer.backgroundColor = CGColorCreateGenericRGB (0.0, 0.0, 0.0, 1.0);
682 +  priv->hslider_layer.hidden = YES;
683 +
684 +  [parent_layer addSublayer:priv->vbar_layer];
685 +  [parent_layer addSublayer:priv->vslider_layer];
686 +
687 +  [parent_layer addSublayer:priv->hbar_layer];
688 +  [parent_layer addSublayer:priv->hslider_layer];
689  }
690
691  static void
692 @@ -3053,6 +3238,22 @@ gtk_scrolled_window_unrealize (GtkWidget *widget)
693    gdk_window_destroy (priv->hbackground_window);
694    priv->hbackground_window = NULL;
695
696 +  [priv->vbar_layer removeFromSuperlayer];
697 +  [priv->vbar_layer release];
698 +  priv->vbar_layer = NULL;
699 +
700 +  [priv->vslider_layer removeFromSuperlayer];
701 +  [priv->vslider_layer release];
702 +  priv->vslider_layer = NULL;
703 +
704 +  [priv->hbar_layer removeFromSuperlayer];
705 +  [priv->hbar_layer release];
706 +  priv->hbar_layer = NULL;
707 +
708 +  [priv->hslider_layer removeFromSuperlayer];
709 +  [priv->hslider_layer release];
710 +  priv->hslider_layer = NULL;
711 +
712    gtk_widget_set_realized (widget, FALSE);
713
714    GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->unrealize (widget);
715 @@ -3076,6 +3277,9 @@ gtk_scrolled_window_map (GtkWidget *widget)
716      gdk_window_hide (priv->hbackground_window);
717
718    GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->map (widget);
719 +
720 +  if (priv->overlay_scrollbars)
721 +    gtk_scrolled_window_map_layers (scrolled_window);
722  }
723
724  static void
725 @@ -3088,6 +3292,9 @@ gtk_scrolled_window_unmap (GtkWidget *widget)
726    gdk_window_hide (priv->vbackground_window);
727    gdk_window_hide (priv->hbackground_window);
728
729 +  /* Always unmap the layers, regardless of overlay state */
730 +  gtk_scrolled_window_unmap_layers (scrolled_window);
731 +
732    GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->unmap (widget);
733  }
734
735 @@ -3117,75 +3324,25 @@ gtk_scrolled_window_grab_notify (GtkWidget *widget,
736      }
737  }
738
739 -static void
740 -gtk_scrolled_window_rounded_rectangle (cairo_t *cr,
741 -                                       gint     x,
742 -                                       gint     y,
743 -                                       gint     width,
744 -                                       gint     height,
745 -                                       gint     x_radius,
746 -                                       gint     y_radius)
747 -{
748 -  gint x1, x2;
749 -  gint y1, y2;
750 -  gint xr1, xr2;
751 -  gint yr1, yr2;
752 -
753 -  x1 = x;
754 -  x2 = x1 + width;
755 -  y1 = y;
756 -  y2 = y1 + height;
757 -
758 -  x_radius = MIN (x_radius, width  / 2.0);
759 -  y_radius = MIN (y_radius, height / 2.0);
760 -
761 -  xr1 = x_radius;
762 -  xr2 = x_radius / 2.0;
763 -  yr1 = y_radius;
764 -  yr2 = y_radius / 2.0;
765 -
766 -  cairo_move_to    (cr, x1 + xr1, y1);
767 -  cairo_line_to    (cr, x2 - xr1, y1);
768 -  cairo_curve_to   (cr, x2 - xr2, y1, x2, y1 + yr2, x2, y1 + yr1);
769 -  cairo_line_to    (cr, x2, y2 - yr1);
770 -  cairo_curve_to   (cr, x2, y2 - yr2, x2 - xr2, y2, x2 - xr1, y2);
771 -  cairo_line_to    (cr, x1 + xr1, y2);
772 -  cairo_curve_to   (cr, x1 + xr2, y2, x1, y2 - yr2, x1, y2 - yr1);
773 -  cairo_line_to    (cr, x1, y1 + yr1);
774 -  cairo_curve_to   (cr, x1, y1 + yr2, x1 + xr2, y1, x1 + xr1, y1);
775 -  cairo_close_path (cr);
776 -}
777 -
778  static gboolean
779 -gtk_scrolled_window_over_child_scroll_areas (GtkScrolledWindow *scrolled_window,
780 -                                             GdkEvent          *event,
781 -                                             gint               x,
782 -                                             gint               y,
783 -                                             gboolean          *over_vscroll,
784 -                                             gboolean          *over_hscroll)
785 +gtk_scrolled_window_over_scroll_areas (GtkScrolledWindow *scrolled_window,
786 +                                       gint               x,
787 +                                       gint               y,
788 +                                       gboolean          *over_vscroll,
789 +                                       gboolean          *over_hscroll)
790  {
791    GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
792 -  GtkWidget *child;
793    GdkRectangle vbar_rect;
794    GdkRectangle hbar_rect;
795    gboolean over_v = FALSE;
796    gboolean over_h = FALSE;
797
798 -  child = gtk_bin_get_child (GTK_BIN (scrolled_window));
799 -  if (!child)
800 -    return FALSE;
801 -
802 -  if (gtk_get_event_widget (event) != child)
803 -    return FALSE;
804 -
805    if (gtk_adjustment_get_value (priv->opacity) == 0.0)
806      return FALSE;
807
808 -  gtk_scrolled_window_get_child_scroll_areas (scrolled_window,
809 -                                              child,
810 -                                              ((GdkEventAny *) event)->window,
811 -                                              &vbar_rect, NULL,
812 -                                              &hbar_rect, NULL);
813 +  gtk_scrolled_window_get_scroll_areas (scrolled_window,
814 +                                        &vbar_rect, NULL,
815 +                                        &hbar_rect, NULL);
816
817    if (vbar_rect.width > 0 &&
818        x >= vbar_rect.x && x < (vbar_rect.x + vbar_rect.width) &&
819 @@ -3207,72 +3364,48 @@ gtk_scrolled_window_over_child_scroll_areas (GtkScrolledWindow *scrolled_window,
820  }
821
822  static void
823 -gtk_scrolled_window_get_child_scroll_areas (GtkScrolledWindow *scrolled_window,
824 -                                            GtkWidget         *child,
825 -                                            GdkWindow         *child_window,
826 -                                            GdkRectangle      *vbar_rect,
827 -                                            GdkRectangle      *vslider_rect,
828 -                                            GdkRectangle      *hbar_rect,
829 -                                            GdkRectangle      *hslider_rect)
830 +gtk_scrolled_window_get_scroll_areas (GtkScrolledWindow *scrolled_window,
831 +                                      GdkRectangle      *vbar_rect,
832 +                                      GdkRectangle      *vslider_rect,
833 +                                      GdkRectangle      *hbar_rect,
834 +                                      GdkRectangle      *hslider_rect)
835  {
836     GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
837     GtkAdjustment *adj;
838 -   GtkAllocation allocation;
839 +   gdouble value;
840     gdouble lower;
841     gdouble page_size;
842     gdouble upper;
843 -   gdouble value_h = 0.0;
844 -   gdouble value_v = 0.0;
845     gdouble ratio;
846     gdouble width;
847     gdouble height;
848     gdouble x;
849     gdouble y;
850 -   gint window_width;
851 -   gint window_height;
852     gint viewport_width;
853     gint viewport_height;
854     gint offset_x = 0;
855     gint offset_y = 0;
856
857 -   window_width = gdk_window_get_width (child_window);
858 -   window_height = gdk_window_get_height (child_window);
859 -
860 -   gtk_widget_get_allocation (child, &allocation);
861 -
862 -   viewport_width = MIN (window_width, allocation.width);
863 -   viewport_height = MIN (window_height, allocation.height);
864 -
865 -   if (scrolled_window->vscrollbar)
866 -     {
867 -       adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar));
868 -
869 -       value_v = gtk_adjustment_get_value (adj);
870 -     }
871 -
872 -   if (scrolled_window->hscrollbar)
873 -     {
874 -       adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar));
875 -
876 -       value_h = gtk_adjustment_get_value (adj);
877 -     }
878 -
879 -   if (window_width > allocation.width)
880 -     offset_x = value_h;
881 -
882 -   if (window_height > allocation.height)
883 -     offset_y = value_v;
884 +   viewport_width = priv->viewport_allocation.width;
885 +   viewport_height = priv->viewport_allocation.height;
886
887     if ((vbar_rect || vslider_rect) && scrolled_window->vscrollbar)
888       {
889         adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar));
890
891         g_object_get (adj,
892 +                     "value", &value,
893                       "lower", &lower,
894                       "upper", &upper,
895                       "page-size", &page_size,
896                       NULL);
897
898 +       /* take overshooting into account */
899 +       if (priv->unclamped_vadj_value + page_size > upper)
900 +         page_size = upper - priv->unclamped_vadj_value;
901 +       else if (priv->unclamped_vadj_value < 0.0)
902 +         page_size += priv->unclamped_vadj_value;
903 +
904         ratio = page_size / (upper - lower);
905         if (ratio < 1.0)
906           {
907 @@ -3280,7 +3413,7 @@ gtk_scrolled_window_get_child_scroll_areas (GtkScrolledWindow *scrolled_window,
908             height = MAX (height, 20);
909             height = MIN (height, viewport_height - (2 * priv->sb_padding));
910
911 -           ratio = (value_v - lower) / (upper - page_size - lower);
912 +           ratio = (value - lower) / (upper - page_size - lower);
913             y = ratio * (viewport_height - (2 * priv->sb_padding) - height) + priv->sb_padding;
914             x = viewport_width - priv->sb_width - priv->sb_padding;
915
916 @@ -3328,11 +3461,18 @@ gtk_scrolled_window_get_child_scroll_areas (GtkScrolledWindow *scrolled_window,
917         adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar));
918
919         g_object_get (adj,
920 +                     "value", &value,
921                       "lower", &lower,
922                       "upper", &upper,
923                       "page-size", &page_size,
924                       NULL);
925
926 +       /* take overshooting into account */
927 +       if (priv->unclamped_hadj_value + page_size > upper)
928 +         page_size = upper - priv->unclamped_hadj_value;
929 +       else if (priv->unclamped_hadj_value < 0.0)
930 +         page_size += priv->unclamped_hadj_value;
931 +
932         ratio = page_size / (upper - lower);
933         if (ratio < 1.0)
934           {
935 @@ -3340,7 +3480,7 @@ gtk_scrolled_window_get_child_scroll_areas (GtkScrolledWindow *scrolled_window,
936             width = MAX (width, 20);
937             width = MIN (width, viewport_width - (2 * priv->sb_padding));
938
939 -           ratio = (value_h - lower) / (upper - page_size - lower);
940 +           ratio = (value - lower) / (upper - page_size - lower);
941             x = ratio * (viewport_width - (2 * priv->sb_padding) - width) + priv->sb_padding;
942             y = viewport_height - priv->sb_width - priv->sb_padding;
943
944 @@ -3384,69 +3524,6 @@ gtk_scrolled_window_get_child_scroll_areas (GtkScrolledWindow *scrolled_window,
945       }
946  }
947
948 -static gboolean
949 -gtk_scrolled_window_child_expose (GtkWidget         *widget,
950 -                                  GdkEventExpose    *eevent,
951 -                                  GtkScrolledWindow *scrolled_window)
952 -{
953 -   GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
954 -   GdkRectangle vbar_rect;
955 -   GdkRectangle vslider_rect;
956 -   GdkRectangle hbar_rect;
957 -   GdkRectangle hslider_rect;
958 -   cairo_t   *cr;
959 -
960 -   if (!priv->overlay_scrollbars)
961 -     return FALSE;
962 -
963 -   cr = gdk_cairo_create (eevent->window);
964 -   gdk_cairo_region (cr, eevent->region);
965 -   cairo_clip (cr);
966 -
967 -   gtk_scrolled_window_get_child_scroll_areas (scrolled_window,
968 -                                               gtk_bin_get_child (GTK_BIN (scrolled_window)),
969 -                                               eevent->window,
970 -                                               &vbar_rect, &vslider_rect,
971 -                                               &hbar_rect, &hslider_rect);
972 -
973 -   if (priv->sb_visible)
974 -     {
975 -       if (scrolled_window->vscrollbar && vbar_rect.width > 0)
976 -         gdk_cairo_rectangle (cr, &vbar_rect);
977 -
978 -       if (scrolled_window->hscrollbar && hbar_rect.width > 0)
979 -         gdk_cairo_rectangle (cr, &hbar_rect);
980 -
981 -       cairo_set_source_rgba (cr, 0, 0, 0, gtk_adjustment_get_value (priv->opacity) / 2.0);
982 -       cairo_fill (cr);
983 -     }
984 -
985 -   if (scrolled_window->vscrollbar && vslider_rect.width > 0)
986 -     gtk_scrolled_window_rounded_rectangle (cr,
987 -                                            vslider_rect.x,
988 -                                            vslider_rect.y,
989 -                                            vslider_rect.width,
990 -                                            vslider_rect.height,
991 -                                            priv->sb_radius,
992 -                                            priv->sb_radius);
993 -
994 -   if (scrolled_window->hscrollbar && hslider_rect.width > 0)
995 -     gtk_scrolled_window_rounded_rectangle (cr,
996 -                                            hslider_rect.x,
997 -                                            hslider_rect.y,
998 -                                            hslider_rect.width,
999 -                                            hslider_rect.height,
1000 -                                            priv->sb_radius,
1001 -                                            priv->sb_radius);
1002 -
1003 -   cairo_set_source_rgba (cr, 0, 0, 0, gtk_adjustment_get_value (priv->opacity));
1004 -   cairo_fill (cr);
1005 -
1006 -   cairo_destroy (cr);
1007 -
1008 -   return FALSE;
1009 -}
1010 -
1011  static void
1012  gtk_scrolled_window_cancel_animation (GtkScrolledWindow *scrolled_window)
1013  {
1014 @@ -3541,39 +3618,6 @@ gtk_scrolled_window_start_fade_out_animation (GtkScrolledWindow *scrolled_window
1015  }
1016
1017  static void
1018 -gtk_scrolled_window_expose_scrollbars (GtkAdjustment     *adj,
1019 -                                       GtkScrolledWindow *scrolled_window)
1020 -{
1021 -  GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
1022 -
1023 -  if (priv->overlay_scrollbars)
1024 -    {
1025 -      GtkWidget *child = gtk_bin_get_child (GTK_BIN (scrolled_window));
1026 -
1027 -      if (child && gtk_widget_get_visible (child))
1028 -        {
1029 -          GtkAllocation alloc;
1030 -
1031 -          gtk_widget_get_allocation (child, &alloc);
1032 -
1033 -          if (scrolled_window->vscrollbar)
1034 -            gtk_widget_queue_draw_area (child,
1035 -                                        alloc.width - 20,
1036 -                                        0,
1037 -                                        20,
1038 -                                        alloc.height);
1039 -
1040 -          if (scrolled_window->hscrollbar)
1041 -            gtk_widget_queue_draw_area (child,
1042 -                                        0,
1043 -                                        alloc.height - 20,
1044 -                                        alloc.width,
1045 -                                        20);
1046 -        }
1047 -    }
1048 -}
1049 -
1050 -static void
1051  gtk_scrolled_window_init_overlay_scrollbars (GtkScrolledWindow *scrolled_window)
1052  {
1053    _gtk_widget_set_captured_event_handler (GTK_WIDGET (scrolled_window),
1054 @@ -3592,8 +3636,43 @@ gtk_scrolled_window_overlay_scrollbars_changed (GtkSettings *settings,
1055                  &priv->overlay_scrollbars,
1056                  NULL);
1057
1058 +  if (priv->overlay_scrollbars)
1059 +    gtk_scrolled_window_map_layers (GTK_SCROLLED_WINDOW (user_data));
1060 +  else
1061 +    gtk_scrolled_window_unmap_layers (GTK_SCROLLED_WINDOW (user_data));
1062 +
1063    gtk_widget_queue_resize (user_data);
1064  }
1065
1066 +static void
1067 +gtk_scrolled_window_map_layers (GtkScrolledWindow *scrolled_window)
1068 +{
1069 +  GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
1070 +
1071 +  priv->vbar_layer.hidden = NO;
1072 +  priv->vslider_layer.hidden = NO;
1073 +
1074 +  priv->hbar_layer.hidden = NO;
1075 +  priv->hslider_layer.hidden = NO;
1076 +}
1077 +
1078 +static void
1079 +gtk_scrolled_window_unmap_layers (GtkScrolledWindow *scrolled_window)
1080 +{
1081 +  GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
1082 +
1083 +  priv->vbar_layer.hidden = YES;
1084 +  [priv->vbar_layer setNeedsDisplay];
1085 +
1086 +  priv->vslider_layer.hidden = YES;
1087 +  [priv->vslider_layer setNeedsDisplay];
1088 +
1089 +  priv->hbar_layer.hidden = YES;
1090 +  [priv->hbar_layer setNeedsDisplay];
1091 +
1092 +  priv->hslider_layer.hidden = YES;
1093 +  [priv->hslider_layer setNeedsDisplay];
1094 +}
1095 +
1096  #define __GTK_SCROLLED_WINDOW_C__
1097  #include "gtkaliasdef.c"
1098 --
1099 1.7.10.2 (Apple Git-33)