diff --git a/data/gnome-shell.schemas b/data/gnome-shell.schemas index 4e1f49620..6da8e3231 100644 --- a/data/gnome-shell.schemas +++ b/data/gnome-shell.schemas @@ -73,6 +73,20 @@ + + /schemas/desktop/gnome/shell/sidebar/autohide + /desktop/gnome/shell/sidebar/autohide + gnome-shell + bool + true + + Whether the sidebar should automatically hide itself in compact mode + + Controls the autohide state of the sidebar. + + + + /schemas/desktop/gnome/shell/sidebar/widgets /desktop/gnome/shell/sidebar/widgets diff --git a/js/ui/sidebar.js b/js/ui/sidebar.js index 5389f251a..6d12db3dc 100644 --- a/js/ui/sidebar.js +++ b/js/ui/sidebar.js @@ -4,6 +4,7 @@ const Big = imports.gi.Big; const Clutter = imports.gi.Clutter; const Shell = imports.gi.Shell; const Lang = imports.lang; +const Mainloop = imports.mainloop; const Main = imports.ui.main; const Panel = imports.ui.panel; @@ -58,6 +59,8 @@ Sidebar.prototype = { if (this._visible) Main.chrome.addActor(this.actor); + this._hidden = false; + this._hideTimeoutId = 0; this._widgets = []; this.addWidget(new ToggleWidget()); @@ -69,8 +72,14 @@ Sidebar.prototype = { Lang.bind(this, this._expandedChanged)); this._gconf.connect('changed::sidebar/visible', Lang.bind(this, this._visibleChanged)); + this._gconf.connect('changed::sidebar/autohide', + Lang.bind(this, this._autohideChanged)); + + this.actor.connect('enter-event',Lang.bind(this,this._restoreHidden)); + this.actor.connect('leave-event',Lang.bind(this,this._startHideTimeout)); this._adjustPosition(); + this._autohideChanged(); }, addWidget: function(widget) { @@ -90,7 +99,7 @@ Sidebar.prototype = { _adjustPosition: function() { let primary=global.get_primary_monitor(); - this.actor.y = Math.max(primary.y + Panel.PANEL_HEIGHT,primary.height/2 - this.actor.height/2); + this.actor.y = Math.floor(Math.max(primary.y + Panel.PANEL_HEIGHT,primary.height/2 - this.actor.height/2)); this.actor.x = primary.x; }, @@ -118,6 +127,21 @@ Sidebar.prototype = { this._collapse(); }, + _autohideChanged: function() { + let autohide = this._gconf.get_boolean("sidebar/autohide"); + if (autohide == this._autohide) + return; + + this._autohide = autohide; + if (autohide) { + this.actor.set_reactive(true); + this._hide(); + } else { + this.actor.set_reactive(false); + this._restore(); + } + }, + _expand: function() { this._expanded = true; for (let i = 0; i < this._widgets.length; i++) @@ -135,16 +159,70 @@ Sidebar.prototype = { for (let i = 0; i < this._widgets.length; i++) this._widgets[i].collapse(); - // Updated the strut/stage area after the animation completes + // Update the strut/stage area after the animation completes Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME, - onComplete: function () { + onComplete: Lang.bind(this, function () { this.actor.width = SIDEBAR_COLLAPSED_WIDTH; - } }); + }) }); + }, + + _hide: function() { + if (!this._expanded) { + this._hidden = true; + for (let i = 0; i < this._widgets.length; i++) + this._widgets[i].hide(); + + // Update the strut/stage area after the animation completes + Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME / 2, + onComplete: Lang.bind(this, function () { + this.actor.width = Math.floor(WidgetBox.WIDGETBOX_PADDING * 2 + SIDEBAR_PADDING); + }) }); + } + }, + + _restore: function() { + if (!this._expanded) { + this._hidden = false; + for (let i = 0; i < this._widgets.length; i++) + this._widgets[i].restore(); + + // Updated the strut/stage area after the animation completes + Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME / 2, + onComplete: function () { + this.actor.width = SIDEBAR_COLLAPSED_WIDTH; + } }); + } + }, + + _restoreHidden: function(actor, event) { + this._cancelHideTimeout(); + if (this._hidden) + this._restore(); + return false; + }, + + _startHideTimeout: function(actor, event) { + if (!this._expanded) { + this._cancelHideTimeout(); + this._hideTimeoutId = Mainloop.timeout_add_seconds(2, Lang.bind(this,this._hideTimeoutFunc)); + } + return false; + }, + + _cancelHideTimeout: function() { + if (this._hideTimeoutId != 0) { + Mainloop.source_remove(this._hideTimeoutId); + this._hideTimeoutId = 0; + } + }, + + _hideTimeoutFunc: function() { + this._hide(); + return false; }, destroy: function() { this.hide(); - for (let i = 0; i < this._widgets.length; i++) this._widgets[i].destroy(); this.actor.destroy(); diff --git a/js/ui/widgetBox.js b/js/ui/widgetBox.js index b7dae7459..1455160e2 100644 --- a/js/ui/widgetBox.js +++ b/js/ui/widgetBox.js @@ -373,6 +373,20 @@ WidgetBox.prototype = { Main.chrome.untrackActor(this._hbox); }, + hide: function() { + if (this.state == Widget.STATE_COLLAPSED) + Tweener.addTween(this._cbox, { x: -Widget.COLLAPSED_WIDTH, + time: ANIMATION_TIME / 2, + transition: "easeOutQuad" }); + }, + + restore: function() { + if (this.state == Widget.STATE_COLLAPSED) + Tweener.addTween(this._cbox, { x: 0, + time: ANIMATION_TIME / 2, + transition: "easeOutQuad" }); + }, + destroy: function() { if (this._widget.destroy) this._widget.destroy();