Merge lp:~cimi/overlay-scrollbar/unity-net-workarea-region into lp:overlay-scrollbar

Proposed by Andrea Cimitan
Status: Merged
Approved by: Ted Gould
Approved revision: 258
Merged at revision: 249
Proposed branch: lp:~cimi/overlay-scrollbar/unity-net-workarea-region
Merge into: lp:overlay-scrollbar
Diff against target: 235 lines (+140/-12)
1 file modified
os/os-scrollbar.c (+140/-12)
To merge this branch: bzr merge lp:~cimi/overlay-scrollbar/unity-net-workarea-region
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Review via email: mp+64331@code.launchpad.net
To post a comment you must log in.
251. By Andrea Cimitan

Cast the two GdkRectangle

252. By Andrea Cimitan

Gets the root window of the proper screen and display

253. By Andrea Cimitan

Added a FIXME

254. By Andrea Cimitan

Now uses the right window on the right screen

255. By Andrea Cimitan

Added a FIXME for the root window on screen-changed

256. By Andrea Cimitan

Added comment to the static function

257. By Andrea Cimitan

Typo

258. By Andrea Cimitan

Removed the FIXME as the screen does not change for a widget in X11

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

You're right in the comment! You should put the clear in the if statement so that it doesn't change unless you're sure you're making it better. If for some reason it failed, it's better to leave it in the default state rather than clearing it.

review: Approve
Revision history for this message
Andrea Cimitan (cimi) wrote :

but in sanitize_x/y, if the region is empty, usage of region is skipped... so again, won't change much if the xgetwindowproperty fail.

basically we have two solutions if xgetwindowproperty fails:
1) the scrollbars won't take into account the struts (like now, because the region is cleared everytime).
2) the scrollbars will use the region calculated before (if the region will be cleared only inside the if statement).

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

Would it make things simpler if we just make the default square be the
screensize and then we don't have to detect if it's empty?

Revision history for this message
Andrea Cimitan (cimi) wrote :

it's exactly the same ted. the code to clear the region is used just because union is used, so if you don't clear the previous region then you'll obtain a bigger region

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'os/os-scrollbar.c'
2--- os/os-scrollbar.c 2011-06-09 17:12:44 +0000
3+++ os/os-scrollbar.c 2011-06-12 23:49:28 +0000
4@@ -27,6 +27,8 @@
5 #include "os-scrollbar.h"
6 #include "os-private.h"
7 #include <gdk/gdkx.h>
8+#include <X11/Xatom.h>
9+#include <X11/Xutil.h>
10 #include <X11/extensions/XInput2.h>
11 #include "math.h"
12
13@@ -86,7 +88,9 @@
14 };
15
16 static Atom net_active_window_atom = None;
17+static Atom unity_net_workarea_region_atom = None;
18 static GList *os_root_list = NULL;
19+static cairo_region_t *os_workarea = NULL;
20
21 static void swap_adjustment (OsScrollbar *scrollbar, GtkAdjustment *adjustment);
22 static void swap_thumb (OsScrollbar *scrollbar, GtkWidget *thumb);
23@@ -270,6 +274,56 @@
24 }
25 }
26
27+/* calculate the workarea using _UNITY_NET_WORKAREA_REGION */
28+static void
29+calc_workarea (Display *display,
30+ Window root)
31+{
32+ Atom type;
33+ cairo_rectangle_int_t test;
34+ gint result, fmt;
35+ gulong nitems, nleft;
36+ guchar *property_data;
37+ gulong *long_data;
38+ guint i;
39+
40+ result = XGetWindowProperty (display, root,
41+ unity_net_workarea_region_atom,
42+ 0L, 4096L, FALSE, XA_CARDINAL,
43+ &type, &fmt, &nitems, &nleft, &property_data);
44+
45+ /* clear the os_workarea region,
46+ * before the union with the new rectangles.
47+ * Maybe it'd be better to place this call
48+ * inside the if statement below. */
49+ cairo_region_subtract (os_workarea, os_workarea);
50+
51+ if (result == Success && property_data)
52+ {
53+ long_data = (gulong*) property_data;
54+
55+ if (fmt == 32 && type == XA_CARDINAL && nitems % 4 == 0)
56+ {
57+ int count;
58+ unsigned int i;
59+
60+ count = nitems / 4;
61+
62+ for (i = 0; i < count; i++)
63+ {
64+ cairo_rectangle_int_t rect;
65+
66+ rect.x = long_data[i * 4 + 0];
67+ rect.y = long_data[i * 4 + 1];
68+ rect.width = long_data[i * 4 + 2];
69+ rect.height = long_data[i * 4 + 3];
70+
71+ cairo_region_union_rectangle (os_workarea, &rect);
72+ }
73+ }
74+ }
75+}
76+
77 /* deactivate the pager if it's the case */
78 static void
79 deactivate_pager (OsScrollbar *scrollbar)
80@@ -364,7 +418,7 @@
81 gint x,
82 gint y)
83 {
84- GdkRectangle rect;
85+ cairo_rectangle_int_t rect;
86 OsScrollbarPrivate *priv;
87 gint screen_width, n_monitor;
88 GdkScreen *screen;
89@@ -375,9 +429,37 @@
90 * to calculate monitor boundaries. */
91 screen = gtk_widget_get_screen (GTK_WIDGET (scrollbar));
92 n_monitor = gdk_screen_get_monitor_at_point (screen, x - 1, y);
93- gdk_screen_get_monitor_geometry (screen, n_monitor, &rect);
94-
95- screen_width = rect.x + rect.width;
96+ gdk_screen_get_monitor_geometry (screen, n_monitor, (GdkRectangle*) &rect);
97+
98+ if (cairo_region_is_empty (os_workarea))
99+ screen_width = rect.x + rect.width;
100+ else
101+ {
102+ cairo_region_t *monitor_workarea;
103+ cairo_rectangle_int_t tmp_rect;
104+ gint i, x, width;
105+
106+ x = rect.x;
107+ width = rect.width;
108+
109+ monitor_workarea = cairo_region_create_rectangle (&rect);
110+
111+ cairo_region_intersect (monitor_workarea, os_workarea);
112+
113+ for (i = 0; i < cairo_region_num_rectangles (monitor_workarea); i++)
114+ {
115+ cairo_region_get_rectangle (monitor_workarea, i, &tmp_rect);
116+
117+ if (tmp_rect.x > x)
118+ x = tmp_rect.x;
119+ if (tmp_rect.x + tmp_rect.width < width)
120+ width = tmp_rect.x + tmp_rect.width;
121+ }
122+
123+ screen_width = x + width;
124+
125+ cairo_region_destroy (monitor_workarea);
126+ }
127
128 if (priv->orientation == GTK_ORIENTATION_VERTICAL &&
129 (n_monitor != gdk_screen_get_monitor_at_point (screen, x - 1 + priv->slider.width, y) ||
130@@ -399,7 +481,7 @@
131 gint x,
132 gint y)
133 {
134- GdkRectangle rect;
135+ cairo_rectangle_int_t rect;
136 OsScrollbarPrivate *priv;
137 gint screen_height, n_monitor;
138 GdkScreen *screen;
139@@ -410,9 +492,37 @@
140 * to calculate monitor boundaries. */
141 screen = gtk_widget_get_screen (GTK_WIDGET (scrollbar));
142 n_monitor = gdk_screen_get_monitor_at_point (screen, x, y - 1);
143- gdk_screen_get_monitor_geometry (screen, n_monitor, &rect);
144-
145- screen_height = rect.y + rect.height;
146+ gdk_screen_get_monitor_geometry (screen, n_monitor, (GdkRectangle*) &rect);
147+
148+ if (cairo_region_is_empty (os_workarea))
149+ screen_height = rect.y + rect.height;
150+ else
151+ {
152+ cairo_region_t *monitor_workarea;
153+ cairo_rectangle_int_t tmp_rect;
154+ gint i, y, height;
155+
156+ y = rect.y;
157+ height = rect.height;
158+
159+ monitor_workarea = cairo_region_create_rectangle (&rect);
160+
161+ cairo_region_intersect (monitor_workarea, os_workarea);
162+
163+ for (i = 0; i < cairo_region_num_rectangles (monitor_workarea); i++)
164+ {
165+ cairo_region_get_rectangle (monitor_workarea, i, &tmp_rect);
166+
167+ if (tmp_rect.y > y)
168+ y = tmp_rect.y;
169+ if (tmp_rect.y + tmp_rect.height < height)
170+ height = tmp_rect.y + tmp_rect.height;
171+ }
172+
173+ screen_height = y + height;
174+
175+ cairo_region_destroy (monitor_workarea);
176+ }
177
178 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
179 (n_monitor != gdk_screen_get_monitor_at_point (screen, x, y - 1 + priv->slider.height) ||
180@@ -847,10 +957,16 @@
181
182 xev = gdkxevent;
183
184- if (xev->xany.type == PropertyNotify &&
185- xev->xproperty.atom == net_active_window_atom)
186+ if (xev->type == PropertyNotify)
187 {
188- g_list_foreach (os_root_list, root_gfunc, NULL);
189+ if (xev->xproperty.atom == net_active_window_atom)
190+ {
191+ g_list_foreach (os_root_list, root_gfunc, NULL);
192+ }
193+ else if (xev->xproperty.atom == unity_net_workarea_region_atom)
194+ {
195+ calc_workarea (xev->xany.display, xev->xany.window);
196+ }
197 }
198
199 return GDK_FILTER_CONTINUE;
200@@ -1997,16 +2113,22 @@
201
202 if (os_root_list == NULL)
203 {
204+ GdkScreen *screen;
205 GdkWindow *root;
206
207 /* used in the root_filter_func to match the right property. */
208 net_active_window_atom = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW");
209+ unity_net_workarea_region_atom = gdk_x11_get_xatom_by_name ("_UNITY_NET_WORKAREA_REGION");
210
211 /* append the object to the static linked list. */
212 os_root_list = g_list_append (os_root_list, scrollbar);
213
214+ /* create the region. */
215+ os_workarea = cairo_region_create ();
216+
217 /* apply the root_filter_func. */
218- root = gdk_get_default_root_window ();
219+ screen = gtk_widget_get_screen (GTK_WIDGET (scrollbar));
220+ root = gdk_screen_get_root_window (screen);
221 gdk_window_set_events (root, gdk_window_get_events (root) |
222 GDK_PROPERTY_CHANGE_MASK);
223 gdk_window_add_filter (root, root_filter_func, NULL);
224@@ -2091,6 +2213,12 @@
225 priv->window_group = NULL;
226 }
227
228+ if (os_workarea != NULL)
229+ {
230+ cairo_region_destroy (os_workarea);
231+ os_workarea = NULL;
232+ }
233+
234 swap_adjustment (scrollbar, NULL);
235 swap_thumb (scrollbar, NULL);
236

Subscribers

People subscribed via source and target branches