widget: ensure proper modifiers on key events

This commit extends the key event handling for text widgets to always check for
appropriate modifier keys. Previously this wasn't necessary, as the text widgets
would only ever receive key events it registered for, but now it may be the top-level
key event handler and thus receive all key events that aren't handled elsewhere.

Fixes: https://todo.sr.ht/~eliasnaur/gio/487
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit is contained in:
Chris Waldon
2023-03-13 10:13:40 -04:00
committed by Elias Naur
parent 107401cf07
commit b09ef80d9f
2 changed files with 45 additions and 35 deletions
+31 -26
View File
@@ -396,6 +396,37 @@ func (e *Editor) command(gtx layout.Context, k key.Event) {
if k.Modifiers.Contain(key.ModShift) {
selAct = selectionExtend
}
if k.Modifiers.Contain(key.ModShortcut) {
switch k.Name {
// Initiate a paste operation, by requesting the clipboard contents; other
// half is in Editor.processKey() under clipboard.Event.
case "V":
if !e.ReadOnly {
clipboard.ReadOp{Tag: &e.eventKey}.Add(gtx.Ops)
}
// Copy or Cut selection -- ignored if nothing selected.
case "C", "X":
e.scratch = e.text.SelectedText(e.scratch)
if text := string(e.scratch); text != "" {
clipboard.WriteOp{Text: text}.Add(gtx.Ops)
if k.Name == "X" && !e.ReadOnly {
e.Delete(1)
}
}
// Select all
case "A":
e.text.SetCaret(0, e.text.Len())
case "Z":
if !e.ReadOnly {
if k.Modifiers.Contain(key.ModShift) {
e.redo()
} else {
e.undo()
}
}
}
return
}
switch k.Name {
case key.NameReturn, key.NameEnter:
if !e.ReadOnly {
@@ -447,32 +478,6 @@ func (e *Editor) command(gtx layout.Context, k key.Event) {
e.text.MoveStart(selAct)
case key.NameEnd:
e.text.MoveEnd(selAct)
// Initiate a paste operation, by requesting the clipboard contents; other
// half is in Editor.processKey() under clipboard.Event.
case "V":
if !e.ReadOnly {
clipboard.ReadOp{Tag: &e.eventKey}.Add(gtx.Ops)
}
// Copy or Cut selection -- ignored if nothing selected.
case "C", "X":
e.scratch = e.text.SelectedText(e.scratch)
if text := string(e.scratch); text != "" {
clipboard.WriteOp{Text: text}.Add(gtx.Ops)
if k.Name == "X" && !e.ReadOnly {
e.Delete(1)
}
}
// Select all
case "A":
e.text.SetCaret(0, e.text.Len())
case "Z":
if !e.ReadOnly {
if k.Modifiers.Contain(key.ModShift) {
e.redo()
} else {
e.undo()
}
}
}
}
+14 -9
View File
@@ -296,6 +296,20 @@ func (e *Selectable) command(gtx layout.Context, k key.Event) {
if k.Modifiers.Contain(key.ModShift) {
selAct = selectionExtend
}
if k.Modifiers == key.ModShortcut {
switch k.Name {
// Copy or Cut selection -- ignored if nothing selected.
case "C", "X":
e.scratch = e.text.SelectedText(e.scratch)
if text := string(e.scratch); text != "" {
clipboard.WriteOp{Text: text}.Add(gtx.Ops)
}
// Select all
case "A":
e.text.SetCaret(0, e.text.Len())
}
return
}
switch k.Name {
case key.NameUpArrow:
e.text.MoveLines(-1, selAct)
@@ -327,15 +341,6 @@ func (e *Selectable) command(gtx layout.Context, k key.Event) {
e.text.MoveStart(selAct)
case key.NameEnd:
e.text.MoveEnd(selAct)
// Copy or Cut selection -- ignored if nothing selected.
case "C", "X":
e.scratch = e.text.SelectedText(e.scratch)
if text := string(e.scratch); text != "" {
clipboard.WriteOp{Text: text}.Add(gtx.Ops)
}
// Select all
case "A":
e.text.SetCaret(0, e.text.Len())
}
}