def write_to_screen(self, cli, screen, mouse_handlers, write_position):
        """
        Write window to screen. This renders the user control, the margins and
        copies everything over to the absolute position at the given screen.
        """
        # Calculate margin sizes.
        left_margin_widths = [self._get_margin_width(cli, m) for m in self.left_margins]
        right_margin_widths = [self._get_margin_width(cli, m) for m in self.right_margins]
        total_margin_width = sum(left_margin_widths + right_margin_widths)

        # Render UserControl.
        ui_content = self.content.create_content(
            cli, write_position.width - total_margin_width, write_position.height)
        assert isinstance(ui_content, UIContent)

        # Scroll content.
        wrap_lines = self.wrap_lines(cli)
        scroll_func = self._scroll_when_linewrapping if wrap_lines else self._scroll_without_linewrapping

        scroll_func(
            ui_content, write_position.width - total_margin_width, write_position.height, cli)

        # Write body
        digraph = cli.vi_state.waiting_for_digraph
        visible_line_to_row_col, rowcol_to_yx = self._copy_body(
            ui_content, screen, write_position,
            sum(left_margin_widths), write_position.width - total_margin_width,
            self.vertical_scroll, self.horizontal_scroll,
            has_focus=self.content.has_focus(cli),
            wrap_lines=wrap_lines,
            vertical_scroll_2=self.vertical_scroll_2,
            always_hide_cursor=self.always_hide_cursor(cli),
            cursor_char='?' if digraph else False)

        # Remember render info. (Set before generating the margins. They need this.)
        x_offset=write_position.xpos + sum(left_margin_widths)
        y_offset=write_position.ypos

        self.render_info = WindowRenderInfo(
            ui_content=ui_content,
            horizontal_scroll=self.horizontal_scroll,
            vertical_scroll=self.vertical_scroll,
            window_width=write_position.width - total_margin_width,
            window_height=write_position.height,
            configured_scroll_offsets=self.scroll_offsets,
            visible_line_to_row_col=visible_line_to_row_col,
            rowcol_to_yx=rowcol_to_yx,
            x_offset=x_offset,
            y_offset=y_offset,
            wrap_lines=wrap_lines)

        # Set mouse handlers.
        def mouse_handler(cli, mouse_event):
            """ Wrapper around the mouse_handler of the `UIControl` that turns
            screen coordinates into line coordinates. """
            # Find row/col position first.
            yx_to_rowcol = dict((v, k) for k, v in rowcol_to_yx.items())
            y = mouse_event.position.y
            x = mouse_event.position.x

            # If clicked below the content area, look for a position in the
            # last line instead.
            max_y = write_position.ypos + len(visible_line_to_row_col) - 1
            y = min(max_y, y)

            while x >= 0:
                try:
                    row, col = yx_to_rowcol[y, x]
                except __HOLE__:
                    # Try again. (When clicking on the right side of double
                    # width characters, or on the right side of the input.)
                    x -= 1
                else:
                    # Found position, call handler of UIControl.
                    result = self.content.mouse_handler(
                        cli, MouseEvent(position=Point(x=col, y=row),
                                        event_type=mouse_event.event_type))
                    break
            else:
                # nobreak.
                # (No x/y coordinate found for the content. This happens in
                # case of a FillControl, that only specifies a background, but
                # doesn't have a content. Report (0,0) instead.)
                result = self.content.mouse_handler(
                    cli, MouseEvent(position=Point(x=0, y=0),
                                    event_type=mouse_event.event_type))

            # If it returns NotImplemented, handle it here.
            if result == NotImplemented:
                return self._mouse_handler(cli, mouse_event)

            return result

        mouse_handlers.set_mouse_handler_for_range(
            x_min=write_position.xpos + sum(left_margin_widths),
            x_max=write_position.xpos + write_position.width - total_margin_width,
            y_min=write_position.ypos,
            y_max=write_position.ypos + write_position.height,
            handler=mouse_handler)

        # Render and copy margins.
        move_x = 0

        def render_margin(m, width):
            " Render margin. Return `Screen`. "
            # Retrieve margin tokens.
            tokens = m.create_margin(cli, self.render_info, width, write_position.height)

            # Turn it into a UIContent object.
            # already rendered those tokens using this size.)
            return TokenListControl.static(tokens).create_content(
                cli, width + 1, write_position.height)

        for m, width in zip(self.left_margins, left_margin_widths):
            # Create screen for margin.
            margin_screen = render_margin(m, width)

            # Copy and shift X.
            self._copy_margin(margin_screen, screen, write_position, move_x, width)
            move_x += width

        move_x = write_position.width - sum(right_margin_widths)

        for m, width in zip(self.right_margins, right_margin_widths):
            # Create screen for margin.
            margin_screen = render_margin(m, width)

            # Copy and shift X.
            self._copy_margin(margin_screen, screen, write_position, move_x, width)
            move_x += width
dataset/ETHPy150Open jonathanslenders/python-prompt-toolkit/prompt_toolkit/layout/containers.py/Window.write_to_screen