Hello community, here is the log from the commit of package kitty for openSUSE:Factory checked in at 2020-03-30 23:02:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kitty (Old) and /work/SRC/openSUSE:Factory/.kitty.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kitty" Mon Mar 30 23:02:14 2020 rev:9 rq:789483 version:0.17.2 Changes: -------- --- /work/SRC/openSUSE:Factory/kitty/kitty.changes 2020-03-26 23:33:20.254776414 +0100 +++ /work/SRC/openSUSE:Factory/.kitty.new.3160/kitty.changes 2020-03-30 23:02:15.544137404 +0200 @@ -1,0 +2,25 @@ +Sun Mar 29 11:26:43 UTC 2020 - Michael Vetter <mvet...@suse.com> + +- Update to 0.17.2: + * Add a launch --watcher option that allows defining callbacks + that are called for various events in the window's life-cycle + (#2440) + * Fix a regression in 0.17 that broke drawing of borders with + non-minimal borders (#2474) + * Hints kitten: Allow copying to primary selection as well + as clipboard (#2487) + * Add a new mappable action close_other_windows_in_tab to close + all but the active window (#2484) + * Hints kitten: Adjust the default regex used to detect line + numbers to handle line+column numbers (#2268) + * Fix blank space at the start of tab bar in the powerline + style when first tab is inactive (#2478) + * Fix regression causing incorrect rendering of separators in + tab bar when defining a tab bar background color (#2480) + * Fix a regression in 0.17 that broke the kitty @ launch remote + command and also broke the --tab-title option when + creating a new tab. (#2488) + * Linux: Fix selection of fonts with multiple width variants + not preferring the normal width faces (#2491) + +------------------------------------------------------------------- Old: ---- kitty-0.17.1.tar.gz New: ---- kitty-0.17.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kitty.spec ++++++ --- /var/tmp/diff_new_pack.Fh52n1/_old 2020-03-30 23:02:16.312137840 +0200 +++ /var/tmp/diff_new_pack.Fh52n1/_new 2020-03-30 23:02:16.324137847 +0200 @@ -17,7 +17,7 @@ Name: kitty -Version: 0.17.1 +Version: 0.17.2 Release: 0 Summary: A GPU-based terminal emulator License: GPL-3.0-only ++++++ kitty-0.17.1.tar.gz -> kitty-0.17.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/docs/changelog.rst new/kitty-0.17.2/docs/changelog.rst --- old/kitty-0.17.1/docs/changelog.rst 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/docs/changelog.rst 2020-03-29 05:50:17.000000000 +0200 @@ -4,6 +4,37 @@ |kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator. To update |kitty|, :doc:`follow the instructions <binary>`. +0.17.2 [2020-03-29] +-------------------- + +- Add a :option:`launch --watcher` option that allows defining callbacks + that are called for various events in the window's life-cycle (:iss:`2440`) + +- Fix a regression in 0.17 that broke drawing of borders with non-minimal + borders (:iss:`2474`) + +- Hints kitten: Allow copying to primary selection as well as clipboard + (:pull:`2487`) + +- Add a new mappable action ``close_other_windows_in_tab`` to close all but the + active window (:iss:`2484`) + +- Hints kitten: Adjust the default regex used to detect line numbers to handle + line+column numbers (:iss:`2268`) + +- Fix blank space at the start of tab bar in the powerline style when first tab is + inactive (:iss:`2478`) + +- Fix regression causing incorrect rendering of separators in tab bar when + defining a tab bar background color (:pull:`2480`) + +- Fix a regression in 0.17 that broke the kitty @ launch remote command and + also broke the --tab-title option when creating a new tab. (:iss:`2488`) + +- Linux: Fix selection of fonts with multiple width variants not preferring + the normal width faces (:iss:`2491`) + + 0.17.1 [2020-03-24] -------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/docs/index.rst new/kitty-0.17.2/docs/index.rst --- old/kitty-0.17.1/docs/index.rst 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/docs/index.rst 2020-03-29 05:50:17.000000000 +0200 @@ -192,6 +192,12 @@ # asks which OS Window to move the tab into map ctrl+f4 detach_tab ask +Finally, you can define a shortcut to close all windows in a tab other than +the currently active window:: + + map f9 close_other_windows_in_tab + + Other keyboard shortcuts ---------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/docs/launch.rst new/kitty-0.17.2/docs/launch.rst --- old/kitty-0.17.1/docs/launch.rst 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/docs/launch.rst 2020-03-29 05:50:17.000000000 +0200 @@ -61,6 +61,35 @@ map f1 launch my-program @active-kitty-window-id +Watching launched windows +--------------------------- + +The :option:`launch --watcher` option allows you to specify python functions +that will be called at specific events, such as when the window is resized or +closed. Simply specify the path to a python module that specifies callback +functions for the events you are interested in, for example: + +.. code-block:: python + + def on_resize(boss, window, data): + # Here data will contain old_geometry and new_geometry + + def on_close(boss, window, data): + # called when window is closed, typically when the program running in + # it exits. + + +Every callback is passed a reference to the global ``Boss`` object as well as +the ``Window`` object the action is occurring on. The ``data`` object is +mapping that contains event dependent data. Some useful methods and attributes +for the ``Window`` object are: ``as_text(as_ans=False, add_history=False, +add_wrap_markers=False, alternate_screen=False)`` with which you can get the +contents of the window and its scrollback buffer. Similarly, +``window.child.pid`` is the PID of the processes that was launched +in the window and ``window.id`` is the internal kitty ``id`` of the +window. + + Syntax reference ------------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kittens/diff/main.py new/kitty-0.17.2/kittens/diff/main.py --- old/kitty-0.17.1/kittens/diff/main.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kittens/diff/main.py 2020-03-29 05:50:17.000000000 +0200 @@ -48,6 +48,9 @@ except ImportError: has_highlighter = False + def highlight_collection(collection: 'Collection', aliases: Optional[Dict[str, str]] = None) -> Union[str, Dict[str, 'DiffHighlight']]: + return '' + INITIALIZING, COLLECTED, DIFFED, COMMAND, MESSAGE = range(5) ESCAPE = K['ESCAPE'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kittens/hints/main.py new/kitty-0.17.2/kittens/hints/main.py --- old/kitty-0.17.1/kittens/hints/main.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kittens/hints/main.py 2020-03-29 05:50:17.000000000 +0200 @@ -21,7 +21,7 @@ KeyEvent, backspace_key, enter_key, key_defs as K ) from kitty.typing import BossType, KittyCommonOpts -from kitty.utils import ScreenSize, screen_size_function +from kitty.utils import ScreenSize, screen_size_function, set_primary_selection from ..tui.handler import Handler, result_handler from ..tui.loop import Loop @@ -349,7 +349,7 @@ def linenum_marks(text: str, args: HintsCLIOptions, Mark: Type[Mark], extra_cli_args: Sequence[str], *a: Any) -> Generator[Mark, None, None]: regex = args.regex if regex == DEFAULT_REGEX: - regex = r'(?P<path>(?:\S*/\S+)|(?:\S+[.][a-zA-Z0-9]{2,7})):(?P<line>\d+)' + regex = r'(?P<path>(?:\S*/\S+?)|(?:\S+[.][a-zA-Z0-9]{2,7})):(?P<line>\d+)' yield from mark(regex, [brackets, quotes], text, args) @@ -360,12 +360,8 @@ return {k: getattr(m, k) for k in dir(m)} if customize_processing == '::linenum::': return {'mark': linenum_marks, 'handle_result': linenum_handle_result} - from kitty.constants import config_dir - customize_processing = os.path.expandvars(os.path.expanduser(customize_processing)) - if os.path.isabs(customize_processing): - custom_path = customize_processing - else: - custom_path = os.path.join(config_dir, customize_processing) + from kitty.constants import resolve_custom_file + custom_path = resolve_custom_file(customize_processing) import runpy return runpy.run_path(custom_path, run_name='__main__') @@ -413,9 +409,11 @@ type=list What program to use to open matched text. Defaults to the default open program for the operating system. Use a value of :file:`-` to paste the match into the -terminal window instead. A value of :file:`@` will copy the match to the clipboard. -A value of :file:`default` will run the default open program. Can be specified -multiple times to run multiple programs. +terminal window instead. A value of :file:`@` will copy the match to the +clipboard. A value of :file:`*` will copy the match to the primary selection +(on systems that support primary selections). A value of :file:`default` will +run the default open program. Can be specified multiple times to run multiple +programs. --type @@ -629,6 +627,8 @@ w.paste(joined_text()) elif program == '@': set_clipboard_string(joined_text()) + elif program == '*': + set_primary_selection(joined_text()) else: cwd = None w = boss.window_id_map.get(target_window_id) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/cli.py new/kitty-0.17.2/kitty/cli.py --- old/kitty-0.17.1/kitty/cli.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/cli.py 2020-03-29 05:50:17.000000000 +0200 @@ -96,7 +96,9 @@ def option(x: str) -> str: - idx = x.find('-') + idx = x.rfind('--') + if idx < 0: + idx = x.find('-') if idx > -1: x = x[idx:] parts = map(bold, x.split()) @@ -119,6 +121,10 @@ return italic(x) +def doc(x: str) -> str: + return f'https://sw.kovidgoyal.net/kitty/{x}.html' + + OptionSpecSeq = List[Union[str, OptionDict]] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/conf/definition.py new/kitty-0.17.2/kitty/conf/definition.py --- old/kitty-0.17.1/kitty/conf/definition.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/conf/definition.py 2020-03-29 05:50:17.000000000 +0200 @@ -6,7 +6,7 @@ from functools import partial from typing import ( Any, Callable, Dict, Generator, Iterable, List, Match, Optional, Sequence, - Set, Tuple, Union, cast, get_type_hints + Set, Tuple, Union, get_type_hints ) from .utils import to_bool @@ -156,7 +156,7 @@ 'layouts': 'https://sw.kovidgoyal.net/kitty/index.html#layouts', 'sessions': 'https://sw.kovidgoyal.net/kitty/index.html#sessions', }[m.group(2)] - return cast(str, m.group(2)) + return str(m.group(2)) return re.sub(r':([a-zA-Z0-9]+):`(.+?)`', sub, text, flags=re.DOTALL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/constants.py new/kitty-0.17.2/kitty/constants.py --- old/kitty-0.17.1/kitty/constants.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/constants.py 2020-03-29 05:50:17.000000000 +0200 @@ -20,7 +20,7 @@ appname: str = 'kitty' -version: Version = Version(0, 17, 1) +version: Version = Version(0, 17, 2) str_version: str = '.'.join(map(str, version)) _plat = sys.platform.lower() is_macos: bool = 'darwin' in _plat @@ -198,3 +198,10 @@ if set_val is not None: setattr(running_in_kitty, 'ans', set_val) return bool(getattr(running_in_kitty, 'ans', False)) + + +def resolve_custom_file(path: str) -> str: + path = os.path.expandvars(os.path.expanduser(path)) + if not os.path.isabs(path): + path = os.path.join(config_dir, path) + return path diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/fast_data_types.pyi new/kitty-0.17.2/kitty/fast_data_types.pyi --- old/kitty-0.17.1/kitty/fast_data_types.pyi 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/fast_data_types.pyi 2020-03-29 05:50:17.000000000 +0200 @@ -323,6 +323,7 @@ FC_DUAL: int FC_WEIGHT_REGULAR: int FC_WEIGHT_BOLD: int +FC_WIDTH_NORMAL: int FC_SLANT_ROMAN: int FC_SLANT_ITALIC: int BORDERS_PROGRAM: int @@ -402,6 +403,7 @@ style: str spacing: str weight: int + width: int slant: int hint_style: int subpixel: int diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/fontconfig.c new/kitty-0.17.2/kitty/fontconfig.c --- old/kitty-0.17.1/kitty/fontconfig.c 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/fontconfig.c 2020-03-29 05:50:17.000000000 +0200 @@ -47,6 +47,7 @@ S(FC_FULLNAME, full_name); S(FC_POSTSCRIPT_NAME, postscript_name); I(FC_WEIGHT, weight); + I(FC_WIDTH, width) I(FC_SLANT, slant); I(FC_HINT_STYLE, hint_style); I(FC_INDEX, index); @@ -247,5 +248,7 @@ PyModule_AddIntMacro(module, FC_DUAL); PyModule_AddIntMacro(module, FC_MONO); PyModule_AddIntMacro(module, FC_CHARCELL); + PyModule_AddIntMacro(module, FC_WIDTH_NORMAL); + return true; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/fonts/fontconfig.py new/kitty-0.17.2/kitty/fonts/fontconfig.py --- old/kitty-0.17.1/kitty/fonts/fontconfig.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/fonts/fontconfig.py 2020-03-29 05:50:17.000000000 +0200 @@ -8,7 +8,7 @@ from kitty.fast_data_types import ( FC_DUAL, FC_MONO, FC_SLANT_ITALIC, FC_SLANT_ROMAN, FC_WEIGHT_BOLD, - FC_WEIGHT_REGULAR, fc_list, fc_match as fc_match_impl + FC_WEIGHT_REGULAR, FC_WIDTH_NORMAL, fc_list, fc_match as fc_match_impl ) from kitty.options_stub import Options from kitty.typing import FontConfigPattern @@ -73,11 +73,13 @@ q = family_name_to_key(family) font_map = all_fonts_map(monospaced) - def score(candidate: FontConfigPattern) -> Tuple[int, int]: + def score(candidate: FontConfigPattern) -> Tuple[int, int, int]: bold_score = abs((FC_WEIGHT_BOLD if bold else FC_WEIGHT_REGULAR) - candidate.get('weight', 0)) italic_score = abs((FC_SLANT_ITALIC if italic else FC_SLANT_ROMAN) - candidate.get('slant', 0)) monospace_match = 0 if candidate.get('spacing') == 'MONO' else 1 - return bold_score + italic_score, monospace_match + width_score = abs(candidate.get('width', FC_WIDTH_NORMAL) - FC_WIDTH_NORMAL) + + return bold_score + italic_score, monospace_match, width_score # First look for an exact match for selector in ('ps_map', 'full_map', 'family_map'): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/launch.py new/kitty-0.17.2/kitty/launch.py --- old/kitty-0.17.1/kitty/launch.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/launch.py 2020-03-29 05:50:17.000000000 +0200 @@ -6,14 +6,15 @@ from functools import lru_cache from typing import Any, Dict, List, Optional, Sequence, Tuple +from .boss import Boss from .child import Child from .cli import parse_args from .cli_stub import LaunchCLIOptions +from .constants import resolve_custom_file from .fast_data_types import set_clipboard_string -from .utils import set_primary_selection -from .window import Window -from .boss import Boss from .tabs import Tab +from .utils import set_primary_selection +from .window import Watchers, Window try: from typing import TypedDict @@ -148,6 +149,14 @@ --os-window-name Set the WM_NAME property on X11 for the newly created OS Window when using :option:`launch --type`=os-window. Defaults to :option:`launch --os-window-class`. + + +--watcher -w +type=list +Path to a python file. Appropriately named functions in this file will be called +for various events, such as when the window is resized or closed. See the section +on watchers in the launch command documentation :doc:`launch`. Relative paths are +resolved relative to the kitty config directory. ''' @@ -176,7 +185,7 @@ tm = boss.active_tab_manager if tm: tab: Optional[Tab] = tm.new_tab(empty_tab=True, location=opts.location) - if opts.tab_title and tab: + if opts.tab_title and tab is not None: tab.set_title(opts.tab_title) else: tab = None @@ -184,7 +193,7 @@ oswid = boss.add_os_window(wclass=opts.os_window_class, wname=opts.os_window_name) tm = boss.os_window_map[oswid] tab = tm.new_tab(empty_tab=True) - if opts.tab_title: + if opts.tab_title and tab is not None: tab.set_title(opts.tab_title) else: tab = target_tab or boss.active_tab @@ -192,6 +201,23 @@ return tab +def load_watch_modules(opts: LaunchCLIOptions) -> Optional[Watchers]: + if not opts.watcher: + return None + import runpy + ans = Watchers() + for path in opts.watcher: + path = resolve_custom_file(path) + m = runpy.run_path(path, run_name='__kitty_watcher__') + w = m.get('on_close') + if callable(w): + ans.on_close.append(w) + w = m.get('on_resize') + if callable(w): + ans.on_resize.append(w) + return ans + + class LaunchKwds(TypedDict): allow_remote_control: bool @@ -274,7 +300,8 @@ else: tab = tab_for_window(boss, opts, target_tab) if tab is not None: - new_window: Window = tab.new_window(env=env or None, **kw) + watchers = load_watch_modules(opts) + new_window: Window = tab.new_window(env=env or None, watchers=watchers or None, **kw) if opts.keep_focus and active: boss.set_active_window(active, switch_os_window_if_needed=True) return new_window diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/layout.py new/kitty-0.17.2/kitty/layout.py --- old/kitty-0.17.1/kitty/layout.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/layout.py 2020-03-29 05:50:17.000000000 +0200 @@ -549,7 +549,7 @@ def minimal_borders(self, windows: WindowList, active_window: Optional[WindowType], needs_borders_map: Dict[int, bool]) -> Generator[Borders, None, None]: for w in windows: - if (w is active_window and draw_active_borders) or w.needs_attention: + if w is not active_window or draw_active_borders or w.needs_attention: yield all_borders else: yield no_borders @@ -1512,6 +1512,13 @@ else: p2.two = w1 + def minimal_borders(self, windows: WindowList, active_window: Optional[WindowType], needs_borders_map: Dict[int, bool]) -> Generator[Borders, None, None]: + for w in windows: + if (w is active_window and draw_active_borders) or w.needs_attention: + yield all_borders + else: + yield no_borders + def layout_action(self, action_name: str, args: Sequence[str], all_windows: WindowList, active_window_idx: int) -> Optional[Union[bool, int]]: if action_name == 'rotate': args = args or ('90',) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/rc/launch.py new/kitty-0.17.2/kitty/rc/launch.py --- old/kitty-0.17.1/kitty/rc/launch.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/rc/launch.py 2020-03-29 05:50:17.000000000 +0200 @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, Optional +from kitty.cli_stub import LaunchCLIOptions from kitty.launch import ( launch as do_launch, options_spec as launch_options_spec, parse_launch_args @@ -16,7 +17,7 @@ ) if TYPE_CHECKING: - from kitty.cli_stub import LaunchRCOptions as CLIOptions, LaunchCLIOptions + from kitty.cli_stub import LaunchRCOptions as CLIOptions class Launch(RemoteCommand): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/rc/set_colors.py new/kitty-0.17.2/kitty/rc/set_colors.py --- old/kitty-0.17.1/kitty/rc/set_colors.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/rc/set_colors.py 2020-03-29 05:50:17.000000000 +0200 @@ -57,6 +57,7 @@ this option, any color arguments are ignored and --configured and --all are implied. ''' + '\n\n' + MATCH_WINDOW_OPTION + '\n\n' + MATCH_TAB_OPTION.replace('--match -m', '--match-tab -t') argspec = 'COLOR_OR_FILE ...' + args_completion = {'files': ('CONF files', ('*.conf',))} def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType: final_colors: Dict[str, int] = {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/tab_bar.py new/kitty-0.17.2/kitty/tab_bar.py --- old/kitty-0.17.1/kitty/tab_bar.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/tab_bar.py 2020-03-29 05:50:17.000000000 +0200 @@ -81,8 +81,11 @@ screen.draw(' ' * trailing_spaces) end = screen.cursor.x screen.cursor.bold = screen.cursor.italic = False - screen.cursor.fg = screen.cursor.bg = 0 + screen.cursor.fg = 0 + if not is_last: + screen.cursor.bg = as_rgb(color_as_int(draw_data.inactive_bg)) screen.draw(draw_data.sep) + screen.cursor.bg = 0 return end @@ -137,6 +140,7 @@ screen.draw(' ') screen.cursor.fg = tab_fg elif screen.cursor.x == 0: + screen.cursor.bg = tab_bg screen.draw(' ') start_draw = 1 @@ -182,7 +186,7 @@ s.color_profile.update_ansi_color_table(build_ansi_color_table(opts)) s.color_profile.set_configured_colors( color_as_int(opts.inactive_tab_foreground), - color_as_int(opts.background) + color_as_int(opts.tab_bar_background or opts.background) ) self.blank_rects: Tuple[Rect, ...] = () sep = opts.tab_separator @@ -226,10 +230,13 @@ self.draw_data = self.draw_data._replace(default_bg=color_from_int(spec['tab_bar_background'])) elif 'background' in spec and not self.opts.tab_bar_background: self.draw_data = self.draw_data._replace(default_bg=color_from_int(spec['background'])) - self.screen.color_profile.set_configured_colors( - spec.get('inactive_tab_foreground', color_as_int(self.opts.inactive_tab_foreground)), - spec.get('inactive_tab_background', color_as_int(self.opts.inactive_tab_background)) - ) + fg = spec.get('inactive_tab_foreground', color_as_int(self.opts.inactive_tab_foreground)) + bg = spec.get('tab_bar_background', False) + if bg is None: + bg = color_as_int(self.opts.background) + elif bg is False: + bg = color_as_int(self.opts.tab_bar_background or self.opts.background) + self.screen.color_profile.set_configured_colors(fg, bg) def layout(self) -> None: central, tab_bar, vw, vh, cell_width, cell_height = viewport_for_window(self.os_window_id) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/tabs.py new/kitty-0.17.2/kitty/tabs.py --- old/kitty-0.17.1/kitty/tabs.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/tabs.py 2020-03-29 05:50:17.000000000 +0200 @@ -26,7 +26,7 @@ from .options_stub import Options from .tab_bar import TabBar, TabBarData from .utils import log_error, resolved_shell -from .window import Window, WindowDict +from .window import Window, WindowDict, Watchers from .typing import TypedDict, SessionTab, SessionType @@ -345,11 +345,15 @@ location: Optional[str] = None, copy_colors_from: Optional[Window] = None, allow_remote_control: bool = False, - marker: Optional[str] = None + marker: Optional[str] = None, + watchers: Optional[Watchers] = None ) -> Window: child = self.launch_child( use_shell=use_shell, cmd=cmd, stdin=stdin, cwd_from=cwd_from, cwd=cwd, env=env, allow_remote_control=allow_remote_control) - window = Window(self, child, self.opts, self.args, override_title=override_title, copy_colors_from=copy_colors_from) + window = Window( + self, child, self.opts, self.args, override_title=override_title, + copy_colors_from=copy_colors_from, watchers=watchers + ) if overlay_for is not None: overlaid = next(w for w in self.windows if w.id == overlay_for) window.overlay_for = overlay_for @@ -384,6 +388,13 @@ if self.windows: self.remove_window(self.windows[self.active_window_idx]) + def close_other_windows_in_tab(self) -> None: + if len(self.windows) > 1: + active_window = self.windows[self.active_window_idx] + for window in tuple(self.windows): + if window is not active_window: + self.remove_window(window) + def previous_active_window_idx(self, num: int) -> Optional[int]: try: old_window_id = self.active_window_history[-num] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitty-0.17.1/kitty/window.py new/kitty-0.17.2/kitty/window.py --- old/kitty-0.17.1/kitty/window.py 2020-03-24 15:15:19.000000000 +0100 +++ new/kitty-0.17.2/kitty/window.py 2020-03-29 05:50:17.000000000 +0200 @@ -10,8 +10,8 @@ from enum import IntEnum from itertools import chain from typing import ( - Any, Callable, Deque, Dict, List, Optional, Pattern, Sequence, Tuple, - Union + Any, Callable, Deque, Dict, Iterable, List, Optional, Pattern, Sequence, + Tuple, Union ) from .child import ProcessDesc @@ -32,7 +32,7 @@ from .options_stub import Options from .rgb import to_color from .terminfo import get_capabilities -from .typing import ChildType, TabType, TypedDict +from .typing import BossType, ChildType, TabType, TypedDict from .utils import ( color_as_int, get_primary_selection, load_shaders, open_cmd, open_url, parse_color_set, read_shell_environment, sanitize_title, @@ -77,6 +77,19 @@ DYNAMIC_COLOR_CODES.update({k+100: v for k, v in DYNAMIC_COLOR_CODES.items()}) +class Watcher: + + def __call__(self, boss: BossType, window: 'Window', data: Dict[str, Any]) -> None: + pass + + +class Watchers: + + def __init__(self) -> None: + self.on_resize: List[Watcher] = [] + self.on_close: List[Watcher] = [] + + def calculate_gl_geometry(window_geometry: WindowGeometry, viewport_width: int, viewport_height: int, cell_width: int, cell_height: int) -> ScreenGeometry: dx, dy = 2 * cell_width / viewport_width, 2 * cell_height / viewport_height xmargin = window_geometry.left / viewport_width @@ -181,8 +194,10 @@ opts: Options, args: CLIOptions, override_title: Optional[str] = None, - copy_colors_from: Optional['Window'] = None + copy_colors_from: Optional['Window'] = None, + watchers: Optional[Watchers] = None ): + self.watchers = watchers or Watchers() self.action_on_close: Optional[Callable] = None self.action_on_removal: Optional[Callable] = None self.current_marker_spec: Optional[Tuple[str, Union[str, Tuple[Tuple[int, str], ...]]]] = None @@ -303,6 +318,7 @@ if not self.pty_resized_once: self.pty_resized_once = True self.child.mark_terminal_ready() + self.call_watchers(self.watchers.on_resize, {'old_geometry': self.geometry, 'new_geometry': new_geometry}) else: sg = self.update_position(new_geometry) self.geometry = g = new_geometry @@ -536,7 +552,17 @@ return ''.join((l.rstrip() or '\n') for l in lines) return ''.join(lines) + def call_watchers(self, which: Iterable[Watcher], data: Dict[str, Any]) -> None: + boss = get_boss() + for w in which: + try: + w(boss, self, data) + except Exception: + import traceback + traceback.print_exc() + def destroy(self) -> None: + self.call_watchers(self.watchers.on_close, {}) self.destroyed = True if hasattr(self, 'screen'): # Remove cycles so that screen is de-allocated immediately