Blame SOURCES/resurrect-system-monitor.patch

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