titonbarua / shadow-cljs-gjs-target

A Gjs(Gnome Javascript Bindings) target for shadow-cljs compiler.
Other
41 stars 2 forks source link

WIP - Initial setup for gnome extension #2

Closed ieugen closed 3 years ago

ieugen commented 3 years ago

I would like to develop a Gnome Extension in ClojureScript

ieugen commented 3 years ago

cc @titonbarua

I've compiled the app and copied the extension files. Started an embedded wayland session to test it. I enabled the extension using the Extensions app.

I got this information in the terminal where I started the Wayland session:

I believe the GJS environment does not have a window object as shadow-cljs-gjs-target assumes. I believe another target is needed. One with imports as global.

cd examples/gnome-extension-demo/
npx shadow-cljs release app
cp clojurescript-demo@gnome-extensions.netdava.com/extension.js ~/.local/share/gnome-shell/extensions/clojurescript-demo@gnome-extensions.netdava.com/

# Copy the metadata.json and stylesheet.css as well 

#Open nested wayland, enable extension and watch terminal
dbus-run-session -- gnome-shell --nested --wayland
JS ERROR: Extension clojurescript-demo@gnome-extensions.netdava.com: TypeError: window.ARGV is undefined
@/home/ieugen/.local/share/gnome-shell/extensions/clojurescript-demo@gnome-extensions.netdava.com/extension.js:243:861
@/home/ieugen/.local/share/gnome-shell/extensions/clojurescript-demo@gnome-extensions.netdava.com/extension.js:244:3
_callExtensionInit@resource:///org/gnome/shell/ui/extensionSystem.js:420:13
_callExtensionEnable@resource:///org/gnome/shell/ui/extensionSystem.js:145:18
_onEnabledExtensionsChanged/<@resource:///org/gnome/shell/ui/extensionSystem.js:491:35
_onEnabledExtensionsChanged@resource:///org/gnome/shell/ui/extensionSystem.js:491:14
createCheckedMethod/<@resource:///org/gnome/gjs/modules/core/overrides/Gio.js:533:46
enableExtension@resource:///org/gnome/shell/ui/extensionSystem.js:194:29
EnableExtension@resource:///org/gnome/shell/ui/shellDBus.js:307:38
_handleMethodCall@resource:///org/gnome/gjs/modules/core/overrides/Gio.js:327:38
_wrapJSObject/<@resource:///org/gnome/gjs/modules/core/overrides/Gio.js:404:34
 tree ~/.local/share/gnome-shell/extensions/clojurescript-demo@gnome-extensions.netdava.com/
$HOME/.local/share/gnome-shell/extensions/clojurescript-demo@gnome-extensions.netdava.com/
├── extension.js
├── metadata.json
└── stylesheet.css
titonbarua commented 3 years ago

Could it be that the only ARGV key is undefined? Perhaps the gnome shell mechanism does not populate the key? window['ARGV'] is used to call the clojurescript main function. Take a look at this function: https://github.com/titonbarua/shadow-cljs-gjs-target/blob/0e5d98eb9bb8dbc94e40a08eccc4c1a7ee624891/src/shadow_cljs_gjs_target/core.clj#L81-L84

Perhaps we can change it so that ARGV is defined to an empty object if it is not called already.

ieugen commented 3 years ago

I have little experience with this.

All I know is that gnome shell expects a Javascript file that has some top level functions.

Looking at the code:

extension.js contains the following @extension.js:243:861

Zc(Je,window.ARGV.slice(0));

Where function Je(){return console.log("Extension initialized")}

I believe the issue here is that we should NOT call into the clojurescript main function. The shadow cljs compiler should just compile the functions and leave them be.

gjs will call the init, enable and disable functions when loading extension.js . We should be building a library, not executable code. I wonder if it will work with :target :node-library.

titonbarua commented 3 years ago

Good point. If you rewrite make-main-call-js to just return an empty string, the main function will not be called. You should experiment with that. I would very much like to be more helpful to you and get my hands dirty, but unfortunately I am little too busy with other things.

I am not sure if :node-library will be useful to you, but I would really like if you make the efforts available for merger with this project. Perhaps we can enable gnome-extension support with a custom flag?

ieugen commented 3 years ago

I managed to push something that works.

I created a new namespace to manage gnome extensions since IMO the code is different. I am doing some hacks to make sure the functions are visible.

(g/set js/global "init" init)
(g/set js/global "enable" enable)
(g/set js/global "disable" disable)

and

       (update :append str "var init = global.init; var disable = global.disable; var enable = global.enable"))]

But it works. I believe there we can avoid g/set js/global but I don't know how. Help is appreciated.

Also, let me know how do you want to move forward with this PR. Once it's done I would like to use it for a small app. I would also like to write an article about it once it's merged.

Clojure ScriptGnome Extension Demo-Message: 03:47:49.150: clojurescript-demo initialized
Clojure ScriptGnome Extension Demo-Message: 03:47:49.150: Clojure ScriptGnome Extension Demo
Clojure ScriptGnome Extension Demo-Message: 03:47:49.159: Enable clojurescript-demo extension
Clojure ScriptGnome Extension Demo-Message: 03:47:49.160: Clojure ScriptGnome Extension Demo

Captură de ecran de la 2020-11-21 03-31-44

titonbarua commented 3 years ago

Nice work! I am currently trying your to use your demo and looking into the mentioned minor issues.

titonbarua commented 3 years ago

Works as expected albeit with problems in release build.

Optimized build (or release build) has always been broken. Unfortunately, it will need some serious time investment to fix the issue. Also, proper exports are possible. We just need to look at node-library target.

Anyway, for now I think we are good to go. You might add a shell script to copy the built files and styles and metadata to the .local/share/** location. I will merge your PR and bump project version.

ieugen commented 3 years ago

Thanks. Things can be improved of course. I'll work on this when I have some time.