diff --git a/lib/program.js b/lib/program.js index e2bd09a..d7c6d9b 100644 --- a/lib/program.js +++ b/lib/program.js @@ -445,6 +445,8 @@ Program.prototype._bindMouse = function(s, buf) { , y = parts[1].charCodeAt(2) , mod; + this.emit('mouse-debug', s, buf); + key.name = 'mouse'; key.type = 'X10'; @@ -468,20 +470,32 @@ Program.prototype._bindMouse = function(s, buf) { key.action = b & 1 ? 'wheeldown' : 'wheelup'; key.button = 'middle'; } else if (b === 3) { - // Could also be a movement. + // NOTE: x10 and urxvt have no way + // of telling which button mouseup used. key.action = 'mouseup'; key.button = 'unknown'; } else { key.action = 'mousedown'; + var button = b & 3; key.button = - b === 0 ? 'left' - : b === 1 ? 'middle' - : b === 2 ? 'right' + button === 0 ? 'left' + : button === 1 ? 'middle' + : button === 2 ? 'right' : 'unknown'; } // Probably a movement. - if (key.action === 'mousedown' && key.button === 'unknown') { + // The *newer* VTE gets mouse movements comepletely wrong. + // This presents a problem: older versions of VTE that get it right might + // be confused by the second conditional in the if statement. + // NOTE: Possibly just switch back to the if statement below. + // none, shift, ctrl, alt + // gnome: 32, 36, 48, 40 + // xterm: 35, _, 51, _ + // urxvt: 35, _, _, _ + // if (key.action === 'mousedown' && key.button === 'unknown') { + if (b === 35 || b === 39 || b === 51 || b === 43 + || (this.isVTE && (b === 32 || b === 36 || b === 48 || b === 40))) { delete key.button; key.action = 'mousemove'; } @@ -499,6 +513,8 @@ Program.prototype._bindMouse = function(s, buf) { , x = +parts[1] , y = +parts[2]; + this.emit('mouse-debug', s, buf); + key.name = 'mouse'; key.type = 'urxvt'; @@ -512,25 +528,42 @@ Program.prototype._bindMouse = function(s, buf) { key.meta = !!((mod >> 1) & 1); key.ctrl = !!((mod >> 2) & 1); + // XXX Bug in urxvt after wheelup/down + if (b === 128 || b === 129) { + b = 67; + } + + b -= 32; + if ((b >> 6) & 1) { key.action = b & 1 ? 'wheeldown' : 'wheelup'; key.button = 'middle'; - // } else if (b === 3) { - // // Could also be a movement. - // key.action = 'mouseup'; - // key.button = 'unknown'; + } else if (b === 3) { + // NOTE: x10 and urxvt have no way + // of telling which button mouseup used. + key.action = 'mouseup'; + key.button = 'unknown'; } else { - // XXX Normally here: key.action = 'mousedown'; + var button = b & 3; key.button = - b === 0 ? 'left' - : b === 1 ? 'middle' - : b === 2 ? 'right' + button === 0 ? 'left' + : button === 1 ? 'middle' + : button === 2 ? 'right' : 'unknown'; } // Probably a movement. - if (key.action === 'mousedown' && key.button === 'unknown') { + // The *newer* VTE gets mouse movements comepletely wrong. + // This presents a problem: older versions of VTE that get it right might + // be confused by the second conditional in the if statement. + // NOTE: Possibly just switch back to the if statement below. + // none, shift, ctrl, alt + // urxvt: 35, _, _, _ + // gnome: 32, 36, 48, 40 + // if (key.action === 'mousedown' && key.button === 'unknown') { + if (b === 35 || b === 39 || b === 51 || b === 43 + || (this.isVTE && (b === 32 || b === 36 || b === 48 || b === 40))) { delete key.button; key.action = 'mousemove'; } @@ -549,6 +582,8 @@ Program.prototype._bindMouse = function(s, buf) { , x = +parts[1] , y = +parts[2]; + this.emit('mouse-debug', s, buf); + key.name = 'mouse'; key.type = 'sgr'; @@ -565,24 +600,29 @@ Program.prototype._bindMouse = function(s, buf) { if ((b >> 6) & 1) { key.action = b & 1 ? 'wheeldown' : 'wheelup'; key.button = 'middle'; - // } else if (b === 3) { - // // Could also be a movement. - // key.action = 'mouseup'; - // key.button = 'unknown'; } else { - // XXX Normally here: key.action = down ? 'mousedown' : 'mouseup'; + var button = b & 3; key.button = - b === 0 ? 'left' - : b === 1 ? 'middle' - : b === 2 ? 'right' + button === 0 ? 'left' + : button === 1 ? 'middle' + : button === 2 ? 'right' : 'unknown'; } // Probably a movement. - if (key.action === 'mousedown' && key.button === 'unknown') { + // The *newer* VTE gets mouse movements comepletely wrong. + // This presents a problem: older versions of VTE that get it right might + // be confused by the second conditional in the if statement. + // NOTE: Possibly just switch back to the if statement below. + // none, shift, ctrl, alt + // xterm: 35, _, 51, _ + // gnome: 32, 36, 48, 40 + // if (key.action === 'mousedown' && key.button === 'unknown') { + if (b === 35 || b === 39 || b === 51 || b === 43 + || (this.isVTE && (b === 32 || b === 36 || b === 48 || b === 40))) { delete key.button; key.action = 'mousemove'; } @@ -603,6 +643,8 @@ Program.prototype._bindMouse = function(s, buf) { , y = +parts[2] , page = +parts[3]; + this.emit('mouse-debug', s, buf); + key.name = 'mouse'; key.type = 'dec'; @@ -634,6 +676,8 @@ Program.prototype._bindMouse = function(s, buf) { , x = +parts[2] , y = +parts[3]; + this.emit('mouse-debug', s, buf); + key.name = 'mouse'; key.type = 'vt300'; @@ -2868,12 +2912,12 @@ Program.prototype.enableMouse = function() { }, true); } - // libvte is broken, older versions do not support the - // X10 UTF extension, later versions do support SGR however + // libvte is broken. Older versions do not support the + // X10 UTF extension. However, later versions do support + // SGR/URXVT. if (this.isVTE) { return this.setMouse({ - // XXX May be better to use URXVT mouse here since - // it was originally better implemented? + // NOTE: Could also use urxvtMouse here. sgrMouse: true, allMotion: true }, true); diff --git a/test/program-mouse.js b/test/program-mouse.js index be42f3f..f73c1a6 100755 --- a/test/program-mouse.js +++ b/test/program-mouse.js @@ -39,10 +39,16 @@ program.on('keypress', function(ch, data) { program.write(util.inspect(data)); }); -program.on('mouse-debug', function(data) { - program.cup(20, 0); - data = Array.prototype.slice.call(data); - program.write(util.inspect(data)); +program.on('mouse-debug', function(s, buf) { + if (s) { + program.cup(10, 0); + program.write(util.inspect(s)); + } + if (buf) { + program.cup(11, 0); + buf = Array.prototype.slice.call(buf); + program.write(util.inspect(buf)); + } }); // program.getCursor(function(err, data) {