1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-26 05:03:15 +00:00

1. Added support for KDE

2. Added zenity fallback for platforms where notify-send doesn't work correctly
This commit is contained in:
Bryan Roe
2019-05-18 02:48:27 -07:00
parent 020bae80a5
commit e28b5d7b0e
3 changed files with 163 additions and 85 deletions

File diff suppressed because one or more lines are too long

View File

@@ -129,17 +129,19 @@ function linux_messageBox()
this.create = function create(title, caption, timeout)
{
if (timeout == null) { timeout = 10; }
var zenity = '';
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
var zenity = '', kdialog = '';
var uid = require('user-sessions').consoleUid();
var xinfo = require('monitor-info').getXInfo(uid);
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("whereis zenity | awk '{ print $2 }'\nexit\n");
child.waitExit();
zenity = child.stdout.str.trim();
if (zenity == '') { throw ('Zenity not installed'); }
var uid = require('user-sessions').consoleUid();
var xinfo = require('monitor-info').getXInfo(uid);
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
if (zenity != '')
{
// GNOME/ZENITY
ret.child = require('child_process').execFile(zenity, ['zenity', '--question', '--title=' + title, '--text=' + caption, '--timeout=' + timeout], { uid: uid, env: { XAUTHORITY: xinfo.xauthority, DISPLAY: xinfo.display } });
ret.child.promise = ret;
ret.child.stderr.on('data', function (chunk) { });
@@ -159,7 +161,45 @@ function linux_messageBox()
break;
}
});
}
else
{
child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("whereis kdialog | awk '{ print $2 }'\nexit\n");
child.waitExit();
kdialog = child.stdout.str.trim();
if (kdialog == '') { ret._rej('Platform not supported (zenity or kdialog not found)'); return (ret); }
if (process.env['DISPLAY'])
{
ret.child = require('child_process').execFile(kdialog, ['kdialog', '--title', title, '--yesno', caption]);
ret.child.promise = ret;
}
else
{
var xdg = require('user-sessions').findEnv(uid, 'XDG_RUNTIME_DIR');
if (!xinfo || !xinfo.display || !xinfo.xauthority || !xdg) { ret._rej('Interal Error, could not determine X11/XDG env'); return (ret); }
ret.child = require('child_process').execFile(kdialog, ['kdialog', '--title', title, '--yesno', caption], { uid: uid, env: { DISPLAY: xinfo.display, XAUTHORITY: xinfo.xauthority, XDG_RUNTIME_DIR: xdg } });
ret.child.promise = ret;
}
ret.child.stdout.on('data', function (chunk) { });
ret.child.stderr.on('data', function (chunk) { });
ret.child.on('exit', function (code)
{
switch (code) {
case 0:
this.promise._res();
break;
case 1:
this.promise._rej('denied');
break;
default:
this.promise._rej('timeout');
break;
}
});
}
return (ret);

View File

@@ -14,23 +14,33 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
var toasters = {};
var promise = require('promise');
if (process.platform == 'linux')
{
function findPath(app)
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("whereis " + app + " | awk '{ print $2 }'\nexit\n");
child.waitExit();
child.stdout.str = child.stdout.str.trim();
return (child.stdout.str == '' ? null : child.stdout.str);
}
}
function Toaster()
{
this._ObjectID = 'toaster';
this.Toast = function Toast(title, caption)
{
var retVal = {};
var emitter = require('events').inherits(retVal);
emitter.createEvent('Dismissed');
var retVal = new promise(function (res, rej) { this._res = res; this._rej = rej; });
retVal.title = title;
retVal.caption = caption;
if (process.platform == 'win32')
{
emitter.createEvent('Clicked');
var GM = require('_GenericMarshal');
var kernel32 = GM.CreateNativeProxy('kernel32.dll');
kernel32.CreateMethod('ProcessIdToSessionId');
@@ -38,7 +48,7 @@ function Toaster()
var consoleUid = require('user-sessions').consoleUid();
if (kernel32.ProcessIdToSessionId(process.pid, psid).Val == 0)
{
throw ('Internal Error');
retVal._rej('internal error'); return (retVal);
}
if (consoleUid == psid.toBuffer().readUInt32LE())
@@ -52,7 +62,7 @@ function Toaster()
retVal._child = require('ScriptContainer').Create({ processIsolation: true, sessionId: consoleUid });
}
retVal._child.parent = retVal;
retVal._child.on('exit', function (code) { this.parent.emit('Dismissed'); delete this.parent._child; });
retVal._child.on('exit', function (code) { this.parent._res('DISMISSED'); });
retVal._child.addModule('win-console', getJSModule('win-console'));
retVal._child.addModule('win-message-pump', getJSModule('win-message-pump'));
@@ -69,76 +79,104 @@ function Toaster()
require('ScriptContainer').send('done');\
";
retVal._child.ExecuteString(str);
toasters[retVal._hashCode()] = retVal;
retVal.on('Dismissed', function () { delete toasters[this._hashCode()]; });
console.log('Returning');
return (retVal);
}
else
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("whereis notify-send | awk '{ print $2 }'\nexit\n");
child.waitExit();
if (child.stdout.str.trim() == '') {
// notify-send doesn't exist, lets check kdialog
child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("whereis kdialog | awk '{ print $2 }'\nexit\n");
child.waitExit();
if (child.stdout.str.trim() == '') { throw ('Toast not supported on this platform'); }
// Let's use kdialog
if (process.env['DISPLAY'])
try
{
retVal._notify = require('child_process').execFile(child.stdout.str.trim(), ['kdialog', '--title', retVal.title, '--passivepopup', retVal.caption, '5']);
retVal.consoleUid = require('user-sessions').consoleUid();
retVal.xinfo = require('monitor-info').getXInfo(retVal.consoleUid);
}
else
catch(xxe)
{
var consoleUid = require('user-sessions').consoleUid();
var xinfo = require('monitor-info').getXInfo(consoleUid);
var xdg = require('user-sessions').findEnv(consoleUid, 'XDG_RUNTIME_DIR');
if (!xinfo || !xinfo.display || !xinfo.xauthority || !xdg)
retVal._rej(xxe);
return (retVal);
}
var util = findPath('zenity');
if (util)
{
throw ('Internal Error');
}
retVal._notify = require('child_process').execFile(child.stdout.str.trim(), ['kdialog', '--title', retVal.title, '--passivepopup', retVal.caption, '5'], { uid: consoleUid, env: { DISPLAY: xinfo.display, XAUTHORITY: xinfo.xauthority, XDG_RUNTIME_DIR: xdg } });
}
retVal._notify.stdout.on('data', function (chunk) { });
retVal._notify.stderr.on('data', function (chunk) { });
retVal._notify.waitExit();
}
else
// Use ZENITY
retVal.child = require('child_process').execFile(util, ['zenity', '--notification', '--title=' + title, '--text=' + caption, '--timeout=5'], { uid: retVal.consoleUid, env: { XAUTHORITY: retVal.xinfo.xauthority, DISPLAY: retVal.xinfo.display } });
retVal.child.parent = retVal;
retVal.child.stderr.str = '';
retVal.child.stderr.on('data', function (chunk) { this.str += chunk.toString(); this.parent.kill(); });
retVal.child.stdout.on('data', function (chunk) { });
retVal.child.on('exit', function (code)
{
// Let's use notify-send
if(this.stderr.str.trim() != '')
{
if ((util = findPath('notify-send')) && this.stderr.str.split('GLib-CRITICAL').length > 1)
{
// This is a bug in zenity, so we should try notify-send
if (process.env['DISPLAY'])
{
// DISPLAY is set, so we good to go
retVal._notify = require('child_process').execFile(child.stdout.str.trim(), ['notify-send', retVal.title, retVal.caption]);
this.parent.child = require('child_process').execFile(util, ['notify-send', this.parent.title, this.parent.caption]);
this.parent.child.parent = this.parent;
}
else
{
// We need to find the DISPLAY to use
var consoleUid = require('user-sessions').consoleUid();
var username = require('user-sessions').getUsername(consoleUid);
var display = require('monitor-info').getXInfo(consoleUid).display;
retVal._notify = require('child_process').execFile('/bin/sh', ['sh']);
retVal._notify.stdin.write('su - ' + username + ' -c "DISPLAY=' + display + ' notify-send \'' + retVal.title + '\' \'' + retVal.caption + '\'"\n');
retVal._notify.stdin.write('exit\n');
this.parent.child = require('child_process').execFile('/bin/sh', ['sh']);
this.parent.child.parent = this.parent;
this.parent.child.stdin.write('su - ' + username + ' -c "DISPLAY=' + display + ' notify-send \'' + this.parent.title + '\' \'' + this.parent.caption + '\'"\n');
this.parent.child.stdin.write('exit\n');
}
this.parent.child.stdout.on('data', function (chunk) { });
this.parent.child.waitExit();
// NOTIFY-SEND has a bug where timeouts don't work, so the default is 5 seconds
this.parent._timeout = setTimeout(function onFakeDismissed(obj)
{
obj._res('DISMISSED');
}, 10000, this.parent);
}
else
{
// Fake a toast using zenity --info
util = findPath('zenity');
this.parent.child = require('child_process').execFile(util, ['zenity', '--info', '--title=' + this.parent.title, '--text=' + this.parent.caption, '--timeout=5'], { uid: this.parent.consoleUid, env: { XAUTHORITY: this.parent.xinfo.xauthority, DISPLAY: this.parent.xinfo.display } });
this.parent.child.parent = this.parent;
this.parent.child.stderr.on('data', function (chunk) { });
this.parent.child.stdout.on('data', function (chunk) { });
this.parent.child.on('exit', function (code)
{
this.parent._res('DISMISSED');
});
}
}
else
{
this.parent._res('DISMISSED');
}
});
}
else
{
util = findPath('kdialog');
if (util)
{
// use KDIALOG
var xdg = require('user-sessions').findEnv(retVal.consoleUid, 'XDG_RUNTIME_DIR');
if (!retVal.xinfo || !retVal.xinfo.display || !retVal.xinfo.xauthority || !xdg)
{
retVal._rej('Internal Error');
return (retVal);
}
retVal._notify = require('child_process').execFile(util, ['kdialog', '--title', retVal.title, '--passivepopup', retVal.caption, '5'], { uid: retVal.consoleUid, env: { DISPLAY: retVal.xinfo.display, XAUTHORITY: retVal.xinfo.xauthority, XDG_RUNTIME_DIR: xdg } });
retVal._notify.parent = retVal;
retVal._notify.stdout.on('data', function (chunk) { });
retVal._notify.waitExit();
// NOTIFY-SEND has a bug where timeouts don't work, so the default is 10 seconds
retVal._timeout = setTimeout(function onFakeDismissed(obj) {
obj.emit('Dismissed');
}, 10000, retVal);
toasters[retVal._hashCode()] = retVal;
retVal.on('Dismissed', function () { delete toasters[this._hashCode()]; });
retVal._notify.stderr.on('data', function (chunk) { });
retVal._notify.on('exit', function (code) { this.parent._res('DISMISSED'); });
}
else
{
retVal._rej ('Zenity/KDialog not found');
}
}
return (retVal);
}
};