Check-in [608b4bc12b]

Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:New TIP 532: Re-implementation of event loop processing.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 608b4bc12b3251a679069feaf4d1aa36f7b0f2d03dfe53737c32f7f77485a836
User & Date: gcramer 2019-01-13 11:43:21
Context
2019-01-13
14:25
Update of TIP 532. check-in: e2821cfbab user: gcramer tags: trunk
11:43
New TIP 532: Re-implementation of event loop processing. check-in: 608b4bc12b user: gcramer tags: trunk
2019-01-08
08:37
fix typo check-in: da14be79f4 user: pooryorick tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added tip/532,md.

            1  +# TIP 532: Re-implementation of event loop processing.
            2  +	Author:         Gregor Cramer <[email protected]>
            3  +	State:          Final
            4  +	Type:           Project
            5  +	Vote:           Pending
            6  +	Created:        09-Jan-2019
            7  +	Post-History:  
            8  +	Keywords:       Tk, bind, event, event loop
            9  +	Tcl-Version:    8.7
           10  +	Tk-Branch:      bug6e8afe516d
           11  +----
           12  +
           13  +# Abstract
           14  +
           15  +Current implementation of event loop processing suffers from a limited event ring.
           16  +This limitation is causing unexpected behavior. Moreover some issues in event loop
           17  +handling are known.
           18  +
           19  +Increasing the event size of the event ring can solve the problems caused by event
           20  +queue overflow locally, but not in general. Therefore the author decided to re-implement
           21  +the event processing, the revised implementation is working as if the event ring is
           22  +unlimited. Moreover new implementation is more efficient (in time), and all known
           23  +issues in event handling have been eliminated.
           24  +
           25  +This project (re-implementing the event loop handling) has been started with error report
           26  +[Severe bugs in binding (tkBind.c)](https://core.tcl-lang.org/tk/tktview/6e8afe516df85f6213f436ef7c2fab2ec2d11c76).
           27  +
           28  +# Rationale
           29  +
           30  +The following problems, caused by event ring overflow, have been solved:
           31  +
           32  +1. Sometimes double-clicks with mouse will not be detected, nothing happens although this
           33  +event is bound (see test case
           34  +[bind-32.2](https://core.tcl-lang.org/tk/artifact/6377cb0d762b7261?ln=6123-6143)).
           35  +This problem occurs often in applications[Scidb](http://scidb.sourceforge.net),
           36  +because this application is using tooltips heavily, causing a lot of intervening
           37  +expose events.
           38  +
           39  +2. Immediately after startup of application [Scidb](http://scidb.sourceforge.net)
           40  +(same with applications [Scid](http://scid.sourceforge.net), and
           41  +[Scid vs PC](http://scidvspc.sourceforge.net))
           42  +it's not possible to open the menu via a shortcut like \<Alt-m\>. This event will be
           43  +gobbled, because of many intervening events, causing an event ring overflow.
           44  +
           45  +3. After switching a tab pane in a notebook window the tab is losing the focus sometimes.
           46  +This has been observed in applications [Scid](http://scid.sourceforge.net), and
           47  +[Scid vs PC](http://scidvspc.sourceforge.net).
           48  +
           49  +Moreover the following issues have been solved:
           50  +
           51  +4. It's possible to bind an event like `\<Quadruple-1\>`, but it's nearly impossible to
           52  +trigger this event (with mousepad). Even a triple-click is not so easy. This behavior is
           53  +user-unfriendly, and it seems that it is caused by an erroneous implementation.
           54  +
           55  +5. If a statement like `event generate . \<1\>` is executed, and after some time
           56  +(\> 500 ms) this statement is executed again, then it's likeky that a double-click event
           57  +will be triggered, even if a single-click event is expected, because the triggering
           58  +of double-click events has to fit time requirements (due to manual; see test case
           59  +[bind-32.4](https://core.tcl-lang.org/tk/artifact/6377cb0d762b7261?ln=6158-6171)).
           60  +
           61  +6. `event generate . \<FocusIn\> -sendevent 1` is not working, the argument of
           62  +`sendevent` get lost (test case
           63  +[bind-32.6](https://core.tcl-lang.org/tk/artifact/6377cb0d762b7261?ln=6192-6204)).
           64  +
           65  +7. See following code:
           66  +
           67  +		bind . \<Double-1\> { lappend x "Double" }  
           68  +		bind . \<1\>\<1\> { lappend x "11" }  
           69  +		event generate . \<1\> -x 0 -y 0 -time 0  
           70  +		event generate . \<1\> -x 0 -y 0 -time 0
           71  +		set x
           72  +
           73  +	This gives the result `11`, but `Double` is expected, because the time (and space)
           74  +	constraints for a double click are fulfilled. With other words, the legacy implementation
           75  +	is not preferring the most specialized event. But it should, because the manual says
           76  +	(`man bind`):
           77  +
           78  +	> If more than one binding matches a particular event and they have the
           79  +	> same tag, then the most specific binding is chosen and its script is
           80  +	> evaluated.
           81  +
           82  +	And the sequence `\<Double-1\>` is more specific than `\<1\>\<1\>` because of time and
           83  +	space requirements (in `\<Double-1\>`). Note that constant `PREFER_MOST_SPECIALIZED_EVENT=1`
           84  +	has to set when compiling to enable this new feature.
           85  +
           86  +8. Legacy implementation cannot handle homogeneous equal sequences properly, see this script:
           87  +
           88  +		bind . <1><Control-1> { lappend x "first" }
           89  +		bind . <Control-1><1> { lappend x "last" }
           90  +		event generate . <Control-1>
           91  +		event generate . <Control-1>
           92  +		set x
           93  +	
           94  +	Manual (`man bind`) says:
           95  +
           96  +	> If these tests fail to determine a winner, then the most recently registered
           97  +	> sequence is the winner.
           98  +
           99  +	In this script there is no winner, so the latter defined one has to be chosen, and
          100  +	revised implementation is doing this.
          101  +
          102  +Legacy code also suffers from causing memory holes, revised implementation is tested
          103  +to be memory friendly.
          104  +
          105  +The revised implementation supports an additional syntax for binding motion events
          106  +(if constant `SUPPORT_ADDITIONAL_MOTION_SYNTAX=1` is set when compiling). E.g.,
          107  +the following bindings
          108  +
          109  +	bind . \<B2-Motion\> { ... }  
          110  +	bind . \<B1-B2-Motion\> { ... }
          111  +
          112  +can be expressed in a different way:
          113  +
          114  +  	bind . \<Motion-2\> { ... }  
          115  +  	bind . \<Motion-1-2\> { ... }
          116  +
          117  +The additional syntax is easier to remember, because button press/release events will also
          118  +be expressed in the latter form, for example `bind . \<ButtonPress-1\>`. The former
          119  +syntax (`\<B2-Motion\>`) form will still be supported.
          120  +
          121  +# Specification
          122  +
          123  +The whole handling in file `general/tkBind.c` has been re-implemented. This implementation
          124  +is passing all test cases in `tests/bind.test`. Note that legacy implementation is failing
          125  +in some (of the new) test cases.
          126  +
          127  +Case (4): Legacy implementation is computing the time difference of nth click with fst click,
          128  +and tests whether it is less than 500 ms. But this seems to be an implementation bug. Revised
          129  +implementation computes the difference of nth and (n+1)th click. This behavior also conforms
          130  +better to the behavior of other toolkits. With new implementation the use of quadruple clicks
          131  +(and triple clicks) is unproblematic. See also test case
          132  +[bind-32.6](https://core.tcl-lang.org/tk/artifact/6377cb0d762b7261?ln=6172-6191).
          133  +
          134  +Case (5) is only a minor bug, and there exists a work-around. But the author decided to
          135  +eliminate this design bug, with revised implementation option **-time** is recognizing new
          136  +special value **current**, and is using the current event time in this case. This extension
          137  +is fully backward compatible. See also test case
          138  +[bind-32.4](https://core.tcl-lang.org/tk/artifact/6377cb0d762b7261?ln=6158-6171).
          139  +
          140  +For the fix of case (6) the author decided that non-zero values (given with option
          141  +**-send_event**) will be converted to **1**. This is conform to the manual, see
          142  +`man bind` (search for **Sendevent**), see also lines 3287ff in legacy file
          143  +[generic/tkBind.c](http://core.tcl.tk/tk/artifact/e41f45f7f6ac3447?ln=4178-4203).
          144  +
          145  +The fix of (7) is not fully backwards compatible. But in the author's opinion this is not
          146  +a real problem, nobody is using sequences like `\<1\>\<1\>`, it is not expected that
          147  +applications have to be adjusted.
          148  +
          149  +Fix of (8) is correcting a major bug, see test case
          150  +[bind-33.13](https://core.tcl-lang.org/tk/artifact/6377cb0d762b7261?ln=6550-6566).
          151  +
          152  +# Implementation
          153  +
          154  +Please refer to the
          155  +[bug6e8afe516d](https://core.tcl-lang.org/tk/timeline?r=bug6e8afe516d)
          156  +branch of the core Tcl repository.
          157  +
          158  +The event ring has been removed. Revised implementation is working with promoted
          159  +event bindings, and remembers the latest event per event type. This technique works
          160  +as if we have an inifinite event ring, so no overflow is possible.
          161  +
          162  +Based on tests the performance in time is better than with legacy implementation. This
          163  +result is expected, because a triple-nested loop, executed for each incoming event, has
          164  +been changed to a quasi-double-nested loop (only in very seldom cases it is still
          165  +triple-nested). Furthermore the traversed lists are shorter than with legacy implementation,
          166  +because the event ring, always containing 30 items, has been eliminated. Only unbinding
          167  +a tag is a bit slower than before. Memory consumption did not change significantly.
          168  +
          169  +# Backwards Compatibility
          170  +
          171  +Fix of issue (7) is not fully backwards compatible (more details in section **Rationale**).
          172  +
          173  +Moreover fix of issue (8) is not backwards compatible, but here erroneous behavior has been
          174  +corrected.
          175  +
          176  +Beside these two exceptions the revised implementation is fully backwards compatible, even
          177  +if the additional syntax style for motion bindings is enabled.
          178  +
          179  +# Copyright
          180  +
          181  +This document has been placed in the public domain.