Projects STRLCPY termdash Commits ed738319
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■
    CHANGELOG.md
    skipped 6 lines
    7 7   
    8 8  ## [Unreleased]
    9 9   
     10 +### Fixed
     11 + 
     12 +- Termdash could deadlock when a `Button` or a `TextInput` was configured to
     13 + call the `Container.Update` method.
     14 + 
    10 15  ## [0.9.0] - 28-Apr-2019
    11 16   
    12 17  ### Added
    skipped 267 lines
  • ■ ■ ■ ■ ■ ■
    widgets/button/button.go
    skipped 153 lines
    154 154   )
    155 155  }
    156 156   
    157  -// Keyboard processes keyboard events, acts as a button press on the configured
    158  -// Key.
    159  -//
    160  -// Implements widgetapi.Widget.Keyboard.
    161  -func (b *Button) Keyboard(k *terminalapi.Keyboard) error {
     157 +// activated asserts whether the keyboard event activated the button.
     158 +func (b *Button) keyActivated(k *terminalapi.Keyboard) bool {
    162 159   b.mu.Lock()
    163 160   defer b.mu.Unlock()
    164 161   
    skipped 1 lines
    166 163   b.state = button.Down
    167 164   now := time.Now().UTC()
    168 165   b.keyTriggerTime = &now
     166 + return true
     167 + }
     168 + return false
     169 +}
     170 + 
     171 +// Keyboard processes keyboard events, acts as a button press on the configured
     172 +// Key.
     173 +//
     174 +// Implements widgetapi.Widget.Keyboard.
     175 +func (b *Button) Keyboard(k *terminalapi.Keyboard) error {
     176 + if b.keyActivated(k) {
     177 + // Mutex must be released when calling the callback.
     178 + // Users might call container methods from the callback like the
     179 + // Container.Update, see #205.
    169 180   return b.callback()
    170 181   }
    171 182   return nil
    172 183  }
    173 184   
    174  -// Mouse processes mouse events, acts as a button press if both the press and
    175  -// the release happen inside the button.
    176  -//
    177  -// Implements widgetapi.Widget.Mouse.
    178  -func (b *Button) Mouse(m *terminalapi.Mouse) error {
     185 +// mouseActivated asserts whether the mouse event activated the button.
     186 +func (b *Button) mouseActivated(m *terminalapi.Mouse) bool {
    179 187   b.mu.Lock()
    180 188   defer b.mu.Unlock()
    181 189   
    skipped 1 lines
    183 191   b.state = state
    184 192   b.keyTriggerTime = nil
    185 193   
    186  - if clicked {
     194 + return clicked
     195 +}
     196 + 
     197 +// Mouse processes mouse events, acts as a button press if both the press and
     198 +// the release happen inside the button.
     199 +//
     200 +// Implements widgetapi.Widget.Mouse.
     201 +func (b *Button) Mouse(m *terminalapi.Mouse) error {
     202 + if b.mouseActivated(m) {
     203 + // Mutex must be released when calling the callback.
     204 + // Users might call container methods from the callback like the
     205 + // Container.Update, see #205.
    187 206   return b.callback()
    188 207   }
    189 208   return nil
    skipped 19 lines
  • ■ ■ ■ ■ ■
    widgets/textinput/textinput.go
    skipped 219 lines
    220 220   return nil
    221 221  }
    222 222   
    223  -// Keyboard processes keyboard events.
     223 +// keyboard processes keyboard events.
     224 +// Returns a bool indicating if the content was submitted and the text in the
     225 +// field at submission time.
    224 226  // Implements widgetapi.Widget.Keyboard.
    225  -func (ti *TextInput) Keyboard(k *terminalapi.Keyboard) error {
     227 +func (ti *TextInput) keyboard(k *terminalapi.Keyboard) (bool, string) {
    226 228   ti.mu.Lock()
    227 229   defer ti.mu.Unlock()
    228 230   
    skipped 22 lines
    251 253   ti.editor.reset()
    252 254   }
    253 255   if ti.opts.onSubmit != nil {
    254  - return ti.opts.onSubmit(text)
     256 + return true, text
    255 257   }
    256 258   
    257 259   default:
    258 260   if err := wrap.ValidText(string(k.Key)); err != nil {
    259 261   // Ignore unsupported runes.
    260  - return nil
     262 + return false, ""
    261 263   }
    262 264   if ti.opts.filter != nil && !ti.opts.filter(rune(k.Key)) {
    263 265   // Ignore filtered runes.
    264  - return nil
     266 + return false, ""
    265 267   }
    266 268   ti.editor.insert(rune(k.Key))
    267 269   }
    268 270   
     271 + return false, ""
     272 +}
     273 + 
     274 +// Keyboard processes keyboard events.
     275 +// Implements widgetapi.Widget.Keyboard.
     276 +func (ti *TextInput) Keyboard(k *terminalapi.Keyboard) error {
     277 + if submitted, text := ti.keyboard(k); submitted {
     278 + // Mutex must be released when calling the callback.
     279 + // Users might call container methods from the callback like the
     280 + // Container.Update, see #205.
     281 + return ti.opts.onSubmit(text)
     282 + }
    269 283   return nil
    270 284  }
    271 285   
    skipped 107 lines
Please wait...
Page is in error, reload to recover