From: Kenny Tilton
Subject: No peek-char-no-hang?
Date: 
Message-ID: <3eoHc.62908$a92.53974@twister.nyc.rr.com>
Conversations with Tk are getting a tad non-deterministic, so I have to 
code a pre-emptive strike to clear any input before attempting an exchange.

Since I cannot get peek-char to return nil when there is no input, I 
will go with read-char-no-hang and unread-char, but I am curious: did I 
miss some way to get peek-char not to hang, or is there some other way 
to test for input before doing the peek-char, or...?

kt

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application

From: Erann Gat
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <gNOSPAMat-057589.23580908072004@nntp1.jpl.nasa.gov>
In article <·····················@twister.nyc.rr.com>,
 Kenny Tilton <·······@nyc.rr.com> wrote:

> Conversations with Tk are getting a tad non-deterministic, so I have to 
> code a pre-emptive strike to clear any input before attempting an exchange.
> 
> Since I cannot get peek-char to return nil when there is no input, I 
> will go with read-char-no-hang and unread-char, but I am curious: did I 
> miss some way to get peek-char not to hang, or is there some other way 
> to test for input before doing the peek-char, or...?

(and (listen stream) (peek-char stream))

E.
From: Kenny Tilton
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <uRyHc.63181$a92.36600@twister.nyc.rr.com>
Erann Gat wrote:

> In article <·····················@twister.nyc.rr.com>,
>  Kenny Tilton <·······@nyc.rr.com> wrote:
> 
> 
>>Conversations with Tk are getting a tad non-deterministic, so I have to 
>>code a pre-emptive strike to clear any input before attempting an exchange.
>>
>>Since I cannot get peek-char to return nil when there is no input, I 
>>will go with read-char-no-hang and unread-char, but I am curious: did I 
>>miss some way to get peek-char not to hang, or is there some other way 
>>to test for input before doing the peek-char, or...?
> 
> 
> (and (listen stream) (peek-char stream))

cool, thx. I went with:

(defun peek-char-no-hang (stream)
   (and (listen stream) (peek-char nil stream)))

Peter, while playing around with my new peek-char-no-hang I have run 
into the problem again for a different reason. Even after clearing the 
buffer I cannot count on doing an immediate exchange. If I drag the 
scale thumb back and forth for a few seconds I eventually get wish 
sending a command after I think the buffer is clear but before I can get 
the immediate (not!) exchange completed.

Looks like even simple queries will have to be handled as labelled 
callbacks. Or is it time for Tk FFI bindings?

kt

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Peter Herth
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <ccmjcr$a82$1@newsreader2.netcologne.de>
Kenny Tilton wrote:

> Peter, while playing around with my new peek-char-no-hang I have run
> into the problem again for a different reason. Even after clearing the
> buffer I cannot count on doing an immediate exchange. If I drag the
> scale thumb back and forth for a few seconds I eventually get wish
> sending a command after I think the buffer is clear but before I can get
> the immediate (not!) exchange completed.

As written before, please let me look at the snippet, may be some Tk
issue, or a windows issue (I think Unix handles the read and writes
to pipes a little bit different but cannot remember exactly how)
 
> Looks like even simple queries will have to be handled as labelled
> callbacks. Or is it time for Tk FFI bindings?

I think more structured callbacks may be the way to go, if not the
latest version of Ltk already fixes your problem. A FFI version
of the Tk bindings is thinkable, but would open a lot of cans of
worms, as it would be quite non-portable and a lot of work to do.

Peter

-- 
pet project: http://dawn.netcologne.de
homepage:    http://www.peter-herth.de
lisp stuff:  http://www.peter-herth.de/lisp.html
get Ltk here: http://www.peter-herth.de/ltk/
From: Peter Herth
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <cclkkt$rh6$1@newsreader2.netcologne.de>
For a long time I was quite worried about something like that
happening with Ltk. But I never encountered it yet, but that
isn't any guarantee it doesn't strike me as well :p. So
I would be interested in a description of the problems you
run into.

Peter

-- 
pet project: http://dawn.netcologne.de
homepage:    http://www.peter-herth.de
lisp stuff:  http://www.peter-herth.de/lisp.html
get Ltk here: http://www.peter-herth.de/ltk/
From: Kenny Tilton
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <ppwHc.63156$a92.5235@twister.nyc.rr.com>
Peter Herth wrote:
> For a long time I was quite worried about something like that
> happening with Ltk. But I never encountered it yet, but that
> isn't any guarantee it doesn't strike me as well :p. So
> I would be interested in a description of the problems you
> run into.
> 
> Peter
> 

Hey, Peter. Thx again for a great contrib.

Here's my current guess, but first a caveat: I have been whacking on LTk 
pretty heavily, so this might just be a problem I created for myself.

Background: I added scale widgets, including starting them off at a 
specified value. eg, a "font size" scale running from 7 to 24 but 
starting off at 14.

Guess: Setting a widget's value procedurally causes Tk to kick off its 
command if one has been defined. If before returning to/entering the 
mainloop I then try an immediate exchange (say asking Tk to evaluate and 
puts the script "[font families]", when I (read *w*) I will get back the 
command(s) from any widgets I had set.

So the problem sequence seems to be:

- set a widget command to puts a callback key
- set a widget value such that Tk kicks off its command (scale does this)
- query Tk by sending it "puts [<whatever>]"
- read to get answer to query, instead get the callback key

One solution might be to carefully consume the command callback after 
any widget set. Me, I just accepted that in general Tk may surprise me 
with stuff in stdin on the Lisp side, so I process stdin before 
attempting an immediate exchange. A more extreme (and elegant?) solution 
would be to eschew any concept of immediate exchange and treat those as 
one-time callbacks: post the query and let the response be picked up in 
mainloop handling.

kt

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Peter Herth
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <ccmirr$8r0$1@newsreader2.netcologne.de>
Kenny Tilton wrote:

> So the problem sequence seems to be:
> 
> - set a widget command to puts a callback key
> - set a widget value such that Tk kicks off its command (scale does this)
> - query Tk by sending it "puts [<whatever>]"
> - read to get answer to query, instead get the callback key
> 

I havent run into that situation yet, but if I understand it correctly,
you are encountering it with widgets that you modify from your software
and have also callbacks defined upon to report any modification ?
You should look at the latest Ltk release, as I only use read now,
communication with Tk has become more robust. The only time I get
unexpected output from Tk, is when it creates error messages.
If you like to mail me the code snipped in question, I will
have a look at it, perhaps I get an idea how to solve that problem.

Peter

-- 
pet project: http://dawn.netcologne.de
homepage:    http://www.peter-herth.de
lisp stuff:  http://www.peter-herth.de/lisp.html
get Ltk here: http://www.peter-herth.de/ltk/
From: Kenny Tilton
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <fAXHc.38331$4h7.4092006@twister.nyc.rr.com>
Peter Herth wrote:
> Kenny Tilton wrote:
> 
> 
>>So the problem sequence seems to be:
>>
>>- set a widget command to puts a callback key
>>- set a widget value such that Tk kicks off its command (scale does this)
>>- query Tk by sending it "puts [<whatever>]"
>>- read to get answer to query, instead get the callback key
>>
> 
> 
> I havent run into that situation yet, but if I understand it correctly,
> you are encountering it with widgets that you modify from your software
> and have also callbacks defined upon to report any modification ?

Yep.

> You should look at the latest Ltk release...

I have 0.8.5, which seems to be the latest (just checked now).

, as I only use read now,
> communication with Tk has become more robust.

I do not know what you mean by "only use read now". As opposed to what? 
Just to expedite things, here is the full exposition of my confusion 
<g>: Looking at the scale code I see you do allow the Lisp client code 
to set the scale value. But I also see you do not have a command for a 
scale. (Aside: tho you do for other widgets.) So how does my application 
know when the user has changed the scale setting? I understand other 
widgets can be driven by the variable associated with the scale, but 
what if I want the application to make interesting decisions based on 
the scale setting? Do I have to move that more interesting logic into a 
Tcl script?

 From your next article:

> Kenny Tilton wrote:
> 
> 
>>> Peter, while playing around with my new peek-char-no-hang I have run
>>> into the problem again for a different reason. Even after clearing the
>>> buffer I cannot count on doing an immediate exchange. If I drag the
>>> scale thumb back and forth for a few seconds I eventually get wish
>>> sending a command after I think the buffer is clear but before I can get
>>> the immediate (not!) exchange completed.
> 
> 
> As written before, please let me look at the snippet, may be some Tk
> issue, or a windows issue (I think Unix handles the read and writes
> to pipes a little bit different but cannot remember exactly how)

I just thought of something: I happen to be writing all writes to Tk 
also to my listener, and that has been known in the past to flush out 
potential synchronization problems in IPC because it slows down the Lisp 
process....yep, that seems to have cured it. With all print diagnostics 
disabled, I can drag the scale back and forth quite a bit and quite 
crazily without triggering a mis-synch. I would be concerned though that 
if I /did/ have some heavy-lifting code running on any change of the 
scale that I could see this problem again.


>  
> 
>>> Looks like even simple queries will have to be handled as labelled
>>> callbacks. Or is it time for Tk FFI bindings?
> 
> 
> I think more structured callbacks may be the way to go, if not the
> latest version of Ltk already fixes your problem. A FFI version
> of the Tk bindings is thinkable, but would open a lot of cans of
> worms, as it would be quite non-portable and a lot of work to do.

<g> Cello has kinda made FFI bindings seem like a walk in the park to 
me, but I know what you mean. Where do you see the non-portability? 
Let's fix that and benefit from better/faster access to all libraries. My 2.

kt

ps. as for sending you a snippet, that would be impossible, you would 
have to grab the whole shebang from CVS to make any sense of it. Cells 
supports a declarative paradigm in which a big engine takes care of 
imperative steps such as communicating with Tk, so it is scattered all 
over the joint.

Here is the code for my little font-view demo, with a spinbox for all 
fonts returned by Tk "font families", a sclae for the font size, and a 
text box to show a phrase in the currently selected font and size. (As 
the scale thumb is dragged or the spinbox spun, the text changes on the 
fly.):

(let ((*debug-tk* nil)
       (*callbacks* (make-hash-table)))
    (cell-reset)
    (tk-start)
    (let ((*tk-root* (to-be ;; cells init for top cellish instance
                       (make-instance 'font-view)))))
       (mainloop))))

(defmodel font-view (frame-stack)
   ()
   (:default-initargs
     :md-value (c? (tk-eval-list "font families"))
     :pady 2 :padx 4
     :layout (pack-layout? "-side left -fill both -expand 1 -anchor nw")
     :kids  (c? (list
                 (mk-spinbox :md-name :font-face
                   :md-value (c-in (car (^md-value)))
                   :tk-values (c? (md-value .parent)))
                 (mk-scale :md-name :font-size
                   :md-value (c-in 14) ;; initial setting
                   :tk-label "Font Size"
                   :from 7 :to 24
                   :orient 'horizontal)
                 (mk-label :text "Four score and seven years ago today"
                   :wraplength 600
                   :font (c? (list
                               (md-value (fm^ :font-face))
                               (md-value (fm^ :font-size)))))))))


frame-stack is a standard Tk frame wrapper with a stack mixin which 
arranges for vertical layout by other declarative deets I think can be 
left out.

Here is the resulting tk-send log:

tk-send> frame .w10
tk-send> puts -nonewline {(};puts -nonewline [font families];puts 
{)};flush stdout
tk-send> spinbox .w10.font-face
tk-send> scale .w10.font-size
tk-send> label .w10.w11
tk-send> .w10.font-face set SYSTEM
tk-send> pack .w10.font-face
0> registering callback | FONT-FACE | :ID .W10.FONT-FACE.COMMAND
tk-send> .w10.font-face configure -command {puts {(callback 
.W10.FONT-FACE.COMMAND)};flush stdout; list}
tk-send> .w10.font-face configure -values {system 8514oem fixedsys 
terminal roman script modern {small fonts} {ms serif} wst_czec wst_engl 
wst_fren wst_germ wst_ital wst_span wst_swed courier {ms sans serif}

...<snip some fonts>....

events} {mini pics lil stuff} {mini pics lil vehicles} {mini pics red 
rock} {bitstream vera sans mono} {bitstream vera serif} {bitstream vera 
sans} {myriad condensed web} {myriad web} {chessmaster 6000} sydnie}
tk-send> .w10.font-size set 14
tk-send> pack .w10.font-size
tk-send> .w10.font-size configure -orient horizontal
0> registering callback | FONT-SIZE | :ID .W10.FONT-SIZE.COMMAND
tk-send> .w10.font-size configure -command {puts {(callback 
.W10.FONT-SIZE.COMMAND)};flush stdout; list}
tk-send> .w10.font-size configure -from 7
tk-send> .w10.font-size configure -label {Font Size}
tk-send> .w10.font-size configure -to 24
tk-send> pack .w10.w11
tk-send> .w10.w11 configure -font {system 14}
tk-send> .w10.w11 configure -text {Four score and seven years ago today}
tk-send> .w10.w11 configure -wraplength 600
tk-send> pack .w10 -side left -fill both -expand 1 -anchor nw
tk-send> pack .w10.font-face .w10.font-size .w10.w11 -side top -anchor 
nw -padx 4 -pady 2
tk-send> .w10 configure -padx 4
tk-send> .w10 configure -pady 2

k

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Peter Herth
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <ccpk6c$hqn$1@newsreader2.netcologne.de>
Kenny Tilton wrote:

> 
>> I havent run into that situation yet, but if I understand it correctly,
>> you are encountering it with widgets that you modify from your software
>> and have also callbacks defined upon to report any modification ?
> 
> Yep.
> 
>> You should look at the latest Ltk release...
> 
> I have 0.8.5, which seems to be the latest (just checked now).

Ok you are current, thats a start :)
 
> , as I only use read now,
>> communication with Tk has become more robust.
> 
> I do not know what you mean by "only use read now". As opposed to what?

In earlear Ltk versions I used for example read-line to read out the 
states of some widgets and that was less robust as read as it depended
on getting all line endings properly for example, while read ignores
all additional whitespace.

> Just to expedite things, here is the full exposition of my confusion
> <g>: Looking at the scale code I see you do allow the Lisp client code
> to set the scale value. But I also see you do not have a command for a
> scale. (Aside: tho you do for other widgets.) So how does my application
> know when the user has changed the scale setting? I understand other
> widgets can be driven by the variable associated with the scale, but
> what if I want the application to make interesting decisions based on
> the scale setting? Do I have to move that more interesting logic into a
> Tcl script?

Well that means a command option is missing for the scale widget :). I just
wrote one some minutes ago. So the interesting question is: what code did
YOU use to get notified by the scale widget ? If we look at that code, I
could get an idea how to fix things.

> <g> Cello has kinda made FFI bindings seem like a walk in the park to
> me, but I know what you mean. Where do you see the non-portability?
> Let's fix that and benefit from better/faster access to all libraries. My

Well we are lacking any standard for FFI right now. UFFI could be it
as soon it has callback support. And I think the amount of coded
needed if it calls the C library behind TK directly would be quite
big compared to the current Ltk code.

> ps. as for sending you a snippet, that would be impossible, you would
> have to grab the whole shebang from CVS to make any sense of it. Cells
> supports a declarative paradigm in which a big engine takes care of
> imperative steps such as communicating with Tk, so it is scattered all
> over the joint.

Yes, the Lisp code would help me less, but a sketch how you are dealing
in principal with Tk might help.

> 
> Here is the resulting tk-send log:
>

Ah here we are talking business now :)
 
> tk-send> scale .w10.font-size

there is our scale widget created...

> tk-send> .w10.font-face configure -command {puts {(callback
> .W10.FONT-FACE.COMMAND)};flush stdout; list}

And I think here we get to the root of things. Unfortunately
scale as well as the scrollbars is written a little bit
"too clever" (I stumbled over the same thing when just
writing the command option for Ltk). The command configuration
option for the scale widget does *not* take the code to run
when the scale is changed, but function name to call when
the scale is changed... that is, if you do for example:
myscale configure -command myscalefun
on every chance of myscale, myscalefun is called with the new
scale value as a parameter. So I guess the lonely list statement
at the end of your callback code should deal with the extra argument.

Here is my updated code for the scale widget in Ltk, if you model your 
code like it, perhaps all problems are already solved:

;;; scale widget

(defclass scale (widget)
  ((from :accessor scale-from :initarg :from  :initform nil)
   (to :accessor scale-to :initarg :to :initform nil)
   (orient :accessor scale-orient :initarg :orient  :initform nil)
   ;; added command slot to the scale class
   (command :accessor command :initarg :command :initform nil)
   )
  )

(defmethod create ((sc scale))
  ;; new handling of the command argument
  (when (command sc)
    (add-callback (name sc) (command sc)) ;; standard callback defining
  ;; to handle the "special" callback handling, defining a callback
  ;; function in tcl with the name "widgetname-callback"
  ;; it consumes the value and sends it together with the 
    (format-wish "proc ~a-command {val} {puts -nonewline {(\"~a\" };puts
-nonewline \"[~a get]\";puts {)};flush stdout }" (name sc) (name sc) (path
sc)))

  (format-wish "scale ~a -variable ···@[ -from ~a~]·@[ -to ~a~]·@[ -orient
~(~a~)~] ~a" (path sc) (name sc)
               (scale-from sc)
               (scale-to sc)
               (scale-orient sc)
               (if (command sc)
                   (format nil "-command ~a-command" (name sc) ) ;; just give the name of
the function to call here
                 "")
               ))

;; sample usage:
(with-ltk
  (defparameter sc (make-instance 'scale :from 10 :to 20 
                                    :command (lambda (val) 
                                                (format t "scale val : ~a~%" val)
                                                (force-output))))
  (pack sc))

I hope this helps to cure the hanging problems :)

Peter

-- 
pet project: http://dawn.netcologne.de
homepage:    http://www.peter-herth.de
lisp stuff:  http://www.peter-herth.de/lisp.html
get Ltk here: http://www.peter-herth.de/ltk/
From: Kenny Tilton
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <sp4Ic.38351$4h7.4234003@twister.nyc.rr.com>
Peter Herth wrote:

> Kenny Tilton wrote:
> 
> 
>>>I havent run into that situation yet, but if I understand it correctly,
>>>you are encountering it with widgets that you modify from your software
>>>and have also callbacks defined upon to report any modification ?
>>
>>Yep.
>>
>>
>>>You should look at the latest Ltk release...
>>
>>I have 0.8.5, which seems to be the latest (just checked now).
> 
> 
> Ok you are current, thats a start :)
>  
> 
>>, as I only use read now,
>>
>>>communication with Tk has become more robust.
>>
>>I do not know what you mean by "only use read now". As opposed to what?
> 
> 
> In earlear Ltk versions I used for example read-line...

oh, ok. right, that did not handle errors or stuff like ({times 
roman}...) real well.

  to read out the
> states of some widgets and that was less robust as read as it depended
> on getting all line endings properly for example, while read ignores
> all additional whitespace.
> 
> 
>>Just to expedite things, here is the full exposition of my confusion
>><g>: Looking at the scale code I see you do allow the Lisp client code
>>to set the scale value. But I also see you do not have a command for a
>>scale. (Aside: tho you do for other widgets.) So how does my application
>>know when the user has changed the scale setting? I understand other
>>widgets can be driven by the variable associated with the scale, but
>>what if I want the application to make interesting decisions based on
>>the scale setting? Do I have to move that more interesting logic into a
>>Tcl script?
> 
> 
> Well that means a command option is missing for the scale widget :). I just
> wrote one some minutes ago. So the interesting question is: what code did
> YOU use to get notified by the scale widget ? If we look at that code, I
> could get an idea how to fix things.

I have not adequately made clear that Celtic has deviated wildly from 
LTk. I have not used recent LTks, tho I stay current with releases in 
case I need to tap your expertise. But I also have amazoned up 
Ousterhout and Welch/Jones and make good use of the on-line doc on the 
tcl site. I did scales, spinboxes, and most things from scratch, at this 
point using just the core LTk low-level wizardry (the hard stuff to work 
out).

As for how I get notified: I /did/ use the command as you did with other 
things (as a callback) and it works fine--not sure why you say it works 
differently.

Here is my scale definition:

(def-widget scale ()
   ()
   (-activebackground -background -borderwidth -cursor
     -font -foreground -highlightbackground -highlightcolor
     -highlightthickness -orient -relief -repeatdelay
     -repeatinterval -takefocus -troughcolor
     -bigincrement (-command nil) -digits -from
     (-tk-label -label) (-tk-length -length) -resolution
     -showvalue -sliderlength -sliderrelief
     -state -tickinterval -to (-tk-variable -variable) -width)
   (:default-initargs
       :md-value (c-in nil)
       :command (lambda (self)
                   (setf (^md-value) (tk-eval (format nil "~a get" 
(^path)))))))

(def-c-output .md-value ((self scale))
   (when new-value
     (if (listp new-value)
         (tk-format "set ~a {~{~a~^ ~}}" (^path) new-value)
       (tk-format "~a set ~a" (^path) new-value))))


...and the enabling macro:

(defmacro def-widget (class (&key (std-factory t))
                        (&rest std-slots)
                        (&rest tk-options) &rest defclass-options)
   (multiple-value-bind (slots outputs)
           (loop for tk-option-def in tk-options
               for slot-name = (intern (de- (if (atom tk-option-def)
                                                tk-option-def (car 
tk-option-def))))
               collecting `(,slot-name :initform nil
				      :initarg ,(intern (string slot-name) :keyword)
				      :accessor ,slot-name)
               into slot-defs
               when (or (atom tk-option-def)
                      (cadr tk-option-def))
               collecting `(def-c-output ,slot-name ((self ,class))
                             (when new-value
                               (configure self ,(string (if (atom 
tk-option-def)
 
tk-option-def (cadr tk-option-def)))
                                 new-value)))

               into outputs
               finally (return (values slot-defs outputs)))
         `(progn
            (defmodel ,class (widget)
              (,@(append std-slots slots))
              ,@defclass-options)
            (defun ,(intern (format nil "MK-~a" class)) (&rest inits)
              (apply 'make-instance ',class inits))
            ,(when std-factory
               `(defmethod make-tk-instance ((self ,class))
                  (trc nil "!!! tk-creating" self)
                  (tk-format ,(format nil "~(~a~) ~~a" class) (path self))))
            ,@outputs)))

> 
> 
>><g> Cello has kinda made FFI bindings seem like a walk in the park to
>>me, but I know what you mean. Where do you see the non-portability?
>>Let's fix that and benefit from better/faster access to all libraries. My
> 
> 
> Well we are lacking any standard for FFI right now. UFFI could be it
> as soon it has callback support. And I think the amount of coded
> needed if it calls the C library behind TK directly would be quite
> big compared to the current Ltk code.
> 
> 
>>ps. as for sending you a snippet, that would be impossible, you would
>>have to grab the whole shebang from CVS to make any sense of it. Cells
>>supports a declarative paradigm in which a big engine takes care of
>>imperative steps such as communicating with Tk, so it is scattered all
>>over the joint.
> 
> 
> Yes, the Lisp code would help me less, but a sketch how you are dealing
> in principal with Tk might help.
> 
> 
>>Here is the resulting tk-send log:
>>
> 
> 
> Ah here we are talking business now :)
>  
> 
>>tk-send> scale .w10.font-size
> 
> 
> there is our scale widget created...
> 
> 
>>tk-send> .w10.font-face configure -command {puts {(callback
>>.W10.FONT-FACE.COMMAND)};flush stdout; list}
> 
> 
> And I think here we get to the root of things. Unfortunately
> scale as well as the scrollbars is written a little bit
> "too clever" (I stumbled over the same thing when just
> writing the command option for Ltk). The command configuration
> option for the scale widget does *not* take the code to run
> when the scale is changed, but function name to call when
> the scale is changed...

My experience is different. I am using the same callback scheme you 
originated:

(def-c-output command ((self widget))
   (when (and new-value (^command-is-callback))
     (configure self "-command"
       (format nil
           "puts {(callback ~a)};flush stdout; list" ;; list cuz Tk 
feeds args to some
                                              ; widgets' commands and 
list will consume syntax
         (register-callback self "command" new-value)))))


In Cell-ese, this means the command slot normally gets set up as a 
callback (I added the callback symbol just to make the ID of a message 
from Tk as a callback a positive identification.)

This works fine for scales, and I wager it would work fine for 
scrollbars, but right now I have just gone with your scroll logic which 
is working fine (and there is where I flag command-is-callback as nil).

But scale commands "callback" just fine. Except, yeah, Tk adds the value 
to the command which is why I have that throwaway "list" trailer to 
consume the value.


  that is, if you do for example:
> myscale configure -command myscalefun
> on every chance of myscale, myscalefun is called with the new
> scale value as a parameter. So I guess the lonely list statement
> at the end of your callback code should deal with the extra argument.
> 
> Here is my updated code for the scale widget in Ltk, if you model your 
> code like it, perhaps all problems are already solved:
> 
> ;;; scale widget
> 
> (defclass scale (widget)
>   ((from :accessor scale-from :initarg :from  :initform nil)
>    (to :accessor scale-to :initarg :to :initform nil)
>    (orient :accessor scale-orient :initarg :orient  :initform nil)
>    ;; added command slot to the scale class
>    (command :accessor command :initarg :command :initform nil)
>    )
>   )
> 
> (defmethod create ((sc scale))
>   ;; new handling of the command argument
>   (when (command sc)
>     (add-callback (name sc) (command sc)) ;; standard callback defining
>   ;; to handle the "special" callback handling, defining a callback
>   ;; function in tcl with the name "widgetname-callback"
>   ;; it consumes the value and sends it together with the 
>     (format-wish "proc ~a-command {val} {puts -nonewline {(\"~a\" };puts
> -nonewline \"[~a get]\";puts {)};flush stdout }" (name sc) (name sc) (path
> sc)))

Excellent. I had decided already to save one round-trip and figure out 
how to just let Tk tell me the new value (instead of throwing it away 
with the "list" trailer, looks like you have the ideal fix.

> 
>   (format-wish "scale ~a -variable ···@[ -from ~a~]·@[ -to ~a~]·@[ -orient
> ~(~a~)~] ~a" (path sc) (name sc)
>                (scale-from sc)
>                (scale-to sc)
>                (scale-orient sc)
>                (if (command sc)
>                    (format nil "-command ~a-command" (name sc) ) ;; just give the name of
> the function to call here
>                  "")
>                ))
> 
> ;; sample usage:
> (with-ltk
>   (defparameter sc (make-instance 'scale :from 10 :to 20 
>                                     :command (lambda (val) 
>                                                 (format t "scale val : ~a~%" val)
>                                                 (force-output))))
>   (pack sc))
> 
> I hope this helps to cure the hanging problems :)

What about handling the <<ListboxSelect>> virtual event? Is not a query 
to Tk still necessary to determine which item was selected? Well, I see 
you do not handle that virtual event yet. And unless I am mistaken they 
do not send along the item selected (which seems like a serious omission).

Anyway, I am not sure we can count on never getting responses in an 
order different from which we would like.

kt


-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Peter Herth
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <ccqv5p$jme$1@newsreader2.netcologne.de>
Kenny Tilton wrote:

> I have not adequately made clear that Celtic has deviated wildly from
> LTk. I have not used recent LTks, tho I stay current with releases in
> case I need to tap your expertise. But I also have amazoned up
> Ousterhout and Welch/Jones and make good use of the on-line doc on the
> tcl site. I did scales, spinboxes, and most things from scratch, at this
> point using just the core LTk low-level wizardry (the hard stuff to work
> out).

I browsed through your Celtic code earlier so I already had the impression
that it differs from Ltk substancely. What I was asking what in priciple
you are trying to do like "defining a callback for the -command option
of the scale and as a response reading the value of the widget". 

 

> But scale commands "callback" just fine. Except, yeah, Tk adds the value
> to the command which is why I have that throwaway "list" trailer to
> consume the value.

Ok, then it should not make a problem communication-wise, but if you
send back the new value with the callback, you save yourself the
reading of the widget and therefore a possibility to get the
communication out of sync :).
  
> Excellent. I had decided already to save one round-trip and figure out
> how to just let Tk tell me the new value (instead of throwing it away
> with the "list" trailer, looks like you have the ideal fix.

:)

> What about handling the <<ListboxSelect>> virtual event? Is not a query
> to Tk still necessary to determine which item was selected? Well, I see
> you do not handle that virtual event yet. And unless I am mistaken they
> do not send along the item selected (which seems like a serious omission).

To be honest, event-handling in Ltk is only done in a rudimentarily way.
But as the support of the widgets is basically done, this will be the
last big step to take towards a 1.0 Version. I am currently planning to
redo the bind mechanism, so that an event object is returned to report
the mouse coordinates, keyboard symbols etc. But to complement that,
for those widgets that have a command option or virtual events,
that will be handled like for the scale widget now. So I am always glad 
for suggestions/hints to missed ones.

> Anyway, I am not sure we can count on never getting responses in an
> order different from which we would like.

Well that is actually the big question I want to solve, either we can
count on getting them in the right order or have to take precautions
to deal with changing response orders. From our discussion I get the
impression that your problems have nothing to do with possible celtic-ltk
differences, but to check this, try running the slider with pure ltk code
and see if you can get that out of sync too (like reading the value of the
scale from the callback). If you get sync problems there too, then its 
probably a Windows-induced phenomenum, as using Linux/Mac Os X I never
observed them (but as mentioned in an earlier post, I am quite certain
that pipes are handled different between Unix/Windows, so it would not
come as a huge surprise... ).

Peter


-- 
pet project: http://dawn.netcologne.de
homepage:    http://www.peter-herth.de
lisp stuff:  http://www.peter-herth.de/lisp.html
get Ltk here: http://www.peter-herth.de/ltk/
From: Peter Herth
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <ccr5gu$4b3$1@newsreader2.netcologne.de>
So, after some digging around I think I have located the source of 
the problem. It happens when the Tk generates events (sends text to
Lisp) while Lisp still processes an earlier event and during this
processing sends requests to Tk. So when Lisp does a read on the
stream, it reads the additional generated events before it can
read an answer. It can be easily demonstrated if I redefine 
the value method on the scale widget:


(defmethod value ((sc scale))
  (format-wish "puts $~a;flush stdout" (name sc))
  (sleep 1)    ;; forcing lag between write and read
  (read-wish))

and using it like:

(defparameter s (make-instance 'scale :from 1 :to 100 :command
                                        (lambda (val)
                                          (format t "scale changed to:~a~%" val)
                                          (force-output)
                                          (format t "scale val read: ~a~%" (value s))(force-output))))

So the good news is: we got an answer to the question whether we can rely on
the order things can be read from Tk.
The bad news is: the answer is *NO*.

But I think I already got an idea how to resolve this, though I have to
ponder it a while (basically something like tagging all output from Tk
and filtering it into "events" and "answers" and dispatching properly
on it). 

Peter

-- 
pet project: http://dawn.netcologne.de
homepage:    http://www.peter-herth.de
lisp stuff:  http://www.peter-herth.de/lisp.html
get Ltk here: http://www.peter-herth.de/ltk/
From: Kenny Tilton
Subject: Re: No peek-char-no-hang?
Date: 
Message-ID: <%4aIc.17497$oW6.4147355@twister.nyc.rr.com>
Peter Herth wrote:
> So, after some digging around I think I have located the source of 
> the problem. It happens when the Tk generates events (sends text to
> Lisp) while Lisp still processes an earlier event and during this
> processing sends requests to Tk. So when Lisp does a read on the
> stream, it reads the additional generated events before it can
> read an answer. It can be easily demonstrated if I redefine 
> the value method on the scale widget:
> 
> 
> (defmethod value ((sc scale))
>   (format-wish "puts $~a;flush stdout" (name sc))
>   (sleep 1)    ;; forcing lag between write and read
>   (read-wish))
> 
> and using it like:
> 
> (defparameter s (make-instance 'scale :from 1 :to 100 :command
>                                         (lambda (val)
>                                           (format t "scale changed to:~a~%" val)
>                                           (force-output)
>                                           (format t "scale val read: ~a~%" (value s))(force-output))))
> 
> So the good news is: we got an answer to the question whether we can rely on
> the order things can be read from Tk.
> The bad news is: the answer is *NO*.
> 
> But I think I already got an idea how to resolve this, though I have to
> ponder it a while (basically something like tagging all output from Tk
> and filtering it into "events" and "answers" and dispatching properly
> on it). 

Right, that is what I meant when I suggested treating everything as an 
Id'ed callback (unless we want to bite the FFI bullet). A gensym could 
be the ID. I think this is a fine fix, btw. And I see this is pretty 
much how I handled <<ListboxSelect>>:

(def-c-output bindings () ;;; (w widget) event fun)
   (loop for binding in new-value
         for name = (create-name)
         do (destructuring-bind (event . fn) binding
              (declare (ignorable event))
              (tk-format "bind ~a ~a {puts {(callback ~a)};flush stdout}"
                (^path) event (register-callback self name fn)))))

(def-widget listbox ()
   ()
   (-activestyle -background -borderwidth -cursor
     -disabledforeground -exportselection -font -foreground
     -height -highlightbackground -highlightcolor -highlightthickness
     -relief -selectbackground -selectborderwidth -selectforeground
     -setgrid -state -takefocus -width
     -xscrollcommand -yscrollcommand
     -listvariable -selectmode)
   (:default-initargs
       :bindings (c? (when (selector self)
                       (list (cons "<<ListboxSelect>>"
                               (lambda (self)
                                 (setf (selection (selector self))
                                   (car (listbox-get-selection 
self))))))))))

kt


-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application