Skip to content

Commit

Permalink
add swap-with-largest action
Browse files Browse the repository at this point in the history
  • Loading branch information
timbertson committed Oct 13, 2018
1 parent 8a21bce commit 10a8153
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

<key type="as" name="slinger-swap-next-window"> <default>["&lt;Mod4&gt;&lt;Shift&gt;j"]</default><summary>Swap with next window</summary><description>Swap with next window.</description></key>
<key type="as" name="slinger-swap-prev-window"> <default>["&lt;Mod4&gt;&lt;Shift&gt;k"]</default><summary>Swap with prev window</summary><description>Swap with prev window.</description></key>
<key type="as" name="slinger-swap-largest-window"> <default>["&lt;Mod4&gt;&lt;Shift&gt;space"]</default><summary>Swap with prev window</summary><description>Swap with prev window.</description></key>

<key type="as" name="slinger-move-right"> <default>["&lt;Mod4&gt;l"]</default><summary>Grow master area</summary><description>Grow master area.</description></key>
<key type="as" name="slinger-move-left"> <default>["&lt;Mod4&gt;h"]</default><summary>Shrink master area</summary><description>Shrink master area.</description></key>
Expand Down
59 changes: 44 additions & 15 deletions src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface WindowActions {
moveWindowWorkspace(diff: number): Function
selectWindow(diff: number): Function
swapWindow(diff: number): Function
swapLargestWindow(): Function
toggleMaximize(): void
minimize(): void
unminimize(): void
Expand Down Expand Up @@ -93,6 +94,11 @@ module WindowActions {
Sys.activateLater(win);
}

function sizeSortOrder(rect: Rect, _screenMidpoint: Point) {
// negative puts biggest window first
return -Rect.area(rect);
}

function radialSortOrder(rect: Rect, screenMidpoint: Point) {
const midpoint = Rect.midpoint(rect);
const vector = Point.subtract(screenMidpoint, midpoint);
Expand Down Expand Up @@ -129,9 +135,8 @@ module WindowActions {
order: number
private _stableSequence: number

constructor(win: WindowType, midpoint: Point) {
this.win = win;
this.order = radialSortOrder(Sys.windowRect(win), midpoint);
constructor(win: WindowType, midpoint: Point, ordering: (rect: Rect, screenMidpoint: Point) => number) { this.win = win;
this.order = ordering(Sys.windowRect(win), midpoint);
this._stableSequence = null;
}

Expand All @@ -143,7 +148,18 @@ module WindowActions {
}
}

function withWindowPair(diff: number, fn: (a: WindowType, b: WindowType) => void): boolean {
function withWindowDiff(diff: number, fn: (a: WindowType, b: WindowType) => void): boolean {
return withWindowPair(
radialSortOrder,
function(i) { return i + diff; },
fn);
}

function withWindowPair(
ordering: (rect: Rect, screenMidpoint: Point) => number,
selectIndex: (current: number) => number,
fn: (a: WindowType, b: WindowType) => void
): boolean {
const [win, visibleWindows] = Sys.visibleWindows();
if (visibleWindows.length < 2) {
return false; // no pair
Expand All @@ -156,7 +172,7 @@ module WindowActions {
const screenMidpoint = Point.scaleConstant(0.5, workArea);

const windows = (visibleWindows
.map(function(w: WindowType) { return new SortableWindow(w, screenMidpoint); })
.map(function(w: WindowType) { return new SortableWindow(w, screenMidpoint, ordering); })
.sort(function(a: SortableWindow, b: SortableWindow) {
if (a.order === b.order) {
// ensure a stable sort by using index position for equivalent windows
Expand All @@ -183,15 +199,19 @@ module WindowActions {
// return [ Sys.windowTitle(w.win), w.order, w.stableSequence(), Rect.copy(Sys.windowRect(w.win))];
// })));

let newIdx = (windowIdx + diff) % windows.length;
let newIdx = selectIndex(windowIdx);
if (newIdx === null || newIdx === windowIdx) {
return false;
}
newIdx = newIdx % windows.length;
if (newIdx < 0) newIdx += windows.length;
fn(win, windows[newIdx].win);
return true;
}

function selectWindow(diff: number) {
return function() {
if (withWindowPair(diff, function(_a: WindowType, b: WindowType) {
if (withWindowDiff(diff, function(_a: WindowType, b: WindowType) {
Sys.activate(b);
}) === null) {
p("No active window, activating the first visible window");
Expand All @@ -205,13 +225,22 @@ module WindowActions {

function swapWindow(diff: number) {
return function() {
withWindowPair(diff, function(a: WindowType, b: WindowType) {
const ar = Sys.windowRect(a);
const br = Sys.windowRect(b);
Sys.moveResize(b, ar);
Sys.moveResize(a, br);
Sys.activateLater(a); // necessary?
})
withWindowDiff(diff, swapWindows);
}
}

function swapWindows(a: WindowType, b: WindowType) {
const ar = Sys.windowRect(a);
const br = Sys.windowRect(b);
Sys.moveResize(b, ar);
Sys.moveResize(a, br);
Sys.activateLater(a); // necessary?
}

function swapLargestWindow() {
return function() {
let selectFirst = function(_currentIdx: number) { return 0; };
withWindowPair(sizeSortOrder, selectFirst, swapWindows)
}
}

Expand Down Expand Up @@ -354,7 +383,7 @@ module WindowActions {
return {
moveAction, resizeAction, switchWorkspace, moveWindowWorkspace,
toggleMaximize, minimize, unminimize, selectWindow, swapWindow,
fillAvailableSpace, distribute
swapLargestWindow, fillAvailableSpace, distribute
};
}
}
1 change: 1 addition & 0 deletions src/extension_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class Extension {

handle('slinger-swap-next-window', windowActions.swapWindow(1));
handle('slinger-swap-prev-window', windowActions.swapWindow(-1));
handle('slinger-swap-largest-window', windowActions.swapLargestWindow());

handle('slinger-move-right', windowActions.moveAction(1, Axis.x));
handle('slinger-move-left', windowActions.moveAction(-1, Axis.x));
Expand Down

0 comments on commit 10a8153

Please sign in to comment.