Fix frameGeometry, clientGeometry, minSize problems (issue 152)

This commit is contained in:
Peter Fajdiga
2026-02-22 00:05:21 +01:00
parent 973956ed5e
commit 6c698c9c82
10 changed files with 59 additions and 19 deletions

View File

@@ -79,7 +79,7 @@ class Column {
public getMinWidth() {
let maxMinWidth = Column.minWidth;
for (const window of this.windows.iterator()) {
const minWidth = window.client.kwinClient.minSize.width;
const minWidth = window.client.kwinClient.minSize.width.ceil();
if (minWidth > maxMinWidth) {
maxMinWidth = minWidth;
}

View File

@@ -7,7 +7,7 @@ class Window {
constructor(client: ClientWrapper, column: Column) {
this.client = client;
this.height = client.kwinClient.frameGeometry.height;
this.height = client.kwinClient.frameGeometry.height.round();
let maximizedMode = this.client.getMaximizedMode();
if (maximizedMode === undefined) {
@@ -123,7 +123,7 @@ class Window {
public onFrameGeometryChanged() {
const newGeometry = this.client.kwinClient.frameGeometry;
this.column.setWidth(newGeometry.width, true);
this.column.setWidth(newGeometry.width.round(), true);
this.column.grid.desktop.onLayoutChanged();
}

View File

@@ -1,3 +1,21 @@
interface Number {
round(this: number): number;
floor(this: number): number;
ceil(this: number): number;
}
Number.prototype.round = function() {
return Math.round(this);
};
Number.prototype.floor = function() {
return Math.floor(this);
};
Number.prototype.ceil = function() {
return Math.ceil(this);
};
interface Function {
partial<H extends any[], T extends any[], R>(
this: (...args: [...H, ...T]) => R,

View File

@@ -38,3 +38,20 @@ function rectContainsPoint(rect: QmlRect, point: QmlPoint) {
rect.y <= point.y &&
rectBottom(rect) >= point.y;
}
function roundQtRect(rect: QmlRect) {
return Qt.rect(
rect.x.round(),
rect.y.round(),
rect.width.round(),
rect.height.round(),
);
}
function rectRightRound(rect: QmlRect) {
return rect.x.round() + rect.width.round();
}
function rectBottomRound(rect: QmlRect) {
return rect.y.round() + rect.height.round();
}

View File

@@ -21,7 +21,7 @@ class ClientWrapper {
}
this.signalManager = ClientWrapper.initSignalManager(this);
this.rulesSignalManager = rulesSignalManager;
this.preferredWidth = kwinClient.frameGeometry.width;
this.preferredWidth = kwinClient.frameGeometry.width.round();
this.manipulatingGeometry = new Doer();
this.lastPlacement = null;
this.stateManager = new ClientState.Manager(constructInitialState(this));
@@ -49,10 +49,10 @@ class ClientWrapper {
if (Clients.isOnOneOfVirtualDesktops(this.kwinClient, kwinDesktops)) {
const frame = this.kwinClient.frameGeometry;
this.kwinClient.frameGeometry = Qt.rect(
frame.x + dx,
frame.y + dy,
frame.width,
frame.height,
frame.x.round() + dx,
frame.y.round() + dy,
frame.width.round(),
frame.height.round(),
);
}
@@ -142,7 +142,7 @@ class ClientWrapper {
if (!Clients.isOnVirtualDesktop(this.kwinClient, Workspace.currentDesktop)) {
return;
}
const frame = this.kwinClient.frameGeometry;
const frame = roundQtRect(this.kwinClient.frameGeometry);
if (frame.x < screenSize.x) {
frame.x = screenSize.x;
} else if (rectRight(frame) > rectRight(screenSize)) {

View File

@@ -47,8 +47,8 @@ namespace Clients {
export function isFullScreenGeometry(kwinClient: KwinClient) {
const fullScreenArea = Workspace.clientArea(ClientAreaOption.FullScreenArea, kwinClient.output, getKwinDesktopApprox(kwinClient));
return kwinClient.clientGeometry.width >= fullScreenArea.width &&
kwinClient.clientGeometry.height >= fullScreenArea.height;
return kwinClient.clientGeometry.width.round() >= fullScreenArea.width &&
kwinClient.clientGeometry.height.round() >= fullScreenArea.height;
}
export function isOnVirtualDesktop(kwinClient: KwinClient, kwinDesktop: KwinDesktop) {

View File

@@ -23,7 +23,7 @@ class PinManager {
const newLots: PinManager.Lot[] = [];
for (const lot of lots) {
lot.split(newLots, client.frameGeometry);
lot.split(newLots, roundQtRect(client.frameGeometry));
}
lots = newLots;
}

View File

@@ -111,7 +111,7 @@ class World {
if (tiledWindow === null) {
return;
}
const cursorAlreadyInFocus = rectContainsPoint(Workspace.activeWindow.frameGeometry, Workspace.cursorPos);
const cursorAlreadyInFocus = rectContainsPoint(roundQtRect(Workspace.activeWindow.frameGeometry), Workspace.cursorPos);
if (cursorAlreadyInFocus) {
return;
}

View File

@@ -30,10 +30,10 @@ namespace ClientState {
const clientRect = client.kwinClient.frameGeometry;
const width = client.preferredWidth;
client.place(
clientRect.x,
clientRect.y,
clientRect.x.round(),
clientRect.y.round(),
width,
Math.min(clientRect.height, Math.round(placementArea.height / 2)),
Math.min(clientRect.height.round(), Math.round(placementArea.height / 2)),
);
}

View File

@@ -123,7 +123,12 @@ namespace ClientState {
return;
}
const newGeometry = client.kwinClient.frameGeometry;
const newGeometry = roundQtRect(client.kwinClient.frameGeometry);
if (rectEquals(oldGeometry, newGeometry)) {
// no real changes, nothing to do
return;
}
const oldCenterX = oldGeometry.x + oldGeometry.width/2;
const oldCenterY = oldGeometry.y + oldGeometry.height/2;
const newCenterX = newGeometry.x + newGeometry.width/2;
@@ -193,9 +198,9 @@ namespace ClientState {
private static getResizeNeighborColumn(window: Window) {
const kwinClient = window.client.kwinClient;
const column = window.column;
if (Workspace.cursorPos.x > rectRight(kwinClient.clientGeometry)) {
if (Workspace.cursorPos.x > rectRightRound(kwinClient.clientGeometry)) {
return column.grid.getRightColumn(column);
} else if (Workspace.cursorPos.x < kwinClient.clientGeometry.x) {
} else if (Workspace.cursorPos.x < kwinClient.clientGeometry.x.round()) {
return column.grid.getLeftColumn(column);
} else {
return null;