Dear list members, Rich Heiberger reported to me last week that the Messages window in the Rcmdr GUI was freezing -- that is, messages posted to this window didn't appear -- under Windows and R 2.8.0. I was able to confirm this problem on three Windows systems, one using Vista and the other two XP. In each case, I used R 2.8.0 and Rcmdr 1.4-4 (the current version). The problem doesn't occur with R 2.7.2 and Rcmdr 1.4-4. Nor does it occur on my Mac OS/X and Ubtuntu Linux systems. In my case, the problem occurred only using Rgui, not under Rterm. Rich experienced the problem with both Rgui and Rterm. On the other hand, Erich Neuwirth tells me that the Messages window works fine for him generally under Windows with R 2.8.0 and Rcmdr 1.4-4, so whatever the source of the problem, it doesn't always manifest itself. Some detail, and a kludgy solution appear below. What's odd is that the Rcmdr has three similar windows -- Script, Output, and Messages, created by the following code: For the messages window: messagesFrame <- tkframe(.commander) putRcmdr("messagesWindow", tktext(messagesFrame, bg="lightgray", font=getRcmdr("logFont"), height=3, width=log.width, wrap="none")) .messages <- MessagesWindow() messagesXscroll <- ttkscrollbar(messagesFrame, orient="horizontal", command=function(...) tkxview(.messages, ...)) messagesYscroll <- ttkscrollbar(messagesFrame, command=function(...) tkyview(.messages, ...)) tkconfigure(.messages, xscrollcommand=function(...) tkset(messagesXscroll, ...)) tkconfigure(.messages, yscrollcommand=function(...) tkset(messagesYscroll, ...)) For the script window (note that "log" is a hold-over from earlier terminology): logFrame <- tkframe(CommanderWindow()) putRcmdr("logWindow", tktext(logFrame, bg="white", foreground=getRcmdr("log.text.color"), font=getRcmdr("logFont"), height=log.height, width=log.width, wrap="none", undo=TRUE)) .log <- LogWindow() logXscroll <- ttkscrollbar(logFrame, orient="horizontal", command=function(...) tkxview(.log, ...)) logYscroll <- ttkscrollbar(logFrame, command=function(...) tkyview(.log, ...)) tkconfigure(.log, xscrollcommand=function(...) tkset(logXscroll, ...)) tkconfigure(.log, yscrollcommand=function(...) tkset(logYscroll, ...)) For the output window: outputFrame <- tkframe(.commander) putRcmdr("outputWindow", tktext(outputFrame, bg="white", foreground=getRcmdr("output.text.color"), font=getRcmdr("logFont"), height=output.height, width=log.width, wrap="none", undo=TRUE)) .output <- OutputWindow() outputXscroll <- ttkscrollbar(outputFrame, orient="horizontal", command=function(...) tkxview(.output, ...)) outputYscroll <- ttkscrollbar(outputFrame, command=function(...) tkyview(.output, ...)) tkconfigure(.output, xscrollcommand=function(...) tkset(outputXscroll, ...)) tkconfigure(.output, yscrollcommand=function(...) tkset(outputYscroll, ...)) Note that the functions MessagesWindow(), LogWindow(), and OutputWindow() simply return their respective tk windows. These windows are also similarly placed in the master Rcmdr window (slightly edited): tkgrid(.log, logYscroll, sticky="news", columnspan=2) tkgrid(logXscroll) tkgrid(logFrame, sticky="news", padx=10, pady=0, columnspan=2) tkgrid(.output, outputYscroll, sticky="news", columnspan=2) tkgrid(outputXscroll, columnspan=1 + (.log.commands && !.console.output)) tkgrid(outputFrame, sticky="news", padx=10, pady=0, columnspan=2) tkgrid(.messages, messagesYscroll, sticky="news", columnspan=2) tkgrid(messagesXscroll) tkgrid(messagesFrame, sticky="news", padx=10, pady=0, columnspan=2) I was able successfully to write directly to the script and output windows:> tkinsert(LogWindow(), "end", "\n testing \n")<Tcl>> tkinsert(OutputWindow(), "end", "\n testing \n")<Tcl> But writing to the message window, though it produced no error, also had no visible effect:> tkinsert(MessagesWindow(), "end", "\n testing \n")<Tcl> Checking the contents of the Messages window via tkget(MessagesWindow(), "1.0", "end") revealed, however, that the text should have been there. Suspecting a timing/event-loop-synchronization issue, I inserted a delay into the function that sends text to the Messages window; here's a simplified version of that function: Message <- function(message, type=c("note", "error", "warning")){ Sys.sleep(0.01) .message <- MessagesWindow() if (!missing(message)) { tkinsert(.message, "end", paste("\n", message, "\n")) tkyview.moveto(.message, 1.0) } } The 0.01 second delay is apparently sufficient to fix the problem. I'm reporting the problem because I suspect that there's some issue with tcltk in the Windows version of R 2.8.0 (though I didn't see anything in the CHANGES or NEWS file to suggest this). Regards, John ------------------------------ John Fox, Professor Department of Sociology McMaster University Hamilton, Ontario, Canada web: socserv.mcmaster.ca/jfox
John Fox wrote:> Dear list members, > > Rich Heiberger reported to me last week that the Messages window in the > Rcmdr GUI was freezing -- that is, messages posted to this window didn't > appear -- under Windows and R 2.8.0. I was able to confirm this problem on > three Windows systems, one using Vista and the other two XP. In each case, I > used R 2.8.0 and Rcmdr 1.4-4 (the current version). The problem doesn't > occur with R 2.7.2 and Rcmdr 1.4-4. Nor does it occur on my Mac OS/X and > Ubtuntu Linux systems. In my case, the problem occurred only using Rgui, not > under Rterm. Rich experienced the problem with both Rgui and Rterm. On the > other hand, Erich Neuwirth tells me that the Messages window works fine for > him generally under Windows with R 2.8.0 and Rcmdr 1.4-4, so whatever the > source of the problem, it doesn't always manifest itself. Some detail, and a > kludgy solution appear below. > > What's odd is that the Rcmdr has three similar windows -- Script, Output, > and Messages, created by the following code: > > For the messages window: > > messagesFrame <- tkframe(.commander) > putRcmdr("messagesWindow", tktext(messagesFrame, bg="lightgray", > font=getRcmdr("logFont"), height=3, width=log.width, wrap="none")) > .messages <- MessagesWindow() > messagesXscroll <- ttkscrollbar(messagesFrame, orient="horizontal", > command=function(...) tkxview(.messages, ...)) > messagesYscroll <- ttkscrollbar(messagesFrame, > command=function(...) tkyview(.messages, ...)) > tkconfigure(.messages, xscrollcommand=function(...) > tkset(messagesXscroll, ...)) > tkconfigure(.messages, yscrollcommand=function(...) > tkset(messagesYscroll, ...)) > > For the script window (note that "log" is a hold-over from earlier > terminology): > > logFrame <- tkframe(CommanderWindow()) > putRcmdr("logWindow", tktext(logFrame, bg="white", > foreground=getRcmdr("log.text.color"), > font=getRcmdr("logFont"), height=log.height, width=log.width, > wrap="none", undo=TRUE)) > .log <- LogWindow() > logXscroll <- ttkscrollbar(logFrame, orient="horizontal", > command=function(...) tkxview(.log, ...)) > logYscroll <- ttkscrollbar(logFrame, > command=function(...) tkyview(.log, ...)) > tkconfigure(.log, xscrollcommand=function(...) tkset(logXscroll, ...)) > tkconfigure(.log, yscrollcommand=function(...) tkset(logYscroll, ...)) > > For the output window: > > outputFrame <- tkframe(.commander) > > putRcmdr("outputWindow", tktext(outputFrame, bg="white", > foreground=getRcmdr("output.text.color"), > font=getRcmdr("logFont"), height=output.height, width=log.width, > wrap="none", undo=TRUE)) > .output <- OutputWindow() > outputXscroll <- ttkscrollbar(outputFrame, orient="horizontal", > command=function(...) tkxview(.output, ...)) > outputYscroll <- ttkscrollbar(outputFrame, > command=function(...) tkyview(.output, ...)) > tkconfigure(.output, xscrollcommand=function(...) tkset(outputXscroll, > ...)) > tkconfigure(.output, yscrollcommand=function(...) tkset(outputYscroll, > ...)) > > Note that the functions MessagesWindow(), LogWindow(), and OutputWindow() > simply return their respective tk windows. > > These windows are also similarly placed in the master Rcmdr window (slightly > edited): > > tkgrid(.log, logYscroll, sticky="news", columnspan=2) > tkgrid(logXscroll) > tkgrid(logFrame, sticky="news", padx=10, pady=0, columnspan=2) > > tkgrid(.output, outputYscroll, sticky="news", columnspan=2) > tkgrid(outputXscroll, columnspan=1 + (.log.commands && > !.console.output)) > tkgrid(outputFrame, sticky="news", padx=10, pady=0, columnspan=2) > > tkgrid(.messages, messagesYscroll, sticky="news", columnspan=2) > tkgrid(messagesXscroll) > tkgrid(messagesFrame, sticky="news", padx=10, pady=0, columnspan=2) > > I was able successfully to write directly to the script and output windows: > >> tkinsert(LogWindow(), "end", "\n testing \n") > <Tcl> > >> tkinsert(OutputWindow(), "end", "\n testing \n") > <Tcl> > > But writing to the message window, though it produced no error, also had no > visible effect: > >> tkinsert(MessagesWindow(), "end", "\n testing \n") > <Tcl> > > Checking the contents of the Messages window via tkget(MessagesWindow(), > "1.0", "end") revealed, however, that the text should have been there. > > Suspecting a timing/event-loop-synchronization issue, I inserted a delay > into the function that sends text to the Messages window; here's a > simplified version of that function: > > Message <- function(message, type=c("note", "error", "warning")){ > Sys.sleep(0.01) > .message <- MessagesWindow() > if (!missing(message)) { > tkinsert(.message, "end", paste("\n", message, "\n")) > tkyview.moveto(.message, 1.0) > } > } > > The 0.01 second delay is apparently sufficient to fix the problem. > > I'm reporting the problem because I suspect that there's some issue with > tcltk in the Windows version of R 2.8.0 (though I didn't see anything in the > CHANGES or NEWS file to suggest this).... Hmm, does it help with a suitably placed tcl("update") or tcl("update","idletasks")? -- O__ ---- Peter Dalgaard ?ster Farimagsgade 5, Entr.B c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907