Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tiling-assistant@leleat-on-github/prefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export default class Prefs extends ExtensionPreferences {
'show-layout-panel-indicator',
'enable-advanced-experimental-features',
'disable-tile-groups',
'move-to-adjacent-monitor',
'low-performance-move-mode',
'enable-layout-picker',
'monitor-switch-grace-period',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@
<key name="disable-tile-groups" type="b">
<default>false</default>
</key>
<key name="move-to-adjacent-monitor" type="b">
<!-- Repeating tile left/right half moves the window to the adjacent monitor -->
<default>false</default>
</key>
<key name="default-move-mode" type="i">
<!-- 0: Edge Tiling, 1: Adaptive Tiling, 2: Favorite Layout, 3: Ignore TA -->
<default>0</default>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ export default class TilingKeybindingHandler {
Twm.toggleTiling(window, rect, { ignoreTA: true });
// Tile a window
} else {
if (Settings.getBoolean('move-to-adjacent-monitor') &&
this._moveToAdjacentMonitor(window, shortcutName))
return;

const dynamicSetting = Settings.getInt('dynamic-keybinding-behavior');
const windowsStyle = DynamicKeybindings.TILING_STATE_WINDOWS;
const isWindowsStyle = dynamicSetting === windowsStyle;
Expand Down Expand Up @@ -324,6 +328,72 @@ export default class TilingKeybindingHandler {
});
}

/**
* Rectangle-style monitor traversal: repeating 'tile left/right half' on a
* window that already fills that side of its monitor moves it to the
* adjacent monitor in that direction, tiled to the opposite half. Past the
* last monitor it wraps around to the far monitor on the other side.
*
* @param {Meta.Window} window a Meta.Window.
* @param {string} shortcutName the shortcut.
* @returns {boolean} whether the shortcut was handled.
*/
_moveToAdjacentMonitor(window, shortcutName) {
const isLeft = shortcutName === 'tile-left-half';
if (!isLeft && shortcutName !== 'tile-right-half')
return false;

if (!window.isTiled || !window.tiledRect)
return false;

const workArea = new Rect(window.get_work_area_current_monitor());
const wRect = window.tiledRect;
const isFullHeight =
wRect.y === workArea.y &&
wRect.height === workArea.height;
const isOnThatSide = isLeft
? wRect.x === workArea.x && wRect.width !== workArea.width
: wRect.x2 === workArea.x2 && wRect.x !== workArea.x;
if (!isFullHeight || !isOnThatSide)
return false;

const monitor = window.get_monitor();
const direction = isLeft ? Meta.DisplayDirection.LEFT : Meta.DisplayDirection.RIGHT;
let target = global.display.get_monitor_neighbor_index(monitor, direction);
if (target === -1)
target = this._getFarthestMonitor(monitor, isLeft ? Meta.DisplayDirection.RIGHT : Meta.DisplayDirection.LEFT);

// Single monitor: nowhere to go, but don't untile either.
if (target === monitor)
return true;

const targetWorkArea = new Rect(window.get_work_area_for_monitor(target));
const oppositeHalf = isLeft ? 'tile-right-half' : 'tile-left-half';
const rect = Twm.getTileFor(oppositeHalf, targetWorkArea, target);
Twm.tile(window, rect, { monitorNr: target }).catch(logError);
return true;
}

/**
* @param {number} monitor the monitor index to start from.
* @param {Meta.DisplayDirection} direction the direction to walk in.
* @returns {number} the last monitor reached by following neighbors from
* `monitor` in `direction`, or `monitor` itself if it has none.
*/
_getFarthestMonitor(monitor, direction) {
let farthest = monitor;
// Bounded by the monitor count in case neighbors ever form a cycle.
for (let i = 0; i < global.display.get_n_monitors(); i++) {
const next = global.display.get_monitor_neighbor_index(farthest, direction);
if (next === -1)
break;

farthest = next;
}

return farthest;
}

/**
* Changes the tiling state of the `window` based on its current tiling
* state and the activated shortcut.
Expand Down
14 changes: 14 additions & 0 deletions tiling-assistant@leleat-on-github/src/ui/prefs.ui
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,20 @@
</object>
</child>
<!-- ======================================================================================== -->
<!-- = Group: Multi-Monitor ================================================================= -->
<!-- ======================================================================================== -->
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes" comments="Translators: This is the header for a preference group in the 'General' tab">Multi-Monitor</property>
<child>
<object class="AdwSwitchRow" id="move_to_adjacent_monitor">
<property name="title" translatable="yes" comments="Translators: This is a setting in the 'Multi-Monitor' preference group in the 'General' tab">Move to Adjacent Monitor on Repeat</property>
<property name="subtitle" translatable="yes" comments="Translators: This is the explanation for the 'Move to Adjacent Monitor on Repeat' setting in the 'General' tab">Tiling a window to the left or right half again moves it to the next monitor in that direction, tiled to the opposite half, wrapping around past the last monitor.</property>
</object>
</child>
</object>
</child>
<!-- ======================================================================================== -->
<!-- = Group: Focus Hint ==================================================================== -->
<!-- ======================================================================================== -->
<child>
Expand Down
Loading