rivo / tview

Terminal UI library with rich, interactive widgets — written in Golang

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[question/bug] Trying to understand key events better

dkyanakiev opened this issue · comments

Hi,

Hopefully this is a good format to ask a question..
I've been toying around with the library after some inspiration from a few similar TUIs and wanted to try and build my own.
For the most part it's great and I manage to figure out all the issues I have, except one.

The Enter key.. no matter what I do to configure my inputs .. the moment I hit enter - my app goes back to the main table that is shown when starting the app.

I've tried modifying the keyEnter to return nil, to just print out log messages..
It would do what it's supposed to do + still return me to my Home Screen . Example: https://github.com/dkyanakiev/vaul7y/blob/feature/improvments/view/policy.go#L49
On tables that don't even have the enter key configured in the events the result is the same.

I've tried looking for similar issues but I can't seem to find anything even close to my issue.
Thanks in advance

I actually found the issue I believe
Adding a code snippet

func (v *View) InputMainCommands(event *tcell.EventKey) *tcell.EventKey {
	if event == nil {
		return event
	}
	switch event.Key() {
	case tcell.KeyEnter:
		v.logger.Debug().Msg("Enter pressed")
		v.Layout.Container.SetFocus(v.state.Elements.TableMain)
		v.logger.Debug().Msgf("Focus set to %s", v.state.Elements.TableMain.GetTitle())
	case tcell.KeyCtrlM:
		v.Watcher.Unsubscribe()
		v.Mounts()
	case tcell.KeyCtrlP:
		v.VPolicy()
		// Needs editing
		// case tcell.KeyCtrlJ:
		// 	v.SecretObject()
	}

	return event
}

I tried to modify the keyEnter to see what's happening exactly and noticed that the IDE is complaining, and then I saw it

duplicate case tcell.KeyCtrlM (constant 13 of type tcell.Key) in expression switch (see details)compiler[DuplicateCase](https://pkg.go.dev/golang.org/x/tools/internal/typesinternal#DuplicateCase)
inputs.go(40, 7): duplicate case tcell.KeyCtrlM (constant 13 of type tcell.Key) in expression switch
inputs.go(36, 7): previous case (this error)

Does this mean there is a bug with what id each key is mapped to?

Does this mean there is a bug with what id each key is mapped to?

Not really a bug. Some key combos are overlapping.
(e.g. try CTRL+m in the terminal -> Same as if you'd press ENTER😉)

See
https://github.com/gdamore/tcell/blob/8a50441ee1fd29b18a4a7d51e98423a17ec8ef4c/key.go#L384
https://unix.stackexchange.com/questions/533759/why-are-ctrl-m-and-return-keys-the-same-r-char

If you want to "reserve" a key for your own purpose, you must assign "nil" to the event after you have processed your code, like for example

func (v *View) InputMainCommands(event *tcell.EventKey) *tcell.EventKey {
  switch event.Key() {
    case tcell.KeyEnter:
      // do your actions for the ENTER key
      event = nil
    } // END case
    // …
  } // END switch
  return event
} // END InputMainCommands

This way your KeyHandler acts like a filter and disables the default functionality, like for example CTRL-C exits the program. If you want to use the Key-Combination CTRL-C for something else like Copy you need to filter this key-event from the event loop.
It is possible to stack Key-Handlers:
For example you have an InputField in a Form in an Application.
When the InputField has the focus, for every keystroke this happens:

  1. The custom event-handler for the InputField is called.
  2. When the returned event is not nil, the default event-handler InputField is called.
  3. When the returned event is not nil, the custom event-handler for the Form is called.
  4. When the returned event is not nil, the default event-handler for the Form is called.
  5. When the returned event is not nil, the custom event-handler for the Application is called.
  6. When the returned event is not nil, the default event-handler for the Application is called.

Sometimes you can shoot yourself in the foot due to this. I had assigned a functionality to the Plus and the Minus keys in the custom event-handler for my Application and discovered that i wasn't able to enter the plus or minus sign into an InputField anymore.