I am tinkering around with ltk as it provides the option of running a remote GUI. However, when trying to use the remote GUI I run into issues I do not encounter when running ltk locally:
(in-package :ltk-user)
(defun add-current-investigation-frame (master)
(let* ((frame (make-instance 'frame :master master :width 100 :height 100))
(topic-label (make-instance 'label :text "Current Investigation" :master frame))
(project-label (make-instance 'entry :text "N/A" :master frame))
(action-button (make-instance 'button
:master frame
:text "new investigation")))
(setf (command action-button) (lambda ()
(format t "test~%")
(let ((next-project (nth (random 3) '("A" "B" "N/A"))))
(setf (text project-label) next-project))))
(pack frame)
(pack topic-label :side :top)
(pack project-label :side :top)
(pack action-button :side :top)))
(defun create-main-view ()
(let ((wrapper-frame (make-instance 'frame :master nil)))
(pack wrapper-frame)
(add-current-investigation-frame wrapper-frame)))
(defun create-remote-view (&optional (port 8888))
(Ltk:with-remote-ltk port ()
(create-main-view)))
(defun create-local-view ()
(with-ltk ()
(create-main-view)))
When running (create-local-view) everything works fine and the content of the entry widget changes randomly.
When running (create-remote-view) I get the error message can't read server: no such variable. Why does this error occur and how can I fix this?
I am using the remote.tcl deployed by quicklisp:
#!/usr/bin/wish
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
wm withdraw .
set host localhost
if {[llength $argv] == 2} {
set host [lindex $argv 0]
set port [lindex $argv 1]} else {
set port [lindex $argv 0]}
#puts "connecting to $host $port"
set server [socket $host $port]
set wi [open "|wish" RDWR]
fconfigure $server -blocking 0
fconfigure $wi -blocking 0
fileevent $server readable {set txt [read $server];puts $wi "$txt";flush $wi}
fileevent $wi readable {
if {[eof $wi]} {
close $wi
exit} else {
set txt [read $wi]; puts -nonewline $server $txt;flush $server}}
This is a preliminary answer as I am not entirely sure that this fix does not break anything. I will update this answer in the future to report back on encountered issues. But for now this fixes the issue.
In
ltk.lispthere is a function calledinit-wishwhich requires an additional line(send-wish "set server stdout")Explanation: The function seems to set up the wish interface and actions (confirmed by inserting prints in the
remote.tcl). However, as one can seeserveris referenced in all procs yet it is never declared if we consider all those declarations to be in their own namespace. Consequently, the missing server has to be defined. As all the output is read byfileevent $wi ...and then passed on further, definingserverasstdoutseemed the most sensible.It seems to work, however I have no clue if this breaks other stuff