port key bindings to the kwin6 ShortcutHandler system
This commit is contained in:
@@ -3,7 +3,6 @@ type KeyBinding = {
|
|||||||
description: string;
|
description: string;
|
||||||
comment?: string;
|
comment?: string;
|
||||||
defaultKeySequence: string;
|
defaultKeySequence: string;
|
||||||
action: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type NumKeyBinding = {
|
type NumKeyBinding = {
|
||||||
@@ -12,7 +11,6 @@ type NumKeyBinding = {
|
|||||||
comment?: string;
|
comment?: string;
|
||||||
defaultModifiers: string;
|
defaultModifiers: string;
|
||||||
fKeys: boolean;
|
fKeys: boolean;
|
||||||
action: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatComment(comment: string | undefined) {
|
function formatComment(comment: string | undefined) {
|
||||||
|
|||||||
148
src/Actions.ts
148
src/Actions.ts
@@ -1,7 +1,7 @@
|
|||||||
namespace Actions {
|
namespace Actions {
|
||||||
export function init(world: World, config: Config) {
|
export function getAction(world: World, config: Config, name: string) {
|
||||||
return {
|
switch (name) {
|
||||||
focusLeft: () => {
|
case "focus-left": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
const prevColumn = grid.getPrevColumn(column);
|
const prevColumn = grid.getPrevColumn(column);
|
||||||
if (prevColumn === null) {
|
if (prevColumn === null) {
|
||||||
@@ -9,9 +9,9 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
prevColumn.focus();
|
prevColumn.focus();
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
focusRight: () => {
|
case "focus-right": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
const nextColumn = grid.getNextColumn(column);
|
const nextColumn = grid.getNextColumn(column);
|
||||||
if (nextColumn === null) {
|
if (nextColumn === null) {
|
||||||
@@ -19,9 +19,9 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
nextColumn.focus();
|
nextColumn.focus();
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
focusUp: () => {
|
case "focus-up": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
const prevWindow = column.getPrevWindow(window);
|
const prevWindow = column.getPrevWindow(window);
|
||||||
if (prevWindow === null) {
|
if (prevWindow === null) {
|
||||||
@@ -29,9 +29,9 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
prevWindow.focus();
|
prevWindow.focus();
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
focusDown: () => {
|
case "focus-down": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
const nextWindow = column.getNextWindow(window);
|
const nextWindow = column.getNextWindow(window);
|
||||||
if (nextWindow === null) {
|
if (nextWindow === null) {
|
||||||
@@ -39,9 +39,9 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
nextWindow.focus();
|
nextWindow.focus();
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
focusStart: () => {
|
case "focus-start": return () => {
|
||||||
world.do((clientManager, desktopManager) => {
|
world.do((clientManager, desktopManager) => {
|
||||||
const grid = desktopManager.getCurrentDesktop().grid;
|
const grid = desktopManager.getCurrentDesktop().grid;
|
||||||
const firstColumn = grid.getFirstColumn();
|
const firstColumn = grid.getFirstColumn();
|
||||||
@@ -50,9 +50,9 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
firstColumn.focus();
|
firstColumn.focus();
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
focusEnd: () => {
|
case "focus-end": return () => {
|
||||||
world.do((clientManager, desktopManager) => {
|
world.do((clientManager, desktopManager) => {
|
||||||
const grid = desktopManager.getCurrentDesktop().grid;
|
const grid = desktopManager.getCurrentDesktop().grid;
|
||||||
const lastColumn = grid.getLastColumn();
|
const lastColumn = grid.getLastColumn();
|
||||||
@@ -61,9 +61,9 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
lastColumn.focus();
|
lastColumn.focus();
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
windowMoveLeft: () => {
|
case "window-move-left": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
if (column.getWindowCount() === 1) {
|
if (column.getWindowCount() === 1) {
|
||||||
// move from own column into existing column
|
// move from own column into existing column
|
||||||
@@ -79,9 +79,9 @@ namespace Actions {
|
|||||||
window.moveToColumn(newColumn);
|
window.moveToColumn(newColumn);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
windowMoveRight: () => {
|
case "window-move-right": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
if (column.getWindowCount() === 1) {
|
if (column.getWindowCount() === 1) {
|
||||||
// move from own column into existing column
|
// move from own column into existing column
|
||||||
@@ -97,100 +97,100 @@ namespace Actions {
|
|||||||
window.moveToColumn(newColumn);
|
window.moveToColumn(newColumn);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
windowMoveUp: () => {
|
case "window-move-up": return () => {
|
||||||
// TODO (optimization): only arrange moved windows
|
// TODO (optimization): only arrange moved windows
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
column.moveWindowUp(window);
|
column.moveWindowUp(window);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
windowMoveDown: () => {
|
case "window-move-down": return () => {
|
||||||
// TODO (optimization): only arrange moved windows
|
// TODO (optimization): only arrange moved windows
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
column.moveWindowDown(window);
|
column.moveWindowDown(window);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
windowMoveStart: () => {
|
case "window-move-start": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
const newColumn = new Column(grid, null);
|
const newColumn = new Column(grid, null);
|
||||||
window.moveToColumn(newColumn);
|
window.moveToColumn(newColumn);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
windowMoveEnd: () => {
|
case "window-move-end": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
const newColumn = new Column(grid, grid.getLastColumn());
|
const newColumn = new Column(grid, grid.getLastColumn());
|
||||||
window.moveToColumn(newColumn);
|
window.moveToColumn(newColumn);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
windowToggleFloating: () => {
|
case "window-toggle-floating": return () => {
|
||||||
const kwinClient = Workspace.activeWindow;
|
const kwinClient = Workspace.activeWindow;
|
||||||
world.do((clientManager, desktopManager) => {
|
world.do((clientManager, desktopManager) => {
|
||||||
clientManager.toggleFloatingClient(kwinClient);
|
clientManager.toggleFloatingClient(kwinClient);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
columnMoveLeft: () => {
|
case "column-move-left": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
grid.moveColumnLeft(column);
|
grid.moveColumnLeft(column);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
columnMoveRight: () => {
|
case "column-move-right": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
grid.moveColumnRight(column);
|
grid.moveColumnRight(column);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
columnMoveStart: () => {
|
case "column-move-start": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
column.moveAfter(null);
|
column.moveAfter(null);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
columnMoveEnd: () => {
|
case "column-move-end": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
column.moveAfter(grid.getLastColumn());
|
column.moveAfter(grid.getLastColumn());
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
columnToggleStacked: () => {
|
case "column-toggle-stacked": return () => {
|
||||||
world.doIfTiledFocused(false, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(false, (clientManager, desktopManager, window, column, grid) => {
|
||||||
column.toggleStacked();
|
column.toggleStacked();
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
columnWidthIncrease: () => {
|
case "column-width-increase": return () => {
|
||||||
world.doIfTiledFocused(false, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(false, (clientManager, desktopManager, window, column, grid) => {
|
||||||
config.columnResizer.increaseWidth(column, config.manualResizeStep);
|
config.columnResizer.increaseWidth(column, config.manualResizeStep);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
columnWidthDecrease: () => {
|
case "column-width-decrease": return () => {
|
||||||
world.doIfTiledFocused(false, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(false, (clientManager, desktopManager, window, column, grid) => {
|
||||||
config.columnResizer.decreaseWidth(column, config.manualResizeStep);
|
config.columnResizer.decreaseWidth(column, config.manualResizeStep);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
columnsWidthEqualize: () => {
|
case "columns-width-equalize": return () => {
|
||||||
world.do((clientManager, desktopManager) => {
|
world.do((clientManager, desktopManager) => {
|
||||||
desktopManager.getCurrentDesktop().equalizeVisibleColumnsWidths();
|
desktopManager.getCurrentDesktop().equalizeVisibleColumnsWidths();
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
gridScrollLeft: () => {
|
case "grid-scroll-left": return () => {
|
||||||
gridScroll(world, -config.manualScrollStep);
|
gridScroll(world, -config.manualScrollStep);
|
||||||
},
|
};
|
||||||
|
|
||||||
gridScrollRight: () => {
|
case "grid-scroll-right": return () => {
|
||||||
gridScroll(world, config.manualScrollStep);
|
gridScroll(world, config.manualScrollStep);
|
||||||
},
|
};
|
||||||
|
|
||||||
gridScrollStart: () => {
|
case "grid-scroll-start": return () => {
|
||||||
world.do((clientManager, desktopManager) => {
|
world.do((clientManager, desktopManager) => {
|
||||||
const grid = desktopManager.getCurrentDesktop().grid;
|
const grid = desktopManager.getCurrentDesktop().grid;
|
||||||
const firstColumn = grid.getFirstColumn();
|
const firstColumn = grid.getFirstColumn();
|
||||||
@@ -199,9 +199,9 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
grid.desktop.scrollToColumn(firstColumn);
|
grid.desktop.scrollToColumn(firstColumn);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
gridScrollEnd: () => {
|
case "grid-scroll-end": return () => {
|
||||||
world.do((clientManager, desktopManager) => {
|
world.do((clientManager, desktopManager) => {
|
||||||
const grid = desktopManager.getCurrentDesktop().grid;
|
const grid = desktopManager.getCurrentDesktop().grid;
|
||||||
const lastColumn = grid.getLastColumn();
|
const lastColumn = grid.getLastColumn();
|
||||||
@@ -210,15 +210,15 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
grid.desktop.scrollToColumn(lastColumn);
|
grid.desktop.scrollToColumn(lastColumn);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
gridScrollFocused: () => {
|
case "grid-scroll-focused": return () => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
grid.desktop.scrollCenterRange(column);
|
grid.desktop.scrollCenterRange(column);
|
||||||
})
|
})
|
||||||
},
|
};
|
||||||
|
|
||||||
gridScrollLeftColumn: () => {
|
case "grid-scroll-left-column": return () => {
|
||||||
world.do((clientManager, desktopManager) => {
|
world.do((clientManager, desktopManager) => {
|
||||||
const grid = desktopManager.getCurrentDesktop().grid;
|
const grid = desktopManager.getCurrentDesktop().grid;
|
||||||
const column = grid.getLeftmostVisibleColumn(grid.desktop.getCurrentVisibleRange(), true);
|
const column = grid.getLeftmostVisibleColumn(grid.desktop.getCurrentVisibleRange(), true);
|
||||||
@@ -233,9 +233,9 @@ namespace Actions {
|
|||||||
|
|
||||||
grid.desktop.scrollToColumn(prevColumn);
|
grid.desktop.scrollToColumn(prevColumn);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
gridScrollRightColumn: () => {
|
case "grid-scroll-right-column": return () => {
|
||||||
world.do((clientManager, desktopManager) => {
|
world.do((clientManager, desktopManager) => {
|
||||||
const grid = desktopManager.getCurrentDesktop().grid;
|
const grid = desktopManager.getCurrentDesktop().grid;
|
||||||
const column = grid.getRightmostVisibleColumn(grid.desktop.getCurrentVisibleRange(), true);
|
const column = grid.getRightmostVisibleColumn(grid.desktop.getCurrentVisibleRange(), true);
|
||||||
@@ -250,13 +250,15 @@ namespace Actions {
|
|||||||
|
|
||||||
grid.desktop.scrollToColumn(nextColumn);
|
grid.desktop.scrollToColumn(nextColumn);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
};
|
|
||||||
|
default: throw new Error("unknown action: " + name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initNum(world: World) {
|
export function getNumAction(world: World, name: string) {
|
||||||
return {
|
switch (name) {
|
||||||
focusColumn: (columnIndex: number) => {
|
case "focus-": return (columnIndex: number) => {
|
||||||
world.do((clientManager, desktopManager) => {
|
world.do((clientManager, desktopManager) => {
|
||||||
const grid = desktopManager.getCurrentDesktop().grid;
|
const grid = desktopManager.getCurrentDesktop().grid;
|
||||||
const targetColumn = grid.getColumnAtIndex(columnIndex);
|
const targetColumn = grid.getColumnAtIndex(columnIndex);
|
||||||
@@ -265,9 +267,9 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
targetColumn.focus();
|
targetColumn.focus();
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
windowMoveToColumn: (columnIndex: number) => {
|
case "window-move-to-column-": return (columnIndex: number) => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
const targetColumn = grid.getColumnAtIndex(columnIndex);
|
const targetColumn = grid.getColumnAtIndex(columnIndex);
|
||||||
if (targetColumn === null) {
|
if (targetColumn === null) {
|
||||||
@@ -276,9 +278,9 @@ namespace Actions {
|
|||||||
window.moveToColumn(targetColumn);
|
window.moveToColumn(targetColumn);
|
||||||
grid.desktop.autoAdjustScroll();
|
grid.desktop.autoAdjustScroll();
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
columnMoveToColumn: (columnIndex: number) => {
|
case "column-move-to-column-": return (columnIndex: number) => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, grid) => {
|
||||||
const targetColumn = grid.getColumnAtIndex(columnIndex);
|
const targetColumn = grid.getColumnAtIndex(columnIndex);
|
||||||
if (targetColumn === null || targetColumn === column) {
|
if (targetColumn === null || targetColumn === column) {
|
||||||
@@ -290,9 +292,9 @@ namespace Actions {
|
|||||||
column.moveAfter(grid.getPrevColumn(targetColumn));
|
column.moveAfter(grid.getPrevColumn(targetColumn));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
columnMoveToDesktop: (desktopIndex: number) => {
|
case "column-move-to-desktop-": return (desktopIndex: number) => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, oldGrid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, oldGrid) => {
|
||||||
const kwinDesktop = Workspace.desktops[desktopIndex];
|
const kwinDesktop = Workspace.desktops[desktopIndex];
|
||||||
if (kwinDesktop === undefined) {
|
if (kwinDesktop === undefined) {
|
||||||
@@ -304,9 +306,9 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
column.moveToGrid(newGrid, newGrid.getLastColumn());
|
column.moveToGrid(newGrid, newGrid.getLastColumn());
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
tailMoveToDesktop: (desktopIndex: number) => {
|
case "tail-move-to-desktop-": return (desktopIndex: number) => {
|
||||||
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, oldGrid) => {
|
world.doIfTiledFocused(true, (clientManager, desktopManager, window, column, oldGrid) => {
|
||||||
const kwinDesktop = Workspace.desktops[desktopIndex];
|
const kwinDesktop = Workspace.desktops[desktopIndex];
|
||||||
if (kwinDesktop === undefined) {
|
if (kwinDesktop === undefined) {
|
||||||
@@ -318,8 +320,10 @@ namespace Actions {
|
|||||||
}
|
}
|
||||||
oldGrid.evacuateTail(newGrid, column);
|
oldGrid.evacuateTail(newGrid, column);
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
};
|
|
||||||
|
default: throw new Error("unknown num action: " + name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function gridScroll(world: World, amount: number) {
|
function gridScroll(world: World, amount: number) {
|
||||||
|
|||||||
6
src/extern/kwin.d.ts
vendored
6
src/extern/kwin.d.ts
vendored
@@ -1,6 +1,5 @@
|
|||||||
declare const KWin: {
|
declare const KWin: {
|
||||||
readConfig(key: string, defaultValue: any): any;
|
readConfig(key: string, defaultValue: any): any;
|
||||||
registerShortcut(name: string, description: string, keySequence: string, callback: () => void): void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
declare const Workspace: {
|
declare const Workspace: {
|
||||||
@@ -83,3 +82,8 @@ interface KwinClient {
|
|||||||
interface KwinDesktop {
|
interface KwinDesktop {
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShortcutHandler = {
|
||||||
|
readonly activated: QSignal<[void]>;
|
||||||
|
destroy(): void;
|
||||||
|
};
|
||||||
|
|||||||
@@ -3,176 +3,148 @@ const keyBindings: KeyBinding[] = [
|
|||||||
name: "window-toggle-floating",
|
name: "window-toggle-floating",
|
||||||
description: "Toggle floating",
|
description: "Toggle floating",
|
||||||
defaultKeySequence: "Meta+Space",
|
defaultKeySequence: "Meta+Space",
|
||||||
action: "windowToggleFloating",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "focus-left",
|
name: "focus-left",
|
||||||
description: "Move focus left",
|
description: "Move focus left",
|
||||||
defaultKeySequence: "Meta+A",
|
defaultKeySequence: "Meta+A",
|
||||||
action: "focusLeft",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "focus-right",
|
name: "focus-right",
|
||||||
description: "Move focus right",
|
description: "Move focus right",
|
||||||
comment: "Clashes with default KDE shortcuts, may require manual remapping",
|
comment: "Clashes with default KDE shortcuts, may require manual remapping",
|
||||||
defaultKeySequence: "Meta+D",
|
defaultKeySequence: "Meta+D",
|
||||||
action: "focusRight",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "focus-up",
|
name: "focus-up",
|
||||||
description: "Move focus up",
|
description: "Move focus up",
|
||||||
comment: "Clashes with default KDE shortcuts, may require manual remapping",
|
comment: "Clashes with default KDE shortcuts, may require manual remapping",
|
||||||
defaultKeySequence: "Meta+W",
|
defaultKeySequence: "Meta+W",
|
||||||
action: "focusUp",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "focus-down",
|
name: "focus-down",
|
||||||
description: "Move focus down",
|
description: "Move focus down",
|
||||||
comment: "Clashes with default KDE shortcuts, may require manual remapping",
|
comment: "Clashes with default KDE shortcuts, may require manual remapping",
|
||||||
defaultKeySequence: "Meta+S",
|
defaultKeySequence: "Meta+S",
|
||||||
action: "focusDown",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "focus-start",
|
name: "focus-start",
|
||||||
description: "Move focus to start",
|
description: "Move focus to start",
|
||||||
defaultKeySequence: "Meta+Home",
|
defaultKeySequence: "Meta+Home",
|
||||||
action: "focusStart",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "focus-end",
|
name: "focus-end",
|
||||||
description: "Move focus to end",
|
description: "Move focus to end",
|
||||||
defaultKeySequence: "Meta+End",
|
defaultKeySequence: "Meta+End",
|
||||||
action: "focusEnd",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "window-move-left",
|
name: "window-move-left",
|
||||||
description: "Move window left",
|
description: "Move window left",
|
||||||
comment: "Moves window out of and into columns",
|
comment: "Moves window out of and into columns",
|
||||||
defaultKeySequence: "Meta+Shift+A",
|
defaultKeySequence: "Meta+Shift+A",
|
||||||
action: "windowMoveLeft",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "window-move-right",
|
name: "window-move-right",
|
||||||
description: "Move window right",
|
description: "Move window right",
|
||||||
comment: "Moves window out of and into columns",
|
comment: "Moves window out of and into columns",
|
||||||
defaultKeySequence: "Meta+Shift+D",
|
defaultKeySequence: "Meta+Shift+D",
|
||||||
action: "windowMoveRight",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "window-move-up",
|
name: "window-move-up",
|
||||||
description: "Move window up",
|
description: "Move window up",
|
||||||
defaultKeySequence: "Meta+Shift+W",
|
defaultKeySequence: "Meta+Shift+W",
|
||||||
action: "windowMoveUp",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "window-move-down",
|
name: "window-move-down",
|
||||||
description: "Move window down",
|
description: "Move window down",
|
||||||
defaultKeySequence: "Meta+Shift+S",
|
defaultKeySequence: "Meta+Shift+S",
|
||||||
action: "windowMoveDown",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "window-move-start",
|
name: "window-move-start",
|
||||||
description: "Move window to start",
|
description: "Move window to start",
|
||||||
defaultKeySequence: "Meta+Shift+Home",
|
defaultKeySequence: "Meta+Shift+Home",
|
||||||
action: "windowMoveStart",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "window-move-end",
|
name: "window-move-end",
|
||||||
description: "Move window to end",
|
description: "Move window to end",
|
||||||
defaultKeySequence: "Meta+Shift+End",
|
defaultKeySequence: "Meta+Shift+End",
|
||||||
action: "windowMoveEnd",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "column-toggle-stacked",
|
name: "column-toggle-stacked",
|
||||||
description: "Toggle stacked layout for focused column",
|
description: "Toggle stacked layout for focused column",
|
||||||
comment: "One window in the column visible, others shaded; not supported on Wayland",
|
comment: "One window in the column visible, others shaded; not supported on Wayland",
|
||||||
defaultKeySequence: "Meta+X",
|
defaultKeySequence: "Meta+X",
|
||||||
action: "columnToggleStacked",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "column-move-left",
|
name: "column-move-left",
|
||||||
description: "Move column left",
|
description: "Move column left",
|
||||||
defaultKeySequence: "Meta+Ctrl+Shift+A",
|
defaultKeySequence: "Meta+Ctrl+Shift+A",
|
||||||
action: "columnMoveLeft",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "column-move-right",
|
name: "column-move-right",
|
||||||
description: "Move column right",
|
description: "Move column right",
|
||||||
defaultKeySequence: "Meta+Ctrl+Shift+D",
|
defaultKeySequence: "Meta+Ctrl+Shift+D",
|
||||||
action: "columnMoveRight",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "column-move-start",
|
name: "column-move-start",
|
||||||
description: "Move column to start",
|
description: "Move column to start",
|
||||||
defaultKeySequence: "Meta+Ctrl+Shift+Home",
|
defaultKeySequence: "Meta+Ctrl+Shift+Home",
|
||||||
action: "columnMoveStart",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "column-move-end",
|
name: "column-move-end",
|
||||||
description: "Move column to end",
|
description: "Move column to end",
|
||||||
defaultKeySequence: "Meta+Ctrl+Shift+End",
|
defaultKeySequence: "Meta+Ctrl+Shift+End",
|
||||||
action: "columnMoveEnd",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "column-width-increase",
|
name: "column-width-increase",
|
||||||
description: "Increase column width",
|
description: "Increase column width",
|
||||||
defaultKeySequence: "Meta+Ctrl++",
|
defaultKeySequence: "Meta+Ctrl++",
|
||||||
action: "columnWidthIncrease",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "column-width-decrease",
|
name: "column-width-decrease",
|
||||||
description: "Decrease column width",
|
description: "Decrease column width",
|
||||||
defaultKeySequence: "Meta+Ctrl+-",
|
defaultKeySequence: "Meta+Ctrl+-",
|
||||||
action: "columnWidthDecrease",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "columns-width-equalize",
|
name: "columns-width-equalize",
|
||||||
description: "Equalize widths of visible columns",
|
description: "Equalize widths of visible columns",
|
||||||
defaultKeySequence: "Meta+Ctrl+X",
|
defaultKeySequence: "Meta+Ctrl+X",
|
||||||
action: "columnsWidthEqualize",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "grid-scroll-focused",
|
name: "grid-scroll-focused",
|
||||||
description: "Center focused window",
|
description: "Center focused window",
|
||||||
comment: "Scrolls so that the focused window is centered in the screen",
|
comment: "Scrolls so that the focused window is centered in the screen",
|
||||||
defaultKeySequence: "Meta+Alt+Return",
|
defaultKeySequence: "Meta+Alt+Return",
|
||||||
action: "gridScrollFocused",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "grid-scroll-left-column",
|
name: "grid-scroll-left-column",
|
||||||
description: "Scroll one column to the left",
|
description: "Scroll one column to the left",
|
||||||
defaultKeySequence: "Meta+Alt+A",
|
defaultKeySequence: "Meta+Alt+A",
|
||||||
action: "gridScrollLeftColumn",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "grid-scroll-right-column",
|
name: "grid-scroll-right-column",
|
||||||
description: "Scroll one column to the right",
|
description: "Scroll one column to the right",
|
||||||
defaultKeySequence: "Meta+Alt+D",
|
defaultKeySequence: "Meta+Alt+D",
|
||||||
action: "gridScrollRightColumn",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "grid-scroll-left",
|
name: "grid-scroll-left",
|
||||||
description: "Scroll left",
|
description: "Scroll left",
|
||||||
defaultKeySequence: "Meta+Alt+PgUp",
|
defaultKeySequence: "Meta+Alt+PgUp",
|
||||||
action: "gridScrollLeft",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "grid-scroll-right",
|
name: "grid-scroll-right",
|
||||||
description: "Scroll right",
|
description: "Scroll right",
|
||||||
defaultKeySequence: "Meta+Alt+PgDown",
|
defaultKeySequence: "Meta+Alt+PgDown",
|
||||||
action: "gridScrollRight",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "grid-scroll-start",
|
name: "grid-scroll-start",
|
||||||
description: "Scroll to start",
|
description: "Scroll to start",
|
||||||
defaultKeySequence: "Meta+Alt+Home",
|
defaultKeySequence: "Meta+Alt+Home",
|
||||||
action: "gridScrollStart",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "grid-scroll-end",
|
name: "grid-scroll-end",
|
||||||
description: "Scroll to end",
|
description: "Scroll to end",
|
||||||
defaultKeySequence: "Meta+Alt+End",
|
defaultKeySequence: "Meta+Alt+End",
|
||||||
action: "gridScrollEnd",
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -183,7 +155,6 @@ const numKeyBindings: NumKeyBinding[] = [
|
|||||||
comment: "Clashes with default KDE shortcuts, may require manual remapping",
|
comment: "Clashes with default KDE shortcuts, may require manual remapping",
|
||||||
defaultModifiers: "Meta",
|
defaultModifiers: "Meta",
|
||||||
fKeys: false,
|
fKeys: false,
|
||||||
action: "focusColumn",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "window-move-to-column-",
|
name: "window-move-to-column-",
|
||||||
@@ -191,7 +162,6 @@ const numKeyBindings: NumKeyBinding[] = [
|
|||||||
comment: "Requires manual remapping according to your keyboard layout, e.g. Meta+Shift+1 -> Meta+!",
|
comment: "Requires manual remapping according to your keyboard layout, e.g. Meta+Shift+1 -> Meta+!",
|
||||||
defaultModifiers: "Meta+Shift",
|
defaultModifiers: "Meta+Shift",
|
||||||
fKeys: false,
|
fKeys: false,
|
||||||
action: "windowMoveToColumn",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "column-move-to-column-",
|
name: "column-move-to-column-",
|
||||||
@@ -199,20 +169,17 @@ const numKeyBindings: NumKeyBinding[] = [
|
|||||||
comment: "Requires manual remapping according to your keyboard layout, e.g. Meta+Ctrl+Shift+1 -> Meta+Ctrl+!",
|
comment: "Requires manual remapping according to your keyboard layout, e.g. Meta+Ctrl+Shift+1 -> Meta+Ctrl+!",
|
||||||
defaultModifiers: "Meta+Ctrl+Shift",
|
defaultModifiers: "Meta+Ctrl+Shift",
|
||||||
fKeys: false,
|
fKeys: false,
|
||||||
action: "columnMoveToColumn",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "column-move-to-desktop-",
|
name: "column-move-to-desktop-",
|
||||||
description: "Move column to desktop ",
|
description: "Move column to desktop ",
|
||||||
defaultModifiers: "Meta+Ctrl+Shift",
|
defaultModifiers: "Meta+Ctrl+Shift",
|
||||||
fKeys: true,
|
fKeys: true,
|
||||||
action: "columnMoveToDesktop",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "tail-move-to-desktop-",
|
name: "tail-move-to-desktop-",
|
||||||
description: "Move this and all following columns to desktop ",
|
description: "Move this and all following columns to desktop ",
|
||||||
defaultModifiers: "Meta+Ctrl+Shift+Alt",
|
defaultModifiers: "Meta+Ctrl+Shift+Alt",
|
||||||
fKeys: true,
|
fKeys: true,
|
||||||
action: "tailMoveToDesktop",
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ type KeyBinding = {
|
|||||||
description: string;
|
description: string;
|
||||||
comment?: string;
|
comment?: string;
|
||||||
defaultKeySequence: string;
|
defaultKeySequence: string;
|
||||||
action: keyof ReturnType<typeof Actions.init>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type NumKeyBinding = {
|
type NumKeyBinding = {
|
||||||
@@ -12,7 +11,6 @@ type NumKeyBinding = {
|
|||||||
comment?: string;
|
comment?: string;
|
||||||
defaultModifiers: string;
|
defaultModifiers: string;
|
||||||
fKeys: boolean;
|
fKeys: boolean;
|
||||||
action: keyof ReturnType<typeof Actions.initNum>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function catchWrap(f: () => void) {
|
function catchWrap(f: () => void) {
|
||||||
@@ -26,45 +24,43 @@ function catchWrap(f: () => void) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerKeyBinding(name: string, description: string, keySequence: string, callback: () => void) {
|
function registerKeyBinding(world: World, config: Actions.Config, shortcutActions: ShortcutAction[], keyBinding: KeyBinding) {
|
||||||
KWin.registerShortcut(
|
shortcutActions.push(new ShortcutAction(
|
||||||
"karousel-" + name,
|
keyBinding,
|
||||||
"Karousel: " + description,
|
catchWrap(Actions.getAction(world, config, keyBinding.name)),
|
||||||
keySequence,
|
));
|
||||||
catchWrap(callback),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerNumKeyBindings(name: string, description: string, modifiers: string, fKeys: boolean, callback: (i: number) => void) {
|
function registerNumKeyBindings(world: World, shortcutActions: ShortcutAction[], numKeyBinding: NumKeyBinding) {
|
||||||
const numPrefix = fKeys ? "F" : "";
|
const numPrefix = numKeyBinding.fKeys ? "F" : "";
|
||||||
const n = fKeys ? 12 : 9;
|
const n = numKeyBinding.fKeys ? 12 : 9;
|
||||||
for (let i = 0; i < 12; i++) {
|
for (let i = 0; i < 12; i++) {
|
||||||
const numKey = String(i + 1);
|
const numKey = String(i + 1);
|
||||||
const keySequence = i < n ?
|
const keySequence = i < n ?
|
||||||
modifiers + "+" + numPrefix + numKey :
|
numKeyBinding.defaultModifiers + "+" + numPrefix + numKey :
|
||||||
"";
|
"";
|
||||||
registerKeyBinding(
|
const action = Actions.getNumAction(world, numKeyBinding.name);
|
||||||
name + numKey,
|
shortcutActions.push(new ShortcutAction(
|
||||||
description + numKey,
|
{
|
||||||
keySequence,
|
name: numKeyBinding.name + numKey,
|
||||||
() => callback(i),
|
description: numKeyBinding.description + numKey,
|
||||||
);
|
defaultKeySequence: keySequence,
|
||||||
|
},
|
||||||
|
catchWrap(() => action(i)),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerKeyBindings(world: World, config: Config) {
|
function registerKeyBindings(world: World, config: Actions.Config) {
|
||||||
const actions = Actions.init(world, {
|
const shortcutActions: ShortcutAction[] = [];
|
||||||
manualScrollStep: config.manualScrollStep,
|
|
||||||
manualResizeStep: config.manualResizeStep,
|
|
||||||
columnResizer: config.scrollingCentered ? new RawResizer() : new ContextualResizer(),
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const binding of keyBindings) {
|
for (const keyBinding of keyBindings) {
|
||||||
registerKeyBinding(binding.name, binding.description, binding.defaultKeySequence, actions[binding.action]);
|
registerKeyBinding(world, config, shortcutActions, keyBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
const numActions = Actions.initNum(world);
|
for (const numKeyBinding of numKeyBindings) {
|
||||||
for (const binding of numKeyBindings) {
|
registerNumKeyBindings(world, shortcutActions, numKeyBinding);
|
||||||
registerNumKeyBindings(binding.name, binding.description, binding.defaultModifiers, binding.fKeys, numActions[binding.action]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return shortcutActions;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
function init() {
|
function init() {
|
||||||
const config = loadConfig();
|
return new World(loadConfig());
|
||||||
const world = new World(config);
|
|
||||||
registerKeyBindings(world, config);
|
|
||||||
return world;
|
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/utils/ShortcutAction.ts
Normal file
25
src/utils/ShortcutAction.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
class ShortcutAction {
|
||||||
|
private readonly shortcutHandler: ShortcutHandler;
|
||||||
|
|
||||||
|
constructor(keyBinding: KeyBinding, f: () => void) {
|
||||||
|
this.shortcutHandler = ShortcutAction.initShortcutHandler(keyBinding);
|
||||||
|
this.shortcutHandler.activated.connect(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public destroy() {
|
||||||
|
this.shortcutHandler.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static initShortcutHandler(keyBinding: KeyBinding) {
|
||||||
|
return Qt.createQmlObject(
|
||||||
|
`import QtQuick 6.0
|
||||||
|
import org.kde.kwin 3.0
|
||||||
|
ShortcutHandler {
|
||||||
|
name: "karousel-${keyBinding.name}";
|
||||||
|
text: "Karousel: ${keyBinding.description}";
|
||||||
|
sequence: "${keyBinding.defaultKeySequence}";
|
||||||
|
}`,
|
||||||
|
qmlBase,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,11 +4,17 @@ class World {
|
|||||||
public readonly clientManager: ClientManager;
|
public readonly clientManager: ClientManager;
|
||||||
private readonly pinManager: PinManager;
|
private readonly pinManager: PinManager;
|
||||||
private readonly workspaceSignalManager: SignalManager;
|
private readonly workspaceSignalManager: SignalManager;
|
||||||
|
private readonly shortcutActions: ShortcutAction[];
|
||||||
private readonly screenResizedDelayer: Delayer;
|
private readonly screenResizedDelayer: Delayer;
|
||||||
|
|
||||||
constructor(config: Config) {
|
constructor(config: Config) {
|
||||||
this.untileOnDrag = config.untileOnDrag;
|
this.untileOnDrag = config.untileOnDrag;
|
||||||
this.workspaceSignalManager = initWorkspaceSignalHandlers(this);
|
this.workspaceSignalManager = initWorkspaceSignalHandlers(this);
|
||||||
|
this.shortcutActions = registerKeyBindings(this, {
|
||||||
|
manualScrollStep: config.manualScrollStep,
|
||||||
|
manualResizeStep: config.manualResizeStep,
|
||||||
|
columnResizer: config.scrollingCentered ? new RawResizer() : new ContextualResizer(),
|
||||||
|
});
|
||||||
|
|
||||||
this.screenResizedDelayer = new Delayer(1000, () => {
|
this.screenResizedDelayer = new Delayer(1000, () => {
|
||||||
// this delay ensures that docks are taken into account by `Workspace.clientArea`
|
// this delay ensures that docks are taken into account by `Workspace.clientArea`
|
||||||
@@ -96,6 +102,9 @@ class World {
|
|||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
this.workspaceSignalManager.destroy();
|
this.workspaceSignalManager.destroy();
|
||||||
|
for (const shortcutAction of this.shortcutActions) {
|
||||||
|
shortcutAction.destroy();
|
||||||
|
}
|
||||||
this.clientManager.destroy();
|
this.clientManager.destroy();
|
||||||
this.desktopManager.destroy();
|
this.desktopManager.destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user