From 3fe7b139590a23a5f594094a948ff573f488f0e9 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Wed, 9 Jun 2010 19:09:48 +0200 Subject: [PATCH] [workspaceSwitcher] Constrain to monitor size Currently the workspaceSwitcher does not take the screen size into account which could result into overflowing the screen. Fix that but using Shell.GenericContainer instead of St.BoxLayout which takes the monitor size into account when allocating. https://bugzilla.gnome.org/show_bug.cgi?id=620404 --- data/theme/gnome-shell.css | 8 +++- js/ui/workspaceSwitcherPopup.js | 71 +++++++++++++++++++++++++++++---- 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index 7e2a05775..0143ac96d 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -1009,6 +1009,10 @@ StTooltip { } /* Workspace Switcher */ +.workspace-switcher-group { + padding: 12px; +} + .workspace-switcher-container { background: rgba(0,0,0,0.8); border: 1px solid rgba(128,128,128,0.40); @@ -1025,7 +1029,7 @@ StTooltip { } .ws-switcher-active-left { - height: 98px; + height: 100px; border: 0px; background: rgba(255,255,255,0.5); background-image: url("ws-switch-arrow-left.svg"); @@ -1033,7 +1037,7 @@ StTooltip { } .ws-switcher-active-right { - height: 98px; + height: 100px; border: 0px; background: rgba(255,255,255,0.5); background-image: url("ws-switch-arrow-right.svg"); diff --git a/js/ui/workspaceSwitcherPopup.js b/js/ui/workspaceSwitcherPopup.js index b638d9955..55d460156 100644 --- a/js/ui/workspaceSwitcherPopup.js +++ b/js/ui/workspaceSwitcherPopup.js @@ -21,18 +21,25 @@ function WorkspaceSwitcherPopup() { WorkspaceSwitcherPopup.prototype = { _init : function() { - this.actor = new Clutter.Group({ reactive: true, + this.actor = new St.Group({ reactive: true, x: 0, y: 0, width: global.screen_width, - height: global.screen_height }); + height: global.screen_height, + style_class: 'workspace-switcher-group' }); Main.uiGroup.add_actor(this.actor); - this._scaleWidth = global.screen_width / global.screen_height; - this._container = new St.BoxLayout({ style_class: 'workspace-switcher-container' }); - this._list = new St.BoxLayout({ style_class: 'workspace-switcher' }); + this._list = new Shell.GenericContainer({ style_class: 'workspace-switcher' }); + this._itemSpacing = 0; + this._list.connect('style-changed', Lang.bind(this, function() { + let [found, spacing] = this._list.get_theme_node().get_length('spacing', false); + this._itemSpacing = (found) ? spacing : 0; + })); + this._list.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth)); + this._list.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight)); + this._list.connect('allocate', Lang.bind(this, this._allocate)); this._container.add(this._list); this.actor.add_actor(this._container); @@ -45,6 +52,57 @@ WorkspaceSwitcherPopup.prototype = { this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout)); }, + _getPreferredWidth : function (actor, forHeight, alloc) { + let children = this._list.get_children(); + let primary = global.get_primary_monitor(); + + let availwidth = primary.width; + availwidth -= this.actor.get_theme_node().get_horizontal_padding(); + availwidth -= this._container.get_theme_node().get_horizontal_padding(); + availwidth -= this._list.get_theme_node().get_horizontal_padding(); + + let width = 0; + for (let i = 0; i < children.length; i++) { + let [childMinWidth, childNaturalWidth] = children[i].get_preferred_width(-1); + let [childMinHeight, childNaturalHeight] = children[i].get_preferred_height(childNaturalWidth); + width += childNaturalHeight * primary.width / primary.height; + } + + let spacing = this._itemSpacing * (global.screen.n_workspaces - 1); + width += spacing; + width = Math.min(width, availwidth); + + this._childWidth = (width - spacing) / global.screen.n_workspaces; + + alloc.min_size = width; + alloc.natural_size = width; + }, + + _getPreferredHeight : function (actor, forWidth, alloc) { + let primary = global.get_primary_monitor(); + this._childHeight = Math.round(this._childWidth * primary.height / primary.width); + + alloc.min_size = this._childHeight; + alloc.natural_size = this._childHeight; + }, + + _allocate : function (actor, box, flags) { + let children = this._list.get_children(); + let childBox = new Clutter.ActorBox(); + + let x = box.x1; + let prevChildBoxX2 = box.x1 - this._itemSpacing; + for (let i = 0; i < children.length; i++) { + childBox.x1 = prevChildBoxX2 + this._itemSpacing; + childBox.x2 = Math.round(x + this._childWidth); + childBox.y1 = box.y1; + childBox.y2 = box.y1 + this._childHeight; + x += this._childWidth + this._itemSpacing; + prevChildBoxX2 = childBox.x2; + children[i].allocate(childBox, flags); + } + }, + _redraw : function(direction, activeWorkspaceIndex) { this._list.destroy_children(); @@ -58,8 +116,7 @@ WorkspaceSwitcherPopup.prototype = { else indicator = new St.Bin({ style_class: 'ws-switcher-box' }); - this._list.add(indicator); - indicator.set_width(Math.round(indicator.get_height() * this._scaleWidth)); + this._list.add_actor(indicator); } },