1 From 69e85305f2d455c8943514edde215ce69791076a Mon Sep 17 00:00:00 2001
2 From: Kristian Rietveld <kris@lanedo.com>
3 Date: Sun, 2 Sep 2012 21:21:51 +0200
4 Subject: [PATCH 20/68] Introduce a background window
6 The background window covers the part left uncovered by the overshoot
7 window. Two background windows are used to be able to cover an "L shape"
8 that appears when is scrolled in the horizontal and vertical direction
9 at the same time. These background windows are used to capture events,
10 such as scroll events. In the future, it could also be used to draw a
11 specific background pattern/gradient (if the window is configured as
14 gtk/gtkscrolledwindow.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++
15 1 file changed, 104 insertions(+)
17 diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
18 index 02745b1..9d0d87a 100644
19 --- a/gtk/gtkscrolledwindow.c
20 +++ b/gtk/gtkscrolledwindow.c
21 @@ -95,6 +95,8 @@ typedef struct {
22 /* Kinetic scrolling */
23 GdkEvent *button_press_event;
24 GdkWindow *overshoot_window;
25 + GdkWindow *vbackground_window;
26 + GdkWindow *hbackground_window;
27 guint pointer_grabbed : 1;
28 guint kinetic_scrolling : 1;
29 guint capture_button_press : 1;
30 @@ -1481,6 +1483,8 @@ gtk_scrolled_window_expose (GtkWidget *widget,
31 vscrollbar_window = gtk_widget_get_window (scrolled_window->vscrollbar);
33 if (event->window == priv->overshoot_window ||
34 + event->window == priv->vbackground_window ||
35 + event->window == priv->hbackground_window ||
36 event->window == hscrollbar_window ||
37 event->window == vscrollbar_window)
38 GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->expose_event (widget, event);
39 @@ -1871,6 +1875,7 @@ _gtk_scrolled_window_allocate_overshoot_window (GtkScrolledWindow *scrolled_wind
40 _gtk_scrolled_window_get_overshoot (scrolled_window,
41 &overshoot_x, &overshoot_y);
43 + /* Overshoot window */
44 window_allocation = relative_allocation;
45 window_allocation.x += allocation.x;
46 window_allocation.y += allocation.y;
47 @@ -1887,6 +1892,46 @@ _gtk_scrolled_window_allocate_overshoot_window (GtkScrolledWindow *scrolled_wind
48 gdk_window_move_resize (priv->overshoot_window,
49 window_allocation.x, window_allocation.y,
50 window_allocation.width, window_allocation.height);
52 + /* Vertical background window */
53 + window_allocation = relative_allocation;
54 + window_allocation.x += allocation.x;
55 + window_allocation.y += allocation.y;
57 + if (ABS (overshoot_x) > 0)
59 + window_allocation.width = ABS (overshoot_x);
60 + if (overshoot_x > 0)
61 + window_allocation.x += relative_allocation.width - overshoot_x;
63 + gdk_window_move_resize (priv->vbackground_window,
64 + window_allocation.x, window_allocation.y,
65 + window_allocation.width,
66 + window_allocation.height);
67 + gdk_window_show (priv->vbackground_window);
70 + gdk_window_hide (priv->vbackground_window);
72 + /* Horizontal background window */
73 + window_allocation = relative_allocation;
74 + window_allocation.x += allocation.x;
75 + window_allocation.y += allocation.y;
77 + if (ABS (overshoot_y) > 0)
79 + window_allocation.height = ABS (overshoot_y);
80 + if (overshoot_y > 0)
81 + window_allocation.y += relative_allocation.height - overshoot_y;
83 + gdk_window_move_resize (priv->hbackground_window,
84 + window_allocation.x, window_allocation.y,
85 + window_allocation.width,
86 + window_allocation.height);
87 + gdk_window_show (priv->hbackground_window);
90 + gdk_window_hide (priv->hbackground_window);
94 @@ -3259,6 +3304,7 @@ gtk_scrolled_window_realize (GtkWidget *widget)
95 gtk_widget_get_allocation (widget, &allocation);
96 gtk_scrolled_window_relative_allocation (widget, &relative_allocation);
98 + /* Overshoot window */
99 attributes.window_type = GDK_WINDOW_CHILD;
100 attributes.x = allocation.x + relative_allocation.x;
101 attributes.y = allocation.y + relative_allocation.y;
102 @@ -3277,6 +3323,45 @@ gtk_scrolled_window_realize (GtkWidget *widget)
104 gdk_window_set_user_data (priv->overshoot_window, widget);
106 + /* Vertical background window */
107 + attributes.window_type = GDK_WINDOW_CHILD;
108 + attributes.x = allocation.x + relative_allocation.x;
109 + attributes.y = allocation.y + relative_allocation.y;
110 + attributes.width = 0;
111 + attributes.height = 0;
112 + attributes.wclass = GDK_INPUT_ONLY;
113 + attributes.visual = gtk_widget_get_visual (widget);
114 + attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK |
115 + GDK_BUTTON_MOTION_MASK | GDK_SCROLL_MASK;
117 + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
119 + priv->vbackground_window =
120 + gdk_window_new (gtk_widget_get_parent_window (widget),
121 + &attributes, attributes_mask);
123 + gdk_window_set_user_data (priv->vbackground_window, widget);
125 + /* Horizontal background window */
126 + attributes.window_type = GDK_WINDOW_CHILD;
127 + attributes.x = allocation.x + relative_allocation.x;
128 + attributes.y = allocation.y + relative_allocation.y;
129 + attributes.width = 0;
130 + attributes.height = 0;
131 + attributes.wclass = GDK_INPUT_ONLY;
132 + attributes.visual = gtk_widget_get_visual (widget);
133 + attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK |
134 + GDK_BUTTON_MOTION_MASK | GDK_SCROLL_MASK;
136 + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
138 + priv->hbackground_window =
139 + gdk_window_new (gtk_widget_get_parent_window (widget),
140 + &attributes, attributes_mask);
142 + gdk_window_set_user_data (priv->hbackground_window, widget);
145 child_widget = gtk_bin_get_child (GTK_BIN (widget));
148 @@ -3296,6 +3381,14 @@ gtk_scrolled_window_unrealize (GtkWidget *widget)
149 gdk_window_destroy (priv->overshoot_window);
150 priv->overshoot_window = NULL;
152 + gdk_window_set_user_data (priv->vbackground_window, NULL);
153 + gdk_window_destroy (priv->vbackground_window);
154 + priv->vbackground_window = NULL;
156 + gdk_window_set_user_data (priv->hbackground_window, NULL);
157 + gdk_window_destroy (priv->hbackground_window);
158 + priv->hbackground_window = NULL;
160 gtk_widget_set_realized (widget, FALSE);
162 GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->unrealize (widget);
163 @@ -3308,6 +3401,15 @@ gtk_scrolled_window_map (GtkWidget *widget)
164 GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
166 gdk_window_show (priv->overshoot_window);
167 + if (gdk_window_get_width (priv->vbackground_window) > 1)
168 + gdk_window_show (priv->vbackground_window);
170 + gdk_window_hide (priv->vbackground_window);
172 + if (gdk_window_get_height (priv->hbackground_window) > 1)
173 + gdk_window_show (priv->hbackground_window);
175 + gdk_window_hide (priv->hbackground_window);
177 GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->map (widget);
179 @@ -3319,6 +3421,8 @@ gtk_scrolled_window_unmap (GtkWidget *widget)
180 GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
182 gdk_window_hide (priv->overshoot_window);
183 + gdk_window_hide (priv->vbackground_window);
184 + gdk_window_hide (priv->hbackground_window);
186 GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->unmap (widget);
189 1.7.10.2 (Apple Git-33)