Blame SOURCES/resurrect-system-monitor.patch

2b8871
From 7c3b0af4fde0b542089f2b0c84250404eef0ecca 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
2b8871
Subject: [PATCH 1/5] 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
2b8871
index 6e8c41f..6764f9a 100644
79c34a
--- a/meson.build
79c34a
+++ b/meson.build
2b8871
@@ -55,6 +55,7 @@ all_extensions += [
79c34a
   'native-window-placement',
79c34a
   'no-hot-corner',
79c34a
   'panel-favorites',
79c34a
+  'systemMonitor',
79c34a
   'top-icons',
79c34a
   'updates-dialog',
2b8871
   'user-theme',
79c34a
-- 
2b8871
2.21.0
79c34a
79c34a
2b8871
From ddf4d70df56321366a2cb8b89689d59be4dbb718 Mon Sep 17 00:00:00 2001
79c34a
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
2b8871
Date: Fri, 17 May 2019 22:55:48 +0000
2b8871
Subject: [PATCH 2/5] systemMonitor: Modernise code
79c34a
2b8871
 - port to ES6 classes
2b8871
 - replace Lang.bind()
2b8871
 - destructure imports
2b8871
 - fix style issues (stray/missing spaces/semi-colons, indent, ...)
79c34a
---
2b8871
 extensions/systemMonitor/extension.js | 377 +++++++++++++-------------
2b8871
 1 file changed, 192 insertions(+), 185 deletions(-)
79c34a
79c34a
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
2b8871
index 7b09df0..89f8916 100644
79c34a
--- a/extensions/systemMonitor/extension.js
79c34a
+++ b/extensions/systemMonitor/extension.js
2b8871
@@ -1,22 +1,16 @@
2b8871
 /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
79c34a
 
2b8871
-const Clutter = imports.gi.Clutter;
2b8871
-const GTop = imports.gi.GTop;
2b8871
-const Lang = imports.lang;
2b8871
-const Mainloop = imports.mainloop;
2b8871
-const St = imports.gi.St;
2b8871
-const Shell = imports.gi.Shell;
2b8871
+/* exported init */
2b8871
 
2b8871
+const { Clutter, GLib, GTop, Shell, St } = imports.gi;
2b8871
+
2b8871
+const ExtensionUtils = imports.misc.extensionUtils;
79c34a
 const Main = imports.ui.main;
79c34a
 const Tweener = imports.ui.tweener;
79c34a
 
79c34a
 const Gettext = imports.gettext.domain('gnome-shell-extensions');
2b8871
 const _ = Gettext.gettext;
2b8871
 
2b8871
-const ExtensionUtils = imports.misc.extensionUtils;
2b8871
-const Me = ExtensionUtils.getCurrentExtension();
2b8871
-const Convenience = Me.imports.convenience;
2b8871
-
2b8871
 const INDICATOR_UPDATE_INTERVAL = 500;
2b8871
 const INDICATOR_NUM_GRID_LINES = 3;
79c34a
 
2b8871
@@ -24,32 +18,38 @@ const ITEM_LABEL_SHOW_TIME = 0.15;
2b8871
 const ITEM_LABEL_HIDE_TIME = 0.1;
2b8871
 const ITEM_HOVER_TIMEOUT = 300;
2b8871
 
2b8871
-const Indicator = new Lang.Class({
2b8871
-    Name: 'SystemMonitor.Indicator',
2b8871
-
2b8871
-    _init: function() {
2b8871
+const Indicator = class {
2b8871
+    constructor() {
79c34a
         this._initValues();
79c34a
-        this.drawing_area = new St.DrawingArea({ reactive: true });
2b8871
-        this.drawing_area.connect('repaint', Lang.bind(this, this._draw));
79c34a
-        this.drawing_area.connect('button-press-event', function() {
2b8871
+        this._drawingArea = new St.DrawingArea({ reactive: true });
2b8871
+        this._drawingArea.connect('repaint', this._draw.bind(this));
2b8871
+        this._drawingArea.connect('button-press-event', () => {
79c34a
             let app = Shell.AppSystem.get_default().lookup_app('gnome-system-monitor.desktop');
79c34a
             app.open_new_window(-1);
2b8871
             return true;
2b8871
         });
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);
2b8871
+        this.actor = new St.Bin({
2b8871
+            style_class: 'extension-systemMonitor-indicator-area',
2b8871
+            reactive: true,
2b8871
+            track_hover: true,
2b8871
+            x_fill: true,
2b8871
+            y_fill: true
79c34a
+        });
2b8871
+        this.actor.add_actor(this._drawingArea);
79c34a
 
2b8871
-        this._timeout = Mainloop.timeout_add(INDICATOR_UPDATE_INTERVAL, Lang.bind(this, function () {
2b8871
-            this._updateValues();
2b8871
-            this.drawing_area.queue_repaint();
2b8871
-            return true;
2b8871
-        }));
2b8871
-    },
2b8871
+        this.actor.connect('destroy', this._onDestroy.bind(this));
2b8871
 
2b8871
-    showLabel: function() {
2b8871
+        this._timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
2b8871
+            INDICATOR_UPDATE_INTERVAL,
2b8871
+            () => {
2b8871
+                this._updateValues();
2b8871
+                this._drawingArea.queue_repaint();
2b8871
+                return GLib.SOURCE_CONTINUE;
2b8871
+            });
2b8871
+    }
2b8871
+
2b8871
+    showLabel() {
2b8871
         if (this.label == null)
2b8871
             return;
2b8871
 
2b8871
@@ -58,12 +58,10 @@ const Indicator = new Lang.Class({
2b8871
 
2b8871
         let [stageX, stageY] = this.actor.get_transformed_position();
2b8871
 
2b8871
-	let itemWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
2b8871
-        let itemHeight = this.actor.allocation.y2 - this.actor.allocation.y1;
2b8871
+        let itemWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
2b8871
 
2b8871
-	let labelWidth = this.label.width;
2b8871
-        let labelHeight = this.label.height;
2b8871
-        let xOffset = Math.floor((itemWidth - labelWidth) / 2)
2b8871
+        let labelWidth = this.label.width;
2b8871
+        let xOffset = Math.floor((itemWidth - labelWidth) / 2);
2b8871
 
2b8871
         let x = stageX + xOffset;
2b8871
 
2b8871
@@ -73,48 +71,51 @@ const Indicator = new Lang.Class({
79c34a
         let y = stageY - this.label.get_height() - yOffset;
79c34a
 
79c34a
         this.label.set_position(x, y);
2b8871
-        Tweener.addTween(this.label,
2b8871
-                         { opacity: 255,
2b8871
-                           time: ITEM_LABEL_SHOW_TIME,
2b8871
-                           transition: 'easeOutQuad',
2b8871
-                         });
2b8871
-    },
2b8871
-
2b8871
-    setLabelText: function(text) {
2b8871
+        Tweener.addTween(this.label, {
2b8871
+            opacity: 255,
2b8871
+            time: ITEM_LABEL_SHOW_TIME,
2b8871
+            transition: 'easeOutQuad',
2b8871
+        });
2b8871
+    }
2b8871
+
2b8871
+    setLabelText(text) {
2b8871
         if (this.label == null)
2b8871
-            this.label = new St.Label({ style_class: 'extension-systemMonitor-indicator-label'});
2b8871
+            this.label = new St.Label({
2b8871
+                style_class: 'extension-systemMonitor-indicator-label'
2b8871
+            });
79c34a
 
2b8871
         this.label.set_text(text);
2b8871
         Main.layoutManager.addChrome(this.label);
2b8871
         this.label.hide();
2b8871
-    },
2b8871
-
2b8871
-    hideLabel: function () {
2b8871
-        Tweener.addTween(this.label,
2b8871
-                         { opacity: 0,
2b8871
-                           time: ITEM_LABEL_HIDE_TIME,
2b8871
-                           transition: 'easeOutQuad',
2b8871
-                           onComplete: Lang.bind(this, function() {
2b8871
-                               this.label.hide();
2b8871
-                           })
2b8871
-                         });
2b8871
-    },
2b8871
-
2b8871
-    destroy: function() {
2b8871
-        Mainloop.source_remove(this._timeout);
2b8871
+    }
2b8871
 
2b8871
+    hideLabel() {
2b8871
+        Tweener.addTween(this.label, {
2b8871
+            opacity: 0,
2b8871
+            time: ITEM_LABEL_HIDE_TIME,
2b8871
+            transition: 'easeOutQuad',
2b8871
+            onComplete: () => this.label.hide()
2b8871
+        });
2b8871
+    }
79c34a
+
2b8871
+    destroy() {
2b8871
         this.actor.destroy();
2b8871
-	if (this.label)
2b8871
-	    this.label.destroy();
2b8871
-    },
2b8871
+    }
2b8871
+
2b8871
+    _onDestroy() {
2b8871
+        GLib.source_remove(this._timeout);
79c34a
+
2b8871
+        if (this.label)
2b8871
+            this.label.destroy();
2b8871
+    }
2b8871
 
2b8871
-    _initValues: function() {
2b8871
-    },
2b8871
+    _initValues() {
2b8871
+    }
79c34a
 
2b8871
-    _updateValues: function() {
2b8871
-    },
2b8871
+    _updateValues() {
2b8871
+    }
2b8871
 
2b8871
-    _draw: function(area) {
2b8871
+    _draw(area) {
2b8871
         let [width, height] = area.get_surface_size();
2b8871
         let themeNode = this.actor.get_theme_node();
2b8871
         let cr = area.get_context();
2b8871
@@ -123,12 +124,12 @@ const Indicator = new Lang.Class({
2b8871
         let color = themeNode.get_color(this.gridColor);
2b8871
         let gridOffset = Math.floor(height / (INDICATOR_NUM_GRID_LINES + 1));
2b8871
         for (let i = 1; i <= INDICATOR_NUM_GRID_LINES; ++i) {
2b8871
-                cr.moveTo(0, i * gridOffset + .5);
2b8871
-                cr.lineTo(width, i * gridOffset + .5);
2b8871
+            cr.moveTo(0, i * gridOffset + .5);
2b8871
+            cr.lineTo(width, i * gridOffset + .5);
2b8871
         }
2b8871
         Clutter.cairo_set_source_color(cr, color);
2b8871
         cr.setLineWidth(1);
2b8871
-        cr.setDash([4,1], 0);
2b8871
+        cr.setDash([4, 1], 0);
2b8871
         cr.stroke();
2b8871
 
2b8871
         //draw the foreground
2b8871
@@ -155,12 +156,12 @@ const Indicator = new Lang.Class({
2b8871
         let renderStats = this.renderStats;
2b8871
 
2b8871
         // Make sure we don't have more sample points than pixels
2b8871
-        renderStats.map(Lang.bind(this, function(k){
2b8871
+        renderStats.map(k => {
2b8871
             let stat = this.stats[k];
2b8871
             if (stat.values.length > width) {
2b8871
                 stat.values = stat.values.slice(stat.values.length - width, stat.values.length);
2b8871
             }
2b8871
-        }));
2b8871
+        });
2b8871
 
2b8871
         for (let i = 0; i < renderStats.length; ++i) {
2b8871
             let stat = this.stats[renderStats[i]];
2b8871
@@ -178,10 +179,10 @@ const Indicator = new Lang.Class({
2b8871
                 cr.lineTo(0, height);
2b8871
                 cr.closePath();
2b8871
             } else {
2b8871
-                let nextStat = this.stats[renderStats[i+1]];
2b8871
+                let nextStat = this.stats[renderStats[i + 1]];
2b8871
                 makePath(nextStat.values, true);
2b8871
             }
2b8871
-            cr.closePath()
2b8871
+            cr.closePath();
2b8871
             Clutter.cairo_set_source_color(cr, color);
2b8871
             cr.fill();
2b8871
 
2b8871
@@ -193,40 +194,42 @@ const Indicator = new Lang.Class({
2b8871
             cr.stroke();
79c34a
         }
79c34a
     }
2b8871
-});
2b8871
-
2b8871
-const CpuIndicator = new Lang.Class({
2b8871
-    Name: 'SystemMonitor.CpuIndicator',
2b8871
-    Extends: Indicator,
2b8871
+};
79c34a
 
2b8871
-    _init: function() {
2b8871
-        this.parent();
2b8871
+const CpuIndicator = class extends Indicator {
2b8871
+    constructor() {
2b8871
+        super();
79c34a
 
2b8871
         this.gridColor = '-grid-color';
2b8871
-        this.renderStats = [ 'cpu-user', 'cpu-sys', 'cpu-iowait' ];
2b8871
+        this.renderStats = ['cpu-user', 'cpu-sys', 'cpu-iowait'];
2b8871
 
2b8871
         // Make sure renderStats is sorted as necessary for rendering
2b8871
-        let renderStatOrder = {'cpu-total': 0, 'cpu-user': 1, 'cpu-sys': 2, 'cpu-iowait': 3};
2b8871
-        this.renderStats = this.renderStats.sort(function(a,b) {
2b8871
+        let renderStatOrder = {
2b8871
+            'cpu-total': 0,
2b8871
+            'cpu-user': 1,
2b8871
+            'cpu-sys': 2,
2b8871
+            'cpu-iowait': 3
2b8871
+        };
2b8871
+        this.renderStats = this.renderStats.sort((a, b) => {
2b8871
             return renderStatOrder[a] - renderStatOrder[b];
2b8871
         });
2b8871
 
2b8871
-	this.setLabelText(_("CPU"));
2b8871
-    },
2b8871
+        this.setLabelText(_('CPU'));
2b8871
+    }
2b8871
 
2b8871
-    _initValues: function() {
2b8871
+    _initValues() {
2b8871
         this._prev = new GTop.glibtop_cpu;
2b8871
         GTop.glibtop_get_cpu(this._prev);
2b8871
 
2b8871
         this.stats = {
2b8871
-                       'cpu-user': {color: '-cpu-user-color', values: []},
2b8871
-                       'cpu-sys': {color: '-cpu-sys-color', values: []},
2b8871
-                       'cpu-iowait': {color: '-cpu-iowait-color', values: []},
2b8871
-                       'cpu-total': {color: '-cpu-total-color', values: []}
2b8871
-                     };
2b8871
-    },
2b8871
-
2b8871
-    _updateValues: function() {
2b8871
+            'cpu-user': { color: '-cpu-user-color', values: [] },
2b8871
+            'cpu-sys': { color: '-cpu-sys-color', values: [] },
2b8871
+            'cpu-iowait': { color: '-cpu-iowait-color', values: [] },
2b8871
+            'cpu-total': { color: '-cpu-total-color', values: [] }
2b8871
+        };
2b8871
+    }
2b8871
+
2b8871
+    _updateValues() {
2b8871
         let cpu = new GTop.glibtop_cpu;
2b8871
         let t = 0.0;
2b8871
         GTop.glibtop_get_cpu(cpu);
2b8871
@@ -246,37 +249,34 @@ const CpuIndicator = new Lang.Class({
2b8871
 
2b8871
         this._prev = cpu;
2b8871
     }
2b8871
-});
2b8871
+};
2b8871
 
2b8871
-const MemoryIndicator = new Lang.Class({
2b8871
-    Name: 'SystemMonitor.MemoryIndicator',
2b8871
-    Extends: Indicator,
2b8871
-
2b8871
-    _init: function() {
2b8871
-        this.parent();
2b8871
+const MemoryIndicator = class extends Indicator {
2b8871
+    constructor() {
2b8871
+        super();
2b8871
 
2b8871
         this.gridColor = '-grid-color';
2b8871
-        this.renderStats = [ 'mem-user', 'mem-other', 'mem-cached' ];
2b8871
+        this.renderStats = ['mem-user', 'mem-other', 'mem-cached'];
2b8871
 
2b8871
         // Make sure renderStats is sorted as necessary for rendering
2b8871
         let renderStatOrder = { 'mem-cached': 0, 'mem-other': 1, 'mem-user': 2 };
2b8871
-        this.renderStats = this.renderStats.sort(function(a,b) {
2b8871
+        this.renderStats = this.renderStats.sort((a, b) => {
2b8871
             return renderStatOrder[a] - renderStatOrder[b];
2b8871
         });
2b8871
 
2b8871
-	this.setLabelText(_("Memory"));
2b8871
-    },
2b8871
+        this.setLabelText(_('Memory'));
2b8871
+    }
2b8871
 
2b8871
-    _initValues: function() {
2b8871
+    _initValues() {
2b8871
         this.mem = new GTop.glibtop_mem;
2b8871
         this.stats = {
2b8871
-                        'mem-user': { color: "-mem-user-color", values: [] },
2b8871
-                        'mem-other': { color: "-mem-other-color", values: [] },
2b8871
-                        'mem-cached': { color: "-mem-cached-color", values: [] }
2b8871
-                     };
2b8871
-    },
2b8871
+            'mem-user': { color: '-mem-user-color', values: [] },
2b8871
+            'mem-other': { color: '-mem-other-color', values: [] },
2b8871
+            'mem-cached': { color: '-mem-cached-color', values: [] }
2b8871
+        };
2b8871
+    }
2b8871
 
2b8871
-    _updateValues: function() {
2b8871
+    _updateValues() {
2b8871
         GTop.glibtop_get_mem(this.mem);
2b8871
 
2b8871
         let t = this.mem.user / this.mem.total;
2b8871
@@ -286,90 +286,97 @@ const MemoryIndicator = new Lang.Class({
2b8871
         t += this.mem.cached / this.mem.total;
2b8871
         this.stats['mem-cached'].values.push(t);
2b8871
     }
2b8871
-});
2b8871
+};
2b8871
 
2b8871
 const INDICATORS = [CpuIndicator, MemoryIndicator];
2b8871
 
2b8871
-const Extension = new Lang.Class({
2b8871
-    Name: 'SystemMonitor.Extension',
2b8871
-
2b8871
-    _init: function() {
2b8871
-	Convenience.initTranslations();
2b8871
-
2b8871
-	this._showLabelTimeoutId = 0;
2b8871
-	this._resetHoverTimeoutId = 0;
2b8871
-	this._labelShowing = false;
2b8871
-    },
2b8871
-
2b8871
-    enable: function() {
79c34a
-	this._box = new St.BoxLayout({ style_class: 'extension-systemMonitor-container',
79c34a
-				       x_align: Clutter.ActorAlign.START,
79c34a
-				       x_expand: true });
2b8871
-	this._indicators = [ ];
2b8871
-
2b8871
-	for (let i = 0; i < INDICATORS.length; i++) {
2b8871
-	    let indicator = new (INDICATORS[i])();
2b8871
-
2b8871
-            indicator.actor.connect('notify::hover', Lang.bind(this, function() {
2b8871
-		this._onHover(indicator);
2b8871
-	    }));
79c34a
-	    this._box.add_actor(indicator.actor);
2b8871
-	    this._indicators.push(indicator);
2b8871
-	}
2b8871
-
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);
2b8871
-    },
2b8871
-
2b8871
-    disable: function() {
2b8871
-	this._indicators.forEach(function(i) { i.destroy(); });
2b8871
-
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();
2b8871
-    },
2b8871
-
2b8871
-    _onHover: function (item) {
2b8871
+class Extension {
2b8871
+    constructor() {
2b8871
+        ExtensionUtils.initTranslations();
2b8871
+
2b8871
+        this._showLabelTimeoutId = 0;
2b8871
+        this._resetHoverTimeoutId = 0;
2b8871
+        this._labelShowing = false;
2b8871
+    }
2b8871
+
2b8871
+    enable() {
2b8871
+        this._box = new St.BoxLayout({
2b8871
+            style_class: 'extension-systemMonitor-container',
2b8871
+            x_align: Clutter.ActorAlign.START,
2b8871
+            x_expand: true
2b8871
+        });
2b8871
+        this._indicators = [];
2b8871
+
2b8871
+        for (let i = 0; i < INDICATORS.length; i++) {
2b8871
+            let indicator = new (INDICATORS[i])();
2b8871
+
2b8871
+            indicator.actor.connect('notify::hover', () => {
2b8871
+                this._onHover(indicator);
2b8871
+            });
2b8871
+            this._box.add_actor(indicator.actor);
2b8871
+            this._indicators.push(indicator);
2b8871
+        }
2b8871
+
2b8871
+        this._boxHolder = new St.BoxLayout({
2b8871
+            x_expand: true,
2b8871
+            y_expand: true,
2b8871
+            x_align: Clutter.ActorAlign.START,
2b8871
+        });
2b8871
+        let menuButton = Main.messageTray._messageTrayMenuButton.actor;
2b8871
+        Main.messageTray.actor.remove_child(menuButton);
2b8871
+        Main.messageTray.actor.add_child(this._boxHolder);
2b8871
+
2b8871
+        this._boxHolder.add_child(this._box);
2b8871
+        this._boxHolder.add_child(menuButton);
2b8871
+    }
2b8871
+
2b8871
+    disable() {
2b8871
+        this._indicators.forEach(i => i.destroy());
2b8871
+
2b8871
+        let menuButton = Main.messageTray._messageTrayMenuButton.actor;
2b8871
+        this._boxHolder.remove_child(menuButton);
2b8871
+        Main.messageTray.actor.add_child(menuButton);
2b8871
+
2b8871
+        this._box.destroy();
2b8871
+        this._boxHolder.destroy();
2b8871
+    }
2b8871
+
2b8871
+    _onHover(item) {
2b8871
         if (item.actor.get_hover()) {
2b8871
-            if (this._showLabelTimeoutId == 0) {
2b8871
-                let timeout = this._labelShowing ? 0 : ITEM_HOVER_TIMEOUT;
2b8871
-                this._showLabelTimeoutId = Mainloop.timeout_add(timeout,
2b8871
-                    Lang.bind(this, function() {
2b8871
-                        this._labelShowing = true;
2b8871
-                        item.showLabel();
2b8871
-                        return false;
2b8871
-                    }));
2b8871
-                if (this._resetHoverTimeoutId > 0) {
2b8871
-                    Mainloop.source_remove(this._resetHoverTimeoutId);
2b8871
-                    this._resetHoverTimeoutId = 0;
2b8871
-                }
2b8871
+            if (this._showLabelTimeoutId)
2b8871
+                return;
2b8871
+
2b8871
+            let timeout = this._labelShowing ? 0 : ITEM_HOVER_TIMEOUT;
2b8871
+            this._showLabelTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
2b8871
+                timeout,
2b8871
+                () => {
2b8871
+                    this._labelShowing = true;
2b8871
+                    item.showLabel();
2b8871
+                    this._showLabelTimeoutId = 0;
2b8871
+                    return GLib.SOURCE_REMOVE;
2b8871
+                });
2b8871
+
2b8871
+            if (this._resetHoverTimeoutId > 0) {
2b8871
+                GLib.source_remove(this._resetHoverTimeoutId);
2b8871
+                this._resetHoverTimeoutId = 0;
2b8871
             }
2b8871
         } else {
2b8871
             if (this._showLabelTimeoutId > 0)
2b8871
-                Mainloop.source_remove(this._showLabelTimeoutId);
2b8871
+                GLib.source_remove(this._showLabelTimeoutId);
2b8871
             this._showLabelTimeoutId = 0;
2b8871
             item.hideLabel();
2b8871
-            if (this._labelShowing) {
2b8871
-                this._resetHoverTimeoutId = Mainloop.timeout_add(ITEM_HOVER_TIMEOUT,
2b8871
-                    Lang.bind(this, function() {
2b8871
-                        this._labelShowing = false;
2b8871
-                        return false;
2b8871
-                    }));
2b8871
-            }
2b8871
+            if (!this._labelShowing)
2b8871
+                return;
2b8871
+
2b8871
+            this._resetHoverTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
2b8871
+                ITEM_HOVER_TIMEOUT,
2b8871
+                () => {
2b8871
+                    this._labelShowing = false;
2b8871
+                    return GLib.SOURCE_REMOVE;
2b8871
+                });
2b8871
         }
2b8871
-    },
2b8871
-});
2b8871
+    }
2b8871
+}
2b8871
 
2b8871
 function init() {
2b8871
     return new Extension();
2b8871
-- 
2b8871
2.21.0
2b8871
2b8871
2b8871
From e7ea49cd416e8ede9767f5ade46a06764d1e9a5b Mon Sep 17 00:00:00 2001
2b8871
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
2b8871
Date: Wed, 17 May 2017 19:31:58 +0200
2b8871
Subject: [PATCH 3/5] systemMonitor: Move indicators to calendar
2b8871
2b8871
The message tray joined the invisible choir, so we have to find
2b8871
a new home for the extension UI. The message list in the calendar
2b8871
drop-down looks like the best option, given that it replaced the
2b8871
old tray (and also took over the old keyboard shortcut to bring
2b8871
it up quickly).
2b8871
---
2b8871
 extensions/systemMonitor/extension.js   | 65 ++++++++++++-------------
2b8871
 extensions/systemMonitor/stylesheet.css | 14 ------
2b8871
 2 files changed, 31 insertions(+), 48 deletions(-)
2b8871
2b8871
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
2b8871
index 89f8916..0188960 100644
2b8871
--- a/extensions/systemMonitor/extension.js
2b8871
+++ b/extensions/systemMonitor/extension.js
2b8871
@@ -3,9 +3,11 @@
2b8871
 /* exported init */
2b8871
 
2b8871
 const { Clutter, GLib, GTop, Shell, St } = imports.gi;
2b8871
+const Signals = imports.signals;
2b8871
 
2b8871
 const ExtensionUtils = imports.misc.extensionUtils;
2b8871
 const Main = imports.ui.main;
2b8871
+const MessageList = imports.ui.messageList;
2b8871
 const Tweener = imports.ui.tweener;
2b8871
 
2b8871
 const Gettext = imports.gettext.domain('gnome-shell-extensions');
2b8871
@@ -21,22 +23,25 @@ const ITEM_HOVER_TIMEOUT = 300;
2b8871
 const Indicator = class {
2b8871
     constructor() {
2b8871
         this._initValues();
2b8871
-        this._drawingArea = new St.DrawingArea({ reactive: true });
2b8871
+        this._drawingArea = new St.DrawingArea();
2b8871
         this._drawingArea.connect('repaint', this._draw.bind(this));
2b8871
-        this._drawingArea.connect('button-press-event', () => {
2b8871
+
2b8871
+        this.actor = new St.Button({
2b8871
+            style_class: 'message message-content extension-systemMonitor-indicator-area',
2b8871
+            child: this._drawingArea,
2b8871
+            x_expand: true,
2b8871
+            x_fill: true,
2b8871
+            y_fill: true,
2b8871
+            can_focus: true
2b8871
+        });
2b8871
+
2b8871
+        this.actor.connect('clicked', () => {
2b8871
             let app = Shell.AppSystem.get_default().lookup_app('gnome-system-monitor.desktop');
2b8871
             app.open_new_window(-1);
2b8871
-            return true;
2b8871
-        });
2b8871
 
2b8871
-        this.actor = new St.Bin({
2b8871
-            style_class: 'extension-systemMonitor-indicator-area',
2b8871
-            reactive: true,
2b8871
-            track_hover: true,
2b8871
-            x_fill: true,
2b8871
-            y_fill: true
2b8871
+            Main.overview.hide();
2b8871
+            Main.panel.closeCalendar();
2b8871
         });
2b8871
-        this.actor.add_actor(this._drawingArea);
2b8871
 
2b8871
         this.actor.connect('destroy', this._onDestroy.bind(this));
2b8871
 
2b8871
@@ -71,6 +76,7 @@ const Indicator = class {
2b8871
         let y = stageY - this.label.get_height() - yOffset;
2b8871
 
2b8871
         this.label.set_position(x, y);
2b8871
+        this.label.get_parent().set_child_above_sibling(this.label, null);
2b8871
         Tweener.addTween(this.label, {
2b8871
             opacity: 255,
2b8871
             time: ITEM_LABEL_SHOW_TIME,
2b8871
@@ -98,6 +104,14 @@ const Indicator = class {
2b8871
         });
2b8871
     }
2b8871
 
2b8871
+    /* MessageList.Message boilerplate */
2b8871
+    canClose() {
2b8871
+        return false;
2b8871
+    }
2b8871
+
2b8871
+    clear() {
2b8871
+    }
2b8871
+
2b8871
     destroy() {
2b8871
         this.actor.destroy();
2b8871
     }
2b8871
@@ -195,6 +209,7 @@ const Indicator = class {
2b8871
         }
2b8871
     }
2b8871
 };
2b8871
+Signals.addSignalMethods(Indicator.prototype); // For MessageList.Message compat
2b8871
 
2b8871
 const CpuIndicator = class extends Indicator {
2b8871
     constructor() {
2b8871
@@ -300,11 +315,7 @@ class Extension {
2b8871
     }
2b8871
 
2b8871
     enable() {
2b8871
-        this._box = new St.BoxLayout({
2b8871
-            style_class: 'extension-systemMonitor-container',
2b8871
-            x_align: Clutter.ActorAlign.START,
2b8871
-            x_expand: true
2b8871
-        });
2b8871
+        this._section = new MessageList.MessageListSection(_('System Monitor'));
2b8871
         this._indicators = [];
2b8871
 
2b8871
         for (let i = 0; i < INDICATORS.length; i++) {
2b8871
@@ -313,32 +324,18 @@ class Extension {
2b8871
             indicator.actor.connect('notify::hover', () => {
2b8871
                 this._onHover(indicator);
2b8871
             });
2b8871
-            this._box.add_actor(indicator.actor);
2b8871
+            this._section.addMessage(indicator, false);
2b8871
             this._indicators.push(indicator);
2b8871
         }
2b8871
 
2b8871
-        this._boxHolder = new St.BoxLayout({
2b8871
-            x_expand: true,
2b8871
-            y_expand: true,
2b8871
-            x_align: Clutter.ActorAlign.START,
2b8871
-        });
2b8871
-        let menuButton = Main.messageTray._messageTrayMenuButton.actor;
2b8871
-        Main.messageTray.actor.remove_child(menuButton);
2b8871
-        Main.messageTray.actor.add_child(this._boxHolder);
2b8871
-
2b8871
-        this._boxHolder.add_child(this._box);
2b8871
-        this._boxHolder.add_child(menuButton);
2b8871
+        Main.panel.statusArea.dateMenu._messageList._addSection(this._section);
2b8871
+        this._section.actor.get_parent().set_child_at_index(this._section.actor, 0);
2b8871
     }
2b8871
 
2b8871
     disable() {
2b8871
         this._indicators.forEach(i => i.destroy());
2b8871
 
2b8871
-        let menuButton = Main.messageTray._messageTrayMenuButton.actor;
2b8871
-        this._boxHolder.remove_child(menuButton);
2b8871
-        Main.messageTray.actor.add_child(menuButton);
2b8871
-
2b8871
-        this._box.destroy();
2b8871
-        this._boxHolder.destroy();
79c34a
+        Main.panel.statusArea.dateMenu._messageList._removeSection(this._section);
2b8871
     }
79c34a
 
2b8871
     _onHover(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
-- 
2b8871
2.21.0
79c34a
79c34a
2b8871
From f73fe9cfb5f9dbd6647e4eb30a9af0fb7ff79219 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
2b8871
Subject: [PATCH 4/5] 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
2b8871
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell-extensions3
79c34a
---
2b8871
 extensions/systemMonitor/extension.js | 17 ++++++++++++++++-
2b8871
 1 file changed, 16 insertions(+), 1 deletion(-)
79c34a
79c34a
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
2b8871
index 0188960..b4d5a9d 100644
79c34a
--- a/extensions/systemMonitor/extension.js
79c34a
+++ b/extensions/systemMonitor/extension.js
2b8871
@@ -303,6 +303,21 @@ const MemoryIndicator = class extends Indicator {
79c34a
     }
2b8871
 };
79c34a
 
2b8871
+class SystemMonitorSection extends MessageList.MessageListSection {
2b8871
+    constructor() {
2b8871
+        super(_('System Monitor'));
2b8871
+    }
79c34a
+
2b8871
+    _onTitleClicked() {
2b8871
+        super._onTitleClicked();
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
+    }
2b8871
+}
79c34a
+
79c34a
 const INDICATORS = [CpuIndicator, MemoryIndicator];
79c34a
 
2b8871
 class Extension {
2b8871
@@ -315,7 +330,7 @@ class Extension {
2b8871
     }
79c34a
 
2b8871
     enable() {
2b8871
-        this._section = new MessageList.MessageListSection(_('System Monitor'));
2b8871
+        this._section = new SystemMonitorSection();
2b8871
         this._indicators = [];
79c34a
 
2b8871
         for (let i = 0; i < INDICATORS.length; i++) {
79c34a
-- 
2b8871
2.21.0
79c34a
79c34a
2b8871
From df76e98d6bbac7dccc86f66e82eac2977fb5ed87 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
2b8871
Subject: [PATCH 5/5] 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
-- 
2b8871
2.21.0
79c34a