Merge lp:~cimi/overlay-scrollbar/0.2-refactoring into lp:overlay-scrollbar

Proposed by Andrea Cimitan
Status: Merged
Approved by: Ted Gould
Approved revision: 239
Merged at revision: 238
Proposed branch: lp:~cimi/overlay-scrollbar/0.2-refactoring
Merge into: lp:overlay-scrollbar
Diff against target: 2609 lines (+955/-960)
4 files modified
os/os-animation.c (+33/-37)
os/os-pager.c (+184/-192)
os/os-scrollbar.c (+626/-618)
os/os-thumb.c (+112/-113)
To merge this branch: bzr merge lp:~cimi/overlay-scrollbar/0.2-refactoring
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Review via email: mp+61454@code.launchpad.net

Description of the change

Functions moved, comments, etc etc...

........(compiles) :D

To post a comment you must log in.
239. By Andrea Cimitan

Renamed xevent into xev to save space

Revision history for this message
Ted Gould (ted) wrote :

Wow, major reshuffle. Kinda hard to trace everything in the diff, but I couldn't find anything unexpected.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'os/os-animation.c'
2--- os/os-animation.c 2011-04-04 16:17:15 +0000
3+++ os/os-animation.c 2011-05-18 18:39:29 +0000
4@@ -37,45 +37,9 @@
5 guint32 source_id;
6 };
7
8-static gboolean os_animation_update_cb (gpointer user_data);
9 static void os_animation_dispose (GObject* object);
10 static void os_animation_finalize (GObject* object);
11
12-/* Private functions. */
13-
14-static gboolean
15-os_animation_update_cb (gpointer user_data)
16-{
17- OsAnimation *animation = OS_ANIMATION (user_data);
18- OsAnimationPrivate *priv = animation->priv;
19- const gint64 current_time = g_get_monotonic_time ();
20- const gint64 end_time = priv->start_time + priv->duration;
21-
22- if (current_time < end_time)
23- {
24- /* On-going animation. */
25- const gfloat diff_time = current_time - priv->start_time;
26- const gfloat weight = diff_time / priv->duration;
27-
28- priv->update_func (weight, priv->user_data);
29-
30- return TRUE;
31- }
32- else
33- {
34- /* Animation ended. */
35- priv->update_func (1.0f, priv->user_data);
36- priv->source_id = 0;
37-
38- if (priv->end_func != NULL)
39- priv->end_func (priv->user_data);
40-
41- return FALSE;
42- }
43-}
44-
45-/* Type definition. */
46-
47 G_DEFINE_TYPE (OsAnimation, os_animation, G_TYPE_OBJECT);
48
49 static void
50@@ -189,6 +153,38 @@
51 priv->duration = (gint64) duration * G_GINT64_CONSTANT (1000);
52 }
53
54+/* callback called by the animation */
55+static gboolean
56+update_cb (gpointer user_data)
57+{
58+ OsAnimation *animation = OS_ANIMATION (user_data);
59+ OsAnimationPrivate *priv = animation->priv;
60+ const gint64 current_time = g_get_monotonic_time ();
61+ const gint64 end_time = priv->start_time + priv->duration;
62+
63+ if (current_time < end_time)
64+ {
65+ /* On-going animation. */
66+ const gfloat diff_time = current_time - priv->start_time;
67+ const gfloat weight = diff_time / priv->duration;
68+
69+ priv->update_func (weight, priv->user_data);
70+
71+ return TRUE;
72+ }
73+ else
74+ {
75+ /* Animation ended. */
76+ priv->update_func (1.0f, priv->user_data);
77+ priv->source_id = 0;
78+
79+ if (priv->end_func != NULL)
80+ priv->end_func (priv->user_data);
81+
82+ return FALSE;
83+ }
84+}
85+
86 /**
87 * os_animation_start:
88 * @animation: a #OsAnimation
89@@ -207,7 +203,7 @@
90 if (priv->source_id == 0)
91 {
92 priv->start_time = g_get_monotonic_time ();
93- priv->source_id = g_timeout_add (priv->rate, os_animation_update_cb, animation);
94+ priv->source_id = g_timeout_add (priv->rate, update_cb, animation);
95 }
96 }
97
98
99=== modified file 'os/os-pager.c'
100--- os/os-pager.c 2011-05-12 23:39:33 +0000
101+++ os/os-pager.c 2011-05-18 18:39:29 +0000
102@@ -49,135 +49,40 @@
103 gboolean detached;
104 gboolean visible;
105 gfloat weight;
106- gint width;
107- gint height;
108 gulong handler_id;
109 };
110
111-static gboolean rectangle_changed (GdkRectangle rectangle1, GdkRectangle rectangle2);
112 static void os_pager_dispose (GObject *object);
113 static void os_pager_finalize (GObject *object);
114-static void os_pager_change_state_cb (gfloat weight, gpointer user_data);
115-static void os_pager_create (OsPager *pager);
116-static void os_pager_draw (OsPager *pager);
117-static void os_pager_draw_connection (OsPager *pager);
118-static void os_pager_mask (OsPager *pager);
119-static void os_pager_notify_gtk_theme_name_cb (GObject *object, GParamSpec* pspec, gpointer user_data);
120
121 /* Private functions */
122
123-static gboolean
124-rectangle_changed (GdkRectangle rectangle1,
125- GdkRectangle rectangle2)
126-{
127- if (rectangle1.x != rectangle2.x) return TRUE;
128- if (rectangle1.y != rectangle2.y) return TRUE;
129- if (rectangle1.width != rectangle2.width) return TRUE;
130- if (rectangle1.height != rectangle2.height) return TRUE;
131-
132- return FALSE;
133-}
134-
135-/* Create a pager. */
136-static void
137-os_pager_create (OsPager *pager)
138-{
139- GdkWindowAttr attributes;
140- OsPagerPrivate *priv;
141-
142- priv = pager->priv;
143-
144- /* Instead reparenting,
145- * which doesn't seem to work well,
146- * destroy the two windows. */
147- if (priv->connection_window != NULL)
148- {
149- /* From the Gdk documentation:
150- * "Note that a window will not be destroyed
151- * automatically when its reference count
152- * reaches zero. You must call
153- * gdk_window_destroy ()
154- * yourself before that happens". */
155- gdk_window_destroy (priv->connection_window);
156-
157- g_object_unref (priv->connection_window);
158- priv->connection_window = NULL;
159- }
160-
161- if (priv->pager_window != NULL)
162- {
163- /* From the Gdk documentation:
164- * "Note that a window will not be destroyed
165- * automatically when its reference count
166- * reaches zero. You must call
167- * gdk_window_destroy ()
168- * yourself before that happens". */
169- gdk_window_destroy (priv->pager_window);
170-
171- g_object_unref (priv->pager_window);
172- priv->pager_window = NULL;
173- }
174-
175- attributes.width = priv->allocation.width;
176- attributes.height = priv->allocation.height;
177- attributes.wclass = GDK_INPUT_OUTPUT;
178- attributes.window_type = GDK_WINDOW_CHILD;
179- attributes.visual = gtk_widget_get_visual (priv->parent);
180- attributes.colormap = gtk_widget_get_colormap (priv->parent);
181-
182- /* connection_window */
183- priv->connection_window = gdk_window_new (gtk_widget_get_window (priv->parent),
184- &attributes,
185- GDK_WA_VISUAL | GDK_WA_COLORMAP);
186-
187- g_object_ref_sink (priv->connection_window);
188-
189- gdk_window_set_transient_for (priv->connection_window,
190- gtk_widget_get_window (priv->parent));
191-
192- gdk_window_input_shape_combine_region (priv->connection_window,
193- gdk_region_new (),
194- 0, 0);
195-
196- /* pager_window */
197- priv->pager_window = gdk_window_new (gtk_widget_get_window (priv->parent),
198- &attributes,
199- GDK_WA_VISUAL | GDK_WA_COLORMAP);
200-
201- g_object_ref_sink (priv->pager_window);
202-
203- /* stay above the connection_window */
204- gdk_window_set_transient_for (priv->pager_window,
205- priv->connection_window);
206-
207- gdk_window_input_shape_combine_region (priv->pager_window,
208- gdk_region_new (),
209- 0, 0);
210-}
211-
212-static void
213-os_pager_change_state_cb (gfloat weight,
214- gpointer user_data)
215-{
216- OsPager *pager;
217- OsPagerPrivate *priv;
218-
219- pager = OS_PAGER (user_data);
220-
221- priv = pager->priv;
222-
223- priv->weight = weight;
224-
225- if (priv->parent == NULL)
226- return;
227-
228- os_pager_draw_connection (pager);
229- os_pager_draw (pager);
230-}
231-
232-/* Draw on the pager_window. */
233-static void
234-os_pager_draw (OsPager *pager)
235+/* draw on the connection_window */
236+static void
237+draw_connection (OsPager *pager)
238+{
239+ GdkColor color;
240+ OsPagerPrivate *priv;
241+
242+ priv = pager->priv;
243+
244+ /* 0.6 is taken from os_thumb_expose. */
245+ color.red = 65535 * 0.6;
246+ color.green = 65535 * 0.6;
247+ color.blue = 65535 * 0.6;
248+
249+ gdk_colormap_alloc_color (gdk_drawable_get_colormap (priv->connection_window), &color, FALSE, TRUE);
250+
251+ gdk_window_set_background (priv->connection_window, &color);
252+
253+ gdk_window_clear (priv->connection_window);
254+
255+ gdk_window_invalidate_rect (gtk_widget_get_window (priv->parent), &priv->allocation, TRUE);
256+}
257+
258+/* draw on the pager_window */
259+static void
260+draw_pager (OsPager *pager)
261 {
262 GdkColor c1, c2, color;
263 GtkStyle *style;
264@@ -214,63 +119,32 @@
265 gdk_window_invalidate_rect (gtk_widget_get_window (priv->parent), &priv->allocation, TRUE);
266 }
267
268-/* Draw on the connection_window. */
269-static void
270-os_pager_draw_connection (OsPager *pager)
271-{
272- GdkColor color;
273- OsPagerPrivate *priv;
274-
275- priv = pager->priv;
276-
277- /* 0.6 is taken from os_thumb_expose. */
278- color.red = 65535 * 0.6;
279- color.green = 65535 * 0.6;
280- color.blue = 65535 * 0.6;
281-
282- gdk_colormap_alloc_color (gdk_drawable_get_colormap (priv->connection_window), &color, FALSE, TRUE);
283-
284- gdk_window_set_background (priv->connection_window, &color);
285-
286- gdk_window_clear (priv->connection_window);
287-
288- gdk_window_invalidate_rect (gtk_widget_get_window (priv->parent), &priv->allocation, TRUE);
289-}
290-
291-/* Mask the pager_window. */
292-static void
293-os_pager_mask (OsPager *pager)
294-{
295- OsPagerPrivate *priv;
296-
297- priv = pager->priv;
298-
299- gdk_window_shape_combine_region (priv->pager_window,
300- gdk_region_rectangle (&priv->mask),
301- 0, 0);
302-
303- gdk_window_clear (priv->pager_window);
304-}
305-
306-/* Mask the connection_window. */
307-static void
308-os_pager_mask_connection (OsPager *pager)
309-{
310- OsPagerPrivate *priv;
311-
312- priv = pager->priv;
313-
314- gdk_window_shape_combine_region (priv->connection_window,
315- gdk_region_rectangle (&priv->connection_mask),
316- 0, 0);
317-
318- gdk_window_clear (priv->connection_window);
319-}
320-
321-static void
322-os_pager_notify_gtk_theme_name_cb (GObject* gobject,
323- GParamSpec* pspec,
324- gpointer user_data)
325+/* callback called by the change-state animation */
326+static void
327+change_state_cb (gfloat weight,
328+ gpointer user_data)
329+{
330+ OsPager *pager;
331+ OsPagerPrivate *priv;
332+
333+ pager = OS_PAGER (user_data);
334+
335+ priv = pager->priv;
336+
337+ priv->weight = weight;
338+
339+ if (priv->parent == NULL)
340+ return;
341+
342+ draw_connection (pager);
343+ draw_pager (pager);
344+}
345+
346+/* callback called when the Gtk+ theme changes */
347+static void
348+notify_gtk_theme_name_cb (GObject* gobject,
349+ GParamSpec* pspec,
350+ gpointer user_data)
351 {
352 OsPager *pager;
353 OsPagerPrivate *priv;
354@@ -283,11 +157,22 @@
355 priv->connection_window == NULL)
356 return;
357
358- os_pager_draw_connection (pager);
359- os_pager_draw (pager);
360-}
361-
362-/* Type definition. */
363+ draw_connection (pager);
364+ draw_pager (pager);
365+}
366+
367+/* check if two GdkRectangle are different */
368+static gboolean
369+rectangle_changed (GdkRectangle rectangle1,
370+ GdkRectangle rectangle2)
371+{
372+ if (rectangle1.x != rectangle2.x) return TRUE;
373+ if (rectangle1.y != rectangle2.y) return TRUE;
374+ if (rectangle1.width != rectangle2.width) return TRUE;
375+ if (rectangle1.height != rectangle2.height) return TRUE;
376+
377+ return FALSE;
378+}
379
380 G_DEFINE_TYPE (OsPager, os_pager, G_TYPE_OBJECT);
381
382@@ -335,10 +220,10 @@
383 priv->weight = 1.0f;
384
385 priv->animation = os_animation_new (RATE_FADE, DURATION_FADE_OUT,
386- os_pager_change_state_cb, NULL, pager);
387+ change_state_cb, NULL, pager);
388
389 priv->handler_id = g_signal_connect (gtk_settings_get_default (), "notify::gtk-theme-name",
390- G_CALLBACK (os_pager_notify_gtk_theme_name_cb), pager);
391+ G_CALLBACK (notify_gtk_theme_name_cb), pager);
392 }
393
394 static void
395@@ -413,6 +298,21 @@
396 return g_object_new (OS_TYPE_PAGER, NULL);
397 }
398
399+/* move a mask on the connection_window, fake movement */
400+static void
401+mask_connection (OsPager *pager)
402+{
403+ OsPagerPrivate *priv;
404+
405+ priv = pager->priv;
406+
407+ gdk_window_shape_combine_region (priv->connection_window,
408+ gdk_region_rectangle (&priv->connection_mask),
409+ 0, 0);
410+
411+ gdk_window_clear (priv->connection_window);
412+}
413+
414 /**
415 * os_pager_connect:
416 * @pager: a #OsPager
417@@ -438,7 +338,7 @@
418 if (priv->parent == NULL)
419 return;
420
421- os_pager_mask_connection (pager);
422+ mask_connection (pager);
423 }
424
425 /**
426@@ -468,6 +368,21 @@
427 gdk_window_hide (priv->pager_window);
428 }
429
430+/* move a mask on the pager_window, fake movement */
431+static void
432+mask_pager (OsPager *pager)
433+{
434+ OsPagerPrivate *priv;
435+
436+ priv = pager->priv;
437+
438+ gdk_window_shape_combine_region (priv->pager_window,
439+ gdk_region_rectangle (&priv->mask),
440+ 0, 0);
441+
442+ gdk_window_clear (priv->pager_window);
443+}
444+
445 /**
446 * os_pager_move_resize:
447 * @pager: a #OsPager
448@@ -493,7 +408,7 @@
449 if (priv->parent == NULL)
450 return;
451
452- os_pager_mask (pager);
453+ mask_pager (pager);
454 }
455
456 /**
457@@ -534,7 +449,7 @@
458 {
459 priv->weight = 1.0f;
460
461- os_pager_draw (pager);
462+ draw_pager (pager);
463 }
464 }
465 }
466@@ -574,6 +489,83 @@
467 }
468 }
469
470+/* create connection_window and pager_window */
471+static void
472+create_windows (OsPager *pager)
473+{
474+ GdkWindowAttr attributes;
475+ OsPagerPrivate *priv;
476+
477+ priv = pager->priv;
478+
479+ /* Instead reparenting,
480+ * which doesn't seem to work well,
481+ * destroy the two windows. */
482+ if (priv->connection_window != NULL)
483+ {
484+ /* From the Gdk documentation:
485+ * "Note that a window will not be destroyed
486+ * automatically when its reference count
487+ * reaches zero. You must call
488+ * gdk_window_destroy ()
489+ * yourself before that happens". */
490+ gdk_window_destroy (priv->connection_window);
491+
492+ g_object_unref (priv->connection_window);
493+ priv->connection_window = NULL;
494+ }
495+
496+ if (priv->pager_window != NULL)
497+ {
498+ /* From the Gdk documentation:
499+ * "Note that a window will not be destroyed
500+ * automatically when its reference count
501+ * reaches zero. You must call
502+ * gdk_window_destroy ()
503+ * yourself before that happens". */
504+ gdk_window_destroy (priv->pager_window);
505+
506+ g_object_unref (priv->pager_window);
507+ priv->pager_window = NULL;
508+ }
509+
510+ attributes.width = priv->allocation.width;
511+ attributes.height = priv->allocation.height;
512+ attributes.wclass = GDK_INPUT_OUTPUT;
513+ attributes.window_type = GDK_WINDOW_CHILD;
514+ attributes.visual = gtk_widget_get_visual (priv->parent);
515+ attributes.colormap = gtk_widget_get_colormap (priv->parent);
516+
517+ /* connection_window */
518+ priv->connection_window = gdk_window_new (gtk_widget_get_window (priv->parent),
519+ &attributes,
520+ GDK_WA_VISUAL | GDK_WA_COLORMAP);
521+
522+ g_object_ref_sink (priv->connection_window);
523+
524+ gdk_window_set_transient_for (priv->connection_window,
525+ gtk_widget_get_window (priv->parent));
526+
527+ gdk_window_input_shape_combine_region (priv->connection_window,
528+ gdk_region_new (),
529+ 0, 0);
530+
531+ /* pager_window */
532+ priv->pager_window = gdk_window_new (gtk_widget_get_window (priv->parent),
533+ &attributes,
534+ GDK_WA_VISUAL | GDK_WA_COLORMAP);
535+
536+ g_object_ref_sink (priv->pager_window);
537+
538+ /* stay above the connection_window */
539+ gdk_window_set_transient_for (priv->pager_window,
540+ priv->connection_window);
541+
542+ gdk_window_input_shape_combine_region (priv->pager_window,
543+ gdk_region_new (),
544+ 0, 0);
545+}
546+
547 /**
548 * os_pager_set_parent:
549 * @pager: a #OsPager
550@@ -608,10 +600,10 @@
551
552 priv->weight = 1.0f;
553
554- os_pager_create (pager);
555- os_pager_draw_connection (pager);
556- os_pager_draw (pager);
557- os_pager_mask (pager);
558+ create_windows (pager);
559+ draw_connection (pager);
560+ draw_pager (pager);
561+ mask_pager (pager);
562
563 gdk_window_move_resize (priv->connection_window,
564 priv->allocation.x,
565
566=== modified file 'os/os-scrollbar.c'
567--- os/os-scrollbar.c 2011-05-17 20:54:31 +0000
568+++ os/os-scrollbar.c 2011-05-18 18:39:29 +0000
569@@ -65,12 +65,12 @@
570 gboolean active_window;
571 gboolean can_deactivate_pager;
572 gboolean can_hide;
573- gboolean toplevel_button_press;
574 gboolean filter;
575 gboolean fullsize;
576 gboolean internal;
577 gboolean lock_position;
578 gboolean proximity;
579+ gboolean toplevel_button_press;
580 gint win_x;
581 gint win_y;
582 gint slide_initial_slider_position;
583@@ -86,7 +86,20 @@
584 static Atom net_active_window_atom = None;
585 static GList *os_root_list = NULL;
586
587+static void swap_adjustment (OsScrollbar *scrollbar, GtkAdjustment *adjustment);
588+static void swap_thumb (OsScrollbar *scrollbar, GtkWidget *thumb);
589+static void adjustment_changed_cb (GtkAdjustment *adjustment, gpointer user_data);
590+static void adjustment_value_changed_cb (GtkAdjustment *adjustment, gpointer user_data);
591+static gboolean thumb_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
592+static gboolean thumb_button_release_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
593+static gboolean thumb_enter_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data);
594+static gboolean thumb_leave_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data);
595+static void thumb_map_cb (GtkWidget *widget, gpointer user_data);
596+static gboolean thumb_motion_notify_event_cb (GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
597+static gboolean thumb_scroll_event_cb (GtkWidget *widget, GdkEventScroll *event, gpointer user_data);
598+static void thumb_unmap_cb (GtkWidget *widget, gpointer user_data);
599 static gboolean os_scrollbar_expose_event (GtkWidget *widget, GdkEventExpose *event);
600+
601 static void os_scrollbar_grab_notify (GtkWidget *widget, gboolean was_grabbed);
602 static void os_scrollbar_hide (GtkWidget *widget);
603 static void os_scrollbar_map (GtkWidget *widget);
604@@ -98,98 +111,13 @@
605 static void os_scrollbar_unrealize (GtkWidget *widget);
606 static void os_scrollbar_dispose (GObject *object);
607 static void os_scrollbar_finalize (GObject *object);
608-static void os_scrollbar_calc_layout_pager (OsScrollbar *scrollbar, gdouble adjustment_value);
609-static void os_scrollbar_calc_layout_slider (OsScrollbar *scrollbar, gdouble adjustment_value);
610-static gdouble os_scrollbar_coord_to_value (OsScrollbar *scrollbar, gint coord);
611-static void os_scrollbar_deactivate_pager (OsScrollbar *scrollbar);
612-static gboolean os_scrollbar_deactivate_pager_cb (gpointer user_data);
613-static gdouble os_scrollbar_get_wheel_delta (OsScrollbar *scrollbar, GdkScrollDirection direction);
614-static void os_scrollbar_hide_thumb (OsScrollbar *scrollbar);
615-static gboolean os_scrollbar_hide_thumb_cb (gpointer user_data);
616-static gboolean os_scrollbar_unlock_thumb_cb (gpointer user_data);
617-static void os_scrollbar_move (OsScrollbar *scrollbar, gint mouse_x, gint mouse_y);
618-static void os_scrollbar_move_thumb (OsScrollbar *scrollbar, gint x, gint y);
619-static void os_scrollbar_notify_adjustment_cb (GObject *object, gpointer user_data);
620-static void os_scrollbar_notify_orientation_cb (GObject *object, gpointer user_data);
621-static gint os_scrollbar_sanitize_x (OsScrollbar *scrollbar, gint x, gint y);
622-static gint os_scrollbar_sanitize_y (OsScrollbar *scrollbar, gint x, gint y);
623-static void os_scrollbar_store_window_position (OsScrollbar *scrollbar);
624-static void os_scrollbar_swap_adjustment (OsScrollbar *scrollbar, GtkAdjustment *adjustment);
625-static void os_scrollbar_swap_thumb (OsScrollbar *scrollbar, GtkWidget *thumb);
626-static gboolean thumb_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
627-static gboolean thumb_button_release_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
628-static gboolean thumb_enter_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data);
629-static gboolean thumb_leave_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data);
630-static void thumb_map_cb (GtkWidget *widget, gpointer user_data);
631-static gboolean thumb_motion_notify_event_cb (GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
632-static gboolean thumb_scroll_event_cb (GtkWidget *widget, GdkEventScroll *event, gpointer user_data);
633-static void thumb_unmap_cb (GtkWidget *widget, gpointer user_data);
634-static void pager_move (OsScrollbar *scrollbar);
635-static void pager_set_state_from_pointer (OsScrollbar *scrollbar, gint x, gint y);
636-static void adjustment_changed_cb (GtkAdjustment *adjustment, gpointer user_data);
637-static void adjustment_value_changed_cb (GtkAdjustment *adjustment, gpointer user_data);
638-static GdkFilterReturn root_filter_func (GdkXEvent *gdkxevent, GdkEvent *event, gpointer user_data);
639-static void root_gfunc (gpointer data, gpointer user_data);
640-static gboolean toplevel_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, gpointer user_data);
641-static GdkFilterReturn toplevel_filter_func (GdkXEvent *gdkxevent, GdkEvent *event, gpointer user_data);
642
643 /* Private functions. */
644
645-/* Present a X11 window. */
646-static void
647-os_present_window_with_timestamp (Screen *screen,
648- gint xid,
649- guint32 timestamp)
650-{
651- Display *display;
652- Window root;
653- XEvent xev;
654-
655- if (timestamp == 0)
656- g_warning ("Received a timestamp of 0; window activation may not "
657- "function properly.\n");
658-
659- display = DisplayOfScreen (screen);
660- root = RootWindowOfScreen (screen);
661-
662- xev.xclient.type = ClientMessage;
663- xev.xclient.serial = 0;
664- xev.xclient.send_event = True;
665- xev.xclient.display = display;
666- xev.xclient.window = xid;
667- xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW");
668- xev.xclient.format = 32;
669- xev.xclient.data.l[0] = 1;
670- xev.xclient.data.l[1] = timestamp;
671- xev.xclient.data.l[2] = 0;
672- xev.xclient.data.l[3] = 0;
673- xev.xclient.data.l[4] = 0;
674-
675- gdk_error_trap_push ();
676-
677- XSendEvent (display, root, False,
678- SubstructureRedirectMask | SubstructureNotifyMask,
679- &xev);
680-
681- gdk_flush ();
682-
683- gdk_error_trap_pop ();
684-}
685-
686-/* Present a GDK window. */
687-static void
688-os_present_gdk_window_with_timestamp (GtkWidget *widget,
689- guint32 timestamp)
690-{
691- os_present_window_with_timestamp (GDK_SCREEN_XSCREEN (gtk_widget_get_screen (widget)),
692- GDK_WINDOW_XID (gtk_widget_get_window (widget)),
693- timestamp);
694-}
695-
696-/* Calculate layout and store info. */
697-static void
698-os_scrollbar_calc_layout_pager (OsScrollbar *scrollbar,
699- gdouble adjustment_value)
700+/* calculate pager layout info */
701+static void
702+calc_layout_pager (OsScrollbar *scrollbar,
703+ gdouble adjustment_value)
704 {
705 OsScrollbarPrivate *priv;
706
707@@ -261,10 +189,10 @@
708 }
709 }
710
711-/* Calculate OsScrollbar layout and store info. */
712+/* calculate slider (thumb) layout info */
713 static void
714-os_scrollbar_calc_layout_slider (OsScrollbar *scrollbar,
715- gdouble adjustment_value)
716+calc_layout_slider (OsScrollbar *scrollbar,
717+ gdouble adjustment_value)
718 {
719 OsScrollbarPrivate *priv;
720
721@@ -316,51 +244,9 @@
722 }
723 }
724
725-/* Traduce pixels into proper values. */
726-static gdouble
727-os_scrollbar_coord_to_value (OsScrollbar *scrollbar,
728- gint coord)
729-{
730- OsScrollbarPrivate *priv;
731- gdouble frac;
732- gdouble value;
733- gint trough_length;
734- gint trough_start;
735- gint slider_length;
736-
737- priv = scrollbar->priv;
738-
739- if (priv->orientation == GTK_ORIENTATION_VERTICAL)
740- {
741- trough_length = priv->trough.height;
742- trough_start = priv->trough.y;
743- slider_length = MAX (priv->slider.height, priv->overlay.height);
744- }
745- else
746- {
747- trough_length = priv->trough.width;
748- trough_start = priv->trough.y;
749- slider_length = MAX (priv->slider.width, priv->overlay.width);
750- }
751-
752- if (trough_length == slider_length)
753- frac = 1.0;
754- else
755- frac = (MAX (0, coord - trough_start) /
756- (gdouble) (trough_length - slider_length));
757-
758- value = priv->adjustment->lower + frac * (priv->adjustment->upper -
759- priv->adjustment->lower -
760- priv->adjustment->page_size);
761-
762- value = CLAMP (value, priv->adjustment->lower, priv->adjustment->upper - priv->adjustment->page_size);
763-
764- return value;
765-}
766-
767-/* Deactivate pager if it's ok to make it inactive. */
768+/* deactivate the pager if it's the case */
769 static void
770-os_scrollbar_deactivate_pager (OsScrollbar *scrollbar)
771+deactivate_pager (OsScrollbar *scrollbar)
772 {
773 OsScrollbarPrivate *priv;
774
775@@ -370,8 +256,9 @@
776 os_pager_set_active (OS_PAGER (priv->pager), FALSE);
777 }
778
779+/* timeout before deactivating the pager */
780 static gboolean
781-os_scrollbar_deactivate_pager_cb (gpointer user_data)
782+deactivate_pager_cb (gpointer user_data)
783 {
784 OsScrollbar *scrollbar;
785 OsScrollbarPrivate *priv;
786@@ -381,33 +268,15 @@
787
788 OS_DCHECK (!priv->active_window);
789
790- os_scrollbar_deactivate_pager (scrollbar);
791+ deactivate_pager (scrollbar);
792 priv->source_deactivate_pager_id = 0;
793
794 return FALSE;
795 }
796
797-static gdouble
798-os_scrollbar_get_wheel_delta (OsScrollbar *scrollbar,
799- GdkScrollDirection direction)
800-{
801- OsScrollbarPrivate *priv;
802- gdouble delta;
803-
804- priv = scrollbar->priv;
805-
806- delta = pow (priv->adjustment->page_size, 2.0 / 3.0);
807-
808- if (direction == GDK_SCROLL_UP ||
809- direction == GDK_SCROLL_LEFT)
810- delta = - delta;
811-
812- return delta;
813-}
814-
815-/* Hide if it's ok to hide. */
816+/* hide the thumb if it's the case */
817 static void
818-os_scrollbar_hide_thumb (OsScrollbar *scrollbar)
819+hide_thumb (OsScrollbar *scrollbar)
820 {
821 OsScrollbarPrivate *priv;
822
823@@ -420,8 +289,9 @@
824 }
825 }
826
827+/* timeout before hiding the thumb */
828 static gboolean
829-os_scrollbar_hide_thumb_cb (gpointer user_data)
830+hide_thumb_cb (gpointer user_data)
831 {
832 OsScrollbar *scrollbar;
833 OsScrollbarPrivate *priv;
834@@ -429,97 +299,44 @@
835 scrollbar = OS_SCROLLBAR (user_data);
836 priv = scrollbar->priv;
837
838- os_scrollbar_hide_thumb (scrollbar);
839+ hide_thumb (scrollbar);
840 priv->source_hide_thumb_id = 0;
841
842 return FALSE;
843 }
844
845-static gboolean
846-os_scrollbar_unlock_thumb_cb (gpointer user_data)
847-{
848- OsScrollbar *scrollbar;
849- OsScrollbarPrivate *priv;
850-
851- scrollbar = OS_SCROLLBAR (user_data);
852- priv = scrollbar->priv;
853-
854- if (priv->can_hide)
855- priv->lock_position = FALSE;
856-
857- priv->source_unlock_thumb_id = 0;
858-
859- return FALSE;
860-}
861-
862+/* move the pager */
863 static void
864-os_scrollbar_move (OsScrollbar *scrollbar,
865- gint mouse_x,
866- gint mouse_y)
867+move_pager (OsScrollbar *scrollbar)
868 {
869+ GdkRectangle mask;
870 OsScrollbarPrivate *priv;
871- gint delta;
872- gint c;
873- gdouble new_value;
874
875 priv = scrollbar->priv;
876
877 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
878- delta = mouse_y - priv->slide_initial_coordinate;
879+ {
880+ mask.x = 0;
881+ mask.y = priv->overlay.y;
882+ mask.width = DEFAULT_PAGER_WIDTH;
883+ mask.height = priv->overlay.height;
884+ }
885 else
886- delta = mouse_x - priv->slide_initial_coordinate;
887-
888- c = priv->slide_initial_slider_position + delta;
889-
890- new_value = os_scrollbar_coord_to_value (scrollbar, c);
891-
892- gtk_adjustment_set_value (priv->adjustment, new_value);
893-}
894-
895-static void
896-os_scrollbar_move_thumb (OsScrollbar *scrollbar,
897- gint x,
898- gint y)
899-{
900- OsScrollbarPrivate *priv;
901-
902- priv = scrollbar->priv;
903-
904- gtk_window_move (GTK_WINDOW (priv->thumb),
905- os_scrollbar_sanitize_x (scrollbar, x, y),
906- os_scrollbar_sanitize_y (scrollbar, x, y));
907-}
908-
909-static void
910-os_scrollbar_notify_adjustment_cb (GObject *object,
911- gpointer user_data)
912-{
913- OsScrollbar *scrollbar;
914-
915- scrollbar = OS_SCROLLBAR (object);
916-
917- os_scrollbar_swap_adjustment (scrollbar, gtk_range_get_adjustment (GTK_RANGE (object)));
918-}
919-
920-static void
921-os_scrollbar_notify_orientation_cb (GObject *object,
922- gpointer user_data)
923-{
924- OsScrollbar *scrollbar;
925- OsScrollbarPrivate *priv;
926-
927- scrollbar = OS_SCROLLBAR (object);
928- priv = scrollbar->priv;
929-
930- priv->orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (object));
931-
932- os_scrollbar_swap_thumb (scrollbar, os_thumb_new (priv->orientation));
933-}
934-
935+ {
936+ mask.x = priv->overlay.x;
937+ mask.y = 0;
938+ mask.width = priv->overlay.width;
939+ mask.height = DEFAULT_PAGER_WIDTH;
940+ }
941+
942+ os_pager_move_resize (OS_PAGER (priv->pager), mask);
943+}
944+
945+/* sanitize x coordinate of thumb window */
946 static gint
947-os_scrollbar_sanitize_x (OsScrollbar *scrollbar,
948- gint x,
949- gint y)
950+sanitize_x (OsScrollbar *scrollbar,
951+ gint x,
952+ gint y)
953 {
954 GdkRectangle rect;
955 OsScrollbarPrivate *priv;
956@@ -550,10 +367,11 @@
957 return x;
958 }
959
960+/* sanitize y coordinate of thumb window */
961 static gint
962-os_scrollbar_sanitize_y (OsScrollbar *scrollbar,
963- gint x,
964- gint y)
965+sanitize_y (OsScrollbar *scrollbar,
966+ gint x,
967+ gint y)
968 {
969 GdkRectangle rect;
970 OsScrollbarPrivate *priv;
971@@ -584,33 +402,53 @@
972 return y;
973 }
974
975-/* Store scrollbar window position. */
976-static void
977-os_scrollbar_store_window_position (OsScrollbar *scrollbar)
978-{
979- OsScrollbarPrivate *priv;
980- gint win_x, win_y;
981-
982- priv = scrollbar->priv;
983-
984- gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &win_x, &win_y);
985-
986- if (priv->orientation == GTK_ORIENTATION_VERTICAL)
987- {
988- priv->win_x = win_x + priv->thumb_all.x;
989- priv->win_y = win_y + priv->thumb_all.y;
990- }
991- else
992- {
993- priv->win_x = win_x + priv->thumb_all.x;
994- priv->win_y = win_y + priv->thumb_all.y;
995- }
996-}
997-
998-/* Swap the adjustment pointer. */
999-static void
1000-os_scrollbar_swap_adjustment (OsScrollbar *scrollbar,
1001- GtkAdjustment *adjustment)
1002+/* move the thumb window */
1003+static void
1004+move_thumb (OsScrollbar *scrollbar,
1005+ gint x,
1006+ gint y)
1007+{
1008+ OsScrollbarPrivate *priv;
1009+
1010+ priv = scrollbar->priv;
1011+
1012+ gtk_window_move (GTK_WINDOW (priv->thumb),
1013+ sanitize_x (scrollbar, x, y),
1014+ sanitize_y (scrollbar, x, y));
1015+}
1016+
1017+/* callback called when the adjustment changes */
1018+static void
1019+notify_adjustment_cb (GObject *object,
1020+ gpointer user_data)
1021+{
1022+ OsScrollbar *scrollbar;
1023+
1024+ scrollbar = OS_SCROLLBAR (object);
1025+
1026+ swap_adjustment (scrollbar, gtk_range_get_adjustment (GTK_RANGE (object)));
1027+}
1028+
1029+/* callback called when the orientation changes */
1030+static void
1031+notify_orientation_cb (GObject *object,
1032+ gpointer user_data)
1033+{
1034+ OsScrollbar *scrollbar;
1035+ OsScrollbarPrivate *priv;
1036+
1037+ scrollbar = OS_SCROLLBAR (object);
1038+ priv = scrollbar->priv;
1039+
1040+ priv->orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (object));
1041+
1042+ swap_thumb (scrollbar, os_thumb_new (priv->orientation));
1043+}
1044+
1045+/* swap adjustment pointer */
1046+static void
1047+swap_adjustment (OsScrollbar *scrollbar,
1048+ GtkAdjustment *adjustment)
1049 {
1050 OsScrollbarPrivate *priv;
1051
1052@@ -639,10 +477,10 @@
1053 }
1054 }
1055
1056-/* Swap the thumb pointer. */
1057+/* swap thumb pointer */
1058 static void
1059-os_scrollbar_swap_thumb (OsScrollbar *scrollbar,
1060- GtkWidget *thumb)
1061+swap_thumb (OsScrollbar *scrollbar,
1062+ GtkWidget *thumb)
1063 {
1064 OsScrollbarPrivate *priv;
1065
1066@@ -697,6 +535,353 @@
1067 }
1068 }
1069
1070+/* timeout before unlocking the thumb */
1071+static gboolean
1072+unlock_thumb_cb (gpointer user_data)
1073+{
1074+ OsScrollbar *scrollbar;
1075+ OsScrollbarPrivate *priv;
1076+
1077+ scrollbar = OS_SCROLLBAR (user_data);
1078+ priv = scrollbar->priv;
1079+
1080+ if (priv->can_hide)
1081+ priv->lock_position = FALSE;
1082+
1083+ priv->source_unlock_thumb_id = 0;
1084+
1085+ return FALSE;
1086+}
1087+
1088+/* adjustment functions */
1089+
1090+static void
1091+adjustment_changed_cb (GtkAdjustment *adjustment,
1092+ gpointer user_data)
1093+{
1094+ OsScrollbar *scrollbar;
1095+ OsScrollbarPrivate *priv;
1096+
1097+ scrollbar = OS_SCROLLBAR (user_data);
1098+ priv = scrollbar->priv;
1099+
1100+ /* FIXME(Cimi) we should control each time os_pager_show()/hide()
1101+ * is called here and in map()/unmap().
1102+ * We are arbitrary calling that and I'm frightened we should show or keep
1103+ * hidden a pager that is meant to be hidden/shown.
1104+ * I don't want to see pagers reappearing because
1105+ * of a change in the adjustment of an invisible pager or viceversa. */
1106+ if ((adjustment->upper - adjustment->lower) > adjustment->page_size)
1107+ {
1108+ priv->fullsize = FALSE;
1109+ if (priv->proximity != FALSE)
1110+ os_pager_show (OS_PAGER (priv->pager));
1111+ }
1112+ else
1113+ {
1114+ priv->fullsize = TRUE;
1115+ if (priv->proximity != FALSE)
1116+ {
1117+ os_pager_hide (OS_PAGER (priv->pager));
1118+
1119+ gtk_widget_hide (priv->thumb);
1120+ }
1121+ }
1122+
1123+ calc_layout_pager (scrollbar, adjustment->value);
1124+ calc_layout_slider (scrollbar, adjustment->value);
1125+
1126+ if (!priv->motion_notify_event && !priv->enter_notify_event)
1127+ gtk_widget_hide (GTK_WIDGET (priv->thumb));
1128+
1129+ move_pager (scrollbar);
1130+}
1131+
1132+static void
1133+adjustment_value_changed_cb (GtkAdjustment *adjustment,
1134+ gpointer user_data)
1135+{
1136+ OsScrollbar *scrollbar;
1137+ OsScrollbarPrivate *priv;
1138+
1139+ scrollbar = OS_SCROLLBAR (user_data);
1140+ priv = scrollbar->priv;
1141+
1142+ calc_layout_pager (scrollbar, adjustment->value);
1143+ calc_layout_slider (scrollbar, adjustment->value);
1144+
1145+ if (!priv->motion_notify_event && !priv->enter_notify_event)
1146+ gtk_widget_hide (GTK_WIDGET (priv->thumb));
1147+
1148+ if (gtk_widget_get_mapped (GTK_WIDGET (priv->thumb)))
1149+ {
1150+ /* if we're dragging the thumb, it can't be detached. */
1151+ if (priv->motion_notify_event)
1152+ {
1153+ os_pager_set_detached (OS_PAGER (priv->pager), FALSE);
1154+ os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
1155+ }
1156+ else
1157+ {
1158+ gint x_pos, y_pos;
1159+ gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (priv->thumb)), &x_pos, &y_pos);
1160+
1161+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
1162+ {
1163+ if (priv->win_y + priv->overlay.y > y_pos + priv->slider.height)
1164+ {
1165+ GdkRectangle mask;
1166+
1167+ mask.x = 0;
1168+ mask.y = y_pos + priv->slider.height / 2 - priv->win_y;
1169+ mask.width = DEFAULT_PAGER_WIDTH;
1170+ mask.height = priv->overlay.y - mask.y;
1171+
1172+ os_pager_connect (OS_PAGER (priv->pager), mask);
1173+ os_pager_set_detached (OS_PAGER (priv->pager), TRUE);
1174+
1175+ os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
1176+ }
1177+ else if (priv->win_y + priv->overlay.y + priv->overlay.height < y_pos)
1178+ {
1179+ GdkRectangle mask;
1180+
1181+ mask.x = 0;
1182+ mask.y = priv->overlay.y + priv->overlay.height;
1183+ mask.width = DEFAULT_PAGER_WIDTH;
1184+ mask.height = y_pos + priv->slider.height / 2 - priv->win_y - mask.y;
1185+
1186+ os_pager_connect (OS_PAGER (priv->pager), mask);
1187+ os_pager_set_detached (OS_PAGER (priv->pager), TRUE);
1188+
1189+ os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
1190+ }
1191+ else
1192+ {
1193+ os_pager_set_detached (OS_PAGER (priv->pager), FALSE);
1194+ os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
1195+ }
1196+ }
1197+ else
1198+ {
1199+ if (priv->win_x + priv->overlay.x > x_pos + priv->slider.width)
1200+ {
1201+ GdkRectangle mask;
1202+
1203+ mask.x = x_pos + priv->slider.width / 2 - priv->win_x;
1204+ mask.y = 0;
1205+ mask.width = priv->overlay.x - mask.x;
1206+ mask.height = DEFAULT_PAGER_WIDTH;
1207+
1208+ os_pager_connect (OS_PAGER (priv->pager), mask);
1209+ os_pager_set_detached (OS_PAGER (priv->pager), TRUE);
1210+
1211+ os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
1212+ }
1213+ else if (priv->win_x + priv->overlay.x + priv->overlay.width < x_pos)
1214+ {
1215+ GdkRectangle mask;
1216+
1217+ mask.x = priv->overlay.y + priv->overlay.height;
1218+ mask.y = 0;
1219+ mask.width = x_pos + priv->slider.width / 2 - priv->win_x - mask.x;
1220+ mask.height = DEFAULT_PAGER_WIDTH;
1221+
1222+ os_pager_connect (OS_PAGER (priv->pager), mask);
1223+ os_pager_set_detached (OS_PAGER (priv->pager), TRUE);
1224+ }
1225+ else
1226+ {
1227+ os_pager_set_detached (OS_PAGER (priv->pager), FALSE);
1228+ os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
1229+ }
1230+ }
1231+ }
1232+ }
1233+
1234+ move_pager (scrollbar);
1235+}
1236+
1237+/* pager functions */
1238+
1239+/* set the state of the pager checking mouse position */
1240+static void
1241+pager_set_state_from_pointer (OsScrollbar *scrollbar,
1242+ gint x,
1243+ gint y)
1244+{
1245+ GtkAllocation allocation;
1246+ OsScrollbarPrivate *priv;
1247+
1248+ priv = scrollbar->priv;
1249+
1250+ OS_DCHECK (!priv->active_window);
1251+
1252+ gtk_widget_get_allocation (gtk_widget_get_parent (GTK_WIDGET (scrollbar)), &allocation);
1253+
1254+ if ((x > allocation.x && x < allocation.x + allocation.width) &&
1255+ (y > allocation.y && y < allocation.y + allocation.height))
1256+ {
1257+ priv->can_deactivate_pager = FALSE;
1258+ os_pager_set_active (OS_PAGER (priv->pager), TRUE);
1259+ }
1260+ else
1261+ {
1262+ priv->can_deactivate_pager = TRUE;
1263+ os_pager_set_active (OS_PAGER (priv->pager), FALSE);
1264+ }
1265+}
1266+
1267+/* root window functions */
1268+
1269+/* react on active window changes */
1270+static void
1271+root_gfunc (gpointer data,
1272+ gpointer user_data)
1273+{
1274+ OsScrollbar *scrollbar;
1275+ OsScrollbarPrivate *priv;
1276+
1277+ scrollbar = OS_SCROLLBAR (data);
1278+ priv = scrollbar->priv;
1279+
1280+ OS_DCHECK (scrollbar != NULL);
1281+
1282+ if (gtk_widget_get_mapped (GTK_WIDGET (scrollbar)))
1283+ {
1284+ if (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (scrollbar))) ==
1285+ gdk_screen_get_active_window (gtk_widget_get_screen (GTK_WIDGET (scrollbar))))
1286+ {
1287+ /* stops potential running timeout. */
1288+ if (priv->source_deactivate_pager_id != 0)
1289+ {
1290+ g_source_remove (priv->source_deactivate_pager_id);
1291+ priv->source_deactivate_pager_id = 0;
1292+ }
1293+
1294+ priv->active_window = TRUE;
1295+
1296+ priv->can_deactivate_pager = FALSE;
1297+ os_pager_set_active (OS_PAGER (priv->pager), TRUE);
1298+ }
1299+ else if (priv->active_window)
1300+ {
1301+ GdkWindow *parent;
1302+ GdkWindow *window;
1303+ const gint64 current_time = g_get_monotonic_time ();
1304+ const gint64 end_time = priv->present_time + TIMEOUT_PRESENT_WINDOW * 1000;
1305+
1306+ priv->active_window = FALSE;
1307+
1308+ /* loop through parent windows until it reaches
1309+ * either an unknown GdkWindow (NULL),
1310+ * or the toplevel window. */
1311+ window = gtk_widget_get_window (GTK_WIDGET (scrollbar));
1312+ parent = gdk_window_at_pointer (NULL, NULL);
1313+ while (parent != NULL)
1314+ {
1315+ if (window == parent)
1316+ break;
1317+
1318+ parent = gdk_window_get_parent (parent);
1319+ }
1320+
1321+ if (parent != NULL)
1322+ {
1323+ gint x, y;
1324+
1325+ gdk_window_get_pointer (window, &x, &y, NULL);
1326+
1327+ /* when the window is unfocused,
1328+ * check the position of the pointer
1329+ * and set the state accordingly. */
1330+ pager_set_state_from_pointer (scrollbar, x, y);
1331+ }
1332+ else
1333+ {
1334+ /* if the pointer is outside of the window, set it inactive. */
1335+ priv->can_deactivate_pager = TRUE;
1336+ os_pager_set_active (OS_PAGER (priv->pager), FALSE);
1337+ }
1338+
1339+ if ((current_time > end_time) && priv->thumb != NULL)
1340+ gtk_widget_hide (priv->thumb);
1341+ }
1342+ }
1343+}
1344+
1345+/* filter function applied to the root window */
1346+static GdkFilterReturn
1347+root_filter_func (GdkXEvent *gdkxevent,
1348+ GdkEvent *event,
1349+ gpointer user_data)
1350+{
1351+ XEvent* xev;
1352+
1353+ xev = gdkxevent;
1354+
1355+ if (xev->xany.type == PropertyNotify &&
1356+ xev->xproperty.atom == net_active_window_atom)
1357+ {
1358+ g_list_foreach (os_root_list, root_gfunc, NULL);
1359+ }
1360+
1361+ return GDK_FILTER_CONTINUE;
1362+}
1363+
1364+/* thumb functions */
1365+
1366+/* present a X11 window */
1367+static void
1368+present_window_with_timestamp (Screen *screen,
1369+ gint xid,
1370+ guint32 timestamp)
1371+{
1372+ Display *display;
1373+ Window root;
1374+ XEvent xev;
1375+
1376+ if (timestamp == 0)
1377+ g_warning ("Received a timestamp of 0; window activation may not "
1378+ "function properly.\n");
1379+
1380+ display = DisplayOfScreen (screen);
1381+ root = RootWindowOfScreen (screen);
1382+
1383+ xev.xclient.type = ClientMessage;
1384+ xev.xclient.serial = 0;
1385+ xev.xclient.send_event = True;
1386+ xev.xclient.display = display;
1387+ xev.xclient.window = xid;
1388+ xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW");
1389+ xev.xclient.format = 32;
1390+ xev.xclient.data.l[0] = 1;
1391+ xev.xclient.data.l[1] = timestamp;
1392+ xev.xclient.data.l[2] = 0;
1393+ xev.xclient.data.l[3] = 0;
1394+ xev.xclient.data.l[4] = 0;
1395+
1396+ gdk_error_trap_push ();
1397+
1398+ XSendEvent (display, root, False,
1399+ SubstructureRedirectMask | SubstructureNotifyMask,
1400+ &xev);
1401+
1402+ gdk_flush ();
1403+
1404+ gdk_error_trap_pop ();
1405+}
1406+
1407+/* present a Gdk window */
1408+static void
1409+present_gdk_window_with_timestamp (GtkWidget *widget,
1410+ guint32 timestamp)
1411+{
1412+ present_window_with_timestamp (GDK_SCREEN_XSCREEN (gtk_widget_get_screen (widget)),
1413+ GDK_WINDOW_XID (gtk_widget_get_window (widget)),
1414+ timestamp);
1415+}
1416+
1417 static gboolean
1418 thumb_button_press_event_cb (GtkWidget *widget,
1419 GdkEventButton *event,
1420@@ -716,7 +901,7 @@
1421 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (scrollbar))));
1422
1423 priv->present_time = g_get_monotonic_time ();
1424- os_present_gdk_window_with_timestamp (GTK_WIDGET (scrollbar), event->time);
1425+ present_gdk_window_with_timestamp (GTK_WIDGET (scrollbar), event->time);
1426
1427 priv->button_press_event = TRUE;
1428 priv->motion_notify_event = FALSE;
1429@@ -830,7 +1015,7 @@
1430 g_source_remove (priv->source_deactivate_pager_id);
1431
1432 priv->source_deactivate_pager_id = g_timeout_add (TIMEOUT_THUMB_HIDE,
1433- os_scrollbar_deactivate_pager_cb,
1434+ deactivate_pager_cb,
1435 scrollbar);
1436 }
1437
1438@@ -840,7 +1025,7 @@
1439 g_source_remove (priv->source_hide_thumb_id);
1440
1441 priv->source_hide_thumb_id = g_timeout_add (TIMEOUT_THUMB_HIDE,
1442- os_scrollbar_hide_thumb_cb,
1443+ hide_thumb_cb,
1444 scrollbar);
1445 }
1446
1447@@ -916,6 +1101,73 @@
1448 }
1449 }
1450
1451+/* traduce coordinates into GtkRange values */
1452+static gdouble
1453+coord_to_value (OsScrollbar *scrollbar,
1454+ gint coord)
1455+{
1456+ OsScrollbarPrivate *priv;
1457+ gdouble frac;
1458+ gdouble value;
1459+ gint trough_length;
1460+ gint trough_start;
1461+ gint slider_length;
1462+
1463+ priv = scrollbar->priv;
1464+
1465+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
1466+ {
1467+ trough_length = priv->trough.height;
1468+ trough_start = priv->trough.y;
1469+ slider_length = MAX (priv->slider.height, priv->overlay.height);
1470+ }
1471+ else
1472+ {
1473+ trough_length = priv->trough.width;
1474+ trough_start = priv->trough.y;
1475+ slider_length = MAX (priv->slider.width, priv->overlay.width);
1476+ }
1477+
1478+ if (trough_length == slider_length)
1479+ frac = 1.0;
1480+ else
1481+ frac = (MAX (0, coord - trough_start) /
1482+ (gdouble) (trough_length - slider_length));
1483+
1484+ value = priv->adjustment->lower + frac * (priv->adjustment->upper -
1485+ priv->adjustment->lower -
1486+ priv->adjustment->page_size);
1487+
1488+ value = CLAMP (value, priv->adjustment->lower, priv->adjustment->upper - priv->adjustment->page_size);
1489+
1490+ return value;
1491+}
1492+
1493+/* from pointer movement, set GtkRange value */
1494+static void
1495+capture_movement (OsScrollbar *scrollbar,
1496+ gint mouse_x,
1497+ gint mouse_y)
1498+{
1499+ OsScrollbarPrivate *priv;
1500+ gint delta;
1501+ gint c;
1502+ gdouble new_value;
1503+
1504+ priv = scrollbar->priv;
1505+
1506+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
1507+ delta = mouse_y - priv->slide_initial_coordinate;
1508+ else
1509+ delta = mouse_x - priv->slide_initial_coordinate;
1510+
1511+ c = priv->slide_initial_slider_position + delta;
1512+
1513+ new_value = coord_to_value (scrollbar, c);
1514+
1515+ gtk_adjustment_set_value (priv->adjustment, new_value);
1516+}
1517+
1518 static gboolean
1519 thumb_motion_notify_event_cb (GtkWidget *widget,
1520 GdkEventMotion *event,
1521@@ -945,13 +1197,14 @@
1522 priv->slide_initial_coordinate = event->x_root;
1523 }
1524
1525- os_scrollbar_move (scrollbar, event->x_root, event->y_root);
1526+ /* FIXME(Cimi) seems useless. */
1527+ capture_movement (scrollbar, event->x_root, event->y_root);
1528 priv->value_changed_event = FALSE;
1529 }
1530
1531 priv->motion_notify_event = TRUE;
1532
1533- os_scrollbar_move (scrollbar, event->x_root, event->y_root);
1534+ capture_movement (scrollbar, event->x_root, event->y_root);
1535
1536 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
1537 {
1538@@ -1006,12 +1259,31 @@
1539 }
1540 }
1541
1542- os_scrollbar_move_thumb (scrollbar, x, y);
1543+ move_thumb (scrollbar, x, y);
1544 }
1545
1546 return FALSE;
1547 }
1548
1549+/* mouse wheel delta */
1550+static gdouble
1551+get_wheel_delta (OsScrollbar *scrollbar,
1552+ GdkScrollDirection direction)
1553+{
1554+ OsScrollbarPrivate *priv;
1555+ gdouble delta;
1556+
1557+ priv = scrollbar->priv;
1558+
1559+ delta = pow (priv->adjustment->page_size, 2.0 / 3.0);
1560+
1561+ if (direction == GDK_SCROLL_UP ||
1562+ direction == GDK_SCROLL_LEFT)
1563+ delta = - delta;
1564+
1565+ return delta;
1566+}
1567+
1568 static gboolean
1569 thumb_scroll_event_cb (GtkWidget *widget,
1570 GdkEventScroll *event,
1571@@ -1026,7 +1298,7 @@
1572
1573 priv->value_changed_event = TRUE;
1574
1575- delta = os_scrollbar_get_wheel_delta (scrollbar, event->direction);
1576+ delta = get_wheel_delta (scrollbar, event->direction);
1577
1578 gtk_adjustment_set_value (priv->adjustment,
1579 CLAMP (priv->adjustment->value + delta,
1580@@ -1054,297 +1326,30 @@
1581 os_pager_set_detached (OS_PAGER (priv->pager), FALSE);
1582 }
1583
1584-/* Move the pager to the right position. */
1585+/* toplevel functions */
1586+
1587+/* store the position of the toplevel window */
1588 static void
1589-pager_move (OsScrollbar *scrollbar)
1590+store_toplevel_position (OsScrollbar *scrollbar)
1591 {
1592- GdkRectangle mask;
1593 OsScrollbarPrivate *priv;
1594+ gint win_x, win_y;
1595
1596 priv = scrollbar->priv;
1597
1598+ /* In reality, I'm storing widget's window, not the toplevel.
1599+ * Is that the same with gdk_window_get_origin? */
1600+ gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &win_x, &win_y);
1601+
1602 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
1603 {
1604- mask.x = 0;
1605- mask.y = priv->overlay.y;
1606- mask.width = DEFAULT_PAGER_WIDTH;
1607- mask.height = priv->overlay.height;
1608- }
1609- else
1610- {
1611- mask.x = priv->overlay.x;
1612- mask.y = 0;
1613- mask.width = priv->overlay.width;
1614- mask.height = DEFAULT_PAGER_WIDTH;
1615- }
1616-
1617- os_pager_move_resize (OS_PAGER (priv->pager), mask);
1618-}
1619-
1620-static void
1621-pager_set_state_from_pointer (OsScrollbar *scrollbar,
1622- gint x,
1623- gint y)
1624-{
1625- GtkAllocation allocation;
1626- OsScrollbarPrivate *priv;
1627-
1628- priv = scrollbar->priv;
1629-
1630- OS_DCHECK (!priv->active_window);
1631-
1632- gtk_widget_get_allocation (gtk_widget_get_parent (GTK_WIDGET (scrollbar)), &allocation);
1633-
1634- if ((x > allocation.x && x < allocation.x + allocation.width) &&
1635- (y > allocation.y && y < allocation.y + allocation.height))
1636- {
1637- priv->can_deactivate_pager = FALSE;
1638- os_pager_set_active (OS_PAGER (priv->pager), TRUE);
1639- }
1640- else
1641- {
1642- priv->can_deactivate_pager = TRUE;
1643- os_pager_set_active (OS_PAGER (priv->pager), FALSE);
1644- }
1645-}
1646-
1647-static void
1648-adjustment_changed_cb (GtkAdjustment *adjustment,
1649- gpointer user_data)
1650-{
1651- OsScrollbar *scrollbar;
1652- OsScrollbarPrivate *priv;
1653-
1654- scrollbar = OS_SCROLLBAR (user_data);
1655- priv = scrollbar->priv;
1656-
1657- /* FIXME(Cimi) we should control each time os_pager_show()/hide()
1658- * is called here and in map()/unmap().
1659- * We are arbitrary calling that and I'm frightened we should show or keep
1660- * hidden a pager that is meant to be hidden/shown.
1661- * I don't want to see pagers reappearing because
1662- * of a change in the adjustment of an invisible pager or viceversa. */
1663- if ((adjustment->upper - adjustment->lower) > adjustment->page_size)
1664- {
1665- priv->fullsize = FALSE;
1666- if (priv->proximity != FALSE)
1667- os_pager_show (OS_PAGER (priv->pager));
1668- }
1669- else
1670- {
1671- priv->fullsize = TRUE;
1672- if (priv->proximity != FALSE)
1673- {
1674- os_pager_hide (OS_PAGER (priv->pager));
1675-
1676- gtk_widget_hide (priv->thumb);
1677- }
1678- }
1679-
1680- os_scrollbar_calc_layout_pager (scrollbar, adjustment->value);
1681- os_scrollbar_calc_layout_slider (scrollbar, adjustment->value);
1682-
1683- if (!priv->motion_notify_event && !priv->enter_notify_event)
1684- gtk_widget_hide (GTK_WIDGET (priv->thumb));
1685-
1686- pager_move (scrollbar);
1687-}
1688-
1689-static void
1690-adjustment_value_changed_cb (GtkAdjustment *adjustment,
1691- gpointer user_data)
1692-{
1693- OsScrollbar *scrollbar;
1694- OsScrollbarPrivate *priv;
1695-
1696- scrollbar = OS_SCROLLBAR (user_data);
1697- priv = scrollbar->priv;
1698-
1699- os_scrollbar_calc_layout_pager (scrollbar, adjustment->value);
1700- os_scrollbar_calc_layout_slider (scrollbar, adjustment->value);
1701-
1702- if (!priv->motion_notify_event && !priv->enter_notify_event)
1703- gtk_widget_hide (GTK_WIDGET (priv->thumb));
1704-
1705- if (gtk_widget_get_mapped (GTK_WIDGET (priv->thumb)))
1706- {
1707- /* if we're dragging the thumb, it can't be detached. */
1708- if (priv->motion_notify_event)
1709- {
1710- os_pager_set_detached (OS_PAGER (priv->pager), FALSE);
1711- os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
1712- }
1713- else
1714- {
1715- gint x_pos, y_pos;
1716- gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (priv->thumb)), &x_pos, &y_pos);
1717-
1718- if (priv->orientation == GTK_ORIENTATION_VERTICAL)
1719- {
1720- if (priv->win_y + priv->overlay.y > y_pos + priv->slider.height)
1721- {
1722- GdkRectangle mask;
1723-
1724- mask.x = 0;
1725- mask.y = y_pos + priv->slider.height / 2 - priv->win_y;
1726- mask.width = DEFAULT_PAGER_WIDTH;
1727- mask.height = priv->overlay.y - mask.y;
1728-
1729- os_pager_connect (OS_PAGER (priv->pager), mask);
1730- os_pager_set_detached (OS_PAGER (priv->pager), TRUE);
1731-
1732- os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
1733- }
1734- else if (priv->win_y + priv->overlay.y + priv->overlay.height < y_pos)
1735- {
1736- GdkRectangle mask;
1737-
1738- mask.x = 0;
1739- mask.y = priv->overlay.y + priv->overlay.height;
1740- mask.width = DEFAULT_PAGER_WIDTH;
1741- mask.height = y_pos + priv->slider.height / 2 - priv->win_y - mask.y;
1742-
1743- os_pager_connect (OS_PAGER (priv->pager), mask);
1744- os_pager_set_detached (OS_PAGER (priv->pager), TRUE);
1745-
1746- os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
1747- }
1748- else
1749- {
1750- os_pager_set_detached (OS_PAGER (priv->pager), FALSE);
1751- os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
1752- }
1753- }
1754- else
1755- {
1756- if (priv->win_x + priv->overlay.x > x_pos + priv->slider.width)
1757- {
1758- GdkRectangle mask;
1759-
1760- mask.x = x_pos + priv->slider.width / 2 - priv->win_x;
1761- mask.y = 0;
1762- mask.width = priv->overlay.x - mask.x;
1763- mask.height = DEFAULT_PAGER_WIDTH;
1764-
1765- os_pager_connect (OS_PAGER (priv->pager), mask);
1766- os_pager_set_detached (OS_PAGER (priv->pager), TRUE);
1767-
1768- os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
1769- }
1770- else if (priv->win_x + priv->overlay.x + priv->overlay.width < x_pos)
1771- {
1772- GdkRectangle mask;
1773-
1774- mask.x = priv->overlay.y + priv->overlay.height;
1775- mask.y = 0;
1776- mask.width = x_pos + priv->slider.width / 2 - priv->win_x - mask.x;
1777- mask.height = DEFAULT_PAGER_WIDTH;
1778-
1779- os_pager_connect (OS_PAGER (priv->pager), mask);
1780- os_pager_set_detached (OS_PAGER (priv->pager), TRUE);
1781- }
1782- else
1783- {
1784- os_pager_set_detached (OS_PAGER (priv->pager), FALSE);
1785- os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
1786- }
1787- }
1788- }
1789- }
1790-
1791- pager_move (scrollbar);
1792-}
1793-
1794-static GdkFilterReturn
1795-root_filter_func (GdkXEvent *gdkxevent,
1796- GdkEvent *event,
1797- gpointer user_data)
1798-{
1799- XEvent* xevent;
1800-
1801- xevent = gdkxevent;
1802-
1803- if (xevent->xany.type == PropertyNotify &&
1804- xevent->xproperty.atom == net_active_window_atom)
1805- {
1806- g_list_foreach (os_root_list, root_gfunc, NULL);
1807- }
1808-
1809- return GDK_FILTER_CONTINUE;
1810-}
1811-
1812-static void
1813-root_gfunc (gpointer data,
1814- gpointer user_data)
1815-{
1816- OsScrollbar *scrollbar;
1817- OsScrollbarPrivate *priv;
1818-
1819- scrollbar = OS_SCROLLBAR (data);
1820- priv = scrollbar->priv;
1821-
1822- OS_DCHECK (scrollbar != NULL);
1823-
1824- if (gtk_widget_get_mapped (GTK_WIDGET (scrollbar)))
1825- {
1826- if (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (scrollbar))) ==
1827- gdk_screen_get_active_window (gtk_widget_get_screen (GTK_WIDGET (scrollbar))))
1828- {
1829- /* stops potential running timeout. */
1830- if (priv->source_deactivate_pager_id != 0)
1831- {
1832- g_source_remove (priv->source_deactivate_pager_id);
1833- priv->source_deactivate_pager_id = 0;
1834- }
1835-
1836- priv->active_window = TRUE;
1837-
1838- priv->can_deactivate_pager = FALSE;
1839- os_pager_set_active (OS_PAGER (priv->pager), TRUE);
1840- }
1841- else if (priv->active_window)
1842- {
1843- GdkWindow *parent;
1844- GdkWindow *window;
1845- const gint64 current_time = g_get_monotonic_time ();
1846- const gint64 end_time = priv->present_time + TIMEOUT_PRESENT_WINDOW * 1000;
1847-
1848- priv->active_window = FALSE;
1849-
1850- /* loop through parent windows until it reaches
1851- * either an unknown GdkWindow (NULL),
1852- * or the toplevel window. */
1853- window = gtk_widget_get_window (GTK_WIDGET (scrollbar));
1854- parent = gdk_window_at_pointer (NULL, NULL);
1855- while (parent != NULL)
1856- {
1857- if (window == parent)
1858- break;
1859-
1860- parent = gdk_window_get_parent (parent);
1861- }
1862-
1863- if (parent != NULL)
1864- {
1865- gint x, y;
1866-
1867- gdk_window_get_pointer (window, &x, &y, NULL);
1868-
1869- /* when the window is unfocused,
1870- * check the position of the pointer
1871- * and set the state accordingly. */
1872- pager_set_state_from_pointer (scrollbar, x, y);
1873- }
1874- else
1875- {
1876- /* if the pointer is outside of the window, set it inactive. */
1877- priv->can_deactivate_pager = TRUE;
1878- os_pager_set_active (OS_PAGER (priv->pager), FALSE);
1879- }
1880-
1881- if ((current_time > end_time) && priv->thumb != NULL)
1882- gtk_widget_hide (priv->thumb);
1883- }
1884+ priv->win_x = win_x + priv->thumb_all.x;
1885+ priv->win_y = win_y + priv->thumb_all.y;
1886+ }
1887+ else
1888+ {
1889+ priv->win_x = win_x + priv->thumb_all.x;
1890+ priv->win_y = win_y + priv->thumb_all.y;
1891 }
1892 }
1893
1894@@ -1405,15 +1410,15 @@
1895
1896 priv->lock_position = FALSE;
1897
1898- os_scrollbar_calc_layout_pager (scrollbar, priv->adjustment->value);
1899- os_scrollbar_calc_layout_slider (scrollbar, priv->adjustment->value);
1900+ calc_layout_pager (scrollbar, priv->adjustment->value);
1901+ calc_layout_slider (scrollbar, priv->adjustment->value);
1902
1903- os_scrollbar_store_window_position (scrollbar);
1904+ store_toplevel_position (scrollbar);
1905
1906 return FALSE;
1907 }
1908
1909-/* Add a filter to the toplevel GdkWindow, to activate proximity effect. */
1910+/* filter function applied to the toplevel window */
1911 static GdkFilterReturn
1912 toplevel_filter_func (GdkXEvent *gdkxevent,
1913 GdkEvent *event,
1914@@ -1421,37 +1426,37 @@
1915 {
1916 OsScrollbar *scrollbar;
1917 OsScrollbarPrivate *priv;
1918- XEvent *xevent;
1919+ XEvent *xev;
1920
1921 g_return_val_if_fail (OS_SCROLLBAR (user_data), GDK_FILTER_CONTINUE);
1922
1923 scrollbar = OS_SCROLLBAR (user_data);
1924
1925 priv = scrollbar->priv;
1926- xevent = gdkxevent;
1927+ xev = gdkxevent;
1928
1929 g_return_val_if_fail (priv->pager != NULL, GDK_FILTER_CONTINUE);
1930 g_return_val_if_fail (priv->thumb != NULL, GDK_FILTER_CONTINUE);
1931
1932 if (!priv->fullsize)
1933 {
1934- if (xevent->type == ButtonPress)
1935+ if (xev->type == ButtonPress)
1936 {
1937 priv->toplevel_button_press = TRUE;
1938 gtk_widget_hide (priv->thumb);
1939 }
1940
1941- if (priv->toplevel_button_press && xevent->type == ButtonRelease)
1942+ if (priv->toplevel_button_press && xev->type == ButtonRelease)
1943 {
1944 priv->toplevel_button_press = FALSE;
1945
1946 /* proximity area */
1947 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
1948 {
1949- if ((priv->thumb_all.x - xevent->xbutton.x <= PROXIMITY_WIDTH &&
1950- priv->thumb_all.x - xevent->xbutton.x >= 0) &&
1951- (xevent->xbutton.y >= priv->thumb_all.y + priv->overlay.y &&
1952- xevent->xbutton.y <= priv->thumb_all.y + priv->overlay.y + priv->overlay.height))
1953+ if ((priv->thumb_all.x - xev->xbutton.x <= PROXIMITY_WIDTH &&
1954+ priv->thumb_all.x - xev->xbutton.x >= 0) &&
1955+ (xev->xbutton.y >= priv->thumb_all.y + priv->overlay.y &&
1956+ xev->xbutton.y <= priv->thumb_all.y + priv->overlay.y + priv->overlay.height))
1957 {
1958 priv->can_hide = FALSE;
1959
1960@@ -1465,15 +1470,15 @@
1961 gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos);
1962
1963 x = priv->thumb_all.x;
1964- y = CLAMP (xevent->xbutton.y - priv->slider.height / 2,
1965+ y = CLAMP (xev->xbutton.y - priv->slider.height / 2,
1966 priv->thumb_all.y + priv->overlay.y,
1967 priv->thumb_all.y + priv->overlay.y + priv->overlay.height - priv->slider.height);
1968
1969- os_scrollbar_move_thumb (scrollbar, x_pos + x, y_pos + y);
1970+ move_thumb (scrollbar, x_pos + x, y_pos + y);
1971 }
1972 else
1973 {
1974- os_scrollbar_move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y);
1975+ move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y);
1976 }
1977
1978 gtk_widget_show (GTK_WIDGET (priv->thumb));
1979@@ -1481,10 +1486,10 @@
1980 }
1981 else
1982 {
1983- if ((priv->thumb_all.y - xevent->xbutton.y <= PROXIMITY_WIDTH &&
1984- priv->thumb_all.y - xevent->xbutton.y >= 0) &&
1985- (xevent->xbutton.x >= priv->thumb_all.x + priv->overlay.x &&
1986- xevent->xbutton.x <= priv->thumb_all.x + priv->overlay.x + priv->overlay.width))
1987+ if ((priv->thumb_all.y - xev->xbutton.y <= PROXIMITY_WIDTH &&
1988+ priv->thumb_all.y - xev->xbutton.y >= 0) &&
1989+ (xev->xbutton.x >= priv->thumb_all.x + priv->overlay.x &&
1990+ xev->xbutton.x <= priv->thumb_all.x + priv->overlay.x + priv->overlay.width))
1991 {
1992 priv->can_hide = FALSE;
1993
1994@@ -1497,16 +1502,16 @@
1995
1996 gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos);
1997
1998- x = CLAMP (xevent->xbutton.x - priv->slider.width / 2,
1999+ x = CLAMP (xev->xbutton.x - priv->slider.width / 2,
2000 priv->thumb_all.x + priv->overlay.x,
2001 priv->thumb_all.x + priv->overlay.x + priv->overlay.width - priv->slider.width);
2002 y = priv->thumb_all.y;
2003
2004- os_scrollbar_move_thumb (scrollbar, x_pos + x, y_pos + y);
2005+ move_thumb (scrollbar, x_pos + x, y_pos + y);
2006 }
2007 else
2008 {
2009- os_scrollbar_move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y);
2010+ move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y);
2011 }
2012
2013 gtk_widget_show (GTK_WIDGET (priv->thumb));
2014@@ -1520,10 +1525,10 @@
2015 * this call checks the pointer after the scroll-event,
2016 * since it enters the window,
2017 * then sets the state accordingly. */
2018- if (!priv->active_window && xevent->type == EnterNotify)
2019- pager_set_state_from_pointer (scrollbar, xevent->xcrossing.x, xevent->xcrossing.y);
2020+ if (!priv->active_window && xev->type == EnterNotify)
2021+ pager_set_state_from_pointer (scrollbar, xev->xcrossing.x, xev->xcrossing.y);
2022
2023- if (xevent->type == LeaveNotify)
2024+ if (xev->type == LeaveNotify)
2025 {
2026 /* never deactivate the pager in an active window. */
2027 if (!priv->active_window)
2028@@ -1534,7 +1539,7 @@
2029 g_source_remove (priv->source_deactivate_pager_id);
2030
2031 priv->source_deactivate_pager_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE,
2032- os_scrollbar_deactivate_pager_cb,
2033+ deactivate_pager_cb,
2034 scrollbar);
2035 }
2036
2037@@ -1545,32 +1550,32 @@
2038 g_source_remove (priv->source_hide_thumb_id);
2039
2040 priv->source_hide_thumb_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE,
2041- os_scrollbar_hide_thumb_cb,
2042+ hide_thumb_cb,
2043 scrollbar);
2044
2045 if (priv->source_unlock_thumb_id != 0)
2046 g_source_remove (priv->source_unlock_thumb_id);
2047
2048 priv->source_unlock_thumb_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE,
2049- os_scrollbar_unlock_thumb_cb,
2050+ unlock_thumb_cb,
2051 scrollbar);
2052 }
2053
2054 /* get the motion_notify_event trough XEvent */
2055- if (!priv->toplevel_button_press && xevent->type == MotionNotify)
2056+ if (!priv->toplevel_button_press && xev->type == MotionNotify)
2057 {
2058 /* react to motion_notify_event
2059 * and set the state accordingly. */
2060 if (!priv->active_window)
2061- pager_set_state_from_pointer (scrollbar, xevent->xmotion.x, xevent->xmotion.y);
2062+ pager_set_state_from_pointer (scrollbar, xev->xmotion.x, xev->xmotion.y);
2063
2064 /* proximity area */
2065 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
2066 {
2067- if ((priv->thumb_all.x - xevent->xmotion.x <= PROXIMITY_WIDTH &&
2068- priv->thumb_all.x - xevent->xmotion.x >= 0) &&
2069- (xevent->xmotion.y >= priv->thumb_all.y + priv->overlay.y &&
2070- xevent->xmotion.y <= priv->thumb_all.y + priv->overlay.y + priv->overlay.height))
2071+ if ((priv->thumb_all.x - xev->xmotion.x <= PROXIMITY_WIDTH &&
2072+ priv->thumb_all.x - xev->xmotion.x >= 0) &&
2073+ (xev->xmotion.y >= priv->thumb_all.y + priv->overlay.y &&
2074+ xev->xmotion.y <= priv->thumb_all.y + priv->overlay.y + priv->overlay.height))
2075 {
2076 priv->can_hide = FALSE;
2077
2078@@ -1584,15 +1589,15 @@
2079 gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos);
2080
2081 x = priv->thumb_all.x;
2082- y = CLAMP (xevent->xmotion.y - priv->slider.height / 2,
2083+ y = CLAMP (xev->xmotion.y - priv->slider.height / 2,
2084 priv->thumb_all.y + priv->overlay.y,
2085 priv->thumb_all.y + priv->overlay.y + priv->overlay.height - priv->slider.height);
2086
2087- os_scrollbar_move_thumb (scrollbar, x_pos + x, y_pos + y);
2088+ move_thumb (scrollbar, x_pos + x, y_pos + y);
2089 }
2090 else
2091 {
2092- os_scrollbar_move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y);
2093+ move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y);
2094 }
2095
2096 os_pager_set_detached (OS_PAGER (priv->pager), FALSE);
2097@@ -1603,15 +1608,15 @@
2098 {
2099 priv->can_hide = TRUE;
2100 priv->lock_position = FALSE;
2101- os_scrollbar_hide_thumb (scrollbar);
2102+ hide_thumb (scrollbar);
2103 }
2104 }
2105 else
2106 {
2107- if ((priv->thumb_all.y - xevent->xmotion.y <= PROXIMITY_WIDTH &&
2108- priv->thumb_all.y - xevent->xmotion.y >= 0) &&
2109- (xevent->xmotion.x >= priv->thumb_all.x + priv->overlay.x &&
2110- xevent->xmotion.x <= priv->thumb_all.x + priv->overlay.x + priv->overlay.width))
2111+ if ((priv->thumb_all.y - xev->xmotion.y <= PROXIMITY_WIDTH &&
2112+ priv->thumb_all.y - xev->xmotion.y >= 0) &&
2113+ (xev->xmotion.x >= priv->thumb_all.x + priv->overlay.x &&
2114+ xev->xmotion.x <= priv->thumb_all.x + priv->overlay.x + priv->overlay.width))
2115 {
2116 priv->can_hide = FALSE;
2117
2118@@ -1624,16 +1629,16 @@
2119
2120 gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos);
2121
2122- x = CLAMP (xevent->xmotion.x - priv->slider.width / 2,
2123+ x = CLAMP (xev->xmotion.x - priv->slider.width / 2,
2124 priv->thumb_all.x + priv->overlay.x,
2125 priv->thumb_all.x + priv->overlay.x + priv->overlay.width - priv->slider.width);
2126 y = priv->thumb_all.y;
2127
2128- os_scrollbar_move_thumb (scrollbar, x_pos + x, y_pos + y);
2129+ move_thumb (scrollbar, x_pos + x, y_pos + y);
2130 }
2131 else
2132 {
2133- os_scrollbar_move_thumb (scrollbar, priv->win_x + priv->slider.x, priv->win_y);
2134+ move_thumb (scrollbar, priv->win_x + priv->slider.x, priv->win_y);
2135 }
2136
2137 os_pager_set_detached (OS_PAGER (priv->pager), FALSE);
2138@@ -1644,7 +1649,7 @@
2139 {
2140 priv->can_hide = TRUE;
2141 priv->lock_position = FALSE;
2142- os_scrollbar_hide_thumb (scrollbar);
2143+ hide_thumb (scrollbar);
2144 }
2145 }
2146 }
2147@@ -1653,8 +1658,6 @@
2148 return GDK_FILTER_CONTINUE;
2149 }
2150
2151-/* Type definition. */
2152-
2153 G_DEFINE_TYPE (OsScrollbar, os_scrollbar, GTK_TYPE_SCROLLBAR);
2154
2155 static void
2156@@ -1717,6 +1720,11 @@
2157 os_root_list = g_list_append (os_root_list, scrollbar);
2158 }
2159
2160+ priv->button_press_event = FALSE;
2161+ priv->enter_notify_event = FALSE;
2162+ priv->motion_notify_event = FALSE;
2163+ priv->value_changed_event = FALSE;
2164+
2165 priv->active_window = FALSE;
2166 priv->can_deactivate_pager = TRUE;
2167 priv->can_hide = TRUE;
2168@@ -1733,10 +1741,10 @@
2169 priv->pager = os_pager_new ();
2170
2171 g_signal_connect (G_OBJECT (scrollbar), "notify::adjustment",
2172- G_CALLBACK (os_scrollbar_notify_adjustment_cb), NULL);
2173+ G_CALLBACK (notify_adjustment_cb), NULL);
2174
2175 g_signal_connect (G_OBJECT (scrollbar), "notify::orientation",
2176- G_CALLBACK (os_scrollbar_notify_orientation_cb), NULL);
2177+ G_CALLBACK (notify_orientation_cb), NULL);
2178 }
2179
2180 static void
2181@@ -1778,8 +1786,8 @@
2182 priv->pager = NULL;
2183 }
2184
2185- os_scrollbar_swap_adjustment (scrollbar, NULL);
2186- os_scrollbar_swap_thumb (scrollbar, NULL);
2187+ swap_adjustment (scrollbar, NULL);
2188+ swap_thumb (scrollbar, NULL);
2189
2190 G_OBJECT_CLASS (os_scrollbar_parent_class)->dispose (object);
2191 }
2192@@ -1892,11 +1900,11 @@
2193 g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (widget)), "configure-event",
2194 G_CALLBACK (toplevel_configure_event_cb), scrollbar);
2195
2196- os_scrollbar_calc_layout_pager (scrollbar, priv->adjustment->value);
2197+ calc_layout_pager (scrollbar, priv->adjustment->value);
2198
2199 os_pager_set_parent (OS_PAGER (priv->pager), widget);
2200
2201- os_scrollbar_store_window_position (scrollbar);
2202+ store_toplevel_position (scrollbar);
2203 }
2204
2205 static void
2206@@ -1955,16 +1963,16 @@
2207
2208 if (priv->adjustment != NULL)
2209 {
2210- os_scrollbar_calc_layout_pager (scrollbar, priv->adjustment->value);
2211- os_scrollbar_calc_layout_slider (scrollbar, priv->adjustment->value);
2212+ calc_layout_pager (scrollbar, priv->adjustment->value);
2213+ calc_layout_slider (scrollbar, priv->adjustment->value);
2214 }
2215
2216 os_pager_size_allocate (OS_PAGER (priv->pager), rect);
2217
2218- pager_move (scrollbar);
2219+ move_pager (scrollbar);
2220
2221 if (gtk_widget_get_realized (widget))
2222- os_scrollbar_store_window_position (scrollbar);
2223+ store_toplevel_position (scrollbar);
2224
2225 widget->allocation = *allocation;
2226 }
2227
2228=== modified file 'os/os-thumb.c'
2229--- os/os-thumb.c 2011-05-17 22:10:53 +0000
2230+++ os/os-thumb.c 2011-05-18 18:39:29 +0000
2231@@ -50,8 +50,8 @@
2232 gboolean button_press_event;
2233 gboolean motion_notify_event;
2234 gboolean can_rgba;
2235+ gboolean detached;
2236 gboolean use_tolerance;
2237- gboolean detached;
2238 gint pointer_x;
2239 gint pointer_y;
2240 guint32 source_id;
2241@@ -63,8 +63,6 @@
2242 LAST_ARG
2243 };
2244
2245-static void os_thumb_fade_out_cb (gfloat weight, gpointer user_data);
2246-static gboolean os_thumb_timeout_fade_out_cb (gpointer user_data);
2247 static gboolean os_thumb_button_press_event (GtkWidget *widget, GdkEventButton *event);
2248 static gboolean os_thumb_button_release_event (GtkWidget *widget, GdkEventButton *event);
2249 static void os_thumb_composited_changed (GtkWidget *widget);
2250@@ -81,61 +79,12 @@
2251 static void os_thumb_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
2252 static void os_thumb_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
2253
2254-/* Private functions. */
2255-
2256-/* Draw an arror. */
2257-static void
2258-os_cairo_draw_arrow (cairo_t *cr,
2259- gdouble x,
2260- gdouble y,
2261- gdouble width,
2262- gdouble height)
2263-{
2264- cairo_save (cr);
2265-
2266- cairo_translate (cr, x, y);
2267- cairo_move_to (cr, -width / 2, -height / 2);
2268- cairo_line_to (cr, 0, height / 2);
2269- cairo_line_to (cr, width / 2, -height / 2);
2270- cairo_close_path (cr);
2271-
2272- cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 0.75);
2273- cairo_fill_preserve (cr);
2274-
2275- cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 1.0);
2276- cairo_stroke (cr);
2277-
2278- cairo_restore (cr);
2279-}
2280-
2281-/* Draw a rounded rectangle. */
2282-static void
2283-os_cairo_draw_rounded_rect (cairo_t *cr,
2284- gdouble x,
2285- gdouble y,
2286- gdouble width,
2287- gdouble height,
2288- gdouble radius)
2289-{
2290- if (radius < 1)
2291- {
2292- cairo_rectangle (cr, x, y, width, height);
2293- return;
2294- }
2295-
2296- radius = MIN (radius, MIN (width / 2.0, height / 2.0));
2297-
2298- cairo_move_to (cr, x + radius, y);
2299-
2300- cairo_arc (cr, x + width - radius, y + radius, radius, G_PI * 1.5, G_PI * 2);
2301- cairo_arc (cr, x + width - radius, y + height - radius, radius, 0, G_PI * 0.5);
2302- cairo_arc (cr, x + radius, y + height - radius, radius, G_PI * 0.5, G_PI);
2303- cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI * 1.5);
2304-}
2305-
2306-static void
2307-os_thumb_fade_out_cb (gfloat weight,
2308- gpointer user_data)
2309+/* Private functions */
2310+
2311+/* callback called by the fade-out animation */
2312+static void
2313+fade_out_cb (gfloat weight,
2314+ gpointer user_data)
2315 {
2316 OsThumb *thumb;
2317
2318@@ -147,8 +96,9 @@
2319 gtk_widget_hide (GTK_WIDGET (thumb));
2320 }
2321
2322+/* timeout before starting the fade-out animation */
2323 static gboolean
2324-os_thumb_timeout_fade_out_cb (gpointer user_data)
2325+timeout_fade_out_cb (gpointer user_data)
2326 {
2327 OsThumb *thumb;
2328 OsThumbPrivate *priv;
2329@@ -163,8 +113,6 @@
2330 return FALSE;
2331 }
2332
2333-/* Type definition. */
2334-
2335 G_DEFINE_TYPE (OsThumb, os_thumb, GTK_TYPE_WINDOW);
2336
2337 static void
2338@@ -214,16 +162,19 @@
2339 OsThumbPrivate);
2340 priv = thumb->priv;
2341
2342+ priv->button_press_event = FALSE;
2343+ priv->motion_notify_event = FALSE;
2344+
2345 priv->can_rgba = FALSE;
2346 priv->detached = FALSE;
2347+ priv->use_tolerance = FALSE;
2348
2349 priv->source_id = 0;
2350 priv->animation = os_animation_new (RATE_FADE_OUT, DURATION_FADE_OUT,
2351- os_thumb_fade_out_cb, NULL, thumb);
2352+ fade_out_cb, NULL, thumb);
2353
2354 gtk_window_set_skip_pager_hint (GTK_WINDOW (thumb), TRUE);
2355 gtk_window_set_skip_taskbar_hint (GTK_WINDOW (thumb), TRUE);
2356- /* gtk_window_set_has_resize_grip (GTK_WINDOW (thumb), FALSE); */
2357 gtk_window_set_decorated (GTK_WINDOW (thumb), FALSE);
2358 gtk_window_set_focus_on_map (GTK_WINDOW (thumb), FALSE);
2359 gtk_window_set_accept_focus (GTK_WINDOW (thumb), FALSE);
2360@@ -237,43 +188,6 @@
2361 os_thumb_composited_changed (GTK_WIDGET (thumb));
2362 }
2363
2364-static void
2365-os_thumb_dispose (GObject *object)
2366-{
2367- OsThumb *thumb;
2368- OsThumbPrivate *priv;
2369-
2370- thumb = OS_THUMB (object);
2371- priv = thumb->priv;
2372-
2373- if (priv->source_id != 0)
2374- {
2375- g_source_remove (priv->source_id);
2376- priv->source_id = 0;
2377- }
2378-
2379- if (priv->animation != NULL)
2380- {
2381- g_object_unref (priv->animation);
2382- priv->animation = NULL;
2383- }
2384-
2385- if (priv->grabbed_widget != NULL)
2386- {
2387- g_object_unref (priv->grabbed_widget);
2388- priv->grabbed_widget = NULL;
2389- }
2390-
2391- G_OBJECT_CLASS (os_thumb_parent_class)->dispose (object);
2392-}
2393-
2394-static void
2395-os_thumb_finalize (GObject *object)
2396-{
2397- G_OBJECT_CLASS (os_thumb_parent_class)->finalize (object);
2398-}
2399-
2400-
2401 static gboolean
2402 os_thumb_button_press_event (GtkWidget *widget,
2403 GdkEventButton *event)
2404@@ -371,6 +285,56 @@
2405 gtk_widget_queue_draw (widget);
2406 }
2407
2408+/* draw an arrow using cairo */
2409+static void
2410+draw_arrow (cairo_t *cr,
2411+ gdouble x,
2412+ gdouble y,
2413+ gdouble width,
2414+ gdouble height)
2415+{
2416+ cairo_save (cr);
2417+
2418+ cairo_translate (cr, x, y);
2419+ cairo_move_to (cr, -width / 2, -height / 2);
2420+ cairo_line_to (cr, 0, height / 2);
2421+ cairo_line_to (cr, width / 2, -height / 2);
2422+ cairo_close_path (cr);
2423+
2424+ cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 0.75);
2425+ cairo_fill_preserve (cr);
2426+
2427+ cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 1.0);
2428+ cairo_stroke (cr);
2429+
2430+ cairo_restore (cr);
2431+}
2432+
2433+/* draw a rounded rectangle using cairo */
2434+static void
2435+draw_round_rect (cairo_t *cr,
2436+ gdouble x,
2437+ gdouble y,
2438+ gdouble width,
2439+ gdouble height,
2440+ gdouble radius)
2441+{
2442+ radius = MIN (radius, MIN (width / 2.0, height / 2.0));
2443+
2444+ if (radius < 1)
2445+ {
2446+ cairo_rectangle (cr, x, y, width, height);
2447+ return;
2448+ }
2449+
2450+ cairo_move_to (cr, x + radius, y);
2451+
2452+ cairo_arc (cr, x + width - radius, y + radius, radius, G_PI * 1.5, G_PI * 2);
2453+ cairo_arc (cr, x + width - radius, y + height - radius, radius, 0, G_PI * 0.5);
2454+ cairo_arc (cr, x + radius, y + height - radius, radius, G_PI * 0.5, G_PI);
2455+ cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI * 1.5);
2456+}
2457+
2458 static gboolean
2459 os_thumb_expose (GtkWidget *widget,
2460 GdkEventExpose *event)
2461@@ -413,7 +377,7 @@
2462 cairo_set_line_width (cr, 1);
2463 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
2464
2465- os_cairo_draw_rounded_rect (cr, x, y, width, height, radius);
2466+ draw_round_rect (cr, x, y, width, height, radius);
2467
2468 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
2469 pat = cairo_pattern_create_linear (x, y, width + x, y);
2470@@ -426,7 +390,7 @@
2471 cairo_pattern_destroy (pat);
2472 cairo_fill (cr);
2473
2474- os_cairo_draw_rounded_rect (cr, x, y, width, height, radius);
2475+ draw_round_rect (cr, x, y, width, height, radius);
2476
2477 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
2478 pat = cairo_pattern_create_linear (x, y, x, height + y);
2479@@ -461,7 +425,6 @@
2480 cairo_set_source (cr, pat);
2481 cairo_pattern_destroy (pat);
2482
2483-
2484 if (priv->motion_notify_event)
2485 {
2486 cairo_fill_preserve (cr);
2487@@ -472,7 +435,7 @@
2488 cairo_fill (cr);
2489
2490 cairo_set_line_width (cr, 2.0);
2491- os_cairo_draw_rounded_rect (cr, x + 0.5, y + 0.5, width - 1, height - 1, radius - 1);
2492+ draw_round_rect (cr, x + 0.5, y + 0.5, width - 1, height - 1, radius - 1);
2493 if (!priv->detached)
2494 cairo_set_source_rgba (cr, style->bg[GTK_STATE_SELECTED].red/65535.0,
2495 style->bg[GTK_STATE_SELECTED].green/65535.0,
2496@@ -482,15 +445,15 @@
2497 cairo_stroke (cr);
2498
2499 cairo_set_line_width (cr, 1.0);
2500- os_cairo_draw_rounded_rect (cr, x + 1, y + 1, width - 2, height - 2, radius - 1);
2501+ draw_round_rect (cr, x + 1, y + 1, width - 2, height - 2, radius - 1);
2502 cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 0.1);
2503 cairo_stroke (cr);
2504
2505- os_cairo_draw_rounded_rect (cr, x + 2, y + 2, width - 4, height - 4, radius - 3);
2506+ draw_round_rect (cr, x + 2, y + 2, width - 4, height - 4, radius - 3);
2507 cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, 0.5);
2508 cairo_stroke (cr);
2509
2510- os_cairo_draw_rounded_rect (cr, x + 3, y + 3, width - 6, height - 6, radius - 4);
2511+ draw_round_rect (cr, x + 3, y + 3, width - 6, height - 6, radius - 4);
2512 cairo_set_source_rgba (cr, 1, 1, 1, 0.2);
2513 cairo_stroke (cr);
2514
2515@@ -525,14 +488,14 @@
2516 cairo_save (cr);
2517 cairo_translate (cr, 8.5, 8.5);
2518 cairo_rotate (cr, G_PI);
2519- os_cairo_draw_arrow (cr, 0.5, 0, 4, 3);
2520+ draw_arrow (cr, 0.5, 0, 4, 3);
2521 cairo_restore (cr);
2522
2523 /* direction DOWN. */
2524 cairo_save (cr);
2525 cairo_translate (cr, 8.5, height - 8.5);
2526 cairo_rotate (cr, 0);
2527- os_cairo_draw_arrow (cr, -0.5, 0, 4, 3);
2528+ draw_arrow (cr, -0.5, 0, 4, 3);
2529 cairo_restore (cr);
2530 }
2531 else
2532@@ -541,14 +504,14 @@
2533 cairo_save (cr);
2534 cairo_translate (cr, 8.5, 8.5);
2535 cairo_rotate (cr, G_PI * 0.5);
2536- os_cairo_draw_arrow (cr, -0.5, 0, 4, 3);
2537+ draw_arrow (cr, -0.5, 0, 4, 3);
2538 cairo_restore (cr);
2539
2540 /* direction RIGHT. */
2541 cairo_save (cr);
2542 cairo_translate (cr, width - 8.5, 8.5);
2543 cairo_rotate (cr, G_PI * 1.5);
2544- os_cairo_draw_arrow (cr, 0.5, 0, 4, 3);
2545+ draw_arrow (cr, 0.5, 0, 4, 3);
2546 cairo_restore (cr);
2547 }
2548
2549@@ -649,7 +612,7 @@
2550 {
2551 priv->use_tolerance = FALSE;
2552 priv->source_id = g_timeout_add (TIMEOUT_FADE_OUT,
2553- os_thumb_timeout_fade_out_cb,
2554+ timeout_fade_out_cb,
2555 thumb);
2556 }
2557 }
2558@@ -700,7 +663,7 @@
2559 gtk_window_set_opacity (GTK_WINDOW (widget), 1.0f);
2560
2561 priv->source_id = g_timeout_add (TIMEOUT_FADE_OUT,
2562- os_thumb_timeout_fade_out_cb,
2563+ timeout_fade_out_cb,
2564 thumb);
2565
2566 return FALSE;
2567@@ -742,6 +705,42 @@
2568 }
2569
2570 static void
2571+os_thumb_dispose (GObject *object)
2572+{
2573+ OsThumb *thumb;
2574+ OsThumbPrivate *priv;
2575+
2576+ thumb = OS_THUMB (object);
2577+ priv = thumb->priv;
2578+
2579+ if (priv->source_id != 0)
2580+ {
2581+ g_source_remove (priv->source_id);
2582+ priv->source_id = 0;
2583+ }
2584+
2585+ if (priv->animation != NULL)
2586+ {
2587+ g_object_unref (priv->animation);
2588+ priv->animation = NULL;
2589+ }
2590+
2591+ if (priv->grabbed_widget != NULL)
2592+ {
2593+ g_object_unref (priv->grabbed_widget);
2594+ priv->grabbed_widget = NULL;
2595+ }
2596+
2597+ G_OBJECT_CLASS (os_thumb_parent_class)->dispose (object);
2598+}
2599+
2600+static void
2601+os_thumb_finalize (GObject *object)
2602+{
2603+ G_OBJECT_CLASS (os_thumb_parent_class)->finalize (object);
2604+}
2605+
2606+static void
2607 os_thumb_get_property (GObject *object,
2608 guint prop_id,
2609 GValue *value,

Subscribers

People subscribed via source and target branches