diff --git a/Makefile b/Makefile index 0accb45..1530d2e 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ OBJ=src/riverguile.o $\ src/call-layout-demand-handler.o $\ src/call-user-command-handler.o $\ src/call-idle-handler.o $\ + src/call-exit-handler.o $\ src/load-script.o $\ protocol/river-layout-v3.o $\ protocol/ext-idle-notify-v1.o diff --git a/doc/riverguile.1 b/doc/riverguile.1 index a9bba37..f919cb7 100644 --- a/doc/riverguile.1 +++ b/doc/riverguile.1 @@ -78,6 +78,9 @@ of the system being idle is over. Multiple idle handlers can be installed. Note: All idle events relate to the first advetised seat. As of now, river only supports a single seat anyway. +.P +The key \fBexit\fR installs a handler which is called when riverguile exits. +The procedure takes no arguments. . . .SH EXAMPLE diff --git a/src/call-exit-handler.c b/src/call-exit-handler.c new file mode 100644 index 0000000..de6a68a --- /dev/null +++ b/src/call-exit-handler.c @@ -0,0 +1,29 @@ +#include +#include + +#include "riverguile.h" + +static void *call_exit_handler_inner (void *data) +{ + assert(data == NULL); + return scm_call_0(context.exit_handler); +} + +void *call_exit_handler (void) +{ + assert(context.exit_handler != NULL); + + /* Continuation barrier causes stack unwind on exceptions (i.e. errors + * in the user defined exit handler) to stop here. Otherwise the entire + * stack created by scm_with_guile() would be unwound. This makes + * responding to exceptions nicer. + */ + SCM call_result = scm_c_with_continuation_barrier( + call_exit_handler_inner, NULL + ); + + if ( call_result == NULL ) + return (void *)"ERROR: An exception occured while calling the exit handler.\n"; + + return NULL; +} diff --git a/src/call-exit-handler.h b/src/call-exit-handler.h new file mode 100644 index 0000000..6e8d088 --- /dev/null +++ b/src/call-exit-handler.h @@ -0,0 +1,6 @@ +#ifndef RIVERGUILE_CALL_EXIT_HANDLER_H +#define RIVERGUILE_CALL_EXIT_HANDLER_H + +void *call_exit_handler (void); + +#endif diff --git a/src/call-idle-handler.c b/src/call-idle-handler.c index 7dbcc11..727656e 100644 --- a/src/call-idle-handler.c +++ b/src/call-idle-handler.c @@ -21,7 +21,7 @@ static void *call_idle_handler_inner (void *data) void *call_idle_handler (void *data) { /* Continuation barrier causes stack unwind on exceptions (i.e. errors - * in the user defined ide handler) to stop here. Otherwise the entire + * in the user defined idle handler) to stop here. Otherwise the entire * stack created by scm_with_guile() would be unwound. This makes * responding to exceptions nicer. */ @@ -30,7 +30,7 @@ void *call_idle_handler (void *data) ); if ( call_result == NULL ) - return (void *)"ERROR: An exception occured while calling the user-command handler.\n"; + return (void *)"ERROR: An exception occured while calling the idle handler.\n"; return NULL; } diff --git a/src/load-script.c b/src/load-script.c index 1fa8b33..b2e9323 100644 --- a/src/load-script.c +++ b/src/load-script.c @@ -78,6 +78,8 @@ static SCM install_handler (SCM key, SCM proc) context.layout_demand_handler = proc; else if ( scm_is_eq(scm_from_utf8_symbol("user-command"), key) == 1) context.user_command_handler = proc; + else if ( scm_is_eq(scm_from_utf8_symbol("exit"), key) == 1) + context.exit_handler = proc; else if ( scm_is_true(scm_string_prefix_p(scm_from_utf8_string("idle:"), scm_symbol_to_string(key), scm_from_int(0), scm_from_int(5), scm_from_int(0), scm_string_length(scm_symbol_to_string(key)))) == 1 ) diff --git a/src/riverguile.c b/src/riverguile.c index 37a2c05..78eeea8 100644 --- a/src/riverguile.c +++ b/src/riverguile.c @@ -22,6 +22,7 @@ #include "ext-idle-notify-v1.h" #include "load-script.h" +#include "call-exit-handler.h" #include "riverguile.h" #include "output.h" #include "seat.h" @@ -346,6 +347,9 @@ int main(int argc, char *argv[]) if ( setjmp(skip_main_loop) == 0 ) 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) { diff --git a/src/riverguile.h b/src/riverguile.h index 24b67e8..7a6b315 100644 --- a/src/riverguile.h +++ b/src/riverguile.h @@ -11,6 +11,7 @@ struct Context { SCM layout_demand_handler; SCM user_command_handler; + SCM exit_handler; bool loop; int ret;