Skip to content
2 changes: 1 addition & 1 deletion content/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ func (ct *Content) open(url string, history bool) {
return
}
sli := strings.Index(url, "/")
if sli > 0 {
if sli > 0 && len(url) > sli+1 && url[sli+1] != '#' {
fb, err := fs.ReadFile(ct.Source, url)
if err != nil {
core.MessageSnackbar(ct, "Resource at: "+url+" not found")
Expand Down
34 changes: 34 additions & 0 deletions events/key/chord.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,45 @@ type Chord string
// shortcut formatting based on the underlying system platform without import cycles.
var SystemPlatform string

// KeypadMap maps the keypad versions to standard codes,
// for non-printing characters.
var KeypadMap = map[Codes]Codes{
CodeKeypadEnter: CodeReturnEnter,
CodeKeypadFullStop: CodeFullStop,
CodeKeypadEqualSign: CodeEqualSign,
}

// KeypadAlts are alternate codes for keypad keys to use when
// the NumLock key is on.
var KeypadAlts = map[Codes]Codes{
CodeKeypad1: CodeEnd,
CodeKeypad2: CodeDownArrow,
CodeKeypad3: CodePageDown,
CodeKeypad4: CodeLeftArrow,
CodeKeypad6: CodeRightArrow,
CodeKeypad7: CodeHome,
CodeKeypad8: CodeUpArrow,
CodeKeypad9: CodePageUp,
CodeKeypad0: CodeInsert,
CodeKeypadFullStop: CodeDelete,
}

// NewChord returns a string representation of the keyboard event suitable for
// keyboard function maps, etc. Printable runes are sent directly, and
// non-printable ones are converted to their corresponding code names without
// the "Code" prefix.
func NewChord(rn rune, code Codes, mods Modifiers) Chord {
mods.SetFlag(false, CapsLock)
if !mods.HasFlag(NumLock) && code >= CodeKeypadNumLock && code < CodeKeypadEqualSign {
if ac, ok := KeypadAlts[code]; ok {
rn = 0
code = ac
}
}
if ac, ok := KeypadMap[code]; ok {
code = ac
}
mods.SetFlag(false, NumLock)
modstr := mods.ModifiersString()
if modstr != "" && code == CodeSpacebar { // modified space is not regular space
return Chord(modstr + "Spacebar")
Expand Down
2 changes: 1 addition & 1 deletion events/key/chord_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func TestChordDecode(t *testing.T) {
RunChordDecode(t, "a")
RunChordDecode(t, "Control+A")
RunChordDecode(t, "ReturnEnter")
RunChordDecode(t, "KeypadEnter")
// RunChordDecode(t, "KeypadEnter") // now returns ReturnEnter
RunChordDecode(t, "Backspace")
RunChordDecode(t, "Escape")
}
Expand Down
14 changes: 10 additions & 4 deletions events/key/codes.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,6 @@ const (
CodeCompose Codes = 0x10000
)

// TODO: currently have to use official go stringer for this,
// not custom one, which doesn't currently handle discontinuities
// // go: generate stringer -type=Codes

// TODO: Given we use runes outside the unicode space, should we provide a
// printing function? Related: it's a little unfortunate that printing a
// events.Key with %v gives not very readable output like:
Expand Down Expand Up @@ -233,4 +229,14 @@ var CodeRuneMap = map[Codes]rune{
CodeKeypadPlusSign: '+',
CodeKeypadFullStop: '.',
CodeKeypadEqualSign: '=',
CodeKeypad1: '1',
CodeKeypad2: '2',
CodeKeypad3: '3',
CodeKeypad4: '4',
CodeKeypad5: '5',
CodeKeypad6: '6',
CodeKeypad7: '7',
CodeKeypad8: '8',
CodeKeypad9: '9',
CodeKeypad0: '0',
}
10 changes: 5 additions & 5 deletions events/key/enumgen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions events/key/modifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const (

// Shift is the "Shift" key.
Shift

// CapsLock indicates that CapsLock is toggled on at time of keypress
CapsLock

// NumLock indicates that NumLock is toggled on at time of keypress
NumLock
)

// ModifiersString returns the string representation of the modifiers using
Expand Down
20 changes: 17 additions & 3 deletions events/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,27 @@ func (es *Source) Key(typ Types, rn rune, code key.Codes, mods key.Modifiers) {
ev.Init()
es.Deque.Send(ev)

_, mapped := key.CodeRuneMap[code]
mrn, mapped := key.CodeRuneMap[code]

if typ == KeyDown && ev.Code < key.CodeLeftControl &&
(ev.HasAnyModifier(key.Control, key.Meta) || !mapped || ev.Code == key.CodeTab) {
if typ != KeyDown {
return
}

if !ev.HasAnyModifier(key.NumLock) && code >= key.CodeKeypadNumLock && code < key.CodeKeypadEqualSign {
if mapped {
rn = mrn
}
che := NewKey(KeyChord, rn, code, mods)
che.Init()
es.Deque.Send(che)
return
}

if ev.Code < key.CodeLeftControl && (ev.HasAnyModifier(key.Control, key.Meta) || !mapped || ev.Code == key.CodeTab) {
che := NewKey(KeyChord, rn, code, mods)
che.Init()
es.Deque.Send(che)
return
}
}

Expand Down
7 changes: 3 additions & 4 deletions paint/ppath/intersect/bezier.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ func findInflectionPointRangeCubicBezier(p0, p1, p2, p3 math32.Vector2, t, toler
// find the range around an inflection point that we consider flat within the flatness criterion
if math32.IsNaN(t) {
return math32.Inf(1), math32.Inf(1)
}
if t < 0.0 || t > 1.0 {
} else if t < 0.0 || t > 1.0 {
panic("t outside 0.0--1.0 range")
}

Expand All @@ -145,12 +144,12 @@ func findInflectionPointRangeCubicBezier(p0, p1, p2, p3 math32.Vector2, t, toler

if ppath.Equal(nr.X, 0.0) && ppath.Equal(nr.Y, 0.0) {
// if rn is still zero, this curve has p0=p1=p2, so it is straight
return 0.0, 1.0
return math32.Max(0.0, 2.0*t-1.0), 1.0
}

s3 := math32.Abs(ns.X*nr.Y-ns.Y*nr.X) / math32.Hypot(nr.X, nr.Y)
if ppath.Equal(s3, 0.0) {
return 0.0, 1.0 // can approximate whole curve linearly
return math32.Max(0.0, 2.0*t-1.0), 1.0 // can approximate whole curve linearly
}

tf := math32.Cbrt(tolerance / s3)
Expand Down
1 change: 1 addition & 0 deletions system/driver/desktop/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ func (a *App) NewWindow(opts *system.NewWindowOptions) (system.Window, error) {
w.Glw.SetCursorPosCallback(w.CursorPosEvent)
w.Glw.SetCursorEnterCallback(w.CursorEnterEvent)
w.Glw.SetDropCallback(w.DropEvent)
w.Glw.SetInputMode(glfw.LockKeyMods, glfw.True)

w.Show()
a.RunOnMain(func() {
Expand Down
9 changes: 9 additions & 0 deletions system/driver/desktop/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ func GlfwMods(mod glfw.ModifierKey) key.Modifiers {
if mod&glfw.ModSuper != 0 {
m.SetFlag(true, key.Meta)
}
if mod&glfw.ModCapsLock != 0 {
m.SetFlag(true, key.CapsLock)
}
if mod&glfw.ModNumLock != 0 {
m.SetFlag(true, key.NumLock)
}
return m
}

Expand All @@ -45,6 +51,9 @@ func (w *Window) FocusWindow() *Window {
// physical key
func (w *Window) KeyEvent(gw *glfw.Window, ky glfw.Key, scancode int, action glfw.Action, mod glfw.ModifierKey) {
mods := GlfwMods(mod)
if TheApp.Platform() == system.MacOS {
mods.SetFlag(true, key.NumLock) // mac always acts like numlock is on
}
ec := GlfwKeyCode(ky)
rn := key.CodeRuneMap[ec]
typ := events.KeyDown
Expand Down
3 changes: 3 additions & 0 deletions system/driver/desktop/screen.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ func (a *App) PollScreenChanges() {
}
a.GetScreens()
for i, sc := range a.Screens {
if i >= len(csc) { // number could have changed
goto doUpdate
}
ssc := csc[i]
if *ssc != *sc {
goto doUpdate
Expand Down
3 changes: 1 addition & 2 deletions system/driver/desktop/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,7 @@ func (w *Window) SetCursorEnabled(enabled, raw bool) {
}
}

/////////////////////////////////////////////////////////
// Window Callbacks
//////// Window Callbacks

func (w *Window) Moved(gw *glfw.Window, x, y int) {
w.Mu.Lock()
Expand Down