Re: disabling the mouse on Windows



Steve Blinkhorn wrote:
I'm in the process of trying to fix some minor annoyances for a
customer in an application that was built with 8.0 with a custom
version of wish using the Borland compiler several years ago.

The application was built specifically not to use the mouse, but users
- all novices by definition - are nonetheless fiddling with the mouse
and changing the focus in ways that mangle the logic of the
application.   Originally, there were instructions to
physically disconnect the mouse, but that's quite hard with a touchpad
on a notebook.

Ideally, I would have a nonexistent mouse cursor and disable the mouse
buttons entirely for the duration of the application.   The real
problem is that users are clicking on parts of the screen in ways that
change the stacking order of the widgets, so it's the default
behaviour of a mouse click in delivering the focus that's causing the
problem.   The obvious

bind all <ButtonPress-1> {}

doesn't work (whereas "bind all <Tab> {}" does).

Is there something I'm missing, or was this a bug that I'm stuck with
unless I upgrade the whole application to a later release?


Are you familiar with bindtags? Bindtags define how events are processed when received by a widget. By default, "all" is last in the bindtags for a widget, which means any bindings associated with the toplevel, an individual widget, and a widget class all come before "all".


Most default bindings are associated with the widget class, which is why binding to "all" seems to have no effect. Tab is one of the few events that by default is associated with "all", which is why you can override the default tab behavior but not default click behavior.

The problem is, you want to apply a binding that is applied before any other bindings rather than after. This means you either a) have to apply the binding to each widget, or b) alter the bindtags for each widget.

For the latter, here's an example to illustrate the concept:

    button .b1 -text "B1" -command {puts "B1 pressed"}
    button .b2 -text "B2" -command {puts "B2 pressed"}
    pack .b1 .b2
    bindtags .b1 [linsert [bindtags .b1] 0 "special"]
    bind special <1> {break}

You could recursively set the bindtags for every widget by writing a proc that acts on a widget and then all children of a widget. If you are certain you have no commands that begin with "." you can also get away with a simple non-recursive loop over [info commands .*]. It's not bullet-proof since it's possible to have commands that match .* that aren't widgets, but usually it works just fine.


Another solution is to do a grab on an invisible widget, which will cause that widget to receive all mouse events. Be careful with grabs though, it's easy to effectively freeze an application. Since your app is designed for keyboard use only that shouldn't be a problem.
.



Quantcast