Skip to content

[Request] Support for Absolute Pixel Values and Coordinates in Layouts #5

@OldLorekeeper

Description

@OldLorekeeper

Summary

This proposal introduces support for absolute pixel values in layout definitions. Currently, the engine interprets all values as percentages (0-100). This update allows users to specify precise window geometries (e.g. specific widths for sidebars or ultra-wide monitor zones) using either a px suffix or by using values greater than 100.

Key Features:

  1. Explicit Absolute Support: Layout strings can now include px (e.g. 0,0,500px,1080px).
  2. Heuristic Detection: Values larger than 100 are automatically treated as pixels, preserving backward compatibility for existing percentage layouts (which are always <= 100).
  3. Parsing Improvements: Added whitespace trimming to layout parsing to prevent errors with loose configuration strings.

Technical Implementation

1. Logic & Parsing (src/contents/ui/main.qml)

Updated convertLayout to detect absolute values during parsing. It flags a tile as absolute: true if it finds "px" or values > 100.

// In function convertLayout(userLayout)

// IMPROVEMENT: Trim whitespace to prevent parsing errors
let coordinates = tiles[tileIndex].split(',').map(s => s.trim());

if (coordinates.length == 4) {
    let isAbsolute = false;

    // 1. Check for 'px' suffix
    for(let i=0; i<coordinates.length; i++) {
        if (coordinates[i].indexOf('px') !== -1) {
            isAbsolute = true;
            break;
        }
    }

    let x = parseInt(coordinates[0]);
    let y = parseInt(coordinates[1]);
    let w = parseInt(coordinates[2]);
    let h = parseInt(coordinates[3]);

    // 2. Heuristic: If values > 100, force absolute
    if (!isAbsolute && (x > 100 || y > 100 || w > 100 || h > 100)) {
        isAbsolute = true;
    }

    layout.tiles.push({x: x, y: y, w: w, h: h, absolute: isAbsolute});
    isValid = true;
}

2. Popup Grid Rendering (src/contents/ui/PopupTiler.qml)

Updated the visual grid and geometry calculations to correctly map absolute pixels relative to the screen size.

Geometry Calculation (getGeometry):

let layout = layoutRepeater.model[activeLayoutIndex].tiles[activeTileIndex];

// Safety check: Heuristic redetection
let isAbs = layout.absolute || (layout.x > 100 || layout.w > 100);

if (isAbs) {
    return {
        x: clientArea.x + layout.x,
        y: clientArea.y + layout.y,
        width: layout.w,
        height: layout.h
    };
}
// ... existing percentage logic ...

Visual Rendering (Tile Delegate):
To ensure the preview grid looks correct, absolute values are normalized against the screen dimensions.

property bool isAbs: (modelData.absolute === true) || (modelData.x > 100) || (modelData.w > 100)
property real screenW: (popupTiler.width > 0 ? popupTiler.width : 1920)
property real screenH: (popupTiler.height > 0 ? popupTiler.height : 1080)

x: (isAbs ? (modelData.x / screenW) : (modelData.x / 100)) * (tiles.width - borderOffset * 2) + borderOffset
y: (isAbs ? (modelData.y / screenH) : (modelData.y / 100)) * (tiles.height - borderOffset * 2) + borderOffset
width: (isAbs ? (modelData.w / screenW) : (modelData.w / 100)) * (tiles.width - borderOffset * 2)
height: (isAbs ? (modelData.h / screenH) : (modelData.h / 100)) * (tiles.height - borderOffset * 2)

3. Overlay Rendering (src/contents/ui/OverlayTiler.qml)

Similar logic was applied to OverlayTiler to support full-screen drag zones with fixed pixels.

Geometry Calculation:

if (layout.absolute) {
    return {
        x: clientArea.x + layout.x,
        y: clientArea.y + layout.y,
        width: layout.w,
        height: layout.h
    };
}

Visual Rendering:

property bool isAbs: modelData.absolute === true || modelData.x > 100 || modelData.w > 100

// If absolute, subtract margins manually if necessary
x: isAbs ? modelData.x - root.config.overlayScreenEdgeMargin : modelData.x / 100 * tiles.width
y: isAbs ? modelData.y - root.config.overlayScreenEdgeMargin : modelData.y / 100 * tiles.height
width: isAbs ? modelData.w : modelData.w / 100 * tiles.width
height: isAbs ? modelData.h : modelData.h / 100 * tiles.height

Why this change?

This allows users with ultrawide monitors or specific workflow needs to define fixed-width sidebars (e.g. exactly 500px for a chat window) while keeping the rest of the layout flexible. It significantly enhances the configurability of MouseTiler without breaking existing setups.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions