Prev: Remote devices send out EOF when running in cron?
Next: Tcl interface to the FrameMaker desktop publishing system
From: Óscar Fuentes on 10 Feb 2010 16:04 Robert Heller <heller(a)deepsoft.com> writes: >> >> Is there a simple mechanism for disabling all keyboard input for a >> >> given toplevel and enabling it later? >> > >> > man grab >> > man focus >> > >> > Trick: create a canvas, but never map it. Set grab and focus there >> > during times that things are 'busy'. Keyboard / mouse events are >> > flushed away. >> >> It seems that it is not possible to set the focus on an unmapped widget. >> > > Huh? Sure it is -- I do this all of the time. By 'unmapped' what I > mean is creating a widget (such as a canvas, which normally will accept > both keyboard and mouse events) on the same toplevel as you are > displaying and then never packing, placing, or gridding it. I would > normally do this on the toplevel widget, which is generally always > displayed. I did if { ! [winfo exists .toplevel.sucker] } { canvas .toplevel.sucker } focus .toplevel.sucker grab .toplevel.sucker <do-something> puts [focus] grab release .toplevel.sucker This prints nothing and the keypresses made while <do-something> are cached and processed normally after the grab is released. From your description, it seems like 3 or 4 lines of code would do the trick. Care to share them? Thanks.
From: Robert Heller on 10 Feb 2010 18:05 At Wed, 10 Feb 2010 22:04:02 +0100 =?utf-8?Q?=C3=93scar_Fuentes?= <ofv(a)wanadoo.es> wrote: > > Robert Heller <heller(a)deepsoft.com> writes: > > >> >> Is there a simple mechanism for disabling all keyboard input for a > >> >> given toplevel and enabling it later? > >> > > >> > man grab > >> > man focus > >> > > >> > Trick: create a canvas, but never map it. Set grab and focus there > >> > during times that things are 'busy'. Keyboard / mouse events are > >> > flushed away. > >> > >> It seems that it is not possible to set the focus on an unmapped widget. > >> > > > > Huh? Sure it is -- I do this all of the time. By 'unmapped' what I > > mean is creating a widget (such as a canvas, which normally will accept > > both keyboard and mouse events) on the same toplevel as you are > > displaying and then never packing, placing, or gridding it. I would > > normally do this on the toplevel widget, which is generally always > > displayed. > > I did > > if { ! [winfo exists .toplevel.sucker] } { > canvas .toplevel.sucker > } > focus .toplevel.sucker > grab .toplevel.sucker > <do-something> > puts [focus] > grab release .toplevel.sucker > > This prints nothing and the keypresses made while <do-something> are > cached and processed normally after the grab is released. > > From your description, it seems like 3 or 4 lines of code would do the > trick. Care to share them? What you have should work. *Depending* on what <do-something> is. Generally in my code, <do-something> is usually a tkwait of some sort (depends on what is going on). For example: if {[catch {open "|foo -bar whatever" r} pipefp]} { tk_messageBox -type ok -icon error -message "$pipefp" return } # processpipe reads the pipe and does something (maybe updates a log # and/or progress bar). Incr's pipeeof on eof. # (Mostly my code would do this inside of a snit type / widget / # widgetadpator and use object variables and methods, rather than # globals.) set ::pipeeof 0 fileevent $pipefp readable [list processpipe $pipefp] set oldfocus [focus] focus .toplevel.sucker grab .toplevel.sucker tkwait variable ::pipeeof if {"$oldfocus" ne ""} {focus $oldfocus} grab release .toplevel.sucker My guess is that your <do-something> is NOT causing the event-loop to be reentered. If the event-loop is not re-entered, then the events will be neither discarded nor processed. They will just accumulate until the event-loop is reentered, probably after the grab has been released. > > Thanks. > -- Robert Heller -- 978-544-6933 Deepwoods Software -- Download the Model Railroad System http://www.deepsoft.com/ -- Binaries for Linux and MS-Windows heller(a)deepsoft.com -- http://www.deepsoft.com/ModelRailroadSystem/
From: Óscar Fuentes on 10 Feb 2010 21:14 Robert Heller <heller(a)deepsoft.com> writes: >> >> >> Is there a simple mechanism for disabling all keyboard input for a >> >> >> given toplevel and enabling it later? >> >> I did >> >> if { ! [winfo exists .toplevel.sucker] } { >> canvas .toplevel.sucker >> } >> focus .toplevel.sucker >> grab .toplevel.sucker >> <do-something> >> puts [focus] >> grab release .toplevel.sucker >> >> This prints nothing and the keypresses made while <do-something> are >> cached and processed normally after the grab is released. > > What you have should work. *Depending* on what <do-something> is. > Generally in my code, <do-something> is usually a tkwait of some sort > (depends on what is going on). For example: [snip] > My guess is that your <do-something> is NOT causing the event-loop to be > reentered. If the event-loop is not re-entered, then the events will be > neither discarded nor processed. They will just accumulate until the > event-loop is reentered, probably after the grab has been released. Good point but, if that were all of the history, doing update grab release .toplevel.sucker would take care of the pending keypresses. Putting the grab as early as possible and releasing it as late as possible makes things better, but the problem still happens if you press keys fast enough (I measured the time elapsed for a fast two-key sequence: it is easy to get less than 20 milliseconds). The sequence, as shown on the console with the help of some `puts', is: grab start processing first key event process second key event finish processing first key event ungrab Now, I don't know enough about tk's event loop, but AFAIK this shouldn't happen. Even if some library call on the middle executes an `update', this shouldn't be a problem since there is a grab. I confirmed that, at the ungrab point, the current grab is the right one.
From: jdc on 11 Feb 2010 03:29 When using 8.6, you might want to check [tk busy].
From: Uwe Klein on 11 Feb 2010 04:04 jdc wrote: > When using 8.6, you might want to check [tk busy]. which previously had a single home in the blt package. uwe
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Remote devices send out EOF when running in cron? Next: Tcl interface to the FrameMaker desktop publishing system |