load script after initial registry burst
This makes the logic of installing idle handlers and layout handlers a bit cleaner and allows us to send wayland request from the script in the future.
This commit is contained in:
104
src/riverguile.c
104
src/riverguile.c
@@ -118,54 +118,66 @@ static const struct wl_registry_listener registry_listener = {
|
||||
.global_remove = registry_handle_global_remove,
|
||||
};
|
||||
|
||||
static void sync_handle_done (void *, struct wl_callback *, uint32_t);
|
||||
static const struct wl_callback_listener sync_callback_listener = {
|
||||
.done = sync_handle_done,
|
||||
};
|
||||
|
||||
static void sync_handle_done (void *data, struct wl_callback *wl_callback, uint32_t other_data)
|
||||
{
|
||||
static int i = 0;
|
||||
if ( i == 1 )
|
||||
{
|
||||
assert(context.mode == ONESHOT);
|
||||
context.loop = false;
|
||||
return;
|
||||
}
|
||||
|
||||
wl_callback_destroy(wl_callback);
|
||||
context.sync_callback = NULL;
|
||||
|
||||
if ( context.layout_manager == NULL )
|
||||
/* Load the script after connecting to the server and binding interfaces
|
||||
* to allow calling Wayland requests from it.
|
||||
*/
|
||||
assert(context.path != NULL);
|
||||
void *res = scm_with_guile(load_script, (void *)context.path);
|
||||
if ( res != NULL )
|
||||
{
|
||||
fputs("ERROR: Wayland server does not support river-layout-v3.\n", stderr);
|
||||
fputs((char *)res, stderr);
|
||||
context.ret = EXIT_FAILURE;
|
||||
context.loop = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( context.idle_notifier == NULL )
|
||||
if ( context.layout_demand_handler == NULL
|
||||
&& context.user_command_handler != NULL )
|
||||
{
|
||||
if ( wl_list_length(&context.unconfigured_idles) > 0 )
|
||||
{
|
||||
fputs("ERROR: Wayland server does not support ext-idle-notify-v1.\n", stderr);
|
||||
fputs("INFO: This error is not fatal.\n", stderr);
|
||||
}
|
||||
fputs("ERROR: Installing user-command handler without installing a layout-demand handler is not allowed.\n", stderr);
|
||||
fputs("INFO: This error is not fatal, but means riverguile will not provide any layout.\n", stderr);
|
||||
}
|
||||
else
|
||||
|
||||
switch (context.mode)
|
||||
{
|
||||
struct Seat *seat;
|
||||
wl_list_for_each(seat, &context.seats, link)
|
||||
case ONESHOT:
|
||||
/* Oneshot mode. Sync again so we are sure that all commands
|
||||
* have been send, then exit.
|
||||
*/
|
||||
assert(i == 0);
|
||||
i++;
|
||||
context.sync_callback = wl_display_sync(context.wl_display);
|
||||
wl_callback_add_listener(context.sync_callback, &sync_callback_listener, NULL);
|
||||
fputs("INFO: No handlers installed: Riverguile will exit.\n", stderr);
|
||||
break;
|
||||
|
||||
struct Idle *idle, *tmp_i;
|
||||
wl_list_for_each_safe(idle, tmp_i, &context.unconfigured_idles, link)
|
||||
idle_configure(idle, seat);
|
||||
case CONTINOUS:
|
||||
fputs("INFO: At least one handler installed: Riverguile will run continously.\n", stderr);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If outputs were registered before the river_layout_manager is
|
||||
* available, they won't have a river_layout, so we need to create
|
||||
* those here.
|
||||
*/
|
||||
struct Output *output;
|
||||
wl_list_for_each(output, &context.outputs, link)
|
||||
output_configure(output);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener sync_callback_listener = {
|
||||
.done = sync_handle_done,
|
||||
};
|
||||
|
||||
static void handle_interrupt (int signum)
|
||||
{
|
||||
fputs("Killed 💀\n", stderr);
|
||||
fputs("INFO: Killed 💀\n", stderr);
|
||||
context.loop = false;
|
||||
longjmp(skip_main_loop, 1);
|
||||
}
|
||||
@@ -211,7 +223,6 @@ static void handle_error (int signum)
|
||||
kill(getpid(), signum);
|
||||
}
|
||||
|
||||
|
||||
static char *formatted_buffer (const char *fmt, ...)
|
||||
{
|
||||
/* Determine length of formatted text. */
|
||||
@@ -286,36 +297,29 @@ static char *get_script_path (void)
|
||||
if ( path != NULL )
|
||||
free(path);
|
||||
|
||||
fputs("ERROR: No layout script found.\n", stderr);
|
||||
fputs("ERROR: No script found.\n", stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
fputs("INFO: Welcome to riverguile!\n", stderr);
|
||||
|
||||
signal(SIGSEGV, handle_error);
|
||||
signal(SIGFPE, handle_error);
|
||||
signal(SIGINT, handle_interrupt);
|
||||
|
||||
wl_list_init(&context.outputs);
|
||||
wl_list_init(&context.seats);
|
||||
wl_list_init(&context.unconfigured_idles);
|
||||
|
||||
// TODO use argv[1] if present
|
||||
char *path = get_script_path();
|
||||
if ( path == NULL )
|
||||
context.path = get_script_path();
|
||||
if ( context.path == NULL )
|
||||
{
|
||||
context.ret = EXIT_FAILURE;
|
||||
goto early_exit;
|
||||
}
|
||||
|
||||
void *res = scm_with_guile(load_script, (void *)path);
|
||||
if ( res != NULL )
|
||||
{
|
||||
fputs((char *)res, stderr);
|
||||
context.ret = EXIT_FAILURE;
|
||||
context.loop = false;
|
||||
goto early_exit;
|
||||
}
|
||||
fprintf(stderr, "INFO: Found script: %s\n", context.path);
|
||||
|
||||
/* We query the display name here instead of letting wl_display_connect()
|
||||
* figure it out itself, because libwayland (for legacy reasons) falls
|
||||
@@ -348,13 +352,14 @@ int main(int argc, char *argv[])
|
||||
while ( context.loop && wl_display_dispatch(context.wl_display) > 0 );
|
||||
|
||||
if ( context.exit_handler != NULL )
|
||||
call_exit_handler();
|
||||
|
||||
struct Idle *idle, *tmp_i;
|
||||
wl_list_for_each_safe(idle, tmp_i, &context.unconfigured_idles, link)
|
||||
{
|
||||
wl_list_remove(&idle->link);
|
||||
idle_destroy(idle);
|
||||
void *res = scm_with_guile(call_exit_handler, NULL);
|
||||
if ( res != NULL )
|
||||
{
|
||||
fputs((char *)res, stderr);
|
||||
context.ret = EXIT_FAILURE;
|
||||
context.loop = false;
|
||||
}
|
||||
}
|
||||
|
||||
struct Output *output, *tmp_o;
|
||||
@@ -382,9 +387,10 @@ int main(int argc, char *argv[])
|
||||
wl_display_disconnect(context.wl_display);
|
||||
|
||||
early_exit:
|
||||
if ( path != NULL )
|
||||
free(path);
|
||||
if ( context.path != NULL )
|
||||
free(context.path);
|
||||
|
||||
fputs("INFO: Exiting.\n", stderr);
|
||||
return context.ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user