I am writing a simple extension to open browser by clicking the extension button. I would like to know if there is a function which can execute passed shell command as argument. Also, it'd be really helpful if anyone can suggest a good simple reference for extension development.
From https://github.com/GNOME/gnome-shell/blob/master/js/misc/util.js:
// Runs @command_line in the background, handling any errors that
// occur when trying to parse or start the program.
function spawnCommandLine(command_line) {
try {
let [success, argv] = GLib.shell_parse_argv(command_line);
trySpawn(argv);
} catch (err) {
_handleSpawnError(command_line, err);
}
}
There are a few variations on that method in there. Save yourself mountains of headaches and just bookmark the GitHub repository.
Some quick links:
- popupMenu.js: working with popup menus
- panel.js: a good read for implementing "tray" icons
- modalDialog.js: some UI elements were made to be reused, runDialog.js uses this for example
- mpris.js: there are also good examples of using frameworks like DBus in gjs
I can't stress enough how much you'll get out of reading the gnome-shell source. Unfortunately, it's compiled into a resource file now so we don't have local copies to stumble upon.
UPDATE (2021)
If you're reading this, please instead see the documentation available on gjs.guide. Specifically the documentation on Spawning Subprocesses, which covers why this is a bad idea in extensions and how to do it slightly less bad.
const Util = imports.misc.util; Util.spawnCommandLine("...");
–
Basion sudo
? Do you include sudo
in your command, or will Gnome ask for password window-style? –
Epitasis pkexec
or maybe gksudo
. –
Basion communicate_utf8(stdin_buf, cancellable)
does the job for me –
Revolute Utils
functions) to the answer, as it is not obvious that these functions should be just imported without reading the comments. –
Repercussion If you're not interested in the result - i.e. when you want to open a browser window - you can just use GLib.spawn_command_line_async like so:
const GLib = imports.gi.GLib;
...
(this._menuEntries[i]).connect('activate', () => {
GLib.spawn_command_line_async('firefox http://example.com?p='+ my_params[i]);
});
If you need a synchronous result, read https://gjs.guide/guides/gio/subprocesses.html
© 2022 - 2024 — McMap. All rights reserved.