A new kitten to draw dock panels on X11 desktops showing the output from running arbitrary terminal programs

This commit is contained in:
Kovid Goyal 2018-06-02 11:27:01 +05:30
parent 0f82f90968
commit ec0edd6f45
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 185 additions and 1 deletions

View File

@ -239,6 +239,10 @@ Some prominent kittens:
filenames, words, lines, etc from the terminal screen. filenames, words, lines, etc from the terminal screen.
:doc:`Panel <kittens/panel>`
Draw a GPU accelerated dock panel on your desktop showing the output
from an arbitrary terminal program.
.. _sessions: .. _sessions:
Startup Sessions Startup Sessions

37
docs/kittens/panel.rst Normal file
View File

@ -0,0 +1,37 @@
Draw a GPU accelerated dock panel on your desktop
====================================================================================================
.. highlight:: sh
You can use this kitten to draw a GPU accelerated panel on the edge
of your screen, that shows the output from an arbitrary terminal program.
It is useful for showing status information or notifications on your desktop
using terminal programs instead of GUI toolkits.
.. figure:: ../screenshots/panel.png
:alt: Screenshot, showing a sample panel
:align: center
:scale: 100%
Screenshot, showing a sample panel
The screenshot above shows a sample panel that displays the current desktop and
window title as well as miscellaneous system information such as network
activity, CPU load, date/time, etc.
.. note::
This kitten currently only works on X11 desktops
Using this kitten is simple, for example::
kitty +kitten panel sh -c 'printf "\n\n\nHello, world."; sleep 5s'
This will show ``Hello, world.`` at the top edge of your screen for five
seconds. Here the terminal program we are running is ``sh`` with a script to
print out ``Hello, world!``. You can make the terminal program as complex as
you like, as demonstrated in the screenshot above.

BIN
docs/screenshots/panel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

143
kittens/panel/main.py Normal file
View File

@ -0,0 +1,143 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import subprocess
import sys
from kitty.constants import is_macos, is_wayland
from kitty.cli import parse_args
OPTIONS = r'''
--lines
type=int
default=1
The number of lines shown in the panel (the height of the panel). Applies to horizontal panels.
--columns
type=int
default=20
The number of columns shown in the panel (the width of the panel). Applies to vertical panels.
--edge
choices=top,bottom,left,right
default=top
Which edge of the screen to place the panel on. Note that some window managers
(such as i3) do not support placing docked windows on the left and right edges.
--config -c
type=list
Path to config file to use for kitty when drawing the panel.
--override -o
type=list
Override individual kitty configuration options, can be specified multiple times.
Syntax: :italic:`name=value`. For example: :option:`kitty +kitten panel -o` font_size=20
'''.format
args = None
def parse_panel_args(args):
msg = 'Use a command line program to draw a GPU accelerated panel on your X11 desktop'
return parse_args(args, OPTIONS, 'program-to-run', msg, 'panel')
def call_xprop(*cmd, silent=False):
cmd = ['xprop'] + list(cmd)
try:
cp = subprocess.run(cmd, stdout=subprocess.DEVNULL if silent else None)
except FileNotFoundError:
raise SystemExit('You must have the xprop program installed')
if cp.returncode != 0:
raise SystemExit(cp.returncode)
def create_strut(
win_id,
left=0, right=0, top=0, bottom=0, left_start_y=0, left_end_y=0,
right_start_y=0, right_end_y=0, top_start_x=0, top_end_x=0,
bottom_start_x=0, bottom_end_x=0
):
call_xprop(
'-id',
str(int(win_id)), '-format', '_NET_WM_STRUT_PARTIAL', '32cccccccccccc',
'-set', '_NET_WM_STRUT_PARTIAL',
'{left},{right},{top},{bottom},'
'{left_start_y},{left_end_y},{right_start_y},{right_end_y},'
'{top_start_x},{top_end_x},{bottom_start_x},{bottom_end_x}'.format(**locals())
)
def create_top_strut(win_id, width, height):
create_strut(win_id, top=height, top_end_x=width)
def create_bottom_strut(win_id, width, height):
create_strut(win_id, bottom=height, bottom_end_x=width)
def create_left_strut(win_id, width, height):
create_strut(win_id, left=width, left_end_y=height)
def create_right_strut(win_id, width, height):
create_strut(win_id, right=width, right_end_y=height)
def setup_x11_window(win_id):
call_xprop(
'-id', str(win_id), '-format', '_NET_WM_WINDOW_TYPE', '32a',
'-set', '_NET_WM_WINDOW_TYPE', '_NET_WM_WINDOW_TYPE_DOCK'
)
func = globals()['create_{}_strut'.format(args.edge)]
func(win_id, initial_window_size_func.width, initial_window_size_func.height)
def initial_window_size_func(opts, *a):
from kitty.fast_data_types import glfw_primary_monitor_size, set_smallest_allowed_resize
def initial_window_size(cell_width, cell_height, dpi_x, dpi_y):
monitor_width, monitor_height = glfw_primary_monitor_size()
if args.edge in {'top', 'bottom'}:
h = initial_window_size_func.height = cell_height * args.lines + 1
initial_window_size_func.width = monitor_width
set_smallest_allowed_resize(100, h)
else:
w = initial_window_size_func.width = cell_width * args.columns + 1
initial_window_size_func.height = monitor_height
set_smallest_allowed_resize(w, 100)
return initial_window_size_func.width, initial_window_size_func.height
return initial_window_size
def main(sys_args):
global args
if is_macos or is_wayland:
raise SystemExit('Currently the panel kitten is supported only on X11 desktops')
call_xprop('-version', silent=True) # ensure xprop is available
args, items = parse_panel_args(sys_args[1:])
if not items:
raise SystemExit('You must specify the program to run')
sys.argv = ['kitty']
if args.config:
sys.argv.append('--config={}'.format(args.config))
for override in args.override:
sys.argv.append('--override={}'.format(override))
sys.argv.extend(items)
from kitty.main import run_app, main
run_app.cached_values_name = 'panel'
run_app.first_window_callback = setup_x11_window
run_app.initial_window_size_func = initial_window_size_func
main()
if __name__ == '__main__':
main(sys.argv)

View File

@ -12,7 +12,7 @@ aliases = {'url_hints': 'hints'}
def resolved_kitten(k): def resolved_kitten(k):
return aliases.get(k, k) return aliases.get(k, k).replace('-', '_')
def import_kitten_main_module(config_dir, kitten): def import_kitten_main_module(config_dir, kitten):