Search code examples
pythonpython-3.xcurses

curses - addstr text is not visible in larger terminals


I'm writing an IRC client that uses Python's curses library, but the server's response is not output properly on the screen.

Basically, the smaller my terminal, the closer the output is to what it should be:

Full-sized terminal

On a full-sized terminal (1366x768 resolution) there is basically no output

Half-sized terminal

On a half-sized terminal, there is much more visible output

Quarter-sized terminal

On a quarter-sized terminal, the program outputs everything that I would expect it to.

Based on this pattern, my best guess is some line-length issue, but I really have no idea what the problem is.

Source Code

import curses
import queue
import socket
import threading
import time

PAD_LENGTH = 1000

def main(stdscr):
    s = socket.create_connection(("chat.freenode.net",6667))
    s.settimeout(1.0)

    s.send(b"PASS hello\r\n")
    s.send(b"NICK testingclient\r\n")
    s.send(b"USER testingclient tclient tclient :Test Client\r\n")

    s.setblocking(False)

    curses.noecho()
    curses.cbreak()
    stdscr.nodelay(1)

    pad = curses.newpad(PAD_LENGTH,curses.COLS-1)

    top = 0

    while True:
        try:
            msg = s.recv(512).decode("latin-1")
            pad.addstr(msg)
        except BlockingIOError:
            pass

        kc = stdscr.getch()

        if kc != -1:
            k = chr(kc)
            if k == "q":
                break
            elif k == "j" and top < PAD_LENGTH:
                top += 1
            elif k == "k" and top > 0:
                top -= 1

        pad.refresh(top,0,0,0,curses.LINES-1,curses.COLS-1)

    s.close()
    curses.nocbreak()
    curses.echo()
    curses.endwin()

curses.wrapper(main)

Misc Notes

I'm using i3 and xterm on Arch Linux in VirtualBox


Solution

  • The problem was caused by using addstr on a string with a carriage return character.

    I don't know the specific behaviour of \r in curses, but changing the message to msg = s.recv(512).decode("latin-1").replace("\r\n","\n") has provided me with perfect output.

    enter image description here