Skip to content

Commit 57a9f50

Browse files
committed
version 16: introducing windows suggestions
1 parent 31370e0 commit 57a9f50

22 files changed

+1631
-1031
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ This is a Gnome Shell extension implementing modern windows tiling system by ext
2424

2525
<img src="https://github.com/domferr/tilingshell/blob/main/doc/horiz_summary.jpg" align="center"/>
2626

27+
<details>
28+
<summary><span align="center">See here the video overview</span></summary>
29+
30+
https://github.com/user-attachments/assets/2905f0a1-ecd4-47b5-a6bc-59f91716e685
31+
</details>
32+
2733
Have issues, you want to suggest a new feature or contribute? Please open a new [issue](https://github.com/domferr/tilingshell/issues)!
2834

2935
## Usage ##

doc/TilingShellOverview.mp4

459 KB
Binary file not shown.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tilingshell",
3-
"version": "15.1",
3+
"version": "16.0",
44
"author": "Domenico Ferraro <[email protected]>",
55
"private": true,
66
"license": "GPL v2.0",
@@ -13,7 +13,7 @@
1313
"build:package": "npm run clean:package; npm run build && cd ./dist && zip -qr ../[email protected] * && cd ../dist_legacy && zip -qr ../[email protected] *",
1414
"clean:package": "rm -rf './dist/[email protected]'; rm -rf './dist_legacy/[email protected]'",
1515
"install:extension": "mkdir -p ~/.local/share/gnome-shell/extensions/[email protected] && cp ./dist$([ $(gnome-shell --version | grep -o -E '[0-9]+' | head -n 1) -le 44 ] && echo '_legacy')/* ~/.local/share/gnome-shell/extensions/[email protected]/ -r",
16-
"wayland-session": "dbus-run-session -- gnome-shell --nested --wayland",
16+
"wayland-session": "dbus-run-session -- env MUTTER_DEBUG_NUM_DUMMY_MONITORS=1 MUTTER_DEBUG_DUMMY_MODE_SPECS=1920x1080 gnome-shell --nested --wayland",
1717
"dev:wayland": "npm run build && npm run install:extension && npm run wayland-session",
1818
"build:translations": "for file in $(ls translations/*.po); do mkdir -p resources/locale/$(basename $file .po)/LC_MESSAGES; msgfmt -c $file -o resources/locale/$(basename $file .po)/LC_MESSAGES/tilingshell.mo; done",
1919
"create:translations": "xgettext --from-code=UTF-8 --output=translations/[email protected] -j --language=javascript --force-po dist/prefs.js dist/extension.js",

resources/metadata.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Tiling Shell",
3-
"description": "Extend Gnome Shell with advanced tiling window management. Supports multiple monitors, Windows 11 Snap Assistant, Fancy Zones, customised tiling layouts and more.",
3+
"description": "Extend Gnome Shell with advanced tiling window management. Supports multiple monitors, Windows 11 Snap Assistant, Fancy Zones, automatic tiling, keyboard shortcuts, customised tiling layouts and more!",
44
"uuid": "[email protected]",
55
"shell-version": [
66
"42",
@@ -11,11 +11,12 @@
1111
"47"
1212
],
1313
"version": 99,
14-
"version-name": "15.1",
14+
"version-name": "16.0",
1515
"url": "https://github.com/domferr/tilingshell",
1616
"settings-schema": "org.gnome.shell.extensions.tilingshell",
1717
"gettext-domain": "tilingshell",
1818
"donations": {
19-
"kofi": "domferr"
19+
"kofi": "domferr",
20+
"patreon": "domferr"
2021
}
2122
}

resources/schemas/org.gnome.shell.extensions.tilingshell.gschema.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,21 @@
157157
<summary>Tile animation time (milliseconds)</summary>
158158
<description>Animation time in milliseconds of the tiles</description>
159159
</key>
160+
<key name="enable-tiling-system-windows-suggestions" type="b">
161+
<default>false</default>
162+
<summary>Enable window suggestions for the tiling system</summary>
163+
<description>Provides smart suggestions to fill empty tiles when using the tiling system.</description>
164+
</key>
165+
<key name="enable-snap-assistant-windows-suggestions" type="b">
166+
<default>false</default>
167+
<summary>Enable window suggestions for the snap assistant</summary>
168+
<description>Offers suggestions to populate empty tiles when using the snap assistant.</description>
169+
</key>
170+
<key name="enable-screen-edges-windows-suggestions" type="b">
171+
<default>false</default>
172+
<summary>Enable window suggestions for screen edge snapping</summary>
173+
<description>Suggests windows to occupy empty tiles when snapping to screen edges.</description>
174+
</key>
160175

161176
<!-- keybindings -->
162177
<key type="as" name="move-window-right">

src/components/layout/LayoutWidget.ts

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ export default class LayoutWidget<
3535
protected _layout: Layout;
3636
protected _innerGaps: Clutter.Margin;
3737
protected _outerGaps: Clutter.Margin;
38+
protected _scalingFactor: number;
3839

3940
constructor(params: LayoutWidgetConstructorProperties) {
4041
super({ styleClass: params.styleClass || '' });
4142
params.parent.add_child(this);
43+
this._scalingFactor = 1;
4244
if (params.scalingFactor) this.scalingFactor = params.scalingFactor;
4345

4446
this._previews = [];
@@ -50,6 +52,11 @@ export default class LayoutWidget<
5052

5153
public set scalingFactor(value: number) {
5254
enableScalingFactorSupport(this, value);
55+
this._scalingFactor = value;
56+
}
57+
58+
public get scalingFactor(): number {
59+
return this._scalingFactor;
5360
}
5461

5562
public get innerGaps(): Clutter.Margin {
@@ -60,6 +67,10 @@ export default class LayoutWidget<
6067
return this._outerGaps.copy();
6168
}
6269

70+
public get layout(): Layout {
71+
return this._layout;
72+
}
73+
6374
protected draw_layout(): void {
6475
this._previews = this._layout.tiles.map((tile) => {
6576
const tileRect = TileUtils.apply_props(tile, this._containerRect);
@@ -93,21 +104,27 @@ export default class LayoutWidget<
93104
}>,
94105
): boolean {
95106
let trigger_relayout = this._previews.length === 0;
107+
if (params?.layout && this._layout !== params.layout) {
108+
this._layout = params.layout;
109+
trigger_relayout = true;
110+
}
96111
if (params?.innerGaps) {
112+
trigger_relayout ||= !this._areGapsEqual(
113+
this._innerGaps,
114+
params.innerGaps,
115+
);
97116
this._innerGaps = params.innerGaps.copy();
98-
trigger_relayout = true;
99117
}
100118
if (params?.outerGaps && this._outerGaps !== params.outerGaps) {
119+
trigger_relayout ||= !this._areGapsEqual(
120+
this._outerGaps,
121+
params.outerGaps,
122+
);
101123
this._outerGaps = params.outerGaps.copy();
102-
trigger_relayout = true;
103-
}
104-
if (params?.layout && this._layout !== params.layout) {
105-
this._layout = params.layout;
106-
trigger_relayout = true;
107124
}
108125
if (
109126
params?.containerRect &&
110-
this._containerRect !== params.containerRect
127+
!this._containerRect.equal(params.containerRect)
111128
) {
112129
this._containerRect = params.containerRect.copy();
113130
trigger_relayout = true;
@@ -132,4 +149,16 @@ export default class LayoutWidget<
132149

133150
return true;
134151
}
152+
153+
private _areGapsEqual(
154+
first: Clutter.Margin,
155+
second: Clutter.Margin,
156+
): boolean {
157+
return (
158+
first.bottom === second.bottom &&
159+
first.top === second.top &&
160+
first.left === second.left &&
161+
first.right === second.right
162+
);
163+
}
135164
}

src/components/snapassist/snapAssist.ts

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class SnapAssistContent extends St.BoxLayout {
5757
private _signals: SignalHandling;
5858
private _snapAssistLayouts: SnapAssistLayout[];
5959
private _isEnlarged = false;
60-
private _hoveredTile: SnapAssistTile | undefined;
60+
private _hoveredInfo: [SnapAssistTile, SnapAssistLayout] | undefined;
6161
private _bottomPadding: number;
6262
private _blur: boolean;
6363
private _snapAssistantThreshold: number;
@@ -263,24 +263,32 @@ class SnapAssistContent extends St.BoxLayout {
263263
const wasEnlarged = this._isEnlarged;
264264
this.handleOpening(window, ease, currPointerPos);
265265
if (!this._showing || !this._isEnlarged) {
266-
if (this._hoveredTile) this._hoveredTile.set_hover(false);
266+
if (this._hoveredInfo) this._hoveredInfo[0].set_hover(false);
267267

268-
this._hoveredTile = undefined;
268+
this._hoveredInfo = undefined;
269269
if (wasEnlarged) {
270270
this._container.emit(
271271
SNAP_ASSIST_SIGNAL,
272272
new Tile({ x: 0, y: 0, width: 0, height: 0, groups: [] }),
273+
'',
273274
);
274275
}
275276
return;
276277
}
277278

278-
const changed = this.handleTileHovering(currPointerPos);
279-
if (changed) {
279+
const layoutHovered = this.handleTileHovering(currPointerPos);
280+
if (layoutHovered) {
281+
const snapTile = this._hoveredInfo
282+
? this._hoveredInfo[0]
283+
: undefined;
284+
const snapLay = this._hoveredInfo
285+
? this._hoveredInfo[1]
286+
: undefined;
280287
const tile =
281-
this._hoveredTile?.tile ||
288+
snapTile?.tile ||
282289
new Tile({ x: 0, y: 0, width: 0, height: 0, groups: [] });
283-
this._container.emit(SNAP_ASSIST_SIGNAL, tile);
290+
const layoutId = snapLay?.layout.id ?? '';
291+
this._container.emit(SNAP_ASSIST_SIGNAL, tile, layoutId);
284292
}
285293
}
286294

@@ -339,25 +347,33 @@ class SnapAssistContent extends St.BoxLayout {
339347
y: number;
340348
}): boolean {
341349
if (!this._isEnlarged) {
342-
const changed = this._hoveredTile !== undefined;
343-
if (this._hoveredTile) this._hoveredTile.set_hover(false);
350+
const changed = this._hoveredInfo !== undefined;
351+
if (this._hoveredInfo) this._hoveredInfo[0].set_hover(false);
344352

345-
this._hoveredTile = undefined;
353+
this._hoveredInfo = undefined;
346354
return changed;
347355
}
348356

349357
let newTileHovered: SnapAssistTile | undefined;
358+
let layoutHovered: SnapAssistLayout | undefined;
350359
for (let index = 0; index < this._snapAssistLayouts.length; index++) {
351-
const snapAssistLay = this._snapAssistLayouts[index];
352-
newTileHovered = snapAssistLay.getTileBelow(currPointerPos);
353-
if (newTileHovered) break;
360+
newTileHovered =
361+
this._snapAssistLayouts[index].getTileBelow(currPointerPos);
362+
if (newTileHovered) {
363+
layoutHovered = this._snapAssistLayouts[index];
364+
break;
365+
}
354366
}
355-
const tileChanged = newTileHovered !== this._hoveredTile;
367+
368+
const oldTile = this._hoveredInfo ? this._hoveredInfo[0] : undefined;
369+
const tileChanged = newTileHovered !== oldTile;
356370
if (tileChanged) {
357-
this._hoveredTile?.set_hover(false);
358-
this._hoveredTile = newTileHovered;
371+
oldTile?.set_hover(false);
372+
if (newTileHovered === undefined || layoutHovered === undefined)
373+
this._hoveredInfo = undefined;
374+
else this._hoveredInfo = [newTileHovered, layoutHovered];
359375
}
360-
if (this._hoveredTile) this._hoveredTile.set_hover(true);
376+
if (this._hoveredInfo) this._hoveredInfo[0].set_hover(true);
361377

362378
return tileChanged;
363379
}
@@ -373,7 +389,7 @@ export default class SnapAssist extends St.Widget {
373389
GTypeName: 'SnapAssist',
374390
Signals: {
375391
'snap-assist': {
376-
param_types: [Tile.$gtype],
392+
param_types: [Tile.$gtype, String.$gtype], // tile, layout_id
377393
},
378394
},
379395
};

src/components/tilepreview/popupTilePreview.ts

Lines changed: 0 additions & 95 deletions
This file was deleted.

0 commit comments

Comments
 (0)