Merge lp:~cimi/overlay-scrollbar/add-remove-toplevel-filter-func into lp:overlay-scrollbar

Proposed by Andrea Cimitan
Status: Merged
Merged at revision: 150
Proposed branch: lp:~cimi/overlay-scrollbar/add-remove-toplevel-filter-func
Merge into: lp:overlay-scrollbar
Diff against target: 424 lines (+113/-122)
2 files modified
os/os-pager.c (+32/-54)
os/os-scrollbar.c (+81/-68)
To merge this branch: bzr merge lp:~cimi/overlay-scrollbar/add-remove-toplevel-filter-func
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Ayatana Scrollbar Team Pending
Review via email: mp+52703@code.launchpad.net

Description of the change

Various changes, trying to allocate issues for the BadAlloc, optimizing pager, removing the toplevel_filter_func

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

removed toplevel_connect, put everything in realize

151. By Andrea Cimitan

Added parent_urealize_cb

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

Pretty big change! I don't see anything off.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'os/os-pager.c'
2--- os/os-pager.c 2011-03-08 02:17:15 +0000
3+++ os/os-pager.c 2011-03-09 16:19:25 +0000
4@@ -48,8 +48,7 @@
5 static void os_pager_finalize (GObject *object);
6 static void os_pager_create (OsPager *pager);
7 static void os_pager_draw (OsPager *pager);
8-static void os_pager_draw_bitmap (GdkPixmap *pixmap, GdkRectangle mask);
9-static void os_pager_draw_pixmap (GdkPixmap *pixmap, gboolean active);
10+static void os_pager_draw_bitmap (GdkPixmap *pixmap);
11 static void os_pager_mask (OsPager *pager);
12
13 /* Private functions */
14@@ -90,16 +89,17 @@
15 static void
16 os_pager_draw (OsPager *pager)
17 {
18- GdkPixmap *pixmap;
19 OsPagerPrivate *priv;
20+ GtkStyle *style;
21
22 priv = OS_PAGER_GET_PRIVATE (pager);
23
24- pixmap = gdk_pixmap_new (NULL, priv->allocation.width,
25- priv->allocation.height, 24);
26- os_pager_draw_pixmap (pixmap, priv->active);
27-
28- gdk_window_set_back_pixmap (priv->pager_window, pixmap, FALSE);
29+ style = gtk_widget_get_style (priv->parent);
30+
31+ gdk_window_set_background (priv->pager_window,
32+ priv->active ? &style->base[GTK_STATE_SELECTED] :
33+ &style->base[GTK_STATE_INSENSITIVE]);
34+
35 gdk_window_clear (priv->pager_window);
36 }
37
38@@ -112,23 +112,25 @@
39
40 priv = OS_PAGER_GET_PRIVATE (pager);
41
42- bitmap = gdk_pixmap_new (NULL, priv->allocation.width,
43- priv->allocation.height, 1);
44- os_pager_draw_bitmap (bitmap, priv->mask);
45-
46- gdk_window_shape_combine_mask (priv->pager_window, bitmap, 0, 0);
47+ bitmap = gdk_pixmap_new (NULL, MAX (1, priv->mask.width),
48+ MAX (1, priv->mask.height), 1);
49+ os_pager_draw_bitmap (bitmap);
50+
51+ gdk_window_shape_combine_mask (priv->pager_window, bitmap,
52+ priv->mask.x, priv->mask.y);
53+
54+ g_object_unref (bitmap);
55 }
56
57 /* Draw on the bitmap of the pager, to get a mask. */
58 static void
59-os_pager_draw_bitmap (GdkBitmap *bitmap,
60- GdkRectangle mask)
61+os_pager_draw_bitmap (GdkBitmap *bitmap)
62 {
63 cairo_t *cr_surface;
64 cairo_surface_t *surface;
65 gint width, height;
66
67- gdk_drawable_get_size (bitmap, &width, &height);
68+ gdk_pixmap_get_size (bitmap, &width, &height);
69
70 surface = cairo_xlib_surface_create_for_bitmap
71 (GDK_DRAWABLE_XDISPLAY (bitmap), gdk_x11_drawable_get_xid (bitmap),
72@@ -136,42 +138,11 @@
73
74 cr_surface = cairo_create (surface);
75
76- cairo_set_operator (cr_surface, CAIRO_OPERATOR_CLEAR);
77- cairo_paint (cr_surface);
78-
79- cairo_set_operator (cr_surface, CAIRO_OPERATOR_OVER);
80- cairo_rectangle (cr_surface, mask.x, mask.y, mask.width, mask.height);
81- cairo_set_source_rgb (cr_surface, 1.0, 1.0, 1.0);
82- cairo_fill (cr_surface);
83-
84- cairo_destroy (cr_surface);
85-}
86-
87-/* Draw on the pixmap of the pager, the real drawing. */
88-static void
89-os_pager_draw_pixmap (GdkPixmap *pixmap,
90- gboolean active)
91-{
92- cairo_t *cr_surface;
93- cairo_surface_t *surface;
94- gint width, height;
95-
96- gdk_drawable_get_size (pixmap, &width, &height);
97-
98- surface = cairo_xlib_surface_create
99- (GDK_DRAWABLE_XDISPLAY (pixmap), gdk_x11_drawable_get_xid (pixmap),
100- GDK_VISUAL_XVISUAL (gdk_drawable_get_visual (pixmap)), width, height);
101-
102- cr_surface = cairo_create (surface);
103-
104- if (active)
105- cairo_set_source_rgb (cr_surface, 240.0 / 255.0, 119.0 / 255.0, 70.0 / 255.0);
106- else
107- cairo_set_source_rgb (cr_surface, 0.85, 0.85, 0.85);
108-
109- cairo_paint (cr_surface);
110-
111- cairo_destroy (cr_surface);
112+ cairo_paint (cr_surface);
113+
114+ cairo_destroy (cr_surface);
115+
116+ cairo_surface_destroy (surface);
117 }
118
119 /* Type definition. */
120@@ -192,7 +163,7 @@
121 static void
122 os_pager_init (OsPager *pager)
123 {
124- GdkRectangle allocation;
125+ GdkRectangle allocation, mask;
126 OsPagerPrivate *priv;
127
128 priv = OS_PAGER_GET_PRIVATE (pager);
129@@ -204,7 +175,14 @@
130
131 priv->allocation = allocation;
132
133- priv->active = TRUE;
134+ mask.x = 0;
135+ mask.y = 0;
136+ mask.width = 1;
137+ mask.height = 1;
138+
139+ priv->mask = mask;
140+
141+ priv->active = FALSE;
142 priv->visible = FALSE;
143 }
144
145
146=== modified file 'os/os-scrollbar.c'
147--- os/os-scrollbar.c 2011-03-08 15:02:30 +0000
148+++ os/os-scrollbar.c 2011-03-09 16:19:25 +0000
149@@ -62,9 +62,9 @@
150 gboolean enter_notify_event;
151 gboolean motion_notify_event;
152 gboolean value_changed_event;
153- gboolean toplevel_connected;
154 gboolean fullsize;
155 gboolean proximity;
156+ gboolean filter;
157 gboolean can_hide;
158 gboolean can_rgba;
159 gint win_x;
160@@ -100,7 +100,6 @@
161 static void os_scrollbar_swap_adjustment (OsScrollbar *scrollbar, GtkAdjustment *adjustment);
162 static void os_scrollbar_swap_parent (OsScrollbar *scrollbar, GtkWidget *parent);
163 static void os_scrollbar_swap_thumb (OsScrollbar *scrollbar, GtkWidget *thumb);
164-static void os_scrollbar_toplevel_connect (OsScrollbar *scrollbar);
165 static gboolean thumb_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
166 static gboolean thumb_button_release_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
167 static gboolean thumb_enter_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data);
168@@ -108,11 +107,12 @@
169 static gboolean thumb_motion_notify_event_cb (GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
170 static void pager_move (OsScrollbar *scrollbar);
171 static void pager_set_allocation (OsScrollbar *scrollbar);
172+static void pager_set_state (OsScrollbar *scrollbar);
173 static void adjustment_changed_cb (GtkAdjustment *adjustment, gpointer user_data);
174 static void adjustment_value_changed_cb (GtkAdjustment *adjustment, gpointer user_data);
175-static gboolean parent_expose_event_cb (GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
176 static void parent_realize_cb (GtkWidget *widget, gpointer user_data);
177 static void parent_size_allocate_cb (GtkWidget *widget, GtkAllocation *allocation, gpointer user_data);
178+static void parent_unrealize_cb (GtkWidget *widget, gpointer user_data);
179 static gboolean toplevel_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, gpointer user_data);
180 static GdkFilterReturn toplevel_filter_func (GdkXEvent *gdkxevent, GdkEvent *event, gpointer user_data);
181 static gboolean toplevel_leave_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data);
182@@ -551,11 +551,11 @@
183 if (priv->parent != NULL)
184 {
185 g_signal_handlers_disconnect_by_func (G_OBJECT (priv->parent),
186- G_CALLBACK (parent_expose_event_cb), scrollbar);
187- g_signal_handlers_disconnect_by_func (G_OBJECT (priv->parent),
188 G_CALLBACK (parent_realize_cb), scrollbar);
189 g_signal_handlers_disconnect_by_func (G_OBJECT (priv->parent),
190 G_CALLBACK (parent_size_allocate_cb), scrollbar);
191+ g_signal_handlers_disconnect_by_func (G_OBJECT (priv->parent),
192+ G_CALLBACK (parent_unrealize_cb), scrollbar);
193
194 g_object_unref (priv->parent);
195 }
196@@ -566,12 +566,12 @@
197 {
198 g_object_ref_sink (priv->parent);
199
200- g_signal_connect (G_OBJECT (priv->parent), "expose-event",
201- G_CALLBACK (parent_expose_event_cb), scrollbar);
202 g_signal_connect (G_OBJECT (priv->parent), "realize",
203 G_CALLBACK (parent_realize_cb), scrollbar);
204 g_signal_connect (G_OBJECT (priv->parent), "size-allocate",
205 G_CALLBACK (parent_size_allocate_cb), scrollbar);
206+ g_signal_connect (G_OBJECT (priv->parent), "unrealize",
207+ G_CALLBACK (parent_unrealize_cb), scrollbar);
208 }
209 }
210
211@@ -617,35 +617,6 @@
212 }
213 }
214
215-/* Create elements. */
216-/* FIXME(Cimi): Needs to be improved. */
217-static void
218-os_scrollbar_toplevel_connect (OsScrollbar *scrollbar)
219-{
220- OsScrollbarPrivate *priv;
221- gint x_pos, y_pos;
222-
223- priv = OS_SCROLLBAR_GET_PRIVATE (OS_SCROLLBAR (scrollbar));
224-
225- g_return_if_fail (priv->parent != NULL);
226- g_return_if_fail (GDK_IS_WINDOW (gtk_widget_get_window (priv->parent)));
227-
228- gdk_window_add_filter (gtk_widget_get_window (priv->parent), toplevel_filter_func, scrollbar);
229- g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (priv->parent)), "configure-event",
230- G_CALLBACK (toplevel_configure_event_cb), scrollbar);
231- g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (priv->parent)), "leave-notify-event",
232- G_CALLBACK (toplevel_leave_notify_event_cb), scrollbar);
233- priv->toplevel_connected = TRUE;
234-
235- gdk_window_get_position (gtk_widget_get_window (priv->parent), &x_pos, &y_pos);
236-
237- os_scrollbar_calc_layout_pager (scrollbar, priv->adjustment->value);
238-
239- os_scrollbar_move_thumb (scrollbar, x_pos + priv->thumb_all.x, y_pos + priv->thumb_all.y);
240-
241- os_scrollbar_store_window_position (scrollbar);
242-}
243-
244 static gboolean
245 thumb_button_press_event_cb (GtkWidget *widget,
246 GdkEventButton *event,
247@@ -928,6 +899,20 @@
248 }
249
250 static void
251+pager_set_state (OsScrollbar *scrollbar)
252+{
253+ OsScrollbarPrivate *priv;
254+
255+ priv = OS_SCROLLBAR_GET_PRIVATE (scrollbar);
256+
257+ if (gdk_screen_get_active_window (gtk_widget_get_screen (priv->parent)) !=
258+ gtk_widget_get_window (priv->parent))
259+ os_pager_set_active (OS_PAGER (priv->pager), FALSE);
260+ else
261+ os_pager_set_active (OS_PAGER (priv->pager), TRUE);
262+}
263+
264+static void
265 adjustment_changed_cb (GtkAdjustment *adjustment,
266 gpointer user_data)
267 {
268@@ -976,25 +961,6 @@
269 pager_move (scrollbar);
270 }
271
272-static gboolean
273-parent_expose_event_cb (GtkWidget *widget,
274- GdkEventExpose *event,
275- gpointer user_data)
276-{
277- OsScrollbar *scrollbar;
278- OsScrollbarPrivate *priv;
279-
280- scrollbar = OS_SCROLLBAR (user_data);
281- priv = OS_SCROLLBAR_GET_PRIVATE (scrollbar);
282-
283- if (!priv->toplevel_connected)
284- {
285- os_scrollbar_toplevel_connect (scrollbar);
286- }
287-
288- return FALSE;
289-}
290-
291 static void
292 parent_realize_cb (GtkWidget *widget,
293 gpointer user_data)
294@@ -1005,6 +971,19 @@
295 scrollbar = OS_SCROLLBAR (user_data);
296 priv = OS_SCROLLBAR_GET_PRIVATE (scrollbar);
297
298+ if (priv->filter == FALSE && priv->proximity == TRUE)
299+ {
300+ priv->filter = TRUE;
301+ gdk_window_add_filter (gtk_widget_get_window (priv->parent), toplevel_filter_func, scrollbar);
302+ }
303+
304+ g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (priv->parent)), "configure-event",
305+ G_CALLBACK (toplevel_configure_event_cb), scrollbar);
306+ g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (priv->parent)), "leave-notify-event",
307+ G_CALLBACK (toplevel_leave_notify_event_cb), scrollbar);
308+
309+ os_scrollbar_calc_layout_pager (scrollbar, priv->adjustment->value);
310+
311 os_pager_set_parent (OS_PAGER (priv->pager), priv->parent);
312 }
313
314@@ -1045,12 +1024,36 @@
315 if (priv->adjustment != NULL)
316 os_scrollbar_calc_layout_pager (scrollbar, priv->adjustment->value);
317
318- if (priv->pager != NULL)
319- pager_set_allocation (scrollbar);
320+ pager_set_allocation (scrollbar);
321
322 os_scrollbar_store_window_position (scrollbar);
323 }
324
325+static void
326+parent_unrealize_cb (GtkWidget *widget,
327+ gpointer user_data)
328+{
329+ OsScrollbar *scrollbar;
330+ OsScrollbarPrivate *priv;
331+
332+ scrollbar = OS_SCROLLBAR (user_data);
333+ priv = OS_SCROLLBAR_GET_PRIVATE (scrollbar);
334+
335+ /* FIXME(Cimi) check if
336+ * gtk_widget_get_window (priv->parent) and
337+ * gtk_widget_get_toplevel (priv->parent))
338+ * are ready to use, otherwise we might need to store them in priv */
339+
340+ gdk_window_remove_filter (gtk_widget_get_window (priv->parent), toplevel_filter_func, scrollbar);
341+
342+ g_signal_handlers_disconnect_by_func (G_OBJECT (gtk_widget_get_toplevel (priv->parent)),
343+ G_CALLBACK (toplevel_configure_event_cb), scrollbar);
344+ g_signal_handlers_disconnect_by_func (G_OBJECT (gtk_widget_get_toplevel (priv->parent)),
345+ G_CALLBACK (toplevel_leave_notify_event_cb), scrollbar);
346+
347+ os_pager_set_parent (OS_PAGER (priv->pager), NULL);
348+}
349+
350 static gboolean
351 toplevel_configure_event_cb (GtkWidget *widget,
352 GdkEventConfigure *event,
353@@ -1099,7 +1102,7 @@
354 g_return_val_if_fail (priv->pager != NULL, GDK_FILTER_CONTINUE);
355 g_return_val_if_fail (priv->thumb != NULL, GDK_FILTER_CONTINUE);
356
357- if (priv->proximity && !priv->fullsize)
358+ if (!priv->fullsize)
359 {
360 /* get the motion_notify_event trough XEvent */
361 if (xevent->type == MotionNotify)
362@@ -1185,20 +1188,14 @@
363 }
364 else
365 {
366- os_pager_hide (OS_PAGER (priv->pager));
367+ return GDK_FILTER_CONTINUE;
368 }
369
370 /* code to check if the window is active */
371 if (xevent->type == PropertyNotify)
372 {
373- GdkScreen *screen;
374- GdkWindow *active_window;
375-
376- screen = gtk_widget_get_screen (priv->parent);
377-
378- active_window = gdk_screen_get_active_window (screen);
379-
380- if (active_window != gtk_widget_get_window (priv->parent))
381+ if (gdk_screen_get_active_window (gtk_widget_get_screen (priv->parent)) !=
382+ gtk_widget_get_window (priv->parent))
383 {
384 gtk_widget_hide (GTK_WIDGET (priv->thumb));
385 os_pager_set_active (OS_PAGER (priv->pager), FALSE);
386@@ -1267,6 +1264,7 @@
387 priv->can_rgba = FALSE;
388 priv->fullsize = FALSE;
389 priv->proximity = FALSE;
390+ priv->filter = FALSE;
391
392 priv->pager = os_pager_new ();
393
394@@ -1325,7 +1323,16 @@
395
396 priv->proximity = TRUE;
397
398- os_pager_show (OS_PAGER (priv->pager));
399+ pager_set_state (OS_SCROLLBAR (widget));
400+
401+ if (priv->fullsize == FALSE)
402+ os_pager_show (OS_PAGER (priv->pager));
403+
404+ if (gtk_widget_get_realized (priv->parent) && priv->filter == FALSE)
405+ {
406+ priv->filter = TRUE;
407+ gdk_window_add_filter (gtk_widget_get_window (priv->parent), toplevel_filter_func, OS_SCROLLBAR (widget));
408+ }
409
410 #if 0
411 Display *display;
412@@ -1408,6 +1415,12 @@
413 priv->proximity = FALSE;
414
415 os_pager_hide (OS_PAGER (priv->pager));
416+
417+ if (gtk_widget_get_realized (priv->parent) && priv->filter == TRUE)
418+ {
419+ priv->filter = FALSE;
420+ gdk_window_remove_filter (gtk_widget_get_window (priv->parent), toplevel_filter_func, OS_SCROLLBAR (widget));
421+ }
422 }
423
424 static void

Subscribers

People subscribed via source and target branches