diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 218120039..d29d29e6a 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -792,7 +792,8 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, id_type *activ if (is_active_non_floating_window) *active_window_bg = window_bg; needs_render |= prepare_to_render_window(os_window, tab, w, is_active_non_floating_window, now, scan_for_animated_images, active_window_id); for (size_t i = 0; i < w->floating.child_count; i++) { - needs_render |= prepare_to_render_window(os_window, tab, w->floating.children + i, is_active_non_floating_window, now, scan_for_animated_images, active_window_id); + Window *cw = w->floating.children + i; + if (cw->render_data.screen) needs_render |= prepare_to_render_window(os_window, tab, cw, is_active_non_floating_window, now, scan_for_animated_images, active_window_id); } } } @@ -840,7 +841,8 @@ render_prepared_os_window(OSWindow *os_window, unsigned int active_window_id, co if (w->visible && WD.screen) { if (draw_window(os_window, w, i == tab->active_window, num_of_visible_windows)) active_window = w; for (size_t f = 0; f < w->floating.child_count; f++) { - if (draw_window(os_window, w->floating.children + f, i == tab->active_window, num_of_visible_windows)) active_window = w->floating.children + f; + Window *cw = w->floating.children + f; + if (cw->render_data.screen && draw_window(os_window, cw, i == tab->active_window, num_of_visible_windows)) active_window = cw; } } } diff --git a/kitty/launch.py b/kitty/launch.py index e7c10233e..5967ad452 100644 --- a/kitty/launch.py +++ b/kitty/launch.py @@ -81,7 +81,7 @@ of the active window in the tab is used as the tab title. The special value --type type=choices default=window -choices=window,tab,os-window,overlay,overlay-main,background,clipboard,primary +choices=window,tab,os-window,overlay,overlay-main,background,clipboard,primary,float Where to launch the child process: :code:`window` @@ -105,6 +105,9 @@ Where to launch the child process: 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:`float` + A floating window displayed on top of the parent window. + :code:`background` The process will be run in the :italic:`background`, without a kitty window. Note that if :option:`kitten @ launch --allow-remote-control` is @@ -122,7 +125,8 @@ Where to launch the child process: --keep-focus --dont-take-focus type=bool-set Keep the focus on the currently active window instead of switching to the newly -opened window. +opened window. Note that floating windows always take focus from their parent +non-floating window. --cwd @@ -722,8 +726,8 @@ def _launch( tab = tab_for_window(boss, opts, target_tab, next_to) watchers = load_watch_modules(opts.watcher) with Window.set_ignore_focus_changes_for_new_windows(opts.keep_focus): - new_window: Window = tab.new_window( - env=env or None, watchers=watchers or None, is_clone_launch=is_clone_launch, next_to=next_to, **kw) + new_window = tab.new_window( + env=env or None, watchers=watchers or None, is_clone_launch=is_clone_launch, next_to=next_to, is_float=opts.type == 'float', **kw) if spacing: patch_window_edges(new_window, spacing) tab.relayout() diff --git a/kitty/tabs.py b/kitty/tabs.py index e2eba045c..de8acce16 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -568,20 +568,27 @@ class Tab: # {{{ pass_fds: tuple[int, ...] = (), remote_control_fd: int = -1, next_to: Window | None = None, + is_float: bool = False, ) -> Window: + floating_in = 0 + if is_float: + fp = next_to or self.active_window + if fp is not None: + floating_in = fp.id child = self.launch_child( use_shell=use_shell, cmd=cmd, stdin=stdin, cwd_from=cwd_from, cwd=cwd, env=env, is_clone_launch=is_clone_launch, add_listen_on_env_var=False if allow_remote_control and remote_control_passwords else True, hold=hold, pass_fds=pass_fds, remote_control_fd=remote_control_fd, ) window = Window( - self, child, self.args, override_title=override_title, + self, child, self.args, override_title=override_title, floating_in=floating_in, copy_colors_from=copy_colors_from, watchers=watchers, allow_remote_control=allow_remote_control, remote_control_passwords=remote_control_passwords ) # Must add child before laying out so that resize_pty succeeds get_boss().add_child(window) - self._add_window(window, location=location, overlay_for=overlay_for, overlay_behind=overlay_behind, bias=bias, next_to=next_to) + if not floating_in: + self._add_window(window, location=location, overlay_for=overlay_for, overlay_behind=overlay_behind, bias=bias, next_to=next_to) if marker: try: window.set_marker(marker)