Bug 510927

Summary: konsole doesn't always print sixel images on the row it is instructed to. Prints them on the first row instead of second.
Product: [Applications] konsole Reporter: ravachol <rf>
Component: emulationAssignee: Konsole Bugs <konsole-bugs-null>
Status: REPORTED ---    
Severity: minor CC: rf
Priority: NOR    
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: Manjaro   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:
Attachments: Screenshot of kew with the problem visible
Screenshot of kew how it's supposed to look

Description ravachol 2025-10-22 19:31:42 UTC
Created attachment 186015 [details]
Screenshot of kew with the problem visible

SUMMARY
konsole doesn't always print sixel images on the row it is instructed to. Prints them on the first row instead of second. Other terminal emulators don't have this behavior.

STEPS TO REPRODUCE
1. Download https://codeberg.org/ravachol/kew/releases/tag/v3.6.4
2. Run make
3. Run ./kew
4. Play a song in your music library with a cover
5. Make a window into landscape layout
6. Observe how the cover gets printed at row 1 at certain sizes, and row 2 at other sizes.

OBSERVED RESULT
Cover printed on row 1.

EXPECTED RESULT
Cover Printed on row 2.

SOFTWARE/OS VERSIONS
Linux: Manjaro Linux (Wayland)
KDE Plasma Version: 6.3.6

ADDITIONAL INFORMATION

The code used:

void printSquareBitmap(int row, int col, unsigned char *pixels, int width, int height, int baseHeight)
{
        if (pixels == NULL)
        {
                setErrorMessage("Invalid pixel data.\n");
                return;
        }

        // Use the provided width and height
        int pix_width = width;
        int pix_height = height;
        int n_channels = 4; // Assuming RGBA format

        // Validate the image dimensions
        if (pix_width == 0 || pix_height == 0)
        {
                setErrorMessage("Invalid image dimensions.\n");
                return;
        }

        TermSize term_size;
        GString *printable;
        gint cell_width = -1, cell_height = -1;

        tty_init();
        get_tty_size(&term_size);

        if (term_size.width_cells > 0 && term_size.height_cells > 0 &&
            term_size.width_pixels > 0 && term_size.height_pixels > 0)
        {
                cell_width = term_size.width_pixels / term_size.width_cells;
                cell_height = term_size.height_pixels / term_size.height_cells;
        }

        // Set default cell size for some terminals
        if (cell_width <= -1 || cell_height <= -1)
        {
                cell_width = 8;
                cell_height = 16;
        }

        if (cell_width == 0 || cell_height == 0)
        {
                setErrorMessage("Invalid image cell width dimensions.\n");
                return;
        }

        // Calculate corrected width based on aspect ratio correction
        float aspect_ratio_correction = (float)cell_height / (float)cell_width;
        int correctedWidth = (int)(baseHeight * aspect_ratio_correction);

        if (term_size.width_cells > 0 && correctedWidth > term_size.width_cells)
        {
                setErrorMessage("Invalid terminal dimensions.\n");
                return;
        }

        if (term_size.height_cells > 0 && baseHeight > term_size.height_cells)
        {
                setErrorMessage("Invalid terminal dimensions.\n");
                return;
        }

        // Convert image to a printable string using Chafa
        printable = convert_image(
            pixels,
            pix_width,
            pix_height,
            pix_width * n_channels,         // Row stride
            CHAFA_PIXEL_RGBA8_UNASSOCIATED, // Correct pixel format
            correctedWidth,
            baseHeight,
            cell_width,
            cell_height);

        // Ensure the string is null-terminated
        g_string_append_c(printable, '\0');

        // Split the printable string into lines
        const gchar *delimiters = "\n";
        gchar **lines = g_strsplit(printable->str, delimiters, -1);

        // Print each line with indentation
        for (int i = 0; lines[i] != NULL; i++)
        {
                printf("\033[%d;%dH", row + i, col);
                printf("%s", lines[i]);
                fflush(stdout);
        }

        // Free allocated memory
        g_strfreev(lines);
        g_string_free(printable, TRUE);
}
Comment 1 ravachol 2025-10-22 19:32:29 UTC
Created attachment 186016 [details]
Screenshot of kew how it's supposed to look