Skip to content

Commit

Permalink
Fix show/hide cursor for older Windows (#610)
Browse files Browse the repository at this point in the history
  • Loading branch information
itsayellow committed Jan 28, 2021
1 parent bb1b58b commit 88b84e5
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dev

- Fix cursor show/hide to work with older versions of Windows. (#610)

0.16.0.0

Expand Down
34 changes: 28 additions & 6 deletions src/pipx/animate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@
from threading import Event, Thread
from typing import Generator, List

from pipx.constants import emoji_support
from pipx.constants import WINDOWS, emoji_support

stderr_is_tty = sys.stderr.isatty()


HIDE_CURSOR = "\033[?25l"
SHOW_CURSOR = "\033[?25h"
CLEAR_LINE = "\033[K"
EMOJI_ANIMATION_FRAMES = ["⣷", "⣯", "⣟", "⡿", "⢿", "⣻", "⣽", "⣾"]
NONEMOJI_ANIMATION_FRAMES = ["", ".", "..", "..."]
Expand All @@ -19,6 +16,13 @@
MINIMUM_COLS_ALLOW_ANIMATION = 16


if WINDOWS:
import ctypes

class _CursorInfo(ctypes.Structure):
_fields_ = [("size", ctypes.c_int), ("visible", ctypes.c_byte)]


def _env_supports_animation() -> bool:
(term_cols, _) = shutil.get_terminal_size(fallback=(0, 0))
return stderr_is_tty and term_cols > MINIMUM_COLS_ALLOW_ANIMATION
Expand Down Expand Up @@ -96,12 +100,30 @@ def print_animation(
break


# for Windows pre-ANSI-terminal-support (before Windows 10 TH2 (v1511))
# https://stackoverflow.com/a/10455937
def win_cursor(visible: bool) -> None:
ci = _CursorInfo()
handle = ctypes.windll.kernel32.GetStdHandle(-11) # type: ignore[attr-defined]
ctypes.windll.kernel32.GetConsoleCursorInfo(handle, ctypes.byref(ci)) # type: ignore[attr-defined]
ci.visible = visible
ctypes.windll.kernel32.SetConsoleCursorInfo(handle, ctypes.byref(ci)) # type: ignore[attr-defined]


def hide_cursor() -> None:
sys.stderr.write(f"{HIDE_CURSOR}")
if WINDOWS:
win_cursor(visible=False)
else:
sys.stderr.write("\033[?25l")
sys.stderr.flush()


def show_cursor() -> None:
sys.stderr.write(f"{SHOW_CURSOR}")
if WINDOWS:
win_cursor(visible=True)
else:
sys.stderr.write("\033[?25h")
sys.stderr.flush()


def clear_line() -> None:
Expand Down
1 change: 0 additions & 1 deletion src/pipx/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ def exec_app(

# make sure we show cursor again before handing over control
show_cursor()
sys.stderr.flush()

logger.info("exec_app: " + " ".join([str(c) for c in cmd]))

Expand Down

0 comments on commit 88b84e5

Please sign in to comment.