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
7 gtk/gtkscrolledwindow.c | 679 ++++++++++++++++++++++++++---------------------
8 1 file changed, 379 insertions(+), 300 deletions(-)
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
18 +#include "gtktreeview.h"
21 +#include "gdk/quartz/gdkquartz.h"
22 +#include <Cocoa/Cocoa.h>
25 /* scrolled window policy and size requisition handling:
27 @@ -117,6 +121,12 @@ typedef struct {
28 gdouble unclamped_hadj_value;
29 gdouble unclamped_vadj_value;
31 + GtkAllocation viewport_allocation;
32 + CALayer *vbar_layer;
33 + CALayer *hbar_layer;
34 + CALayer *vslider_layer;
35 + CALayer *hslider_layer;
37 GtkAdjustment *opacity;
38 GbAnimation *opacity_anim;
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);
45 - gtk_scrolled_window_over_child_scroll_areas (GtkScrolledWindow *scrolled_window,
47 +static gboolean gtk_scrolled_window_over_scroll_areas (GtkScrolledWindow *scrolled_window,
50 gboolean *over_vscroll,
51 gboolean *over_hscroll);
52 -static void gtk_scrolled_window_get_child_scroll_areas (GtkScrolledWindow *scrolled_window,
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);
67 static void gtk_scrolled_window_overlay_scrollbars_changed (GtkSettings *settings,
70 +static void gtk_scrolled_window_map_layers (GtkScrolledWindow *scrolled_window);
71 +static void gtk_scrolled_window_unmap_layers (GtkScrolledWindow *scrolled_window);
74 static void gtk_scrolled_window_start_snap_back (GtkScrolledWindow *scrolled_window);
75 @@ -536,9 +540,9 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
77 priv->sb_fade_out_delay = 1000;
79 - g_signal_connect (priv->opacity, "value-changed",
80 - G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
82 + g_signal_connect_swapped (priv->opacity, "value-changed",
83 + G_CALLBACK (gtk_scrolled_window_update_scrollbars),
88 @@ -587,7 +591,6 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
89 GtkAdjustment *hadjustment)
92 - GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
94 g_return_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window));
96 @@ -623,7 +626,7 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
97 gtk_scrolled_window_adjustment_value_changed,
99 g_signal_handlers_disconnect_by_func (old_adjustment,
100 - gtk_scrolled_window_expose_scrollbars,
101 + gtk_scrolled_window_update_scrollbars,
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);
110 - g_signal_connect (hadjustment, "value-changed",
111 - G_CALLBACK (gtk_scrolled_window_adjustment_value_changed),
115 - g_signal_connect (hadjustment, "changed",
116 - G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
118 - g_signal_connect (hadjustment, "value-changed",
119 - G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
121 + g_signal_connect_swapped (hadjustment, "changed",
122 + G_CALLBACK (gtk_scrolled_window_update_scrollbars),
124 + g_signal_connect_swapped (hadjustment, "value-changed",
125 + G_CALLBACK (gtk_scrolled_window_update_scrollbars),
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,
133 g_signal_handlers_disconnect_by_func (old_adjustment,
134 - gtk_scrolled_window_expose_scrollbars,
135 + gtk_scrolled_window_update_scrollbars,
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);
144 - g_signal_connect (vadjustment,
146 - G_CALLBACK (gtk_scrolled_window_adjustment_value_changed),
150 - g_signal_connect (vadjustment, "changed",
151 - G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
153 - g_signal_connect (vadjustment, "value-changed",
154 - G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
156 + g_signal_connect_swapped (vadjustment, "changed",
157 + G_CALLBACK (gtk_scrolled_window_update_scrollbars),
159 + g_signal_connect_swapped (vadjustment, "value-changed",
160 + G_CALLBACK (gtk_scrolled_window_update_scrollbars),
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,
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,
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,
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,
182 gtk_widget_unparent (scrolled_window->vscrollbar);
183 @@ -1276,10 +1266,11 @@ gtk_scrolled_window_screen_changed (GtkWidget *widget,
187 -gtk_scrolled_window_paint (GtkWidget *widget,
188 - GdkRectangle *area)
189 +gtk_scrolled_window_paint (GtkWidget *widget,
190 + GdkEventExpose *event)
192 GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
193 + GdkRectangle *area = &event->area;
194 GtkAllocation relative_allocation;
196 if (scrolled_window->shadow_type != GTK_SHADOW_NONE)
197 @@ -1317,6 +1308,116 @@ gtk_scrolled_window_paint (GtkWidget *widget,
202 +gtk_scrolled_window_update_scrollbars (GtkScrolledWindow *scrolled_window)
204 + GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
205 + GtkWidget *widget = GTK_WIDGET (scrolled_window);
207 + gint window_height;
208 + GdkRectangle vbar_rect;
209 + GdkRectangle vslider_rect;
210 + GdkRectangle hbar_rect;
211 + GdkRectangle hslider_rect;
214 + if (!priv->overlay_scrollbars || !gtk_widget_get_realized (widget))
217 + window = gtk_widget_get_window (gtk_widget_get_toplevel (widget));
218 + window_height = gdk_window_get_height (window);
220 + gtk_scrolled_window_get_scroll_areas (scrolled_window,
221 + &vbar_rect, &vslider_rect,
222 + &hbar_rect, &hslider_rect);
224 + if (priv->sb_visible && scrolled_window->vscrollbar && vbar_rect.width > 0)
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;
231 + rect.origin.y = window_height - rect.origin.y - rect.size.height;
233 + priv->vbar_layer.frame = rect;
234 + priv->vbar_layer.opacity = gtk_adjustment_get_value (priv->opacity) / 2.0;
238 + priv->vbar_layer.opacity = 0.0;
241 + if (priv->sb_visible && scrolled_window->hscrollbar && hbar_rect.width > 0)
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;
248 + /* don't overlap in the corner */
249 + if (scrolled_window->vscrollbar && vbar_rect.width > 0)
250 + rect.size.width -= vbar_rect.width;
252 + rect.origin.y = window_height - rect.origin.y - rect.size.height;
254 + priv->hbar_layer.frame = rect;
255 + priv->hbar_layer.opacity = gtk_adjustment_get_value (priv->opacity) / 2.0;
259 + priv->hbar_layer.opacity = 0.0;
262 + if (scrolled_window->vscrollbar && vslider_rect.width > 0)
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;
269 + rect.origin.y = window_height - rect.origin.y - rect.size.height;
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);
277 + priv->vslider_layer.opacity = 0.0;
280 + if (scrolled_window->hscrollbar && hslider_rect.width > 0)
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;
287 + rect.origin.y = window_height - rect.origin.y - rect.size.height;
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);
295 + priv->hslider_layer.opacity = 0.0;
298 + [priv->vbar_layer removeAllAnimations];
299 + [priv->vbar_layer setNeedsDisplay];
301 + [priv->vslider_layer removeAllAnimations];
302 + [priv->vslider_layer setNeedsDisplay];
304 + [priv->hbar_layer removeAllAnimations];
305 + [priv->hbar_layer setNeedsDisplay];
307 + [priv->hslider_layer removeAllAnimations];
308 + [priv->hslider_layer setNeedsDisplay];
312 gtk_scrolled_window_expose (GtkWidget *widget,
313 GdkEventExpose *event)
314 @@ -1326,23 +1427,11 @@ gtk_scrolled_window_expose (GtkWidget *widget,
316 if (gtk_widget_is_drawable (widget))
318 - GdkWindow *hscrollbar_window = NULL;
319 - GdkWindow *vscrollbar_window = NULL;
320 + gtk_scrolled_window_paint (widget, event);
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);
326 - if (scrolled_window->vscrollbar)
327 - vscrollbar_window = gtk_widget_get_window (scrolled_window->vscrollbar);
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);
336 - gtk_scrolled_window_paint (widget, &event->area);
337 + gtk_scrolled_window_update_scrollbars (scrolled_window);
341 @@ -1554,6 +1643,8 @@ gtk_scrolled_window_size_request (GtkWidget *widget,
343 requisition->width += vscrollbar_requisition.width;
346 + requisition->width += priv->sb_width + 2 * priv->sb_padding;
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,
352 requisition->height += hscrollbar_requisition.height;
355 + requisition->height += priv->sb_width + 2 * priv->sb_padding;
358 if (! priv->overlay_scrollbars)
359 @@ -1785,6 +1878,12 @@ _gtk_scrolled_window_allocate_overshoot_window (GtkScrolledWindow *scrolled_wind
362 gdk_window_hide (priv->hbackground_window);
364 + if (priv->overlay_scrollbars)
366 + gtk_scrolled_window_start_fade_in_animation (scrolled_window);
367 + gtk_scrolled_window_update_scrollbars (scrolled_window);
372 @@ -1811,6 +1910,35 @@ gtk_scrolled_window_allocate_child (GtkScrolledWindow *swindow,
376 +gtk_scrolled_window_compute_viewport_allocation (GtkScrolledWindow *scrolled_window)
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;
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.
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))
393 + priv->viewport_allocation.x = toplevel_alloc_x;
394 + priv->viewport_allocation.y = toplevel_alloc_y;
398 + /* Fallback using only the widget's allocation. */
399 + priv->viewport_allocation.x += widget->allocation.x;
400 + priv->viewport_allocation.y += widget->allocation.y;
405 gtk_scrolled_window_size_allocate (GtkWidget *widget,
406 GtkAllocation *allocation)
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);
412 - gtk_scrolled_window_expose_scrollbars (NULL, scrolled_window);
414 scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window);
415 gtk_widget_style_get (widget, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL);
417 @@ -1879,6 +2005,9 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
419 while (previous_hvis != scrolled_window->hscrollbar_visible ||
420 previous_vvis != scrolled_window->vscrollbar_visible);
422 + if (gtk_widget_get_realized (widget))
423 + gtk_scrolled_window_compute_viewport_allocation (scrolled_window);
427 @@ -2166,6 +2295,10 @@ gtk_scrolled_window_scroll_event (GtkWidget *widget,
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);
435 /* If we should start a snap back and no current deceleration
436 * is active, start the snap back.
438 @@ -2343,6 +2476,10 @@ scrolled_window_snap_back_cb (gpointer user_data)
441 priv->deceleration_id = 0;
443 + /* Snap back has finished, make sure the scrollbars will fade out */
444 + gtk_scrolled_window_start_fade_out_timeout (scrolled_window);
449 @@ -2445,6 +2582,25 @@ static gboolean
450 gtk_scrolled_window_captured_motion_notify_scrollbar (GtkWidget *widget,
454 +gtk_scrolled_window_translate_coordinates (GtkWidget *src_widget,
455 + GtkWidget *dest_widget,
461 + if (GTK_IS_TREE_VIEW (src_widget))
463 + gtk_tree_view_convert_bin_window_to_widget_coords (GTK_TREE_VIEW (src_widget),
468 + gtk_widget_translate_coordinates (src_widget, dest_widget,
469 + src_x, src_y, dest_x, dest_y);
473 gtk_scrolled_window_captured_button_press_scrollbar (GtkWidget *widget,
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);
482 if (bevent->button != 1)
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);
492 + if (gtk_scrolled_window_over_scroll_areas (scrolled_window,
494 + &priv->sb_grab_vscroll,
495 + &priv->sb_grab_hscroll))
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);
503 - gtk_scrolled_window_get_child_scroll_areas (scrolled_window,
504 - gtk_bin_get_child (GTK_BIN (widget)),
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);
512 if (priv->sb_grab_vscroll)
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;
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))
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;
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;
537 - if (bevent->y < vslider_rect.y)
538 + if (y < vslider_rect.y)
539 priv->sb_scroll_direction = -1;
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;
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))
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;
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;
565 - if (bevent->x < hslider_rect.x)
566 + if (x < hslider_rect.x)
567 priv->sb_scroll_direction = -1;
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);
577 + gtk_scrolled_window_translate_coordinates (event_widget, widget,
578 + mevent->x, mevent->y, &x, &y);
580 if (priv->sb_pointer_grabbed)
582 @@ -2611,22 +2775,20 @@ gtk_scrolled_window_captured_motion_notify_scrollbar (GtkWidget *widget,
586 - gtk_scrolled_window_get_child_scroll_areas (scrolled_window,
587 - gtk_bin_get_child (GTK_BIN (widget)),
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);
595 if (priv->sb_grab_vscroll)
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;
602 else if (priv->sb_grab_hscroll)
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;
610 @@ -2641,9 +2803,9 @@ gtk_scrolled_window_captured_motion_notify_scrollbar (GtkWidget *widget,
614 - if (gtk_scrolled_window_over_child_scroll_areas (scrolled_window, event,
615 - mevent->x, mevent->y,
617 + if (gtk_scrolled_window_over_scroll_areas (scrolled_window,
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);
626 /* needed when entering the scrollbar */
627 - gtk_scrolled_window_expose_scrollbars (NULL, scrolled_window);
628 + gtk_scrolled_window_update_scrollbars (scrolled_window);
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");
637 - g_signal_connect_after (child, "expose-event",
638 - G_CALLBACK (gtk_scrolled_window_child_expose),
643 @@ -2857,10 +3015,6 @@ gtk_scrolled_window_remove (GtkContainer *container,
645 priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (container);
647 - g_signal_handlers_disconnect_by_func (child,
648 - gtk_scrolled_window_child_expose,
651 gtk_widget_set_scroll_adjustments (child, NULL, NULL);
653 /* chain parent class handler to remove child */
654 @@ -3033,6 +3187,37 @@ gtk_scrolled_window_realize (GtkWidget *widget)
655 priv->overshoot_window);
657 GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->realize (widget);
659 + gtk_scrolled_window_compute_viewport_allocation (scrolled_window);
661 + GdkWindow *parent_window = gtk_widget_get_window (gtk_widget_get_toplevel (widget));
662 + NSView *layer_view;
663 + CALayer *parent_layer;
665 + layer_view = gdk_quartz_window_get_layer_view (parent_window);
666 + parent_layer = [layer_view layer];
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;
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;
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;
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;
684 + [parent_layer addSublayer:priv->vbar_layer];
685 + [parent_layer addSublayer:priv->vslider_layer];
687 + [parent_layer addSublayer:priv->hbar_layer];
688 + [parent_layer addSublayer:priv->hslider_layer];
692 @@ -3053,6 +3238,22 @@ gtk_scrolled_window_unrealize (GtkWidget *widget)
693 gdk_window_destroy (priv->hbackground_window);
694 priv->hbackground_window = NULL;
696 + [priv->vbar_layer removeFromSuperlayer];
697 + [priv->vbar_layer release];
698 + priv->vbar_layer = NULL;
700 + [priv->vslider_layer removeFromSuperlayer];
701 + [priv->vslider_layer release];
702 + priv->vslider_layer = NULL;
704 + [priv->hbar_layer removeFromSuperlayer];
705 + [priv->hbar_layer release];
706 + priv->hbar_layer = NULL;
708 + [priv->hslider_layer removeFromSuperlayer];
709 + [priv->hslider_layer release];
710 + priv->hslider_layer = NULL;
712 gtk_widget_set_realized (widget, FALSE);
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);
718 GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->map (widget);
720 + if (priv->overlay_scrollbars)
721 + gtk_scrolled_window_map_layers (scrolled_window);
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);
729 + /* Always unmap the layers, regardless of overlay state */
730 + gtk_scrolled_window_unmap_layers (scrolled_window);
732 GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->unmap (widget);
735 @@ -3117,75 +3324,25 @@ gtk_scrolled_window_grab_notify (GtkWidget *widget,
740 -gtk_scrolled_window_rounded_rectangle (cairo_t *cr,
758 - x_radius = MIN (x_radius, width / 2.0);
759 - y_radius = MIN (y_radius, height / 2.0);
762 - xr2 = x_radius / 2.0;
764 - yr2 = y_radius / 2.0;
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);
779 -gtk_scrolled_window_over_child_scroll_areas (GtkScrolledWindow *scrolled_window,
783 - gboolean *over_vscroll,
784 - gboolean *over_hscroll)
785 +gtk_scrolled_window_over_scroll_areas (GtkScrolledWindow *scrolled_window,
788 + gboolean *over_vscroll,
789 + gboolean *over_hscroll)
791 GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
793 GdkRectangle vbar_rect;
794 GdkRectangle hbar_rect;
795 gboolean over_v = FALSE;
796 gboolean over_h = FALSE;
798 - child = gtk_bin_get_child (GTK_BIN (scrolled_window));
802 - if (gtk_get_event_widget (event) != child)
805 if (gtk_adjustment_get_value (priv->opacity) == 0.0)
808 - gtk_scrolled_window_get_child_scroll_areas (scrolled_window,
810 - ((GdkEventAny *) event)->window,
813 + gtk_scrolled_window_get_scroll_areas (scrolled_window,
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,
823 -gtk_scrolled_window_get_child_scroll_areas (GtkScrolledWindow *scrolled_window,
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)
836 GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
838 - GtkAllocation allocation;
843 - gdouble value_h = 0.0;
844 - gdouble value_v = 0.0;
851 - gint window_height;
853 gint viewport_height;
857 - window_width = gdk_window_get_width (child_window);
858 - window_height = gdk_window_get_height (child_window);
860 - gtk_widget_get_allocation (child, &allocation);
862 - viewport_width = MIN (window_width, allocation.width);
863 - viewport_height = MIN (window_height, allocation.height);
865 - if (scrolled_window->vscrollbar)
867 - adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar));
869 - value_v = gtk_adjustment_get_value (adj);
872 - if (scrolled_window->hscrollbar)
874 - adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar));
876 - value_h = gtk_adjustment_get_value (adj);
879 - if (window_width > allocation.width)
880 - offset_x = value_h;
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;
887 if ((vbar_rect || vslider_rect) && scrolled_window->vscrollbar)
889 adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar));
895 "page-size", &page_size,
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;
904 ratio = page_size / (upper - lower);
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));
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;
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));
923 "page-size", &page_size,
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;
932 ratio = page_size / (upper - lower);
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));
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;
944 @@ -3384,69 +3524,6 @@ gtk_scrolled_window_get_child_scroll_areas (GtkScrolledWindow *scrolled_window,
949 -gtk_scrolled_window_child_expose (GtkWidget *widget,
950 - GdkEventExpose *eevent,
951 - GtkScrolledWindow *scrolled_window)
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;
960 - if (!priv->overlay_scrollbars)
963 - cr = gdk_cairo_create (eevent->window);
964 - gdk_cairo_region (cr, eevent->region);
967 - gtk_scrolled_window_get_child_scroll_areas (scrolled_window,
968 - gtk_bin_get_child (GTK_BIN (scrolled_window)),
970 - &vbar_rect, &vslider_rect,
971 - &hbar_rect, &hslider_rect);
973 - if (priv->sb_visible)
975 - if (scrolled_window->vscrollbar && vbar_rect.width > 0)
976 - gdk_cairo_rectangle (cr, &vbar_rect);
978 - if (scrolled_window->hscrollbar && hbar_rect.width > 0)
979 - gdk_cairo_rectangle (cr, &hbar_rect);
981 - cairo_set_source_rgba (cr, 0, 0, 0, gtk_adjustment_get_value (priv->opacity) / 2.0);
985 - if (scrolled_window->vscrollbar && vslider_rect.width > 0)
986 - gtk_scrolled_window_rounded_rectangle (cr,
989 - vslider_rect.width,
990 - vslider_rect.height,
994 - if (scrolled_window->hscrollbar && hslider_rect.width > 0)
995 - gtk_scrolled_window_rounded_rectangle (cr,
998 - hslider_rect.width,
999 - hslider_rect.height,
1003 - cairo_set_source_rgba (cr, 0, 0, 0, gtk_adjustment_get_value (priv->opacity));
1006 - cairo_destroy (cr);
1012 gtk_scrolled_window_cancel_animation (GtkScrolledWindow *scrolled_window)
1014 @@ -3541,39 +3618,6 @@ gtk_scrolled_window_start_fade_out_animation (GtkScrolledWindow *scrolled_window
1018 -gtk_scrolled_window_expose_scrollbars (GtkAdjustment *adj,
1019 - GtkScrolledWindow *scrolled_window)
1021 - GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
1023 - if (priv->overlay_scrollbars)
1025 - GtkWidget *child = gtk_bin_get_child (GTK_BIN (scrolled_window));
1027 - if (child && gtk_widget_get_visible (child))
1029 - GtkAllocation alloc;
1031 - gtk_widget_get_allocation (child, &alloc);
1033 - if (scrolled_window->vscrollbar)
1034 - gtk_widget_queue_draw_area (child,
1040 - if (scrolled_window->hscrollbar)
1041 - gtk_widget_queue_draw_area (child,
1043 - alloc.height - 20,
1051 gtk_scrolled_window_init_overlay_scrollbars (GtkScrolledWindow *scrolled_window)
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,
1058 + if (priv->overlay_scrollbars)
1059 + gtk_scrolled_window_map_layers (GTK_SCROLLED_WINDOW (user_data));
1061 + gtk_scrolled_window_unmap_layers (GTK_SCROLLED_WINDOW (user_data));
1063 gtk_widget_queue_resize (user_data);
1067 +gtk_scrolled_window_map_layers (GtkScrolledWindow *scrolled_window)
1069 + GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
1071 + priv->vbar_layer.hidden = NO;
1072 + priv->vslider_layer.hidden = NO;
1074 + priv->hbar_layer.hidden = NO;
1075 + priv->hslider_layer.hidden = NO;
1079 +gtk_scrolled_window_unmap_layers (GtkScrolledWindow *scrolled_window)
1081 + GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
1083 + priv->vbar_layer.hidden = YES;
1084 + [priv->vbar_layer setNeedsDisplay];
1086 + priv->vslider_layer.hidden = YES;
1087 + [priv->vslider_layer setNeedsDisplay];
1089 + priv->hbar_layer.hidden = YES;
1090 + [priv->hbar_layer setNeedsDisplay];
1092 + priv->hslider_layer.hidden = YES;
1093 + [priv->hslider_layer setNeedsDisplay];
1096 #define __GTK_SCROLLED_WINDOW_C__
1097 #include "gtkaliasdef.c"
1099 1.7.10.2 (Apple Git-33)