| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- import {Position} from './position.js';
- import Meta from 'gi://Meta';
- import {Direction, TileWindowManager} from './tileWindowManager.js';
- import GLib from 'gi://GLib';
- export var Orientation;
- (function (Orientation) {
- Orientation[Orientation['Vertical'] = 1] = 'Vertical';
- Orientation[Orientation['Horizontal'] = 2] = 'Horizontal';
- Orientation[Orientation['None'] = 3] = 'None';
- })(Orientation || (Orientation = {}));
- export var TileState;
- (function (TileState) {
- TileState[TileState['DEFAULT'] = 0] = 'DEFAULT';
- TileState[TileState['MINIMIZED'] = 1] = 'MINIMIZED';
- TileState[TileState['MAXIMIZED'] = 2] = 'MAXIMIZED';
- TileState[TileState['ALONE_MAXIMIZED'] = 3] = 'ALONE_MAXIMIZED';
- })(TileState || (TileState = {}));
- export class Tile {
- id;
- _leaf;
- _parent;
- _child1;
- _child2;
- _position;
- _window;
- _state;
- _orientation;
- _updateSource;
- _workspace;
- _nr_tiles;
- _monitor;
- _adjacents;
- static padding = 0;
- static id_count = 0;
- static fullscreen;
- constructor() {
- this.id = Tile.id_count++;
- this._position = new Position();
- this._window = null;
- this._state = TileState.DEFAULT;
- this._leaf = true;
- this._parent = null;
- this._child1 = null;
- this._child2 = null;
- this._orientation = Orientation.None;
- this._nr_tiles = 0;
- this._workspace = 0;
- this._updateSource = null;
- // west / east / north / south
- this._adjacents = [false, false, false, false];
- }
- /** Tile factory
- *
- * @param {Meta.Window} window
- * @param {Position} position
- * @param {number} monitor
- * @param {Tile | null} parent
- * @returns
- */
- static createTileLeaf(window, position, monitor, parent = null) {
- let tile = new Tile();
- tile._window = window;
- tile._position = position;
- tile._monitor = monitor;
- tile._parent = parent;
- tile._leaf = true;
- tile._nr_tiles = 1;
- tile._workspace = 0;
- tile.findAdjacents();
- return tile;
- }
- decrementTiles() {
- this._nr_tiles--;
- if (this._parent)
- this._parent.decrementTiles();
- }
- addWindowOnBlock(window) {
- if (this.leaf) {
- if (!this._window)
- throw new Error('A leaf must have a window');
- let newPositions = this._position.split();
- let c1 = Tile.createTileLeaf(this._window, newPositions[0], this.monitor, this);
- c1._state = this._state;
- this._window.tile = c1;
- let c2 = Tile.createTileLeaf(window, newPositions[1], this.monitor, this);
- window.tile = c2;
- this._window = null;
- this._leaf = false;
- this._child1 = c1;
- this._child2 = c2;
- this._nr_tiles++;
- this._orientation = this._position.width > this._position.height
- ? Orientation.Horizontal : Orientation.Vertical;
- c1.findAdjacents();
- c2.findAdjacents();
- } else if (this._child1 && this._child2) {
- if (this._child1?._nr_tiles > this._child2?._nr_tiles)
- this._child2.addWindowOnBlock(window);
- else
- this._child1.addWindowOnBlock(window);
- this._nr_tiles++;
- } else {
- throw new Error('Unexpected state to add window');
- }
- }
- removeTile() {
- if (this._window == null || this._child1 || this._child2 || !this._leaf)
- throw new Error('Invalid remove state');
- let parent = this._parent;
- if (!parent)
- return null;
- if (parent._child1 === this && parent._child2) {
- parent._leaf = parent._child2._leaf;
- parent._orientation = parent._child2._orientation;
- parent._window = parent._child2._window;
- parent._child1 = parent._child2._child1;
- parent._child2 = parent._child2._child2;
- } else if (parent._child2 === this && parent._child1) {
- parent._leaf = parent._child1._leaf;
- parent._orientation = parent._child1._orientation;
- parent._window = parent._child1._window;
- parent._child2 = parent._child1._child2;
- parent._child1 = parent._child1._child1;
- } else {
- return this;
- }
- if (parent._child1)
- parent._child1._parent = parent;
- if (parent._child2)
- parent._child2._parent = parent;
- if (parent._window)
- parent._window.tile = parent;
- parent.resize(parent._position);
- parent.decrementTiles();
- return parent;
- }
- /** Update tile position and its children size
- *
- * @param {Position} position
- */
- resize(position) {
- this._position = position;
- if (!this._window) {
- let newPositions = this._position.split(this._orientation);
- this._child1?.resize(newPositions[this._child1.position.index]);
- this._child2?.resize(newPositions[this._child2.position.index]);
- }
- }
- forEach(fn) {
- fn(this);
- this._child1?.forEach(fn);
- this._child2?.forEach(fn);
- }
- update() {
- if (this._window) {
- if (!this._window.isAlive)
- return;
- if (this._state === TileState.MAXIMIZED) {
- this._window?._originalMaximize(Meta.MaximizeFlags.BOTH);
- return;
- } else if (this._state === TileState.MINIMIZED) {
- this._window?._originalMinimize();
- return;
- }
- if (this._window.minimized)
- this._window.unminimize();
- if (this._position.proportion === 1) {
- this.state = TileState.ALONE_MAXIMIZED;
- if (this._window.maximized_horizontally || this._window.maximized_vertically)
- this._window.unmaximize(Meta.MaximizeFlags.BOTH);
- const workspc = this._window.get_workspace();
- const area = workspc?.get_work_area_for_monitor(this._monitor ? this._monitor : 0);
- if (!area)
- return;
- this._position.x = 0;
- this._position.y = 0;
- this._position.width = area.width;
- this._position.height = area.height;
- this._window?.move_resize_frame(true, area.x + this._position.x + (this._adjacents[0] ? Tile.padding / 2 : Tile.padding), area.y + this._position.y + (this._adjacents[2] ? Tile.padding / 2 : Tile.padding), this._position.width - (this._adjacents[1] ? Tile.padding * 1.5 : Tile.padding * 2), this._position.height - (this._adjacents[3] ? Tile.padding * 1.5 : Tile.padding * 2));
- if (this._updateSource !== null)
- GLib.Source.remove(this._updateSource);
- this._updateSource = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
- this._window?.move_frame(true, area.x + this._position.x + (this._adjacents[0] ? Tile.padding / 2 : Tile.padding), area.y + this._position.y + (this._adjacents[2] ? Tile.padding / 2 : Tile.padding));
- this._updateSource = null;
- return GLib.SOURCE_REMOVE;
- });
- } else {
- this.state = TileState.DEFAULT;
- if (this._window.maximized_horizontally || this._window.maximized_vertically)
- this._window.unmaximize(Meta.MaximizeFlags.BOTH);
- const workspc = this._window.get_workspace();
- const area = workspc?.get_work_area_for_monitor(this._monitor ? this._monitor : 0);
- if (!area)
- return;
- this._window?.move_resize_frame(true, area.x + this._position.x + (this._adjacents[0] ? Tile.padding / 2 : Tile.padding), area.y + this._position.y + (this._adjacents[2] ? Tile.padding / 2 : Tile.padding), this._position.width - (this._adjacents[1] ? Tile.padding * 1.5 : Tile.padding * 2), this._position.height - (this._adjacents[3] ? Tile.padding * 1.5 : Tile.padding * 2));
- if (this._updateSource !== null)
- GLib.Source.remove(this._updateSource);
- this._updateSource = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
- this._window?.move_frame(true, area.x + this._position.x + (this._adjacents[0] ? Tile.padding / 2 : Tile.padding), area.y + this._position.y + (this._adjacents[2] ? Tile.padding / 2 : Tile.padding));
- this._updateSource = null;
- return GLib.SOURCE_REMOVE;
- });
- }
- } else {
- this._child1?.update();
- this._child2?.update();
- }
- }
- /** Leaf to root research
- *
- * @param {(el : Tile) => boolean} fn
- * @returns
- */
- findParent(fn) {
- if (fn(this)) {
- if (!this._parent)
- return this;
- let res = this._parent.findParent(fn);
- if (res)
- return res;
- else
- return this;
- } else {
- return null;
- }
- }
- /** Classic recursive traversal on tree
- *
- * @param {(el : Tile) => boolean} fn
- * @returns
- */
- find(fn) {
- if (fn(this)) {
- return this;
- } else {
- let r1 = this.child1?.find(fn);
- if (r1)
- return r1;
- let r2 = this.child2?.find(fn);
- if (r2)
- return r2;
- return null;
- }
- }
- getSibling() {
- if (this === this?._parent?._child1)
- return this?._parent?._child2;
- else if (this === this?._parent?._child2)
- return this?._parent?._child1;
- else
- return null;
- }
- contains(window) {
- if (this._window?.get_id() === window.get_id())
- return true;
- return !!(this.child1?.contains(window) || this.child2?.contains(window));
- }
- addToChild() {
- if (this._child1 && this._child2) {
- this._child1.parent = this;
- this._child2.parent = this;
- this._child1.addToChild();
- this._child2.addToChild();
- }
- }
- static fromObject(obj, parent = null) {
- let tile = new Tile();
- if (obj._child1 && obj._child2)
- tile.setChild(Tile.fromObject(obj._child1, tile), Tile.fromObject(obj._child2, tile));
- tile.position = Position.fromObject(obj._position);
- tile.state = obj._state;
- tile.leaf = obj._leaf;
- tile.orientation = obj._orientation;
- tile.monitor = obj._monitor;
- tile.nr_tiles = obj._nr_tiles;
- tile.window = obj._window;
- tile.adjacents = obj._adjacents;
- tile.workspace = obj._workspace;
- if (parent)
- tile.parent = parent;
- if (tile.window)
- tile.window.tile = tile;
- return tile;
- }
- findAdjacents() {
- let _monitor = TileWindowManager.getMonitors()[this.monitor];
- let w = _monitor.closestTile(this, Direction.West);
- let e = _monitor.closestTile(this, Direction.East);
- let n = _monitor.closestTile(this, Direction.North);
- let s = _monitor.closestTile(this, Direction.South);
- this._adjacents = [w !== null, e !== null, n !== null, s !== null];
- }
- setChild(child1, child2) {
- this._child1 = child1;
- this._child2 = child2;
- }
- destroy() {
- if (this._updateSource !== null)
- GLib.Source.remove(this._updateSource);
- this._updateSource = null;
- this._window = null;
- }
- /** *********************/
- /* GETTERS AND SETTERS */
- set orientation(o) {
- this._orientation = o;
- }
- get orientation() {
- return this._orientation;
- }
- set parent(p) {
- this._parent = p;
- }
- get parent() {
- return this._parent;
- }
- get nr_tiles() {
- return this._nr_tiles;
- }
- set nr_tiles(n) {
- this._nr_tiles = n;
- }
- get child1() {
- return this._child1;
- }
- get child2() {
- return this._child2;
- }
- set position(pos) {
- this._position = pos;
- }
- get position() {
- return this._position;
- }
- set window(w) {
- this._window = w;
- }
- get window() {
- return this._window;
- }
- set state(value) {
- this._state = value;
- }
- get state() {
- return this._state;
- }
- set monitor(m) {
- this._monitor = m;
- }
- get monitor() {
- return this._monitor ? this._monitor : 0;
- }
- get adjacents() {
- return this._adjacents;
- }
- set adjacents(adj) {
- this._adjacents = adj;
- }
- set workspace(w) {
- this._workspace = w;
- }
- get workspace() {
- return this._workspace;
- }
- get leaf() {
- return this._leaf;
- }
- set leaf(b) {
- this._leaf = b;
- }
- }
|