Problem Losing Expose Events 
Author Message
 Problem Losing Expose Events

To ensure that a window gets painted before going on to other things, John

Ousterhout writes:

  The bottom line is that you have to explicitly wait until you *know* that
  the window has been displayed.  The way to do this is with the tkwait command.
  Set up a binding for <Expose> on the window you want to see, with the
  binding set to modify a particular variable.  Then use tkwait to wait for
  the variable to change to the given value.  Once you know the window's up,
  then you can go off and do your other work.  Be sure to do one more update
  so that the window gets displayed, and also be sure to remove the binding
  when you're done.  Sorry this is so complicated... there should probably
  be a procedure in the Tk script library to do this automatically.

Trying to follow that advice, I implemented the following test:
#!/home/schendr/tcl/bin/pish -f

proc genName {{var var}} {
  global nameCount
  if [info exists nameCount($var)] {
    incr nameCount($var)
  } else {
    set nameCount($var) 0
  return "$var$nameCount($var)"


proc timedMsg { msg { timeout 30000 }} {
  set winDone {0}
  set w [genName .InfoMessage]
  toplevel $w
  bind $w <Expose> { set winDone {1} }
  wm withdraw $w
  wm title $w "Message"

  frame $w.m

  set tmp [split $msg \n]
  set i 0
  foreach line $tmp {
    set i [max $i [clength $line]]

  message $w.m.l -text "$msg" \
    -width [expr $i*9] \
    -relief {raised} \
    -justify {center}
  button $w.m.b -command "destroy $w" -text "OK"

  pack append $w.m $w.m.l top $w.m.b { top pady 5 }
  pack append $w $w.m {top expand fill}
  if { $timeout != "INFINITE" } { after $timeout "removeTimedMsg $w" }

  wm deiconify $w
  tkwait variable winDone

  return $w


proc removeTimedMsg { win } {

  if { [lsearch [winfo children .] $win] > -1 } { destroy $win }


frame .f -bg {linen} -relief {raised}
button .f.testbug -text {Launch Msg Win} -bg {cornflowerblue} -fg {white} \
  -command {
    timedMsg "Test of expose bug" 3000
    puts stdout "Returned from timed message"
button .f.quit -text {Quit} -bg {red} -fg {white} -command { destroy . }
pack append .f .f.testbug { top frame center padx 10 pady 10 } \
               .f.quit { top frame center padx 10 pady 10 }
pack append . .f { top frame center expand fill }


The result on a Sun SPARCStation 2 running X11R4/Motif was that the proc
timedMsg never returned to the caller.  When the Quit button is pushed on the
main window the window is destroyed, but the program hangs and has to be killed
at the system level.  It is as if the Expose event is being lost or the
variable change is taking place before the tkwait is executed.

The above technique works *most* of the time when using Open Windows 2/vtwm, but
not always.

The only sure way around this was to grab the window created by timedMsg, have
timedMsg return its window name to the caller and let the caller do a tkwait
window on the timedMsg window.

I'm using Tk 2.3 with tclX6.4c.

+--------------- Dan R. Schenck - Data Management - TEXACO EPTD ---------------+

|    _   __         Voice:    (713) 954-6053  Fax:  (713) 954-6911             |
|   /_) /-/ /\/     US Mail:  Texaco, Inc., 3901 Briarpark, Houston, TX 77042  |

Tue, 06 Jun 1995 22:57:49 GMT  
 [ 1 post ] 

 Relevant Pages 

1. Problem losing expose events

2. Expose Events/screen refresh when exposed

3. Problem refreshing canvas after Expose event

4. Expose event problem in tk8.0a2 in Win95

5. Tk8.0b2: menu generated expose events

6. Q: Expose event

7. Trapping an Expose Event

8. force Expose event over whole window?

9. Losing EVENT:Timer?

10. Where is the LOSE FOCUS event?

11. Lost the System Event Display

12. Event case loses connection to data structure when data structure is modified


Powered by phpBB® Forum Software