Merge lp:~cimi/overlay-scrollbar/new-thumb-functionalities into lp:overlay-scrollbar
- new-thumb-functionalities
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 311 |
Proposed branch: | lp:~cimi/overlay-scrollbar/new-thumb-functionalities |
Merge into: | lp:overlay-scrollbar |
Diff against target: |
4177 lines (+1568/-1308) 5 files modified
os/Makefile.am (+1/-1) os/os-bar.c (+454/-355) os/os-private.h (+63/-53) os/os-scrollbar.c (+1008/-866) os/os-thumb.c (+42/-33) |
To merge this branch: | bzr merge lp:~cimi/overlay-scrollbar/new-thumb-functionalities |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
Review via email:
|
Commit message
Description of the change
Big changes... are you really sure you want to review that? :-)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
From an usability point of view I'd reduce the value of TIMEOUT_THUMB_SHOW to 50ms. It seems better here.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andrea Cimitan (cimi) wrote : | # |
Marco, I'm thinking about increasing it to 150 :-) Please notice that the timeout is not respected when the thumb is touching the screen edge.
Anyway, the branch is still in progress :-) Not ready for review (see the "Status"!)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ted Gould (ted) wrote : | # |
In general, I'm a little uncomfortable with all the bit twittling for the state variable. I think that you should put that into its own function. Two reasons, it's easy to mess up. And it seems to be likely someplace you'll want to put a g_debug() statement when things are going wrong.
Also, the diffs would be a lot smaller if the name changes weren't included with the logic changes. I think next time you should split those out into two different merge requests.
Other than that, it was a big diff! :-) I didn't see anything on a general read through.
Preview Diff
1 | === modified file 'os/Makefile.am' |
2 | --- os/Makefile.am 2011-10-05 12:24:21 +0000 |
3 | +++ os/Makefile.am 2011-10-12 17:16:23 +0000 |
4 | @@ -16,8 +16,8 @@ |
5 | |
6 | source_c = \ |
7 | $(srcdir)/os-animation.c \ |
8 | + $(srcdir)/os-bar.c \ |
9 | $(srcdir)/os-log.c \ |
10 | - $(srcdir)/os-pager.c \ |
11 | $(srcdir)/os-scrollbar.c \ |
12 | $(srcdir)/os-thumb.c \ |
13 | $(srcdir)/os-utils.c |
14 | |
15 | === renamed file 'os/os-pager.c' => 'os/os-bar.c' |
16 | --- os/os-pager.c 2011-10-05 12:24:21 +0000 |
17 | +++ os/os-bar.c 2011-10-12 17:16:23 +0000 |
18 | @@ -29,78 +29,45 @@ |
19 | #include <cairo-xlib.h> |
20 | #include <gdk/gdkx.h> |
21 | |
22 | -/* Rate of the fade. */ |
23 | -#define RATE_FADE 30 |
24 | - |
25 | /* Duration of the fade-in. */ |
26 | #define DURATION_FADE_IN 200 |
27 | |
28 | /* Duration of the fade-out. */ |
29 | #define DURATION_FADE_OUT 400 |
30 | |
31 | +/* Max duration of the retracting tail. */ |
32 | +#define MAX_DURATION_TAIL 600 |
33 | + |
34 | +/* Min duration of the retracting tail. */ |
35 | +#define MIN_DURATION_TAIL 100 |
36 | + |
37 | #ifdef USE_GTK3 |
38 | #define SHAPE_REGION(x) (cairo_region_create_rectangle (x)) |
39 | #else |
40 | #define SHAPE_REGION(x) (gdk_region_rectangle (x)) |
41 | #endif |
42 | |
43 | -struct _OsPagerPrivate { |
44 | - GdkWindow *pager_window; |
45 | - GdkWindow *connection_window; |
46 | +struct _OsBarPrivate { |
47 | + GdkRectangle bar_mask; |
48 | + GdkRectangle tail_mask; /* In theory not needed, but easier to read. */ |
49 | + GdkRectangle allocation; |
50 | + GdkWindow *bar_window; |
51 | + GdkWindow *tail_window; |
52 | GtkWidget *parent; |
53 | - GdkRectangle mask; |
54 | - GdkRectangle connection_mask; /* In theory not needed, but easier to read. */ |
55 | - GdkRectangle allocation; |
56 | - OsAnimation *animation; |
57 | + OsAnimation *state_animation; |
58 | + OsAnimation *tail_animation; |
59 | gboolean active; |
60 | gboolean detached; |
61 | gboolean visible; |
62 | gfloat weight; |
63 | - gulong handler_id; |
64 | }; |
65 | |
66 | -static void os_pager_dispose (GObject *object); |
67 | -static void os_pager_finalize (GObject *object); |
68 | - |
69 | -/* Draw on the connection_window. */ |
70 | -static void |
71 | -draw_connection (OsPager *pager) |
72 | -{ |
73 | -#ifdef USE_GTK3 |
74 | - GdkRGBA color; |
75 | - GtkStyleContext *style_context; |
76 | -#else |
77 | - GdkColor color; |
78 | - GtkStyle *style; |
79 | -#endif |
80 | - OsPagerPrivate *priv; |
81 | - |
82 | - priv = pager->priv; |
83 | - |
84 | -#ifdef USE_GTK3 |
85 | - style_context = gtk_widget_get_style_context (priv->parent); |
86 | - |
87 | - gtk_style_context_get_background_color (style_context, GTK_STATE_FLAG_ACTIVE, &color); |
88 | - |
89 | - color.alpha = 1.0; |
90 | - |
91 | - gdk_window_set_background_rgba (priv->connection_window, &color); |
92 | -#else |
93 | - style = gtk_widget_get_style (priv->parent); |
94 | - |
95 | - color = style->bg[GTK_STATE_ACTIVE]; |
96 | - |
97 | - gdk_colormap_alloc_color (gdk_drawable_get_colormap (priv->connection_window), &color, FALSE, TRUE); |
98 | - |
99 | - gdk_window_set_background (priv->connection_window, &color); |
100 | -#endif |
101 | - |
102 | - gdk_window_invalidate_rect (gtk_widget_get_window (priv->parent), &priv->allocation, TRUE); |
103 | -} |
104 | - |
105 | -/* Draw on the pager_window. */ |
106 | -static void |
107 | -draw_pager (OsPager *pager) |
108 | +static void os_bar_dispose (GObject *object); |
109 | +static void os_bar_finalize (GObject *object); |
110 | + |
111 | +/* Draw on the bar_window. */ |
112 | +static void |
113 | +draw_bar (OsBar *bar) |
114 | { |
115 | #ifdef USE_GTK3 |
116 | GdkRGBA c1, c2, color; |
117 | @@ -109,10 +76,10 @@ |
118 | GdkColor c1, c2, color; |
119 | GtkStyle *style; |
120 | #endif |
121 | - OsPagerPrivate *priv; |
122 | + OsBarPrivate *priv; |
123 | gfloat weight; |
124 | |
125 | - priv = pager->priv; |
126 | + priv = bar->priv; |
127 | |
128 | weight = priv->weight; |
129 | |
130 | @@ -135,7 +102,7 @@ |
131 | color.blue = weight * c1.blue + (1.0 - weight) * c2.blue; |
132 | color.alpha = 1.0; |
133 | |
134 | - gdk_window_set_background_rgba (priv->pager_window, &color); |
135 | + gdk_window_set_background_rgba (priv->bar_window, &color); |
136 | #else |
137 | style = gtk_widget_get_style (priv->parent); |
138 | |
139 | @@ -154,9 +121,45 @@ |
140 | color.green = weight * c1.green + (1.0 - weight) * c2.green; |
141 | color.blue = weight * c1.blue + (1.0 - weight) * c2.blue; |
142 | |
143 | - gdk_colormap_alloc_color (gdk_drawable_get_colormap (priv->pager_window), &color, FALSE, TRUE); |
144 | - |
145 | - gdk_window_set_background (priv->pager_window, &color); |
146 | + gdk_colormap_alloc_color (gdk_drawable_get_colormap (priv->bar_window), &color, FALSE, TRUE); |
147 | + |
148 | + gdk_window_set_background (priv->bar_window, &color); |
149 | +#endif |
150 | + |
151 | + gdk_window_invalidate_rect (gtk_widget_get_window (priv->parent), &priv->allocation, TRUE); |
152 | +} |
153 | + |
154 | +/* Draw on the tail_window. */ |
155 | +static void |
156 | +draw_tail (OsBar *bar) |
157 | +{ |
158 | +#ifdef USE_GTK3 |
159 | + GdkRGBA color; |
160 | + GtkStyleContext *style_context; |
161 | +#else |
162 | + GdkColor color; |
163 | + GtkStyle *style; |
164 | +#endif |
165 | + OsBarPrivate *priv; |
166 | + |
167 | + priv = bar->priv; |
168 | + |
169 | +#ifdef USE_GTK3 |
170 | + style_context = gtk_widget_get_style_context (priv->parent); |
171 | + |
172 | + gtk_style_context_get_background_color (style_context, GTK_STATE_FLAG_ACTIVE, &color); |
173 | + |
174 | + color.alpha = 1.0; |
175 | + |
176 | + gdk_window_set_background_rgba (priv->tail_window, &color); |
177 | +#else |
178 | + style = gtk_widget_get_style (priv->parent); |
179 | + |
180 | + color = style->bg[GTK_STATE_ACTIVE]; |
181 | + |
182 | + gdk_colormap_alloc_color (gdk_drawable_get_colormap (priv->tail_window), &color, FALSE, TRUE); |
183 | + |
184 | + gdk_window_set_background (priv->tail_window, &color); |
185 | #endif |
186 | |
187 | gdk_window_invalidate_rect (gtk_widget_get_window (priv->parent), &priv->allocation, TRUE); |
188 | @@ -167,35 +170,35 @@ |
189 | change_state_cb (gfloat weight, |
190 | gpointer user_data) |
191 | { |
192 | - OsPager *pager; |
193 | - OsPagerPrivate *priv; |
194 | - |
195 | - pager = OS_PAGER (user_data); |
196 | - |
197 | - priv = pager->priv; |
198 | + OsBar *bar; |
199 | + OsBarPrivate *priv; |
200 | + |
201 | + bar = OS_BAR (user_data); |
202 | + |
203 | + priv = bar->priv; |
204 | |
205 | priv->weight = weight; |
206 | |
207 | if (priv->parent == NULL) |
208 | return; |
209 | |
210 | - draw_pager (pager); |
211 | + draw_bar (bar); |
212 | } |
213 | |
214 | /* Stop function called by the change-state animation. */ |
215 | static void |
216 | change_state_stop_cb (gpointer user_data) |
217 | { |
218 | - OsPager *pager; |
219 | - OsPagerPrivate *priv; |
220 | - |
221 | - pager = OS_PAGER (user_data); |
222 | - |
223 | - priv = pager->priv; |
224 | + OsBar *bar; |
225 | + OsBarPrivate *priv; |
226 | + |
227 | + bar = OS_BAR (user_data); |
228 | + |
229 | + priv = bar->priv; |
230 | |
231 | priv->weight = 1.0f; |
232 | |
233 | - draw_pager (pager); |
234 | + draw_bar (bar); |
235 | } |
236 | |
237 | /* Callback called when the Gtk+ theme changes. */ |
238 | @@ -204,19 +207,19 @@ |
239 | GParamSpec* pspec, |
240 | gpointer user_data) |
241 | { |
242 | - OsPager *pager; |
243 | - OsPagerPrivate *priv; |
244 | + OsBar *bar; |
245 | + OsBarPrivate *priv; |
246 | |
247 | - pager = OS_PAGER (user_data); |
248 | - priv = pager->priv; |
249 | + bar = OS_BAR (user_data); |
250 | + priv = bar->priv; |
251 | |
252 | if (priv->parent == NULL || |
253 | - priv->pager_window == NULL || |
254 | - priv->connection_window == NULL) |
255 | + priv->bar_window == NULL || |
256 | + priv->tail_window == NULL) |
257 | return; |
258 | |
259 | - draw_connection (pager); |
260 | - draw_pager (pager); |
261 | + draw_tail (bar); |
262 | + draw_bar (bar); |
263 | } |
264 | |
265 | /* Check if two GdkRectangle are different. */ |
266 | @@ -232,29 +235,93 @@ |
267 | return FALSE; |
268 | } |
269 | |
270 | -G_DEFINE_TYPE (OsPager, os_pager, G_TYPE_OBJECT); |
271 | - |
272 | -static void |
273 | -os_pager_class_init (OsPagerClass *class) |
274 | +/* Callback called by the retract-tail animation. */ |
275 | +static void |
276 | +retract_tail_cb (gfloat weight, |
277 | + gpointer user_data) |
278 | +{ |
279 | + GdkRectangle tail_mask; |
280 | + OsBar *bar; |
281 | + OsBarPrivate *priv; |
282 | + |
283 | + bar = OS_BAR (user_data); |
284 | + |
285 | + priv = bar->priv; |
286 | + |
287 | + if (priv->parent == NULL) |
288 | + return; |
289 | + |
290 | + tail_mask = priv->tail_mask; |
291 | + |
292 | + if (priv->allocation.height >= priv->allocation.width) |
293 | + { |
294 | + tail_mask.height = tail_mask.height * (1.0 - weight); |
295 | + |
296 | + if (priv->tail_mask.y + priv->tail_mask.height < priv->bar_mask.y + priv->bar_mask.height) |
297 | + tail_mask.y = priv->tail_mask.y + priv->tail_mask.height - tail_mask.height; |
298 | + } |
299 | + else |
300 | + { |
301 | + tail_mask.width = tail_mask.width * (1.0 - weight); |
302 | + |
303 | + if (priv->tail_mask.x + priv->tail_mask.width < priv->bar_mask.x + priv->bar_mask.width) |
304 | + tail_mask.x = priv->tail_mask.x + priv->tail_mask.width - tail_mask.width; |
305 | + } |
306 | + |
307 | + if (weight < 1.0) |
308 | + gdk_window_shape_combine_region (priv->tail_window, |
309 | + SHAPE_REGION(&tail_mask), |
310 | + 0, 0); |
311 | + else |
312 | + { |
313 | + /* Store the new tail_mask and hide the tail_window. */ |
314 | + priv->tail_mask = tail_mask; |
315 | + gdk_window_hide (priv->tail_window); |
316 | + } |
317 | +} |
318 | + |
319 | +/* Stop function called by the retract-tail animation. */ |
320 | +static void |
321 | +retract_tail_stop_cb (gpointer user_data) |
322 | +{ |
323 | + OsBar *bar; |
324 | + OsBarPrivate *priv; |
325 | + |
326 | + bar = OS_BAR (user_data); |
327 | + |
328 | + priv = bar->priv; |
329 | + |
330 | + if (priv->parent == NULL) |
331 | + return; |
332 | + |
333 | + gdk_window_shape_combine_region (priv->tail_window, |
334 | + SHAPE_REGION(&priv->tail_mask), |
335 | + 0, 0); |
336 | +} |
337 | + |
338 | +G_DEFINE_TYPE (OsBar, os_bar, G_TYPE_OBJECT); |
339 | + |
340 | +static void |
341 | +os_bar_class_init (OsBarClass *class) |
342 | { |
343 | GObjectClass *gobject_class = G_OBJECT_CLASS (class); |
344 | |
345 | - gobject_class->dispose = os_pager_dispose; |
346 | - gobject_class->finalize = os_pager_finalize; |
347 | + gobject_class->dispose = os_bar_dispose; |
348 | + gobject_class->finalize = os_bar_finalize; |
349 | |
350 | - g_type_class_add_private (gobject_class, sizeof (OsPagerPrivate)); |
351 | + g_type_class_add_private (gobject_class, sizeof (OsBarPrivate)); |
352 | } |
353 | |
354 | static void |
355 | -os_pager_init (OsPager *pager) |
356 | +os_bar_init (OsBar *bar) |
357 | { |
358 | GdkRectangle allocation, mask; |
359 | - OsPagerPrivate *priv; |
360 | + OsBarPrivate *priv; |
361 | |
362 | - pager->priv = G_TYPE_INSTANCE_GET_PRIVATE (pager, |
363 | - OS_TYPE_PAGER, |
364 | - OsPagerPrivate); |
365 | - priv = pager->priv; |
366 | + bar->priv = G_TYPE_INSTANCE_GET_PRIVATE (bar, |
367 | + OS_TYPE_BAR, |
368 | + OsBarPrivate); |
369 | + priv = bar->priv; |
370 | |
371 | allocation.x = 0; |
372 | allocation.y = 0; |
373 | @@ -268,8 +335,8 @@ |
374 | mask.width = 1; |
375 | mask.height = 1; |
376 | |
377 | - priv->connection_mask = mask; |
378 | - priv->mask = mask; |
379 | + priv->bar_mask = mask; |
380 | + priv->tail_mask = mask; |
381 | |
382 | priv->active = FALSE; |
383 | priv->detached = FALSE; |
384 | @@ -277,217 +344,227 @@ |
385 | |
386 | priv->weight = 1.0f; |
387 | |
388 | - priv->animation = os_animation_new (RATE_FADE, DURATION_FADE_OUT, |
389 | - change_state_cb, NULL, pager); |
390 | - |
391 | - priv->handler_id = g_signal_connect (gtk_settings_get_default (), "notify::gtk-theme-name", |
392 | - G_CALLBACK (notify_gtk_theme_name_cb), pager); |
393 | -} |
394 | - |
395 | -static void |
396 | -os_pager_dispose (GObject *object) |
397 | -{ |
398 | - OsPager *pager; |
399 | - OsPagerPrivate *priv; |
400 | - |
401 | - pager = OS_PAGER (object); |
402 | - priv = pager->priv; |
403 | - |
404 | - if (priv->animation != NULL) |
405 | - { |
406 | - g_object_unref (priv->animation); |
407 | - priv->animation = NULL; |
408 | - } |
409 | - |
410 | - if (priv->connection_window != NULL) |
411 | - { |
412 | - /* From the Gdk documentation: |
413 | - * "Note that a window will not be destroyed |
414 | - * automatically when its reference count |
415 | - * reaches zero. You must call |
416 | - * gdk_window_destroy () |
417 | - * yourself before that happens". */ |
418 | - gdk_window_destroy (priv->connection_window); |
419 | - |
420 | - g_object_unref (priv->connection_window); |
421 | - priv->connection_window = NULL; |
422 | - } |
423 | - |
424 | - if (priv->pager_window != NULL) |
425 | - { |
426 | - /* From the Gdk documentation: |
427 | - * "Note that a window will not be destroyed |
428 | - * automatically when its reference count |
429 | - * reaches zero. You must call |
430 | - * gdk_window_destroy () |
431 | - * yourself before that happens". */ |
432 | - gdk_window_destroy (priv->pager_window); |
433 | - |
434 | - g_object_unref (priv->pager_window); |
435 | - priv->pager_window = NULL; |
436 | - } |
437 | - |
438 | - os_pager_set_parent (pager, NULL); |
439 | - |
440 | - g_signal_handler_disconnect (gtk_settings_get_default (), |
441 | - priv->handler_id); |
442 | - |
443 | - G_OBJECT_CLASS (os_pager_parent_class)->dispose (object); |
444 | -} |
445 | - |
446 | -static void |
447 | -os_pager_finalize (GObject *object) |
448 | -{ |
449 | - G_OBJECT_CLASS (os_pager_parent_class)->finalize (object); |
450 | + priv->state_animation = os_animation_new (RATE_ANIMATION, DURATION_FADE_OUT, |
451 | + change_state_cb, NULL, bar); |
452 | + priv->tail_animation = os_animation_new (RATE_ANIMATION, MAX_DURATION_TAIL, |
453 | + retract_tail_cb, NULL, bar); |
454 | + |
455 | + g_signal_connect (gtk_settings_get_default (), "notify::gtk-theme-name", |
456 | + G_CALLBACK (notify_gtk_theme_name_cb), bar); |
457 | +} |
458 | + |
459 | +static void |
460 | +os_bar_dispose (GObject *object) |
461 | +{ |
462 | + OsBar *bar; |
463 | + OsBarPrivate *priv; |
464 | + |
465 | + bar = OS_BAR (object); |
466 | + priv = bar->priv; |
467 | + |
468 | + if (priv->tail_animation != NULL) |
469 | + { |
470 | + g_object_unref (priv->tail_animation); |
471 | + priv->tail_animation = NULL; |
472 | + } |
473 | + |
474 | + if (priv->state_animation != NULL) |
475 | + { |
476 | + g_object_unref (priv->state_animation); |
477 | + priv->state_animation = NULL; |
478 | + } |
479 | + |
480 | + if (priv->tail_window != NULL) |
481 | + { |
482 | + /* From the Gdk documentation: |
483 | + * "Note that a window will not be destroyed |
484 | + * automatically when its reference count |
485 | + * reaches zero. You must call |
486 | + * gdk_window_destroy () |
487 | + * yourself before that happens". */ |
488 | + gdk_window_destroy (priv->tail_window); |
489 | + |
490 | + g_object_unref (priv->tail_window); |
491 | + priv->tail_window = NULL; |
492 | + } |
493 | + |
494 | + if (priv->bar_window != NULL) |
495 | + { |
496 | + /* From the Gdk documentation: |
497 | + * "Note that a window will not be destroyed |
498 | + * automatically when its reference count |
499 | + * reaches zero. You must call |
500 | + * gdk_window_destroy () |
501 | + * yourself before that happens". */ |
502 | + gdk_window_destroy (priv->bar_window); |
503 | + |
504 | + g_object_unref (priv->bar_window); |
505 | + priv->bar_window = NULL; |
506 | + } |
507 | + |
508 | + os_bar_set_parent (bar, NULL); |
509 | + |
510 | + G_OBJECT_CLASS (os_bar_parent_class)->dispose (object); |
511 | +} |
512 | + |
513 | +static void |
514 | +os_bar_finalize (GObject *object) |
515 | +{ |
516 | + G_OBJECT_CLASS (os_bar_parent_class)->finalize (object); |
517 | } |
518 | |
519 | /* Public functions. */ |
520 | |
521 | /** |
522 | - * os_pager_new: |
523 | - * |
524 | - * Creates a new #OsPager instance. |
525 | - * |
526 | - * Returns: the new #OsPager instance. |
527 | + * os_bar_new: |
528 | + * |
529 | + * Creates a new #OsBar instance. |
530 | + * |
531 | + * Returns: the new #OsBar instance. |
532 | **/ |
533 | -OsPager* |
534 | -os_pager_new (void) |
535 | +OsBar* |
536 | +os_bar_new (void) |
537 | { |
538 | - return g_object_new (OS_TYPE_PAGER, NULL); |
539 | + return g_object_new (OS_TYPE_BAR, NULL); |
540 | } |
541 | |
542 | -/* Move a mask on the connection_window, fake movement. */ |
543 | +/* Move a mask on the tail_window, fake movement. */ |
544 | static void |
545 | -mask_connection (OsPager *pager) |
546 | +mask_tail (OsBar *bar) |
547 | { |
548 | - OsPagerPrivate *priv; |
549 | - |
550 | - priv = pager->priv; |
551 | - |
552 | - gdk_window_shape_combine_region (priv->connection_window, |
553 | - SHAPE_REGION(&priv->connection_mask), |
554 | + OsBarPrivate *priv; |
555 | + |
556 | + priv = bar->priv; |
557 | + |
558 | + gdk_window_shape_combine_region (priv->tail_window, |
559 | + SHAPE_REGION(&priv->tail_mask), |
560 | 0, 0); |
561 | } |
562 | |
563 | /** |
564 | - * os_pager_connect: |
565 | - * @pager: a #OsPager |
566 | - * @mask: a #GdkRectangle with the position and dimension of the connection |
567 | - * |
568 | - * Moves and resizes connection. |
569 | - **/ |
570 | -void |
571 | -os_pager_connect (OsPager *pager, |
572 | - GdkRectangle mask) |
573 | -{ |
574 | - OsPagerPrivate *priv; |
575 | - |
576 | - g_return_if_fail (OS_IS_PAGER (pager)); |
577 | - |
578 | - priv = pager->priv; |
579 | - |
580 | - if (!rectangle_changed (priv->connection_mask, mask)) |
581 | - return; |
582 | - |
583 | - priv->connection_mask = mask; |
584 | - |
585 | - if (priv->parent == NULL) |
586 | - return; |
587 | - |
588 | - mask_connection (pager); |
589 | -} |
590 | - |
591 | -/** |
592 | - * os_pager_hide: |
593 | - * @pager: a #OsPager |
594 | - * |
595 | - * Hides the #OsPager. |
596 | - **/ |
597 | -void |
598 | -os_pager_hide (OsPager *pager) |
599 | -{ |
600 | - OsPagerPrivate *priv; |
601 | - |
602 | - g_return_if_fail (OS_IS_PAGER (pager)); |
603 | - |
604 | - priv = pager->priv; |
605 | - |
606 | - priv->visible = FALSE; |
607 | - |
608 | - if (priv->parent == NULL) |
609 | + * os_bar_connect: |
610 | + * @bar: a #OsBar |
611 | + * @mask: a #GdkRectangle with the position and dimension of the tail |
612 | + * |
613 | + * Moves and resizes tail. |
614 | + **/ |
615 | +void |
616 | +os_bar_connect (OsBar *bar, |
617 | + GdkRectangle mask) |
618 | +{ |
619 | + OsBarPrivate *priv; |
620 | + |
621 | + g_return_if_fail (OS_IS_BAR (bar)); |
622 | + |
623 | + priv = bar->priv; |
624 | + |
625 | + if (!os_animation_is_running (priv->tail_animation) && |
626 | + !rectangle_changed (priv->tail_mask, mask)) |
627 | return; |
628 | |
629 | /* If there's an animation currently running, stop it. */ |
630 | - os_animation_stop (priv->animation, change_state_stop_cb); |
631 | - |
632 | - gdk_window_hide (priv->connection_window); |
633 | - gdk_window_hide (priv->pager_window); |
634 | -} |
635 | - |
636 | -/* Move a mask on the pager_window, fake movement. */ |
637 | + os_animation_stop (priv->tail_animation, NULL); |
638 | + |
639 | + priv->tail_mask = mask; |
640 | + |
641 | + if (priv->parent == NULL) |
642 | + return; |
643 | + |
644 | + mask_tail (bar); |
645 | +} |
646 | + |
647 | +/** |
648 | + * os_bar_hide: |
649 | + * @bar: a #OsBar |
650 | + * |
651 | + * Hides the #OsBar. |
652 | + **/ |
653 | +void |
654 | +os_bar_hide (OsBar *bar) |
655 | +{ |
656 | + OsBarPrivate *priv; |
657 | + |
658 | + g_return_if_fail (OS_IS_BAR (bar)); |
659 | + |
660 | + priv = bar->priv; |
661 | + |
662 | + priv->visible = FALSE; |
663 | + |
664 | + if (priv->parent == NULL) |
665 | + return; |
666 | + |
667 | + /* Immediately hide, then stop animations. */ |
668 | + gdk_window_hide (priv->tail_window); |
669 | + gdk_window_hide (priv->bar_window); |
670 | + |
671 | + os_animation_stop (priv->tail_animation, retract_tail_stop_cb); |
672 | + os_animation_stop (priv->state_animation, change_state_stop_cb); |
673 | +} |
674 | + |
675 | +/* Move a mask on the bar_window, fake movement. */ |
676 | static void |
677 | -mask_pager (OsPager *pager) |
678 | +mask_bar (OsBar *bar) |
679 | { |
680 | - OsPagerPrivate *priv; |
681 | - |
682 | - priv = pager->priv; |
683 | - |
684 | - gdk_window_shape_combine_region (priv->pager_window, |
685 | - SHAPE_REGION(&priv->mask), |
686 | + OsBarPrivate *priv; |
687 | + |
688 | + priv = bar->priv; |
689 | + |
690 | + gdk_window_shape_combine_region (priv->bar_window, |
691 | + SHAPE_REGION(&priv->bar_mask), |
692 | 0, 0); |
693 | } |
694 | |
695 | /** |
696 | - * os_pager_move_resize: |
697 | - * @pager: a #OsPager |
698 | - * @mask: a #GdkRectangle with the position and dimension of the #OsPager |
699 | + * os_bar_move_resize: |
700 | + * @bar: a #OsBar |
701 | + * @mask: a #GdkRectangle with the position and dimension of the #OsBar |
702 | * |
703 | - * Moves and resizes @pager. |
704 | + * Moves and resizes @bar. |
705 | **/ |
706 | void |
707 | -os_pager_move_resize (OsPager *pager, |
708 | - GdkRectangle mask) |
709 | +os_bar_move_resize (OsBar *bar, |
710 | + GdkRectangle mask) |
711 | { |
712 | - OsPagerPrivate *priv; |
713 | - |
714 | - g_return_if_fail (OS_IS_PAGER (pager)); |
715 | - |
716 | - priv = pager->priv; |
717 | - |
718 | - if (!rectangle_changed (priv->mask, mask)) |
719 | + OsBarPrivate *priv; |
720 | + |
721 | + g_return_if_fail (OS_IS_BAR (bar)); |
722 | + |
723 | + priv = bar->priv; |
724 | + |
725 | + if (!rectangle_changed (priv->bar_mask, mask)) |
726 | return; |
727 | |
728 | - priv->mask = mask; |
729 | + priv->bar_mask = mask; |
730 | |
731 | if (priv->parent == NULL) |
732 | return; |
733 | |
734 | - mask_pager (pager); |
735 | + mask_bar (bar); |
736 | } |
737 | |
738 | /** |
739 | - * os_pager_set_active: |
740 | - * @pager: a #OsPager |
741 | + * os_bar_set_active: |
742 | + * @bar: a #OsBar |
743 | * @active: whether is active or not |
744 | - * @animation: whether animate it or not |
745 | + * @animate: whether animate it or not |
746 | * |
747 | - * Changes the activity state of @pager. |
748 | + * Changes the activity state of @bar. |
749 | **/ |
750 | void |
751 | -os_pager_set_active (OsPager *pager, |
752 | - gboolean active, |
753 | - gboolean animate) |
754 | +os_bar_set_active (OsBar *bar, |
755 | + gboolean active, |
756 | + gboolean animate) |
757 | { |
758 | - OsPagerPrivate *priv; |
759 | - |
760 | - g_return_if_fail (OS_IS_PAGER (pager)); |
761 | - |
762 | - priv = pager->priv; |
763 | - |
764 | - /* Set the state and draw even if there's an animation running, that is |
765 | - * (!animate && os_animation_is_running (priv->animation)). */ |
766 | + OsBarPrivate *priv; |
767 | + |
768 | + g_return_if_fail (OS_IS_BAR (bar)); |
769 | + |
770 | + priv = bar->priv; |
771 | + |
772 | + /* Set the state and draw even if there's a state_animation running, that is |
773 | + * (!animate && os_animation_is_running (priv->state_animation)). */ |
774 | if ((priv->active != active) || |
775 | - (!animate && os_animation_is_running (priv->animation))) |
776 | + (!animate && os_animation_is_running (priv->state_animation))) |
777 | { |
778 | gboolean visible; |
779 | |
780 | @@ -496,43 +573,45 @@ |
781 | if (priv->parent == NULL) |
782 | return; |
783 | |
784 | - visible = gdk_window_is_visible (priv->pager_window); |
785 | + visible = gdk_window_is_visible (priv->bar_window); |
786 | |
787 | if (visible) |
788 | - os_animation_stop (priv->animation, NULL); |
789 | + os_animation_stop (priv->state_animation, NULL); |
790 | |
791 | if (visible && animate) |
792 | { |
793 | - os_animation_set_duration (priv->animation, priv->active ? DURATION_FADE_IN : |
794 | - DURATION_FADE_OUT); |
795 | - os_animation_start (priv->animation); |
796 | + os_animation_set_duration (priv->state_animation, priv->active ? DURATION_FADE_IN : |
797 | + DURATION_FADE_OUT); |
798 | + os_animation_start (priv->state_animation); |
799 | } |
800 | |
801 | if (!visible || !animate) |
802 | { |
803 | priv->weight = 1.0f; |
804 | |
805 | - draw_pager (pager); |
806 | + draw_bar (bar); |
807 | } |
808 | } |
809 | } |
810 | |
811 | /** |
812 | - * os_pager_set_detached: |
813 | - * @pager: a #OsPager |
814 | - * @detached: whether the pager is detached or not |
815 | + * os_bar_set_detached: |
816 | + * @bar: a #OsBar |
817 | + * @detached: whether the bar is detached or not |
818 | + * @animate: whether animate it or not |
819 | * |
820 | - * Changes the detached state of @pager. |
821 | + * Changes the detached state of @bar. |
822 | **/ |
823 | void |
824 | -os_pager_set_detached (OsPager *pager, |
825 | - gboolean detached) |
826 | +os_bar_set_detached (OsBar *bar, |
827 | + gboolean detached, |
828 | + gboolean animate) |
829 | { |
830 | - OsPagerPrivate *priv; |
831 | - |
832 | - g_return_if_fail (OS_IS_PAGER (pager)); |
833 | - |
834 | - priv = pager->priv; |
835 | + OsBarPrivate *priv; |
836 | + |
837 | + g_return_if_fail (OS_IS_BAR (bar)); |
838 | + |
839 | + priv = bar->priv; |
840 | |
841 | if (priv->detached != detached) |
842 | { |
843 | @@ -543,27 +622,49 @@ |
844 | |
845 | if (priv->detached) |
846 | { |
847 | - gdk_window_show (priv->connection_window); |
848 | - gdk_window_raise (priv->pager_window); |
849 | + /* If there's a tail animation currently running, stop it. */ |
850 | + os_animation_stop (priv->tail_animation, retract_tail_stop_cb); |
851 | + |
852 | + /* No tail connection animation yet. */ |
853 | + gdk_window_show (priv->tail_window); |
854 | + gdk_window_raise (priv->bar_window); |
855 | + } |
856 | + else if (animate) |
857 | + { |
858 | + gint32 duration; |
859 | + |
860 | + /* The detached state should already stop this. */ |
861 | + OS_DCHECK (!os_animation_is_running (priv->tail_animation)); |
862 | + |
863 | + /* Calculate and set the duration. */ |
864 | + if (priv->allocation.height >= priv->allocation.width) |
865 | + duration = MIN_DURATION_TAIL + ((gdouble) priv->tail_mask.height / priv->allocation.height) * |
866 | + (MAX_DURATION_TAIL - MIN_DURATION_TAIL); |
867 | + else |
868 | + duration = MIN_DURATION_TAIL + ((gdouble) priv->tail_mask.width / priv->allocation.width) * |
869 | + (MAX_DURATION_TAIL - MIN_DURATION_TAIL); |
870 | + os_animation_set_duration (priv->tail_animation, duration); |
871 | + |
872 | + os_animation_start (priv->tail_animation); |
873 | } |
874 | else |
875 | - gdk_window_hide (priv->connection_window); |
876 | + gdk_window_hide (priv->tail_window); |
877 | } |
878 | } |
879 | |
880 | -/* Create connection_window and pager_window. */ |
881 | +/* Create tail_window and bar_window. */ |
882 | static void |
883 | -create_windows (OsPager *pager) |
884 | +create_windows (OsBar *bar) |
885 | { |
886 | GdkWindowAttr attributes; |
887 | - OsPagerPrivate *priv; |
888 | + OsBarPrivate *priv; |
889 | |
890 | - priv = pager->priv; |
891 | + priv = bar->priv; |
892 | |
893 | /* Instead reparenting, |
894 | * which doesn't seem to work well, |
895 | * destroy the two windows. */ |
896 | - if (priv->connection_window != NULL) |
897 | + if (priv->tail_window != NULL) |
898 | { |
899 | /* From the Gdk documentation: |
900 | * "Note that a window will not be destroyed |
901 | @@ -571,13 +672,13 @@ |
902 | * reaches zero. You must call |
903 | * gdk_window_destroy () |
904 | * yourself before that happens". */ |
905 | - gdk_window_destroy (priv->connection_window); |
906 | + gdk_window_destroy (priv->tail_window); |
907 | |
908 | - g_object_unref (priv->connection_window); |
909 | - priv->connection_window = NULL; |
910 | + g_object_unref (priv->tail_window); |
911 | + priv->tail_window = NULL; |
912 | } |
913 | |
914 | - if (priv->pager_window != NULL) |
915 | + if (priv->bar_window != NULL) |
916 | { |
917 | /* From the Gdk documentation: |
918 | * "Note that a window will not be destroyed |
919 | @@ -585,10 +686,10 @@ |
920 | * reaches zero. You must call |
921 | * gdk_window_destroy () |
922 | * yourself before that happens". */ |
923 | - gdk_window_destroy (priv->pager_window); |
924 | + gdk_window_destroy (priv->bar_window); |
925 | |
926 | - g_object_unref (priv->pager_window); |
927 | - priv->pager_window = NULL; |
928 | + g_object_unref (priv->bar_window); |
929 | + priv->bar_window = NULL; |
930 | } |
931 | |
932 | attributes.event_mask = 0; |
933 | @@ -601,8 +702,8 @@ |
934 | attributes.colormap = gtk_widget_get_colormap (priv->parent); |
935 | #endif |
936 | |
937 | - /* connection_window. */ |
938 | - priv->connection_window = gdk_window_new (gtk_widget_get_window (priv->parent), |
939 | + /* tail_window. */ |
940 | + priv->tail_window = gdk_window_new (gtk_widget_get_window (priv->parent), |
941 | &attributes, |
942 | #ifdef USE_GTK3 |
943 | GDK_WA_VISUAL); |
944 | @@ -610,13 +711,13 @@ |
945 | GDK_WA_VISUAL | GDK_WA_COLORMAP); |
946 | #endif |
947 | |
948 | - g_object_ref_sink (priv->connection_window); |
949 | + g_object_ref_sink (priv->tail_window); |
950 | |
951 | - gdk_window_set_transient_for (priv->connection_window, |
952 | + gdk_window_set_transient_for (priv->tail_window, |
953 | gtk_widget_get_window (priv->parent)); |
954 | |
955 | /* FIXME(Cimi) maybe this is not required with 0 as event mask. */ |
956 | - gdk_window_input_shape_combine_region (priv->connection_window, |
957 | + gdk_window_input_shape_combine_region (priv->tail_window, |
958 | #ifdef USE_GTK3 |
959 | cairo_region_create (), |
960 | #else |
961 | @@ -624,22 +725,22 @@ |
962 | #endif |
963 | 0, 0); |
964 | |
965 | - /* pager_window. */ |
966 | - priv->pager_window = gdk_window_new (gtk_widget_get_window (priv->parent), |
967 | - &attributes, |
968 | + /* bar_window. */ |
969 | + priv->bar_window = gdk_window_new (gtk_widget_get_window (priv->parent), |
970 | + &attributes, |
971 | #ifdef USE_GTK3 |
972 | - GDK_WA_VISUAL); |
973 | + GDK_WA_VISUAL); |
974 | #else |
975 | - GDK_WA_VISUAL | GDK_WA_COLORMAP); |
976 | + GDK_WA_VISUAL | GDK_WA_COLORMAP); |
977 | #endif |
978 | |
979 | - g_object_ref_sink (priv->pager_window); |
980 | + g_object_ref_sink (priv->bar_window); |
981 | |
982 | - gdk_window_set_transient_for (priv->pager_window, |
983 | + gdk_window_set_transient_for (priv->bar_window, |
984 | gtk_widget_get_window (priv->parent)); |
985 | |
986 | /* FIXME(Cimi) maybe this is not required with 0 as event mask. */ |
987 | - gdk_window_input_shape_combine_region (priv->pager_window, |
988 | + gdk_window_input_shape_combine_region (priv->bar_window, |
989 | #ifdef USE_GTK3 |
990 | cairo_region_create (), |
991 | #else |
992 | @@ -649,30 +750,30 @@ |
993 | } |
994 | |
995 | /** |
996 | - * os_pager_set_parent: |
997 | - * @pager: a #OsPager |
998 | + * os_bar_set_parent: |
999 | + * @bar: a #OsBar |
1000 | * @parent: a #GtkWidget |
1001 | * |
1002 | * Sets the parent widget |
1003 | **/ |
1004 | void |
1005 | -os_pager_set_parent (OsPager *pager, |
1006 | - GtkWidget *parent) |
1007 | +os_bar_set_parent (OsBar *bar, |
1008 | + GtkWidget *parent) |
1009 | { |
1010 | - OsPagerPrivate *priv; |
1011 | - |
1012 | - g_return_if_fail (OS_IS_PAGER (pager)); |
1013 | - |
1014 | - priv = pager->priv; |
1015 | - |
1016 | - /* Stop currently running animation. */ |
1017 | - if (priv->animation != NULL) |
1018 | - os_animation_stop (priv->animation, NULL); |
1019 | + OsBarPrivate *priv; |
1020 | + |
1021 | + g_return_if_fail (OS_IS_BAR (bar)); |
1022 | + |
1023 | + priv = bar->priv; |
1024 | + |
1025 | + /* Stop currently running animations. */ |
1026 | + if (priv->tail_animation != NULL) |
1027 | + os_animation_stop (priv->tail_animation, retract_tail_stop_cb); |
1028 | + if (priv->state_animation != NULL) |
1029 | + os_animation_stop (priv->state_animation, NULL); |
1030 | |
1031 | if (priv->parent != NULL) |
1032 | - { |
1033 | - g_object_unref (priv->parent); |
1034 | - } |
1035 | + g_object_unref (priv->parent); |
1036 | |
1037 | priv->parent = parent; |
1038 | |
1039 | @@ -682,69 +783,67 @@ |
1040 | |
1041 | priv->weight = 1.0f; |
1042 | |
1043 | - create_windows (pager); |
1044 | - draw_connection (pager); |
1045 | - draw_pager (pager); |
1046 | - mask_pager (pager); |
1047 | + create_windows (bar); |
1048 | + draw_tail (bar); |
1049 | + draw_bar (bar); |
1050 | + mask_bar (bar); |
1051 | |
1052 | - gdk_window_move_resize (priv->connection_window, |
1053 | + gdk_window_move_resize (priv->tail_window, |
1054 | priv->allocation.x, |
1055 | priv->allocation.y, |
1056 | priv->allocation.width, |
1057 | priv->allocation.height); |
1058 | |
1059 | - gdk_window_move_resize (priv->pager_window, |
1060 | + gdk_window_move_resize (priv->bar_window, |
1061 | priv->allocation.x, |
1062 | priv->allocation.y, |
1063 | priv->allocation.width, |
1064 | priv->allocation.height); |
1065 | |
1066 | if (priv->visible) |
1067 | - { |
1068 | - gdk_window_show (priv->pager_window); |
1069 | - } |
1070 | + gdk_window_show (priv->bar_window); |
1071 | } |
1072 | } |
1073 | |
1074 | /** |
1075 | - * os_pager_show: |
1076 | - * @pager: a #OsPager |
1077 | + * os_bar_show: |
1078 | + * @bar: a #OsBar |
1079 | * |
1080 | - * Shows @pager. |
1081 | + * Shows @bar. |
1082 | **/ |
1083 | void |
1084 | -os_pager_show (OsPager *pager) |
1085 | +os_bar_show (OsBar *bar) |
1086 | { |
1087 | - OsPagerPrivate *priv; |
1088 | - |
1089 | - g_return_if_fail (OS_IS_PAGER (pager)); |
1090 | - |
1091 | - priv = pager->priv; |
1092 | + OsBarPrivate *priv; |
1093 | + |
1094 | + g_return_if_fail (OS_IS_BAR (bar)); |
1095 | + |
1096 | + priv = bar->priv; |
1097 | |
1098 | priv->visible = TRUE; |
1099 | |
1100 | if (priv->parent == NULL) |
1101 | return; |
1102 | |
1103 | - gdk_window_show (priv->pager_window); |
1104 | + gdk_window_show (priv->bar_window); |
1105 | } |
1106 | |
1107 | /** |
1108 | - * os_pager_size_allocate: |
1109 | - * @pager: a #OsPager |
1110 | + * os_bar_size_allocate: |
1111 | + * @bar: a #OsBar |
1112 | * @rectangle: a #GdkRectangle |
1113 | * |
1114 | * Sets the position and dimension of the whole area. |
1115 | **/ |
1116 | void |
1117 | -os_pager_size_allocate (OsPager *pager, |
1118 | - GdkRectangle rectangle) |
1119 | +os_bar_size_allocate (OsBar *bar, |
1120 | + GdkRectangle rectangle) |
1121 | { |
1122 | - OsPagerPrivate *priv; |
1123 | - |
1124 | - g_return_if_fail (OS_IS_PAGER (pager)); |
1125 | - |
1126 | - priv = pager->priv; |
1127 | + OsBarPrivate *priv; |
1128 | + |
1129 | + g_return_if_fail (OS_IS_BAR (bar)); |
1130 | + |
1131 | + priv = bar->priv; |
1132 | |
1133 | if (!rectangle_changed (priv->allocation, rectangle)) |
1134 | return; |
1135 | @@ -754,13 +853,13 @@ |
1136 | if (priv->parent == NULL) |
1137 | return; |
1138 | |
1139 | - gdk_window_move_resize (priv->connection_window, |
1140 | + gdk_window_move_resize (priv->tail_window, |
1141 | rectangle.x, |
1142 | rectangle.y, |
1143 | rectangle.width, |
1144 | rectangle.height); |
1145 | |
1146 | - gdk_window_move_resize (priv->pager_window, |
1147 | + gdk_window_move_resize (priv->bar_window, |
1148 | rectangle.x, |
1149 | rectangle.y, |
1150 | rectangle.width, |
1151 | |
1152 | === modified file 'os/os-private.h' |
1153 | --- os/os-private.h 2011-10-05 12:24:21 +0000 |
1154 | +++ os/os-private.h 2011-10-12 17:16:23 +0000 |
1155 | @@ -30,7 +30,11 @@ |
1156 | #pragma GCC visibility push(hidden) |
1157 | #endif /* __GNUC__ */ |
1158 | |
1159 | +/* Rate of the animations (frames per second). */ |
1160 | +#define RATE_ANIMATION 30 |
1161 | + |
1162 | /* Size of the thumb in pixels. */ |
1163 | +#define MIN_THUMB_HEIGHT 35 |
1164 | #define THUMB_WIDTH 17 |
1165 | #define THUMB_HEIGHT 69 |
1166 | |
1167 | @@ -39,14 +43,19 @@ |
1168 | |
1169 | G_BEGIN_DECLS |
1170 | |
1171 | +typedef struct |
1172 | +{ |
1173 | + gint x; |
1174 | + gint y; |
1175 | +} OsCoordinate; |
1176 | + |
1177 | typedef enum |
1178 | { |
1179 | OS_EVENT_NONE = 0, |
1180 | OS_EVENT_BUTTON_PRESS = 1, |
1181 | OS_EVENT_ENTER_NOTIFY = 2, |
1182 | - OS_EVENT_MOTION_NOTIFY = 4, |
1183 | - OS_EVENT_VALUE_CHANGED = 8 |
1184 | -} OsEvent; |
1185 | + OS_EVENT_MOTION_NOTIFY = 4 |
1186 | +} OsEventFlags; |
1187 | |
1188 | /* os-log.c */ |
1189 | |
1190 | @@ -150,6 +159,57 @@ |
1191 | void os_animation_stop (OsAnimation *animation, |
1192 | OsAnimationStopFunc stop_func); |
1193 | |
1194 | +/* os-bar.c */ |
1195 | + |
1196 | +#define OS_TYPE_BAR (os_bar_get_type ()) |
1197 | +#define OS_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OS_TYPE_BAR, OsBar)) |
1198 | +#define OS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OS_TYPE_BAR, OsBarClass)) |
1199 | +#define OS_IS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OS_TYPE_BAR)) |
1200 | +#define OS_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OS_TYPE_BAR)) |
1201 | +#define OS_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OS_TYPE_BAR, OsBarClass)) |
1202 | + |
1203 | +typedef struct _OsBar OsBar; |
1204 | +typedef struct _OsBarClass OsBarClass; |
1205 | +typedef struct _OsBarPrivate OsBarPrivate; |
1206 | + |
1207 | +struct _OsBar { |
1208 | + GObject parent_instance; |
1209 | + |
1210 | + OsBarPrivate *priv; |
1211 | +}; |
1212 | + |
1213 | +struct _OsBarClass { |
1214 | + GObjectClass parent_class; |
1215 | +}; |
1216 | + |
1217 | +GType os_bar_get_type (void) G_GNUC_CONST; |
1218 | + |
1219 | +OsBar* os_bar_new (void); |
1220 | + |
1221 | +void os_bar_hide (OsBar *bar); |
1222 | + |
1223 | +void os_bar_connect (OsBar *bar, |
1224 | + GdkRectangle mask); |
1225 | + |
1226 | +void os_bar_move_resize (OsBar *bar, |
1227 | + GdkRectangle mask); |
1228 | + |
1229 | +void os_bar_set_active (OsBar *bar, |
1230 | + gboolean active, |
1231 | + gboolean animate); |
1232 | + |
1233 | +void os_bar_set_detached (OsBar *bar, |
1234 | + gboolean detached, |
1235 | + gboolean animate); |
1236 | + |
1237 | +void os_bar_set_parent (OsBar *bar, |
1238 | + GtkWidget *parent); |
1239 | + |
1240 | +void os_bar_show (OsBar *bar); |
1241 | + |
1242 | +void os_bar_size_allocate (OsBar *bar, |
1243 | + GdkRectangle rectangle); |
1244 | + |
1245 | /* os-thumb.c */ |
1246 | |
1247 | #define OS_TYPE_THUMB (os_thumb_get_type ()) |
1248 | @@ -184,56 +244,6 @@ |
1249 | void os_thumb_set_detached (OsThumb *thumb, |
1250 | gboolean detached); |
1251 | |
1252 | -/* os-pager.c */ |
1253 | - |
1254 | -#define OS_TYPE_PAGER (os_pager_get_type ()) |
1255 | -#define OS_PAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OS_TYPE_PAGER, OsPager)) |
1256 | -#define OS_PAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OS_TYPE_PAGER, OsPagerClass)) |
1257 | -#define OS_IS_PAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OS_TYPE_PAGER)) |
1258 | -#define OS_IS_PAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OS_TYPE_PAGER)) |
1259 | -#define OS_PAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OS_TYPE_PAGER, OsPagerClass)) |
1260 | - |
1261 | -typedef struct _OsPager OsPager; |
1262 | -typedef struct _OsPagerClass OsPagerClass; |
1263 | -typedef struct _OsPagerPrivate OsPagerPrivate; |
1264 | - |
1265 | -struct _OsPager { |
1266 | - GObject parent_instance; |
1267 | - |
1268 | - OsPagerPrivate *priv; |
1269 | -}; |
1270 | - |
1271 | -struct _OsPagerClass { |
1272 | - GObjectClass parent_class; |
1273 | -}; |
1274 | - |
1275 | -GType os_pager_get_type (void) G_GNUC_CONST; |
1276 | - |
1277 | -OsPager* os_pager_new (void); |
1278 | - |
1279 | -void os_pager_hide (OsPager *pager); |
1280 | - |
1281 | -void os_pager_connect (OsPager *pager, |
1282 | - GdkRectangle mask); |
1283 | - |
1284 | -void os_pager_move_resize (OsPager *pager, |
1285 | - GdkRectangle mask); |
1286 | - |
1287 | -void os_pager_set_active (OsPager *pager, |
1288 | - gboolean active, |
1289 | - gboolean animate); |
1290 | - |
1291 | -void os_pager_set_detached (OsPager *pager, |
1292 | - gboolean detached); |
1293 | - |
1294 | -void os_pager_set_parent (OsPager *pager, |
1295 | - GtkWidget *parent); |
1296 | - |
1297 | -void os_pager_show (OsPager *pager); |
1298 | - |
1299 | -void os_pager_size_allocate (OsPager *pager, |
1300 | - GdkRectangle rectangle); |
1301 | - |
1302 | G_END_DECLS |
1303 | |
1304 | #ifdef __GNUC__ |
1305 | |
1306 | === modified file 'os/os-scrollbar.c' |
1307 | --- os/os-scrollbar.c 2011-10-05 12:24:21 +0000 |
1308 | +++ os/os-scrollbar.c 2011-10-12 17:16:23 +0000 |
1309 | @@ -34,20 +34,17 @@ |
1310 | #include <X11/Xutil.h> |
1311 | #include <X11/extensions/XInput2.h> |
1312 | |
1313 | -/* Size of the pager in pixels. */ |
1314 | -#define PAGER_SIZE 3 |
1315 | +/* Size of the bar in pixels. */ |
1316 | +#define BAR_SIZE 3 |
1317 | |
1318 | /* Size of the proximity effect in pixels. */ |
1319 | #define PROXIMITY_SIZE 30 |
1320 | |
1321 | -/* Rate of the paging. */ |
1322 | -#define RATE_PAGING 30 |
1323 | - |
1324 | -/* Max duration of the paging. */ |
1325 | -#define MAX_DURATION_PAGING 1000 |
1326 | - |
1327 | -/* Min duration of the paging. */ |
1328 | -#define MIN_DURATION_PAGING 250 |
1329 | +/* Max duration of the scrolling. */ |
1330 | +#define MAX_DURATION_SCROLLING 1000 |
1331 | + |
1332 | +/* Min duration of the scrolling. */ |
1333 | +#define MIN_DURATION_SCROLLING 250 |
1334 | |
1335 | /* Timeout assumed for PropertyNotify _NET_ACTIVE_WINDOW event. */ |
1336 | #define TIMEOUT_PRESENT_WINDOW 400 |
1337 | @@ -58,6 +55,9 @@ |
1338 | /* Timeout before hiding in ms, after leaving the thumb. */ |
1339 | #define TIMEOUT_THUMB_HIDE 200 |
1340 | |
1341 | +/* Timeout before showing in ms, after entering the proximity. */ |
1342 | +#define TIMEOUT_THUMB_SHOW 100 |
1343 | + |
1344 | /* Timeout before hiding in ms, after leaving the toplevel. */ |
1345 | #define TIMEOUT_TOPLEVEL_HIDE 200 |
1346 | |
1347 | @@ -71,48 +71,60 @@ |
1348 | |
1349 | typedef enum |
1350 | { |
1351 | + OS_STATE_NONE = 0, |
1352 | + OS_STATE_CONNECTED = 1, |
1353 | + OS_STATE_DETACHED = 2, |
1354 | + OS_STATE_FULLSIZE = 4, |
1355 | + OS_STATE_INTERNAL = 8, |
1356 | + OS_STATE_LOCKED = 16, |
1357 | + OS_STATE_RECONNECTING = 32 |
1358 | +} OsStateFlags; |
1359 | + |
1360 | +typedef enum |
1361 | +{ |
1362 | OS_STRUT_SIDE_NONE = 0, |
1363 | OS_STRUT_SIDE_TOP = 1, |
1364 | OS_STRUT_SIDE_BOTTOM = 2, |
1365 | OS_STRUT_SIDE_LEFT = 4, |
1366 | OS_STRUT_SIDE_RIGHT = 8 |
1367 | -} OsStrutSide; |
1368 | +} OsStrutSideFlags; |
1369 | + |
1370 | +typedef struct |
1371 | +{ |
1372 | + gboolean proximity; |
1373 | + gboolean running; |
1374 | +} OsWindowFilter; |
1375 | |
1376 | struct _OsScrollbarPrivate |
1377 | { |
1378 | GdkRectangle overlay; |
1379 | GdkRectangle slider; |
1380 | GdkRectangle trough; |
1381 | - GtkAllocation pager_all; |
1382 | + GtkAllocation bar_all; |
1383 | GtkAllocation thumb_all; |
1384 | GtkAdjustment *adjustment; |
1385 | GtkOrientation orientation; |
1386 | GtkWidget *thumb; |
1387 | GtkWindowGroup *window_group; |
1388 | OsAnimation *animation; |
1389 | - OsPager *pager; |
1390 | + OsBar *bar; |
1391 | + OsCoordinate pointer; |
1392 | + OsCoordinate thumb_win; |
1393 | + OsEventFlags event; |
1394 | + OsStateFlags state; |
1395 | OsSide side; |
1396 | - OsEvent event; |
1397 | + OsWindowFilter filter; |
1398 | gboolean active_window; |
1399 | - gboolean can_deactivate_pager; |
1400 | - gboolean can_hide; |
1401 | - gboolean detached_scroll; |
1402 | - gboolean filter; |
1403 | - gboolean fullsize; |
1404 | - gboolean internal; |
1405 | - gboolean lock_position; |
1406 | - gboolean proximity; |
1407 | - gboolean toplevel_button_press; |
1408 | + gboolean deactivable_bar; |
1409 | + gboolean hidable_thumb; |
1410 | + gboolean window_button_press; /* FIXME(Cimi) to replace with X11 input events. */ |
1411 | gdouble value; |
1412 | - gint win_x; |
1413 | - gint win_y; |
1414 | gint slide_initial_slider_position; |
1415 | gint slide_initial_coordinate; |
1416 | - gint pointer_x; |
1417 | - gint pointer_y; |
1418 | gint64 present_time; |
1419 | - guint32 source_deactivate_pager_id; |
1420 | + guint32 source_deactivate_bar_id; |
1421 | guint32 source_hide_thumb_id; |
1422 | + guint32 source_show_thumb_id; |
1423 | guint32 source_unlock_thumb_id; |
1424 | }; |
1425 | |
1426 | @@ -159,10 +171,10 @@ |
1427 | static void os_scrollbar_dispose (GObject *object); |
1428 | static void os_scrollbar_finalize (GObject *object); |
1429 | |
1430 | -/* Calculate pager layout info. */ |
1431 | +/* Calculate bar layout info. */ |
1432 | static void |
1433 | -calc_layout_pager (OsScrollbar *scrollbar, |
1434 | - gdouble adjustment_value) |
1435 | +calc_layout_bar (OsScrollbar *scrollbar, |
1436 | + gdouble adjustment_value) |
1437 | { |
1438 | OsScrollbarPrivate *priv; |
1439 | |
1440 | @@ -279,6 +291,23 @@ |
1441 | } |
1442 | } |
1443 | |
1444 | +/* Calculate the position of the thumb window. */ |
1445 | +static void |
1446 | +calc_thumb_window_position (OsScrollbar *scrollbar) |
1447 | +{ |
1448 | + OsScrollbarPrivate *priv; |
1449 | + gint x_pos, y_pos; |
1450 | + |
1451 | + priv = scrollbar->priv; |
1452 | + |
1453 | + /* In reality, I'm storing widget's window, not the toplevel. |
1454 | + * Is that the same with gdk_window_get_origin? */ |
1455 | + gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
1456 | + |
1457 | + priv->thumb_win.x = x_pos + priv->thumb_all.x; |
1458 | + priv->thumb_win.y = y_pos + priv->thumb_all.y; |
1459 | +} |
1460 | + |
1461 | /* Calculate the workarea using _UNITY_NET_WORKAREA_REGION. */ |
1462 | static void |
1463 | calc_workarea (Display *display, |
1464 | @@ -327,21 +356,114 @@ |
1465 | } |
1466 | } |
1467 | |
1468 | -/* Deactivate the pager if it's the case. */ |
1469 | -static void |
1470 | -deactivate_pager (OsScrollbar *scrollbar) |
1471 | -{ |
1472 | - OsScrollbarPrivate *priv; |
1473 | - |
1474 | - priv = scrollbar->priv; |
1475 | - |
1476 | - if (priv->pager != NULL && priv->can_deactivate_pager) |
1477 | - os_pager_set_active (priv->pager, FALSE, TRUE); |
1478 | -} |
1479 | - |
1480 | -/* Timeout before deactivating the pager. */ |
1481 | +/* Check whether the thumb movement can be considered connected or not. */ |
1482 | +static void |
1483 | +check_connection (OsScrollbar *scrollbar) |
1484 | +{ |
1485 | + OsScrollbarPrivate *priv; |
1486 | + gint x_pos, y_pos; |
1487 | + |
1488 | + priv = scrollbar->priv; |
1489 | + |
1490 | + /* This seems to be required to get proper values. */ |
1491 | + calc_layout_bar (scrollbar, gtk_adjustment_get_value (priv->adjustment)); |
1492 | + calc_layout_slider (scrollbar, gtk_adjustment_get_value (priv->adjustment)); |
1493 | + |
1494 | + gdk_window_get_origin (gtk_widget_get_window (priv->thumb), &x_pos, &y_pos); |
1495 | + |
1496 | + if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
1497 | + { |
1498 | + if (priv->overlay.height > priv->slider.height) |
1499 | + { |
1500 | + if (y_pos >= priv->thumb_win.y + priv->overlay.y && |
1501 | + y_pos + priv->slider.height <= priv->thumb_win.y + priv->overlay.y + priv->overlay.height) |
1502 | + priv->state |= OS_STATE_CONNECTED; |
1503 | + else |
1504 | + priv->state &= ~(OS_STATE_CONNECTED); |
1505 | + } |
1506 | + else |
1507 | + { |
1508 | + if (y_pos == priv->thumb_win.y + priv->slider.y) |
1509 | + priv->state |= OS_STATE_CONNECTED; |
1510 | + else |
1511 | + priv->state &= ~(OS_STATE_CONNECTED); |
1512 | + } |
1513 | + } |
1514 | + else |
1515 | + { |
1516 | + if (priv->overlay.width > priv->slider.width) |
1517 | + { |
1518 | + if (x_pos >= priv->thumb_win.x + priv->overlay.x && |
1519 | + x_pos + priv->slider.width <= priv->thumb_win.x + priv->overlay.x + priv->overlay.width) |
1520 | + priv->state |= OS_STATE_CONNECTED; |
1521 | + else |
1522 | + priv->state &= ~(OS_STATE_CONNECTED); |
1523 | + } |
1524 | + else |
1525 | + { |
1526 | + if (x_pos == priv->thumb_win.x + priv->slider.x) |
1527 | + priv->state |= OS_STATE_CONNECTED; |
1528 | + else |
1529 | + priv->state &= ~(OS_STATE_CONNECTED); |
1530 | + } |
1531 | + } |
1532 | +} |
1533 | + |
1534 | +/* Traduce coordinates into GtkRange values. */ |
1535 | +static gdouble |
1536 | +coord_to_value (OsScrollbar *scrollbar, |
1537 | + gint coord) |
1538 | +{ |
1539 | + OsScrollbarPrivate *priv; |
1540 | + gdouble frac; |
1541 | + gdouble value; |
1542 | + gint trough_length; |
1543 | + gint slider_length; |
1544 | + |
1545 | + priv = scrollbar->priv; |
1546 | + |
1547 | + if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
1548 | + { |
1549 | + trough_length = priv->trough.height; |
1550 | + slider_length = MAX (priv->slider.height, priv->overlay.height); |
1551 | + } |
1552 | + else |
1553 | + { |
1554 | + trough_length = priv->trough.width; |
1555 | + slider_length = MAX (priv->slider.width, priv->overlay.width); |
1556 | + } |
1557 | + |
1558 | + if (trough_length == slider_length) |
1559 | + frac = 1.0; |
1560 | + else |
1561 | + frac = (MAX (0, coord) / (gdouble) (trough_length - slider_length)); |
1562 | + |
1563 | + value = gtk_adjustment_get_lower (priv->adjustment) + frac * (gtk_adjustment_get_upper (priv->adjustment) - |
1564 | + gtk_adjustment_get_lower (priv->adjustment) - |
1565 | + gtk_adjustment_get_page_size (priv->adjustment)); |
1566 | + |
1567 | + value = CLAMP (value, |
1568 | + gtk_adjustment_get_lower (priv->adjustment), |
1569 | + gtk_adjustment_get_upper (priv->adjustment) - gtk_adjustment_get_page_size (priv->adjustment)); |
1570 | + |
1571 | + return value; |
1572 | +} |
1573 | + |
1574 | +/* Deactivate the bar if it's the case. */ |
1575 | +static void |
1576 | +deactivate_bar (OsScrollbar *scrollbar) |
1577 | +{ |
1578 | + OsScrollbarPrivate *priv; |
1579 | + |
1580 | + priv = scrollbar->priv; |
1581 | + |
1582 | + if (priv->bar != NULL && priv->deactivable_bar) |
1583 | + os_bar_set_active (priv->bar, FALSE, TRUE); |
1584 | +} |
1585 | + |
1586 | +/* Timeout before deactivating the bar. */ |
1587 | static gboolean |
1588 | -deactivate_pager_cb (gpointer user_data) |
1589 | +deactivate_bar_cb (gpointer user_data) |
1590 | { |
1591 | OsScrollbar *scrollbar; |
1592 | OsScrollbarPrivate *priv; |
1593 | @@ -351,8 +473,8 @@ |
1594 | |
1595 | OS_DCHECK (!priv->active_window); |
1596 | |
1597 | - deactivate_pager (scrollbar); |
1598 | - priv->source_deactivate_pager_id = 0; |
1599 | + deactivate_bar (scrollbar); |
1600 | + priv->source_deactivate_bar_id = 0; |
1601 | |
1602 | return FALSE; |
1603 | } |
1604 | @@ -365,7 +487,7 @@ |
1605 | |
1606 | priv = scrollbar->priv; |
1607 | |
1608 | - if (priv->can_hide) |
1609 | + if (priv->hidable_thumb) |
1610 | gtk_widget_hide (priv->thumb); |
1611 | } |
1612 | |
1613 | @@ -396,9 +518,9 @@ |
1614 | #endif |
1615 | } |
1616 | |
1617 | -/* Move the pager. */ |
1618 | +/* Move the bar. */ |
1619 | static void |
1620 | -move_pager (OsScrollbar *scrollbar) |
1621 | +move_bar (OsScrollbar *scrollbar) |
1622 | { |
1623 | GdkRectangle mask; |
1624 | OsScrollbarPrivate *priv; |
1625 | @@ -409,7 +531,7 @@ |
1626 | { |
1627 | mask.x = 0; |
1628 | mask.y = priv->overlay.y; |
1629 | - mask.width = priv->pager_all.width; |
1630 | + mask.width = priv->bar_all.width; |
1631 | mask.height = priv->overlay.height; |
1632 | } |
1633 | else |
1634 | @@ -417,10 +539,10 @@ |
1635 | mask.x = priv->overlay.x; |
1636 | mask.y = 0; |
1637 | mask.width = priv->overlay.width; |
1638 | - mask.height = priv->pager_all.height; |
1639 | + mask.height = priv->bar_all.height; |
1640 | } |
1641 | |
1642 | - os_pager_move_resize (priv->pager, mask); |
1643 | + os_bar_move_resize (priv->bar, mask); |
1644 | } |
1645 | |
1646 | /* Sanitize x coordinate of thumb window. */ |
1647 | @@ -481,7 +603,7 @@ |
1648 | |
1649 | for (i = 0; i < cairo_region_num_rectangles (struts_region); i++) |
1650 | { |
1651 | - OsStrutSide strut_side; |
1652 | + OsStrutSideFlags strut_side; |
1653 | gint count; |
1654 | |
1655 | cairo_region_get_rectangle (struts_region, i, &tmp_rect); |
1656 | @@ -548,7 +670,7 @@ |
1657 | (n_monitor != gdk_screen_get_monitor_at_point (screen, monitor_x + priv->thumb_all.width, y) || |
1658 | monitor_x + priv->thumb_all.width >= screen_width)) |
1659 | { |
1660 | - priv->internal = TRUE; |
1661 | + priv->state |= OS_STATE_INTERNAL; |
1662 | return MAX (x - priv->thumb_all.width, screen_width - priv->thumb_all.width); |
1663 | } |
1664 | |
1665 | @@ -556,12 +678,12 @@ |
1666 | (n_monitor != gdk_screen_get_monitor_at_point (screen, monitor_x - priv->thumb_all.width, y) || |
1667 | monitor_x - priv->thumb_all.width <= screen_x)) |
1668 | { |
1669 | - priv->internal = TRUE; |
1670 | + priv->state |= OS_STATE_INTERNAL; |
1671 | return MAX (x, screen_x); |
1672 | } |
1673 | |
1674 | if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
1675 | - priv->internal = FALSE; |
1676 | + priv->state &= ~(OS_STATE_INTERNAL); |
1677 | |
1678 | return x; |
1679 | } |
1680 | @@ -624,7 +746,7 @@ |
1681 | |
1682 | for (i = 0; i < cairo_region_num_rectangles (struts_region); i++) |
1683 | { |
1684 | - OsStrutSide strut_side; |
1685 | + OsStrutSideFlags strut_side; |
1686 | gint count; |
1687 | |
1688 | cairo_region_get_rectangle (struts_region, i, &tmp_rect); |
1689 | @@ -691,7 +813,7 @@ |
1690 | (n_monitor != gdk_screen_get_monitor_at_point (screen, x, monitor_y + priv->thumb_all.height) || |
1691 | monitor_y + priv->thumb_all.height >= screen_height)) |
1692 | { |
1693 | - priv->internal = TRUE; |
1694 | + priv->state |= OS_STATE_INTERNAL; |
1695 | return MAX (y - priv->thumb_all.height, screen_height - priv->thumb_all.height); |
1696 | } |
1697 | |
1698 | @@ -699,12 +821,12 @@ |
1699 | (n_monitor != gdk_screen_get_monitor_at_point (screen, x, monitor_y - priv->thumb_all.height) || |
1700 | monitor_y - priv->thumb_all.height <= screen_y)) |
1701 | { |
1702 | - priv->internal = TRUE; |
1703 | + priv->state |= OS_STATE_INTERNAL; |
1704 | return MAX (y, screen_y); |
1705 | } |
1706 | |
1707 | if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) |
1708 | - priv->internal = FALSE; |
1709 | + priv->state &= ~(OS_STATE_INTERNAL); |
1710 | |
1711 | return y; |
1712 | } |
1713 | @@ -752,10 +874,10 @@ |
1714 | swap_thumb (scrollbar, os_thumb_new (priv->orientation)); |
1715 | } |
1716 | |
1717 | -/* Callback called by the paging animation. */ |
1718 | +/* Callback called by the scrolling animation. */ |
1719 | static void |
1720 | -paging_cb (gfloat weight, |
1721 | - gpointer user_data) |
1722 | +scrolling_cb (gfloat weight, |
1723 | + gpointer user_data) |
1724 | { |
1725 | gdouble new_value; |
1726 | OsScrollbar *scrollbar; |
1727 | @@ -779,6 +901,22 @@ |
1728 | gtk_adjustment_set_value (priv->adjustment, new_value); |
1729 | } |
1730 | |
1731 | +/* End function called by the scrolling animation. */ |
1732 | +static void |
1733 | +scrolling_end_cb (gpointer user_data) |
1734 | +{ |
1735 | + OsScrollbar *scrollbar; |
1736 | + OsScrollbarPrivate *priv; |
1737 | + |
1738 | + scrollbar = OS_SCROLLBAR (user_data); |
1739 | + |
1740 | + priv = scrollbar->priv; |
1741 | + |
1742 | + priv->state &= ~(OS_STATE_RECONNECTING); |
1743 | + |
1744 | + check_connection (scrollbar); |
1745 | +} |
1746 | + |
1747 | /* Swap adjustment pointer. */ |
1748 | static void |
1749 | swap_adjustment (OsScrollbar *scrollbar, |
1750 | @@ -879,8 +1017,8 @@ |
1751 | scrollbar = OS_SCROLLBAR (user_data); |
1752 | priv = scrollbar->priv; |
1753 | |
1754 | - if (priv->can_hide) |
1755 | - priv->lock_position = FALSE; |
1756 | + if (priv->hidable_thumb) |
1757 | + priv->state &= ~(OS_STATE_LOCKED); |
1758 | |
1759 | priv->source_unlock_thumb_id = 0; |
1760 | |
1761 | @@ -899,43 +1037,43 @@ |
1762 | scrollbar = OS_SCROLLBAR (user_data); |
1763 | priv = scrollbar->priv; |
1764 | |
1765 | - /* FIXME(Cimi) we should control each time os_pager_show()/hide() |
1766 | - * is called here and in map()/unmap(). |
1767 | + /* FIXME(Cimi) we should control each time os_bar_show ()/hide () |
1768 | + * is called here and in map ()/unmap (). |
1769 | * We are arbitrary calling that and I'm frightened we should show or keep |
1770 | - * hidden a pager that is meant to be hidden/shown. |
1771 | - * I don't want to see pagers reappearing because |
1772 | - * of a change in the adjustment of an invisible pager or viceversa. */ |
1773 | + * hidden a bar that is meant to be hidden/shown. |
1774 | + * I don't want to see bars reappearing because |
1775 | + * of a change in the adjustment of an invisible bar or viceversa. */ |
1776 | if (gtk_adjustment_get_upper (adjustment) - gtk_adjustment_get_lower (adjustment) > |
1777 | gtk_adjustment_get_page_size (adjustment)) |
1778 | { |
1779 | - priv->fullsize = FALSE; |
1780 | - if (priv->proximity != FALSE) |
1781 | - os_pager_show (priv->pager); |
1782 | + priv->state &= ~(OS_STATE_FULLSIZE); |
1783 | + if (priv->filter.proximity) |
1784 | + os_bar_show (priv->bar); |
1785 | } |
1786 | else |
1787 | { |
1788 | - priv->fullsize = TRUE; |
1789 | - if (priv->proximity != FALSE) |
1790 | + priv->state |= OS_STATE_FULLSIZE; |
1791 | + if (priv->filter.proximity) |
1792 | { |
1793 | - os_pager_hide (priv->pager); |
1794 | + os_bar_hide (priv->bar); |
1795 | |
1796 | gtk_widget_hide (priv->thumb); |
1797 | } |
1798 | } |
1799 | |
1800 | - calc_layout_pager (scrollbar, gtk_adjustment_get_value (adjustment)); |
1801 | + calc_layout_bar (scrollbar, gtk_adjustment_get_value (adjustment)); |
1802 | calc_layout_slider (scrollbar, gtk_adjustment_get_value (adjustment)); |
1803 | |
1804 | if (!(priv->event & OS_EVENT_ENTER_NOTIFY) && |
1805 | !(priv->event & OS_EVENT_MOTION_NOTIFY)) |
1806 | gtk_widget_hide (priv->thumb); |
1807 | |
1808 | - move_pager (scrollbar); |
1809 | + move_bar (scrollbar); |
1810 | } |
1811 | |
1812 | -/* Update the visual connection between pager and thumb. */ |
1813 | +/* Update the tail (visual connection) between bar and thumb. */ |
1814 | static void |
1815 | -update_visual_connection (OsScrollbar *scrollbar) |
1816 | +update_tail (OsScrollbar *scrollbar) |
1817 | { |
1818 | OsScrollbarPrivate *priv; |
1819 | gint x_pos, y_pos; |
1820 | @@ -946,73 +1084,85 @@ |
1821 | |
1822 | if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
1823 | { |
1824 | - if (priv->win_y + priv->overlay.y >= y_pos + priv->slider.height) |
1825 | + if (priv->thumb_win.y + priv->overlay.y >= y_pos + priv->slider.height) |
1826 | { |
1827 | GdkRectangle mask; |
1828 | |
1829 | mask.x = 0; |
1830 | - mask.y = y_pos + priv->slider.height / 2 - priv->win_y; |
1831 | - mask.width = priv->pager_all.width; |
1832 | + mask.y = y_pos + priv->slider.height / 2 - priv->thumb_win.y; |
1833 | + mask.width = priv->bar_all.width; |
1834 | mask.height = priv->overlay.y - mask.y; |
1835 | |
1836 | - os_pager_connect (priv->pager, mask); |
1837 | - os_pager_set_detached (priv->pager, TRUE); |
1838 | - |
1839 | + os_bar_connect (priv->bar, mask); |
1840 | + |
1841 | + priv->state |= OS_STATE_DETACHED; |
1842 | + |
1843 | + os_bar_set_detached (priv->bar, TRUE, FALSE); |
1844 | os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE); |
1845 | } |
1846 | - else if (priv->win_y + priv->overlay.y + priv->overlay.height <= y_pos) |
1847 | + else if (priv->thumb_win.y + priv->overlay.y + priv->overlay.height <= y_pos) |
1848 | { |
1849 | GdkRectangle mask; |
1850 | |
1851 | mask.x = 0; |
1852 | mask.y = priv->overlay.y + priv->overlay.height; |
1853 | - mask.width = priv->pager_all.width; |
1854 | - mask.height = y_pos + priv->slider.height / 2 - priv->win_y - mask.y; |
1855 | - |
1856 | - os_pager_connect (priv->pager, mask); |
1857 | - os_pager_set_detached (priv->pager, TRUE); |
1858 | - |
1859 | + mask.width = priv->bar_all.width; |
1860 | + mask.height = y_pos + priv->slider.height / 2 - priv->thumb_win.y - mask.y; |
1861 | + |
1862 | + os_bar_connect (priv->bar, mask); |
1863 | + |
1864 | + priv->state |= OS_STATE_DETACHED; |
1865 | + |
1866 | + os_bar_set_detached (priv->bar, TRUE, FALSE); |
1867 | os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE); |
1868 | } |
1869 | - else |
1870 | + else |
1871 | { |
1872 | - os_pager_set_detached (priv->pager, FALSE); |
1873 | + priv->state &= ~(OS_STATE_DETACHED); |
1874 | + |
1875 | + os_bar_set_detached (priv->bar, FALSE, FALSE); |
1876 | os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
1877 | } |
1878 | } |
1879 | else |
1880 | { |
1881 | - if (priv->win_x + priv->overlay.x >= x_pos + priv->slider.width) |
1882 | + if (priv->thumb_win.x + priv->overlay.x >= x_pos + priv->slider.width) |
1883 | { |
1884 | GdkRectangle mask; |
1885 | |
1886 | - mask.x = x_pos + priv->slider.width / 2 - priv->win_x; |
1887 | + mask.x = x_pos + priv->slider.width / 2 - priv->thumb_win.x; |
1888 | mask.y = 0; |
1889 | mask.width = priv->overlay.x - mask.x; |
1890 | - mask.height = priv->pager_all.height; |
1891 | - |
1892 | - os_pager_connect (priv->pager, mask); |
1893 | - os_pager_set_detached (priv->pager, TRUE); |
1894 | - |
1895 | + mask.height = priv->bar_all.height; |
1896 | + |
1897 | + os_bar_connect (priv->bar, mask); |
1898 | + |
1899 | + priv->state |= OS_STATE_DETACHED; |
1900 | + |
1901 | + os_bar_set_detached (priv->bar, TRUE, FALSE); |
1902 | os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE); |
1903 | } |
1904 | - else if (priv->win_x + priv->overlay.x + priv->overlay.width <= x_pos) |
1905 | + else if (priv->thumb_win.x + priv->overlay.x + priv->overlay.width <= x_pos) |
1906 | { |
1907 | GdkRectangle mask; |
1908 | |
1909 | mask.x = priv->overlay.x + priv->overlay.width; |
1910 | mask.y = 0; |
1911 | - mask.width = x_pos + priv->slider.width / 2 - priv->win_x - mask.x; |
1912 | - mask.height = priv->pager_all.height; |
1913 | - |
1914 | - os_pager_connect (priv->pager, mask); |
1915 | - os_pager_set_detached (priv->pager, TRUE); |
1916 | - |
1917 | + mask.width = x_pos + priv->slider.width / 2 - priv->thumb_win.x - mask.x; |
1918 | + mask.height = priv->bar_all.height; |
1919 | + |
1920 | + os_bar_connect (priv->bar, mask); |
1921 | + |
1922 | + priv->state |= OS_STATE_DETACHED; |
1923 | + |
1924 | + os_bar_set_detached (priv->bar, TRUE, FALSE); |
1925 | os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE); |
1926 | } |
1927 | else |
1928 | { |
1929 | - os_pager_set_detached (priv->pager, FALSE); |
1930 | + priv->state &= ~(OS_STATE_DETACHED); |
1931 | + |
1932 | + os_bar_set_detached (priv->bar, FALSE, FALSE); |
1933 | os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
1934 | } |
1935 | } |
1936 | @@ -1028,35 +1178,28 @@ |
1937 | scrollbar = OS_SCROLLBAR (user_data); |
1938 | priv = scrollbar->priv; |
1939 | |
1940 | - calc_layout_pager (scrollbar, gtk_adjustment_get_value (adjustment)); |
1941 | + calc_layout_bar (scrollbar, gtk_adjustment_get_value (adjustment)); |
1942 | calc_layout_slider (scrollbar, gtk_adjustment_get_value (adjustment)); |
1943 | |
1944 | if (!(priv->event & OS_EVENT_ENTER_NOTIFY) && |
1945 | !(priv->event & OS_EVENT_MOTION_NOTIFY)) |
1946 | gtk_widget_hide (priv->thumb); |
1947 | |
1948 | - if (gtk_widget_get_mapped (priv->thumb)) |
1949 | - { |
1950 | - /* If we're dragging the thumb, it can't be detached. */ |
1951 | - if (priv->event & OS_EVENT_MOTION_NOTIFY) |
1952 | - { |
1953 | - os_pager_set_detached (priv->pager, FALSE); |
1954 | - os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
1955 | - } |
1956 | - else |
1957 | - update_visual_connection (scrollbar); |
1958 | - } |
1959 | + if (gtk_widget_get_mapped (priv->thumb) && |
1960 | + !((priv->event & OS_EVENT_MOTION_NOTIFY) && |
1961 | + (priv->state & OS_STATE_CONNECTED))) |
1962 | + update_tail (scrollbar); |
1963 | |
1964 | - move_pager (scrollbar); |
1965 | + move_bar (scrollbar); |
1966 | } |
1967 | |
1968 | -/* Pager functions. */ |
1969 | +/* Bar functions. */ |
1970 | |
1971 | -/* Set the state of the pager checking mouse position. */ |
1972 | +/* Set the state of the bar checking mouse position. */ |
1973 | static void |
1974 | -pager_set_state_from_pointer (OsScrollbar *scrollbar, |
1975 | - gint x, |
1976 | - gint y) |
1977 | +bar_set_state_from_pointer (OsScrollbar *scrollbar, |
1978 | + gint x, |
1979 | + gint y) |
1980 | { |
1981 | GtkAllocation allocation; |
1982 | OsScrollbarPrivate *priv; |
1983 | @@ -1070,13 +1213,13 @@ |
1984 | if ((x > allocation.x && x < allocation.x + allocation.width) && |
1985 | (y > allocation.y && y < allocation.y + allocation.height)) |
1986 | { |
1987 | - priv->can_deactivate_pager = FALSE; |
1988 | - os_pager_set_active (priv->pager, TRUE, TRUE); |
1989 | + priv->deactivable_bar = FALSE; |
1990 | + os_bar_set_active (priv->bar, TRUE, TRUE); |
1991 | } |
1992 | else |
1993 | { |
1994 | - priv->can_deactivate_pager = TRUE; |
1995 | - os_pager_set_active (priv->pager, FALSE, TRUE); |
1996 | + priv->deactivable_bar = TRUE; |
1997 | + os_bar_set_active (priv->bar, FALSE, TRUE); |
1998 | } |
1999 | } |
2000 | |
2001 | @@ -1105,16 +1248,16 @@ |
2002 | gdk_screen_get_active_window (gtk_widget_get_screen (GTK_WIDGET (scrollbar)))) |
2003 | { |
2004 | /* Stops potential running timeout. */ |
2005 | - if (priv->source_deactivate_pager_id != 0) |
2006 | + if (priv->source_deactivate_bar_id != 0) |
2007 | { |
2008 | - g_source_remove (priv->source_deactivate_pager_id); |
2009 | - priv->source_deactivate_pager_id = 0; |
2010 | + g_source_remove (priv->source_deactivate_bar_id); |
2011 | + priv->source_deactivate_bar_id = 0; |
2012 | } |
2013 | |
2014 | priv->active_window = TRUE; |
2015 | |
2016 | - priv->can_deactivate_pager = FALSE; |
2017 | - os_pager_set_active (priv->pager, TRUE, TRUE); |
2018 | + priv->deactivable_bar = FALSE; |
2019 | + os_bar_set_active (priv->bar, TRUE, TRUE); |
2020 | } |
2021 | else if (priv->active_window) |
2022 | { |
2023 | @@ -1147,13 +1290,13 @@ |
2024 | /* When the window is unfocused, |
2025 | * check the position of the pointer |
2026 | * and set the state accordingly. */ |
2027 | - pager_set_state_from_pointer (scrollbar, x, y); |
2028 | + bar_set_state_from_pointer (scrollbar, x, y); |
2029 | } |
2030 | else |
2031 | { |
2032 | /* If the pointer is outside of the window, set it inactive. */ |
2033 | - priv->can_deactivate_pager = TRUE; |
2034 | - os_pager_set_active (priv->pager, FALSE, TRUE); |
2035 | + priv->deactivable_bar = TRUE; |
2036 | + os_bar_set_active (priv->bar, FALSE, TRUE); |
2037 | } |
2038 | |
2039 | if ((current_time > end_time) && priv->thumb != NULL) |
2040 | @@ -1251,7 +1394,8 @@ |
2041 | { |
2042 | if (event->type == GDK_BUTTON_PRESS) |
2043 | { |
2044 | - if (event->button == 1) |
2045 | + if (event->button == 1 || |
2046 | + event->button == 2) |
2047 | { |
2048 | OsScrollbar *scrollbar; |
2049 | OsScrollbarPrivate *priv; |
2050 | @@ -1268,7 +1412,60 @@ |
2051 | priv->event |= OS_EVENT_BUTTON_PRESS; |
2052 | priv->event &= ~(OS_EVENT_MOTION_NOTIFY); |
2053 | |
2054 | - priv->detached_scroll = FALSE; |
2055 | + if (event->button == 2) |
2056 | + { |
2057 | + /* Reconnect the thumb with the bar. */ |
2058 | + gdouble new_value; |
2059 | + gint c, delta; |
2060 | + gint32 duration; |
2061 | + |
2062 | + if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2063 | + { |
2064 | + priv->slide_initial_slider_position = event->y_root - priv->thumb_win.y - event->y; |
2065 | + priv->slide_initial_coordinate = event->y_root; |
2066 | + |
2067 | + delta = event->y_root - priv->slide_initial_coordinate; |
2068 | + } |
2069 | + else |
2070 | + { |
2071 | + priv->slide_initial_slider_position = event->x_root - priv->thumb_win.x - event->x; |
2072 | + priv->slide_initial_coordinate = event->x_root; |
2073 | + |
2074 | + delta = event->x_root - priv->slide_initial_coordinate; |
2075 | + } |
2076 | + |
2077 | + c = priv->slide_initial_slider_position + delta; |
2078 | + |
2079 | + /* If a scrolling animation is running, |
2080 | + * stop it and add the new value. */ |
2081 | + os_animation_stop (priv->animation, NULL); |
2082 | + |
2083 | + new_value = coord_to_value (scrollbar, c); |
2084 | + |
2085 | + /* Only start the animation if needed. */ |
2086 | + if (new_value != gtk_adjustment_get_value (priv->adjustment)) |
2087 | + { |
2088 | + priv->state |= OS_STATE_RECONNECTING; |
2089 | + |
2090 | + priv->value = new_value; |
2091 | + |
2092 | + /* Calculate and set the duration. */ |
2093 | + if (priv->value > gtk_adjustment_get_value (priv->adjustment)) |
2094 | + duration = MIN_DURATION_SCROLLING + ((priv->value - gtk_adjustment_get_value (priv->adjustment)) / |
2095 | + (gtk_adjustment_get_upper (priv->adjustment) - |
2096 | + gtk_adjustment_get_lower (priv->adjustment))) * |
2097 | + (MAX_DURATION_SCROLLING - MIN_DURATION_SCROLLING); |
2098 | + else |
2099 | + duration = MIN_DURATION_SCROLLING + ((gtk_adjustment_get_value (priv->adjustment) - priv->value) / |
2100 | + (gtk_adjustment_get_upper (priv->adjustment) - |
2101 | + gtk_adjustment_get_lower (priv->adjustment))) * |
2102 | + (MAX_DURATION_SCROLLING - MIN_DURATION_SCROLLING); |
2103 | + os_animation_set_duration (priv->animation, duration); |
2104 | + |
2105 | + /* Start the scrolling animation. */ |
2106 | + os_animation_start (priv->animation); |
2107 | + } |
2108 | + } |
2109 | |
2110 | if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2111 | { |
2112 | @@ -1281,8 +1478,8 @@ |
2113 | priv->slide_initial_coordinate = event->x_root; |
2114 | } |
2115 | |
2116 | - priv->pointer_x = event->x; |
2117 | - priv->pointer_y = event->y; |
2118 | + priv->pointer.x = event->x; |
2119 | + priv->pointer.y = event->y; |
2120 | } |
2121 | } |
2122 | |
2123 | @@ -1299,7 +1496,7 @@ |
2124 | |
2125 | priv = scrollbar->priv; |
2126 | |
2127 | - /* If a paging animation is running, |
2128 | + /* If a scrolling animation is running, |
2129 | * stop it and add the new value. */ |
2130 | if (os_animation_is_running (priv->animation)) |
2131 | { |
2132 | @@ -1314,13 +1511,17 @@ |
2133 | gtk_adjustment_get_lower (priv->adjustment), |
2134 | gtk_adjustment_get_upper (priv->adjustment) - gtk_adjustment_get_page_size (priv->adjustment)); |
2135 | |
2136 | + /* There's no need to do start a new animation. */ |
2137 | + if (priv->value == gtk_adjustment_get_value (priv->adjustment)) |
2138 | + return; |
2139 | + |
2140 | /* Calculate and set the duration. */ |
2141 | - duration = MIN_DURATION_PAGING + ((priv->value - gtk_adjustment_get_value (priv->adjustment)) / |
2142 | - gtk_adjustment_get_page_increment (priv->adjustment)) * |
2143 | - (MAX_DURATION_PAGING - MIN_DURATION_PAGING); |
2144 | + duration = MIN_DURATION_SCROLLING + ((priv->value - gtk_adjustment_get_value (priv->adjustment)) / |
2145 | + gtk_adjustment_get_page_increment (priv->adjustment)) * |
2146 | + (MAX_DURATION_SCROLLING - MIN_DURATION_SCROLLING); |
2147 | os_animation_set_duration (priv->animation, duration); |
2148 | |
2149 | - /* Start the paging animation. */ |
2150 | + /* Start the scrolling animation. */ |
2151 | os_animation_start (priv->animation); |
2152 | } |
2153 | |
2154 | @@ -1334,7 +1535,7 @@ |
2155 | |
2156 | priv = scrollbar->priv; |
2157 | |
2158 | - /* If a paging animation is running, |
2159 | + /* If a scrolling animation is running, |
2160 | * stop it and subtract the new value. */ |
2161 | if (os_animation_is_running (priv->animation)) |
2162 | { |
2163 | @@ -1349,13 +1550,17 @@ |
2164 | gtk_adjustment_get_lower (priv->adjustment), |
2165 | gtk_adjustment_get_upper (priv->adjustment) - gtk_adjustment_get_page_size (priv->adjustment)); |
2166 | |
2167 | + /* There's no need to do start a new animation. */ |
2168 | + if (priv->value == gtk_adjustment_get_value (priv->adjustment)) |
2169 | + return; |
2170 | + |
2171 | /* Calculate and set the duration. */ |
2172 | - duration = MIN_DURATION_PAGING + ((gtk_adjustment_get_value (priv->adjustment) - priv->value) / |
2173 | - gtk_adjustment_get_page_increment (priv->adjustment)) * |
2174 | - (MAX_DURATION_PAGING - MIN_DURATION_PAGING); |
2175 | + duration = MIN_DURATION_SCROLLING + ((gtk_adjustment_get_value (priv->adjustment) - priv->value) / |
2176 | + gtk_adjustment_get_page_increment (priv->adjustment)) * |
2177 | + (MAX_DURATION_SCROLLING - MIN_DURATION_SCROLLING); |
2178 | os_animation_set_duration (priv->animation, duration); |
2179 | |
2180 | - /* Start the paging animation. */ |
2181 | + /* Start the scrolling animation. */ |
2182 | os_animation_start (priv->animation); |
2183 | } |
2184 | |
2185 | @@ -1366,7 +1571,8 @@ |
2186 | { |
2187 | if (event->type == GDK_BUTTON_RELEASE) |
2188 | { |
2189 | - if (event->button == 1) |
2190 | + if (event->button == 1 || |
2191 | + event->button == 2) |
2192 | { |
2193 | OsScrollbar *scrollbar; |
2194 | OsScrollbarPrivate *priv; |
2195 | @@ -1376,24 +1582,23 @@ |
2196 | |
2197 | gtk_window_set_transient_for (GTK_WINDOW (widget), NULL); |
2198 | |
2199 | - if (!(priv->event & OS_EVENT_MOTION_NOTIFY) && !priv->detached_scroll) |
2200 | + if (event->button == 1 && |
2201 | + !(priv->event & OS_EVENT_MOTION_NOTIFY)) |
2202 | { |
2203 | if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2204 | { |
2205 | - if (priv->pointer_y < priv->slider.height / 2) |
2206 | + if (priv->pointer.y < priv->slider.height / 2) |
2207 | page_up (scrollbar); |
2208 | else |
2209 | page_down (scrollbar); |
2210 | } |
2211 | else |
2212 | { |
2213 | - if (priv->pointer_x < priv->slider.width / 2) |
2214 | + if (priv->pointer.x < priv->slider.width / 2) |
2215 | page_up (scrollbar); |
2216 | else |
2217 | page_down (scrollbar); |
2218 | } |
2219 | - |
2220 | - priv->event |= OS_EVENT_VALUE_CHANGED; |
2221 | } |
2222 | |
2223 | priv->event &= ~(OS_EVENT_BUTTON_PRESS | OS_EVENT_MOTION_NOTIFY); |
2224 | @@ -1416,11 +1621,11 @@ |
2225 | |
2226 | priv->event |= OS_EVENT_ENTER_NOTIFY; |
2227 | |
2228 | - priv->can_deactivate_pager = FALSE; |
2229 | - priv->can_hide = FALSE; |
2230 | + priv->deactivable_bar = FALSE; |
2231 | + priv->hidable_thumb = FALSE; |
2232 | |
2233 | - if (priv->internal) |
2234 | - priv->lock_position = TRUE; |
2235 | + if (priv->state & OS_STATE_INTERNAL) |
2236 | + priv->state |= OS_STATE_LOCKED; |
2237 | |
2238 | return FALSE; |
2239 | } |
2240 | @@ -1440,20 +1645,20 @@ |
2241 | * not interacting with the thumb. */ |
2242 | if (!(priv->event & OS_EVENT_BUTTON_PRESS)) |
2243 | { |
2244 | - /* Never deactivate the pager in an active window. */ |
2245 | + /* Never deactivate the bar in an active window. */ |
2246 | if (!priv->active_window) |
2247 | { |
2248 | - priv->can_deactivate_pager = TRUE; |
2249 | - |
2250 | - if (priv->source_deactivate_pager_id != 0) |
2251 | - g_source_remove (priv->source_deactivate_pager_id); |
2252 | - |
2253 | - priv->source_deactivate_pager_id = g_timeout_add (TIMEOUT_THUMB_HIDE, |
2254 | - deactivate_pager_cb, |
2255 | - scrollbar); |
2256 | + priv->deactivable_bar = TRUE; |
2257 | + |
2258 | + if (priv->source_deactivate_bar_id != 0) |
2259 | + g_source_remove (priv->source_deactivate_bar_id); |
2260 | + |
2261 | + priv->source_deactivate_bar_id = g_timeout_add (TIMEOUT_THUMB_HIDE, |
2262 | + deactivate_bar_cb, |
2263 | + scrollbar); |
2264 | } |
2265 | |
2266 | - priv->can_hide = TRUE; |
2267 | + priv->hidable_thumb = TRUE; |
2268 | |
2269 | if (priv->source_hide_thumb_id != 0) |
2270 | g_source_remove (priv->source_hide_thumb_id); |
2271 | @@ -1481,9 +1686,9 @@ |
2272 | scrollbar = OS_SCROLLBAR (user_data); |
2273 | priv = scrollbar->priv; |
2274 | |
2275 | - /* Immediately set the pager to be active. */ |
2276 | - priv->can_deactivate_pager = FALSE; |
2277 | - os_pager_set_active (priv->pager, TRUE, FALSE); |
2278 | + /* Immediately set the bar to be active. */ |
2279 | + priv->deactivable_bar = FALSE; |
2280 | + os_bar_set_active (priv->bar, TRUE, FALSE); |
2281 | |
2282 | xid = GDK_WINDOW_XID (gtk_widget_get_window (widget)); |
2283 | xid_parent = GDK_WINDOW_XID (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (scrollbar)))); |
2284 | @@ -1542,46 +1747,6 @@ |
2285 | } |
2286 | } |
2287 | |
2288 | -/* Traduce coordinates into GtkRange values. */ |
2289 | -static gdouble |
2290 | -coord_to_value (OsScrollbar *scrollbar, |
2291 | - gint coord) |
2292 | -{ |
2293 | - OsScrollbarPrivate *priv; |
2294 | - gdouble frac; |
2295 | - gdouble value; |
2296 | - gint trough_length; |
2297 | - gint slider_length; |
2298 | - |
2299 | - priv = scrollbar->priv; |
2300 | - |
2301 | - if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2302 | - { |
2303 | - trough_length = priv->trough.height; |
2304 | - slider_length = MAX (priv->slider.height, priv->overlay.height); |
2305 | - } |
2306 | - else |
2307 | - { |
2308 | - trough_length = priv->trough.width; |
2309 | - slider_length = MAX (priv->slider.width, priv->overlay.width); |
2310 | - } |
2311 | - |
2312 | - if (trough_length == slider_length) |
2313 | - frac = 1.0; |
2314 | - else |
2315 | - frac = (MAX (0, coord) / (gdouble) (trough_length - slider_length)); |
2316 | - |
2317 | - value = gtk_adjustment_get_lower (priv->adjustment) + frac * (gtk_adjustment_get_upper (priv->adjustment) - |
2318 | - gtk_adjustment_get_lower (priv->adjustment) - |
2319 | - gtk_adjustment_get_page_size (priv->adjustment)); |
2320 | - |
2321 | - value = CLAMP (value, |
2322 | - gtk_adjustment_get_lower (priv->adjustment), |
2323 | - gtk_adjustment_get_upper (priv->adjustment) - gtk_adjustment_get_page_size (priv->adjustment)); |
2324 | - |
2325 | - return value; |
2326 | -} |
2327 | - |
2328 | /* From pointer movement, set adjustment value. */ |
2329 | static void |
2330 | capture_movement (OsScrollbar *scrollbar, |
2331 | @@ -1622,184 +1787,214 @@ |
2332 | { |
2333 | gint x, y; |
2334 | |
2335 | - /* Thumb and pager are detached. |
2336 | - * Detached scroll: keep the thumb detached during the scroll, |
2337 | - * update the visual connection when reaching an edge. */ |
2338 | - if (priv->event & OS_EVENT_VALUE_CHANGED) |
2339 | - { |
2340 | - /* Return if the mouse movement is small. */ |
2341 | - if (abs (priv->pointer_x - event->x) <= TOLERANCE_MOTION && |
2342 | - abs (priv->pointer_y - event->y) <= TOLERANCE_MOTION) |
2343 | - return FALSE; |
2344 | - |
2345 | - priv->detached_scroll = TRUE; |
2346 | - |
2347 | - /* Stop the paging animation if it's running. */ |
2348 | - os_animation_stop (priv->animation, NULL); |
2349 | + /* Use tolerance at the first calls to this motion notify event. */ |
2350 | + if (!(priv->event & OS_EVENT_MOTION_NOTIFY) && |
2351 | + abs (priv->pointer.x - event->x) <= TOLERANCE_MOTION && |
2352 | + abs (priv->pointer.y - event->y) <= TOLERANCE_MOTION) |
2353 | + return FALSE; |
2354 | + |
2355 | + if (!(priv->event & OS_EVENT_MOTION_NOTIFY)) |
2356 | + { |
2357 | + /* Check if we can consider the thumb movement connected with the overlay. */ |
2358 | + check_connection (scrollbar); |
2359 | + |
2360 | + priv->event |= OS_EVENT_MOTION_NOTIFY; |
2361 | + } |
2362 | + |
2363 | + /* Before stopping the animation, |
2364 | + * check if it's reconnecting. |
2365 | + * In this case we need to update the slide values |
2366 | + * with the current position. */ |
2367 | + if (os_animation_is_running (priv->animation)) |
2368 | + { |
2369 | + if (priv->state & OS_STATE_RECONNECTING) |
2370 | + { |
2371 | + /* It's a reconnecting animation. */ |
2372 | + if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2373 | + { |
2374 | + priv->slide_initial_slider_position = MIN (priv->slider.y, priv->overlay.y); |
2375 | + priv->slide_initial_coordinate = event->y_root; |
2376 | + } |
2377 | + else |
2378 | + { |
2379 | + priv->slide_initial_slider_position = MIN (priv->slider.x, priv->overlay.x); |
2380 | + priv->slide_initial_coordinate = event->x_root; |
2381 | + } |
2382 | + } |
2383 | + else |
2384 | + { |
2385 | + /* Stop the paging animation now. */ |
2386 | + os_animation_stop (priv->animation, NULL); |
2387 | + } |
2388 | + } |
2389 | + |
2390 | + /* Behave differently when the thumb is connected or not. */ |
2391 | + if (priv->state & OS_STATE_CONNECTED) |
2392 | + { |
2393 | + /* This is a connected scroll, |
2394 | + * the thumb movement is kept in sync with the overlay. */ |
2395 | + |
2396 | + if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2397 | + { |
2398 | + if (priv->overlay.height > priv->slider.height) |
2399 | + { |
2400 | + /* Limit x and y within the overlay. */ |
2401 | + x = priv->thumb_win.x; |
2402 | + y = CLAMP (event->y_root - priv->pointer.y, |
2403 | + priv->thumb_win.y + priv->overlay.y, |
2404 | + priv->thumb_win.y + priv->overlay.y + priv->overlay.height - priv->slider.height); |
2405 | + } |
2406 | + else |
2407 | + { |
2408 | + x = priv->thumb_win.x; |
2409 | + y = priv->thumb_win.y + priv->slider.y; |
2410 | + } |
2411 | + } |
2412 | + else |
2413 | + { |
2414 | + if (priv->overlay.width > priv->slider.width) |
2415 | + { |
2416 | + /* Limit x and y within the overlay. */ |
2417 | + x = CLAMP (event->x_root - priv->pointer.x, |
2418 | + priv->thumb_win.x + priv->overlay.x, |
2419 | + priv->thumb_win.x + priv->overlay.x + priv->overlay.width - priv->slider.width); |
2420 | + y = priv->thumb_win.y; |
2421 | + } |
2422 | + else |
2423 | + { |
2424 | + x = priv->thumb_win.x + priv->slider.x; |
2425 | + y = priv->thumb_win.y; |
2426 | + } |
2427 | + } |
2428 | + |
2429 | + /* There's no need to stop animations, |
2430 | + * since the reconnecting animation should not have |
2431 | + * state OS_STATE_CONNECTED, unless it's ended. |
2432 | + * Just capture the movement and change adjustment's value (scroll). */ |
2433 | + capture_movement (scrollbar, event->x_root, event->y_root); |
2434 | + } |
2435 | + else |
2436 | + { |
2437 | + /* This is a fine scroll, works subtly different. |
2438 | + * It has to take care of reconnection, |
2439 | + * and scrolling is not allowed when hitting an edge. */ |
2440 | |
2441 | /* Limit x and y within the allocation. */ |
2442 | if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2443 | { |
2444 | - x = priv->win_x; |
2445 | - y = CLAMP (event->y_root - priv->pointer_y, |
2446 | - priv->win_y, |
2447 | - priv->win_y + priv->thumb_all.height - priv->slider.height); |
2448 | + x = priv->thumb_win.x; |
2449 | + y = CLAMP (event->y_root - priv->pointer.y, |
2450 | + priv->thumb_win.y, |
2451 | + priv->thumb_win.y + priv->thumb_all.height - priv->slider.height); |
2452 | } |
2453 | else |
2454 | { |
2455 | - x = CLAMP (event->x_root - priv->pointer_x, |
2456 | - priv->win_x, |
2457 | - priv->win_x + priv->thumb_all.width - priv->slider.width); |
2458 | - y = priv->win_y; |
2459 | + x = CLAMP (event->x_root - priv->pointer.x, |
2460 | + priv->thumb_win.x, |
2461 | + priv->thumb_win.x + priv->thumb_all.width - priv->slider.width); |
2462 | + y = priv->thumb_win.y; |
2463 | } |
2464 | |
2465 | /* Fine scroll while detached, |
2466 | * do not scroll when hitting an edge. */ |
2467 | if ((priv->orientation == GTK_ORIENTATION_VERTICAL && |
2468 | - y > priv->win_y && |
2469 | - y < priv->win_y + priv->thumb_all.height - priv->slider.height) || |
2470 | + y > priv->thumb_win.y && |
2471 | + y < priv->thumb_win.y + priv->thumb_all.height - priv->slider.height) || |
2472 | (priv->orientation == GTK_ORIENTATION_HORIZONTAL && |
2473 | - x > priv->win_x && |
2474 | - x < priv->win_x + priv->thumb_all.width - priv->slider.width)) |
2475 | - capture_movement (scrollbar, event->x_root, event->y_root); |
2476 | - |
2477 | - move_thumb (scrollbar, x, y); |
2478 | - |
2479 | - if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2480 | - { |
2481 | - if (gtk_adjustment_get_value (priv->adjustment) == 0) |
2482 | - { |
2483 | - update_visual_connection (scrollbar); |
2484 | - |
2485 | - if (priv->overlay.height > priv->slider.height) |
2486 | - { |
2487 | - priv->slide_initial_slider_position = 0; |
2488 | - priv->slide_initial_coordinate = MAX (event->y_root, priv->win_y + priv->pointer_y); |
2489 | - } |
2490 | - else |
2491 | - { |
2492 | - priv->slide_initial_slider_position = 0; |
2493 | - priv->slide_initial_coordinate = event->y_root; |
2494 | - } |
2495 | - } |
2496 | - else if (priv->overlay.y + priv->overlay.height >= priv->trough.height) |
2497 | - { |
2498 | - update_visual_connection (scrollbar); |
2499 | - |
2500 | - if (priv->overlay.height > priv->slider.height) |
2501 | - { |
2502 | - priv->slide_initial_slider_position = priv->trough.height - priv->overlay.height; |
2503 | - priv->slide_initial_coordinate = MAX (event->y_root, priv->win_y + priv->pointer_y); |
2504 | - } |
2505 | - else |
2506 | - { |
2507 | - priv->slide_initial_slider_position = priv->trough.height - priv->slider.height; |
2508 | - priv->slide_initial_coordinate = event->y_root; |
2509 | - } |
2510 | - } |
2511 | - } |
2512 | - else |
2513 | - { |
2514 | - if (gtk_adjustment_get_value (priv->adjustment) == 0) |
2515 | - { |
2516 | - update_visual_connection (scrollbar); |
2517 | - |
2518 | - if (priv->overlay.width > priv->slider.width) |
2519 | - { |
2520 | - priv->slide_initial_slider_position = 0; |
2521 | - priv->slide_initial_coordinate = MAX (event->x_root, priv->win_x + priv->pointer_x); |
2522 | - } |
2523 | - else |
2524 | - { |
2525 | - priv->slide_initial_slider_position = 0; |
2526 | - priv->slide_initial_coordinate = event->x_root; |
2527 | - } |
2528 | - } |
2529 | - else if (priv->overlay.x + priv->overlay.width >= priv->trough.width) |
2530 | - { |
2531 | - update_visual_connection (scrollbar); |
2532 | - |
2533 | - if (priv->overlay.width > priv->slider.width) |
2534 | - { |
2535 | - priv->slide_initial_slider_position = priv->trough.width - priv->overlay.width; |
2536 | - priv->slide_initial_coordinate = MAX (event->x_root, priv->win_x + priv->pointer_x); |
2537 | - } |
2538 | - else |
2539 | - { |
2540 | - priv->slide_initial_slider_position = priv->trough.width - priv->slider.width; |
2541 | - priv->slide_initial_coordinate = event->x_root; |
2542 | - } |
2543 | - } |
2544 | - } |
2545 | - |
2546 | - return FALSE; |
2547 | - } |
2548 | - |
2549 | - OS_DCHECK (!priv->detached_scroll); |
2550 | - |
2551 | - /* Thumb and pager are connected. |
2552 | - * Normal scroll: keep the thumb in sync with the pager, |
2553 | - * do not update the visual connection. */ |
2554 | - priv->event |= OS_EVENT_MOTION_NOTIFY; |
2555 | - |
2556 | - capture_movement (scrollbar, event->x_root, event->y_root); |
2557 | - |
2558 | - if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2559 | - { |
2560 | - if (priv->overlay.height > priv->slider.height) |
2561 | - { |
2562 | - /* Limit x and y within the overlay. */ |
2563 | - x = priv->win_x; |
2564 | - y = CLAMP (event->y_root - priv->pointer_y, |
2565 | - priv->win_y + priv->overlay.y, |
2566 | - priv->win_y + priv->overlay.y + priv->overlay.height - priv->slider.height); |
2567 | - |
2568 | - if (gtk_adjustment_get_value (priv->adjustment) == 0) |
2569 | - { |
2570 | - priv->slide_initial_slider_position = 0; |
2571 | - priv->slide_initial_coordinate = MAX (event->y_root, priv->win_y + priv->pointer_y); |
2572 | - } |
2573 | - else if (priv->overlay.y + priv->overlay.height >= priv->trough.height) |
2574 | - { |
2575 | - priv->slide_initial_slider_position = priv->trough.height - priv->overlay.height; |
2576 | - priv->slide_initial_coordinate = MAX (event->y_root, priv->win_y + priv->pointer_y); |
2577 | - } |
2578 | - } |
2579 | - else |
2580 | - { |
2581 | - x = priv->win_x; |
2582 | - y = priv->win_y + priv->slider.y; |
2583 | - } |
2584 | - } |
2585 | - else |
2586 | - { |
2587 | - if (priv->overlay.width > priv->slider.width) |
2588 | - { |
2589 | - /* Limit x and y within the overlay. */ |
2590 | - x = CLAMP (event->x_root - priv->pointer_x, |
2591 | - priv->win_x + priv->overlay.x, |
2592 | - priv->win_x + priv->overlay.x + priv->overlay.width - priv->slider.width); |
2593 | - y = priv->win_y; |
2594 | - |
2595 | - if (gtk_adjustment_get_value (priv->adjustment) == 0) |
2596 | - { |
2597 | - priv->slide_initial_slider_position = 0; |
2598 | - priv->slide_initial_coordinate = MAX (event->x_root, priv->win_x + priv->pointer_x); |
2599 | - } |
2600 | - else if (priv->overlay.x + priv->overlay.width >= priv->trough.width) |
2601 | - { |
2602 | - priv->slide_initial_slider_position = priv->trough.width - priv->overlay.width; |
2603 | - priv->slide_initial_coordinate = MAX (event->x_root, priv->win_x + priv->pointer_x); |
2604 | - } |
2605 | - } |
2606 | - else |
2607 | - { |
2608 | - x = priv->win_x + priv->slider.x; |
2609 | - y = priv->win_y; |
2610 | - } |
2611 | - } |
2612 | - |
2613 | + x > priv->thumb_win.x && |
2614 | + x < priv->thumb_win.x + priv->thumb_all.width - priv->slider.width)) |
2615 | + { |
2616 | + /* Stop the animation now. |
2617 | + * Only the reconnecting animation can be running now, |
2618 | + * because the paging animations were stop before. */ |
2619 | + os_animation_stop (priv->animation, NULL); |
2620 | + |
2621 | + /* Capture the movement and change adjustment's value (scroll). */ |
2622 | + capture_movement (scrollbar, event->x_root, event->y_root); |
2623 | + } |
2624 | + else if (!os_animation_is_running (priv->animation) && |
2625 | + !(priv->state & OS_STATE_DETACHED)) |
2626 | + { |
2627 | + /* Animate scrolling till reaches the edge. */ |
2628 | + if ((priv->orientation == GTK_ORIENTATION_VERTICAL && y <= priv->thumb_win.y) || |
2629 | + (priv->orientation == GTK_ORIENTATION_HORIZONTAL && x <= priv->thumb_win.x)) |
2630 | + priv->value = gtk_adjustment_get_lower (priv->adjustment); |
2631 | + else |
2632 | + priv->value = gtk_adjustment_get_upper (priv->adjustment) - |
2633 | + gtk_adjustment_get_page_size (priv->adjustment); |
2634 | + |
2635 | + /* Proceed with the reconnection only if needed. */ |
2636 | + if (priv->value != gtk_adjustment_get_value (priv->adjustment)) |
2637 | + { |
2638 | + /* If the thumb is not detached, proceed with reconnection. */ |
2639 | + priv->state |= OS_STATE_RECONNECTING; |
2640 | + |
2641 | + os_animation_set_duration (priv->animation, MIN_DURATION_SCROLLING); |
2642 | + |
2643 | + /* Start the scrolling animation. */ |
2644 | + os_animation_start (priv->animation); |
2645 | + } |
2646 | + } |
2647 | + } |
2648 | + |
2649 | + /* Move the thumb window. */ |
2650 | move_thumb (scrollbar, x, y); |
2651 | + |
2652 | + /* Adjust slide values in some special situations, |
2653 | + * update the tail if the thumb is detached and |
2654 | + * check if the movement changed the thumb state to connected. */ |
2655 | + if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2656 | + { |
2657 | + if (gtk_adjustment_get_value (priv->adjustment) <= gtk_adjustment_get_lower (priv->adjustment)) |
2658 | + { |
2659 | + if (priv->state & OS_STATE_DETACHED) |
2660 | + update_tail (scrollbar); |
2661 | + |
2662 | + if (!(priv->state & OS_STATE_CONNECTED)) |
2663 | + check_connection (scrollbar); |
2664 | + |
2665 | + priv->slide_initial_slider_position = 0; |
2666 | + priv->slide_initial_coordinate = MAX (event->y_root, priv->thumb_win.y + priv->pointer.y); |
2667 | + } |
2668 | + else if (priv->overlay.y + priv->overlay.height >= priv->trough.height) |
2669 | + { |
2670 | + if (priv->state & OS_STATE_DETACHED) |
2671 | + update_tail (scrollbar); |
2672 | + |
2673 | + if (!(priv->state & OS_STATE_CONNECTED)) |
2674 | + check_connection (scrollbar); |
2675 | + |
2676 | + priv->slide_initial_slider_position = priv->trough.height - MAX (priv->overlay.height, priv->slider.height); |
2677 | + priv->slide_initial_coordinate = MIN (event->y_root, (priv->thumb_win.y + priv->trough.height - |
2678 | + priv->slider.height + priv->pointer.y)); |
2679 | + } |
2680 | + } |
2681 | + else |
2682 | + { |
2683 | + if (gtk_adjustment_get_value (priv->adjustment) <= gtk_adjustment_get_lower (priv->adjustment)) |
2684 | + { |
2685 | + if (priv->state & OS_STATE_DETACHED) |
2686 | + update_tail (scrollbar); |
2687 | + |
2688 | + if (!(priv->state & OS_STATE_CONNECTED)) |
2689 | + check_connection (scrollbar); |
2690 | + |
2691 | + priv->slide_initial_slider_position = 0; |
2692 | + priv->slide_initial_coordinate = MAX (event->x_root, priv->thumb_win.x + priv->pointer.x); |
2693 | + } |
2694 | + else if (priv->overlay.x + priv->overlay.width >= priv->trough.width) |
2695 | + { |
2696 | + if (priv->state & OS_STATE_DETACHED) |
2697 | + update_tail (scrollbar); |
2698 | + |
2699 | + if (!(priv->state & OS_STATE_CONNECTED)) |
2700 | + check_connection (scrollbar); |
2701 | + |
2702 | + priv->slide_initial_slider_position = priv->trough.width - MAX (priv->overlay.width, priv->slider.width); |
2703 | + priv->slide_initial_coordinate = MIN (event->x_root, (priv->thumb_win.x + priv->trough.width - |
2704 | + priv->slider.width + priv->pointer.x)); |
2705 | + } |
2706 | + } |
2707 | } |
2708 | |
2709 | return FALSE; |
2710 | @@ -1836,11 +2031,9 @@ |
2711 | scrollbar = OS_SCROLLBAR (user_data); |
2712 | priv = scrollbar->priv; |
2713 | |
2714 | - /* Stop the paging animation if it's running. */ |
2715 | + /* Stop the scrolling animation if it's running. */ |
2716 | os_animation_stop (priv->animation, NULL); |
2717 | |
2718 | - priv->event |= OS_EVENT_VALUE_CHANGED; |
2719 | - |
2720 | delta = get_wheel_delta (scrollbar, event->direction); |
2721 | |
2722 | gtk_adjustment_set_value (priv->adjustment, |
2723 | @@ -1849,6 +2042,25 @@ |
2724 | (gtk_adjustment_get_upper (priv->adjustment) - |
2725 | gtk_adjustment_get_page_size (priv->adjustment)))); |
2726 | |
2727 | + /* Deal with simultaneous events. */ |
2728 | + if (priv->event & OS_EVENT_BUTTON_PRESS) |
2729 | + { |
2730 | + priv->event &= ~(OS_EVENT_MOTION_NOTIFY); |
2731 | + |
2732 | + /* we need to update the slide values |
2733 | + * with the current position. */ |
2734 | + if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2735 | + { |
2736 | + priv->slide_initial_slider_position = MIN (priv->slider.y, priv->overlay.y); |
2737 | + priv->slide_initial_coordinate = event->y_root; |
2738 | + } |
2739 | + else |
2740 | + { |
2741 | + priv->slide_initial_slider_position = MIN (priv->slider.x, priv->overlay.x); |
2742 | + priv->slide_initial_coordinate = event->x_root; |
2743 | + } |
2744 | + } |
2745 | + |
2746 | return FALSE; |
2747 | } |
2748 | |
2749 | @@ -1863,31 +2075,28 @@ |
2750 | priv = scrollbar->priv; |
2751 | |
2752 | priv->event = OS_EVENT_NONE; |
2753 | - |
2754 | - priv->detached_scroll = FALSE; |
2755 | - |
2756 | - os_pager_set_detached (priv->pager, FALSE); |
2757 | + priv->hidable_thumb = TRUE; |
2758 | + |
2759 | + /* Remove running hide timeout, if there is one. */ |
2760 | + if (priv->source_hide_thumb_id != 0) |
2761 | + { |
2762 | + g_source_remove (priv->source_hide_thumb_id); |
2763 | + priv->source_hide_thumb_id = 0; |
2764 | + } |
2765 | + |
2766 | + /* This could hardly still be running, |
2767 | + * but it is not impossible. */ |
2768 | + if (priv->source_show_thumb_id != 0) |
2769 | + { |
2770 | + g_source_remove (priv->source_show_thumb_id); |
2771 | + priv->source_show_thumb_id = 0; |
2772 | + } |
2773 | + |
2774 | + os_bar_set_detached (priv->bar, FALSE, TRUE); |
2775 | } |
2776 | |
2777 | /* Toplevel functions. */ |
2778 | |
2779 | -/* Store the position of the toplevel window. */ |
2780 | -static void |
2781 | -store_toplevel_position (OsScrollbar *scrollbar) |
2782 | -{ |
2783 | - OsScrollbarPrivate *priv; |
2784 | - gint x_pos, y_pos; |
2785 | - |
2786 | - priv = scrollbar->priv; |
2787 | - |
2788 | - /* In reality, I'm storing widget's window, not the toplevel. |
2789 | - * Is that the same with gdk_window_get_origin? */ |
2790 | - gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
2791 | - |
2792 | - priv->win_x = x_pos + priv->thumb_all.x; |
2793 | - priv->win_y = y_pos + priv->thumb_all.y; |
2794 | -} |
2795 | - |
2796 | static gboolean |
2797 | toplevel_configure_event_cb (GtkWidget *widget, |
2798 | GdkEventConfigure *event, |
2799 | @@ -1902,7 +2111,7 @@ |
2800 | * and the configure-event happens after |
2801 | * the PropertyNotify _NET_ACTIVE_WINDOW event, |
2802 | * see if the mouse pointer is over this window, if TRUE, |
2803 | - * proceed with pager_set_state_from_pointer. */ |
2804 | + * proceed with bar_set_state_from_pointer (). */ |
2805 | if (!is_insensitive (scrollbar) && |
2806 | (current_time > end_time) && |
2807 | gtk_widget_get_mapped (GTK_WIDGET (scrollbar))) |
2808 | @@ -1932,34 +2141,67 @@ |
2809 | /* When the window is resized (maximize/restore), |
2810 | * check the position of the pointer |
2811 | * and set the state accordingly. */ |
2812 | - pager_set_state_from_pointer (scrollbar, x, y); |
2813 | + bar_set_state_from_pointer (scrollbar, x, y); |
2814 | } |
2815 | } |
2816 | else |
2817 | { |
2818 | - priv->can_deactivate_pager = FALSE; |
2819 | - os_pager_set_active (priv->pager, TRUE, TRUE); |
2820 | + priv->deactivable_bar = FALSE; |
2821 | + os_bar_set_active (priv->bar, TRUE, TRUE); |
2822 | } |
2823 | } |
2824 | |
2825 | if (current_time > end_time) |
2826 | gtk_widget_hide (priv->thumb); |
2827 | |
2828 | - priv->lock_position = FALSE; |
2829 | + priv->state &= ~(OS_STATE_LOCKED); |
2830 | |
2831 | - calc_layout_pager (scrollbar, gtk_adjustment_get_value (priv->adjustment)); |
2832 | + calc_layout_bar (scrollbar, gtk_adjustment_get_value (priv->adjustment)); |
2833 | calc_layout_slider (scrollbar, gtk_adjustment_get_value (priv->adjustment)); |
2834 | |
2835 | - store_toplevel_position (scrollbar); |
2836 | + calc_thumb_window_position (scrollbar); |
2837 | |
2838 | return FALSE; |
2839 | } |
2840 | |
2841 | +/* widget's window functions. */ |
2842 | + |
2843 | +/* Move the thumb in the proximity area. */ |
2844 | +static void |
2845 | +adjust_thumb_position (OsScrollbar *scrollbar, |
2846 | + gdouble event_x, |
2847 | + gdouble event_y) |
2848 | +{ |
2849 | + OsScrollbarPrivate *priv; |
2850 | + gint x, y, x_pos, y_pos; |
2851 | + |
2852 | + priv = scrollbar->priv; |
2853 | + |
2854 | + gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
2855 | + |
2856 | + if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
2857 | + { |
2858 | + x = priv->thumb_all.x; |
2859 | + y = CLAMP (event_y - priv->slider.height / 2, |
2860 | + priv->thumb_all.y, |
2861 | + priv->thumb_all.y + priv->thumb_all.height - priv->slider.height); |
2862 | + } |
2863 | + else |
2864 | + { |
2865 | + x = CLAMP (event_x - priv->slider.width / 2, |
2866 | + priv->thumb_all.x, |
2867 | + priv->thumb_all.x + priv->thumb_all.width - priv->slider.width); |
2868 | + y = priv->thumb_all.y; |
2869 | + } |
2870 | + |
2871 | + move_thumb (scrollbar, x_pos + x, y_pos + y); |
2872 | +} |
2873 | + |
2874 | /* Checks if the pointer is in the proximity area. */ |
2875 | static gboolean |
2876 | check_proximity (OsScrollbar *scrollbar, |
2877 | - gint x, |
2878 | - gint y) |
2879 | + gint x, |
2880 | + gint y) |
2881 | { |
2882 | OsScrollbarPrivate *priv; |
2883 | |
2884 | @@ -1968,28 +2210,28 @@ |
2885 | switch (priv->side) |
2886 | { |
2887 | case OS_SIDE_RIGHT: |
2888 | - return (x >= priv->pager_all.x + priv->pager_all.width - PROXIMITY_SIZE && |
2889 | - x <= priv->pager_all.x + priv->pager_all.width) && |
2890 | - (y >= priv->pager_all.y + priv->overlay.y && |
2891 | - y <= priv->pager_all.y + priv->overlay.y + priv->overlay.height); |
2892 | + return (x >= priv->bar_all.x + priv->bar_all.width - PROXIMITY_SIZE && |
2893 | + x <= priv->bar_all.x + priv->bar_all.width) && |
2894 | + (y >= priv->bar_all.y && |
2895 | + y <= priv->bar_all.y + priv->bar_all.height); |
2896 | break; |
2897 | case OS_SIDE_BOTTOM: |
2898 | - return (y >= priv->pager_all.y + priv->pager_all.height - PROXIMITY_SIZE && |
2899 | - y <= priv->pager_all.y + priv->pager_all.height) && |
2900 | - (x >= priv->pager_all.x + priv->overlay.x && |
2901 | - x <= priv->pager_all.x + priv->overlay.x + priv->overlay.width); |
2902 | + return (y >= priv->bar_all.y + priv->bar_all.height - PROXIMITY_SIZE && |
2903 | + y <= priv->bar_all.y + priv->bar_all.height) && |
2904 | + (x >= priv->bar_all.x && |
2905 | + x <= priv->bar_all.x + priv->bar_all.width); |
2906 | break; |
2907 | case OS_SIDE_LEFT: |
2908 | - return (x <= priv->pager_all.x + priv->pager_all.width + PROXIMITY_SIZE && |
2909 | - x >= priv->pager_all.x) && |
2910 | - (y >= priv->pager_all.y + priv->overlay.y && |
2911 | - y <= priv->pager_all.y + priv->overlay.y + priv->overlay.height); |
2912 | + return (x <= priv->bar_all.x + priv->bar_all.width + PROXIMITY_SIZE && |
2913 | + x >= priv->bar_all.x) && |
2914 | + (y >= priv->bar_all.y && |
2915 | + y <= priv->bar_all.y + priv->bar_all.height); |
2916 | break; |
2917 | case OS_SIDE_TOP: |
2918 | - return (y <= priv->pager_all.y + priv->pager_all.height + PROXIMITY_SIZE && |
2919 | - y >= priv->pager_all.y) && |
2920 | - (x >= priv->pager_all.x + priv->overlay.x && |
2921 | - x <= priv->pager_all.x + priv->overlay.x + priv->overlay.width); |
2922 | + return (y <= priv->bar_all.y + priv->bar_all.height + PROXIMITY_SIZE && |
2923 | + y >= priv->bar_all.y) && |
2924 | + (x >= priv->bar_all.x && |
2925 | + x <= priv->bar_all.x + priv->bar_all.width); |
2926 | break; |
2927 | default: |
2928 | break; |
2929 | @@ -1998,6 +2240,64 @@ |
2930 | return FALSE; |
2931 | } |
2932 | |
2933 | +/* Callback that shows the thumb if it's the case. */ |
2934 | +static gboolean |
2935 | +show_thumb_cb (gpointer user_data) |
2936 | +{ |
2937 | + OsScrollbar *scrollbar; |
2938 | + OsScrollbarPrivate *priv; |
2939 | + |
2940 | + scrollbar = OS_SCROLLBAR (user_data); |
2941 | + priv = scrollbar->priv; |
2942 | + |
2943 | + if (!priv->hidable_thumb) |
2944 | + { |
2945 | + gtk_widget_show (priv->thumb); |
2946 | + |
2947 | + update_tail (scrollbar); |
2948 | + } |
2949 | + |
2950 | + priv->source_show_thumb_id = 0; |
2951 | + |
2952 | + return FALSE; |
2953 | +} |
2954 | + |
2955 | +/* Adds a timeout to reveal the thumb. */ |
2956 | +static void |
2957 | +show_thumb (OsScrollbar *scrollbar) |
2958 | +{ |
2959 | + OsScrollbarPrivate *priv; |
2960 | + |
2961 | + priv = scrollbar->priv; |
2962 | + |
2963 | + /* Just update the tail if the thumb is already mapped. */ |
2964 | + if (gtk_widget_get_mapped (priv->thumb)) |
2965 | + { |
2966 | + update_tail (scrollbar); |
2967 | + return; |
2968 | + } |
2969 | + |
2970 | + if (priv->state & OS_STATE_INTERNAL) |
2971 | + { |
2972 | + /* If the scrollbar is close to one edge of the screen, |
2973 | + * show it immediately, ignoring the timeout, |
2974 | + * to preserve Fitts' law. */ |
2975 | + if (priv->source_show_thumb_id != 0) |
2976 | + { |
2977 | + g_source_remove (priv->source_show_thumb_id); |
2978 | + priv->source_show_thumb_id = 0; |
2979 | + } |
2980 | + |
2981 | + gtk_widget_show (priv->thumb); |
2982 | + |
2983 | + update_tail (scrollbar); |
2984 | + } |
2985 | + else if (priv->source_show_thumb_id == 0) |
2986 | + priv->source_show_thumb_id = g_timeout_add (TIMEOUT_THUMB_SHOW, |
2987 | + show_thumb_cb, |
2988 | + scrollbar); |
2989 | +} |
2990 | + |
2991 | /* Filter function applied to the toplevel window. */ |
2992 | #ifdef USE_GTK3 |
2993 | typedef enum |
2994 | @@ -2025,10 +2325,10 @@ |
2995 | |
2996 | xev = gdkxevent; |
2997 | |
2998 | - g_return_val_if_fail (OS_IS_PAGER (priv->pager), GDK_FILTER_CONTINUE); |
2999 | + g_return_val_if_fail (OS_IS_BAR (priv->bar), GDK_FILTER_CONTINUE); |
3000 | g_return_val_if_fail (OS_IS_THUMB (priv->thumb), GDK_FILTER_CONTINUE); |
3001 | |
3002 | - if (!priv->fullsize) |
3003 | + if (!(priv->state & OS_STATE_FULLSIZE)) |
3004 | { |
3005 | OsXEvent os_xevent; |
3006 | gdouble event_x, event_y; |
3007 | @@ -2092,101 +2392,72 @@ |
3008 | |
3009 | if (os_xevent == OS_XEVENT_BUTTON_PRESS) |
3010 | { |
3011 | - priv->toplevel_button_press = TRUE; |
3012 | + priv->window_button_press = TRUE; |
3013 | + |
3014 | + if (priv->source_show_thumb_id != 0) |
3015 | + { |
3016 | + g_source_remove (priv->source_show_thumb_id); |
3017 | + priv->source_show_thumb_id = 0; |
3018 | + } |
3019 | + |
3020 | gtk_widget_hide (priv->thumb); |
3021 | } |
3022 | |
3023 | - if (priv->toplevel_button_press && os_xevent == OS_XEVENT_BUTTON_RELEASE) |
3024 | + if (priv->window_button_press && os_xevent == OS_XEVENT_BUTTON_RELEASE) |
3025 | { |
3026 | - priv->toplevel_button_press = FALSE; |
3027 | + priv->window_button_press = FALSE; |
3028 | |
3029 | /* Proximity area. */ |
3030 | - if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
3031 | - { |
3032 | - if (check_proximity (scrollbar, event_x, event_y)) |
3033 | - { |
3034 | - priv->can_hide = FALSE; |
3035 | - |
3036 | - if (priv->lock_position) |
3037 | - return GDK_FILTER_CONTINUE; |
3038 | - |
3039 | - if (priv->overlay.height > priv->slider.height) |
3040 | - { |
3041 | - gint x, y, x_pos, y_pos; |
3042 | - |
3043 | - gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
3044 | - |
3045 | - x = priv->thumb_all.x; |
3046 | - y = CLAMP (event_y - priv->slider.height / 2, |
3047 | - priv->thumb_all.y + priv->overlay.y, |
3048 | - priv->thumb_all.y + priv->overlay.y + priv->overlay.height - priv->slider.height); |
3049 | - |
3050 | - move_thumb (scrollbar, x_pos + x, y_pos + y); |
3051 | - } |
3052 | - else |
3053 | - { |
3054 | - move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y); |
3055 | - } |
3056 | - |
3057 | - gtk_widget_show (priv->thumb); |
3058 | - } |
3059 | - } |
3060 | - else |
3061 | - { |
3062 | - if (check_proximity (scrollbar, event_x, event_y)) |
3063 | - { |
3064 | - priv->can_hide = FALSE; |
3065 | - |
3066 | - if (priv->lock_position) |
3067 | - return GDK_FILTER_CONTINUE; |
3068 | - |
3069 | - if (priv->overlay.width > priv->slider.width) |
3070 | - { |
3071 | - gint x, y, x_pos, y_pos; |
3072 | - |
3073 | - gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
3074 | - |
3075 | - x = CLAMP (event_x - priv->slider.width / 2, |
3076 | - priv->thumb_all.x + priv->overlay.x, |
3077 | - priv->thumb_all.x + priv->overlay.x + priv->overlay.width - priv->slider.width); |
3078 | - y = priv->thumb_all.y; |
3079 | - |
3080 | - move_thumb (scrollbar, x_pos + x, y_pos + y); |
3081 | - } |
3082 | - else |
3083 | - { |
3084 | - move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y); |
3085 | - } |
3086 | - |
3087 | - gtk_widget_show (priv->thumb); |
3088 | - } |
3089 | + if (check_proximity (scrollbar, event_x, event_y)) |
3090 | + { |
3091 | + priv->hidable_thumb = FALSE; |
3092 | + |
3093 | + if (priv->state & OS_STATE_LOCKED) |
3094 | + return GDK_FILTER_CONTINUE; |
3095 | + |
3096 | + adjust_thumb_position (scrollbar, event_x, event_y); |
3097 | + |
3098 | + gtk_widget_show (priv->thumb); |
3099 | + |
3100 | + update_tail (scrollbar); |
3101 | } |
3102 | } |
3103 | |
3104 | if (os_xevent == OS_XEVENT_LEAVE) |
3105 | { |
3106 | - /* Never deactivate the pager in an active window. */ |
3107 | + priv->window_button_press = FALSE; |
3108 | + |
3109 | + /* Never deactivate the bar in an active window. */ |
3110 | if (!priv->active_window) |
3111 | { |
3112 | - priv->can_deactivate_pager = TRUE; |
3113 | - |
3114 | - if (priv->source_deactivate_pager_id != 0) |
3115 | - g_source_remove (priv->source_deactivate_pager_id); |
3116 | - |
3117 | - priv->source_deactivate_pager_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE, |
3118 | - deactivate_pager_cb, |
3119 | - scrollbar); |
3120 | - } |
3121 | - |
3122 | - priv->toplevel_button_press = FALSE; |
3123 | - priv->can_hide = TRUE; |
3124 | - |
3125 | - if (priv->source_hide_thumb_id != 0) |
3126 | - g_source_remove (priv->source_hide_thumb_id); |
3127 | - |
3128 | - priv->source_hide_thumb_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE, |
3129 | - hide_thumb_cb, |
3130 | - scrollbar); |
3131 | + priv->deactivable_bar = TRUE; |
3132 | + |
3133 | + if (priv->source_deactivate_bar_id != 0) |
3134 | + g_source_remove (priv->source_deactivate_bar_id); |
3135 | + |
3136 | + priv->source_deactivate_bar_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE, |
3137 | + deactivate_bar_cb, |
3138 | + scrollbar); |
3139 | + } |
3140 | + |
3141 | + if (gtk_widget_get_mapped (priv->thumb) && |
3142 | + !(priv->event & OS_EVENT_BUTTON_PRESS)) |
3143 | + { |
3144 | + priv->hidable_thumb = TRUE; |
3145 | + |
3146 | + if (priv->source_hide_thumb_id != 0) |
3147 | + g_source_remove (priv->source_hide_thumb_id); |
3148 | + |
3149 | + priv->source_hide_thumb_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE, |
3150 | + hide_thumb_cb, |
3151 | + scrollbar); |
3152 | + } |
3153 | + |
3154 | + if (priv->source_show_thumb_id != 0) |
3155 | + { |
3156 | + g_source_remove (priv->source_show_thumb_id); |
3157 | + priv->source_show_thumb_id = 0; |
3158 | + } |
3159 | |
3160 | if (priv->source_unlock_thumb_id != 0) |
3161 | g_source_remove (priv->source_unlock_thumb_id); |
3162 | @@ -2197,107 +2468,47 @@ |
3163 | } |
3164 | |
3165 | /* Get the motion_notify_event trough XEvent. */ |
3166 | - if (!priv->toplevel_button_press && os_xevent == OS_XEVENT_MOTION) |
3167 | + if (!priv->window_button_press && os_xevent == OS_XEVENT_MOTION) |
3168 | { |
3169 | /* React to motion_notify_event |
3170 | * and set the state accordingly. */ |
3171 | if (!is_insensitive (scrollbar) && !priv->active_window) |
3172 | - pager_set_state_from_pointer (scrollbar, event_x, event_y); |
3173 | + bar_set_state_from_pointer (scrollbar, event_x, event_y); |
3174 | |
3175 | /* Proximity area. */ |
3176 | - if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
3177 | + if (check_proximity (scrollbar, event_x, event_y)) |
3178 | { |
3179 | - if (check_proximity (scrollbar, event_x, event_y)) |
3180 | - { |
3181 | - priv->can_hide = FALSE; |
3182 | - |
3183 | - if (priv->source_hide_thumb_id != 0) |
3184 | - { |
3185 | - g_source_remove (priv->source_hide_thumb_id); |
3186 | - priv->source_hide_thumb_id = 0; |
3187 | - } |
3188 | - |
3189 | - if (priv->lock_position) |
3190 | - return GDK_FILTER_CONTINUE; |
3191 | - |
3192 | - if (priv->overlay.height > priv->slider.height) |
3193 | - { |
3194 | - gint x, y, x_pos, y_pos; |
3195 | - |
3196 | - gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
3197 | - |
3198 | - x = priv->thumb_all.x; |
3199 | - y = CLAMP (event_y - priv->slider.height / 2, |
3200 | - priv->thumb_all.y + priv->overlay.y, |
3201 | - priv->thumb_all.y + priv->overlay.y + priv->overlay.height - priv->slider.height); |
3202 | - |
3203 | - move_thumb (scrollbar, x_pos + x, y_pos + y); |
3204 | - } |
3205 | - else |
3206 | - { |
3207 | - move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y); |
3208 | - } |
3209 | - |
3210 | - os_pager_set_detached (priv->pager, FALSE); |
3211 | - os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
3212 | - gtk_widget_show (priv->thumb); |
3213 | - } |
3214 | - else |
3215 | - { |
3216 | - priv->can_hide = TRUE; |
3217 | - priv->lock_position = FALSE; |
3218 | - |
3219 | - if (gtk_widget_get_mapped (priv->thumb) && |
3220 | - priv->source_hide_thumb_id == 0) |
3221 | - priv->source_hide_thumb_id = g_timeout_add (TIMEOUT_PROXIMITY_HIDE, |
3222 | - hide_thumb_cb, |
3223 | - scrollbar); |
3224 | - } |
3225 | + priv->hidable_thumb = FALSE; |
3226 | + |
3227 | + if (priv->source_hide_thumb_id != 0) |
3228 | + { |
3229 | + g_source_remove (priv->source_hide_thumb_id); |
3230 | + priv->source_hide_thumb_id = 0; |
3231 | + } |
3232 | + |
3233 | + if (priv->state & OS_STATE_LOCKED) |
3234 | + return GDK_FILTER_CONTINUE; |
3235 | + |
3236 | + adjust_thumb_position (scrollbar, event_x, event_y); |
3237 | + |
3238 | + show_thumb (scrollbar); |
3239 | } |
3240 | else |
3241 | { |
3242 | - if (check_proximity (scrollbar, event_x, event_y)) |
3243 | + priv->state &= ~(OS_STATE_LOCKED); |
3244 | + |
3245 | + if (priv->source_show_thumb_id != 0) |
3246 | { |
3247 | - priv->can_hide = FALSE; |
3248 | - |
3249 | - if (priv->source_hide_thumb_id != 0) |
3250 | - { |
3251 | - g_source_remove (priv->source_hide_thumb_id); |
3252 | - priv->source_hide_thumb_id = 0; |
3253 | - } |
3254 | - |
3255 | - if (priv->lock_position) |
3256 | - return GDK_FILTER_CONTINUE; |
3257 | - |
3258 | - if (priv->overlay.width > priv->slider.width) |
3259 | - { |
3260 | - gint x, y, x_pos, y_pos; |
3261 | - |
3262 | - gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
3263 | - |
3264 | - x = CLAMP (event_x - priv->slider.width / 2, |
3265 | - priv->thumb_all.x + priv->overlay.x, |
3266 | - priv->thumb_all.x + priv->overlay.x + priv->overlay.width - priv->slider.width); |
3267 | - y = priv->thumb_all.y; |
3268 | - |
3269 | - move_thumb (scrollbar, x_pos + x, y_pos + y); |
3270 | - } |
3271 | - else |
3272 | - { |
3273 | - move_thumb (scrollbar, priv->win_x + priv->slider.x, priv->win_y); |
3274 | - } |
3275 | - |
3276 | - os_pager_set_detached (priv->pager, FALSE); |
3277 | - os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
3278 | - gtk_widget_show (priv->thumb); |
3279 | + g_source_remove (priv->source_show_thumb_id); |
3280 | + priv->source_show_thumb_id = 0; |
3281 | } |
3282 | - else |
3283 | + |
3284 | + if (gtk_widget_get_mapped (priv->thumb) && |
3285 | + !(priv->event & OS_EVENT_BUTTON_PRESS)) |
3286 | { |
3287 | - priv->can_hide = TRUE; |
3288 | - priv->lock_position = FALSE; |
3289 | + priv->hidable_thumb = TRUE; |
3290 | |
3291 | - if (gtk_widget_get_mapped (priv->thumb) && |
3292 | - priv->source_hide_thumb_id == 0) |
3293 | + if (priv->source_hide_thumb_id == 0) |
3294 | priv->source_hide_thumb_id = g_timeout_add (TIMEOUT_PROXIMITY_HIDE, |
3295 | hide_thumb_cb, |
3296 | scrollbar); |
3297 | @@ -2325,120 +2536,79 @@ |
3298 | |
3299 | xev = gdkxevent; |
3300 | |
3301 | - g_return_val_if_fail (OS_IS_PAGER (priv->pager), GDK_FILTER_CONTINUE); |
3302 | + g_return_val_if_fail (OS_IS_BAR (priv->bar), GDK_FILTER_CONTINUE); |
3303 | g_return_val_if_fail (OS_IS_THUMB (priv->thumb), GDK_FILTER_CONTINUE); |
3304 | |
3305 | - if (!priv->fullsize) |
3306 | + if (!(priv->state & OS_STATE_FULLSIZE)) |
3307 | { |
3308 | if (xev->type == ButtonPress) |
3309 | { |
3310 | - priv->toplevel_button_press = TRUE; |
3311 | + priv->window_button_press = TRUE; |
3312 | + |
3313 | + if (priv->source_show_thumb_id != 0) |
3314 | + { |
3315 | + g_source_remove (priv->source_show_thumb_id); |
3316 | + priv->source_show_thumb_id = 0; |
3317 | + } |
3318 | + |
3319 | gtk_widget_hide (priv->thumb); |
3320 | } |
3321 | |
3322 | - if (priv->toplevel_button_press && xev->type == ButtonRelease) |
3323 | + if (priv->window_button_press && xev->type == ButtonRelease) |
3324 | { |
3325 | - priv->toplevel_button_press = FALSE; |
3326 | + priv->window_button_press = FALSE; |
3327 | |
3328 | /* Proximity area. */ |
3329 | - if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
3330 | - { |
3331 | - if (check_proximity (scrollbar, xev->xbutton.x, xev->xbutton.y)) |
3332 | - { |
3333 | - priv->can_hide = FALSE; |
3334 | - |
3335 | - if (priv->source_hide_thumb_id != 0) |
3336 | - { |
3337 | - g_source_remove (priv->source_hide_thumb_id); |
3338 | - priv->source_hide_thumb_id = 0; |
3339 | - } |
3340 | - |
3341 | - if (priv->lock_position) |
3342 | - return GDK_FILTER_CONTINUE; |
3343 | - |
3344 | - if (priv->overlay.height > priv->slider.height) |
3345 | - { |
3346 | - gint x, y, x_pos, y_pos; |
3347 | - |
3348 | - gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
3349 | - |
3350 | - x = priv->thumb_all.x; |
3351 | - y = CLAMP (xev->xbutton.y - priv->slider.height / 2, |
3352 | - priv->thumb_all.y + priv->overlay.y, |
3353 | - priv->thumb_all.y + priv->overlay.y + priv->overlay.height - priv->slider.height); |
3354 | - |
3355 | - move_thumb (scrollbar, x_pos + x, y_pos + y); |
3356 | - } |
3357 | - else |
3358 | - { |
3359 | - move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y); |
3360 | - } |
3361 | - |
3362 | - gtk_widget_show (priv->thumb); |
3363 | - } |
3364 | - } |
3365 | - else |
3366 | - { |
3367 | - if (check_proximity (scrollbar, xev->xbutton.x, xev->xbutton.y)) |
3368 | - { |
3369 | - priv->can_hide = FALSE; |
3370 | - |
3371 | - if (priv->source_hide_thumb_id != 0) |
3372 | - { |
3373 | - g_source_remove (priv->source_hide_thumb_id); |
3374 | - priv->source_hide_thumb_id = 0; |
3375 | - } |
3376 | - |
3377 | - if (priv->lock_position) |
3378 | - return GDK_FILTER_CONTINUE; |
3379 | - |
3380 | - if (priv->overlay.width > priv->slider.width) |
3381 | - { |
3382 | - gint x, y, x_pos, y_pos; |
3383 | - |
3384 | - gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
3385 | - |
3386 | - x = CLAMP (xev->xbutton.x - priv->slider.width / 2, |
3387 | - priv->thumb_all.x + priv->overlay.x, |
3388 | - priv->thumb_all.x + priv->overlay.x + priv->overlay.width - priv->slider.width); |
3389 | - y = priv->thumb_all.y; |
3390 | - |
3391 | - move_thumb (scrollbar, x_pos + x, y_pos + y); |
3392 | - } |
3393 | - else |
3394 | - { |
3395 | - move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y); |
3396 | - } |
3397 | - |
3398 | - gtk_widget_show (priv->thumb); |
3399 | - } |
3400 | + if (check_proximity (scrollbar, xev->xbutton.x, xev->xbutton.y)) |
3401 | + { |
3402 | + priv->hidable_thumb = FALSE; |
3403 | + |
3404 | + if (priv->state & OS_STATE_LOCKED) |
3405 | + return GDK_FILTER_CONTINUE; |
3406 | + |
3407 | + adjust_thumb_position (scrollbar, xev->xbutton.x, xev->xbutton.y); |
3408 | + |
3409 | + gtk_widget_show (priv->thumb); |
3410 | + |
3411 | + update_tail (scrollbar); |
3412 | } |
3413 | } |
3414 | |
3415 | if (xev->type == LeaveNotify) |
3416 | { |
3417 | - /* Never deactivate the pager in an active window. */ |
3418 | + priv->window_button_press = FALSE; |
3419 | + |
3420 | + /* Never deactivate the bar in an active window. */ |
3421 | if (!priv->active_window) |
3422 | { |
3423 | - priv->can_deactivate_pager = TRUE; |
3424 | - |
3425 | - if (priv->source_deactivate_pager_id != 0) |
3426 | - g_source_remove (priv->source_deactivate_pager_id); |
3427 | - |
3428 | - priv->source_deactivate_pager_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE, |
3429 | - deactivate_pager_cb, |
3430 | - scrollbar); |
3431 | - } |
3432 | - |
3433 | - priv->toplevel_button_press = FALSE; |
3434 | - priv->can_hide = TRUE; |
3435 | - |
3436 | - if (priv->source_hide_thumb_id != 0) |
3437 | - g_source_remove (priv->source_hide_thumb_id); |
3438 | - |
3439 | - priv->source_hide_thumb_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE, |
3440 | - hide_thumb_cb, |
3441 | - scrollbar); |
3442 | + priv->deactivable_bar = TRUE; |
3443 | + |
3444 | + if (priv->source_deactivate_bar_id != 0) |
3445 | + g_source_remove (priv->source_deactivate_bar_id); |
3446 | + |
3447 | + priv->source_deactivate_bar_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE, |
3448 | + deactivate_bar_cb, |
3449 | + scrollbar); |
3450 | + } |
3451 | + |
3452 | + if (gtk_widget_get_mapped (priv->thumb) && |
3453 | + !(priv->event & OS_EVENT_BUTTON_PRESS)) |
3454 | + { |
3455 | + priv->hidable_thumb = TRUE; |
3456 | + |
3457 | + if (priv->source_hide_thumb_id != 0) |
3458 | + g_source_remove (priv->source_hide_thumb_id); |
3459 | + |
3460 | + priv->source_hide_thumb_id = g_timeout_add (TIMEOUT_TOPLEVEL_HIDE, |
3461 | + hide_thumb_cb, |
3462 | + scrollbar); |
3463 | + } |
3464 | + |
3465 | + if (priv->source_show_thumb_id != 0) |
3466 | + { |
3467 | + g_source_remove (priv->source_show_thumb_id); |
3468 | + priv->source_show_thumb_id = 0; |
3469 | + } |
3470 | |
3471 | if (priv->source_unlock_thumb_id != 0) |
3472 | g_source_remove (priv->source_unlock_thumb_id); |
3473 | @@ -2449,95 +2619,47 @@ |
3474 | } |
3475 | |
3476 | /* Get the motion_notify_event trough XEvent. */ |
3477 | - if (!priv->toplevel_button_press && xev->type == MotionNotify) |
3478 | + if (!priv->window_button_press && xev->type == MotionNotify) |
3479 | { |
3480 | /* React to motion_notify_event |
3481 | * and set the state accordingly. */ |
3482 | if (!is_insensitive (scrollbar) && !priv->active_window) |
3483 | - pager_set_state_from_pointer (scrollbar, xev->xmotion.x, xev->xmotion.y); |
3484 | + bar_set_state_from_pointer (scrollbar, xev->xmotion.x, xev->xmotion.y); |
3485 | |
3486 | /* Proximity area. */ |
3487 | - if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
3488 | + if (check_proximity (scrollbar, xev->xmotion.x, xev->xmotion.y)) |
3489 | { |
3490 | - if (check_proximity (scrollbar, xev->xmotion.x, xev->xmotion.y)) |
3491 | - { |
3492 | - priv->can_hide = FALSE; |
3493 | - |
3494 | - if (priv->lock_position) |
3495 | - return GDK_FILTER_CONTINUE; |
3496 | - |
3497 | - if (priv->overlay.height > priv->slider.height) |
3498 | - { |
3499 | - gint x, y, x_pos, y_pos; |
3500 | - |
3501 | - gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
3502 | - |
3503 | - x = priv->thumb_all.x; |
3504 | - y = CLAMP (xev->xmotion.y - priv->slider.height / 2, |
3505 | - priv->thumb_all.y + priv->overlay.y, |
3506 | - priv->thumb_all.y + priv->overlay.y + priv->overlay.height - priv->slider.height); |
3507 | - |
3508 | - move_thumb (scrollbar, x_pos + x, y_pos + y); |
3509 | - } |
3510 | - else |
3511 | - { |
3512 | - move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y); |
3513 | - } |
3514 | - |
3515 | - os_pager_set_detached (priv->pager, FALSE); |
3516 | - os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
3517 | - gtk_widget_show (priv->thumb); |
3518 | - } |
3519 | - else |
3520 | - { |
3521 | - priv->can_hide = TRUE; |
3522 | - priv->lock_position = FALSE; |
3523 | - |
3524 | - if (gtk_widget_get_mapped (priv->thumb) && |
3525 | - priv->source_hide_thumb_id == 0) |
3526 | - priv->source_hide_thumb_id = g_timeout_add (TIMEOUT_PROXIMITY_HIDE, |
3527 | - hide_thumb_cb, |
3528 | - scrollbar); |
3529 | - } |
3530 | + priv->hidable_thumb = FALSE; |
3531 | + |
3532 | + if (priv->source_hide_thumb_id != 0) |
3533 | + { |
3534 | + g_source_remove (priv->source_hide_thumb_id); |
3535 | + priv->source_hide_thumb_id = 0; |
3536 | + } |
3537 | + |
3538 | + if (priv->state & OS_STATE_LOCKED) |
3539 | + return GDK_FILTER_CONTINUE; |
3540 | + |
3541 | + adjust_thumb_position (scrollbar, xev->xmotion.x, xev->xmotion.y); |
3542 | + |
3543 | + show_thumb (scrollbar); |
3544 | } |
3545 | else |
3546 | { |
3547 | - if (check_proximity (scrollbar, xev->xmotion.x, xev->xmotion.y)) |
3548 | + priv->state &= ~(OS_STATE_LOCKED); |
3549 | + |
3550 | + if (priv->source_show_thumb_id != 0) |
3551 | { |
3552 | - priv->can_hide = FALSE; |
3553 | - |
3554 | - if (priv->lock_position) |
3555 | - return GDK_FILTER_CONTINUE; |
3556 | - |
3557 | - if (priv->overlay.width > priv->slider.width) |
3558 | - { |
3559 | - gint x, y, x_pos, y_pos; |
3560 | - |
3561 | - gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (scrollbar)), &x_pos, &y_pos); |
3562 | - |
3563 | - x = CLAMP (xev->xmotion.x - priv->slider.width / 2, |
3564 | - priv->thumb_all.x + priv->overlay.x, |
3565 | - priv->thumb_all.x + priv->overlay.x + priv->overlay.width - priv->slider.width); |
3566 | - y = priv->thumb_all.y; |
3567 | - |
3568 | - move_thumb (scrollbar, x_pos + x, y_pos + y); |
3569 | - } |
3570 | - else |
3571 | - { |
3572 | - move_thumb (scrollbar, priv->win_x + priv->slider.x, priv->win_y); |
3573 | - } |
3574 | - |
3575 | - os_pager_set_detached (priv->pager, FALSE); |
3576 | - os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
3577 | - gtk_widget_show (priv->thumb); |
3578 | + g_source_remove (priv->source_show_thumb_id); |
3579 | + priv->source_show_thumb_id = 0; |
3580 | } |
3581 | - else |
3582 | + |
3583 | + if (gtk_widget_get_mapped (priv->thumb) && |
3584 | + !(priv->event & OS_EVENT_BUTTON_PRESS)) |
3585 | { |
3586 | - priv->can_hide = TRUE; |
3587 | - priv->lock_position = FALSE; |
3588 | + priv->hidable_thumb = TRUE; |
3589 | |
3590 | - if (gtk_widget_get_mapped (priv->thumb) && |
3591 | - priv->source_hide_thumb_id == 0) |
3592 | + if (priv->source_hide_thumb_id == 0) |
3593 | priv->source_hide_thumb_id = g_timeout_add (TIMEOUT_PROXIMITY_HIDE, |
3594 | hide_thumb_cb, |
3595 | scrollbar); |
3596 | @@ -2550,6 +2672,44 @@ |
3597 | } |
3598 | #endif |
3599 | |
3600 | +/* Add the window filter function. */ |
3601 | +static void |
3602 | +add_window_filter (OsScrollbar *scrollbar) |
3603 | +{ |
3604 | + OsScrollbarPrivate *priv; |
3605 | + |
3606 | + priv = scrollbar->priv; |
3607 | + |
3608 | + /* Don't add duplicated filters. */ |
3609 | + if (!priv->filter.running && |
3610 | + gtk_widget_get_realized (GTK_WIDGET (scrollbar))) |
3611 | + { |
3612 | + priv->filter.running = TRUE; |
3613 | + gdk_window_add_filter (gtk_widget_get_window (GTK_WIDGET (scrollbar)), |
3614 | + window_filter_func, |
3615 | + scrollbar); |
3616 | + } |
3617 | +} |
3618 | + |
3619 | +/* Remove the window filter function. */ |
3620 | +static void |
3621 | +remove_window_filter (OsScrollbar *scrollbar) |
3622 | +{ |
3623 | + OsScrollbarPrivate *priv; |
3624 | + |
3625 | + priv = scrollbar->priv; |
3626 | + |
3627 | + /* Remove only if the filter is running. */ |
3628 | + if (priv->filter.running && |
3629 | + gtk_widget_get_realized (GTK_WIDGET (scrollbar))) |
3630 | + { |
3631 | + priv->filter.running = FALSE; |
3632 | + gdk_window_remove_filter (gtk_widget_get_window (GTK_WIDGET (scrollbar)), |
3633 | + window_filter_func, |
3634 | + scrollbar); |
3635 | + } |
3636 | +} |
3637 | + |
3638 | G_DEFINE_TYPE (OsScrollbar, os_scrollbar, GTK_TYPE_SCROLLBAR); |
3639 | |
3640 | static void |
3641 | @@ -2634,27 +2794,34 @@ |
3642 | |
3643 | priv->event = OS_EVENT_NONE; |
3644 | |
3645 | + priv->state = OS_STATE_NONE; |
3646 | + |
3647 | + priv->side = OS_SIDE_RIGHT; |
3648 | + |
3649 | + priv->filter.proximity = FALSE; |
3650 | + priv->filter.running = FALSE; |
3651 | + |
3652 | priv->active_window = FALSE; |
3653 | - priv->can_deactivate_pager = TRUE; |
3654 | - priv->can_hide = TRUE; |
3655 | - priv->detached_scroll = FALSE; |
3656 | - priv->filter = FALSE; |
3657 | - priv->fullsize = FALSE; |
3658 | - priv->internal = FALSE; |
3659 | - priv->lock_position = FALSE; |
3660 | - priv->proximity = FALSE; |
3661 | - priv->toplevel_button_press = FALSE; |
3662 | - priv->side = OS_SIDE_RIGHT; |
3663 | - priv->source_deactivate_pager_id = 0; |
3664 | + priv->deactivable_bar = TRUE; |
3665 | + priv->hidable_thumb = TRUE; |
3666 | + priv->window_button_press = FALSE; |
3667 | + |
3668 | + priv->pointer.x = 0; |
3669 | + priv->pointer.y = 0; |
3670 | + priv->thumb_win.x = 0; |
3671 | + priv->thumb_win.y = 0; |
3672 | + |
3673 | + priv->source_deactivate_bar_id = 0; |
3674 | priv->source_hide_thumb_id = 0; |
3675 | + priv->source_show_thumb_id = 0; |
3676 | priv->source_unlock_thumb_id = 0; |
3677 | |
3678 | - priv->pager = os_pager_new (); |
3679 | + priv->bar = os_bar_new (); |
3680 | |
3681 | priv->window_group = gtk_window_group_new (); |
3682 | |
3683 | - priv->animation = os_animation_new (RATE_PAGING, MAX_DURATION_PAGING, |
3684 | - paging_cb, NULL, scrollbar); |
3685 | + priv->animation = os_animation_new (RATE_ANIMATION, MAX_DURATION_SCROLLING, |
3686 | + scrolling_cb, scrolling_end_cb, scrollbar); |
3687 | priv->value = 0; |
3688 | |
3689 | g_signal_connect (G_OBJECT (scrollbar), "notify::adjustment", |
3690 | @@ -2673,10 +2840,10 @@ |
3691 | scrollbar = OS_SCROLLBAR (object); |
3692 | priv = scrollbar->priv; |
3693 | |
3694 | - if (priv->source_deactivate_pager_id != 0) |
3695 | + if (priv->source_deactivate_bar_id != 0) |
3696 | { |
3697 | - g_source_remove (priv->source_deactivate_pager_id); |
3698 | - priv->source_deactivate_pager_id = 0; |
3699 | + g_source_remove (priv->source_deactivate_bar_id); |
3700 | + priv->source_deactivate_bar_id = 0; |
3701 | } |
3702 | |
3703 | if (priv->source_hide_thumb_id != 0) |
3704 | @@ -2711,10 +2878,10 @@ |
3705 | priv->animation = NULL; |
3706 | } |
3707 | |
3708 | - if (priv->pager != NULL) |
3709 | + if (priv->bar != NULL) |
3710 | { |
3711 | - g_object_unref (priv->pager); |
3712 | - priv->pager = NULL; |
3713 | + g_object_unref (priv->bar); |
3714 | + priv->bar = NULL; |
3715 | } |
3716 | |
3717 | if (priv->window_group != NULL) |
3718 | @@ -2767,8 +2934,7 @@ |
3719 | *minimal_width = *natural_width = 0; |
3720 | else |
3721 | { |
3722 | - /* Smaller than 35 pixels the thumb looks weird. */ |
3723 | - *minimal_width = 35; |
3724 | + *minimal_width = MIN_THUMB_HEIGHT; |
3725 | *natural_width = THUMB_HEIGHT; |
3726 | } |
3727 | } |
3728 | @@ -2788,8 +2954,7 @@ |
3729 | *minimal_height = *natural_height = 0; |
3730 | else |
3731 | { |
3732 | - /* Smaller than 35 pixels the thumb looks weird. */ |
3733 | - *minimal_height = 35; |
3734 | + *minimal_height = MIN_THUMB_HEIGHT; |
3735 | *natural_height = THUMB_HEIGHT; |
3736 | } |
3737 | } |
3738 | @@ -2823,10 +2988,10 @@ |
3739 | gdk_screen_get_active_window (gtk_widget_get_screen (widget))) |
3740 | { |
3741 | /* Stops potential running timeout. */ |
3742 | - if (priv->source_deactivate_pager_id != 0) |
3743 | + if (priv->source_deactivate_bar_id != 0) |
3744 | { |
3745 | - g_source_remove (priv->source_deactivate_pager_id); |
3746 | - priv->source_deactivate_pager_id = 0; |
3747 | + g_source_remove (priv->source_deactivate_bar_id); |
3748 | + priv->source_deactivate_bar_id = 0; |
3749 | } |
3750 | |
3751 | priv->active_window = TRUE; |
3752 | @@ -2846,29 +3011,24 @@ |
3753 | * for example when switching notebook page, |
3754 | * check the position of the pointer |
3755 | * and set the state accordingly. */ |
3756 | - pager_set_state_from_pointer (scrollbar, x, y); |
3757 | + bar_set_state_from_pointer (scrollbar, x, y); |
3758 | } |
3759 | else |
3760 | { |
3761 | /* On map-event of an active window, |
3762 | - * the pager should be active. */ |
3763 | - priv->can_deactivate_pager = FALSE; |
3764 | - os_pager_set_active (priv->pager, TRUE, FALSE); |
3765 | + * the bar should be active. */ |
3766 | + priv->deactivable_bar = FALSE; |
3767 | + os_bar_set_active (priv->bar, TRUE, FALSE); |
3768 | } |
3769 | } |
3770 | |
3771 | - if (priv->fullsize == FALSE) |
3772 | - os_pager_show (priv->pager); |
3773 | + if (!(priv->state & OS_STATE_FULLSIZE)) |
3774 | + os_bar_show (priv->bar); |
3775 | |
3776 | if (!is_insensitive (scrollbar)) |
3777 | { |
3778 | - priv->proximity = TRUE; |
3779 | - |
3780 | - if (gtk_widget_get_realized (widget) && priv->filter == FALSE) |
3781 | - { |
3782 | - priv->filter = TRUE; |
3783 | - gdk_window_add_filter (gtk_widget_get_window (widget), window_filter_func, scrollbar); |
3784 | - } |
3785 | + priv->filter.proximity = TRUE; |
3786 | + add_window_filter (scrollbar); |
3787 | } |
3788 | } |
3789 | |
3790 | @@ -2889,20 +3049,17 @@ |
3791 | gdk_window_get_events (gtk_widget_get_window (widget)) | |
3792 | GDK_POINTER_MOTION_MASK); |
3793 | |
3794 | - if (priv->filter == FALSE && priv->proximity == TRUE) |
3795 | - { |
3796 | - priv->filter = TRUE; |
3797 | - gdk_window_add_filter (gtk_widget_get_window (widget), window_filter_func, scrollbar); |
3798 | - } |
3799 | + if (priv->filter.proximity) |
3800 | + add_window_filter (scrollbar); |
3801 | |
3802 | g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (widget)), "configure-event", |
3803 | G_CALLBACK (toplevel_configure_event_cb), scrollbar); |
3804 | |
3805 | - calc_layout_pager (scrollbar, gtk_adjustment_get_value (priv->adjustment)); |
3806 | - |
3807 | - os_pager_set_parent (priv->pager, widget); |
3808 | - |
3809 | - store_toplevel_position (scrollbar); |
3810 | + calc_layout_bar (scrollbar, gtk_adjustment_get_value (priv->adjustment)); |
3811 | + |
3812 | + os_bar_set_parent (priv->bar, widget); |
3813 | + |
3814 | + calc_thumb_window_position (scrollbar); |
3815 | } |
3816 | |
3817 | static void |
3818 | @@ -2965,7 +3122,7 @@ |
3819 | scrollbar = OS_SCROLLBAR (widget); |
3820 | priv = scrollbar->priv; |
3821 | |
3822 | - /* Get the side, then move thumb and pager accordingly. */ |
3823 | + /* Get the side, then move thumb and bar accordingly. */ |
3824 | retrieve_side (scrollbar); |
3825 | |
3826 | priv->trough.x = allocation->x; |
3827 | @@ -2973,7 +3130,7 @@ |
3828 | priv->trough.width = allocation->width; |
3829 | priv->trough.height = allocation->height; |
3830 | |
3831 | - priv->pager_all = *allocation; |
3832 | + priv->bar_all = *allocation; |
3833 | priv->thumb_all = *allocation; |
3834 | |
3835 | if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
3836 | @@ -2986,16 +3143,16 @@ |
3837 | } |
3838 | |
3839 | if (priv->side == OS_SIDE_RIGHT) |
3840 | - priv->pager_all.x = allocation->x - PAGER_SIZE; |
3841 | + priv->bar_all.x = allocation->x - BAR_SIZE; |
3842 | |
3843 | - priv->pager_all.width = PAGER_SIZE; |
3844 | + priv->bar_all.width = BAR_SIZE; |
3845 | |
3846 | priv->thumb_all.width = THUMB_WIDTH; |
3847 | |
3848 | if (priv->side == OS_SIDE_RIGHT) |
3849 | - priv->thumb_all.x = allocation->x - priv->pager_all.width; |
3850 | + priv->thumb_all.x = allocation->x - priv->bar_all.width; |
3851 | else |
3852 | - priv->thumb_all.x = allocation->x + priv->pager_all.width - priv->thumb_all.width; |
3853 | + priv->thumb_all.x = allocation->x + priv->bar_all.width - priv->thumb_all.width; |
3854 | |
3855 | allocation->width = 0; |
3856 | } |
3857 | @@ -3009,32 +3166,32 @@ |
3858 | } |
3859 | |
3860 | if (priv->side == OS_SIDE_BOTTOM) |
3861 | - priv->pager_all.y = allocation->y - PAGER_SIZE; |
3862 | + priv->bar_all.y = allocation->y - BAR_SIZE; |
3863 | |
3864 | - priv->pager_all.height = PAGER_SIZE; |
3865 | + priv->bar_all.height = BAR_SIZE; |
3866 | |
3867 | priv->thumb_all.height = THUMB_WIDTH; |
3868 | |
3869 | if (priv->side == OS_SIDE_BOTTOM) |
3870 | - priv->thumb_all.y = allocation->y - priv->pager_all.height; |
3871 | + priv->thumb_all.y = allocation->y - priv->bar_all.height; |
3872 | else |
3873 | - priv->thumb_all.y = allocation->y + priv->pager_all.height - priv->thumb_all.height; |
3874 | + priv->thumb_all.y = allocation->y + priv->bar_all.height - priv->thumb_all.height; |
3875 | |
3876 | allocation->height = 0; |
3877 | } |
3878 | |
3879 | if (priv->adjustment != NULL) |
3880 | { |
3881 | - calc_layout_pager (scrollbar, gtk_adjustment_get_value (priv->adjustment)); |
3882 | + calc_layout_bar (scrollbar, gtk_adjustment_get_value (priv->adjustment)); |
3883 | calc_layout_slider (scrollbar, gtk_adjustment_get_value (priv->adjustment)); |
3884 | } |
3885 | |
3886 | - os_pager_size_allocate (priv->pager, priv->pager_all); |
3887 | + os_bar_size_allocate (priv->bar, priv->bar_all); |
3888 | |
3889 | - move_pager (scrollbar); |
3890 | + move_bar (scrollbar); |
3891 | |
3892 | if (gtk_widget_get_realized (widget)) |
3893 | - store_toplevel_position (scrollbar); |
3894 | + calc_thumb_window_position (scrollbar); |
3895 | |
3896 | gtk_widget_set_allocation (widget, allocation); |
3897 | } |
3898 | @@ -3047,15 +3204,10 @@ |
3899 | |
3900 | priv = scrollbar->priv; |
3901 | |
3902 | - priv->proximity = FALSE; |
3903 | - |
3904 | - if (gtk_widget_get_realized (GTK_WIDGET (scrollbar)) && priv->filter == TRUE) |
3905 | - { |
3906 | - priv->filter = FALSE; |
3907 | - gdk_window_remove_filter (gtk_widget_get_window (GTK_WIDGET (scrollbar)), window_filter_func, scrollbar); |
3908 | - } |
3909 | - |
3910 | - os_pager_set_active (priv->pager, FALSE, FALSE); |
3911 | + priv->filter.proximity = FALSE; |
3912 | + remove_window_filter (scrollbar); |
3913 | + |
3914 | + os_bar_set_active (priv->bar, FALSE, FALSE); |
3915 | |
3916 | gtk_widget_hide (priv->thumb); |
3917 | } |
3918 | @@ -3068,16 +3220,11 @@ |
3919 | |
3920 | priv = scrollbar->priv; |
3921 | |
3922 | - priv->proximity = TRUE; |
3923 | - |
3924 | - if (gtk_widget_get_realized (GTK_WIDGET (scrollbar)) && priv->filter == FALSE) |
3925 | - { |
3926 | - priv->filter = TRUE; |
3927 | - gdk_window_add_filter (gtk_widget_get_window (GTK_WIDGET (scrollbar)), window_filter_func, scrollbar); |
3928 | - } |
3929 | + priv->filter.proximity = TRUE; |
3930 | + add_window_filter (scrollbar); |
3931 | |
3932 | if (priv->active_window) |
3933 | - os_pager_set_active (priv->pager, TRUE, FALSE); |
3934 | + os_bar_set_active (priv->bar, TRUE, FALSE); |
3935 | else |
3936 | { |
3937 | gint x, y; |
3938 | @@ -3087,7 +3234,7 @@ |
3939 | /* When the window is unfocused, |
3940 | * check the position of the pointer |
3941 | * and set the state accordingly. */ |
3942 | - pager_set_state_from_pointer (scrollbar, x, y); |
3943 | + bar_set_state_from_pointer (scrollbar, x, y); |
3944 | } |
3945 | } |
3946 | |
3947 | @@ -3150,17 +3297,12 @@ |
3948 | |
3949 | GTK_WIDGET_CLASS (g_type_class_peek (GTK_TYPE_WIDGET))->unmap (widget); |
3950 | |
3951 | - priv->proximity = FALSE; |
3952 | - |
3953 | - os_pager_hide (priv->pager); |
3954 | + os_bar_hide (priv->bar); |
3955 | |
3956 | gtk_widget_hide (priv->thumb); |
3957 | |
3958 | - if (gtk_widget_get_realized (widget) && priv->filter == TRUE) |
3959 | - { |
3960 | - priv->filter = FALSE; |
3961 | - gdk_window_remove_filter (gtk_widget_get_window (widget), window_filter_func, scrollbar); |
3962 | - } |
3963 | + priv->filter.proximity = FALSE; |
3964 | + remove_window_filter (scrollbar); |
3965 | } |
3966 | |
3967 | static void |
3968 | @@ -3172,17 +3314,17 @@ |
3969 | scrollbar = OS_SCROLLBAR (widget); |
3970 | priv = scrollbar->priv; |
3971 | |
3972 | - os_pager_hide (priv->pager); |
3973 | + os_bar_hide (priv->bar); |
3974 | |
3975 | gtk_widget_hide (priv->thumb); |
3976 | |
3977 | - priv->filter = FALSE; |
3978 | + priv->filter.running = FALSE; |
3979 | gdk_window_remove_filter (gtk_widget_get_window (widget), window_filter_func, scrollbar); |
3980 | |
3981 | g_signal_handlers_disconnect_by_func (G_OBJECT (gtk_widget_get_toplevel (widget)), |
3982 | G_CALLBACK (toplevel_configure_event_cb), scrollbar); |
3983 | |
3984 | - os_pager_set_parent (priv->pager, NULL); |
3985 | + os_bar_set_parent (priv->bar, NULL); |
3986 | |
3987 | GTK_WIDGET_CLASS (g_type_class_peek (GTK_TYPE_WIDGET))->unrealize (widget); |
3988 | } |
3989 | |
3990 | === modified file 'os/os-thumb.c' |
3991 | --- os/os-thumb.c 2011-10-05 12:24:21 +0000 |
3992 | +++ os/os-thumb.c 2011-10-12 17:16:23 +0000 |
3993 | @@ -29,9 +29,6 @@ |
3994 | #include <math.h> |
3995 | #include <stdlib.h> |
3996 | |
3997 | -/* Rate of the fade-out. */ |
3998 | -#define RATE_FADE_OUT 30 |
3999 | - |
4000 | /* Duration of the fade-out. */ |
4001 | #define DURATION_FADE_OUT 2000 |
4002 | |
4003 | @@ -57,14 +54,12 @@ |
4004 | GtkOrientation orientation; |
4005 | GtkWidget *grabbed_widget; |
4006 | OsAnimation *animation; |
4007 | - OsEvent event; |
4008 | - gboolean can_rgba; |
4009 | + OsCoordinate pointer; |
4010 | + OsCoordinate pointer_root; |
4011 | + OsEventFlags event; |
4012 | + gboolean rgba; |
4013 | gboolean detached; |
4014 | - gboolean use_tolerance; |
4015 | - gint pointer_x; |
4016 | - gint pointer_y; |
4017 | - gint pointer_x_root; |
4018 | - gint pointer_y_root; |
4019 | + gboolean tolerance; |
4020 | guint32 source_id; |
4021 | }; |
4022 | |
4023 | @@ -192,12 +187,17 @@ |
4024 | |
4025 | priv->event = OS_EVENT_NONE; |
4026 | |
4027 | - priv->can_rgba = FALSE; |
4028 | + priv->pointer.x = 0; |
4029 | + priv->pointer.y = 0; |
4030 | + priv->pointer_root.x = 0; |
4031 | + priv->pointer_root.y = 0; |
4032 | + |
4033 | + priv->rgba = FALSE; |
4034 | priv->detached = FALSE; |
4035 | - priv->use_tolerance = FALSE; |
4036 | + priv->tolerance = FALSE; |
4037 | |
4038 | priv->source_id = 0; |
4039 | - priv->animation = os_animation_new (RATE_FADE_OUT, DURATION_FADE_OUT, |
4040 | + priv->animation = os_animation_new (RATE_ANIMATION, DURATION_FADE_OUT, |
4041 | fade_out_cb, NULL, thumb); |
4042 | |
4043 | gtk_window_set_skip_pager_hint (GTK_WINDOW (thumb), TRUE); |
4044 | @@ -237,19 +237,20 @@ |
4045 | |
4046 | if (event->type == GDK_BUTTON_PRESS) |
4047 | { |
4048 | - if (event->button == 1) |
4049 | + if (event->button == 1 || |
4050 | + event->button == 2) |
4051 | { |
4052 | gtk_grab_add (widget); |
4053 | |
4054 | - priv->pointer_x = event->x; |
4055 | - priv->pointer_y = event->y; |
4056 | - priv->pointer_x_root = event->x_root; |
4057 | - priv->pointer_y_root = event->y_root; |
4058 | + priv->pointer.x = event->x; |
4059 | + priv->pointer.y = event->y; |
4060 | + priv->pointer_root.x = event->x_root; |
4061 | + priv->pointer_root.y = event->y_root; |
4062 | |
4063 | priv->event |= OS_EVENT_BUTTON_PRESS; |
4064 | priv->event &= ~(OS_EVENT_MOTION_NOTIFY); |
4065 | |
4066 | - priv->use_tolerance = TRUE; |
4067 | + priv->tolerance = TRUE; |
4068 | |
4069 | gtk_widget_queue_draw (widget); |
4070 | } |
4071 | @@ -273,7 +274,8 @@ |
4072 | |
4073 | if (event->type == GDK_BUTTON_RELEASE) |
4074 | { |
4075 | - if (event->button == 1) |
4076 | + if (event->button == 1 || |
4077 | + event->button == 2) |
4078 | { |
4079 | gtk_grab_remove (widget); |
4080 | |
4081 | @@ -295,7 +297,7 @@ |
4082 | thumb = OS_THUMB (widget); |
4083 | priv = thumb->priv; |
4084 | |
4085 | - priv->can_rgba = FALSE; |
4086 | + priv->rgba = FALSE; |
4087 | |
4088 | if (gdk_screen_is_composited (gtk_widget_get_screen (widget))) |
4089 | { |
4090 | @@ -313,7 +315,7 @@ |
4091 | if (gdk_visual_get_depth (visual) == 32 && (red_mask == 0xff0000 && |
4092 | green_mask == 0x00ff00 && |
4093 | blue_mask == 0x0000ff)) |
4094 | - priv->can_rgba = TRUE; |
4095 | + priv->rgba = TRUE; |
4096 | } |
4097 | |
4098 | gtk_widget_queue_draw (widget); |
4099 | @@ -631,7 +633,7 @@ |
4100 | thumb = OS_THUMB (widget); |
4101 | priv = thumb->priv; |
4102 | |
4103 | - radius = priv->can_rgba ? THUMB_RADIUS : 0; |
4104 | + radius = priv->rgba ? THUMB_RADIUS : 0; |
4105 | |
4106 | #ifdef USE_GTK3 |
4107 | width = gtk_widget_get_allocated_width (widget); |
4108 | @@ -690,8 +692,8 @@ |
4109 | if ((priv->event & OS_EVENT_BUTTON_PRESS) && |
4110 | !(priv->event & OS_EVENT_MOTION_NOTIFY)) |
4111 | { |
4112 | - if ((priv->orientation == GTK_ORIENTATION_VERTICAL && (priv->pointer_y < height / 2)) || |
4113 | - (priv->orientation == GTK_ORIENTATION_HORIZONTAL && (priv->pointer_x < width / 2))) |
4114 | + if ((priv->orientation == GTK_ORIENTATION_VERTICAL && (priv->pointer.y < height / 2)) || |
4115 | + (priv->orientation == GTK_ORIENTATION_HORIZONTAL && (priv->pointer.x < width / 2))) |
4116 | { |
4117 | pattern_add_gdk_rgba_stop (pat, 0.0, &bg_arrow_down, 0.6); |
4118 | pattern_add_gdk_rgba_stop (pat, 0.49, &bg_arrow_down, 0.1); |
4119 | @@ -850,7 +852,7 @@ |
4120 | os_animation_stop (priv->animation, NULL); |
4121 | } |
4122 | |
4123 | - priv->use_tolerance = FALSE; |
4124 | + priv->tolerance = FALSE; |
4125 | |
4126 | return FALSE; |
4127 | } |
4128 | @@ -906,11 +908,11 @@ |
4129 | * see code few lines below. */ |
4130 | if (!(priv->event & OS_EVENT_MOTION_NOTIFY)) |
4131 | { |
4132 | - if (!priv->use_tolerance || |
4133 | - (abs (priv->pointer_x - event->x) > TOLERANCE_FADE || |
4134 | - abs (priv->pointer_y - event->y) > TOLERANCE_FADE)) |
4135 | + if (!priv->tolerance || |
4136 | + (abs (priv->pointer.x - event->x) > TOLERANCE_FADE || |
4137 | + abs (priv->pointer.y - event->y) > TOLERANCE_FADE)) |
4138 | { |
4139 | - priv->use_tolerance = FALSE; |
4140 | + priv->tolerance = FALSE; |
4141 | priv->source_id = g_timeout_add (TIMEOUT_FADE_OUT, |
4142 | timeout_fade_out_cb, |
4143 | thumb); |
4144 | @@ -920,8 +922,8 @@ |
4145 | if (priv->event & OS_EVENT_BUTTON_PRESS && |
4146 | !(priv->event & OS_EVENT_MOTION_NOTIFY)) |
4147 | { |
4148 | - if (abs (priv->pointer_x_root - event->x_root) <= TOLERANCE_MOTION && |
4149 | - abs (priv->pointer_y_root - event->y_root) <= TOLERANCE_MOTION) |
4150 | + if (abs (priv->pointer_root.x - event->x_root) <= TOLERANCE_MOTION && |
4151 | + abs (priv->pointer_root.y - event->y_root) <= TOLERANCE_MOTION) |
4152 | return FALSE; |
4153 | |
4154 | priv->event |= OS_EVENT_MOTION_NOTIFY; |
4155 | @@ -977,6 +979,13 @@ |
4156 | /* If started, stop the fade-out. */ |
4157 | os_animation_stop (priv->animation, fade_out_stop_cb); |
4158 | |
4159 | + if (priv->event & OS_EVENT_MOTION_NOTIFY) |
4160 | + { |
4161 | + priv->event &= ~(OS_EVENT_MOTION_NOTIFY); |
4162 | + |
4163 | + gtk_widget_queue_draw (widget); |
4164 | + } |
4165 | + |
4166 | return FALSE; |
4167 | } |
4168 | |
4169 | @@ -991,7 +1000,7 @@ |
4170 | |
4171 | priv->event = OS_EVENT_NONE; |
4172 | |
4173 | - priv->use_tolerance = FALSE; |
4174 | + priv->tolerance = FALSE; |
4175 | |
4176 | if (priv->grabbed_widget != NULL && gtk_widget_get_mapped (priv->grabbed_widget)) |
4177 | gtk_grab_add (priv->grabbed_widget); |
I do :)