Fix terminal resizing support
This commit is contained in:
parent
39a09f2704
commit
219a509bee
|
@ -35,6 +35,14 @@
|
||||||
|
|
||||||
import curses
|
import curses
|
||||||
import colors
|
import colors
|
||||||
|
try:
|
||||||
|
import signal
|
||||||
|
from fcntl import ioctl
|
||||||
|
import termios
|
||||||
|
import struct
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
|
|
||||||
|
@ -95,7 +103,21 @@ class Screen(CursesStdIO):
|
||||||
# The offset to display lines
|
# The offset to display lines
|
||||||
self.display_lines_offset = 0
|
self.display_lines_offset = 0
|
||||||
|
|
||||||
# Refresh the screen to display everything right away
|
# Keep track of the screen size
|
||||||
|
self.rows, self.cols = self.stdscr.getmaxyx()
|
||||||
|
try:
|
||||||
|
signal.signal(signal.SIGWINCH, self.on_resize)
|
||||||
|
except Exception, e:
|
||||||
|
log.debug("Unable to catch SIGWINCH signal!")
|
||||||
|
|
||||||
|
# Do a refresh right away to draw the screen
|
||||||
|
self.refresh()
|
||||||
|
|
||||||
|
def on_resize(self, *args):
|
||||||
|
log.debug("on_resize_from_signal")
|
||||||
|
# Get the new rows and cols value
|
||||||
|
self.rows, self.cols = struct.unpack("hhhh", ioctl(0, termios.TIOCGWINSZ ,"\000"*8))[0:2]
|
||||||
|
curses.resizeterm(self.rows, self.cols)
|
||||||
self.refresh()
|
self.refresh()
|
||||||
|
|
||||||
def connectionLost(self, reason):
|
def connectionLost(self, reason):
|
||||||
|
@ -124,7 +146,6 @@ class Screen(CursesStdIO):
|
||||||
:param text: str, the text to show
|
:param text: str, the text to show
|
||||||
"""
|
"""
|
||||||
|
|
||||||
rows, cols = self.stdscr.getmaxyx()
|
|
||||||
def get_line_chunks(line):
|
def get_line_chunks(line):
|
||||||
"""
|
"""
|
||||||
Returns a list of 2-tuples (color string, text)
|
Returns a list of 2-tuples (color string, text)
|
||||||
|
@ -160,13 +181,13 @@ class Screen(CursesStdIO):
|
||||||
log.error("Passed a bad colored string..")
|
log.error("Passed a bad colored string..")
|
||||||
line_length = len(line)
|
line_length = len(line)
|
||||||
|
|
||||||
if line_length >= (cols - 1):
|
if line_length >= (self.cols - 1):
|
||||||
s = ""
|
s = ""
|
||||||
# The length of the text without the color tags
|
# The length of the text without the color tags
|
||||||
s_len = 0
|
s_len = 0
|
||||||
# We need to split this over multiple lines
|
# We need to split this over multiple lines
|
||||||
for chunk in get_line_chunks(line):
|
for chunk in get_line_chunks(line):
|
||||||
if (len(chunk[1]) + s_len) < (cols - 1):
|
if (len(chunk[1]) + s_len) < (self.cols - 1):
|
||||||
# This chunk plus the current string in 's' isn't over
|
# This chunk plus the current string in 's' isn't over
|
||||||
# the maximum width, so just append the color tag and text
|
# the maximum width, so just append the color tag and text
|
||||||
s += chunk[0] + chunk[1]
|
s += chunk[0] + chunk[1]
|
||||||
|
@ -175,7 +196,7 @@ class Screen(CursesStdIO):
|
||||||
# The chunk plus the current string in 's' is too long.
|
# The chunk plus the current string in 's' is too long.
|
||||||
# We need to take as much of the chunk and put it into 's'
|
# We need to take as much of the chunk and put it into 's'
|
||||||
# with the color tag.
|
# with the color tag.
|
||||||
remain = (cols - 1) - s_len
|
remain = (self.cols - 1) - s_len
|
||||||
s += chunk[0] + chunk[1][:remain]
|
s += chunk[0] + chunk[1][:remain]
|
||||||
# We append the line since it's full
|
# We append the line since it's full
|
||||||
self.lines.append(s)
|
self.lines.append(s)
|
||||||
|
@ -201,7 +222,6 @@ class Screen(CursesStdIO):
|
||||||
:param row: int, the row number to write the string
|
:param row: int, the row number to write the string
|
||||||
|
|
||||||
"""
|
"""
|
||||||
rows, cols = self.stdscr.getmaxyx()
|
|
||||||
col = 0
|
col = 0
|
||||||
try:
|
try:
|
||||||
parsed = colors.parse_color_string(string)
|
parsed = colors.parse_color_string(string)
|
||||||
|
@ -212,7 +232,7 @@ class Screen(CursesStdIO):
|
||||||
for index, (color, s) in enumerate(parsed):
|
for index, (color, s) in enumerate(parsed):
|
||||||
if index + 1 == len(parsed):
|
if index + 1 == len(parsed):
|
||||||
# This is the last string so lets append some " " to it
|
# This is the last string so lets append some " " to it
|
||||||
s += " " * (cols - (col + len(s)) - 1)
|
s += " " * (self.cols - (col + len(s)) - 1)
|
||||||
self.stdscr.addstr(row, col, s, color)
|
self.stdscr.addstr(row, col, s, color)
|
||||||
col += len(s)
|
col += len(s)
|
||||||
|
|
||||||
|
@ -223,14 +243,13 @@ class Screen(CursesStdIO):
|
||||||
attribute and the status bars.
|
attribute and the status bars.
|
||||||
"""
|
"""
|
||||||
self.stdscr.clear()
|
self.stdscr.clear()
|
||||||
rows, cols = self.stdscr.getmaxyx()
|
|
||||||
|
|
||||||
# Update the status bars
|
# Update the status bars
|
||||||
self.add_string(0, self.topbar)
|
self.add_string(0, self.topbar)
|
||||||
self.add_string(rows - 2, self.bottombar)
|
self.add_string(self.rows - 2, self.bottombar)
|
||||||
|
|
||||||
# The number of rows minus the status bars and the input line
|
# The number of rows minus the status bars and the input line
|
||||||
available_lines = rows - 3
|
available_lines = self.rows - 3
|
||||||
# If the amount of lines exceeds the number of rows, we need to figure out
|
# If the amount of lines exceeds the number of rows, we need to figure out
|
||||||
# which ones to display based on the offset
|
# which ones to display based on the offset
|
||||||
if len(self.lines) > available_lines:
|
if len(self.lines) > available_lines:
|
||||||
|
@ -248,10 +267,11 @@ class Screen(CursesStdIO):
|
||||||
self.add_string(index + 1, line)
|
self.add_string(index + 1, line)
|
||||||
|
|
||||||
# Add the input string
|
# Add the input string
|
||||||
self.add_string(rows - 1, self.input)
|
self.add_string(self.rows - 1, self.input)
|
||||||
|
|
||||||
# Move the cursor
|
# Move the cursor
|
||||||
self.stdscr.move(rows - 1, self.input_cursor)
|
self.stdscr.move(self.rows - 1, self.input_cursor)
|
||||||
|
self.stdscr.redrawwin()
|
||||||
self.stdscr.refresh()
|
self.stdscr.refresh()
|
||||||
|
|
||||||
def doRead(self):
|
def doRead(self):
|
||||||
|
@ -266,7 +286,6 @@ class Screen(CursesStdIO):
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
||||||
def _doRead(self):
|
def _doRead(self):
|
||||||
rows, cols = self.stdscr.getmaxyx()
|
|
||||||
# Read the character
|
# Read the character
|
||||||
c = self.stdscr.getch()
|
c = self.stdscr.getch()
|
||||||
|
|
||||||
|
@ -339,14 +358,14 @@ class Screen(CursesStdIO):
|
||||||
|
|
||||||
# Scrolling through buffer
|
# Scrolling through buffer
|
||||||
elif c == curses.KEY_PPAGE:
|
elif c == curses.KEY_PPAGE:
|
||||||
self.display_lines_offset += rows - 3
|
self.display_lines_offset += self.rows - 3
|
||||||
# We substract 3 for the unavailable lines and 1 extra due to len(self.lines)
|
# We substract 3 for the unavailable lines and 1 extra due to len(self.lines)
|
||||||
if self.display_lines_offset > (len(self.lines) - 4 - rows):
|
if self.display_lines_offset > (len(self.lines) - 4 - self.rows):
|
||||||
self.display_lines_offset = len(self.lines) - 4 - rows
|
self.display_lines_offset = len(self.lines) - 4 - self.rows
|
||||||
|
|
||||||
self.refresh()
|
self.refresh()
|
||||||
elif c == curses.KEY_NPAGE:
|
elif c == curses.KEY_NPAGE:
|
||||||
self.display_lines_offset -= rows - 3
|
self.display_lines_offset -= self.rows - 3
|
||||||
if self.display_lines_offset < 0:
|
if self.display_lines_offset < 0:
|
||||||
self.display_lines_offset = 0
|
self.display_lines_offset = 0
|
||||||
self.refresh()
|
self.refresh()
|
||||||
|
@ -373,8 +392,8 @@ class Screen(CursesStdIO):
|
||||||
self.tab_count = 0
|
self.tab_count = 0
|
||||||
|
|
||||||
# Update the input string on the screen
|
# Update the input string on the screen
|
||||||
self.add_string(rows - 1, self.input)
|
self.add_string(self.rows - 1, self.input)
|
||||||
self.stdscr.move(rows - 1, self.input_cursor)
|
self.stdscr.move(self.rows - 1, self.input_cursor)
|
||||||
self.stdscr.refresh()
|
self.stdscr.refresh()
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
|
Loading…
Reference in New Issue