Blame js/ui/workspaceSwitcherPopup.js

Packit d345d1
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
Packit d345d1
Packit d345d1
const { Clutter, GLib, GObject, Meta, St } = imports.gi;
Packit d345d1
const Mainloop = imports.mainloop;
Packit d345d1
Packit d345d1
const Main = imports.ui.main;
Packit d345d1
const Tweener = imports.ui.tweener;
Packit d345d1
Packit d345d1
var ANIMATION_TIME = 0.1;
Packit d345d1
var DISPLAY_TIMEOUT = 600;
Packit d345d1
Packit d345d1
var WorkspaceSwitcherPopupList = GObject.registerClass(
Packit d345d1
class WorkspaceSwitcherPopupList extends St.Widget {
Packit d345d1
    _init() {
Packit d345d1
        super._init({ style_class: 'workspace-switcher' });
Packit d345d1
Packit d345d1
        this._itemSpacing = 0;
Packit d345d1
        this._childHeight = 0;
Packit d345d1
        this._childWidth = 0;
Packit d345d1
Packit d345d1
        this.connect('style-changed', () => {
Packit d345d1
           this._itemSpacing = this.get_theme_node().get_length('spacing');
Packit d345d1
        });
Packit d345d1
    }
Packit d345d1
Packit d345d1
    vfunc_get_preferred_height(forWidth) {
Packit d345d1
        let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
Packit d345d1
        let themeNode = this.get_theme_node();
Packit d345d1
Packit d345d1
        let availHeight = workArea.height;
Packit d345d1
        availHeight -= themeNode.get_vertical_padding();
Packit d345d1
Packit d345d1
        let height = 0;
Packit d345d1
        for (let child of this.get_children()) {
Packit d345d1
            let [childMinHeight, childNaturalHeight] = child.get_preferred_height(-1);
Packit d345d1
            let [childMinWidth, childNaturalWidth] = child.get_preferred_width(childNaturalHeight);
Packit d345d1
            height += childNaturalHeight * workArea.width / workArea.height;
Packit d345d1
        }
Packit d345d1
Packit d345d1
        let workspaceManager = global.workspace_manager;
Packit d345d1
        let spacing = this._itemSpacing * (workspaceManager.n_workspaces - 1);
Packit d345d1
        height += spacing;
Packit d345d1
        height = Math.min(height, availHeight);
Packit d345d1
Packit d345d1
        this._childHeight = (height - spacing) / workspaceManager.n_workspaces;
Packit d345d1
Packit d345d1
        return themeNode.adjust_preferred_height(height, height);
Packit d345d1
    }
Packit d345d1
Packit d345d1
    vfunc_get_preferred_width(forHeight) {
Packit d345d1
        let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
Packit d345d1
        this._childWidth = Math.round(this._childHeight * workArea.width / workArea.height);
Packit d345d1
Packit d345d1
        return [this._childWidth, this._childWidth];
Packit d345d1
    }
Packit d345d1
Packit d345d1
    vfunc_allocate(box, flags) {
Packit d345d1
        this.set_allocation(box, flags);
Packit d345d1
Packit d345d1
        let themeNode = this.get_theme_node();
Packit d345d1
        box = themeNode.get_content_box(box);
Packit d345d1
Packit d345d1
        let childBox = new Clutter.ActorBox();
Packit d345d1
Packit d345d1
        let y = box.y1;
Packit d345d1
        let prevChildBoxY2 = box.y1 - this._itemSpacing;
Packit d345d1
        for (let child of this.get_children()) {
Packit d345d1
            childBox.x1 = box.x1;
Packit d345d1
            childBox.x2 = box.x1 + this._childWidth;
Packit d345d1
            childBox.y1 = prevChildBoxY2 + this._itemSpacing;
Packit d345d1
            childBox.y2 = Math.round(y + this._childHeight);
Packit d345d1
            y += this._childHeight + this._itemSpacing;
Packit d345d1
            prevChildBoxY2 = childBox.y2;
Packit d345d1
            child.allocate(childBox, flags);
Packit d345d1
        }
Packit d345d1
    }
Packit d345d1
});
Packit d345d1
Packit d345d1
var WorkspaceSwitcherPopup = GObject.registerClass(
Packit d345d1
class WorkspaceSwitcherPopup extends St.Widget {
Packit d345d1
    _init() {
Packit d345d1
        super._init({ x: 0,
Packit d345d1
                      y: 0,
Packit d345d1
                      width: global.screen_width,
Packit d345d1
                      height: global.screen_height,
Packit d345d1
                      style_class: 'workspace-switcher-group' });
Packit d345d1
Packit d345d1
        this.actor = this;
Packit d345d1
Packit d345d1
        Main.uiGroup.add_actor(this);
Packit d345d1
Packit d345d1
        this._timeoutId = 0;
Packit d345d1
Packit d345d1
        this._container = new St.BoxLayout({ style_class: 'workspace-switcher-container' });
Packit d345d1
        this.add_child(this._container);
Packit d345d1
Packit d345d1
        this._list = new WorkspaceSwitcherPopupList();
Packit d345d1
        this._container.add_child(this._list);
Packit d345d1
Packit d345d1
        this._redisplay();
Packit d345d1
Packit d345d1
        this.hide();
Packit d345d1
Packit d345d1
        let workspaceManager = global.workspace_manager;
Packit d345d1
        this._workspaceManagerSignals = [];
Packit d345d1
        this._workspaceManagerSignals.push(workspaceManager.connect('workspace-added',
Packit d345d1
                                                                    this._redisplay.bind(this)));
Packit d345d1
        this._workspaceManagerSignals.push(workspaceManager.connect('workspace-removed',
Packit d345d1
                                                                    this._redisplay.bind(this)));
Packit d345d1
Packit d345d1
        this.connect('destroy', this._onDestroy.bind(this));
Packit d345d1
    }
Packit d345d1
Packit d345d1
    _redisplay() {
Packit d345d1
        let workspaceManager = global.workspace_manager;
Packit d345d1
Packit d345d1
        this._list.destroy_all_children();
Packit d345d1
Packit d345d1
        for (let i = 0; i < workspaceManager.n_workspaces; i++) {
Packit d345d1
            let indicator = null;
Packit d345d1
Packit d345d1
           if (i == this._activeWorkspaceIndex && this._direction == Meta.MotionDirection.UP)
Packit d345d1
               indicator = new St.Bin({ style_class: 'ws-switcher-active-up' });
Packit d345d1
           else if(i == this._activeWorkspaceIndex && this._direction == Meta.MotionDirection.DOWN)
Packit d345d1
               indicator = new St.Bin({ style_class: 'ws-switcher-active-down' });
Packit d345d1
           else
Packit d345d1
               indicator = new St.Bin({ style_class: 'ws-switcher-box' });
Packit d345d1
Packit d345d1
           this._list.add_actor(indicator);
Packit d345d1
Packit d345d1
        }
Packit d345d1
Packit d345d1
        let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
Packit d345d1
        let [containerMinHeight, containerNatHeight] = this._container.get_preferred_height(global.screen_width);
Packit d345d1
        let [containerMinWidth, containerNatWidth] = this._container.get_preferred_width(containerNatHeight);
Packit d345d1
        this._container.x = workArea.x + Math.floor((workArea.width - containerNatWidth) / 2);
Packit d345d1
        this._container.y = workArea.y + Math.floor((workArea.height - containerNatHeight) / 2);
Packit d345d1
    }
Packit d345d1
Packit d345d1
    _show() {
Packit d345d1
        Tweener.addTween(this._container, { opacity: 255,
Packit d345d1
                                            time: ANIMATION_TIME,
Packit d345d1
                                            transition: 'easeOutQuad'
Packit d345d1
                                           });
Packit d345d1
        this.actor.show();
Packit d345d1
    }
Packit d345d1
Packit d345d1
    display(direction, activeWorkspaceIndex) {
Packit d345d1
        this._direction = direction;
Packit d345d1
        this._activeWorkspaceIndex = activeWorkspaceIndex;
Packit d345d1
Packit d345d1
        this._redisplay();
Packit d345d1
        if (this._timeoutId != 0)
Packit d345d1
            Mainloop.source_remove(this._timeoutId);
Packit d345d1
        this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, this._onTimeout.bind(this));
Packit d345d1
        GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._onTimeout');
Packit d345d1
        this._show();
Packit d345d1
    }
Packit d345d1
Packit d345d1
    _onTimeout() {
Packit d345d1
        Mainloop.source_remove(this._timeoutId);
Packit d345d1
        this._timeoutId = 0;
Packit d345d1
        Tweener.addTween(this._container, { opacity: 0.0,
Packit d345d1
                                            time: ANIMATION_TIME,
Packit d345d1
                                            transition: 'easeOutQuad',
Packit d345d1
                                            onComplete() { this.destroy(); },
Packit d345d1
                                            onCompleteScope: this
Packit d345d1
                                           });
Packit d345d1
        return GLib.SOURCE_REMOVE;
Packit d345d1
    }
Packit d345d1
Packit d345d1
    _onDestroy() {
Packit d345d1
        if (this._timeoutId)
Packit d345d1
            Mainloop.source_remove(this._timeoutId);
Packit d345d1
        this._timeoutId = 0;
Packit d345d1
Packit d345d1
        let workspaceManager = global.workspace_manager;
Packit d345d1
        for (let i = 0; i < this._workspaceManagerSignals.length; i++)
Packit d345d1
            workspaceManager.disconnect(this._workspaceManagerSignals[i]);
Packit d345d1
Packit d345d1
        this._workspaceManagerSignals = [];
Packit d345d1
    }
Packit d345d1
});