Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kitty for openSUSE:Factory checked 
in at 2022-09-05 21:21:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kitty (Old)
 and      /work/SRC/openSUSE:Factory/.kitty.new.2083 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kitty"

Mon Sep  5 21:21:44 2022 rev:11 rq:1001194 version:0.26.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/kitty/kitty.changes      2022-09-01 
22:13:01.152542540 +0200
+++ /work/SRC/openSUSE:Factory/.kitty.new.2083/kitty.changes    2022-09-05 
21:21:45.525094366 +0200
@@ -1,0 +2,23 @@
+Mon Sep  5 06:11:31 UTC 2022 - Michael Vetter <mvet...@suse.com>
+
+- Update to 0.26.2:
+  * Allow creating overlay-main windows, which are treated as the
+    active window unlike normal overlays (#5392)
+  * hints kitten: Allow using The launch command as the program to run, to 
open the
+    result in a new kitty tab/window/etc. (#5462)
+  * hyperlinked_grep kitten: Allow control over which parts of rg output are
+    hyperlinked (#5428)
+  * Fix regression in 0.26.0 that caused launching kitty without working STDIO
+    handles to result in high CPU usage and prewarming failing (#5444)
+  * The launch command: Allow setting the margin and padding for newly created
+    windows (#5463)
+  * hints kitten: hyperlink matching: Fix hints occasionally matching text on
+    subsequent line as part of hyperlink (#5450)
+  * Fix a regression in 0.26.0 that broke mapping of native keys whose key 
codes
+    did not fit in 21 bits (#5452)
+  * Wayland: Fix remembering window size not accurate when client side 
decorations
+    are present
+  * Fix an issue where notification identifiers were not sanitized leading to 
code
+    execution if the user clicked on a notification popup from a malicious 
source.
+
+-------------------------------------------------------------------

Old:
----
  kitty-0.26.1.tar.gz

New:
----
  kitty-0.26.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kitty.spec ++++++
--- /var/tmp/diff_new_pack.elkzUj/_old  2022-09-05 21:21:46.093095872 +0200
+++ /var/tmp/diff_new_pack.elkzUj/_new  2022-09-05 21:21:46.097095882 +0200
@@ -19,7 +19,7 @@
 # sphinx_copybutton not in Factory
 %bcond_with docs
 Name:           kitty
-Version:        0.26.1
+Version:        0.26.2
 Release:        0
 Summary:        A GPU-based terminal emulator
 License:        GPL-3.0-only

++++++ kitty-0.26.1.tar.gz -> kitty-0.26.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/docs/changelog.rst 
new/kitty-0.26.2/docs/changelog.rst
--- old/kitty-0.26.1/docs/changelog.rst 2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/docs/changelog.rst 2022-09-05 07:19:50.000000000 +0200
@@ -35,6 +35,31 @@
 Detailed list of changes
 -------------------------------------
 
+0.26.2 [2022-09-05]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- Allow creating :code:`overlay-main` windows, which are treated as the active 
window unlike normal overlays (:iss:`5392`)
+
+- hints kitten: Allow using :doc:`launch` as the program to run, to open the 
result in a new kitty tab/window/etc. (:iss:`5462`)
+
+- hyperlinked_grep kitten: Allow control over which parts of ``rg`` output are 
hyperlinked (:pull:`5428`)
+
+- Fix regression in 0.26.0 that caused launching kitty without working STDIO 
handles to result in high CPU usage and prewarming failing (:iss:`5444`)
+
+- :doc:`/launch`: Allow setting the margin and padding for newly created 
windows (:iss:`5463`)
+
+- macOS: Fix regression in 0.26.0 that caused asking the user for a line of 
input such as for :ac:`set_tab_title` to not work (:iss:`5447`)
+
+- hints kitten: hyperlink matching: Fix hints occasionally matching text on 
subsequent line as part of hyperlink (:pull:`5450`)
+
+- Fix a regression in 0.26.0 that broke mapping of native keys whose key codes 
did not fit in 21 bits (:iss:`5452`)
+
+- Wayland: Fix remembering window size not accurate when client side 
decorations are present
+
+- Fix an issue where notification identifiers were not sanitized leading to
+  code execution if the user clicked on a notification popup from a malicious
+  source. Thanks to Carter Sande for discovering this vulnerability.
+
 0.26.1 [2022-08-30]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/docs/faq.rst 
new/kitty-0.26.2/docs/faq.rst
--- old/kitty-0.26.1/docs/faq.rst       2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/docs/faq.rst       2022-09-05 07:19:50.000000000 +0200
@@ -312,7 +312,11 @@
 Then press the key you want to emulate. Note that this kitten will only show
 keys that actually reach the terminal program, in particular, keys mapped to
 actions in kitty will not be shown. To check those first map them to
-:ac:`no_op`.
+:ac:`no_op`. You can also start a kitty instance without any shortcuts to
+interfere::
+
+    kitty -o clear_all_shortcuts=yes kitty +kitten show_key
+
 
 How do I open a new window or tab with the same working directory as the 
current window?
 
--------------------------------------------------------------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/docs/glossary.rst 
new/kitty-0.26.2/docs/glossary.rst
--- old/kitty-0.26.1/docs/glossary.rst  2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/docs/glossary.rst  2022-09-05 07:19:50.000000000 +0200
@@ -32,7 +32,12 @@
       top of an existing kitty window, entirely covering it. Overlays are used
       throughout kitty, for example, to display the :ref:`the scrollback 
buffer <scrollback>`,
       to display :doc:`hints </kittens/hints>`, for :doc:`unicode input
-      </kittens/unicode_input>` etc.
+      </kittens/unicode_input>` etc. Normal overlays are meant for short
+      duration popups and so are not considered the :italic:`active window`
+      when determining the current working directory or getting input text for
+      kittens, launch commands, etc. To create an overlay considered as a
+      :italic:`main window` use the :code:`overlay-main` argument to
+      :doc:`launch`.
 
    hyperlinks
       Terminals can have hyperlinks, just like the internet. In kitty you can
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/docs/kittens/hyperlinked_grep.rst 
new/kitty-0.26.2/docs/kittens/hyperlinked_grep.rst
--- old/kitty-0.26.1/docs/kittens/hyperlinked_grep.rst  2022-08-29 
21:34:42.000000000 +0200
+++ new/kitty-0.26.2/docs/kittens/hyperlinked_grep.rst  2022-09-05 
07:19:50.000000000 +0200
@@ -74,6 +74,16 @@
 To learn more about kitty's powerful framework for customizing URL click
 actions, see :doc:`here </open_actions>`.
 
+By default, this kitten adds hyperlinks for several parts of ripgrep output:
+the per-file header, match context lines, and match lines. You can control
+which items are linked with a :command:`--kitten hyperlink` flag. For example,
+:command:`--kitten hyperlink=matching_lines` will only add hyperlinks to the
+match lines. :command:`--kitten hyperlink=file_headers,context_lines` will link
+file headers and context lines but not match lines. :command:`--kitten
+hyperlink=none` will cause the command line to be passed to directly to
+:command:`rg` so no hyperlinking will be performed. :command:`--kitten
+hyperlink` may be specified multiple times.
+
 Hopefully, someday this functionality will make it into some `upstream grep
 <https://github.com/BurntSushi/ripgrep/issues/665>`__ program directly removing
 the need for this kitten.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/glfw/wl_window.c 
new/kitty-0.26.2/glfw/wl_window.c
--- old/kitty-0.26.1/glfw/wl_window.c   2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/glfw/wl_window.c   2022-09-05 07:19:50.000000000 +0200
@@ -998,7 +998,7 @@
     if (window->decorated && !window->monitor && 
!window->wl.decorations.serverSide)
     {
         if (top)
-            *top = window->wl.decorations.metrics.top;
+            *top = window->wl.decorations.metrics.top - 
window->wl.decorations.metrics.visible_titlebar_height;
         if (left)
             *left = window->wl.decorations.metrics.width;
         if (right)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kittens/ask/main.py 
new/kitty-0.26.2/kittens/ask/main.py
--- old/kitty-0.26.1/kittens/ask/main.py        2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kittens/ask/main.py        2022-09-05 07:19:50.000000000 
+0200
@@ -158,14 +158,17 @@
 
 class Password(Handler):
 
-    def __init__(self, cli_opts: AskCLIOptions, prompt: str) -> None:
+    def __init__(self, cli_opts: AskCLIOptions, prompt: str, is_password: bool 
= True, initial_text: str = '') -> None:
         self.cli_opts = cli_opts
         self.prompt = prompt
+        self.initial_text = initial_text
         from kittens.tui.line_edit import LineEdit
-        self.line_edit = LineEdit(is_password=True)
+        self.line_edit = LineEdit(is_password=is_password)
 
     def initialize(self) -> None:
         self.cmd.set_cursor_shape('beam')
+        if self.initial_text:
+            self.line_edit.on_text(self.initial_text, True)
         self.draw_screen()
 
     @Handler.atomic_update
@@ -205,7 +208,7 @@
         return ''
 
 
-class Choose(Handler):
+class Choose(Handler):  # {{{
     mouse_tracking = MouseTracking.buttons_only
 
     def __init__(self, cli_opts: AskCLIOptions) -> None:
@@ -441,6 +444,7 @@
     def on_interrupt(self) -> None:
         self.quit_loop(1)
     on_eot = on_interrupt
+# }}}
 
 
 def main(args: List[str]) -> Response:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kittens/hints/main.py 
new/kitty-0.26.2/kittens/hints/main.py
--- old/kitty-0.26.1/kittens/hints/main.py      2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kittens/hints/main.py      2022-09-05 07:19:50.000000000 
+0200
@@ -16,7 +16,7 @@
 from kitty.cli import parse_args
 from kitty.cli_stub import HintsCLIOptions
 from kitty.constants import website_url
-from kitty.fast_data_types import get_options, set_clipboard_string
+from kitty.fast_data_types import get_options, set_clipboard_string, wcswidth
 from kitty.key_encoding import KeyEvent
 from kitty.typing import BossType, KittyCommonOpts
 from kitty.utils import (
@@ -411,7 +411,10 @@
             appended = False
             for line in full_line.split('\r'):
                 if line:
-                    lines.append(line.ljust(cols, '\0'))
+                    line_sz = wcswidth(line)
+                    if line_sz < cols:
+                        line += '\0' * (cols - line_sz)
+                    lines.append(line)
                     lines.append('\r')
                     appended = True
             if appended:
@@ -536,12 +539,27 @@
 --program
 type=list
 What program to use to open matched text. Defaults to the default open program
-for the operating system. Use a value of :code:`-` to paste the match into the
-terminal window instead. A value of :code:`@` will copy the match to the
-clipboard. A value of :code:`*` will copy the match to the primary selection
-(on systems that support primary selections). A value of :code:`default` will
-run the default open program. Can be specified multiple times to run multiple
-programs.
+for the operating system. Various special values are supported:
+
+:code:`-`
+    paste the match into the terminal window.
+
+:code:`@`
+    copy the match to the clipboard
+
+:code:`*`
+    copy the match to the primary selection (on systems that support primary 
selections)
+
+:code:`default`
+    run the default open program.
+
+:code:`launch`
+    run :doc:`/launch` to open the program in a new kitty tab, window, 
overlay, etc.
+    For example::
+
+        --program "launch --type=tab vim"
+
+Can be specified multiple times to run multiple programs.
 
 
 --type
@@ -803,6 +821,7 @@
         elif program == '*':
             set_primary_selection(joined_text())
         else:
+            from kitty.conf.utils import to_cmdline
             cwd = data['cwd']
             program = get_options().open_url_with if program == 'default' else 
program
             if text_type == 'hyperlink':
@@ -811,12 +830,20 @@
                     if w is not None:
                         w.open_url(m, hyperlink_id=1, cwd=cwd)
             else:
+                launch_args = []
+                if isinstance(program, str) and program.startswith('launch '):
+                    launch_args = to_cmdline(program)
+                    launch_args.insert(1, '--cwd=' + cwd)
                 for m, groupdict in zip(matches, groupdicts):
                     if groupdict:
                         m = []
                         for k, v in groupdict.items():
                             m.append('{}={}'.format(k, v or ''))
-                    boss.open_url(m, program, cwd=cwd)
+                    if launch_args:
+                        w = boss.window_id_map.get(target_window_id)
+                        boss.call_remote_control(active_window=w, 
args=tuple(launch_args + ([m] if isinstance(m, str) else m)))
+                    else:
+                        boss.open_url(m, program, cwd=cwd)
 
 
 if __name__ == '__main__':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kittens/hyperlinked_grep/main.py 
new/kitty-0.26.2/kittens/hyperlinked_grep/main.py
--- old/kitty-0.26.1/kittens/hyperlinked_grep/main.py   2022-08-29 
21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kittens/hyperlinked_grep/main.py   2022-09-05 
07:19:50.000000000 +0200
@@ -20,7 +20,49 @@
 
 
 def main() -> None:
-    if not sys.stdout.isatty() and '--pretty' not in sys.argv and '-p' not in 
sys.argv:
+    i = 1
+    all_link_options = {'matching_lines', 'context_lines', 'file_headers'}
+    link_options = set()
+    delegate_to_rg = False
+
+    def parse_link_options(raw: str) -> None:
+        nonlocal delegate_to_rg
+        if not raw:
+            raise SystemExit('Must specify an argument for --kitten option')
+        p, _, s = raw.partition('=')
+        if p != 'hyperlink':
+            raise SystemExit(f'Unknown argument for --kitten: {raw}')
+        for option in s.split(','):
+            if option == 'all':
+                link_options.update(all_link_options)
+                delegate_to_rg = False
+            elif option == 'none':
+                delegate_to_rg = True
+                link_options.clear()
+            elif option not in all_link_options:
+                a = ', '.join(sorted(all_link_options))
+                raise SystemExit(f"hyperlink option must be one of all, none, 
{a}, not '{option}'")
+            else:
+                link_options.add(option)
+                delegate_to_rg = False
+
+    while i < len(sys.argv):
+        if sys.argv[i] == '--kitten':
+            next_item = '' if i + 1 >= len(sys.argv) else sys.argv[i + 1]
+            parse_link_options(next_item)
+            del sys.argv[i:i+2]
+        elif sys.argv[i].startswith('--kitten='):
+            parse_link_options(sys.argv[i][len('--kitten='):])
+            del sys.argv[i]
+        else:
+            i += 1
+    if not link_options:  # Default to linking everything if no options given
+        link_options.update(all_link_options)
+    link_file_headers = 'file_headers' in link_options
+    link_context_lines = 'context_lines' in link_options
+    link_matching_lines = 'matching_lines' in link_options
+
+    if delegate_to_rg or (not sys.stdout.isatty() and '--pretty' not in 
sys.argv and '-p' not in sys.argv):
         os.execlp('rg', 'rg', *sys.argv[1:])
     cmdline = ['rg', '--pretty', '--with-filename'] + sys.argv[1:]
     try:
@@ -31,7 +73,7 @@
     write: Callable[[bytes], None] = cast(Callable[[bytes], None], 
sys.stdout.buffer.write)
     sgr_pat = re.compile(br'\x1b\[.*?m')
     osc_pat = re.compile(b'\x1b\\].*?\x1b\\\\')
-    num_pat = re.compile(br'^(\d+)[:-]')
+    num_pat = re.compile(br'^(\d+)([:-])')
 
     in_result: bytes = b''
     hostname = socket.gethostname().encode('utf-8')
@@ -43,20 +85,22 @@
             if not clean_line:
                 in_result = b''
                 write(b'\n')
-                continue
-            if in_result:
+            elif in_result:
                 m = num_pat.match(clean_line)
                 if m is not None:
-                    write_hyperlink(write, in_result, line, frag=m.group(1))
-                else:
-                    write(line)
+                    is_match_line = m.group(2) == b':'
+                    if (is_match_line and link_matching_lines) or (not 
is_match_line and link_context_lines):
+                        write_hyperlink(write, in_result, line, 
frag=m.group(1))
+                        continue
+                write(line)
             else:
                 if line.strip():
                     path = 
quote_from_bytes(os.path.abspath(clean_line)).encode('utf-8')
                     in_result = b'file://' + hostname + path
-                    write_hyperlink(write, in_result, line)
-                else:
-                    write(line)
+                    if link_file_headers:
+                        write_hyperlink(write, in_result, line)
+                        continue
+                write(line)
     except KeyboardInterrupt:
         p.send_signal(signal.SIGINT)
     except (EOFError, BrokenPipeError):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kittens/remote_file/main.py 
new/kitty-0.26.2/kittens/remote_file/main.py
--- old/kitty-0.26.1/kittens/remote_file/main.py        2022-08-29 
21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kittens/remote_file/main.py        2022-09-05 
07:19:50.000000000 +0200
@@ -273,9 +273,9 @@
     )
     print('Relative paths will be resolved from:', styled(os.getcwd(), 
fg_intense=True, bold=True))
     print()
-    from ..tui.path_completer import PathCompleter
+    from ..tui.path_completer import get_path
     try:
-        dest = PathCompleter().input()
+        dest = get_path()
     except (KeyboardInterrupt, EOFError):
         return
     if dest:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kittens/tui/handler.py 
new/kitty-0.26.2/kittens/tui/handler.py
--- old/kitty-0.26.1/kittens/tui/handler.py     2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kittens/tui/handler.py     2022-09-05 07:19:50.000000000 
+0200
@@ -121,11 +121,22 @@
         self._tui_loop.quit(1)
 
     def on_key_event(self, key_event: KeyEventType, in_bracketed_paste: bool = 
False) -> None:
+        ' Override this method and perform_default_key_action() to handle all 
key events '
         if key_event.text:
             self.on_text(key_event.text, in_bracketed_paste)
         else:
             self.on_key(key_event)
 
+    def perform_default_key_action(self, key_event: KeyEventType) -> bool:
+        ' Override in sub-class if you want to handle these key events 
yourself '
+        if key_event.matches('ctrl+c'):
+            self.on_interrupt()
+            return True
+        if key_event.matches('ctrl+d'):
+            self.on_eot()
+            return True
+        return False
+
     def on_text(self, text: str, in_bracketed_paste: bool = False) -> None:
         pass
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kittens/tui/loop.py 
new/kitty-0.26.2/kittens/tui/loop.py
--- old/kitty-0.26.1/kittens/tui/loop.py        2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kittens/tui/loop.py        2022-09-05 07:19:50.000000000 
+0200
@@ -330,13 +330,8 @@
             except Exception:
                 pass
             else:
-                if k.matches('ctrl+c'):
-                    self.handler.on_interrupt()
-                    return
-                if k.matches('ctrl+d'):
-                    self.handler.on_eot()
-                    return
-                self.handler.on_key_event(k)
+                if not self.handler.perform_default_key_action(k):
+                    self.handler.on_key_event(k)
 
     def _on_pm(self, pm: str) -> None:
         pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kittens/tui/path_completer.py 
new/kitty-0.26.2/kittens/tui/path_completer.py
--- old/kitty-0.26.1/kittens/tui/path_completer.py      2022-08-29 
21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kittens/tui/path_completer.py      2022-09-05 
07:19:50.000000000 +0200
@@ -147,5 +147,9 @@
         return ''
 
 
+def get_path(prompt: str = '> ') -> str:
+    return PathCompleter(prompt).input()
+
+
 def develop() -> None:
     PathCompleter().input()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/boss.py 
new/kitty-0.26.2/kitty/boss.py
--- old/kitty-0.26.1/kitty/boss.py      2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/boss.py      2022-09-05 07:19:50.000000000 +0200
@@ -1702,7 +1702,10 @@
                 if actions:
                     self.drain_actions(actions)
         if not found_action:
-            open_url(url, program or get_options().open_url_with, cwd=cwd)
+            extra_env = {}
+            if self.listening_on:
+                extra_env['KITTY_LISTEN_ON'] = self.listening_on
+            open_url(url, program or get_options().open_url_with, cwd=cwd, 
extra_env=extra_env)
 
     @ac('misc', 'Click a URL using the keyboard')
     def open_url_with_hints(self) -> None:
@@ -2414,8 +2417,11 @@
     @ac('debug', 'Show the environment variables that the kitty process sees')
     def show_kitty_env_vars(self) -> None:
         w = self.active_window
+        env = os.environ.copy()
+        if is_macos and env.get('LC_CTYPE') == 'UTF-8' and not getattr(sys, 
'kitty_run_data').get('lc_ctype_before_python'):
+            del env['LC_CTYPE']
         if w:
-            output = '\n'.join(f'{k}={v}' for k, v in os.environ.items())
+            output = '\n'.join(f'{k}={v}' for k, v in env.items())
             self.display_scrollback(w, output, title=_('Current kitty env 
vars'), report_cursor=False)
 
     @ac('debug', '''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/child-monitor.c 
new/kitty-0.26.2/kitty/child-monitor.c
--- old/kitty-0.26.1/kitty/child-monitor.c      2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty/child-monitor.c      2022-09-05 07:19:50.000000000 
+0200
@@ -974,7 +974,7 @@
 
 static void
 close_os_window(ChildMonitor *self, OSWindow *os_window) {
-    int w = os_window->window_width, h = os_window->window_height;
+    int w = os_window->content_area_width, h = os_window->content_area_height;
     if (os_window->before_fullscreen.is_set && 
is_os_window_fullscreen(os_window)) {
         w = os_window->before_fullscreen.w; h = os_window->before_fullscreen.h;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/child.c 
new/kitty-0.26.2/kitty/child.c
--- old/kitty-0.26.1/kitty/child.c      2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/child.c      2022-09-05 07:19:50.000000000 +0200
@@ -181,8 +181,26 @@
     return PyLong_FromLong(pid);
 }
 
+#ifdef __APPLE__
+#include <crt_externs.h>
+#else
+extern char **environ;
+#endif
+
+static PyObject*
+clearenv_py(PyObject *self UNUSED, PyObject *args UNUSED) {
+#ifdef __APPLE__
+    char **e = *_NSGetEnviron();
+    if (e) *e = NULL;
+#else
+    if (environ) *environ = NULL;
+#endif
+    Py_RETURN_NONE;
+}
+
 static PyMethodDef module_methods[] = {
     METHODB(spawn, METH_VARARGS),
+    {"clearenv", clearenv_py, METH_NOARGS, ""},
     {NULL, NULL, 0, NULL}        /* Sentinel */
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/child.py 
new/kitty-0.26.2/kitty/child.py
--- old/kitty-0.26.1/kitty/child.py     2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/child.py     2022-09-05 07:19:50.000000000 +0200
@@ -169,7 +169,7 @@
 
 
 def set_LANG_in_default_env(val: str) -> None:
-    default_env()['LANG'] = val
+    default_env().setdefault('LANG', val)
 
 
 def openpty() -> Tuple[int, int]:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/cli.py 
new/kitty-0.26.2/kitty/cli.py
--- old/kitty-0.26.1/kitty/cli.py       2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/cli.py       2022-09-05 07:19:50.000000000 +0200
@@ -187,6 +187,7 @@
 def ref_hyperlink(x: str, prefix: str = '') -> str:
     t, q = text_and_target(x)
     url = f'kitty+doc://{hostname()}/#ref={prefix}{q}'
+    t = re.sub(r':([a-z]+):`([^`]+)`', r'\2', t)
     return hyperlink_for_url(url, t)
 
 
@@ -293,7 +294,7 @@
             else:
                 prev_indent = 0
                 if prev_line:
-                    current_cmd['help'] += '\n\n'
+                    current_cmd['help'] += '\n' if 
current_cmd['help'].endswith('::') else '\n\n'
                 else:
                     state = NORMAL
                     (seq if current_cmd.get('condition', True) else 
disabled).append(current_cmd)
@@ -429,6 +430,8 @@
         a('{}: {} {}{}'.format(title('Usage'), bold(yellow(appname)), 
optstring, usage))
         a('')
         message = message or default_msg
+        # replace rst literal code block syntax
+        message = message.replace('::\n\n', ':\n\n')
         wa(prettify(message))
         a('')
         if seq:
@@ -448,6 +451,8 @@
                     blocks[-1] += dt
             if opt.get('help'):
                 t = help_text.replace('%default', str(defval)).strip()
+                # replace rst literal code block syntax
+                t = t.replace('::\n\n', ':\n\n')
                 t = t.replace('#placeholder_for_formatting#', '')
                 wa(prettify(t), indent=4)
                 if opt.get('choices'):
@@ -801,6 +806,7 @@
 Replay previously dumped commands. Specify the path to a dump file previously
 created by :option:`{appname} --dump-commands`. You
 can open a new kitty window to replay the commands with::
+
     {appname} sh -c "{appname} --replay-commands /path/to/dump/file; read"
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/constants.py 
new/kitty-0.26.2/kitty/constants.py
--- old/kitty-0.26.1/kitty/constants.py 2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/constants.py 2022-09-05 07:19:50.000000000 +0200
@@ -22,7 +22,7 @@
 
 appname: str = 'kitty'
 kitty_face = '????'
-version: Version = Version(0, 26, 1)
+version: Version = Version(0, 26, 2)
 str_version: str = '.'.join(map(str, version))
 _plat = sys.platform.lower()
 is_macos: bool = 'darwin' in _plat
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/fast_data_types.pyi 
new/kitty-0.26.2/kitty/fast_data_types.pyi
--- old/kitty-0.26.1/kitty/fast_data_types.pyi  2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty/fast_data_types.pyi  2022-09-05 07:19:50.000000000 
+0200
@@ -1485,3 +1485,4 @@
 
 def set_use_os_log(yes: bool) -> None: ...
 def get_docs_ref_map() -> bytes: ...
+def clearenv() -> None: ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/glfw.c 
new/kitty-0.26.2/kitty/glfw.c
--- old/kitty-0.26.1/kitty/glfw.c       2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/glfw.c       2022-09-05 07:19:50.000000000 +0200
@@ -97,6 +97,22 @@
 }
 
 
+static void
+adjust_window_size_for_csd(OSWindow *w, int width, int height, int 
*adjusted_width, int *adjusted_height) {
+    *adjusted_width = width; *adjusted_height = height;
+    if (global_state.is_wayland) {
+        int left = -1, top, right, bottom;
+        glfwGetWindowFrameSize(w->handle, &left, &top, &right, &bottom);
+        if (left > -1) {
+            *adjusted_width -= left + right;
+            *adjusted_height -= top + bottom;
+            *adjusted_width = MAX(0, *adjusted_width);
+            *adjusted_height = MAX(0, *adjusted_height);
+        }
+    }
+}
+
+
 void
 update_os_window_viewport(OSWindow *window, bool notify_boss) {
     int w, h, fw, fh;
@@ -135,6 +151,7 @@
     window->viewport_height = MAX(window->viewport_height, min_height);
     window->window_width = MAX(w, min_width);
     window->window_height = MAX(h, min_height);
+    adjust_window_size_for_csd(window, window->window_width, 
window->window_height, &window->content_area_width, 
&window->content_area_height);
     if (notify_boss) {
         call_boss(on_window_resize, "KiiO", window->id, 
window->viewport_width, window->viewport_height, dpi_changed ? Py_True : 
Py_False);
     }
@@ -652,13 +669,14 @@
 
 static bool
 do_toggle_fullscreen(OSWindow *w, unsigned int flags, bool restore_sizes) {
-    int width, height, x, y;
+    int width, height, x, y, content_area_width, content_area_height;
     glfwGetWindowSize(w->handle, &width, &height);
     glfwGetWindowPos(w->handle, &x, &y);
+    adjust_window_size_for_csd(w, width, height, &content_area_width, 
&content_area_height);
     bool was_maximized = glfwGetWindowAttrib(w->handle, GLFW_MAXIMIZED);
     if (glfwToggleFullscreen(w->handle, flags)) {
         w->before_fullscreen.is_set = true;
-        w->before_fullscreen.w = width; w->before_fullscreen.h = height; 
w->before_fullscreen.x = x; w->before_fullscreen.y = y;
+        w->before_fullscreen.w = content_area_width; w->before_fullscreen.h = 
content_area_height; w->before_fullscreen.x = x; w->before_fullscreen.y = y;
         w->before_fullscreen.was_maximized = was_maximized;
         return true;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/keys.c 
new/kitty-0.26.2/kitty/keys.c
--- old/kitty-0.26.1/kitty/keys.c       2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/keys.c       2022-09-05 07:19:50.000000000 +0200
@@ -284,9 +284,9 @@
 };
 
 // SingleKey {{{
-typedef uint32_t keybitfield;
-#define KEY_BITS 21
-#define MOD_BITS 10
+typedef uint64_t keybitfield;
+#define KEY_BITS 51
+#define MOD_BITS 12
 #if 1 << (MOD_BITS-1) < GLFW_MOD_KITTY
 #error "Not enough mod bits"
 #endif
@@ -309,9 +309,9 @@
 } SingleKey;
 
 static inline void
-SingleKey_set_vals(SingleKey *self, long key, unsigned short mods, int 
is_native) {
-    if (key >= 0 && (unsigned long)key <= BIT_MASK(keybitfield, KEY_BITS)) {
-        keybitfield k = (keybitfield)(unsigned long)key;
+SingleKey_set_vals(SingleKey *self, long long key, unsigned short mods, int 
is_native) {
+    if (key >= 0 && (unsigned long long)key <= BIT_MASK(keybitfield, 
KEY_BITS)) {
+        keybitfield k = (keybitfield)(unsigned long long)key;
         self->key.key = k & BIT_MASK(keybitfield, KEY_BITS);
     }
     if (!(mods & 1 << (MOD_BITS + 1))) self->key.mods = mods & 
BIT_MASK(u_int32_t, MOD_BITS);
@@ -320,8 +320,8 @@
 
 static PyObject *
 SingleKey_new(PyTypeObject *type, PyObject *args, PyObject *kw) {
-    long key = -1; unsigned short mods = 1 << (MOD_BITS + 1); int is_native = 
-1;
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "|Hpl", SingleKey_kwds, &mods, 
&is_native, &key)) return NULL;
+    long long key = -1; unsigned short mods = 1 << (MOD_BITS + 1); int 
is_native = -1;
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|HpL", SingleKey_kwds, &mods, 
&is_native, &key)) return NULL;
     SingleKey *self = (SingleKey *)type->tp_alloc(type, 0);
     if (self) SingleKey_set_vals(self, key, mods, is_native);
     return (PyObject*)self;
@@ -341,8 +341,8 @@
     unsigned int mods = self->key.mods;
     if (mods) pos += PyOS_snprintf(buf + pos, sizeof(buf) - pos, "mods=%u, ", 
mods);
     if (self->key.is_native) pos += PyOS_snprintf(buf + pos, sizeof(buf) - 
pos, "is_native=True, ");
-    unsigned long key = self->key.key;
-    if (key) pos += PyOS_snprintf(buf + pos, sizeof(buf) - pos, "key=%lu, ", 
key);
+    unsigned long long key = self->key.key;
+    if (key) pos += PyOS_snprintf(buf + pos, sizeof(buf) - pos, "key=%llu, ", 
key);
     if (buf[pos-1] == ' ') pos -= 2;
     pos += PyOS_snprintf(buf + pos, sizeof(buf) - pos, ")");
     return PyUnicode_FromString(buf);
@@ -350,8 +350,8 @@
 
 static PyObject*
 SingleKey_get_key(SingleKey *self, void UNUSED *closure) {
-    const unsigned long val = self->key.key;
-    return PyLong_FromUnsignedLong(val);
+    const unsigned long long val = self->key.key;
+    return PyLong_FromUnsignedLongLong(val);
 }
 
 static PyObject*
@@ -436,8 +436,8 @@
 
 static PyObject*
 SingleKey_replace(SingleKey *self, PyObject *args, PyObject *kw) {
-    long key = -2; unsigned short mods = 1 << (MOD_BITS + 1); int is_native = 
-1;
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "|Hpl", SingleKey_kwds, &mods, 
&is_native, &key)) return NULL;
+    long long key = -2; unsigned short mods = 1 << (MOD_BITS + 1); int 
is_native = -1;
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|HpL", SingleKey_kwds, &mods, 
&is_native, &key)) return NULL;
     SingleKey *ans = (SingleKey*)SingleKey_Type.tp_alloc(&SingleKey_Type, 0);
     if (ans) {
         if (key == -1) key = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/launch.py 
new/kitty-0.26.2/kitty/launch.py
--- old/kitty-0.26.1/kitty/launch.py    2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/launch.py    2022-09-05 07:19:50.000000000 +0200
@@ -21,7 +21,7 @@
 )
 from .options.utils import env as parse_env
 from .tabs import Tab, TabManager
-from .types import run_once
+from .types import OverlayType, run_once
 from .utils import (
     get_editor, log_error, resolve_custom_file, set_primary_selection, which
 )
@@ -56,7 +56,7 @@
 --type
 type=choices
 default=window
-choices=window,tab,os-window,overlay,background,clipboard,primary
+choices=window,tab,os-window,overlay,overlay-main,background,clipboard,primary
 Where to launch the child process:
 
 :code:`window`
@@ -71,6 +71,13 @@
 :code:`overlay`
     An :term:`overlay window <overlay>` covering the current active kitty 
window
 
+:code:`overlay-main`
+    An :term:`overlay window <overlay>` covering the current active kitty 
window.
+    Unlike a plain overlay window, this window is considered as a 
:italic:`main`
+    window which means it is used as the active window for getting the current 
working
+    directory, the input text for kittens, launch commands, etc. Useful if 
this overlay is
+    intended to run for a long time as a primary window.
+
 :code:`background`
     The process will be run in the :italic:`background`, without a kitty 
window.
 
@@ -165,12 +172,14 @@
 Restrict the actions remote control is allowed to take. This works like
 :opt:`remote_control_password`. You can specify a password and list of actions
 just as for :opt:`remote_control_password`. For example::
+
     --remote-control-password '"my passphrase" get-* set-colors'
 
 This password will be in effect for this window only.
 Note that any passwords you have defined for :opt:`remote_control_password`
 in :file:`kitty.conf` are also in effect. You can override them by using the 
same password here.
 You can also disable all :opt:`remote_control_password` global passwords for 
this window, by using::
+
     --remote-control-password '!'
 
 This option only takes effect if :option:`--allow-remote-control`
@@ -271,8 +280,17 @@
 type=list
 Change colors in the newly launched window. You can either specify a path to a
 :file:`.conf` file with the same syntax as :file:`kitty.conf` to read the 
colors
-from, or specify them individually, for example: :code:`--color 
background=white
---color foreground=red`.
+from, or specify them individually, for example::
+
+    --color background=white --color foreground=red
+
+
+--spacing
+type=list
+Set the margin and padding for the newly created window.
+For example: :code:`margin=20` or :code:`padding-left=10` or 
:code:`margin-h=30`. The shorthand form sets
+all values, the :code:`*-h` and :code:`*-v` variants set horizontal and 
vertical values.
+Can be specified multiple times.
 
 
 --watcher -w
@@ -454,6 +472,10 @@
         'overlay_for': None,
         'stdin': None
     }
+    spacing = {}
+    if opts.spacing:
+        from .rc.set_spacing import parse_spacing_settings, patch_window_edges
+        spacing = parse_spacing_settings(opts.spacing)
     if opts.cwd:
         if opts.cwd == 'current':
             if active:
@@ -524,7 +546,7 @@
         kw['cmd'] = final_cmd
     if force_window_launch and opts.type not in non_window_launch_types:
         opts.type = 'window'
-    if opts.type == 'overlay' and active:
+    if opts.type in ('overlay', 'overlay-main') and active:
         kw['overlay_for'] = active.id
     if opts.type == 'background':
         cmd = kw['cmd']
@@ -549,12 +571,17 @@
         if tab is not None:
             watchers = load_watch_modules(opts.watcher)
             new_window: Window = tab.new_window(env=env or None, 
watchers=watchers or None, is_clone_launch=is_clone_launch, **kw)
+            if spacing:
+                patch_window_edges(new_window, spacing)
+                tab.relayout()
             if opts.color:
                 apply_colors(new_window, opts.color)
             if opts.keep_focus and active:
                 boss.set_active_window(active, 
switch_os_window_if_needed=True, for_keep_focus=True)
             if opts.logo:
                 new_window.set_logo(opts.logo, opts.logo_position or '', 
opts.logo_alpha)
+            if opts.type == 'overlay-main':
+                new_window.overlay_type = OverlayType.main
             return new_window
     return None
 
@@ -564,7 +591,7 @@
     return frozenset((
         'window_title', 'tab_title', 'type', 'keep_focus', 'cwd', 'env', 
'hold',
         'location', 'os_window_class', 'os_window_name', 'os_window_title',
-        'logo', 'logo_position', 'logo_alpha', 'color'
+        'logo', 'logo_position', 'logo_alpha', 'color', 'spacing',
     ))
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/launcher/main.c 
new/kitty-0.26.2/kitty/launcher/main.c
--- old/kitty-0.26.1/kitty/launcher/main.c      2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty/launcher/main.c      2022-09-05 07:19:50.000000000 
+0200
@@ -17,6 +17,7 @@
 #include <stdint.h>
 #include <wchar.h>
 #include <Python.h>
+#include <fcntl.h>
 
 #ifndef KITTY_LIB_PATH
 #define KITTY_LIB_PATH "../.."
@@ -268,9 +269,55 @@
 }
 #endif // }}}
 
+static bool
+is_valid_fd(int fd)
+{
+    // This is copied from the python source code as we need the exact same 
semantics
+    // to prevent python from giving us None for sys.stdout and friends.
+#if defined(F_GETFD) && ( \
+        defined(__linux__) || \
+        defined(__APPLE__) || \
+        defined(__wasm__))
+    return fcntl(fd, F_GETFD) >= 0;
+#elif defined(__linux__)
+    int fd2 = dup(fd);
+    if (fd2 >= 0) {
+        close(fd2);
+    }
+    return (fd2 >= 0);
+#else
+    struct stat st;
+    return (fstat(fd, &st) == 0);
+#endif
+}
+
+static bool
+reopen_to_null(const char *mode, FILE *stream) {
+    errno = 0;
+    while (true) {
+        if (freopen("/dev/null", mode, stream) != NULL) return true;
+        if (errno == EINTR) continue;
+        perror("Failed to re-open STDIO handle to /dev/null");
+        return false;
+    }
+}
+
+static bool
+ensure_working_stdio(void) {
+#define C(which, mode) { \
+    int fd = fileno(which); \
+    if (fd < 0) { if (!reopen_to_null(mode, which)) return false; } \
+    else if (!is_valid_fd(fd)) { \
+        close(fd); if (!reopen_to_null(mode, which)) return false; \
+    }}
+    C(stdin, "r") C(stdout, "w") C(stderr, "w")
+    return true;
+#undef C
+}
 
 int main(int argc, char *argv[], char* envp[]) {
     if (argc < 1 || !argv) { fprintf(stderr, "Invalid argc/argv\n"); return 1; 
}
+    if (!ensure_working_stdio()) return 1;
     char exe[PATH_MAX+1] = {0};
     char exe_dir_buf[PATH_MAX+1] = {0};
     FREE_AFTER_FUNCTION const char *lc_ctype = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/main.py 
new/kitty-0.26.2/kitty/main.py
--- old/kitty-0.26.1/kitty/main.py      2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/main.py      2022-09-05 07:19:50.000000000 +0200
@@ -379,6 +379,7 @@
     if is_macos and os.environ.pop('KITTY_LAUNCHED_BY_LAUNCH_SERVICES', None) 
== '1':
         os.chdir(os.path.expanduser('~'))
         args = macos_cmdline(args)
+        getattr(sys, 'kitty_run_data')['launched_by_launch_services'] = True
     try:
         cwd_ok = os.path.isdir(os.getcwd())
     except Exception:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/notify.py 
new/kitty-0.26.2/kitty/notify.py
--- old/kitty-0.26.1/kitty/notify.py    2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/notify.py    2022-09-05 07:19:50.000000000 +0200
@@ -1,13 +1,15 @@
 #!/usr/bin/env python3
 # License: GPLv3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
 
+import re
 from base64 import standard_b64decode
 from collections import OrderedDict
 from itertools import count
-from typing import Dict, Optional, Callable
+from typing import Callable, Dict, Optional
 
 from .constants import is_macos, logo_png_file
 from .fast_data_types import get_boss
+from .types import run_once
 from .utils import log_error
 
 NotifyImplementation = Callable[[str, str, str], None]
@@ -92,6 +94,11 @@
     return ans
 
 
+@run_once
+def sanitize_identifier_pat() -> 're.Pattern[str]':
+    return re.compile(r'[^a-zA-Z0-9-_+.]+')
+
+
 def parse_osc_99(raw: str) -> NotificationCommand:
     cmd = NotificationCommand()
     metadata, payload = raw.partition(';')[::2]
@@ -107,7 +114,7 @@
             if k == 'p':
                 payload_type = v
             elif k == 'i':
-                cmd.identifier = v
+                cmd.identifier = sanitize_identifier_pat().sub('', v)
             elif k == 'e':
                 payload_is_encoded = v == '1'
             elif k == 'd':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/prewarm.py 
new/kitty-0.26.2/kitty/prewarm.py
--- old/kitty-0.26.1/kitty/prewarm.py   2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/prewarm.py   2022-09-05 07:19:50.000000000 +0200
@@ -24,9 +24,9 @@
 from kitty.constants import kitty_exe, running_in_kitty
 from kitty.entry_points import main as main_entry_point
 from kitty.fast_data_types import (
-    CLD_EXITED, CLD_KILLED, CLD_STOPPED, get_options, install_signal_handlers,
-    read_signals, remove_signal_handlers, safe_pipe, set_options,
-    set_use_os_log
+    CLD_EXITED, CLD_KILLED, CLD_STOPPED, clearenv, get_options,
+    install_signal_handlers, read_signals, remove_signal_handlers, safe_pipe,
+    set_options, set_use_os_log
 )
 from kitty.options.types import Options
 from kitty.shm import SharedMemory
@@ -293,6 +293,13 @@
     env = cmd.get('env')
     if env is not None:
         os.environ.clear()
+        # os.environ.clear() does not delete all existing env vars from the
+        # libc environ pointer in some circumstances, I havent figured out
+        # which exactly. Presumably there is something that alters the
+        # libc environ pointer?? The environ pointer is used by os.exec and
+        # therefore by subprocess and friends, so we need to ensure it is
+        # cleared.
+        clearenv()
         os.environ.update(env)
     argv = cmd.get('argv')
     if argv:
@@ -567,8 +574,9 @@
     os.set_inheritable(stdout_write, False)
     os.set_inheritable(death_notify_write, False)
     running_in_kitty(False)
-    if not sys.stdout.line_buffering:  # happens if the parent kitty instance 
has stdout not pointing to a terminal
-        sys.stdout.reconfigure(line_buffering=True)  # type: ignore
+    for x in (sys.stdout, sys.stdin, sys.stderr):
+        if not x.line_buffering:  # happens if the parent kitty instance has 
stdout not pointing to a terminal
+            x.reconfigure(line_buffering=True)  # type: ignore
     try:
         main(stdin_read, stdout_write, death_notify_write)
     finally:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/rc/launch.py 
new/kitty-0.26.2/kitty/rc/launch.py
--- old/kitty-0.26.1/kitty/rc/launch.py 2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/rc/launch.py 2022-09-05 07:19:50.000000000 +0200
@@ -41,6 +41,7 @@
         @first_cmd_output_on_screen.@last_cmd_output.@last_visited_cmd_output: 
Where to get stdin for the process from
     stdin_add_formatting/bool: Boolean indicating whether to add formatting 
codes to stdin
     stdin_add_line_wrap_markers/bool: Boolean indicating whether to add line 
wrap markers to stdin
+    spacing/list.str: A list of spacing specifications, see the docs for the 
set-spacing command
     no_response/bool: Boolean indicating whether to send back the window id
     marker/str: Specification for marker for new window, for example: "text 1 
ERROR"
     logo/str: Path to window logo
@@ -53,8 +54,8 @@
     desc = (
         'Prints out the id of the newly opened window. Any command line 
arguments'
         ' are assumed to be the command line used to run in the new window, if 
none'
-        ' are provided, the default shell is run. For example:\n'
-        ':code:`kitty @ launch --title=Email mutt`'
+        ' are provided, the default shell is run. For example::\n\n'
+        '    kitty @ launch --title=Email mutt'
     )
     options_spec = MATCH_TAB_OPTION + '\n\n' + '''\
 --no-response
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/rc/new_window.py 
new/kitty-0.26.2/kitty/rc/new_window.py
--- old/kitty-0.26.1/kitty/rc/new_window.py     2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty/rc/new_window.py     2022-09-05 07:19:50.000000000 
+0200
@@ -34,8 +34,8 @@
         ' Prints out the id of the newly opened window'
         ' (unless :option:`--no-response` is used). Any command line arguments'
         ' are assumed to be the command line used to run in the new window, if 
none'
-        ' are provided, the default shell is run. For example:\n'
-        ':code:`kitty @ new-window --title Email mutt`'
+        ' are provided, the default shell is run. For example::\n\n'
+        '    kitty @ new-window --title Email mutt'
     )
     options_spec = MATCH_TAB_OPTION + '''\n
 --title
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/rc/set_background_opacity.py 
new/kitty-0.26.2/kitty/rc/set_background_opacity.py
--- old/kitty-0.26.1/kitty/rc/set_background_opacity.py 2022-08-29 
21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/rc/set_background_opacity.py 2022-09-05 
07:19:50.000000000 +0200
@@ -27,7 +27,8 @@
     desc = (
         'Set the background opacity for the specified windows. This will only 
work if you have turned on'
         ' :opt:`dynamic_background_opacity` in :file:`kitty.conf`. The 
background opacity affects all kitty windows in a'
-        ' single OS window. For example: :code:`kitty @ set-background-opacity 
0.5`'
+        ' single OS window. For example::\n\n'
+        '    kitty @ set-background-opacity 0.5'
     )
     options_spec = '''\
 --all -a
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/rc/set_colors.py 
new/kitty-0.26.2/kitty/rc/set_colors.py
--- old/kitty-0.26.1/kitty/rc/set_colors.py     2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty/rc/set_colors.py     2022-09-05 07:19:50.000000000 
+0200
@@ -68,7 +68,8 @@
         'Set the terminal colors for the specified windows/tabs (defaults to 
active window).'
         ' You can either specify the path to a conf file'
         ' (in the same format as :file:`kitty.conf`) to read the colors from 
or you can specify individual colors,'
-        ' for example: :code:`kitty @ set-colors foreground=red 
background=white`'
+        ' for example::\n\n'
+        '    kitty @ set-colors foreground=red background=white'
     )
     options_spec = '''\
 --all -a
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/rc/set_spacing.py 
new/kitty-0.26.2/kitty/rc/set_spacing.py
--- old/kitty-0.26.1/kitty/rc/set_spacing.py    2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty/rc/set_spacing.py    2022-09-05 07:19:50.000000000 
+0200
@@ -2,7 +2,7 @@
 # License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
 
 
-from typing import TYPE_CHECKING, Dict, Optional, List
+from typing import TYPE_CHECKING, Dict, Iterable, List, Optional
 
 from .base import (
     MATCH_TAB_OPTION, MATCH_WINDOW_OPTION, ArgsType, Boss, PayloadGetType,
@@ -37,6 +37,34 @@
         setattr(opts, q, new_edges)
 
 
+def parse_spacing_settings(args: Iterable[str]) -> Dict[str, Optional[float]]:
+    mapper: Dict[str, List[str]] = {}
+    for q in ('margin', 'padding'):
+        mapper[q] = f'{q}-left {q}-top {q}-right {q}-bottom'.split()
+        mapper[f'{q}-h'] = mapper[f'{q}-horizontal'] = f'{q}-left 
{q}-right'.split()
+        mapper[f'{q}-v'] = mapper[f'{q}-vertical'] = f'{q}-top 
{q}-bottom'.split()
+        for edge in ('left', 'top', 'right', 'bottom'):
+            mapper[f'{q}-{edge}'] = [f'{q}-{edge}']
+    settings: Dict[str, Optional[float]] = {}
+    for spec in args:
+        parts = spec.split('=', 1)
+        if len(parts) != 2:
+            raise ValueError(f'{spec} is not a valid setting')
+        which = mapper.get(parts[0].lower())
+        if not which:
+            raise ValueError(f'{parts[0]} is not a valid edge specification')
+        if parts[1].lower() == 'default':
+            val = None
+        else:
+            try:
+                val = float(parts[1])
+            except Exception:
+                raise ValueError(f'{parts[1]} is not a number')
+        for q in which:
+            settings[q] = val
+    return settings
+
+
 class SetSpacing(RemoteCommand):
 
     '''
@@ -70,32 +98,12 @@
     argspec = 'MARGIN_OR_PADDING ...'
 
     def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', 
args: ArgsType) -> PayloadType:
-        settings: Dict[str, Optional[float]] = {}
-        mapper: Dict[str, List[str]] = {}
-        for q in ('margin', 'padding'):
-            mapper[q] = f'{q}-left {q}-top {q}-right {q}-bottom'.split()
-            mapper[f'{q}-h'] = mapper[f'{q}-horizontal'] = f'{q}-left 
{q}-right'.split()
-            mapper[f'{q}-v'] = mapper[f'{q}-vertical'] = f'{q}-top 
{q}-bottom'.split()
-            for edge in ('left', 'top', 'right', 'bottom'):
-                mapper[f'{q}-{edge}'] = [f'{q}-{edge}']
         if not args:
             self.fatal('At least one setting must be specified')
-        for spec in args:
-            parts = spec.split('=', 1)
-            if len(parts) != 2:
-                self.fatal(f'{spec} is not a valid setting')
-            which = mapper.get(parts[0].lower())
-            if not which:
-                self.fatal(f'{parts[0]} is not a valid edge specification')
-            if parts[1].lower() == 'default':
-                val = None
-            else:
-                try:
-                    val = float(parts[1])
-                except Exception:
-                    self.fatal(f'{parts[1]} is not a number')
-            for q in which:
-                settings[q] = val
+        try:
+            settings = parse_spacing_settings(args)
+        except Exception as e:
+            self.fatal(str(e))
         ans = {
             'match_window': opts.match, 'match_tab': opts.match_tab,
             'all': opts.all, 'configured': opts.configured,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/shell.py 
new/kitty-0.26.2/kitty/shell.py
--- old/kitty-0.26.1/kitty/shell.py     2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/shell.py     2022-09-05 07:19:50.000000000 +0200
@@ -2,7 +2,6 @@
 # License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
 
 import os
-import readline
 import shlex
 import sys
 import traceback
@@ -39,6 +38,7 @@
 
 @run_once
 def init_readline() -> None:
+    import readline
     global is_libedit
     with suppress(OSError):
         readline.read_init_file()
@@ -90,6 +90,7 @@
         self.history_path = os.path.join(ddir, 'shell.history')
 
     def complete(self, text: str, state: int) -> Optional[str]:
+        import readline
         if state == 0:
             line = readline.get_line_buffer()
             cmdline = shlex.split(line)
@@ -102,6 +103,7 @@
         return None
 
     def __enter__(self) -> 'Completer':
+        import readline
         with suppress(Exception):
             readline.read_history_file(self.history_path)
         readline.set_completer(self.complete)
@@ -110,6 +112,7 @@
         return self
 
     def __exit__(self, *a: Any) -> None:
+        import readline
         readline.write_history_file(self.history_path)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/state.h 
new/kitty-0.26.2/kitty/state.h
--- old/kitty-0.26.1/kitty/state.h      2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/state.h      2022-09-05 07:19:50.000000000 +0200
@@ -188,7 +188,7 @@
         int x, y, w, h;
         bool is_set, was_maximized;
     } before_fullscreen;
-    int viewport_width, viewport_height, window_width, window_height;
+    int viewport_width, viewport_height, window_width, window_height, 
content_area_width, content_area_height;
     double viewport_x_ratio, viewport_y_ratio;
     Tab *tabs;
     BackgroundImage *bgimage;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/tabs.py 
new/kitty-0.26.2/kitty/tabs.py
--- old/kitty-0.26.1/kitty/tabs.py      2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/tabs.py      2022-09-05 07:19:50.000000000 +0200
@@ -211,7 +211,7 @@
 
     @property
     def active_window_for_cwd(self) -> Optional[Window]:
-        return self.windows.active_group_base
+        return self.windows.active_group_main
 
     @property
     def title(self) -> str:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/types.py 
new/kitty-0.26.2/kitty/types.py
--- old/kitty-0.26.1/kitty/types.py     2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/types.py     2022-09-05 07:19:50.000000000 +0200
@@ -1,16 +1,24 @@
 #!/usr/bin/env python
 # License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
 
+from enum import Enum
 from functools import update_wrapper
 from typing import (
-    TYPE_CHECKING, Any, Callable, Generic, NamedTuple, Tuple, TypeVar, Union, 
Iterator, Dict
+    TYPE_CHECKING, Any, Callable, Dict, Generic, Iterator, NamedTuple, Tuple,
+    TypeVar, Union
 )
+
 if TYPE_CHECKING:
     from kitty.fast_data_types import SingleKey
 
 _T = TypeVar('_T')
 
 
+class OverlayType(Enum):
+    transient: str = 'transient'
+    main: str = 'main'
+
+
 class ParsedShortcut(NamedTuple):
     mods: int
     key_name: str
@@ -160,11 +168,11 @@
 
 @run_once
 def modmap() -> Dict[str, int]:
+    from .constants import is_macos
     from .fast_data_types import (
         GLFW_MOD_ALT, GLFW_MOD_CAPS_LOCK, GLFW_MOD_CONTROL, GLFW_MOD_HYPER,
         GLFW_MOD_META, GLFW_MOD_NUM_LOCK, GLFW_MOD_SHIFT, GLFW_MOD_SUPER
     )
-    from .constants import is_macos
 
     return {'ctrl': GLFW_MOD_CONTROL, 'shift': GLFW_MOD_SHIFT, ('opt' if 
is_macos else 'alt'): GLFW_MOD_ALT,
             ('cmd' if is_macos else 'super'): GLFW_MOD_SUPER, 'hyper': 
GLFW_MOD_HYPER, 'meta': GLFW_MOD_META,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/utils.py 
new/kitty-0.26.2/kitty/utils.py
--- old/kitty-0.26.1/kitty/utils.py     2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/utils.py     2022-09-05 07:19:50.000000000 +0200
@@ -269,7 +269,8 @@
     return cmd
 
 
-def open_cmd(cmd: Union[Iterable[str], List[str]], arg: Union[None, 
Iterable[str], str] = None, cwd: Optional[str] = None) -> 'PopenType[bytes]':
+def open_cmd(cmd: Union[Iterable[str], List[str]], arg: Union[None, 
Iterable[str], str] = None,
+             cwd: Optional[str] = None, extra_env: Optional[Dict[str, str]] = 
None) -> 'PopenType[bytes]':
     import subprocess
     if arg is not None:
         cmd = list(cmd)
@@ -277,13 +278,17 @@
             cmd.append(arg)
         else:
             cmd.extend(arg)
+    env: Optional[Dict[str, str]] = None
+    if extra_env:
+        env = os.environ.copy()
+        env.update(extra_env)
     return subprocess.Popen(
         tuple(cmd), stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, 
stderr=subprocess.DEVNULL, cwd=cwd or None,
-        preexec_fn=clear_handled_signals)
+        preexec_fn=clear_handled_signals, env=env)
 
 
-def open_url(url: str, program: Union[str, List[str]] = 'default', cwd: 
Optional[str] = None) -> 'PopenType[bytes]':
-    return open_cmd(command_for_open(program), url, cwd=cwd)
+def open_url(url: str, program: Union[str, List[str]] = 'default', cwd: 
Optional[str] = None, extra_env: Optional[Dict[str, str]] = None) -> 
'PopenType[bytes]':
+    return open_cmd(command_for_open(program), url, cwd=cwd, 
extra_env=extra_env)
 
 
 def detach(fork: bool = True, setsid: bool = True, redirect: bool = True) -> 
None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/window.py 
new/kitty-0.26.2/kitty/window.py
--- old/kitty-0.26.1/kitty/window.py    2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty/window.py    2022-09-05 07:19:50.000000000 +0200
@@ -41,11 +41,11 @@
     update_window_title, update_window_visibility, wakeup_main_loop
 )
 from .keys import keyboard_mode_name, mod_mask
-from .notify import NotificationCommand, handle_notification_cmd
+from .notify import NotificationCommand, handle_notification_cmd, 
sanitize_identifier_pat
 from .options.types import Options
 from .rgb import to_color
 from .terminfo import get_capabilities
-from .types import MouseEvent, WindowGeometry, ac, run_once
+from .types import MouseEvent, OverlayType, WindowGeometry, ac, run_once
 from .typing import BossType, ChildType, EdgeLiteral, TabType, TypedDict
 from .utils import (
     docs_url, get_primary_selection, kitty_ansi_sanitizer_pat, load_shaders,
@@ -462,6 +462,7 @@
 class Window:
 
     window_custom_type: str = ''
+    overlay_type = OverlayType.transient
 
     def __init__(
         self,
@@ -642,6 +643,8 @@
         }
         if self.window_custom_type:
             ans['window_custom_type'] = self.window_custom_type
+        if self.overlay_type is not OverlayType.transient:
+            ans['overlay_type'] = self.overlay_type.value
         return ans
 
     @property
@@ -998,6 +1001,7 @@
         self.screen.send_escape_code_to_child(OSC, 
f'{code};rgb:{r:04x}/{g:04x}/{b:04x}')
 
     def report_notification_activated(self, identifier: str) -> None:
+        identifier = sanitize_identifier_pat().sub('', identifier)
         self.screen.send_escape_code_to_child(OSC, f'99;i={identifier};')
 
     def set_dynamic_color(self, code: int, value: Union[str, bytes]) -> None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty/window_list.py 
new/kitty-0.26.2/kitty/window_list.py
--- old/kitty-0.26.1/kitty/window_list.py       2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty/window_list.py       2022-09-05 07:19:50.000000000 
+0200
@@ -7,7 +7,7 @@
 from itertools import count
 from typing import Any, Deque, Dict, Iterator, List, Optional, Tuple, Union
 
-from .types import WindowGeometry
+from .types import OverlayType, WindowGeometry
 from .typing import EdgeLiteral, TabType, WindowType
 
 WindowOrId = Union[WindowType, int]
@@ -54,7 +54,10 @@
         return False
 
     @property
-    def base_window_id(self) -> int:
+    def main_window_id(self) -> int:
+        for w in reversed(self.windows):
+            if w.overlay_type is OverlayType.main:
+                return w.id
         return self.windows[0].id if self.windows else 0
 
     @property
@@ -298,9 +301,9 @@
         return None
 
     @property
-    def active_group_base(self) -> Optional[WindowType]:
+    def active_group_main(self) -> Optional[WindowType]:
         with suppress(Exception):
-            return 
self.id_map[self.groups[self.active_group_idx].base_window_id]
+            return 
self.id_map[self.groups[self.active_group_idx].main_window_id]
         return None
 
     def set_active_window_group_for(self, x: WindowOrId, for_keep_focus: 
Optional[WindowType] = None) -> None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty_tests/check_build.py 
new/kitty-0.26.2/kitty_tests/check_build.py
--- old/kitty-0.26.1/kitty_tests/check_build.py 2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty_tests/check_build.py 2022-09-05 07:19:50.000000000 
+0200
@@ -107,6 +107,22 @@
         run_tests(partial(docs_url, local_docs_root=None), w, '/')
         self.ae(docs_url('#ref=issues-123'), 
'https://github.com/kovidgoyal/kitty/issues/123')
 
+    def test_launcher_ensures_stdio(self):
+        from kitty.constants import kitty_exe
+        import subprocess
+        exe = kitty_exe()
+        cp = subprocess.run([exe, '+runpy', f'''\
+import os, sys
+if sys.stdin:
+    os.close(sys.stdin.fileno())
+if sys.stdout:
+    os.close(sys.stdout.fileno())
+if sys.stderr:
+    os.close(sys.stderr.fileno())
+os.execlp({exe!r}, 'kitty', '+runpy', 'import sys; raise SystemExit(1 if 
sys.stdout is None or sys.stdin is None or sys.stderr is None else 0)')
+'''])
+        self.assertEqual(cp.returncode, 0)
+
 
 def main() -> None:
     tests = unittest.defaultTestLoader.loadTestsFromTestCase(TestBuild)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty_tests/datatypes.py 
new/kitty-0.26.2/kitty_tests/datatypes.py
--- old/kitty-0.26.1/kitty_tests/datatypes.py   2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty_tests/datatypes.py   2022-09-05 07:19:50.000000000 
+0200
@@ -535,7 +535,7 @@
         q('a\x1b[bc', 'ac')
         q('a\x1b[12;34:43mbc', 'abc')
 
-    def test_SingleKey(self):
+    def test_single_key(self):
         from kitty.fast_data_types import (
             GLFW_MOD_KITTY, GLFW_MOD_SHIFT, SingleKey
         )
@@ -548,9 +548,14 @@
         self.ae(repr(SingleKey(key=23, mods=2, is_native=True)), 
'SingleKey(mods=2, is_native=True, key=23)')
         self.ae(repr(SingleKey(key=23, mods=2)), 'SingleKey(mods=2, key=23)')
         self.ae(repr(SingleKey(key=23)), 'SingleKey(key=23)')
+        self.ae(repr(SingleKey(key=0x1008ff57)), 'SingleKey(key=269025111)')
         self.ae(repr(SingleKey(key=23)._replace(mods=2)), 'SingleKey(mods=2, 
key=23)')
         self.ae(repr(SingleKey(key=23)._replace(key=-1, mods=GLFW_MOD_KITTY)), 
f'SingleKey(mods={GLFW_MOD_KITTY})')
         self.assertEqual(SingleKey(key=1), SingleKey(key=1))
         self.assertEqual(hash(SingleKey(key=1)), hash(SingleKey(key=1)))
         self.assertNotEqual(hash(SingleKey(key=1, mods=2)), 
hash(SingleKey(key=1)))
         self.assertNotEqual(SingleKey(key=1, mods=2), SingleKey(key=1))
+
+    def test_notify_identifier_sanitization(self):
+        from kitty.notify import sanitize_identifier_pat
+        self.ae(sanitize_identifier_pat().sub('', '\x1b\nabc\n[*'), 'abc')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty_tests/hints.py 
new/kitty-0.26.2/kitty_tests/hints.py
--- old/kitty-0.26.1/kitty_tests/hints.py       2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty_tests/hints.py       2022-09-05 07:19:50.000000000 
+0200
@@ -10,13 +10,14 @@
     def test_url_hints(self):
         from kittens.hints.main import (
             Mark, convert_text, functions_for, linenum_marks,
-            linenum_process_result, mark, parse_hints_args
+            linenum_process_result, mark, parse_hints_args, 
process_escape_codes
         )
         args = parse_hints_args([])[0]
         pattern, post_processors = functions_for(args)
 
         def create_marks(text, cols=20, mark=mark):
             text = convert_text(text, cols)
+            text, _ = process_escape_codes(text)
             return tuple(mark(pattern, post_processors, text, args))
 
         def t(text, url, cols=20):
@@ -32,6 +33,8 @@
         t(f'link:{u}[xxx]', u)
         t(f'`xyz <{u}>`_.', u)
         t(f'<a href="{u}">moo', u)
+        t('\x1b[mhttp://test.me/1234\n\x1b[mx', 'http://test.me/1234')
+        t('\x1b[mhttp://test.me/12345\r\x1b[m6\n\x1b[mx', 
'http://test.me/123456')
 
         def m(text, path, line, cols=20):
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty_tests/prewarm.py 
new/kitty-0.26.2/kitty_tests/prewarm.py
--- old/kitty-0.26.1/kitty_tests/prewarm.py     2022-08-29 21:34:42.000000000 
+0200
+++ new/kitty-0.26.2/kitty_tests/prewarm.py     2022-09-05 07:19:50.000000000 
+0200
@@ -28,13 +28,15 @@
 
         cwd = tempfile.gettempdir()
         env = {'TEST_ENV_PASS': 'xyz'}
-        cols = 117
+        cols = 317
         stdin_data = 'from_stdin'
         pty = self.create_pty(cols=cols)
         ttyname = os.ttyname(pty.slave_fd)
         opts = get_options()
         opts.config_overrides = 'font_family prewarm',
+        os.environ['SHOULD_NOT_BE_PRESENT'] = '1'
         p = fork_prewarm_process(opts, use_exec=True)
+        del os.environ['SHOULD_NOT_BE_PRESENT']
         if p is None:
             return
         p.take_from_worker_fd(create_file=True)
@@ -44,7 +46,7 @@
         'ttyname': os.ttyname(sys.stdout.fileno()),
         'cols': read_screen_size().cols,
         'cwd': os.getcwd(),
-        'env': os.environ.get('TEST_ENV_PASS'),
+        'env': os.environ.copy(),
         'pid': os.getpid(),
         'font_family': get_options().font_family,
         'stdin': sys.stdin.read(),
@@ -59,7 +61,8 @@
         self.assertTrue(data['cterm'])
         self.ae(data['ttyname'], ttyname)
         self.ae(os.path.realpath(data['cwd']), os.path.realpath(cwd))
-        self.ae(data['env'], env['TEST_ENV_PASS'])
+        self.ae(data['env']['TEST_ENV_PASS'], env['TEST_ENV_PASS'])
+        self.assertNotIn('SHOULD_NOT_BE_PRESENT', data['env'])
         self.ae(data['font_family'], 'prewarm')
         self.ae(int(p.from_worker.readline()), data['pid'])
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/kitty_tests/shell_integration.py 
new/kitty-0.26.2/kitty_tests/shell_integration.py
--- old/kitty-0.26.1/kitty_tests/shell_integration.py   2022-08-29 
21:34:42.000000000 +0200
+++ new/kitty-0.26.2/kitty_tests/shell_integration.py   2022-09-05 
07:19:50.000000000 +0200
@@ -368,4 +368,4 @@
             pty.send_cmd_to_child('clone-in-kitty')
             pty.wait_till(lambda: len(pty.callbacks.clone_cmds) == 1)
             env = pty.callbacks.clone_cmds[0].env
-            self.ae(env.get('ES'), 'a\n `b` c\n$d')
+            self.ae(env.get('ES'), 'a\n `b` c\n$d', f'Screen contents: 
{pty.screen_contents()!r}')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitty-0.26.1/publish.py new/kitty-0.26.2/publish.py
--- old/kitty-0.26.1/publish.py 2022-08-29 21:34:42.000000000 +0200
+++ new/kitty-0.26.2/publish.py 2022-09-05 07:19:50.000000000 +0200
@@ -269,13 +269,7 @@
     def update_nightly_description(self, release_id: int) -> None:
         url = f'{self.url_base}/{release_id}'
         now = str(datetime.datetime.utcnow()).split('.')[0] + ' UTC'
-        try:
-            with open('.git/refs/heads/master') as f:
-                commit = f.read().strip()
-        except FileNotFoundError:
-            time.sleep(1)
-            with open('.git/refs/heads/master') as f:
-                commit = f.read().strip()
+        commit = subprocess.check_output(['git', 'rev-parse', '--verify', 
'--end-of-options', 'master^{commit}']).decode('utf-8').strip()
         self.patch(
             url, 'Failed to update nightly release description',
             body=f'Nightly release, generated on: {now} from commit: {commit}.'
@@ -368,7 +362,7 @@
                 'target_commitish': 'master',
                 'name': f'version {self.version}',
                 'body': f'Release version {self.version}.'
-                ' For changelog, see 
https://sw.kovidgoyal.net/kitty/changelog/'
+                ' For changelog, see 
https://sw.kovidgoyal.net/kitty/changelog/#detailed-list-of-changes'
                 ' GPG key used for signing tarballs is: 
https://calibre-ebook.com/signatures/kovid.gpg',
                 'draft': False,
                 'prerelease': False

Reply via email to