~ubuntu-branches/ubuntu/trusty/gnome-shell/trusty-proposed

« back to all changes in this revision

Viewing changes to js/ui/workspacesView.js

Tags: upstream-3.3.90
ImportĀ upstreamĀ versionĀ 3.3.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
2
2
 
3
3
const Clutter = imports.gi.Clutter;
 
4
const Gio = imports.gi.Gio;
4
5
const Lang = imports.lang;
5
6
const Mainloop = imports.mainloop;
6
7
const Meta = imports.gi.Meta;
19
20
// Note that mutter has a compile-time limit of 36
20
21
const MAX_WORKSPACES = 16;
21
22
 
 
23
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
22
24
 
23
25
const CONTROLS_POP_IN_TIME = 0.1;
24
26
 
25
27
 
26
 
function WorkspacesView(workspaces) {
27
 
    this._init(workspaces);
28
 
}
 
28
const WorkspacesView = new Lang.Class({
 
29
    Name: 'WorkspacesView',
29
30
 
30
 
WorkspacesView.prototype = {
31
31
    _init: function(workspaces) {
32
32
        this.actor = new St.Group({ style_class: 'workspaces-view' });
33
33
 
42
42
                this._spacing = node.get_length('spacing');
43
43
                this._updateWorkspaceActors(false);
44
44
            }));
45
 
        this.actor.connect('notify::mapped',
46
 
                           Lang.bind(this, this._onMappedChanged));
47
45
 
48
46
        this._width = 0;
49
47
        this._height = 0;
61
59
        this._zoomOut = false; // zoom to a larger area
62
60
        this._inDrag = false; // dragging a window
63
61
 
 
62
        this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
 
63
        this._updateExtraWorkspacesId =
 
64
            this._settings.connect('changed::workspaces-only-on-primary',
 
65
                                   Lang.bind(this, this._updateExtraWorkspaces));
 
66
 
64
67
        let activeWorkspaceIndex = global.screen.get_active_workspace_index();
65
68
        this._workspaces = workspaces;
66
69
 
69
72
            this._workspaces[w].actor.reparent(this.actor);
70
73
        this._workspaces[activeWorkspaceIndex].actor.raise_top();
71
74
 
72
 
        this._extraWorkspaces = [];
73
 
        let monitors = Main.layoutManager.monitors;
74
 
        let m = 0;
75
 
        for (let i = 0; i < monitors.length; i++) {
76
 
            if (i == Main.layoutManager.primaryIndex)
77
 
                continue;
78
 
            let ws = new Workspace.Workspace(null, i);
79
 
            this._extraWorkspaces[m++] = ws;
80
 
            ws.setGeometry(monitors[i].x, monitors[i].y, monitors[i].width, monitors[i].height);
81
 
            global.overlay_group.add_actor(ws.actor);
82
 
        }
 
75
        this._updateExtraWorkspaces();
83
76
 
84
77
        // Position/scale the desktop windows and their children after the
85
78
        // workspaces have been created. This cannot be done first because
90
83
                                 Lang.bind(this, function() {
91
84
                for (let w = 0; w < this._workspaces.length; w++)
92
85
                    this._workspaces[w].zoomToOverview();
 
86
                if (!this._extraWorkspaces)
 
87
                    return;
93
88
                for (let w = 0; w < this._extraWorkspaces.length; w++)
94
89
                    this._extraWorkspaces[w].zoomToOverview();
95
90
        }));
100
95
                                    this._clipWidth, this._clipHeight);
101
96
        }));
102
97
 
103
 
        this._scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
104
 
                                                     lower: 0,
105
 
                                                     page_increment: 1,
106
 
                                                     page_size: 1,
107
 
                                                     step_increment: 0,
108
 
                                                     upper: this._workspaces.length });
109
 
        this._scrollAdjustment.connect('notify::value',
110
 
                                       Lang.bind(this, this._onScroll));
 
98
        this.scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
 
99
                                                    lower: 0,
 
100
                                                    page_increment: 1,
 
101
                                                    page_size: 1,
 
102
                                                    step_increment: 0,
 
103
                                                    upper: this._workspaces.length });
 
104
        this.scrollAdjustment.connect('notify::value',
 
105
                                      Lang.bind(this, this._onScroll));
111
106
 
112
107
        this._switchWorkspaceNotifyId =
113
108
            global.window_manager.connect('switch-workspace',
121
116
                                                        Lang.bind(this, this._dragBegin));
122
117
        this._windowDragEndId = Main.overview.connect('window-drag-end',
123
118
                                                      Lang.bind(this, this._dragEnd));
124
 
        this._swipeScrollBeginId = 0;
125
 
        this._swipeScrollEndId = 0;
 
119
    },
 
120
 
 
121
    _updateExtraWorkspaces: function() {
 
122
        this._destroyExtraWorkspaces();
 
123
 
 
124
        if (!this._settings.get_boolean('workspaces-only-on-primary'))
 
125
            return;
 
126
 
 
127
        this._extraWorkspaces = [];
 
128
        let monitors = Main.layoutManager.monitors;
 
129
        for (let i = 0; i < monitors.length; i++) {
 
130
            if (i == Main.layoutManager.primaryIndex)
 
131
                continue;
 
132
 
 
133
            let ws = new Workspace.Workspace(null, i);
 
134
            ws.setGeometry(monitors[i].x, monitors[i].y,
 
135
                           monitors[i].width, monitors[i].height);
 
136
            global.overlay_group.add_actor(ws.actor);
 
137
            this._extraWorkspaces.push(ws);
 
138
        }
 
139
    },
 
140
 
 
141
    _destroyExtraWorkspaces: function() {
 
142
        if (!this._extraWorkspaces)
 
143
            return;
 
144
 
 
145
        for (let m = 0; m < this._extraWorkspaces.length; m++)
 
146
            this._extraWorkspaces[m].destroy();
 
147
        this._extraWorkspaces = null;
126
148
    },
127
149
 
128
150
    setGeometry: function(x, y, width, height, spacing) {
159
181
        return this._workspaces[active];
160
182
    },
161
183
 
162
 
    getWorkspaceByIndex: function(index) {
163
 
        return this._workspaces[index];
164
 
    },
165
 
 
166
184
    hide: function() {
167
185
        let activeWorkspaceIndex = global.screen.get_active_workspace_index();
168
186
        let activeWorkspace = this._workspaces[activeWorkspaceIndex];
173
191
 
174
192
        for (let w = 0; w < this._workspaces.length; w++)
175
193
            this._workspaces[w].zoomFromOverview();
 
194
        if (!this._extraWorkspaces)
 
195
            return;
176
196
        for (let w = 0; w < this._extraWorkspaces.length; w++)
177
197
            this._extraWorkspaces[w].zoomFromOverview();
178
198
    },
184
204
    syncStacking: function(stackIndices) {
185
205
        for (let i = 0; i < this._workspaces.length; i++)
186
206
            this._workspaces[i].syncStacking(stackIndices);
 
207
        if (!this._extraWorkspaces)
 
208
            return;
187
209
        for (let i = 0; i < this._extraWorkspaces.length; i++)
188
210
            this._extraWorkspaces[i].syncStacking(stackIndices);
189
211
    },
245
267
        for (let w = 0; w < this._workspaces.length; w++) {
246
268
            let workspace = this._workspaces[w];
247
269
            if (this._animating || this._scrolling) {
248
 
                workspace.hideWindowsOverlays();
249
270
                workspace.actor.show();
250
271
            } else {
251
 
                workspace.showWindowsOverlays();
252
272
                if (this._inDrag)
253
273
                    workspace.actor.visible = (Math.abs(w - active) <= 1);
254
274
                else
264
284
        this._animatingScroll = true;
265
285
 
266
286
        if (showAnimation) {
267
 
            Tweener.addTween(this._scrollAdjustment, {
 
287
            Tweener.addTween(this.scrollAdjustment, {
268
288
               value: index,
269
289
               time: WORKSPACE_SWITCH_TIME,
270
290
               transition: 'easeOutQuad',
274
294
                   })
275
295
            });
276
296
        } else {
277
 
            this._scrollAdjustment.value = index;
 
297
            this.scrollAdjustment.value = index;
278
298
            this._animatingScroll = false;
279
299
        }
280
300
    },
282
302
    updateWorkspaces: function(oldNumWorkspaces, newNumWorkspaces) {
283
303
        let active = global.screen.get_active_workspace_index();
284
304
 
285
 
        Tweener.addTween(this._scrollAdjustment,
 
305
        Tweener.addTween(this.scrollAdjustment,
286
306
                         { upper: newNumWorkspaces,
287
307
                           time: WORKSPACE_SWITCH_TIME,
288
308
                           transition: 'easeOutQuad'
309
329
    },
310
330
 
311
331
    _onDestroy: function() {
312
 
        for (let i = 0; i < this._extraWorkspaces.length; i++)
313
 
            this._extraWorkspaces[i].destroy();
314
 
        this._scrollAdjustment.run_dispose();
 
332
        this._destroyExtraWorkspaces();
 
333
        this.scrollAdjustment.run_dispose();
315
334
        Main.overview.disconnect(this._overviewShowingId);
316
335
        Main.overview.disconnect(this._overviewShownId);
317
336
        global.window_manager.disconnect(this._switchWorkspaceNotifyId);
 
337
        this._settings.disconnect(this._updateExtraWorkspacesId);
318
338
 
319
339
        if (this._inDrag)
320
340
            this._dragEnd();
337
357
        }
338
358
    },
339
359
 
340
 
    _onMappedChanged: function() {
341
 
        if (this.actor.mapped) {
342
 
            let direction = Overview.SwipeScrollDirection.VERTICAL;
343
 
            Main.overview.setScrollAdjustment(this._scrollAdjustment,
344
 
                                              direction);
345
 
            this._swipeScrollBeginId = Main.overview.connect('swipe-scroll-begin',
346
 
                                                             Lang.bind(this, this._swipeScrollBegin));
347
 
            this._swipeScrollEndId = Main.overview.connect('swipe-scroll-end',
348
 
                                                           Lang.bind(this, this._swipeScrollEnd));
349
 
        } else {
350
 
            Main.overview.disconnect(this._swipeScrollBeginId);
351
 
            Main.overview.disconnect(this._swipeScrollEndId);
352
 
        }
353
 
    },
354
 
 
355
360
    _dragBegin: function() {
356
361
        if (this._scrolling)
357
362
            return;
373
378
            this._firstDragMotion = false;
374
379
            for (let i = 0; i < this._workspaces.length; i++)
375
380
                this._workspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
 
381
            if (!this._extraWorkspaces)
 
382
                return DND.DragMotionResult.CONTINUE;
 
383
 
376
384
            for (let i = 0; i < this._extraWorkspaces.length; i++)
377
385
                this._extraWorkspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
378
386
        }
386
394
 
387
395
        for (let i = 0; i < this._workspaces.length; i++)
388
396
            this._workspaces[i].setReservedSlot(null);
 
397
 
 
398
        if (!this._extraWorkspaces)
 
399
            return;
389
400
        for (let i = 0; i < this._extraWorkspaces.length; i++)
390
401
            this._extraWorkspaces[i].setReservedSlot(null);
391
402
    },
392
403
 
393
 
    _swipeScrollBegin: function() {
 
404
    startSwipeScroll: function() {
394
405
        this._scrolling = true;
395
406
    },
396
407
 
397
 
    _swipeScrollEnd: function(overview, result) {
 
408
    endSwipeScroll: function(result) {
398
409
        this._scrolling = false;
399
410
 
400
411
        if (result == Overview.SwipeScrollResult.CLICK) {
443
454
        let dy = newY - currentY;
444
455
 
445
456
        for (let i = 0; i < this._workspaces.length; i++) {
446
 
            this._workspaces[i].hideWindowsOverlays();
447
457
            this._workspaces[i].actor.visible = Math.abs(i - adj.value) <= 1;
448
458
            this._workspaces[i].actor.y += dy;
449
459
        }
452
462
    _getWorkspaceIndexToRemove: function() {
453
463
        return global.screen.get_active_workspace_index();
454
464
    }
455
 
};
 
465
});
456
466
Signals.addSignalMethods(WorkspacesView.prototype);
457
467
 
458
468
 
459
 
function WorkspacesDisplay() {
460
 
    this._init();
461
 
}
 
469
const WorkspacesDisplay = new Lang.Class({
 
470
    Name: 'WorkspacesDisplay',
462
471
 
463
 
WorkspacesDisplay.prototype = {
464
472
    _init: function() {
465
473
        this.actor = new Shell.GenericContainer();
466
474
        this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
467
475
        this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
468
476
        this.actor.connect('allocate', Lang.bind(this, this._allocate));
 
477
        this.actor.connect('notify::mapped', Lang.bind(this, this._setupSwipeScrolling));
 
478
        this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
469
479
        this.actor.set_clip_to_allocation(true);
470
480
 
471
481
        let controls = new St.Bin({ style_class: 'workspace-controls',
482
492
        controls.connect('scroll-event',
483
493
                         Lang.bind(this, this._onScrollEvent));
484
494
 
485
 
        this._monitorIndex = Main.layoutManager.primaryIndex;
 
495
        this._primaryIndex = Main.layoutManager.primaryIndex;
486
496
 
487
497
        this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
488
498
        controls.add_actor(this._thumbnailsBox.actor);
489
499
 
490
 
        this.workspacesView = null;
 
500
        this._workspacesViews = null;
 
501
        this._primaryScrollAdjustment = null;
 
502
 
 
503
        this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
 
504
        this._settings.connect('changed::workspaces-only-on-primary',
 
505
                               Lang.bind(this,
 
506
                                         this._workspacesOnlyOnPrimaryChanged));
 
507
        this._workspacesOnlyOnPrimaryChanged();
491
508
 
492
509
        this._inDrag = false;
493
510
        this._cancelledDrag = false;
498
515
 
499
516
        this._updateAlwaysZoom();
500
517
 
 
518
        // If we stop hiding the overview on layout changes, we will need to
 
519
        // update the _workspacesViews here
501
520
        Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateAlwaysZoom));
502
521
 
503
522
        Main.xdndHandler.connect('drag-begin', Lang.bind(this, function(){
518
537
        this._windowDragBeginId = 0;
519
538
        this._windowDragCancelledId = 0;
520
539
        this._windowDragEndId = 0;
 
540
        this._notifyOpacityId = 0;
 
541
        this._swipeScrollBeginId = 0;
 
542
        this._swipeScrollEndId = 0;
521
543
    },
522
544
 
523
545
    show: function() {
528
550
        this._controls.show();
529
551
        this._thumbnailsBox.show();
530
552
 
531
 
        this._workspaces = [];
532
 
        for (let i = 0; i < global.screen.n_workspaces; i++) {
533
 
            let metaWorkspace = global.screen.get_workspace_by_index(i);
534
 
            this._workspaces[i] = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
535
 
        }
536
 
 
537
 
        if (this.workspacesView)
538
 
            this.workspacesView.destroy();
539
 
        this.workspacesView = new WorkspacesView(this._workspaces);
540
 
        this._updateWorkspacesGeometry();
 
553
        this._updateWorkspacesViews();
541
554
 
542
555
        this._restackedNotifyId =
543
556
            global.screen.connect('restacked',
568
581
        this._onRestacked();
569
582
    },
570
583
 
 
584
    zoomFromOverview: function() {
 
585
        for (let i = 0; i < this._workspacesViews.length; i++) {
 
586
            this._workspacesViews[i].hide();
 
587
        }
 
588
    },
 
589
 
571
590
    hide: function() {
572
591
        this._controls.hide();
573
592
        this._thumbnailsBox.hide();
601
620
            this._windowDragEndId = 0;
602
621
        }
603
622
 
604
 
        this.workspacesView.destroy();
605
 
        this.workspacesView = null;
606
 
        for (let w = 0; w < this._workspaces.length; w++) {
607
 
            this._workspaces[w].disconnectAll();
608
 
            this._workspaces[w].destroy();
609
 
        }
 
623
        for (let i = 0; i < this._workspacesViews.length; i++)
 
624
            this._workspacesViews[i].destroy();
 
625
        this._workspacesViews = null;
 
626
 
 
627
        for (let i = 0; i < this._workspaces.length; i++)
 
628
            for (let w = 0; w < this._workspaces[i].length; w++) {
 
629
                this._workspaces[i][w].disconnectAll();
 
630
                this._workspaces[i][w].destroy();
 
631
            }
 
632
    },
 
633
 
 
634
    _setupSwipeScrolling: function() {
 
635
        if (this._swipeScrollBeginId)
 
636
            Main.overview.disconnect(this._swipeScrollBeginId);
 
637
        this._swipeScrollBeginId = 0;
 
638
 
 
639
        if (this._swipeScrollEndId)
 
640
            Main.overview.disconnect(this._swipeScrollEndId);
 
641
        this._swipeScrollEndId = 0;
 
642
 
 
643
        if (!this.actor.mapped)
 
644
            return;
 
645
 
 
646
        let direction = Overview.SwipeScrollDirection.VERTICAL;
 
647
        Main.overview.setScrollAdjustment(this._scrollAdjustment,
 
648
                                          direction);
 
649
        this._swipeScrollBeginId = Main.overview.connect('swipe-scroll-begin',
 
650
            Lang.bind(this, function() {
 
651
                for (let i = 0; i < this._workspacesViews.length; i++)
 
652
                    this._workspacesViews[i].startSwipeScroll();
 
653
            }));
 
654
        this._swipeScrollEndId = Main.overview.connect('swipe-scroll-end',
 
655
           Lang.bind(this, function(overview, result) {
 
656
                for (let i = 0; i < this._workspacesViews.length; i++)
 
657
                    this._workspacesViews[i].endSwipeScroll(result);
 
658
           }));
 
659
    },
 
660
 
 
661
    _workspacesOnlyOnPrimaryChanged: function() {
 
662
        this._workspacesOnlyOnPrimary = this._settings.get_boolean('workspaces-only-on-primary');
 
663
 
 
664
        if (!Main.overview.visible)
 
665
            return;
 
666
 
 
667
        this._updateWorkspacesViews();
 
668
    },
 
669
 
 
670
    _updateWorkspacesViews: function() {
 
671
        if (this._workspacesViews)
 
672
            for (let i = 0; i < this._workspacesViews.length; i++)
 
673
                this._workspacesViews[i].destroy();
 
674
 
 
675
        if (this._workspaces)
 
676
            for (let i = 0; i < this._workspaces.length; i++)
 
677
                for (let w = 0; w < this._workspaces[i].length; w++)
 
678
                    this._workspaces[i][w].destroy();
 
679
 
 
680
        this._workspacesViews = [];
 
681
        this._workspaces = [];
 
682
        let monitors = Main.layoutManager.monitors;
 
683
        for (let i = 0; i < monitors.length; i++) {
 
684
            if (this._workspacesOnlyOnPrimary && i != this._primaryIndex)
 
685
                continue;  // we are only interested in the primary monitor
 
686
 
 
687
            let monitorWorkspaces = [];
 
688
            for (let w = 0; w < global.screen.n_workspaces; w++) {
 
689
                let metaWorkspace = global.screen.get_workspace_by_index(w);
 
690
                monitorWorkspaces.push(new Workspace.Workspace(metaWorkspace, i));
 
691
            }
 
692
 
 
693
            this._workspaces.push(monitorWorkspaces);
 
694
 
 
695
            let view = new WorkspacesView(monitorWorkspaces);
 
696
            if (this._workspacesOnlyOnPrimary || i == this._primaryIndex) {
 
697
                this._scrollAdjustment = view.scrollAdjustment;
 
698
                this._scrollAdjustment.connect('notify::value',
 
699
                                               Lang.bind(this, this._scrollValueChanged));
 
700
                this._setupSwipeScrolling();
 
701
            }
 
702
            this._workspacesViews.push(view);
 
703
        }
 
704
 
 
705
        this._updateWorkspacesGeometry();
 
706
 
 
707
        for (let i = 0; i < this._workspacesViews.length; i++)
 
708
            global.overlay_group.add_actor(this._workspacesViews[i].actor);
 
709
    },
 
710
 
 
711
    _scrollValueChanged: function() {
 
712
        if (this._workspacesOnlyOnPrimary)
 
713
            return;
 
714
 
 
715
        for (let i = 0; i < this._workspacesViews.length; i++) {
 
716
            if (i == this._primaryIndex)
 
717
                continue;
 
718
 
 
719
            let adjustment = this._workspacesViews[i].scrollAdjustment;
 
720
            // the adjustments work in terms of workspaces, so the
 
721
            // values map directly
 
722
            adjustment.value = this._scrollAdjustment.value;
 
723
        }
 
724
    },
 
725
 
 
726
    _getPrimaryView: function() {
 
727
        if (!this._workspacesViews)
 
728
            return null;
 
729
        if (this._workspacesOnlyOnPrimary)
 
730
            return this._workspacesViews[0];
 
731
        else
 
732
            return this._workspacesViews[this._primaryIndex];
 
733
    },
 
734
 
 
735
    activeWorkspaceHasMaximizedWindows: function() {
 
736
        return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows();
610
737
    },
611
738
 
612
739
    // zoomFraction property allows us to tween the controls sliding in and out
679
806
        this._updateWorkspacesGeometry();
680
807
    },
681
808
 
 
809
    _parentSet: function(actor, oldParent) {
 
810
        if (oldParent && this._notifyOpacityId)
 
811
            oldParent.disconnect(this._notifyOpacityId);
 
812
        this._notifyOpacityId = 0;
 
813
 
 
814
        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
 
815
            function() {
 
816
                let newParent = this.actor.get_parent();
 
817
                if (!newParent)
 
818
                    return;
 
819
 
 
820
                // This is kinda hackish - we want the primary view to
 
821
                // appear as parent of this.actor, though in reality it
 
822
                // is added directly to overlay_group
 
823
                this._notifyOpacityId = newParent.connect('notify::opacity',
 
824
                    Lang.bind(this, function() {
 
825
                        let opacity = this.actor.get_parent().opacity;
 
826
                        let primaryView = this._getPrimaryView();
 
827
                        if (!primaryView)
 
828
                            return;
 
829
                        primaryView.actor.opacity = opacity;
 
830
                        if (opacity == 0)
 
831
                            primaryView.actor.hide();
 
832
                        else
 
833
                            primaryView.actor.show();
 
834
                    }));
 
835
        }));
 
836
    },
 
837
 
682
838
    _updateWorkspacesGeometry: function() {
683
 
        if (!this.workspacesView)
 
839
        if (!this._workspacesViews)
684
840
            return;
685
841
 
686
842
        let fullWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
701
857
        let clipX = rtl ? x + controlsVisible : x;
702
858
        let clipY = y + (fullHeight - clipHeight) / 2;
703
859
 
704
 
        this.workspacesView.setClipRect(clipX, clipY, clipWidth, clipHeight);
705
 
 
706
860
        if (this._zoomOut) {
707
861
            width -= controlsNatural;
708
862
            if (rtl)
717
871
        let difference = fullHeight - height;
718
872
        y += difference / 2;
719
873
 
720
 
        this.workspacesView.setGeometry(x, y, width, height, difference);
 
874
 
 
875
        let monitors = Main.layoutManager.monitors;
 
876
        let m = 0;
 
877
        for (let i = 0; i < monitors.length; i++) {
 
878
            if (i == this._primaryIndex) {
 
879
                this._workspacesViews[m].setClipRect(clipX, clipY,
 
880
                                                     clipWidth, clipHeight);
 
881
                this._workspacesViews[m].setGeometry(x, y, width, height,
 
882
                                                     difference);
 
883
                m++;
 
884
            } else if (!this._workspacesOnlyOnPrimary) {
 
885
                this._workspacesViews[m].setClipRect(monitors[i].x,
 
886
                                                     monitors[i].y,
 
887
                                                     monitors[i].width,
 
888
                                                     monitors[i].height);
 
889
                this._workspacesViews[m].setGeometry(monitors[i].x,
 
890
                                                     monitors[i].y,
 
891
                                                     monitors[i].width,
 
892
                                                     monitors[i].height, 0);
 
893
                m++;
 
894
            }
 
895
        }
721
896
    },
722
897
 
723
898
    _onRestacked: function() {
729
904
            stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
730
905
        }
731
906
 
732
 
        this.workspacesView.syncStacking(stackIndices);
 
907
        for (let i = 0; i < this._workspacesViews.length; i++)
 
908
            this._workspacesViews[i].syncStacking(stackIndices);
 
909
 
733
910
        this._thumbnailsBox.syncStacking(stackIndices);
734
911
    },
735
912
 
736
913
    _workspacesChanged: function() {
737
 
        let oldNumWorkspaces = this._workspaces.length;
 
914
        let oldNumWorkspaces = this._workspaces[0].length;
738
915
        let newNumWorkspaces = global.screen.n_workspaces;
739
916
        let active = global.screen.get_active_workspace_index();
740
917
 
744
921
        this._updateAlwaysZoom();
745
922
        this._updateZoom();
746
923
 
747
 
        if (this.workspacesView == null)
 
924
        if (this._workspacesViews == null)
748
925
            return;
749
926
 
750
927
        let lostWorkspaces = [];
751
928
        if (newNumWorkspaces > oldNumWorkspaces) {
752
 
            // Assume workspaces are only added at the end
753
 
            for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
754
 
                let metaWorkspace = global.screen.get_workspace_by_index(w);
755
 
                this._workspaces[w] = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
 
929
            let monitors = Main.layoutManager.monitors;
 
930
            let m = 0;
 
931
            for (let i = 0; i < monitors.length; i++) {
 
932
                if (this._workspacesOnlyOnPrimaryChanged &&
 
933
                    i != this._primaryIndex)
 
934
                    continue;
 
935
 
 
936
                // Assume workspaces are only added at the end
 
937
                for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
 
938
                    let metaWorkspace = global.screen.get_workspace_by_index(w);
 
939
                    this._workspaces[m++][w] =
 
940
                        new Workspace.Workspace(metaWorkspace, i);
 
941
                }
756
942
            }
757
943
 
758
944
            this._thumbnailsBox.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
763
949
            let removedNum = oldNumWorkspaces - newNumWorkspaces;
764
950
            for (let w = 0; w < oldNumWorkspaces; w++) {
765
951
                let metaWorkspace = global.screen.get_workspace_by_index(w);
766
 
                if (this._workspaces[w].metaWorkspace != metaWorkspace) {
 
952
                if (this._workspaces[0][w].metaWorkspace != metaWorkspace) {
767
953
                    removedIndex = w;
768
954
                    break;
769
955
                }
770
956
            }
771
957
 
772
 
            lostWorkspaces = this._workspaces.splice(removedIndex,
773
 
                                                     removedNum);
 
958
            for (let i = 0; i < this._workspaces.length; i++) {
 
959
                lostWorkspaces = this._workspaces[i].splice(removedIndex,
 
960
                                                            removedNum);
774
961
 
775
 
            for (let l = 0; l < lostWorkspaces.length; l++) {
776
 
                lostWorkspaces[l].disconnectAll();
777
 
                lostWorkspaces[l].destroy();
 
962
                for (let l = 0; l < lostWorkspaces.length; l++) {
 
963
                    lostWorkspaces[l].disconnectAll();
 
964
                    lostWorkspaces[l].destroy();
 
965
                }
778
966
            }
779
967
 
780
968
            this._thumbnailsBox.removeThumbmails(removedIndex, removedNum);
781
969
        }
782
970
 
783
 
        this.workspacesView.updateWorkspaces(oldNumWorkspaces,
784
 
                                             newNumWorkspaces);
 
971
        for (let i = 0; i < this._workspacesViews.length; i++)
 
972
            this._workspacesViews[i].updateWorkspaces(oldNumWorkspaces,
 
973
                                                      newNumWorkspaces);
785
974
    },
786
975
 
787
976
    _updateZoom : function() {
793
982
            this._zoomOut = shouldZoom;
794
983
            this._updateWorkspacesGeometry();
795
984
 
796
 
            if (!this.workspacesView)
 
985
            if (!this._workspacesViews)
797
986
                return;
798
987
 
799
988
            Tweener.addTween(this,
801
990
                               time: WORKSPACE_SWITCH_TIME,
802
991
                               transition: 'easeOutQuad' });
803
992
 
804
 
            this.workspacesView.updateWindowPositions();
 
993
            for (let i = 0; i < this._workspacesViews.length; i++)
 
994
                this._workspacesViews[i].updateWindowPositions();
805
995
        }
806
996
    },
807
997
 
852
1042
            break;
853
1043
        }
854
1044
    }
855
 
};
 
1045
});
856
1046
Signals.addSignalMethods(WorkspacesDisplay.prototype);