From a0a83428cfb21b12368d10711fabf9dd698d5a24 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Wed, 9 Mar 2011 13:56:35 +0100 Subject: [PATCH] telepathyClient: Pin the scrollbar to the bottom When new messages come in we want to scroll down so that the user sees the incoming messages. The current implementation does not work because it relies on a synchronous allocation hack which does not work for unmapped notifications. Fix that by connecting to adjustment::changed and scroll whenever the adjustment changes which equals "new messages", "new timestamp" or "presense change", but don't interference with the user's scroll actions i.e when the user scrolls back to read something don't scroll to the bottom. https://bugzilla.gnome.org/show_bug.cgi?id=614977 --- js/ui/messageTray.js | 29 ++++++++++++++++------------- js/ui/telepathyClient.js | 11 ++++++++++- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js index 39b90f860..4f2512238 100644 --- a/js/ui/messageTray.js +++ b/js/ui/messageTray.js @@ -518,25 +518,28 @@ Notification.prototype = { this._updated(); }, + _createScrollArea: function() { + this.actor.add_style_class_name('multi-line-notification'); + this._scrollArea = new St.ScrollView({ name: 'notification-scrollview', + vscrollbar_policy: Gtk.PolicyType.AUTOMATIC, + hscrollbar_policy: Gtk.PolicyType.NEVER, + vfade: true }); + this.actor.add(this._scrollArea, { row: 1, col: 1 }); + this._contentArea = new St.BoxLayout({ name: 'notification-body', + vertical: true }); + this._scrollArea.add_actor(this._contentArea); + // If we know the notification will be expandable, we need to add + // the banner text to the body as the first element. + this._addBannerBody(); + }, + // addActor: // @actor: actor to add to the body of the notification // // Appends @actor to the notification's body addActor: function(actor, style) { if (!this._scrollArea) { - this.actor.add_style_class_name('multi-line-notification'); - this._scrollArea = new St.ScrollView({ name: 'notification-scrollview', - vscrollbar_policy: Gtk.PolicyType.AUTOMATIC, - hscrollbar_policy: Gtk.PolicyType.NEVER, - vfade: true }); - this.actor.add(this._scrollArea, { row: 1, - col: 1 }); - this._contentArea = new St.BoxLayout({ name: 'notification-body', - vertical: true }); - this._scrollArea.add_actor(this._contentArea); - // If we know the notification will be expandable, we need to add - // the banner text to the body as the first element. - this._addBannerBody(); + this._createScrollArea(); } this._contentArea.add(actor, style ? style : {}); diff --git a/js/ui/telepathyClient.js b/js/ui/telepathyClient.js index d835d3e2b..7dd972e7a 100644 --- a/js/ui/telepathyClient.js +++ b/js/ui/telepathyClient.js @@ -279,6 +279,16 @@ Notification.prototype = { this._responseEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivated)); this.setActionArea(this._responseEntry); + this._oldMaxScrollAdjustment = 0; + this._createScrollArea(); + + this._scrollArea.vscroll.adjustment.connect('changed', Lang.bind(this, function(adjustment) { + let currentValue = adjustment.value + adjustment.page_size; + if (currentValue == this._oldMaxScrollAdjustment) + this.scrollTo(St.Side.BOTTOM); + this._oldMaxScrollAdjustment = adjustment.upper; + })); + this._history = []; this._timestampTimeoutId = 0; }, @@ -305,7 +315,6 @@ Notification.prototype = { let body = this.addBody(text); body.add_style_class_name(style); - this.scrollTo(St.Side.BOTTOM); this._history.unshift({ actor: body, time: timestamp, realMessage: true });