This is a little bit of a hack, but it's possible to set the value of an input variable directly when the window is closed, but adding a beforeunload callback. For example:
runApp(list(
ui = bootstrapPage(
numericInput('n', 'Number of obs', 100),
plotOutput('plot'),
tags$script(type = "text/javascript", "
$(function() { // Run when DOM ready
$(window).bind('beforeunload', function(e) {
Shiny.onInputChange('quit', true); // sets input$quit to true
});
});
")
),
server = function(input, output) {
output$plot <- renderPlot({ hist(runif(input$n)) })
observe({
# If input$quit is unset (NULL) do nothing; if it's anythign else, quit
# and return input$n
if (is.null(input$quit)) return()
stopApp(input$n)
})
}
))