@ -22,7 +22,7 @@ type ttyShareClient struct {
wsConn * websocket . Conn
wsConn * websocket . Conn
detachKeys string
detachKeys string
wcChan chan os . Signal
wcChan chan os . Signal
writeFlag uint32 // used with atomic
ioFlagAtomic uint32 // used with atomic
winSizes struct {
winSizes struct {
thisW uint16
thisW uint16
thisH uint16
thisH uint16
@ -38,7 +38,7 @@ func newTtyShareClient(url string, detachKeys string) *ttyShareClient {
wsConn : nil ,
wsConn : nil ,
detachKeys : detachKeys ,
detachKeys : detachKeys ,
wcChan : make ( chan os . Signal , 1 ) ,
wcChan : make ( chan os . Signal , 1 ) ,
writeFlag: 1 ,
ioFlagAtomic: 1 ,
}
}
}
}
@ -48,6 +48,7 @@ func clearScreen() {
type keyListener struct {
type keyListener struct {
wrappedReader io . Reader
wrappedReader io . Reader
ioFlagAtomicP * uint32
}
}
func ( kl * keyListener ) Read ( data [ ] byte ) ( n int , err error ) {
func ( kl * keyListener ) Read ( data [ ] byte ) ( n int , err error ) {
@ -55,6 +56,13 @@ func (kl *keyListener) Read(data []byte) (n int, err error) {
if _ , ok := err . ( term . EscapeError ) ; ok {
if _ , ok := err . ( term . EscapeError ) ; ok {
log . Debug ( "Escape code detected." )
log . Debug ( "Escape code detected." )
}
}
// If we are not supposed to do any IO, then return 0 bytes read. This happens the local
// window is smaller than the remote one
if atomic . LoadUint32 ( kl . ioFlagAtomicP ) == 0 {
return 0 , err
}
return
return
}
}
@ -62,16 +70,16 @@ func (c *ttyShareClient) updateAndDecideStdoutMuted() {
log . Infof ( "This window: %dx%d. Remote window: %dx%d" , c . winSizes . thisW , c . winSizes . thisH , c . winSizes . remoteW , c . winSizes . remoteH )
log . Infof ( "This window: %dx%d. Remote window: %dx%d" , c . winSizes . thisW , c . winSizes . thisH , c . winSizes . remoteW , c . winSizes . remoteH )
if c . winSizes . thisH < c . winSizes . remoteH || c . winSizes . thisW < c . winSizes . remoteW {
if c . winSizes . thisH < c . winSizes . remoteH || c . winSizes . thisW < c . winSizes . remoteW {
atomic . StoreUint32 ( & c . writeFlag , 0 )
atomic . StoreUint32 ( & c . ioFlagAtomic , 0 )
clearScreen ( )
clearScreen ( )
messageFormat := "\n\rYour window is smaller than the remote window. Please resize .\n\r\tRemote window: %dx%d \n\r\tYour window: %dx%d \n\r"
messageFormat := "\n\rYour window is smaller than the remote window. Please resize or press <C-o C-c> to detach .\n\r\tRemote window: %dx%d \n\r\tYour window: %dx%d \n\r"
fmt . Printf ( messageFormat , c . winSizes . remoteW , c . winSizes . remoteH , c . winSizes . thisW , c . winSizes . thisH )
fmt . Printf ( messageFormat , c . winSizes . remoteW , c . winSizes . remoteH , c . winSizes . thisW , c . winSizes . thisH )
} else {
} else {
if atomic . LoadUint32 ( & c . writeFlag ) == 0 { // clear the screen when changing back to "write"
if atomic . LoadUint32 ( & c . ioFlagAtomic ) == 0 { // clear the screen when changing back to "write"
// TODO: notify the remote side to "refresh" the content.
// TODO: notify the remote side to "refresh" the content.
clearScreen ( )
clearScreen ( )
}
}
atomic . StoreUint32 ( & c . writeFlag , 1 )
atomic . StoreUint32 ( & c . ioFlagAtomic , 1 )
}
}
}
}
@ -148,7 +156,7 @@ func (c *ttyShareClient) Run() (err error) {
err = protoWS . ReadAndHandle (
err = protoWS . ReadAndHandle (
// onWrite
// onWrite
func ( data [ ] byte ) {
func ( data [ ] byte ) {
if atomic . LoadUint32 ( & c . writeFlag ) != 0 {
if atomic . LoadUint32 ( & c . ioFlagAtomic ) != 0 {
os . Stdout . Write ( data )
os . Stdout . Write ( data )
}
}
} ,
} ,
@ -176,6 +184,7 @@ func (c *ttyShareClient) Run() (err error) {
writeLoop := func ( ) {
writeLoop := func ( ) {
kl := & keyListener {
kl := & keyListener {
wrappedReader : term . NewEscapeProxy ( os . Stdin , detachBytes ) ,
wrappedReader : term . NewEscapeProxy ( os . Stdin , detachBytes ) ,
ioFlagAtomicP : & c . ioFlagAtomic ,
}
}
_ , err := io . Copy ( protoWS , kl )
_ , err := io . Copy ( protoWS , kl )