op: change Defer to only restore transformation state

It turns out restoring all operation state from the moment Defer
is executed is too much; for example, a right-click pop-up needs
the transformation, but not the current clip.

Change Defer to only restore the transformation, and reset all
other state.

Other combinations may be needed in future; we'll deal with them then,
possibly by exposing the load state mask.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-01-19 20:04:30 +01:00
parent eea1dbc176
commit d6886737a5
8 changed files with 84 additions and 34 deletions
+4 -2
View File
@@ -140,7 +140,7 @@ func (q *keyQueue) resolveFocus(events *handlerEvents) resolveState {
q.states[id] = state
state = resolveState{}
case opconst.TypeLoad:
id := ops.DecodeLoad(encOp.Data)
id, mask := ops.DecodeLoad(encOp.Data)
restored := q.states[id]
if state.keyboard > restored.keyboard {
restored.keyboard = state.keyboard
@@ -148,7 +148,9 @@ func (q *keyQueue) resolveFocus(events *handlerEvents) resolveState {
if state.pri.replaces(restored.pri) {
restored.tag, restored.pri = state.tag, state.pri
}
state = restored
if mask != 0 {
state = restored
}
}
}
return state
+17 -6
View File
@@ -85,22 +85,33 @@ const (
areaEllipse
)
func (q *pointerQueue) save(id int, state collectState) {
if extra := id - len(q.states) + 1; extra > 0 {
q.states = append(q.states, make([]collectState, extra)...)
}
q.states[id] = state
}
func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents) {
state := collectState{
area: -1,
node: -1,
}
q.save(opconst.InitialStateID, state)
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
switch opconst.OpType(encOp.Data[0]) {
case opconst.TypeSave:
id := ops.DecodeSave(encOp.Data)
if extra := id - len(q.states) + 1; extra > 0 {
q.states = append(q.states, make([]collectState, extra)...)
}
q.states[id] = state
q.save(id, state)
case opconst.TypeLoad:
id := ops.DecodeLoad(encOp.Data)
state = q.states[id]
id, mask := ops.DecodeLoad(encOp.Data)
s := q.states[id]
if mask&opconst.TransformState != 0 {
state.t = s.t
}
if mask&^opconst.TransformState != 0 {
state = s
}
case opconst.TypePass:
state.pass = encOp.Data[1] != 0
case opconst.TypeArea: