def mark_terminal_ready(self) -> None: if self.is_prewarmed: fast_data_types.get_boss().prewarm.mark_child_as_ready( self.prewarmed_child.child_id) else: os.close(self.terminal_ready_fd) self.terminal_ready_fd = -1
def fork(self) -> Optional[int]: if self.forked: return None self.forked = True master, slave = openpty() stdin, self.stdin = self.stdin, None self.is_prewarmed = is_prewarmable(self.argv) if not self.is_prewarmed: ready_read_fd, ready_write_fd = os.pipe() os.set_inheritable(ready_write_fd, False) os.set_inheritable(ready_read_fd, True) if stdin is not None: stdin_read_fd, stdin_write_fd = os.pipe() os.set_inheritable(stdin_write_fd, False) os.set_inheritable(stdin_read_fd, True) else: stdin_read_fd = stdin_write_fd = -1 env = tuple(f'{k}={v}' for k, v in self.final_env().items()) argv = list(self.argv) exe = argv[0] if is_macos and exe == shell_path: # bash will only source ~/.bash_profile if it detects it is a login # shell (see the invocation section of the bash man page), which it # does if argv[0] is prefixed by a hyphen see # https://github.com/kovidgoyal/kitty/issues/247 # it is apparently common to use ~/.bash_profile instead of the # more correct ~/.bashrc on macOS to setup env vars, so if # the default shell is used prefix argv[0] by '-' # # it is arguable whether graphical terminals should start shells # in login mode in general, there are at least a few Linux users # that also make this incorrect assumption, see for example # https://github.com/kovidgoyal/kitty/issues/1870 # xterm, urxvt, konsole and gnome-terminal do not do it in my # testing. argv[0] = (f'-{exe.split("/")[-1]}') self.final_exe = which(exe) or exe self.final_argv0 = argv[0] if self.is_prewarmed: fe = self.final_env() self.prewarmed_child = fast_data_types.get_boss().prewarm( slave, self.argv, self.cwd, fe, stdin) pid = self.prewarmed_child.child_process_pid else: pid = fast_data_types.spawn(self.final_exe, self.cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd, ready_read_fd, ready_write_fd, tuple(handled_signals)) os.close(slave) self.pid = pid self.child_fd = master if not self.is_prewarmed: if stdin is not None: os.close(stdin_read_fd) fast_data_types.thread_write(stdin_write_fd, stdin) os.close(ready_read_fd) self.terminal_ready_fd = ready_write_fd if self.child_fd is not None: os.set_blocking(self.child_fd, False) return pid
def __call__(self, *a: Any) -> None: s = sessions_map.pop(self.sid, None) if s is not None: boss = get_boss() for wid in s.window_ids: qw = boss.window_id_map.get(wid) if qw is not None: qw.screen.render_unfocused_cursor = 0
def __call__(self, window: Window, focused: bool) -> None: s = sessions_map.get(self.sid) if s is not None: boss = get_boss() val = int(focused) for wid in s.window_ids: qw = boss.window_id_map.get(wid) if qw is not None: qw.screen.render_unfocused_cursor = val
def start_receive(self, ar_id: str) -> None: ar = self.active_receives[ar_id] if ar.bypass_ok is not None: self.handle_send_confirmation(ar.bypass_ok, ar_id) return boss = get_boss() window = boss.window_id_map.get(self.window_id) if window is not None: boss.confirm(_( 'The remote machine wants to send some files to this computer. Do you want to allow the transfer?'), self.handle_send_confirmation, ar_id, window=window, )
def start_send(self, cmd: FileTransmissionCommand) -> None: boss = get_boss() window = boss.window_id_map.get(self.window_id) if window is not None: boss._run_kitten( 'transfer_ask', [ 'put', 'multiple' if cmd.container_fmt else 'single', cmd.dest ], window=window, custom_callback=partial(self.handle_send_confirmation, cmd.id), )
def start_receive(self, ar_id: str) -> None: ar = self.active_receives[ar_id] if ar.bypass_ok is not None: self.handle_send_confirmation(ar_id, {'response': 'y' if ar.bypass_ok else 'n'}) return boss = get_boss() window = boss.window_id_map.get(self.window_id) if window is not None: boss._run_kitten('ask', ['--type=yesno', '--message', _( 'The remote machine wants to send some files to this computer. Do you want to allow the transfer?' )], window=window, custom_callback=partial(self.handle_send_confirmation, ar_id), )
def write_ftc_to_child(self, payload: FileTransmissionCommand, appendleft: bool = False, use_pending: bool = True) -> bool: boss = get_boss() window = boss.window_id_map.get(self.window_id) if window is not None: data = tuple(payload.get_serialized_fields(prefix_with_osc_code=True)) queued = window.screen.send_escape_code_to_child(OSC, data) if not queued: if use_pending: if appendleft: self.pending_receive_responses.appendleft(payload) else: self.pending_receive_responses.append(payload) self.start_pending_timer() return queued return False
def write_response_to_child(self, fields: Dict[str, str]) -> None: boss = get_boss() window = boss.window_id_map.get(self.window_id) if window is not None: window.screen.send_escape_code_to_child( OSC, ';'.join(f'{k}={v}' for k, v in fields.items()))
def cmdline_of_prewarmer() -> List[str]: # we need this check in case the prewarmed process has done an exec and # changed its cmdline with suppress(Exception): return cmdline_of_pid(fast_data_types.get_boss().prewarm.worker_pid) return ['']