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