On 02/10/2023 10:17 p.m., Trevor Davis wrote:
 > Thanks!  However, isn't length(dev.list()) == 0 when there are no
devices?  That's what I'm seeing on MacOS.

Ifthere is only one graphics device then R should automatically set it as the active graphics device so it isn't really necessary to manually set it.  Although there wouldn't be any harm in manually setting it you only really need to worry about setting the previous graphics device when there are two or more devices open.

Right, I see. With some more fiddling, I've decided that I don't like the error you get if you try to close device 1, so here's the current version:

safe.dev.off  <- function(which = dev.cur(), prev = dev.prev()) {
  if (which != 1) {
    force(prev)
    grDevices::dev.off(which)
  }
  if (length(dev.list()))
    dev.set(prev)
  else
    c("null device" = 1)
}

This does the dev.set even if there's only one device so it can return the resulting device number.

Duncan Murdoch


Trevor

On Mon, Oct 2, 2023 at 5:25 PM Duncan Murdoch <murdoch.dun...@gmail.com <mailto:murdoch.dun...@gmail.com>> wrote:

    Thanks!  However, isn't length(dev.list()) == 0 when there are no
    devices?  That's what I'm seeing on MacOS.

    Duncan Murdoch

    On 02/10/2023 4:21 p.m., Trevor Davis wrote:
     >  > Use it just like dev.off(), but it *will* restore the previous
    device.
     >
     > I'm observing that if there were no previously open graphics devices
     > then your `safe.dev.off()` opens up a new graphics device which
    may be
     > an undesired side effect (because "surprisingly" `dev.set()` on
    the null
     > graphics device opens up a new graphics device).  To avoid that you
     > could check if `dev.list()` is greater than length 1L:
     >
     >     safe.dev.off  <- function(which = dev.cur(), prev = dev.prev()) {
     >       force(prev)
     >       dev.off(which)
     >       if (length(dev.list()) > 1L) {
     >         dev.set(prev)
     >       }
     >     }
     >
     > Trevor
     >
     > On Mon, Oct 2, 2023 at 11:54 AM Duncan Murdoch
    <murdoch.dun...@gmail.com <mailto:murdoch.dun...@gmail.com>
     > <mailto:murdoch.dun...@gmail.com
    <mailto:murdoch.dun...@gmail.com>>> wrote:
     >
     >     I found some weird behaviour and reported it as
     > https://bugs.r-project.org/show_bug.cgi?id=18604
    <https://bugs.r-project.org/show_bug.cgi?id=18604>
     >     <https://bugs.r-project.org/show_bug.cgi?id=18604
    <https://bugs.r-project.org/show_bug.cgi?id=18604>> and
     > https://github.com/yihui/knitr/issues/2297
    <https://github.com/yihui/knitr/issues/2297>
     >     <https://github.com/yihui/knitr/issues/2297
    <https://github.com/yihui/knitr/issues/2297>>, but it turns out it
     >     was user
     >     error.
     >
     >     The dev.off() function was behaving as documented, but it
    behaves in an
     >     unexpected (by me) way, and that caused the "bugs".
     >
     >     The issue is that
     >
     >          dev.off()
     >
     >     doesn't always result in the previous graphics device being made
     >     current.  If there are two or more other open graphics
    devices, it
     >     won't
     >     choose the previous one, it will choose the next one.
     >
     >     I'm letting people know because this might affect other
    people too.  If
     >     you use dev.off(), don't assume it restores the previous device!
     >
     >     Here's my little workaround alternative:
     >
     >         safe.dev.off  <- function(which = dev.cur(), prev =
    dev.prev()) {
     >           force(prev)
     >           dev.off(which)
     >           dev.set(prev)
     >         }
     >
     >     Use it just like dev.off(), but it *will* restore the
    previous device.
     >
     >     Duncan Murdoch
     >
     >     ______________________________________________
     > R-devel@r-project.org <mailto:R-devel@r-project.org>
    <mailto:R-devel@r-project.org <mailto:R-devel@r-project.org>>
    mailing list
     > https://stat.ethz.ch/mailman/listinfo/r-devel
    <https://stat.ethz.ch/mailman/listinfo/r-devel>
     >     <https://stat.ethz.ch/mailman/listinfo/r-devel
    <https://stat.ethz.ch/mailman/listinfo/r-devel>>
     >


______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to