Skip to content

Commit

Permalink
fix: select last used window when moving focus up or to the left
Browse files Browse the repository at this point in the history
When bismuth finds two windows are equally distanced from the current
window, the last used window will be chosen when focus is moved via
keyboard shortcuts.

Before, the closest windows were always determined based on the top-left
corner of each window. This is fine when focusing a window below or to
the right, since adjacent edge aligned windows will have the top-left
corner on the same line either horizontally or vertically.

When moving the focus up or to the left, however, this is no longer
guaranteed. Even though the bottom of two candidate windows might be
edge to edge with the current window, the top-left corners might be on
different levels since the candidate windows don't have to have the same
height. To correctly select the last used adjacent edge aligned window
to the top or to the left, the bottom-right corner will be used to find
the closest windows.
  • Loading branch information
Daxtorim authored and Mikhail Zolotukhin committed Dec 2, 2021
1 parent 8023c50 commit 969cf96
Showing 1 changed file with 31 additions and 13 deletions.
44 changes: 31 additions & 13 deletions src/kwinscript/engine/index.ts
Expand Up @@ -630,22 +630,27 @@ export class EngineImpl implements Engine {
dir: Direction
): EngineWindow | null {
let vertical: boolean;
let downOrRight: boolean;
let sign: -1 | 1;
switch (dir) {
case "up":
vertical = true;
downOrRight = false;
sign = -1;
break;
case "down":
vertical = true;
downOrRight = true;
sign = 1;
break;
case "left":
vertical = false;
downOrRight = false;
sign = -1;
break;
case "right":
vertical = false;
downOrRight = true;
sign = 1;
break;
default:
Expand Down Expand Up @@ -680,21 +685,34 @@ export class EngineImpl implements Engine {
return null;
}

// When moving downOrRight, check the top-left corner for closest window
// When moving not downOrRight, check the bottom-right corner for closest window
const min =
sign *
candidates.reduce(
vertical
? (prevMin, tile): number => Math.min(tile.geometry.y * sign, prevMin)
: (prevMin, tile): number =>
Math.min(tile.geometry.x * sign, prevMin),
Infinity
);

const closest = candidates.filter(
vertical
? (tile): boolean => tile.geometry.y === min
: (tile): boolean => tile.geometry.x === min
);
candidates.reduce((prevMin, tile): number => {
if (vertical) {
return downOrRight
? Math.min(tile.geometry.y * sign, prevMin)
: Math.min(tile.geometry.maxY * sign, prevMin);
} else {
return downOrRight
? Math.min(tile.geometry.x * sign, prevMin)
: Math.min(tile.geometry.maxX * sign, prevMin);
}
}, Infinity);

const closest = candidates.filter((tile): boolean => {
// adjust min for potential pixel wide misalignment of tiles
if (vertical) {
return downOrRight
? tile.geometry.y < min + 5
: tile.geometry.maxY > min - 5;
} else {
return downOrRight
? tile.geometry.x < min + 5
: tile.geometry.maxX > min - 5;
}
});

return closest.sort((a, b) => b.timestamp - a.timestamp)[0];
}
Expand Down

0 comments on commit 969cf96

Please sign in to comment.