Fmstrat / wintile

Windows 10 window tiling for GNOME
GNU General Public License v3.0
424 stars 54 forks source link

GNOME programs don't size properly #162

Open GrylledCheez opened 1 year ago

GrylledCheez commented 1 year ago

I have been noticing both Gnome Terminal and Gnome Files don't seem to size themselves correctly on my Primary ultrawide in landscape in the top right corner (perhaps other places too). The coloured zone area looks correct in size but when the window sizes itself to the zone it is often smaller or larger than the zone.

Here is a screenshot of both of them in their wrong size snapped into the same zone.

Screenshot from 2023-07-28 18-01-40

Originally posted by @skewty in https://github.com/Fmstrat/wintile/issues/160#issuecomment-1656501688

skewty commented 1 year ago

NOTE: This issues occurs only when using a Wayland session and not when using the legacy X11 session.

skewty commented 1 year ago

NOTE: This issues occurs only when using a Wayland session and not when using the legacy X11 session.

Given that this issue is limited to wayland, perhaps the title should be adjusted to something more like: "window size of tile is sometimes incorrect in wayland"

GrylledCheez commented 1 year ago

It affects me too on X11. gTile and AwesomeTile both do something with the frame buffers, but I can't get them to work the same. Would you like to do a pull request?

nicolaschretienpm commented 5 months ago

I think it could be an issue in moveApp function. The move_resize_frame call in moveAppCoordinates is asynchronous in Wayland and the window width and height checks should be done when app.size-changed is triggered. Below I paste my fix that seems to work in my case (I had the same size issue).

const GObject = imports.gi.GObject;

[...]

/**
 *
 * @param {object} app the window object
 * @param {object} loc = { col, row, width, height }
 */
function moveApp(app, loc) {
    _log(`moveApp) ${JSON.stringify(loc)}`);
    var monitor = null;
    var monitorIndex = null;
    if (loc.mouse)
        monitorIndex = getCurrentMonitor();
    else
        monitorIndex = app.get_monitor();

    monitor = getMonitorInfo(monitorIndex);

    _log(`moveApp) monitor: ${JSON.stringify(monitor)}`);

    var colCount = monitor.colCount;
    var rowCount = monitor.rowCount;

    // if the colCount >= than loc.col means that we're moving into a non-ultrawide monitor and it's near the right of the screen
    if (loc.col >= colCount)
        loc.col = colCount - 1;

    // if the rowCount >= than loc.row means that we're moving into a non-ultrawide monitor and it's near the bottom of the screen
    if (loc.row >= rowCount)
        loc.row = rowCount - 1;

    var colWidth = Math.floor(monitor.width / colCount);
    var rowHeight = Math.floor(monitor.height / rowCount);

    let x = loc.col * colWidth + monitor.x;
    let y = loc.row * rowHeight + monitor.y;
    let w = loc.width * colWidth;
    let h = loc.height * rowHeight;

    if (loc.col + loc.width === colCount)
        w += monitor.width % colCount;

    const handler = app.connect('size-changed', (app) => {
       this.onSizeChanged(app, monitor, loc, colWidth, rowHeight)
    });
    _log(`size-changed handler ${handler}`);

    if (!config.useMaximize) {
        unMaximizeIfMaximized(app);
        moveAppCoordinates(app, x, y, w, h);
    } else {
        if (loc.height < rowCount || loc.width < colCount)
            unMaximizeIfMaximized(app);

        moveAppCoordinates(app, x, y, w, h);
        if (loc.height === rowCount && loc.width === colCount) {
            // Maximize
            _log('moveApp) maximize');
            app.maximize(Meta.MaximizeFlags.HORIZONTAL | Meta.MaximizeFlags.VERTICAL);
        } else if (loc.height === rowCount && !config.gap) {
            // Maximize vertically
            _log('moveApp) maximize - v');
            app.maximize(Meta.MaximizeFlags.VERTICAL);
        } else if (loc.width === colCount && !config.gap) {
            // Maximize horizontally
            _log('moveApp) maximize - h');
            app.maximize(Meta.MaximizeFlags.HORIZONTAL);
        }
    }

    app.wintile.col = loc.col;
    app.wintile.row = loc.row;
    app.wintile.width = loc.width;
    app.wintile.height = loc.height;

//    let window = app.get_frame_rect();
//    let leftShift = window.width - w + config.gap;
//    let upShift = window.height - h + config.gap;
//    if (leftShift && loc.col === colCount - 1) {
//        _log(`moveApp) window wider than anticipated. Shift left by ${leftShift} px`);
//        x -= leftShift;
//        w = window.width;
//    }
//    if (upShift && loc.row === rowCount - 1) {
//        _log(`moveApp) window lower than anticipated. Shift up by ${upShift} px`);
//        y -= upShift;
//        h = window.height;
//    }
//    if (upShift || leftShift)
//        moveAppCoordinates(app, x, y, w, h);

//    _log(`moveApp) window.x: ${window.x} window.y: ${window.y} window.width: ${window.width} window.height: ${window.height}`);
}

function onSizeChanged(app, monitor, loc, colWidth, rowHeight) {
    _log(`onSizeChanged`);

    const handler = GObject.signal_handler_find(app, {signalId: 'size-changed'});
    _log(`disconnect handler ${handler}`);

    if (handler !== 0) {
       app.disconnect(handler);
    }

    var colCount = monitor.colCount;
    var rowCount = monitor.rowCount;

    let x = loc.col * colWidth + monitor.x;
    let y = loc.row * rowHeight + monitor.y;
    let w = loc.width * colWidth;
    let h = loc.height * rowHeight;

    let window = app.get_frame_rect();
    let leftShift = window.width - w + config.gap;
    let upShift = window.height - h + config.gap;
    if (leftShift && loc.col === colCount - 1) {
        _log(`moveApp) window wider than anticipated. Shift left by ${leftShift} px`);
        x -= leftShift;
        w = window.width;
    }
    if (upShift && loc.row === rowCount - 1) {
        _log(`moveApp) window lower than anticipated. Shift up by ${upShift} px`);
        y -= upShift;
        h = window.height;
    }
    if (upShift || leftShift) {
        moveAppCoordinates(app, x, y, w, h);
    }

    _log(`moveApp) window.x: ${window.x} window.y: ${window.y} window.width: ${window.width} window.height: ${window.height}`);
}