-
Notifications
You must be signed in to change notification settings - Fork 599
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to run multiple instances of AwesomeWM and communicate between them with dbus #3949
Comments
This would require to strip out the window management code from the "other" processes (and most of |
i understand that inter-communication could be tricky and be implemented in different approaches, however for starters i'm more curious, how complicated could be implementing |
To my understanding, |
What's the use case, even? But what's the use case for this when all of it stays within Awesome anyways? What do you need separate processes for? |
because rendering panels in the same thread as doing window-management stuff is cringe and also should allow using awesome panels/widgets with hyprland |
Making Awesome multithreading and making Awesome do what Hyprland does is a better approach IMO. |
@joaopauloalbq are you willing to contribute that code..? |
also some after-thoughts:
|
I worked a few hours on a new command line parameter to allow Awesome to be used as a Lua interpreter My primary target for such a feature is to allow running busted with a custom Lua interpreter to have an environment where tests could include Awesome specificities, similar to what https://github.com/mfussenegger/nlua does. It would allow writing integration tests without the current "start Awesome in some nested X server and play the test as a configuration" trick. With a long term vision, my work here could be used to allow running parts of Awesome without the actual WM, so I guess it's worth mentioning it here. I have the early work done, the option can be used, and the base interpreter is starting. And obviously, with a runner script and some config for busted, we can run some tests with Awesome as the Lua interpreter: runner #!/usr/bin/env -S awesome -e
local runner = require "busted.runner"
runner { standalone = false } .busted return {
_all = {
lua = "./runner",
lpath = "/usr/share/awesome/lib/?.lua;/usr/share/awesome/lib/?/init.lua;/usr/share/awesome/lib/?/?.lua",
},
} spec/awesome_spec.lua if os.getenv "LOCAL_LUA_DEBUGGER_VSCODE" == "1" then
require("lldebugger").start()
end
describe("awesome", function()
it("should have access to awesome CAPIs", function()
local capi = {
awesome = _G.awesome,
client = _G.client,
screen = _G.screen,
tag = _G.tag,
}
assert.is_not_nil(capi.client)
assert.is_not_nil(capi.screen)
assert.is_not_nil(capi.tag)
end)
it("should require awesome libraries", function()
assert.has_no.errors(function()
require "gears"
require "awful"
-- require "beautiful"
-- require "naughty"
-- require "wibox"
end)
end)
end) It has to be noted that the only result for all of that are crashes 🥲:
It was obvious that without X stuff, I couldn't have gone far. But I hoped it would have been a little further than that, and I would have had the time to have some fun. My personal conclusion to this little experiment is that it's probably not worth putting more effort into this work, regarding my primary target (which was to run Awesome as a Lua interpreter for Busted tests). If we have to stub/fake half the APIs because we don't have X, there is no reason to force my test to use Awesome as the Lua interpreter. I can write a helper that exposes fake Awesome Globals (just like Awesome unit tests already do) and call it a day. I wanted to run Awesome to have an environment with the C API, but without the X stuff, so basically without what the C API is supposed to be. At this point, why even run Awesome? duh! For those who want to use the Awesome Wibox API to build some applications, it may be interesting to take on the work from here. In the meantime, just use Awexygen (BTW https://github.com/xinhaoyuan/awexygen/blob/b91cd86eed36988a86da70f3f3713e443aa77be3/lib/awesome_rt/root.lua#L24-L26). So, yeah. That's what I did last night instead of sleeping... Anyway, here is the code: diff --git a/awesome.c b/awesome.c
index 2b17c725f..2d387a04e 100644
--- a/awesome.c
+++ b/awesome.c
@@ -560,6 +560,33 @@ true_config_callback(const char *unused)
return true;
}
+/** Run as a Lua interpreter and exit.
+ */
+static void
+interpreter(int argc, char **argv, int lua_arg0, string_array_t *searchpath)
+{
+ luaA_init(NULL, searchpath); // NULL xdgHandle, it seems to be unused anyway
+ string_array_wipe(searchpath);
+ init_rng();
+ ewmh_init_lua();
+ luaA_init_argv(argv, argc, lua_arg0);
+
+ lua_State *L = globalconf_get_lua_State();
+ bool success = true;
+
+ if(luaL_dofile(L, argv[lua_arg0]))
+ {
+ const char *err = lua_tostring(L, -1);
+ fprintf(stderr, "ERROR: %s\n", err);
+ success = false;
+ }
+
+ p_delete(searchpath);
+ lua_close(L);
+
+ exit(success ? EXIT_SUCCESS: EXIT_FAILURE);
+}
+
/** Hello, this is main.
* \param argc Who knows.
* \param argv Who knows.
@@ -590,6 +617,7 @@ main(int argc, char **argv)
globalconf.api_level = awesome_default_api_level();
buffer_init(&globalconf.startup_errors);
string_array_init(&searchpath);
+ int lua_argc = 0;
/* save argv */
awesome_argv = argv;
@@ -601,7 +629,7 @@ main(int argc, char **argv)
/* if no shebang is detected, check the args. Shebang (#!) args are parsed later */
if (!confpath)
- confpath = options_check_args(argc, argv, &default_init_flags, &searchpath);
+ confpath = options_check_args(argc, argv, &default_init_flags, &searchpath, &lua_argc);
/* Get XDG basedir data */
if(!xdgInitHandle(&xdg))
@@ -652,7 +680,13 @@ main(int argc, char **argv)
/* Parse `rc.lua` to see if it has an AwesomeWM modeline */
if (!(default_init_flags & INIT_FLAG_FORCE_CMD_ARGS))
- options_init_config(&xdg, awesome_argv[0], confpath, &default_init_flags, &searchpath);
+ options_init_config(&xdg, awesome_argv[0], confpath, &default_init_flags, &searchpath, &lua_argc);
+
+ /* Execute a Lua script and exit */
+ if (default_init_flags & INIT_FLAG_EXECUTE_LUA)
+ {
+ interpreter(argc, argv, lua_argc, &searchpath);
+ }
/* Setup pipe for SIGCHLD processing */
{
diff --git a/luaa.c b/luaa.c
index bf1800ce9..2377e28a8 100644
--- a/luaa.c
+++ b/luaa.c
@@ -1351,4 +1351,28 @@ luaA_default_newindex(lua_State *L)
return luaA_class_newindex_miss_property(L, NULL);
}
+/** Copies arguments starting at lua_arg0 to _G.arg
+ * based on https://github.com/neovim/neovim/blob/master/src/nvim/lua/executor.c#L347
+*/
+int
+luaA_init_argv(char **argv, int argc, int lua_arg0)
+{
+ lua_State *L = globalconf_get_lua_State();
+ int i = 0;
+ lua_newtable(L); // _G.arg
+
+ if (lua_arg0 > 0) {
+ lua_pushstring(L, argv[lua_arg0 - 1]);
+ lua_rawseti(L, -2, 0);
+
+ for (; i + lua_arg0 < argc; i++) {
+ lua_pushstring(L, argv[i + lua_arg0]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ }
+
+ lua_setglobal(L, "arg");
+ return i;
+}
+
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/luaa.h b/luaa.h
index 04e283422..676344f5e 100644
--- a/luaa.h
+++ b/luaa.h
@@ -331,5 +331,7 @@ void luaA_emit_startup(void);
void luaA_systray_invalidate(void);
+int luaA_init_argv(char **argv, int argc, int lua_arg0);
+
#endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/options.c b/options.c
index 3ef88b563..5efb6181f 100644
--- a/options.c
+++ b/options.c
@@ -72,7 +72,7 @@ push_arg(string_array_t *args, char *value, size_t *len)
* Support both shebang and modeline modes.
*/
bool
-options_init_config(xdgHandle *xdg, char *execpath, char *configpath, int *init_flags, string_array_t *paths)
+options_init_config(xdgHandle *xdg, char *execpath, char *configpath, int *init_flags, string_array_t *paths, int *lua_argc)
{
/* The different state the parser can have. */
enum {
@@ -318,7 +318,7 @@ options_init_config(xdgHandle *xdg, char *execpath, char *configpath, int *init_
/* Be future proof, allow let unknown keys live, let the Lua code decide */
(*init_flags) |= INIT_FLAG_ALLOW_FALLBACK;
- options_check_args(argv.len, argv.tab, init_flags, paths);
+ options_check_args(argv.len, argv.tab, init_flags, paths, lua_argc);
/* Cleanup */
string_array_wipe(&argv);
@@ -402,29 +402,31 @@ exit_help(int exit_code)
#define NO_ARG 0
char *
-options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths)
+options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths, int *lua_argc)
{
static struct option long_options[] =
{
- { "help" , NO_ARG, NULL, 'h' },
- { "version" , NO_ARG, NULL, 'v' },
- { "config" , ARG , NULL, 'c' },
- { "force" , NO_ARG, NULL, 'f' },
- { "check" , NO_ARG, NULL, 'k' },
- { "search" , ARG , NULL, 's' },
- { "no-argb" , NO_ARG, NULL, 'a' },
- { "replace" , NO_ARG, NULL, 'r' },
- { "screen" , ARG , NULL, 'm' },
- { "api-level" , ARG , NULL, 'l' },
- { "reap" , ARG , NULL, '\1' },
- { NULL , NO_ARG, NULL, 0 }
+ { "help" , NO_ARG, NULL, 'h' },
+ { "version" , NO_ARG, NULL, 'v' },
+ { "config" , ARG , NULL, 'c' },
+ { "force" , NO_ARG, NULL, 'f' },
+ { "check" , NO_ARG, NULL, 'k' },
+ { "search" , ARG , NULL, 's' },
+ { "no-argb" , NO_ARG, NULL, 'a' },
+ { "replace" , NO_ARG, NULL, 'r' },
+ { "screen" , ARG , NULL, 'm' },
+ { "api-level" , ARG , NULL, 'l' },
+ { "execute-lua", NO_ARG, NULL, 'e' }, // break out of the loop, everything after this parameter should be passed to the Lua interpreter
+ { "reap" , ARG , NULL, '\1' },
+ { NULL , NO_ARG, NULL, 0 }
};
char *confpath = NULL;
int opt;
+ int opt_position = 1; // 0 is the program name, getopt_long loop starts at argv[1]
- while((opt = getopt_long(argc, argv, "vhfkc:arms:l:",
+ while((opt = getopt_long(argc, argv, "vhfkc:arms:l:e:",
long_options, NULL)) != -1) {
switch(opt)
{
@@ -473,6 +475,18 @@ options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths
case 'l':
set_api_level(optarg);
break;
+ case 'e':
+ (*init_flags) |= INIT_FLAG_EXECUTE_LUA;
+ // --execute-lua is supposed to be the last parameter, followed by the Lua script and its parameters
+ if (opt_position + 1 < argc) {
+ *lua_argc = opt_position + 1;
+ return NULL; // No config file to load
+ }
+ else {
+ fprintf(stderr, "No Lua code to execute\n");
+ exit(EXIT_FAILURE);
+ }
+ break;
case '\1':
/* Silently ignore --reap and its argument */
break;
@@ -480,7 +494,9 @@ options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths
if (! ((*init_flags) & INIT_FLAG_ALLOW_FALLBACK))
exit_help(EXIT_FAILURE);
break;
- }}
+ }
+ opt_position++;
+ }
return confpath;
}
diff --git a/options.h b/options.h
index 97e66e8c8..569eb946c 100644
--- a/options.h
+++ b/options.h
@@ -32,8 +32,9 @@ typedef enum {
INIT_FLAG_AUTO_SCREEN = 0x1 << 3,
INIT_FLAG_ALLOW_FALLBACK = 0x1 << 4,
INIT_FLAG_FORCE_CMD_ARGS = 0x1 << 5,
+ INIT_FLAG_EXECUTE_LUA = 0x1 << 6,
} awesome_init_config_t;
char *options_detect_shebang(int argc, char **argv);
-bool options_init_config(xdgHandle *xdg, char *execpath, char *configpath, int *init_flags, string_array_t *paths);
-char *options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths);
+bool options_init_config(xdgHandle *xdg, char *execpath, char *configpath, int *init_flags, string_array_t *paths, int *lua_argc);
+char *options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths, int *lua_argc); |
thanks for sharing, @Aire-One i'm overall looking positive towards merging smth like that - as it would decrease the "diff surface" of things which would need to be changed for that nowm/toolkit thing btw getting back to the thing about using awesomewm as UI toolkit, if we'll move into that direction, i could also contribute the code for matching not only xresources/gtk3 themes but also gtk4 and qt5/qt6 (i have some drafts for that code already but not in lua, and not for all the theme variables). and would support that direction by porting Themix and some smaller GUI apps to that new toolkit (which would require adding python bindings - which as a result would add some, mb at first limited, python bindings to awesome wm itself*)
btw, fun fact: $ pacman -Qi awesome-luajit-git | grep Size
Installed Size : 34.54 MiB
$ pacman -Qi gtk{2,3,4} | grep Size
Installed Size : 36.47 MiB
Installed Size : 52.14 MiB
Installed Size : 46.50 MiB |
and regarding the awexygen i thought i wrote it in previous messages but apparently either forgot or mistakenly removed while typing other paragraphs: yeah, it looks similar to that final goal i wanna achieve, but its problem that it's a fork of awesome, while keeping smth similar inside existing codebase would take significantly less maintenance effort (and with the time it could be used to speed-up and decouple awesome by splitting it into different processes for panel, wm, notifications, sidebar and other user-defined features, or running all features with alternative WM even inside wayland) |
The concept is that i wanna hv smth like this in my init script:
and inside the config to hv smth like this:
and so on
WDYT?
The text was updated successfully, but these errors were encountered: