Javascript can't do multithreading, that's why calling Gtk.main();
breaks Cinnamon.
Cinnamon applet already runs a main loop and the call of Gtk.main();
tries to create another one.
So it's not possible to open a GtkWindow from a cinnamon applet directly in Javascript.
The solution could be to open a GtkWindow through a Python script, and to use DBus to communicate between the Cinnamon applet and the Python/GTK window.
Unable to open a GtkWindow from a cinnamon applet
سؤال
When I try to open a GtkWindow from a cinnamon applet, the entire desktop freezes.
No errors in the ~/.cinnamon/glass.log
file.
const Gtk = imports.gi.Gtk;
function MyApplet(orientation)
{
this._init(orientation);
}
MyApplet.prototype =
{
__proto__: Applet.IconApplet.prototype,
_init: function(orientation)
{
Applet.IconApplet.prototype._init.call(this, orientation);
try {
this.set_applet_icon_name("dialog-question");
this.set_applet_tooltip("test");
}
catch (e) {
global.logError(e);
};
},
on_applet_clicked: function(event)
{
Gtk.init(null, 0);
let mwindow = new Gtk.Window ({type : Gtk.WindowType.TOPLEVEL});
mwindow.title = "Hello World!";
mwindow.connect ("destroy", function(){Gtk.main_quit()});
mwindow.show();
Gtk.main();
}
};
function main(metadata, orientation)
{
let myApplet = new MyApplet(orientation);
return myApplet;
}
The code is executed until Gtk.main()
then no window is displayed and the desktop get frozen.
Anyone knows how to make it work correctly?
المحلول
نصائح أخرى
This is how you can do it:
const Gtk = imports.gi.Gtk;
const Util = imports.misc.util;
function MyApplet(orientation)
{
this._init(orientation);
}
MyApplet.prototype =
{
__proto__: Applet.IconApplet.prototype,
_init: function(orientation)
{
Applet.IconApplet.prototype._init.call(this, orientation);
try {
this.set_applet_icon_name("dialog-question");
this.set_applet_tooltip("test");
}
catch (e) {
global.logError(e);
};
},
on_applet_clicked: function(event)
{
//path to your applet directory; hardcoded for now!
let path="~/.local/share/cinnamon/applets/your_applet@you.org";
//create in your applet directory a file "yourgtkfile.js" and
//make it executable "chmod +x yourgtkfile.js"
Util.spawnCommandLine(path + "/yourgtkfile.js");
}
};
function main(metadata, orientation)
{
let myApplet = new MyApplet(orientation);
return myApplet;
}
You can copy/paste this in yourgtkfile.js. (Change #!/usr/bin/gjs with #!/usr/bin/cjs)
Or, this one (taken from here) (Change #!/usr/bin/gjs with #!/usr/bin/cjs):
#!/usr/bin/cjs
const Lang = imports.lang;
const Gtk = imports.gi.Gtk;
const Application = new Lang.Class({
//A Class requires an explicit Name parameter. This is the Class Name.
Name: 'Application',
//create the application
_init: function() {
this.application = new Gtk.Application();
//connect to 'activate' and 'startup' signals to handlers.
this.application.connect('activate', Lang.bind(this, this._onActivate));
this.application.connect('startup', Lang.bind(this, this._onStartup));
},
//create the UI
_buildUI: function() {
this._window = new Gtk.ApplicationWindow({ application: this.application,
title: "Hello World!" });
this._window.set_default_size(200, 200);
this.label = new Gtk.Label({ label: "Hello World" });
this._window.add(this.label);
},
//handler for 'activate' signal
_onActivate: function() {
//show the window and all child widgets
this._window.show_all();
},
//handler for 'startup' signal
_onStartup: function() {
this._buildUI();
}
});
//run the application
let app = new Application();
app.application.run(ARGV);
I supposed that you don't need to communicate with the app just launched :)
لا تنتمي إلى StackOverflow