i've noticed that when snarfing some text in an acme window by chording cut & paste that the window often ends up in "modified" state. after some experimentation, i've found that this is because i'm generating the following sequence of button events (button 1 least significant): 0 0 1 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 i.e. button 1 is being released before button 3. acme interprets the last event as an extra "paste", which sets the window to modified. this patch is one way of fixing the problem: it makes b1-b2-b3-b3... equivalent to: b1-b2-b3 the fix relies on the observation that once you've done one operation (cut or paste) you'll never do a different operation (other than undo) for that chording sequence. Reference: /n/sources/patch/applied/acmechord Date: Mon Apr 5 23:22:12 CES 2004 --- /sys/src/cmd/acme/text.c Mon Apr 5 23:22:13 2004 +++ /sys/src/cmd/acme/text.c Mon Apr 5 23:22:12 2004 @@ -861,7 +861,7 @@ { uint q0, q1; int b, x, y; - int state; + int state, op; selecttext = t; /* @@ -917,12 +917,12 @@ clicktext = nil; textsetselect(t, q0, q1); flushimage(display, 1); - state = 0; /* undo when possible; +1 for cut, -1 for paste */ + state = op = 0; /* undo when possible; +1 for cut, -1 for paste */ while(mouse->buttons){ mouse->msec = 0; b = mouse->buttons; if(b & 6){ - if(state==0 && t->what==Body){ + if(state==0 && op==0 && t->what==Body){ seq++; filemark(t->w->body.file); } @@ -931,18 +931,18 @@ winundo(t->w, TRUE); textsetselect(t, q0, t->q0); state = 0; - }else if(state != 1){ + }else if(state != 1 && op != -1){ cut(t, t, nil, TRUE, TRUE, nil, 0); - state = 1; + op = state = 1; } }else{ if(state==1 && t->what==Body){ winundo(t->w, TRUE); textsetselect(t, q0, t->q1); state = 0; - }else if(state != -1){ + }else if(state != -1 && op != 1){ paste(t, t, nil, TRUE, FALSE, nil, 0); - state = -1; + op = state = -1; } } textscrdraw(t);