mirror of
https://github.com/paradoxxxzero/butterfly.git
synced 2026-05-26 07:08:08 +00:00
Fix cursor blur. Fix scrollLock on focus/blur. Rework binaries.
This commit is contained in:
@@ -22,6 +22,7 @@ import tornado.ioloop
|
|||||||
import tornado.httpserver
|
import tornado.httpserver
|
||||||
import tornado_systemd
|
import tornado_systemd
|
||||||
import logging
|
import logging
|
||||||
|
import webbrowser
|
||||||
import uuid
|
import uuid
|
||||||
import ssl
|
import ssl
|
||||||
import getpass
|
import getpass
|
||||||
@@ -39,6 +40,8 @@ tornado.options.define("unminified", default=False,
|
|||||||
|
|
||||||
tornado.options.define("host", default='localhost', help="Server host")
|
tornado.options.define("host", default='localhost', help="Server host")
|
||||||
tornado.options.define("port", default=57575, type=int, help="Server port")
|
tornado.options.define("port", default=57575, type=int, help="Server port")
|
||||||
|
tornado.options.define("one_shot", default=False,
|
||||||
|
help="Run a one-shot instance. Quit at term close")
|
||||||
tornado.options.define("shell", help="Shell to execute at login")
|
tornado.options.define("shell", help="Shell to execute at login")
|
||||||
tornado.options.define("motd", default='motd', help="Path to the motd file.")
|
tornado.options.define("motd", default='motd', help="Path to the motd file.")
|
||||||
tornado.options.define("cmd",
|
tornado.options.define("cmd",
|
||||||
@@ -66,7 +69,9 @@ if os.getuid() == 0:
|
|||||||
ev = os.getenv('XDG_CONFIG_DIRS', '/etc')
|
ev = os.getenv('XDG_CONFIG_DIRS', '/etc')
|
||||||
else:
|
else:
|
||||||
ev = os.getenv(
|
ev = os.getenv(
|
||||||
'XDG_CONFIG_HOME', os.path.join(os.getenv('HOME'), '.config'))
|
'XDG_CONFIG_HOME', os.path.join(
|
||||||
|
os.getenv('HOME', os.path.expanduser('~')),
|
||||||
|
'.config'))
|
||||||
|
|
||||||
butterfly_dir = os.path.join(ev, 'butterfly')
|
butterfly_dir = os.path.join(ev, 'butterfly')
|
||||||
conf_file = os.path.join(butterfly_dir, 'butterfly.conf')
|
conf_file = os.path.join(butterfly_dir, 'butterfly.conf')
|
||||||
@@ -115,6 +120,7 @@ log = logging.getLogger('butterfly')
|
|||||||
host = options.host
|
host = options.host
|
||||||
port = options.port
|
port = options.port
|
||||||
|
|
||||||
|
|
||||||
if not os.path.exists(options.ssl_dir):
|
if not os.path.exists(options.ssl_dir):
|
||||||
os.makedirs(options.ssl_dir)
|
os.makedirs(options.ssl_dir)
|
||||||
|
|
||||||
@@ -301,7 +307,13 @@ log.info('Starting loop')
|
|||||||
|
|
||||||
ioloop = tornado.ioloop.IOLoop.instance()
|
ioloop = tornado.ioloop.IOLoop.instance()
|
||||||
|
|
||||||
|
if port == 0:
|
||||||
|
port = list(http_server._sockets.values())[0].getsockname()[1]
|
||||||
|
|
||||||
url = "http%s://%s:%d/" % (
|
url = "http%s://%s:%d/" % (
|
||||||
"s" if not options.unsecure else "", host, port)
|
"s" if not options.unsecure else "", host, port)
|
||||||
log.warn('Butterfly is ready, open your browser to: %s' % url)
|
|
||||||
|
if not options.one_shot or not webbrowser.open(url):
|
||||||
|
log.warn('Butterfly is ready, open your browser to: %s' % url)
|
||||||
|
|
||||||
ioloop.start()
|
ioloop.start()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
__version__ = '2.0.12'
|
__version__ = '2.0.13'
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
rows, cols = map(int, os.popen('stty size', 'r').read().split())
|
|
||||||
|
|
||||||
for r in range(rows):
|
|
||||||
for c in range(cols):
|
|
||||||
sys.stdout.write('\x1b[48;2;%d;%d;%dm ' % (255 - r, 255 - c, 255))
|
|
||||||
0
butterfly/bin/bcal → butterfly/bin/calendar.py
Executable file → Normal file
0
butterfly/bin/bcal → butterfly/bin/calendar.py
Executable file → Normal file
0
butterfly/bin/bcat → butterfly/bin/cat.py
Executable file → Normal file
0
butterfly/bin/bcat → butterfly/bin/cat.py
Executable file → Normal file
145
butterfly/bin/colors.py
Normal file
145
butterfly/bin/colors.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Butterfly terminal color tester.')
|
||||||
|
parser.add_argument(
|
||||||
|
'--colors',
|
||||||
|
default='16',
|
||||||
|
choices=['8', '16', '256', '16M'],
|
||||||
|
help='Set the color mode to test')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
if args.colors in ['8', '16']:
|
||||||
|
print('Background\n')
|
||||||
|
for l in range(3):
|
||||||
|
sys.stdout.write(' ')
|
||||||
|
for i in range(8):
|
||||||
|
sys.stdout.write('\x1b[%dm \x1b[m ' % (40 + i))
|
||||||
|
sys.stdout.write('\n')
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
if args.colors == '16':
|
||||||
|
print()
|
||||||
|
for l in range(3):
|
||||||
|
sys.stdout.write(' ')
|
||||||
|
for i in range(8):
|
||||||
|
sys.stdout.write('\x1b[%dm \x1b[m ' % (100 + i))
|
||||||
|
sys.stdout.write('\n')
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
print('\nForeground\n')
|
||||||
|
|
||||||
|
for l in range(3):
|
||||||
|
sys.stdout.write(' ')
|
||||||
|
for i in range(8):
|
||||||
|
sys.stdout.write('\x1b[%dm ░▒▓██\x1b[m ' % (30 + i))
|
||||||
|
sys.stdout.write('\n')
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
if args.colors == '16':
|
||||||
|
print()
|
||||||
|
for l in range(3):
|
||||||
|
sys.stdout.write(' ')
|
||||||
|
for i in range(8):
|
||||||
|
sys.stdout.write('\x1b[1;%dm ░▒▓██\x1b[m ' % (30 + i))
|
||||||
|
sys.stdout.write('\n')
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
if args.colors == '256':
|
||||||
|
for i in range(16):
|
||||||
|
sys.stdout.write('\x1b[48;5;%dm \x1b[m' % (i))
|
||||||
|
print()
|
||||||
|
for i in range(16):
|
||||||
|
sys.stdout.write('\x1b[48;5;%dm %03d\x1b[m' % (i, i))
|
||||||
|
print()
|
||||||
|
|
||||||
|
for j in range(6):
|
||||||
|
for i in range(36):
|
||||||
|
sys.stdout.write('\x1b[48;5;%dm \x1b[m' % (16 + j * 36 + i))
|
||||||
|
print()
|
||||||
|
for i in range(36):
|
||||||
|
sys.stdout.write('\x1b[48;5;%dm %03d\x1b[m' % (
|
||||||
|
16 + j * 36 + i, 16 + j * 36 + i))
|
||||||
|
print()
|
||||||
|
for i in range(24):
|
||||||
|
sys.stdout.write('\x1b[48;5;%dm \x1b[m' % (232 + i))
|
||||||
|
print()
|
||||||
|
for i in range(24):
|
||||||
|
sys.stdout.write('\x1b[48;5;%dm %03d\x1b[m' % (232 + i, 232 + i))
|
||||||
|
|
||||||
|
if args.colors == '16M':
|
||||||
|
b = 0
|
||||||
|
g = 0
|
||||||
|
for r in range(256):
|
||||||
|
if r == 128:
|
||||||
|
print()
|
||||||
|
sys.stdout.write('\x1b[48;2;%d;%d;%dm \x1b[m' % (r, g, b))
|
||||||
|
print()
|
||||||
|
|
||||||
|
r = 255
|
||||||
|
b = 0
|
||||||
|
for g in range(256):
|
||||||
|
if g == 128:
|
||||||
|
print()
|
||||||
|
sys.stdout.write('\x1b[48;2;%d;%d;%dm \x1b[m' % (r, g, b))
|
||||||
|
print()
|
||||||
|
|
||||||
|
r = 255
|
||||||
|
g = 255
|
||||||
|
for b in range(256):
|
||||||
|
if b == 128:
|
||||||
|
print()
|
||||||
|
sys.stdout.write('\x1b[48;2;%d;%d;%dm \x1b[m' % (r, g, b))
|
||||||
|
print()
|
||||||
|
|
||||||
|
r = 255
|
||||||
|
b = 255
|
||||||
|
for g in reversed(range(256)):
|
||||||
|
if g == 127:
|
||||||
|
print()
|
||||||
|
sys.stdout.write('\x1b[48;2;%d;%d;%dm \x1b[m' % (r, g, b))
|
||||||
|
print()
|
||||||
|
|
||||||
|
g = 0
|
||||||
|
b = 255
|
||||||
|
for r in reversed(range(256)):
|
||||||
|
if r == 127:
|
||||||
|
print()
|
||||||
|
sys.stdout.write('\x1b[48;2;%d;%d;%dm \x1b[m' % (r, g, b))
|
||||||
|
print()
|
||||||
|
|
||||||
|
r = 0
|
||||||
|
g = 0
|
||||||
|
for b in reversed(range(256)):
|
||||||
|
if b == 127:
|
||||||
|
print()
|
||||||
|
sys.stdout.write('\x1b[48;2;%d;%d;%dm \x1b[m' % (r, g, b))
|
||||||
|
print()
|
||||||
|
|
||||||
|
r = 0
|
||||||
|
b = 0
|
||||||
|
for g in range(256):
|
||||||
|
if g == 128:
|
||||||
|
print()
|
||||||
|
sys.stdout.write('\x1b[48;2;%d;%d;%dm \x1b[m' % (r, g, b))
|
||||||
|
print()
|
||||||
|
|
||||||
|
r = 0
|
||||||
|
g = 255
|
||||||
|
for b in range(256):
|
||||||
|
if b == 128:
|
||||||
|
print()
|
||||||
|
sys.stdout.write('\x1b[48;2;%d;%d;%dm \x1b[m' % (r, g, b))
|
||||||
|
print()
|
||||||
|
|
||||||
|
b = 255
|
||||||
|
g = 255
|
||||||
|
for r in range(256):
|
||||||
|
if r == 128:
|
||||||
|
print()
|
||||||
|
sys.stdout.write('\x1b[48;2;%d;%d;%dm \x1b[m' % (r, g, b))
|
||||||
|
print()
|
||||||
27
butterfly/bin/butterfly_help → butterfly/bin/help.py
Executable file → Normal file
27
butterfly/bin/butterfly_help → butterfly/bin/help.py
Executable file → Normal file
@@ -6,12 +6,14 @@ import base64
|
|||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
print(ansi_colors.white + "Welcome to the butterfly help." + ansi_colors.reset)
|
print(ansi_colors.white + "Welcome to the butterfly help." + ansi_colors.reset)
|
||||||
with image('image/png'):
|
path = os.getenv('BUTTERFLY_PATH')
|
||||||
with open(
|
if path:
|
||||||
os.path.join(
|
path = os.path.join(path, '../static/images/favicon.png')
|
||||||
os.path.abspath(os.path.dirname(__file__)),
|
|
||||||
'../static/images/favicon.png'), 'rb') as i:
|
if path and os.path.exists(path):
|
||||||
print(base64.b64encode(i.read()).decode('ascii'))
|
with image('image/png'):
|
||||||
|
with open(path, 'rb') as i:
|
||||||
|
print(base64.b64encode(i.read()).decode('ascii'))
|
||||||
print("""
|
print("""
|
||||||
Butterfly is a xterm compliant terminal built with python and javascript.
|
Butterfly is a xterm compliant terminal built with python and javascript.
|
||||||
|
|
||||||
@@ -28,12 +30,13 @@ Butterfly is a xterm compliant terminal built with python and javascript.
|
|||||||
|
|
||||||
|
|
||||||
{title}Butterfly programs:{reset}
|
{title}Butterfly programs:{reset}
|
||||||
{strong}bcat : {reset}A wrapper around cat allowing to display images as <img> instead of binary.
|
{strong}b : {reset}Alias for {strong}butterfly{reset} executable. Takes a comand in parameter or launch a butterfly server for one shot use (if outside butterfly).
|
||||||
{strong}bopen : {reset}Open a new terminal at specified location.
|
{strong}b cat : {reset}A wrapper around cat allowing to display images as <img> instead of binary.
|
||||||
{strong}bsession : {reset}Open or rattach a butterfly session. Multiplexing is supported.
|
{strong}b open : {reset}Open a new terminal at specified location.
|
||||||
{strong}b16M : {reset}Test the 16M colors support in terminal.
|
{strong}b session : {reset}Open or rattach a butterfly session. Multiplexing is supported.
|
||||||
{strong}bhr : {reset}Put a html hr. This is a test for html output.
|
{strong}b colors : {reset}Test the terminal colors (16, 256 and 16777216 colors)
|
||||||
{strong}bcal : {reset}Display current month using html. This is also a test for html output.
|
{strong}b hr : {reset}Put a html hr. This is a test for html output.
|
||||||
|
{strong}b calendar : {reset}Display current month using html. This is also a test for html output.
|
||||||
|
|
||||||
|
|
||||||
{title}Styling butterfly:{reset}
|
{title}Styling butterfly:{reset}
|
||||||
0
butterfly/bin/bhr → butterfly/bin/hr.py
Executable file → Normal file
0
butterfly/bin/bhr → butterfly/bin/hr.py
Executable file → Normal file
0
butterfly/bin/bhtml → butterfly/bin/html.py
Executable file → Normal file
0
butterfly/bin/bhtml → butterfly/bin/html.py
Executable file → Normal file
0
butterfly/bin/bopen → butterfly/bin/open.py
Executable file → Normal file
0
butterfly/bin/bopen → butterfly/bin/open.py
Executable file → Normal file
0
butterfly/bin/bsession → butterfly/bin/session.py
Executable file → Normal file
0
butterfly/bin/bsession → butterfly/bin/session.py
Executable file → Normal file
0
butterfly/bin/btest → butterfly/bin/test.py
Executable file → Normal file
0
butterfly/bin/btest → butterfly/bin/test.py
Executable file → Normal file
@@ -288,10 +288,13 @@ class TermWebSocket(Route, tornado.websocket.WebSocketHandler):
|
|||||||
else:
|
else:
|
||||||
self.log.error(
|
self.log.error(
|
||||||
'Socket with neither session nor terminal %r' % self)
|
'Socket with neither session nor terminal %r' % self)
|
||||||
if (self.application.systemd and
|
opts = tornado.options.options
|
||||||
not len(TermWebSocket.sockets) and
|
if opts.one_shot or (
|
||||||
not sum([len(sessions)
|
self.application.systemd and
|
||||||
for user, sessions in TermWebSocket.terminals.items()])):
|
not len(TermWebSocket.sockets) and
|
||||||
|
not sum([
|
||||||
|
len(sessions)
|
||||||
|
for user, sessions in TermWebSocket.terminals.items()])):
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,4 +29,4 @@ $weights: (ExtraLight 100) (Light 300) (Regular 400) (Medium 500) (Semibold 600)
|
|||||||
body
|
body
|
||||||
font-family: $font-family
|
font-family: $font-family
|
||||||
font-size: $font-size
|
font-size: $font-size
|
||||||
line-height: 1.2
|
line-height: $font-line-height
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
html, body
|
html, body
|
||||||
margin: 0
|
margin: 0
|
||||||
padding: 0
|
padding: 0
|
||||||
line-height: 1.2
|
|
||||||
background-color: $bg
|
background-color: $bg
|
||||||
color: $fg
|
color: $fg
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,8 @@
|
|||||||
color: $bg
|
color: $bg
|
||||||
background-color: $fg
|
background-color: $fg
|
||||||
|
|
||||||
.blur .cursor.reverse-video
|
.blur .cursor
|
||||||
|
border: 1px solid $fg
|
||||||
background: none
|
background: none
|
||||||
|
|
||||||
.nbsp
|
.nbsp
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
/** Font
|
/** Font
|
||||||
$font-family: "SourceCodePro" !default
|
$font-family: "SourceCodePro" !default
|
||||||
$font-size: 1em !default
|
$font-size: 1em !default
|
||||||
|
$font-line-height: 1.2 !default
|
||||||
|
|
||||||
/** Colors */
|
/** Colors */
|
||||||
/* Foreground */
|
/* Foreground */
|
||||||
|
|||||||
2
butterfly/static/ext.min.js
vendored
2
butterfly/static/ext.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -2806,7 +2806,6 @@ body {
|
|||||||
html, body {
|
html, body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 1.2;
|
|
||||||
background-color: #110f13;
|
background-color: #110f13;
|
||||||
color: #f4ead5; }
|
color: #f4ead5; }
|
||||||
|
|
||||||
@@ -2923,7 +2922,8 @@ body {
|
|||||||
color: #110f13;
|
color: #110f13;
|
||||||
background-color: #f4ead5; }
|
background-color: #f4ead5; }
|
||||||
|
|
||||||
.blur .cursor.reverse-video {
|
.blur .cursor {
|
||||||
|
border: 1px solid #f4ead5;
|
||||||
background: none; }
|
background: none; }
|
||||||
|
|
||||||
.inline-html {
|
.inline-html {
|
||||||
|
|||||||
@@ -310,16 +310,23 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
Terminal.prototype.focus = function() {
|
Terminal.prototype.focus = function() {
|
||||||
|
var old_sl;
|
||||||
|
old_sl = this.scrollLock;
|
||||||
|
this.scrollLock = true;
|
||||||
if (this.sendFocus) {
|
if (this.sendFocus) {
|
||||||
this.send('\x1b[I');
|
this.send('\x1b[I');
|
||||||
}
|
}
|
||||||
this.showCursor();
|
this.showCursor();
|
||||||
this.body.classList.add('focus');
|
this.body.classList.add('focus');
|
||||||
this.body.classList.remove('blur');
|
this.body.classList.remove('blur');
|
||||||
return this.resize();
|
this.resize();
|
||||||
|
return this.scrollLock = old_sl;
|
||||||
};
|
};
|
||||||
|
|
||||||
Terminal.prototype.blur = function() {
|
Terminal.prototype.blur = function() {
|
||||||
|
var old_sl;
|
||||||
|
old_sl = this.scrollLock;
|
||||||
|
this.scrollLock = true;
|
||||||
this.cursorState = 1;
|
this.cursorState = 1;
|
||||||
this.screen[this.y + this.shift].dirty = true;
|
this.screen[this.y + this.shift].dirty = true;
|
||||||
this.refresh();
|
this.refresh();
|
||||||
@@ -327,7 +334,8 @@
|
|||||||
this.send('\x1b[O');
|
this.send('\x1b[O');
|
||||||
}
|
}
|
||||||
this.body.classList.add('blur');
|
this.body.classList.add('blur');
|
||||||
return this.body.classList.remove('focus');
|
this.body.classList.remove('focus');
|
||||||
|
return this.scrollLock = old_sl;
|
||||||
};
|
};
|
||||||
|
|
||||||
Terminal.prototype.initmouse = function() {
|
Terminal.prototype.initmouse = function() {
|
||||||
@@ -698,9 +706,7 @@
|
|||||||
}
|
}
|
||||||
this.children = Array.prototype.slice.call(lines, -this.rows);
|
this.children = Array.prototype.slice.call(lines, -this.rows);
|
||||||
}
|
}
|
||||||
if (!this.scrollLock) {
|
return this.nativeScrollTo();
|
||||||
return this.nativeScrollTo();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Terminal.prototype._cursorBlink = function() {
|
Terminal.prototype._cursorBlink = function() {
|
||||||
@@ -776,6 +782,9 @@
|
|||||||
if (scroll == null) {
|
if (scroll == null) {
|
||||||
scroll = 2000000000;
|
scroll = 2000000000;
|
||||||
}
|
}
|
||||||
|
if (this.scrollLock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return window.scrollTo(0, scroll);
|
return window.scrollTo(0, scroll);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
6
butterfly/static/main.min.js
vendored
6
butterfly/static/main.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -18,5 +18,5 @@
|
|||||||
{{ colors.white }} Y Y {{ colors.light_white }}From:{{ colors.white }}
|
{{ colors.white }} Y Y {{ colors.light_white }}From:{{ colors.white }}
|
||||||
! ! {{ colors.red if opts.unsecure else colors.green }}{{ butterfly.socket.remote_addr }}:{{ butterfly.socket.remote_port }}{{ colors.reset }}
|
! ! {{ colors.red if opts.unsecure else colors.green }}{{ butterfly.socket.remote_addr }}:{{ butterfly.socket.remote_port }}{{ colors.reset }}
|
||||||
|
|
||||||
For more information type: $ butterfly_help
|
For more information type: {{ colors.white }}$ {{ colors.green }}butterfly help
|
||||||
|
|
||||||
|
|||||||
@@ -159,8 +159,8 @@ class Terminal(object):
|
|||||||
env["LOCATION"] = "http%s://%s:%d/" % (
|
env["LOCATION"] = "http%s://%s:%d/" % (
|
||||||
"s" if not tornado.options.options.unsecure else "",
|
"s" if not tornado.options.options.unsecure else "",
|
||||||
tornado.options.options.host, tornado.options.options.port)
|
tornado.options.options.host, tornado.options.options.port)
|
||||||
env["PATH"] = '%s:%s' % (os.path.abspath(os.path.join(
|
env['BUTTERFLY_PATH'] = os.path.abspath(os.path.join(
|
||||||
os.path.dirname(__file__), 'bin')), env.get("PATH"))
|
os.path.dirname(__file__), 'bin'))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tty = os.ttyname(0).replace('/dev/', '')
|
tty = os.ttyname(0).replace('/dev/', '')
|
||||||
|
|||||||
Submodule butterfly/themes updated: c9dd55f4e6...cfad944d6f
@@ -197,13 +197,21 @@ class Terminal
|
|||||||
erased
|
erased
|
||||||
|
|
||||||
focus: ->
|
focus: ->
|
||||||
|
old_sl = @scrollLock
|
||||||
|
@scrollLock = true
|
||||||
|
|
||||||
@send('\x1b[I') if @sendFocus
|
@send('\x1b[I') if @sendFocus
|
||||||
@showCursor()
|
@showCursor()
|
||||||
@body.classList.add('focus')
|
@body.classList.add('focus')
|
||||||
@body.classList.remove('blur')
|
@body.classList.remove('blur')
|
||||||
@resize()
|
@resize()
|
||||||
|
|
||||||
|
@scrollLock = old_sl
|
||||||
|
|
||||||
blur: ->
|
blur: ->
|
||||||
|
old_sl = @scrollLock
|
||||||
|
@scrollLock = true
|
||||||
|
|
||||||
@cursorState = 1
|
@cursorState = 1
|
||||||
@screen[@y + @shift].dirty = true
|
@screen[@y + @shift].dirty = true
|
||||||
@refresh()
|
@refresh()
|
||||||
@@ -211,6 +219,8 @@ class Terminal
|
|||||||
@body.classList.add('blur')
|
@body.classList.add('blur')
|
||||||
@body.classList.remove('focus')
|
@body.classList.remove('focus')
|
||||||
|
|
||||||
|
@scrollLock = old_sl
|
||||||
|
|
||||||
# XTerm mouse events
|
# XTerm mouse events
|
||||||
# http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
|
# http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
|
||||||
# To better understand these
|
# To better understand these
|
||||||
@@ -538,7 +548,7 @@ class Terminal
|
|||||||
@children = Array.prototype.slice.call(
|
@children = Array.prototype.slice.call(
|
||||||
lines, -@rows)
|
lines, -@rows)
|
||||||
|
|
||||||
@nativeScrollTo() unless @scrollLock
|
@nativeScrollTo()
|
||||||
|
|
||||||
_cursorBlink: ->
|
_cursorBlink: ->
|
||||||
@cursorState ^= 1
|
@cursorState ^= 1
|
||||||
@@ -591,6 +601,7 @@ class Terminal
|
|||||||
|
|
||||||
|
|
||||||
nativeScrollTo: (scroll=2000000000) -> # ~ Max ff number
|
nativeScrollTo: (scroll=2000000000) -> # ~ Max ff number
|
||||||
|
return if @scrollLock
|
||||||
window.scrollTo 0, scroll
|
window.scrollTo 0, scroll
|
||||||
|
|
||||||
scrollDisplay: (disp) ->
|
scrollDisplay: (disp) ->
|
||||||
|
|||||||
43
scripts/butterfly
Executable file
43
scripts/butterfly
Executable file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
if (os.getenv('COLORTERM', '') != 'butterfly' and
|
||||||
|
len(sys.argv) == 1) or (
|
||||||
|
os.getenv('COLORTERM', '') == 'butterfly' and
|
||||||
|
len(sys.argv) > 1 and sys.argv[1] == 'run'):
|
||||||
|
os.execvp('butterfly.server.py', [
|
||||||
|
'butterfly', '--unsecure', '--port=0', '--one-shot'])
|
||||||
|
|
||||||
|
path = os.getenv('BUTTERFLY_PATH')
|
||||||
|
if not path:
|
||||||
|
try:
|
||||||
|
import butterfly
|
||||||
|
path = os.path.join(
|
||||||
|
os.path.dirname(butterfly.__file__), 'bin')
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
os.putenv('BUTTERFLY_PATH', path)
|
||||||
|
if path is None:
|
||||||
|
print("Can't get butterfly path. Aborting.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
add_help=False,
|
||||||
|
description='Butterfly launcher. Please specify a command')
|
||||||
|
parser.add_argument('-h', '--help', action="store_true",
|
||||||
|
help="show this help message and exit")
|
||||||
|
parser.add_argument(
|
||||||
|
'command',
|
||||||
|
nargs='?',
|
||||||
|
choices=[x[:-3] for x in os.listdir(path) if x.endswith('.py')])
|
||||||
|
|
||||||
|
args, _ = parser.parse_known_args()
|
||||||
|
|
||||||
|
if not args.command:
|
||||||
|
parser.print_help()
|
||||||
|
else:
|
||||||
|
file_ = os.path.join(path, '%s.py' % args.command)
|
||||||
|
sys.argv = sys.argv[1:]
|
||||||
|
exec(compile(open(file_).read(), file_, 'exec'))
|
||||||
2
setup.py
2
setup.py
@@ -22,7 +22,7 @@ options = dict(
|
|||||||
url="http://github.com/paradoxxxzero/butterfly",
|
url="http://github.com/paradoxxxzero/butterfly",
|
||||||
license="GPLv3",
|
license="GPLv3",
|
||||||
platforms="Any",
|
platforms="Any",
|
||||||
scripts=['butterfly.server.py'],
|
scripts=['butterfly.server.py', 'scripts/butterfly', 'scripts/b'],
|
||||||
packages=['butterfly'],
|
packages=['butterfly'],
|
||||||
install_requires=["tornado>=3.2", "pyOpenSSL", 'tornado_systemd'],
|
install_requires=["tornado>=3.2", "pyOpenSSL", 'tornado_systemd'],
|
||||||
extras_requires=["libsass"],
|
extras_requires=["libsass"],
|
||||||
|
|||||||
Reference in New Issue
Block a user