From murdoch@dunc@n @end|ng |rom gm@||@com  Tue Oct  3 11:16:58 2023
From: murdoch@dunc@n @end|ng |rom gm@||@com (Duncan Murdoch)
Date: Tue, 3 Oct 2023 05:16:58 -0400
Subject: [Rd] Problems caused by dev.off() behaviour
In-Reply-To: <CAMigB8Ercw=i=ka-fOecK=O=rBb+Pqp1c_S0G2rCJQE8absYRw@mail.gmail.com>
References: <affab490-cd9f-46e7-ab9f-37a4b13d2557@gmail.com>
 <CAMigB8FWHaLWB1SvHi3Bw9dW9jkdHv1C-M3x4NSX0NnqjggyCg@mail.gmail.com>
 <d39b6d56-127d-4c5c-b7b7-e436372fa1ce@gmail.com>
 <CAMigB8Ercw=i=ka-fOecK=O=rBb+Pqp1c_S0G2rCJQE8absYRw@mail.gmail.com>
Message-ID: <eddcab9a-4144-485f-8a0f-77c83e986490@gmail.com>

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.duncan at gmail.com 
> <mailto:murdoch.duncan at 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.duncan at gmail.com <mailto:murdoch.duncan at gmail.com>
>      > <mailto:murdoch.duncan at gmail.com
>     <mailto:murdoch.duncan at 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 at r-project.org <mailto:R-devel at r-project.org>
>     <mailto:R-devel at r-project.org <mailto:R-devel at 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>>
>      >
>



[Rd] Problems caused by dev.off() behaviour
Duncan Murdoch