kopia lustrzana https://github.com/abourget/shuttle-go
Improve slowjog.
rodzic
29ec7d3fd7
commit
cb792838ef
37
README.md
37
README.md
|
@ -1,17 +1,25 @@
|
|||
Linux driver for Contour Design Shuttle Pro V2
|
||||
==============================================
|
||||
|
||||
My goal is to set it up for the Lightworks Non-Linear Editor.
|
||||
The goal of this project is to use the Shuttle Pro V2 with the
|
||||
Lightworks Non-Linear Video Editor. I'm using v14.
|
||||
|
||||
This program supports having modifiers for your Shuttle Pro V2
|
||||
buttons. Avoid Lightworks key bindings with modifiers however. Capital
|
||||
This program supports having **modifiers** for your Shuttle Pro V2
|
||||
buttons. So you can multiple the functionality of your buttons. For
|
||||
example, you can have different bindings for
|
||||
<kbd>B1</kbd>+<kbd>F1</kbd> and <kbd>F1</kbd>.
|
||||
|
||||
Avoid Lightworks key bindings with modifiers however. Capital
|
||||
letters are great as they cannot be combined, and are more direct and
|
||||
they are less likely to conflict with your other bindings and
|
||||
Lightworks recognizes them. All key names used here will work:
|
||||
http://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm
|
||||
Lightworks recognizes them.
|
||||
|
||||
Right now, you need to install `xdotool` from your package
|
||||
repositories. Eventually, we'll get rid of this dependency.
|
||||
The key names to use in the X11 bindings are found here:
|
||||
https://www.cl.cam.ac.uk/~mgk25/ucs/keysymdef.h or you can view them
|
||||
locally in `/usr/include/X11/keysymdef.h` (stripped of the `XK_`
|
||||
prefix).
|
||||
|
||||
You need to install the `xdotool` package before using this program.
|
||||
|
||||
Buttons layout on the Contour Design Shuttle Pro v2:
|
||||
|
||||
|
@ -31,7 +39,18 @@ Buttons layout on the Contour Design Shuttle Pro v2:
|
|||
B2 B3
|
||||
B1 B4
|
||||
|
||||
You can also use `SlowJogL` and `SlowJogR`, to use Frame nudge for example.
|
||||
|
||||
## Slow Jog
|
||||
|
||||
In addition to `JogL` and `JogR`, you can define bindings for
|
||||
`SlowJogL` and `SlowJogR`. For example, you can use a slow jog use to
|
||||
nudge by one frame at a time.
|
||||
|
||||
If you wish to not use slow jog, set the `slow_jog` key to `0` in the
|
||||
configuration for this app. Otherwise, `slow_jog` represents the
|
||||
minimum number of milliseconds between two events to be considered
|
||||
slow. It defaults to 200 ms.
|
||||
|
||||
|
||||
## Disable the native mouse pointer
|
||||
|
||||
|
@ -67,3 +86,5 @@ TODO
|
|||
|
||||
* Check udev, DISPLAY=:0.0 to start ?
|
||||
* Retry ? Check the error message going out.
|
||||
|
||||
* Have a default SlowJog configuration.
|
||||
|
|
|
@ -18,7 +18,7 @@ type Config struct {
|
|||
type AppConfig struct {
|
||||
Name string `json:"name"`
|
||||
MatchWindowTitles []string `json:"match_window_titles"`
|
||||
SlowJog int `json:"slow_jog"` // Time in millisecond to use slow jog
|
||||
SlowJog *int `json:"slow_jog"` // Time in millisecond to use slow jog
|
||||
windowTitleRegexps []*regexp.Regexp
|
||||
Bindings map[string]string `json:"bindings"`
|
||||
bindings []*deviceBinding
|
||||
|
|
78
mapper.go
78
mapper.go
|
@ -118,7 +118,12 @@ func slowJogTiming() time.Duration {
|
|||
if conf == nil {
|
||||
return 200 * time.Millisecond
|
||||
}
|
||||
return time.Duration(conf.SlowJog) * time.Millisecond
|
||||
slowJog := 200
|
||||
if conf.SlowJog != nil {
|
||||
slowJog = *conf.SlowJog
|
||||
}
|
||||
|
||||
return time.Duration(slowJog) * time.Millisecond
|
||||
}
|
||||
|
||||
func (m *Mapper) EmitOther(key string) error {
|
||||
|
@ -158,54 +163,61 @@ func (m *Mapper) EmitKeys(modifiers map[int]bool, keyDown int) error {
|
|||
}
|
||||
|
||||
func (m *Mapper) executeBinding(binding *deviceBinding) error {
|
||||
holdButtons := binding.holdButtons
|
||||
pressButton := binding.pressButton
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
//xtest.FakeInputChecked(m.watcher.conn, m.watcher.rootWin)
|
||||
// cookie := xtest.FakeInputChecked(m.watcher.conn, 2, 0x7b00, 0, m.watcher.lastWindowID, 0, 0, 0x00)
|
||||
// if err := cookie.Check(); err != nil {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// cookie = xtest.FakeInputChecked(m.watcher.conn, 3, 0x7b00, 0, m.watcher.lastWindowID, 0, 0, 0x00)
|
||||
// return cookie.Check()
|
||||
|
||||
fmt.Println("xdotool key --clearmodifiers", binding.original)
|
||||
return exec.Command("xdotool", "key", "--clearmodifiers", binding.original).Run()
|
||||
|
||||
fmt.Println("Executing bindings:", holdButtons, pressButton)
|
||||
// holdButtons := binding.holdButtons
|
||||
// pressButton := binding.pressButton
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
// fmt.Println("Executing bindings:", holdButtons, pressButton)
|
||||
|
||||
for _, button := range holdButtons {
|
||||
fmt.Println("Key down", button)
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
// time.Sleep(10 * time.Millisecond)
|
||||
|
||||
if err := m.virtualKeyboard.KeyDown(keyboardKeysUpper[button]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// for _, button := range holdButtons {
|
||||
// fmt.Println("Key down", button)
|
||||
// time.Sleep(10 * time.Millisecond)
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
// if err := m.virtualKeyboard.KeyDown(keyboardKeysUpper[button]); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
|
||||
fmt.Println("Key press", pressButton)
|
||||
if err := m.virtualKeyboard.KeyDown(keyboardKeysUpper[pressButton]); err != nil {
|
||||
return err
|
||||
}
|
||||
// time.Sleep(10 * time.Millisecond)
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
// fmt.Println("Key press", pressButton)
|
||||
// if err := m.virtualKeyboard.KeyDown(keyboardKeysUpper[pressButton]); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
if err := m.virtualKeyboard.KeyUp(keyboardKeysUpper[pressButton]); err != nil {
|
||||
return err
|
||||
}
|
||||
// time.Sleep(10 * time.Millisecond)
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
// if err := m.virtualKeyboard.KeyUp(keyboardKeysUpper[pressButton]); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
for _, button := range holdButtons {
|
||||
fmt.Println("Key up", button)
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
if err := m.virtualKeyboard.KeyUp(keyboardKeysUpper[button]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// time.Sleep(10 * time.Millisecond)
|
||||
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
// for _, button := range holdButtons {
|
||||
// fmt.Println("Key up", button)
|
||||
// time.Sleep(10 * time.Millisecond)
|
||||
// if err := m.virtualKeyboard.KeyUp(keyboardKeysUpper[button]); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
|
||||
return nil
|
||||
// time.Sleep(50 * time.Millisecond)
|
||||
|
||||
// return nil
|
||||
}
|
||||
|
||||
func jogVal(evs []evdev.InputEvent) int {
|
||||
|
|
8
watch.go
8
watch.go
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/BurntSushi/xgb"
|
||||
"github.com/BurntSushi/xgb/xproto"
|
||||
"github.com/BurntSushi/xgb/xtest"
|
||||
)
|
||||
|
||||
type watcher struct {
|
||||
|
@ -14,6 +15,7 @@ type watcher struct {
|
|||
root xproto.Window
|
||||
activeAtom, nameAtom xproto.Atom
|
||||
prevWindowName string
|
||||
lastWindowID xproto.Window
|
||||
}
|
||||
|
||||
func NewWindowWatcher() *watcher {
|
||||
|
@ -29,6 +31,10 @@ func (w *watcher) Setup() error {
|
|||
// Get the window id of the root window.
|
||||
setup := xproto.Setup(X)
|
||||
|
||||
if err := xtest.Init(X); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.conn = X
|
||||
w.root = setup.DefaultScreen(X).Root
|
||||
|
||||
|
@ -76,6 +82,8 @@ func (w *watcher) watch() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
w.lastWindowID = windowID
|
||||
|
||||
windowName := string(reply.Value)
|
||||
if w.prevWindowName != windowName {
|
||||
w.prevWindowName = windowName
|
||||
|
|
Ładowanie…
Reference in New Issue