8

Is it possible to set Shiny options to open an App automatically in a full view mode, i.e. in a maximized window?

My user interface is designed in a way that is nicely looking only when browsed in a full view.

My source is written in two standard files: server.R and ui.R.

I am interested in both options: to run app in (1) RStudio Window and in (2) External browser.

Although this appears to me as a natural and simple question, I cannot find any suggestion when searching the web. Does anyone know of a solution?

Tom Wenseleers
  • 7,535
  • 7
  • 63
  • 103
Pawel
  • 401
  • 6
  • 17

2 Answers2

11

What you are asking for is browser dependent and cannot be enforced from R or Shiny. I had this same requirement for a conference where I deployed an app as a team activity, all the conference tables had a connected tablet. Note that the reason why this is difficult comes down to security and the risks of phishing / social engineering. Some additional information on this:

You have a few options depending on the constraints of your circumstances, in no particular order:

  1. Request for the browser to switch to fullscreen mode via javascript

There is a Fullscreen API you could use to request the browser to switch to fullscreen mode. The benefit here is that it is browser and platform agnostic provided the browser supports the API. However, it is only a request and not guaranteed to work as intended. This question (and this one) demonstrates an implementation, you could use the excellent shinyjs package if you choose to go down this path.

Here is a minimal example demonstrating the use of the Fullscreen API. using an adaptation of the Old Faithful Geyser Data demonstration app.

app.R

    library(shiny)
    library(shinyjs)
    
    jsToggleFS <- 'shinyjs.toggleFullScreen = function() {
        var element = document.documentElement,
          enterFS = element.requestFullscreen || element.msRequestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen,
          exitFS = document.exitFullscreen || document.msExitFullscreen || document.mozCancelFullScreen || document.webkitExitFullscreen;
        if (!document.fullscreenElement && !document.msFullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement) {
          enterFS.call(element);
        } else {
          exitFS.call(document);
        }
      }'

    ui <- fluidPage(

      useShinyjs(),
      extendShinyjs(text = jsToggleFS),

      titlePanel("Old Faithful Geyser Data"),

      sidebarLayout(sidebarPanel(
        sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30),
        div(
          HTML("<button type='button'>Toggle Fullscreen</button>"),
          onclick = "shinyjs.toggleFullScreen();"
        )
      ),

      mainPanel(plotOutput("distPlot")

      ))
    )

    server <- function(input, output) {

      output$distPlot <- renderPlot({
        x    <- faithful[, 2]
        bins <- seq(min(x), max(x), length.out = input$bins + 1)
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
      })
    }

    shinyApp(ui = ui, server = server)

N.B. If you are implementing this, you may choose something more advanced than my very simplistic HTML button. It is important to note that browsers will only allow the use of the API if initiated by the user. You may find the message Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture. in your javascript console if not detected as a user event.

There is also the screenfull.js library, which tries to package up the API in a more friendly way.

  1. Deploy your app using some form of kiosk mode

Browsers can be instructed to start in kiosk mode (i.e. fullscreen), see here for an example with Chrome on windows. The problem here of course is that unless you are working in a standard environment (like an enterprise) this could be highly frustrating to execute.

  1. Use a browser that is specifically designed to use fullscreen mode all the time

Because my platform was android for the conference, I used an app (not this one but similar) and I placed a shortcut link on the main page after making this browser the default for opening pages. Not ideal, but it met my immediate requirements.

  1. Accept current state / Inform users

Given there is a level of fragility with the available solutions and security concerns regardless of how you choose to tackle this problem, you may opt to accept the current state and layout your app as best you can with this knowledge. Or possibly just inform your users that the app is optimised for use fullscreen and that they can press F11 (or equivalent) in their browser to enable that.

pea
  • 17
  • 3
Kevin Arseneau
  • 6,186
  • 1
  • 21
  • 40
  • Thanks for this - for Javascript option (1) - would you know how to implement that by any chance in an R / Shiny context? I.e. know of a minimal working Shiny example? – Tom Wenseleers Jan 04 '18 at 09:08
  • 1
    Many thanks for that - typically I guess one would just like to have the Shiny app execute shinyjs.toggleFullScreen() upon initialization, rather than when the user clicks the HTML button (as that would be practically the same as the user clicking the maximize button). Can that be done too? – Tom Wenseleers Jan 05 '18 at 08:28
  • @TomWenseleers, no, as noted in my answer it is not allowed for security reasons. You can find many debates discussing this on SO and elsewhere. – Kevin Arseneau Jan 06 '18 at 00:42
  • @TomWenseleers, I will add that you could get creative with the user event that triggers the javascript. The most obvious would be to have a landing page that the user needs to navigate to get to your app and have that process launch your app fullscreen. – Kevin Arseneau Jan 06 '18 at 01:10
  • Yes or maybe detecting an event that will always happen, like hover with the cursor over some part of the shiny app, and then making sure that that event is only triggered once? Would that be an option? – Tom Wenseleers Jan 06 '18 at 01:51
  • @TomWenseleers, yes, any user gesture can be used. However, just be aware it is generally considered bad practice (bordering on unethical/immoral) when your site behaves in a way that the user could not anticipate or expect reasonably. – Kevin Arseneau Jan 06 '18 at 01:57
  • This is a great answer about full screen, however I believe there is a difference between maximized window and full screen window, and maximized window doesn't have the problems of phishing / social engineering. – dracodoc May 22 '19 at 20:08
  • Anybody can replace `extendShinyjs(text = jsToggleFS)` by `extendShinyjs(text = jsToggleFS, functions = c("toggleFullScreen"))` in to order to avoid error. Thanks – Alex Yahiaoui Martinez Sep 17 '20 at 10:01
1

An alternative to running full-screen is to open your app in a different browser from RStudio.

Next to the shiny app launch button there is a tiny triangle that opens a drop-down menu. Within this menu, just click on the icon to change the displaying option to Run External. If you change to external, every time you click Run App it will open in your default browser.

Josiah Yoder
  • 3,321
  • 4
  • 40
  • 58
Sarath_Mj
  • 323
  • 1
  • 2
  • 14
  • Thanks for your answer, but my problem is not how to change the browser type (ex. from RStudio Window to External browser), but how to have full size window immediately after launching an App (without clicking 'maximalize' icon). – Pawel Feb 22 '17 at 14:22
  • If you keep your browser full-screen and relaunch your app, it will remain full-screen (at least in Chrome on Windows). This can be convenient for development. Sadly, it opens a new tab each time you start the browser, but they all are full-screen. – Josiah Yoder Jun 13 '19 at 16:46
  • Letting [the app close itself](https://stackoverflow.com/a/45590324/1048186) when you close the tab is a nice workaround – Josiah Yoder Jun 13 '19 at 19:04
  • Sadly, I don't think it is possible to do the other way. [This snippet](https://github.com/daattali/advanced-shiny/blob/master/close-window/app.R) will close the window, but it doesn't work when executed in onSessionEnded() or onStop() – Josiah Yoder Jun 14 '19 at 15:21