Merge lp:~unity-team/unity/multiple-monitor-support into lp:unity
- multiple-monitor-support
- Merge into trunk
Proposed by
Neil J. Patel
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 539 | ||||
Proposed branch: | lp:~unity-team/unity/multiple-monitor-support | ||||
Merge into: | lp:unity | ||||
Diff against target: |
378 lines (+130/-55) 6 files modified
targets/mutter/Makefile.am (+1/-0) targets/mutter/expose-manager.vala (+22/-15) targets/mutter/main.c (+5/-5) targets/mutter/plugin.vala (+101/-31) targets/mutter/spaces-manager.vala (+1/-1) unity-private/testing/background.vala (+0/-3) |
||||
To merge this branch: | bzr merge lp:~unity-team/unity/multiple-monitor-support | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mirco Müller (community) | Approve | ||
Review via email: mp+35937@code.launchpad.net |
Commit message
Description of the change
This adds some support for multi monitor setups. It basically makes Unity stick to screen 0, which is because it's currently not possible to have a left-edge panel on a monitor that isn't monitor 0.
We can fix that during the natty cycle, but at least this let's you use your other monitors somewhat normally :)
To post a comment you must log in.
Revision history for this message
Mirco Müller (macslow) : | # |
review:
Needs Resubmitting
Revision history for this message
Jason Smith (jassmith) wrote : | # |
+1 looks good
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'targets/mutter/Makefile.am' |
2 | --- targets/mutter/Makefile.am 2010-08-18 13:53:39 +0000 |
3 | +++ targets/mutter/Makefile.am 2010-09-19 17:17:45 +0000 |
4 | @@ -43,6 +43,7 @@ |
5 | --pkg Dbusmenu-Glib-0.2 \ |
6 | --pkg dee-1.0 \ |
7 | --pkg gtk+-2.0 \ |
8 | + --pkg gdk-x11-2.0 \ |
9 | --pkg gee-1.0 \ |
10 | --pkg indicator \ |
11 | --pkg mutter-2.28 \ |
12 | |
13 | === modified file 'targets/mutter/expose-manager.vala' |
14 | --- targets/mutter/expose-manager.vala 2010-08-24 12:02:16 +0000 |
15 | +++ targets/mutter/expose-manager.vala 2010-09-19 17:17:45 +0000 |
16 | @@ -260,12 +260,12 @@ |
17 | private ExposeClone? last_selected_clone = null; |
18 | |
19 | |
20 | - public ExposeManager (Plugin plugin, Launcher.Launcher launcher) |
21 | + public ExposeManager (Plugin owner, Launcher.Launcher launcher) |
22 | { |
23 | this.launcher = launcher; |
24 | - this.owner = plugin; |
25 | + this.owner = owner; |
26 | this.exposed_windows = new List<ExposeClone> (); |
27 | - this.stage = (Clutter.Stage)plugin.get_stage (); |
28 | + this.stage = (Clutter.Stage)owner.get_stage (); |
29 | |
30 | hovered_opacity = 255; |
31 | unhovered_opacity = 255; |
32 | @@ -394,23 +394,23 @@ |
33 | { |
34 | Clutter.Actor last = null; |
35 | |
36 | - int middle_size = (int) (stage.width * 0.8f); |
37 | - int width = (int) stage.width - left_buffer - right_buffer; |
38 | + int middle_size = (int) (owner.primary_monitor.width * 0.8f); |
39 | + int width = (int) owner.primary_monitor.width - left_buffer - right_buffer; |
40 | int slice_width = width / 10; |
41 | |
42 | - int middle_y = (int) stage.height / 2; |
43 | + int middle_y = (int) owner.primary_monitor.height / 2; |
44 | int middle_x = left_buffer + width / 2; |
45 | |
46 | int middle_index = windows.index (active); |
47 | |
48 | - float scale = float.min (1f, (stage.height / 2) / float.max (active.height, active.width)); |
49 | + float scale = float.min (1f, (owner.primary_monitor.height / 2) / float.max (active.height, active.width)); |
50 | scale = 1f; |
51 | |
52 | active.set_anchor_point_from_gravity (Clutter.Gravity.CENTER); |
53 | active.animate (Clutter.AnimationMode.EASE_IN_OUT_SINE, 250, |
54 | "x", (float) middle_x, |
55 | "y", (float) middle_y, |
56 | - "depth", stage.width * -0.7, |
57 | + "depth", owner.primary_monitor.width * -0.7, |
58 | "scale-x", scale, |
59 | "scale-y", scale, |
60 | "rotation-angle-y", 0f); |
61 | @@ -425,13 +425,13 @@ |
62 | actor.set_anchor_point_from_gravity (Clutter.Gravity.CENTER); |
63 | actor.lower (last); |
64 | |
65 | - scale = float.min (1f, (stage.height / 2) / float.max (actor.height, actor.width)); |
66 | + scale = float.min (1f, (owner.primary_monitor.height / 2) / float.max (actor.height, actor.width)); |
67 | scale = 1f; |
68 | |
69 | actor.animate (Clutter.AnimationMode.EASE_IN_OUT_SINE, 250, |
70 | "x", (float) current_x, |
71 | "y", (float) middle_y, |
72 | - "depth", stage.width * -0.7, |
73 | + "depth", owner.primary_monitor.width * -0.7, |
74 | "scale-x", scale, |
75 | "scale-y", scale, |
76 | "rotation-angle-y", 60f); |
77 | @@ -448,13 +448,13 @@ |
78 | actor.set_anchor_point_from_gravity (Clutter.Gravity.CENTER); |
79 | actor.lower (last); |
80 | |
81 | - scale = float.min (1f, (stage.height / 2) / float.max (actor.height, actor.width)); |
82 | + scale = float.min (1f, (owner.primary_monitor.height / 2) / float.max (actor.height, actor.width)); |
83 | scale = 1f; |
84 | |
85 | actor.animate (Clutter.AnimationMode.EASE_IN_OUT_SINE, 250, |
86 | "x", (float) current_x, |
87 | "y", (float) middle_y, |
88 | - "depth", stage.width * -0.7, |
89 | + "depth", owner.primary_monitor.width * -0.7, |
90 | "scale-x", scale, |
91 | "scale-y", scale, |
92 | "rotation-angle-y", -60f); |
93 | @@ -474,25 +474,32 @@ |
94 | |
95 | public void position_windows_on_grid (List<Clutter.Actor> _windows, int top_buffer, int left_buffer, int right_buffer, int bottom_buffer) |
96 | { |
97 | + if (_windows.length () < 1) |
98 | + { |
99 | + warning ("There are no windows to position on grid"); |
100 | + return; |
101 | + } |
102 | + |
103 | List<Clutter.Actor> windows = _windows.copy (); |
104 | windows.sort ((CompareFunc) direct_comparison); |
105 | |
106 | int count = (int) windows.length (); |
107 | int cols = (int) Math.ceil (Math.sqrt (count)); |
108 | + if (cols < 1) cols = 1; |
109 | int rows = 1; |
110 | |
111 | while (cols * rows < count) |
112 | rows++; |
113 | |
114 | - int boxWidth = (int) ((stage.width - left_buffer - right_buffer) / cols); |
115 | - int boxHeight = (int) ((stage.height - top_buffer - bottom_buffer) / rows); |
116 | + int boxWidth = (int) ((owner.primary_monitor.width - left_buffer - right_buffer) / cols); |
117 | + int boxHeight = (int) ((owner.primary_monitor.height - top_buffer - bottom_buffer) / rows); |
118 | |
119 | for (int row = 0; row < rows; row++) |
120 | { |
121 | if (row == rows - 1) |
122 | { |
123 | /* Last row, time to perform centering as needed */ |
124 | - boxWidth = (int) ((stage.width - left_buffer - right_buffer) / windows.length ()); |
125 | + boxWidth = (int) ((owner.primary_monitor.width - left_buffer - right_buffer) / windows.length ()); |
126 | } |
127 | |
128 | for (int col = 0; col < cols; col++) |
129 | |
130 | === modified file 'targets/mutter/main.c' |
131 | --- targets/mutter/main.c 2010-07-20 13:07:00 +0000 |
132 | +++ targets/mutter/main.c 2010-09-19 17:17:45 +0000 |
133 | @@ -174,16 +174,16 @@ |
134 | rects = g_new (XRectangle, 2); |
135 | |
136 | /* Panel first */ |
137 | - rects[0].x = 0; |
138 | - rects[0].y = 0; |
139 | - rects[0].width = width; |
140 | + rects[0].x = plugin->primary_monitor.x; |
141 | + rects[0].y = plugin->primary_monitor.y; |
142 | + rects[0].width = plugin->primary_monitor.width; |
143 | rects[0].height = unity_plugin_get_panel_height (plugin); |
144 | |
145 | /* Launcher */ |
146 | - rects[1].x = 0; |
147 | + rects[1].x = plugin->primary_monitor.y; |
148 | rects[1].y = rects[0].height; |
149 | rects[1].width = unity_plugin_get_launcher_width (plugin) + 1; |
150 | - rects[1].height = height - rects[0].height; |
151 | + rects[1].height = plugin->primary_monitor.height - rects[0].height; |
152 | |
153 | /* Update region */ |
154 | region = XFixesCreateRegion (xdisplay, rects, 2); |
155 | |
156 | === modified file 'targets/mutter/plugin.vala' |
157 | --- targets/mutter/plugin.vala 2010-09-16 17:37:19 +0000 |
158 | +++ targets/mutter/plugin.vala 2010-09-19 17:17:45 +0000 |
159 | @@ -108,8 +108,7 @@ |
160 | } |
161 | |
162 | public ExposeManager expose_manager { get; private set; } |
163 | - public Background background { get; private set; } |
164 | - |
165 | + |
166 | public bool menus_swallow_events { get { return false; } } |
167 | |
168 | private bool _super_key_active = false; |
169 | @@ -125,6 +124,9 @@ |
170 | private static const int QUICKLAUNCHER_WIDTH = 58; |
171 | private static const string UNDECORATED_HINT = "UNDECORATED_HINT"; |
172 | |
173 | + public Gee.ArrayList<Background> backgrounds; |
174 | + public Gdk.Rectangle primary_monitor; |
175 | + |
176 | private Clutter.Stage stage; |
177 | private Application app; |
178 | private WindowManagement wm; |
179 | @@ -231,6 +233,8 @@ |
180 | this.wm = new WindowManagement (this); |
181 | this.maximus = new Maximus (); |
182 | |
183 | + (Clutter.Stage.get_default () as Clutter.Stage).color = { 0, 0, 0, 255 }; |
184 | + |
185 | END_FUNCTION (); |
186 | } |
187 | |
188 | @@ -286,10 +290,13 @@ |
189 | super_key_modifier_press (keysym); |
190 | }); |
191 | |
192 | - this.background = new Background (); |
193 | - this.stage.add_actor (background); |
194 | - this.background.lower_bottom (); |
195 | - this.background.show (); |
196 | + /* Setup the backgrounds */ |
197 | + unowned Gdk.Screen screen = Gdk.Screen.get_default (); |
198 | + backgrounds = new Gee.ArrayList<Background> (); |
199 | + |
200 | + /* Connect to interestng signals */ |
201 | + screen.monitors_changed.connect (relayout); |
202 | + screen.size_changed.connect (relayout); |
203 | |
204 | this.launcher = new Launcher.Launcher (this); |
205 | this.launcher.get_view ().opacity = 0; |
206 | @@ -453,41 +460,97 @@ |
207 | } |
208 | } |
209 | |
210 | + private void refresh_n_backgrounds (int n_monitors) |
211 | + { |
212 | + int size = backgrounds.size; |
213 | + |
214 | + if (size == n_monitors) |
215 | + return; |
216 | + else if (size < n_monitors) |
217 | + { |
218 | + for (int i = 0; i < n_monitors - size; i++) |
219 | + { |
220 | + var bg = new Background (); |
221 | + backgrounds.add (bg); |
222 | + stage.add_actor (bg); |
223 | + bg.lower_bottom (); |
224 | + bg.opacity = 0; |
225 | + bg.show (); |
226 | + bg.animate (Clutter.AnimationMode.EASE_IN_QUAD, 2000, |
227 | + "opacity", 255); |
228 | + } |
229 | + } |
230 | + else |
231 | + { |
232 | + for (int i = 0; i < size - n_monitors; i++) |
233 | + { |
234 | + var bg = backgrounds.get (0); |
235 | + if (bg is Clutter.Actor) |
236 | + { |
237 | + backgrounds.remove (bg); |
238 | + stage.remove_actor (bg); |
239 | + } |
240 | + } |
241 | + } |
242 | + } |
243 | private void relayout () |
244 | { |
245 | START_FUNCTION (); |
246 | - float width, height; |
247 | - |
248 | - this.stage.get_size (out width, out height); |
249 | - |
250 | - this.drag_dest.resize (this.QUICKLAUNCHER_WIDTH, |
251 | - (int)height - this.PANEL_HEIGHT); |
252 | - this.drag_dest.move (0, this.PANEL_HEIGHT); |
253 | - |
254 | - this.background.set_size (width, height); |
255 | - this.background.set_position (0, 0); |
256 | + |
257 | + unowned Gdk.Screen screen = Gdk.Screen.get_default (); |
258 | + int x, y, width, height; |
259 | + |
260 | + /* Figure out what should be the right size and location of Unity */ |
261 | + /* FIXME: This needs to always be monitor 0 right now as it doesn't |
262 | + * seem possible to have panels on a vertical edge of a monitor unless |
263 | + * it's the first or last monitor :( |
264 | + */ |
265 | + screen.get_monitor_geometry (0, // Should be screen.get_primary_monitor() |
266 | + out primary_monitor); |
267 | + x = primary_monitor.x; |
268 | + y = primary_monitor.y; |
269 | + width = primary_monitor.width; |
270 | + height = primary_monitor.height; |
271 | + |
272 | + /* The drag-n-drop region */ |
273 | + drag_dest.resize (QUICKLAUNCHER_WIDTH, |
274 | + height - PANEL_HEIGHT); |
275 | + drag_dest.move (x, y + PANEL_HEIGHT); |
276 | + |
277 | + /* We're responsible for painting the backgrounds on all the monitors */ |
278 | + refresh_n_backgrounds (screen.get_n_monitors ()); |
279 | + for (int i = 0; i < screen.get_n_monitors (); i++) |
280 | + { |
281 | + var bg = backgrounds.get (i); |
282 | + if (bg is Background) |
283 | + { |
284 | + Gdk.Rectangle rect; |
285 | + screen.get_monitor_geometry (i, out rect); |
286 | + |
287 | + bg.set_position (rect.x, rect.y); |
288 | + bg.set_size (rect.width, rect.height); |
289 | + } |
290 | + } |
291 | |
292 | this.launcher.get_container ().set_size (this.QUICKLAUNCHER_WIDTH, |
293 | (height-this.PANEL_HEIGHT)); |
294 | - this.launcher.get_container ().set_position (0, this.PANEL_HEIGHT); |
295 | + this.launcher.get_container ().set_position (x, y + this.PANEL_HEIGHT); |
296 | this.launcher.get_container ().set_clip (0, 0, |
297 | this.QUICKLAUNCHER_WIDTH, |
298 | height-this.PANEL_HEIGHT); |
299 | + |
300 | Utils.set_strut ((Gtk.Window)this.drag_dest, |
301 | - this.QUICKLAUNCHER_WIDTH, 0, (uint32)height, |
302 | - PANEL_HEIGHT, 0, (uint32)width); |
303 | + this.QUICKLAUNCHER_WIDTH, y, (uint32)height, |
304 | + PANEL_HEIGHT, x, (uint32)width); |
305 | |
306 | this.places.set_size (width - this.QUICKLAUNCHER_WIDTH, height); |
307 | - this.places.set_position (this.QUICKLAUNCHER_WIDTH, 0); |
308 | - |
309 | - this.panel.set_size (width, 24); |
310 | - this.panel.set_position (0, 0); |
311 | - |
312 | - /* Leaving this here to remind me that we need to use these when |
313 | - * there are fullscreen windows etc |
314 | - * this.plugin.set_stage_input_region (uint region); |
315 | - * this.plugin.set_stage_reactive (true); |
316 | - */ |
317 | + this.places.set_position (x + this.QUICKLAUNCHER_WIDTH, y); |
318 | + |
319 | + this.panel.set_size (width, PANEL_HEIGHT); |
320 | + this.panel.set_position (x, y); |
321 | + |
322 | + ensure_input_region (); |
323 | + |
324 | END_FUNCTION (); |
325 | } |
326 | |
327 | @@ -686,8 +749,8 @@ |
328 | (this.plugin.get_window_group () as Clutter.Container).add_actor (this.dark_box); |
329 | this.dark_box.raise (plugin.get_normal_window_group ()); |
330 | |
331 | - this.dark_box.set_position (0, 0); |
332 | - this.dark_box.set_size (this.stage.width, this.stage.height); |
333 | + this.dark_box.set_position (primary_monitor.x, primary_monitor.y); |
334 | + this.dark_box.set_size (primary_monitor.width, primary_monitor.height); |
335 | |
336 | this.dark_box.show (); |
337 | |
338 | @@ -1426,6 +1489,13 @@ |
339 | return false; |
340 | }); |
341 | } |
342 | + else if (window.get_window_type () == Mutter.MetaCompWindowType.DOCK) |
343 | + { |
344 | + if (win.get_xwindow (win) == Gdk.x11_drawable_get_xid (drag_dest.window)) |
345 | + { |
346 | + window.opacity = 0; |
347 | + } |
348 | + } |
349 | |
350 | this.maximus.process_window (window); |
351 | this.window_mapped (this, window); |
352 | |
353 | === modified file 'targets/mutter/spaces-manager.vala' |
354 | --- targets/mutter/spaces-manager.vala 2010-08-26 17:08:21 +0000 |
355 | +++ targets/mutter/spaces-manager.vala 2010-09-19 17:17:45 +0000 |
356 | @@ -370,7 +370,7 @@ |
357 | } |
358 | } |
359 | |
360 | - ExposeClone background_clone = new ExposeClone (plugin.background); |
361 | + ExposeClone background_clone = new ExposeClone (plugin.backgrounds.get (0)); |
362 | background_clone.fade_on_close = false; |
363 | |
364 | wsp.add_actor (background_clone); |
365 | |
366 | === modified file 'unity-private/testing/background.vala' |
367 | --- unity-private/testing/background.vala 2010-08-26 15:14:33 +0000 |
368 | +++ unity-private/testing/background.vala 2010-09-19 17:17:45 +0000 |
369 | @@ -156,9 +156,6 @@ |
370 | this.bg_texture.show (); |
371 | } |
372 | |
373 | - this.x = 0.0f; |
374 | - this.y = 0.0f; |
375 | - |
376 | this.gbg.get_color (out type, out primary, out secondary); |
377 | |
378 | this.bg_texture.set_surface_size ((uint) this.width, |
Code is ok. But I'm missing a way to test it on a real multi-monitor setup (using xrandr).