Blame SOURCES/resurrect-system-monitor.patch

79c34a
From 901e1b32939d27b0b0edabe99705fd3066d360ba Mon Sep 17 00:00:00 2001
79c34a
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
79c34a
Date: Wed, 17 May 2017 19:13:50 +0200
79c34a
Subject: [PATCH 1/4] extensions: Resurrect systemMonitor extension
79c34a
79c34a
The extension was removed upstream because:
79c34a
 - it hooks into the message tray that was removed
79c34a
 - it was known to have performance issues
79c34a
 - there are plenty of alternatives
79c34a
79c34a
Those aren't good enough reasons for dropping it downstream
79c34a
as well though, so we need to bring it back ...
79c34a
79c34a
This reverts commit c9a6421f362cd156cf731289eadc11f44f6970ac.
79c34a
---
79c34a
 extensions/systemMonitor/extension.js     | 376 ++++++++++++++++++++++
79c34a
 extensions/systemMonitor/meson.build      |   5 +
79c34a
 extensions/systemMonitor/metadata.json.in |  11 +
79c34a
 extensions/systemMonitor/stylesheet.css   |  35 ++
79c34a
 meson.build                               |   1 +
79c34a
 5 files changed, 428 insertions(+)
79c34a
 create mode 100644 extensions/systemMonitor/extension.js
79c34a
 create mode 100644 extensions/systemMonitor/meson.build
79c34a
 create mode 100644 extensions/systemMonitor/metadata.json.in
79c34a
 create mode 100644 extensions/systemMonitor/stylesheet.css
79c34a
79c34a
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
79c34a
new file mode 100644
79c34a
index 0000000..7b09df0
79c34a
--- /dev/null
79c34a
+++ b/extensions/systemMonitor/extension.js
79c34a
@@ -0,0 +1,376 @@
79c34a
+/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
79c34a
+
79c34a
+const Clutter = imports.gi.Clutter;
79c34a
+const GTop = imports.gi.GTop;
79c34a
+const Lang = imports.lang;
79c34a
+const Mainloop = imports.mainloop;
79c34a
+const St = imports.gi.St;
79c34a
+const Shell = imports.gi.Shell;
79c34a
+
79c34a
+const Main = imports.ui.main;
79c34a
+const Tweener = imports.ui.tweener;
79c34a
+
79c34a
+const Gettext = imports.gettext.domain('gnome-shell-extensions');
79c34a
+const _ = Gettext.gettext;
79c34a
+
79c34a
+const ExtensionUtils = imports.misc.extensionUtils;
79c34a
+const Me = ExtensionUtils.getCurrentExtension();
79c34a
+const Convenience = Me.imports.convenience;
79c34a
+
79c34a
+const INDICATOR_UPDATE_INTERVAL = 500;
79c34a
+const INDICATOR_NUM_GRID_LINES = 3;
79c34a
+
79c34a
+const ITEM_LABEL_SHOW_TIME = 0.15;
79c34a
+const ITEM_LABEL_HIDE_TIME = 0.1;
79c34a
+const ITEM_HOVER_TIMEOUT = 300;
79c34a
+
79c34a
+const Indicator = new Lang.Class({
79c34a
+    Name: 'SystemMonitor.Indicator',
79c34a
+
79c34a
+    _init: function() {
79c34a
+        this._initValues();
79c34a
+        this.drawing_area = new St.DrawingArea({ reactive: true });
79c34a
+        this.drawing_area.connect('repaint', Lang.bind(this, this._draw));
79c34a
+        this.drawing_area.connect('button-press-event', function() {
79c34a
+            let app = Shell.AppSystem.get_default().lookup_app('gnome-system-monitor.desktop');
79c34a
+            app.open_new_window(-1);
79c34a
+            return true;
79c34a
+        });
79c34a
+
79c34a
+        this.actor = new St.Bin({ style_class: "extension-systemMonitor-indicator-area",
79c34a
+                                  reactive: true, track_hover: true,
79c34a
+				  x_fill: true, y_fill: true });
79c34a
+        this.actor.add_actor(this.drawing_area);
79c34a
+
79c34a
+        this._timeout = Mainloop.timeout_add(INDICATOR_UPDATE_INTERVAL, Lang.bind(this, function () {
79c34a
+            this._updateValues();
79c34a
+            this.drawing_area.queue_repaint();
79c34a
+            return true;
79c34a
+        }));
79c34a
+    },
79c34a
+
79c34a
+    showLabel: function() {
79c34a
+        if (this.label == null)
79c34a
+            return;
79c34a
+
79c34a
+        this.label.opacity = 0;
79c34a
+        this.label.show();
79c34a
+
79c34a
+        let [stageX, stageY] = this.actor.get_transformed_position();
79c34a
+
79c34a
+	let itemWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
79c34a
+        let itemHeight = this.actor.allocation.y2 - this.actor.allocation.y1;
79c34a
+
79c34a
+	let labelWidth = this.label.width;
79c34a
+        let labelHeight = this.label.height;
79c34a
+        let xOffset = Math.floor((itemWidth - labelWidth) / 2)
79c34a
+
79c34a
+        let x = stageX + xOffset;
79c34a
+
79c34a
+        let node = this.label.get_theme_node();
79c34a
+        let yOffset = node.get_length('-y-offset');
79c34a
+
79c34a
+        let y = stageY - this.label.get_height() - yOffset;
79c34a
+
79c34a
+        this.label.set_position(x, y);
79c34a
+        Tweener.addTween(this.label,
79c34a
+                         { opacity: 255,
79c34a
+                           time: ITEM_LABEL_SHOW_TIME,
79c34a
+                           transition: 'easeOutQuad',
79c34a
+                         });
79c34a
+    },
79c34a
+
79c34a
+    setLabelText: function(text) {
79c34a
+        if (this.label == null)
79c34a
+            this.label = new St.Label({ style_class: 'extension-systemMonitor-indicator-label'});
79c34a
+
79c34a
+        this.label.set_text(text);
79c34a
+        Main.layoutManager.addChrome(this.label);
79c34a
+        this.label.hide();
79c34a
+    },
79c34a
+
79c34a
+    hideLabel: function () {
79c34a
+        Tweener.addTween(this.label,
79c34a
+                         { opacity: 0,
79c34a
+                           time: ITEM_LABEL_HIDE_TIME,
79c34a
+                           transition: 'easeOutQuad',
79c34a
+                           onComplete: Lang.bind(this, function() {
79c34a
+                               this.label.hide();
79c34a
+                           })
79c34a
+                         });
79c34a
+    },
79c34a
+
79c34a
+    destroy: function() {
79c34a
+        Mainloop.source_remove(this._timeout);
79c34a
+
79c34a
+        this.actor.destroy();
79c34a
+	if (this.label)
79c34a
+	    this.label.destroy();
79c34a
+    },
79c34a
+
79c34a
+    _initValues: function() {
79c34a
+    },
79c34a
+
79c34a
+    _updateValues: function() {
79c34a
+    },
79c34a
+
79c34a
+    _draw: function(area) {
79c34a
+        let [width, height] = area.get_surface_size();
79c34a
+        let themeNode = this.actor.get_theme_node();
79c34a
+        let cr = area.get_context();
79c34a
+
79c34a
+        //draw the background grid
79c34a
+        let color = themeNode.get_color(this.gridColor);
79c34a
+        let gridOffset = Math.floor(height / (INDICATOR_NUM_GRID_LINES + 1));
79c34a
+        for (let i = 1; i <= INDICATOR_NUM_GRID_LINES; ++i) {
79c34a
+                cr.moveTo(0, i * gridOffset + .5);
79c34a
+                cr.lineTo(width, i * gridOffset + .5);
79c34a
+        }
79c34a
+        Clutter.cairo_set_source_color(cr, color);
79c34a
+        cr.setLineWidth(1);
79c34a
+        cr.setDash([4,1], 0);
79c34a
+        cr.stroke();
79c34a
+
79c34a
+        //draw the foreground
79c34a
+
79c34a
+        function makePath(values, reverse, nudge) {
79c34a
+            if (nudge == null) {
79c34a
+                nudge = 0;
79c34a
+            }
79c34a
+            //if we are going in reverse, we are completing the bottom of a chart, so use lineTo
79c34a
+            if (reverse) {
79c34a
+                cr.lineTo(values.length - 1, (1 - values[values.length - 1]) * height + nudge);
79c34a
+                for (let k = values.length - 2; k >= 0; --k) {
79c34a
+                    cr.lineTo(k, (1 - values[k]) * height + nudge);
79c34a
+                }
79c34a
+            } else {
79c34a
+                cr.moveTo(0, (1 - values[0]) * height + nudge);
79c34a
+                for (let k = 1; k < values.length; ++k) {
79c34a
+                    cr.lineTo(k, (1 - values[k]) * height + nudge);
79c34a
+                }
79c34a
+
79c34a
+            }
79c34a
+        }
79c34a
+
79c34a
+        let renderStats = this.renderStats;
79c34a
+
79c34a
+        // Make sure we don't have more sample points than pixels
79c34a
+        renderStats.map(Lang.bind(this, function(k){
79c34a
+            let stat = this.stats[k];
79c34a
+            if (stat.values.length > width) {
79c34a
+                stat.values = stat.values.slice(stat.values.length - width, stat.values.length);
79c34a
+            }
79c34a
+        }));
79c34a
+
79c34a
+        for (let i = 0; i < renderStats.length; ++i) {
79c34a
+            let stat = this.stats[renderStats[i]];
79c34a
+            // We outline at full opacity and fill with 40% opacity
79c34a
+            let outlineColor = themeNode.get_color(stat.color);
79c34a
+            let color = new Clutter.Color(outlineColor);
79c34a
+            color.alpha = color.alpha * .4;
79c34a
+
79c34a
+            // Render the background between us and the next level
79c34a
+            makePath(stat.values, false);
79c34a
+            // If there is a process below us, render the cpu between us and it, otherwise,
79c34a
+            // render to the bottom of the chart
79c34a
+            if (i == renderStats.length - 1) {
79c34a
+                cr.lineTo(stat.values.length - 1, height);
79c34a
+                cr.lineTo(0, height);
79c34a
+                cr.closePath();
79c34a
+            } else {
79c34a
+                let nextStat = this.stats[renderStats[i+1]];
79c34a
+                makePath(nextStat.values, true);
79c34a
+            }
79c34a
+            cr.closePath()
79c34a
+            Clutter.cairo_set_source_color(cr, color);
79c34a
+            cr.fill();
79c34a
+
79c34a
+            // Render the outline of this level
79c34a
+            makePath(stat.values, false, .5);
79c34a
+            Clutter.cairo_set_source_color(cr, outlineColor);
79c34a
+            cr.setLineWidth(1.0);
79c34a
+            cr.setDash([], 0);
79c34a
+            cr.stroke();
79c34a
+        }
79c34a
+    }
79c34a
+});
79c34a
+
79c34a
+const CpuIndicator = new Lang.Class({
79c34a
+    Name: 'SystemMonitor.CpuIndicator',
79c34a
+    Extends: Indicator,
79c34a
+
79c34a
+    _init: function() {
79c34a
+        this.parent();
79c34a
+
79c34a
+        this.gridColor = '-grid-color';
79c34a
+        this.renderStats = [ 'cpu-user', 'cpu-sys', 'cpu-iowait' ];
79c34a
+
79c34a
+        // Make sure renderStats is sorted as necessary for rendering
79c34a
+        let renderStatOrder = {'cpu-total': 0, 'cpu-user': 1, 'cpu-sys': 2, 'cpu-iowait': 3};
79c34a
+        this.renderStats = this.renderStats.sort(function(a,b) {
79c34a
+            return renderStatOrder[a] - renderStatOrder[b];
79c34a
+        });
79c34a
+
79c34a
+	this.setLabelText(_("CPU"));
79c34a
+    },
79c34a
+
79c34a
+    _initValues: function() {
79c34a
+        this._prev = new GTop.glibtop_cpu;
79c34a
+        GTop.glibtop_get_cpu(this._prev);
79c34a
+
79c34a
+        this.stats = {
79c34a
+                       'cpu-user': {color: '-cpu-user-color', values: []},
79c34a
+                       'cpu-sys': {color: '-cpu-sys-color', values: []},
79c34a
+                       'cpu-iowait': {color: '-cpu-iowait-color', values: []},
79c34a
+                       'cpu-total': {color: '-cpu-total-color', values: []}
79c34a
+                     };
79c34a
+    },
79c34a
+
79c34a
+    _updateValues: function() {
79c34a
+        let cpu = new GTop.glibtop_cpu;
79c34a
+        let t = 0.0;
79c34a
+        GTop.glibtop_get_cpu(cpu);
79c34a
+        let total = cpu.total - this._prev.total;
79c34a
+        let user = cpu.user - this._prev.user;
79c34a
+        let sys = cpu.sys - this._prev.sys;
79c34a
+        let iowait = cpu.iowait - this._prev.iowait;
79c34a
+        let idle = cpu.idle - this._prev.idle;
79c34a
+
79c34a
+        t += iowait / total;
79c34a
+        this.stats['cpu-iowait'].values.push(t);
79c34a
+        t += sys / total;
79c34a
+        this.stats['cpu-sys'].values.push(t);
79c34a
+        t += user / total;
79c34a
+        this.stats['cpu-user'].values.push(t);
79c34a
+        this.stats['cpu-total'].values.push(1 - idle / total);
79c34a
+
79c34a
+        this._prev = cpu;
79c34a
+    }
79c34a
+});
79c34a
+
79c34a
+const MemoryIndicator = new Lang.Class({
79c34a
+    Name: 'SystemMonitor.MemoryIndicator',
79c34a
+    Extends: Indicator,
79c34a
+
79c34a
+    _init: function() {
79c34a
+        this.parent();
79c34a
+
79c34a
+        this.gridColor = '-grid-color';
79c34a
+        this.renderStats = [ 'mem-user', 'mem-other', 'mem-cached' ];
79c34a
+
79c34a
+        // Make sure renderStats is sorted as necessary for rendering
79c34a
+        let renderStatOrder = { 'mem-cached': 0, 'mem-other': 1, 'mem-user': 2 };
79c34a
+        this.renderStats = this.renderStats.sort(function(a,b) {
79c34a
+            return renderStatOrder[a] - renderStatOrder[b];
79c34a
+        });
79c34a
+
79c34a
+	this.setLabelText(_("Memory"));
79c34a
+    },
79c34a
+
79c34a
+    _initValues: function() {
79c34a
+        this.mem = new GTop.glibtop_mem;
79c34a
+        this.stats = {
79c34a
+                        'mem-user': { color: "-mem-user-color", values: [] },
79c34a
+                        'mem-other': { color: "-mem-other-color", values: [] },
79c34a
+                        'mem-cached': { color: "-mem-cached-color", values: [] }
79c34a
+                     };
79c34a
+    },
79c34a
+
79c34a
+    _updateValues: function() {
79c34a
+        GTop.glibtop_get_mem(this.mem);
79c34a
+
79c34a
+        let t = this.mem.user / this.mem.total;
79c34a
+        this.stats['mem-user'].values.push(t);
79c34a
+        t += (this.mem.used - this.mem.user - this.mem.cached) / this.mem.total;
79c34a
+        this.stats['mem-other'].values.push(t);
79c34a
+        t += this.mem.cached / this.mem.total;
79c34a
+        this.stats['mem-cached'].values.push(t);
79c34a
+    }
79c34a
+});
79c34a
+
79c34a
+const INDICATORS = [CpuIndicator, MemoryIndicator];
79c34a
+
79c34a
+const Extension = new Lang.Class({
79c34a
+    Name: 'SystemMonitor.Extension',
79c34a
+
79c34a
+    _init: function() {
79c34a
+	Convenience.initTranslations();
79c34a
+
79c34a
+	this._showLabelTimeoutId = 0;
79c34a
+	this._resetHoverTimeoutId = 0;
79c34a
+	this._labelShowing = false;
79c34a
+    },
79c34a
+
79c34a
+    enable: function() {
79c34a
+	this._box = new St.BoxLayout({ style_class: 'extension-systemMonitor-container',
79c34a
+				       x_align: Clutter.ActorAlign.START,
79c34a
+				       x_expand: true });
79c34a
+	this._indicators = [ ];
79c34a
+
79c34a
+	for (let i = 0; i < INDICATORS.length; i++) {
79c34a
+	    let indicator = new (INDICATORS[i])();
79c34a
+
79c34a
+            indicator.actor.connect('notify::hover', Lang.bind(this, function() {
79c34a
+		this._onHover(indicator);
79c34a
+	    }));
79c34a
+	    this._box.add_actor(indicator.actor);
79c34a
+	    this._indicators.push(indicator);
79c34a
+	}
79c34a
+
79c34a
+	this._boxHolder = new St.BoxLayout({ x_expand: true,
79c34a
+					     y_expand: true,
79c34a
+					     x_align: Clutter.ActorAlign.START,
79c34a
+					   });
79c34a
+	let menuButton = Main.messageTray._messageTrayMenuButton.actor;
79c34a
+	Main.messageTray.actor.remove_child(menuButton);
79c34a
+	Main.messageTray.actor.add_child(this._boxHolder);
79c34a
+
79c34a
+	this._boxHolder.add_child(this._box);
79c34a
+	this._boxHolder.add_child(menuButton);
79c34a
+    },
79c34a
+
79c34a
+    disable: function() {
79c34a
+	this._indicators.forEach(function(i) { i.destroy(); });
79c34a
+
79c34a
+	let menuButton = Main.messageTray._messageTrayMenuButton.actor;
79c34a
+	this._boxHolder.remove_child(menuButton);
79c34a
+	Main.messageTray.actor.add_child(menuButton);
79c34a
+
79c34a
+	this._box.destroy();
79c34a
+	this._boxHolder.destroy();
79c34a
+    },
79c34a
+
79c34a
+    _onHover: function (item) {
79c34a
+        if (item.actor.get_hover()) {
79c34a
+            if (this._showLabelTimeoutId == 0) {
79c34a
+                let timeout = this._labelShowing ? 0 : ITEM_HOVER_TIMEOUT;
79c34a
+                this._showLabelTimeoutId = Mainloop.timeout_add(timeout,
79c34a
+                    Lang.bind(this, function() {
79c34a
+                        this._labelShowing = true;
79c34a
+                        item.showLabel();
79c34a
+                        return false;
79c34a
+                    }));
79c34a
+                if (this._resetHoverTimeoutId > 0) {
79c34a
+                    Mainloop.source_remove(this._resetHoverTimeoutId);
79c34a
+                    this._resetHoverTimeoutId = 0;
79c34a
+                }
79c34a
+            }
79c34a
+        } else {
79c34a
+            if (this._showLabelTimeoutId > 0)
79c34a
+                Mainloop.source_remove(this._showLabelTimeoutId);
79c34a
+            this._showLabelTimeoutId = 0;
79c34a
+            item.hideLabel();
79c34a
+            if (this._labelShowing) {
79c34a
+                this._resetHoverTimeoutId = Mainloop.timeout_add(ITEM_HOVER_TIMEOUT,
79c34a
+                    Lang.bind(this, function() {
79c34a
+                        this._labelShowing = false;
79c34a
+                        return false;
79c34a
+                    }));
79c34a
+            }
79c34a
+        }
79c34a
+    },
79c34a
+});
79c34a
+
79c34a
+function init() {
79c34a
+    return new Extension();
79c34a
+}
79c34a
diff --git a/extensions/systemMonitor/meson.build b/extensions/systemMonitor/meson.build
79c34a
new file mode 100644
79c34a
index 0000000..48504f6
79c34a
--- /dev/null
79c34a
+++ b/extensions/systemMonitor/meson.build
79c34a
@@ -0,0 +1,5 @@
79c34a
+extension_data += configure_file(
79c34a
+  input: metadata_name + '.in',
79c34a
+  output: metadata_name,
79c34a
+  configuration: metadata_conf
79c34a
+)
79c34a
diff --git a/extensions/systemMonitor/metadata.json.in b/extensions/systemMonitor/metadata.json.in
79c34a
new file mode 100644
79c34a
index 0000000..fa75007
79c34a
--- /dev/null
79c34a
+++ b/extensions/systemMonitor/metadata.json.in
79c34a
@@ -0,0 +1,11 @@
79c34a
+{
79c34a
+    "shell-version": ["@shell_current@" ],
79c34a
+    "uuid": "@uuid@",
79c34a
+    "extension-id": "@extension_id@",
79c34a
+    "settings-schema": "@gschemaname@",
79c34a
+    "gettext-domain": "@gettext_domain@",
79c34a
+    "original-author": "zaspire@rambler.ru",
79c34a
+    "name": "SystemMonitor",
79c34a
+    "description": "System monitor showing CPU and memory usage in the message tray.",
79c34a
+    "url": "@url@"
79c34a
+}
79c34a
diff --git a/extensions/systemMonitor/stylesheet.css b/extensions/systemMonitor/stylesheet.css
79c34a
new file mode 100644
79c34a
index 0000000..13f95ec
79c34a
--- /dev/null
79c34a
+++ b/extensions/systemMonitor/stylesheet.css
79c34a
@@ -0,0 +1,35 @@
79c34a
+.extension-systemMonitor-container {
79c34a
+    spacing: 5px;
79c34a
+    padding-left: 5px;
79c34a
+    padding-right: 5px;
79c34a
+    padding-bottom: 10px;
79c34a
+    padding-top: 10px;
79c34a
+}
79c34a
+
79c34a
+.extension-systemMonitor-indicator-area {
79c34a
+    border: 1px solid #8d8d8d;
79c34a
+    border-radius: 3px;
79c34a
+    width: 100px;
79c34a
+    /* message tray is 72px, so 20px padding of the container,
79c34a
+       2px of border, makes it 50px */
79c34a
+    height: 50px;
79c34a
+    -grid-color: #575757;
79c34a
+    -cpu-total-color: rgb(0,154,62);
79c34a
+    -cpu-user-color: rgb(69,154,0);
79c34a
+    -cpu-sys-color: rgb(255,253,81);
79c34a
+    -cpu-iowait-color: rgb(210,148,0);
79c34a
+    -mem-user-color: rgb(210,148,0);
79c34a
+    -mem-cached-color: rgb(90,90,90);
79c34a
+    -mem-other-color: rgb(205,203,41);
79c34a
+    background-color: #1e1e1e;
79c34a
+}
79c34a
+
79c34a
+.extension-systemMonitor-indicator-label {
79c34a
+    border-radius: 7px;
79c34a
+    padding: 4px 12px;
79c34a
+    background-color: rgba(0,0,0,0.9);
79c34a
+    text-align: center;
79c34a
+    -y-offset: 8px;
79c34a
+    font-size: 9pt;
79c34a
+    font-weight: bold;
79c34a
+}
79c34a
diff --git a/meson.build b/meson.build
79c34a
index 201c484..cde2d34 100644
79c34a
--- a/meson.build
79c34a
+++ b/meson.build
79c34a
@@ -57,6 +57,7 @@ all_extensions += [
79c34a
   'native-window-placement',
79c34a
   'no-hot-corner',
79c34a
   'panel-favorites',
79c34a
+  'systemMonitor',
79c34a
   'top-icons',
79c34a
   'updates-dialog',
79c34a
   'user-theme'
79c34a
-- 
79c34a
2.20.1
79c34a
79c34a
79c34a
From a0583c021dd74378618139d760b2c4d6d528f11a Mon Sep 17 00:00:00 2001
79c34a
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
79c34a
Date: Wed, 17 May 2017 19:31:58 +0200
79c34a
Subject: [PATCH 2/4] systemMonitor: Move indicators to calendar
79c34a
79c34a
The message tray joined the invisible choir, so we have to find
79c34a
a new home for the extension UI. The message list in the calendar
79c34a
drop-down looks like the best option, given that it replaced the
79c34a
old tray (and also took over the old keyboard shortcut to bring
79c34a
it up quickly).
79c34a
---
79c34a
 extensions/systemMonitor/extension.js   | 56 ++++++++++++-------------
79c34a
 extensions/systemMonitor/stylesheet.css | 14 -------
79c34a
 2 files changed, 28 insertions(+), 42 deletions(-)
79c34a
79c34a
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
79c34a
index 7b09df0..1388a1f 100644
79c34a
--- a/extensions/systemMonitor/extension.js
79c34a
+++ b/extensions/systemMonitor/extension.js
79c34a
@@ -4,10 +4,12 @@ const Clutter = imports.gi.Clutter;
79c34a
 const GTop = imports.gi.GTop;
79c34a
 const Lang = imports.lang;
79c34a
 const Mainloop = imports.mainloop;
79c34a
+const Signals = imports.signals;
79c34a
 const St = imports.gi.St;
79c34a
 const Shell = imports.gi.Shell;
79c34a
 
79c34a
 const Main = imports.ui.main;
79c34a
+const MessageList = imports.ui.messageList;
79c34a
 const Tweener = imports.ui.tweener;
79c34a
 
79c34a
 const Gettext = imports.gettext.domain('gnome-shell-extensions');
79c34a
@@ -29,18 +31,21 @@ const Indicator = new Lang.Class({
79c34a
 
79c34a
     _init: function() {
79c34a
         this._initValues();
79c34a
-        this.drawing_area = new St.DrawingArea({ reactive: true });
79c34a
+        this.drawing_area = new St.DrawingArea();
79c34a
         this.drawing_area.connect('repaint', Lang.bind(this, this._draw));
79c34a
-        this.drawing_area.connect('button-press-event', function() {
79c34a
+
79c34a
+        this.actor = new St.Button({ style_class: "message message-content extension-systemMonitor-indicator-area",
79c34a
+				      x_expand: true, x_fill: true,
79c34a
+                                      y_fill: true, can_focus: true });
79c34a
+        this.actor.add_actor(this.drawing_area);
79c34a
+
79c34a
+        this.actor.connect('clicked', function() {
79c34a
             let app = Shell.AppSystem.get_default().lookup_app('gnome-system-monitor.desktop');
79c34a
             app.open_new_window(-1);
79c34a
-            return true;
79c34a
-        });
79c34a
 
79c34a
-        this.actor = new St.Bin({ style_class: "extension-systemMonitor-indicator-area",
79c34a
-                                  reactive: true, track_hover: true,
79c34a
-				  x_fill: true, y_fill: true });
79c34a
-        this.actor.add_actor(this.drawing_area);
79c34a
+            Main.overview.hide();
79c34a
+            Main.panel.closeCalendar();
79c34a
+        });
79c34a
 
79c34a
         this._timeout = Mainloop.timeout_add(INDICATOR_UPDATE_INTERVAL, Lang.bind(this, function () {
79c34a
             this._updateValues();
79c34a
@@ -73,6 +78,7 @@ const Indicator = new Lang.Class({
79c34a
         let y = stageY - this.label.get_height() - yOffset;
79c34a
 
79c34a
         this.label.set_position(x, y);
79c34a
+        this.label.get_parent().set_child_above_sibling(this.label, null);
79c34a
         Tweener.addTween(this.label,
79c34a
                          { opacity: 255,
79c34a
                            time: ITEM_LABEL_SHOW_TIME,
79c34a
@@ -100,6 +106,14 @@ const Indicator = new Lang.Class({
79c34a
                          });
79c34a
     },
79c34a
 
79c34a
+    /* MessageList.Message boilerplate */
79c34a
+    canClose: function() {
79c34a
+        return false;
79c34a
+    },
79c34a
+
79c34a
+    clear: function() {
79c34a
+    },
79c34a
+
79c34a
     destroy: function() {
79c34a
         Mainloop.source_remove(this._timeout);
79c34a
 
79c34a
@@ -194,6 +208,7 @@ const Indicator = new Lang.Class({
79c34a
         }
79c34a
     }
79c34a
 });
79c34a
+Signals.addSignalMethods(Indicator.prototype); // For MessageList.Message compat
79c34a
 
79c34a
 const CpuIndicator = new Lang.Class({
79c34a
     Name: 'SystemMonitor.CpuIndicator',
79c34a
@@ -302,9 +317,7 @@ const Extension = new Lang.Class({
79c34a
     },
79c34a
 
79c34a
     enable: function() {
79c34a
-	this._box = new St.BoxLayout({ style_class: 'extension-systemMonitor-container',
79c34a
-				       x_align: Clutter.ActorAlign.START,
79c34a
-				       x_expand: true });
79c34a
+	this._section = new MessageList.MessageListSection(_("System Monitor"));
79c34a
 	this._indicators = [ ];
79c34a
 
79c34a
 	for (let i = 0; i < INDICATORS.length; i++) {
79c34a
@@ -313,31 +326,18 @@ const Extension = new Lang.Class({
79c34a
             indicator.actor.connect('notify::hover', Lang.bind(this, function() {
79c34a
 		this._onHover(indicator);
79c34a
 	    }));
79c34a
-	    this._box.add_actor(indicator.actor);
79c34a
+	    this._section.addMessage(indicator, false);
79c34a
 	    this._indicators.push(indicator);
79c34a
 	}
79c34a
 
79c34a
-	this._boxHolder = new St.BoxLayout({ x_expand: true,
79c34a
-					     y_expand: true,
79c34a
-					     x_align: Clutter.ActorAlign.START,
79c34a
-					   });
79c34a
-	let menuButton = Main.messageTray._messageTrayMenuButton.actor;
79c34a
-	Main.messageTray.actor.remove_child(menuButton);
79c34a
-	Main.messageTray.actor.add_child(this._boxHolder);
79c34a
-
79c34a
-	this._boxHolder.add_child(this._box);
79c34a
-	this._boxHolder.add_child(menuButton);
79c34a
+        Main.panel.statusArea.dateMenu._messageList._addSection(this._section);
79c34a
+        this._section.actor.get_parent().set_child_at_index(this._section.actor, 0);
79c34a
     },
79c34a
 
79c34a
     disable: function() {
79c34a
 	this._indicators.forEach(function(i) { i.destroy(); });
79c34a
 
79c34a
-	let menuButton = Main.messageTray._messageTrayMenuButton.actor;
79c34a
-	this._boxHolder.remove_child(menuButton);
79c34a
-	Main.messageTray.actor.add_child(menuButton);
79c34a
-
79c34a
-	this._box.destroy();
79c34a
-	this._boxHolder.destroy();
79c34a
+        Main.panel.statusArea.dateMenu._messageList._removeSection(this._section);
79c34a
     },
79c34a
 
79c34a
     _onHover: function (item) {
79c34a
diff --git a/extensions/systemMonitor/stylesheet.css b/extensions/systemMonitor/stylesheet.css
79c34a
index 13f95ec..978ac12 100644
79c34a
--- a/extensions/systemMonitor/stylesheet.css
79c34a
+++ b/extensions/systemMonitor/stylesheet.css
79c34a
@@ -1,17 +1,4 @@
79c34a
-.extension-systemMonitor-container {
79c34a
-    spacing: 5px;
79c34a
-    padding-left: 5px;
79c34a
-    padding-right: 5px;
79c34a
-    padding-bottom: 10px;
79c34a
-    padding-top: 10px;
79c34a
-}
79c34a
-
79c34a
 .extension-systemMonitor-indicator-area {
79c34a
-    border: 1px solid #8d8d8d;
79c34a
-    border-radius: 3px;
79c34a
-    width: 100px;
79c34a
-    /* message tray is 72px, so 20px padding of the container,
79c34a
-       2px of border, makes it 50px */
79c34a
     height: 50px;
79c34a
     -grid-color: #575757;
79c34a
     -cpu-total-color: rgb(0,154,62);
79c34a
@@ -21,7 +8,6 @@
79c34a
     -mem-user-color: rgb(210,148,0);
79c34a
     -mem-cached-color: rgb(90,90,90);
79c34a
     -mem-other-color: rgb(205,203,41);
79c34a
-    background-color: #1e1e1e;
79c34a
 }
79c34a
 
79c34a
 .extension-systemMonitor-indicator-label {
79c34a
-- 
79c34a
2.20.1
79c34a
79c34a
79c34a
From a56d2c1c5546b6f1a6bf66f168874860b427bf9f Mon Sep 17 00:00:00 2001
79c34a
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
79c34a
Date: Thu, 18 May 2017 16:20:07 +0200
79c34a
Subject: [PATCH 3/4] systemMonitor: Handle clicks on section title
79c34a
79c34a
While on 3.24.x only the event section still has a clickable title,
79c34a
it's a generic message list feature in previous versions. It's easy
79c34a
enough to support with a small subclass, so use that instead of
79c34a
the generic baseclass.
79c34a
79c34a
Fixes: #3
79c34a
---
79c34a
 extensions/systemMonitor/extension.js | 20 +++++++++++++++++++-
79c34a
 1 file changed, 19 insertions(+), 1 deletion(-)
79c34a
79c34a
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
79c34a
index 1388a1f..9c010d8 100644
79c34a
--- a/extensions/systemMonitor/extension.js
79c34a
+++ b/extensions/systemMonitor/extension.js
79c34a
@@ -303,6 +303,24 @@ const MemoryIndicator = new Lang.Class({
79c34a
     }
79c34a
 });
79c34a
 
79c34a
+const SystemMonitorSection = new Lang.Class({
79c34a
+    Name: 'SystemMonitorSection',
79c34a
+    Extends: MessageList.MessageListSection,
79c34a
+
79c34a
+    _init: function() {
79c34a
+        this.parent(_("System Monitor"));
79c34a
+    },
79c34a
+
79c34a
+    _onTitleClicked: function() {
79c34a
+        this.parent();
79c34a
+
79c34a
+        let appSys = Shell.AppSystem.get_default();
79c34a
+        let app = appSys.lookup_app('gnome-system-monitor.desktop');
79c34a
+        if (app)
79c34a
+            app.open_new_window(-1);
79c34a
+    }
79c34a
+});
79c34a
+
79c34a
 const INDICATORS = [CpuIndicator, MemoryIndicator];
79c34a
 
79c34a
 const Extension = new Lang.Class({
79c34a
@@ -317,7 +335,7 @@ const Extension = new Lang.Class({
79c34a
     },
79c34a
 
79c34a
     enable: function() {
79c34a
-	this._section = new MessageList.MessageListSection(_("System Monitor"));
79c34a
+	this._section = new SystemMonitorSection();
79c34a
 	this._indicators = [ ];
79c34a
 
79c34a
 	for (let i = 0; i < INDICATORS.length; i++) {
79c34a
-- 
79c34a
2.20.1
79c34a
79c34a
79c34a
From 0b22b3fb2f05a098408437d9cd48482fddc24766 Mon Sep 17 00:00:00 2001
79c34a
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
79c34a
Date: Thu, 18 May 2017 18:00:17 +0200
79c34a
Subject: [PATCH 4/4] systemMonitor: Provide classic styling
79c34a
79c34a
The indicator tooltips currently don't work out in classic mode
79c34a
(dark text on dark background), so provide some mode-specific
79c34a
style.
79c34a
79c34a
Fixes: #4
79c34a
---
79c34a
 extensions/systemMonitor/classic.css | 6 ++++++
79c34a
 extensions/systemMonitor/meson.build | 4 ++++
79c34a
 2 files changed, 10 insertions(+)
79c34a
 create mode 100644 extensions/systemMonitor/classic.css
79c34a
79c34a
diff --git a/extensions/systemMonitor/classic.css b/extensions/systemMonitor/classic.css
79c34a
new file mode 100644
79c34a
index 0000000..946863d
79c34a
--- /dev/null
79c34a
+++ b/extensions/systemMonitor/classic.css
79c34a
@@ -0,0 +1,6 @@
79c34a
+@import url("stylesheet.css");
79c34a
+
79c34a
+.extension-systemMonitor-indicator-label {
79c34a
+    background-color: rgba(237,237,237,0.9);
79c34a
+    border: 1px solid #a1a1a1;
79c34a
+}
79c34a
diff --git a/extensions/systemMonitor/meson.build b/extensions/systemMonitor/meson.build
79c34a
index 48504f6..b6548b1 100644
79c34a
--- a/extensions/systemMonitor/meson.build
79c34a
+++ b/extensions/systemMonitor/meson.build
79c34a
@@ -3,3 +3,7 @@ extension_data += configure_file(
79c34a
   output: metadata_name,
79c34a
   configuration: metadata_conf
79c34a
 )
79c34a
+
79c34a
+if classic_mode_enabled
79c34a
+  extension_data += files('classic.css')
79c34a
+endif
79c34a
-- 
79c34a
2.20.1
79c34a