__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
import {
    Atk,
    Clutter,
    Gio,
    GLib,
    GObject,
    Meta,
    Shell,
    St
} from '../dependencies/gi.js';
import {
    Extension,
    Main
} from '../dependencies/shell.js';
import {
    AppSwitcherPopup,
    AppIcon as BaseAppIcon,
    baseIconSizes,
    APP_ICON_HOVER_TIMEOUT
} from '../dependencies/unexported/altTab.js';
import * as SwitcherPopup from '../dependencies/unexported/switcherPopup.js';

import { Settings } from '../common.js';
import { TilingWindowManager as Twm } from './tilingWindowManager.js';

/**
 * Optionally, override GNOME's altTab / appSwitcher to group tileGroups
 */
export default class AltTabOverride {
    constructor() {
        if (Settings.getBoolean('tilegroups-in-app-switcher'))
            this._overrideNativeAppSwitcher();

        this._settingsId = Settings.changed('tilegroups-in-app-switcher', () => {
            if (Settings.getBoolean('tilegroups-in-app-switcher'))
                this._overrideNativeAppSwitcher();
            else
                this._restoreNativeAppSwitcher();
        });
    }

    destroy() {
        Settings.disconnect(this._settingsId);
        this._restoreNativeAppSwitcher();
    }

    _overrideNativeAppSwitcher() {
        Main.wm.setCustomKeybindingHandler(
            'switch-applications',
            Shell.ActionMode.NORMAL,
            this._startSwitcher.bind(this)
        );
    }

    _restoreNativeAppSwitcher() {
        Main.wm.setCustomKeybindingHandler(
            'switch-applications',
            Shell.ActionMode.NORMAL,
            Main.wm._startSwitcher.bind(Main.wm)
        );
    }

    /**
     * Copy-pasta from windowManager.js. Removed unused stuff...
     *
     * @param {*} display -
     * @param {*} window -
     * @param {*} binding -
     */
    _startSwitcher(display, window, binding) {
        if (Main.wm._workspaceSwitcherPopup !== null)
            Main.wm._workspaceSwitcherPopup.destroy();

        const tabPopup = new TilingAppSwitcherPopup();

        if (!tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask()))
            tabPopup.destroy();
    }
}

export const TilingAppSwitcherPopup = GObject.registerClass(
class TilingAppSwitcherPopup extends AppSwitcherPopup {
    _init() {
        SwitcherPopup.SwitcherPopup.prototype._init.call(this);

        const settings = new Gio.Settings({ schema_id: 'org.gnome.shell.app-switcher' });
        const workspace = settings.get_boolean('current-workspace-only')
            ? global.workspace_manager.get_active_workspace()
            : null;
        const windows = global.display.get_tab_list(Meta.TabList.NORMAL, workspace);

        this._switcherList = new TilingAppSwitcher(this, windows);
        this._items = this._switcherList.icons;
    }

    // Called when closing an entire app / tileGroup
    _quitApplication(index) {
        const item = this._items[index];
        if (!item)
            return;

        item.cachedWindows.forEach(w => w.delete(global.get_current_time()));
        item.cachedWindows = [];
        this._switcherList._removeIcon(item);
    }

    // Called when closing a window with the thumbnail switcher
    // meaning that .cachedWindow of an item was updated via signals
    _windowRemoved(thumbnailSwitcher, n) {
        const item = this._items[this._selectedIndex];
        if (!item)
            return;

        if (item.cachedWindows.length) {
            const newIndex = Math.min(n, item.cachedWindows.length - 1);
            this._select(this._selectedIndex, newIndex);
        }

        item.updateAppIcons();
    }
});

export const TilingAppSwitcher = GObject.registerClass(
class TilingAppSwitcher extends SwitcherPopup.SwitcherList {
    _init(altTabPopup, windows) {
        // Don't make the SwitcherButtons squares since 1 SwitcherButton
        // may contain multiple AppIcons for a tileGroup.
        super._init(false);

        this.icons = [];
        this._arrows = [];
        this._apps = [];
        this._altTabPopup = altTabPopup;
        this._delayedHighlighted = -1;
        this._mouseTimeOutId = 0;

        const winTracker = Shell.WindowTracker.get_default();
        let groupedWindows;

        // Group windows based on their tileGroup, if tileGroup.length > 1.
        // Otherwise group them based on their respective apps.
        if (Settings.getBoolean('tilegroups-in-app-switcher')) {
            groupedWindows = windows.reduce((allGroups, w) => {
                for (const group of allGroups) {
                    if (w.isTiled && Twm.getTileGroupFor(w).length > 1) {
                        if (Twm.getTileGroupFor(w).includes(group[0])) {
                            group.push(w);
                            return allGroups;
                        }
                    } else if ((!group[0].isTiled || group[0].isTiled && Twm.getTileGroupFor(group[0]).length <= 1) &&
                            winTracker.get_window_app(group[0]) === winTracker.get_window_app(w)) {
                        group.push(w);
                        return allGroups;
                    }
                }
                const newGroup = [w];
                allGroups.push(newGroup);
                return allGroups;
            }, []);

        // Group windows based on apps
        } else {
            groupedWindows = windows.reduce((allGroups, w) => {
                for (const group of allGroups) {
                    if (winTracker.get_window_app(group[0]) === winTracker.get_window_app(w)) {
                        group.push(w);
                        return allGroups;
                    }
                }

                const newGroup = [w];
                allGroups.push(newGroup);
                return allGroups;
            }, []);
        }

        // Construct the AppIcons and add them to the popup.
        groupedWindows.forEach(group => {
            const item = new AppSwitcherItem(group);
            item.connect('all-icons-removed', () => this._removeIcon(item));
            this._addIcon(item);
        });

        // Listen for the app stop state in case the app got closed outside
        // of the app switcher along with closing via the app switcher
        const allApps = windows.map(w => winTracker.get_window_app(w));
        this._apps = [...new Set(allApps)];
        this._stateChangedIds = this._apps.map(app => app.connect('notify::state', () => {
            if (app.state !== Shell.AppState.RUNNING)
                this.icons.forEach(item => item.removeApp(app));
        }));

        this.connect('destroy', this._onDestroy.bind(this));
    }

    _onDestroy() {
        if (this._mouseTimeOutId !== 0)
            GLib.source_remove(this._mouseTimeOutId);

        this._stateChangedIds?.forEach((id, index) => this._apps[index].disconnect(id));
        this._stateChangedIds = [];
        this._apps = [];
    }

    _setIconSize() {
        let j = 0;
        while (this._items.length > 1 && this._items[j].style_class !== 'item-box')
            j++;

        let themeNode = this._items[j].get_theme_node();
        this._list.ensure_style();

        let iconPadding = themeNode.get_horizontal_padding();
        let iconBorder = themeNode.get_border_width(St.Side.LEFT) + themeNode.get_border_width(St.Side.RIGHT);
        let [, labelNaturalHeight] = this.icons[j].label.get_preferred_height(-1);
        let iconSpacing = labelNaturalHeight + iconPadding + iconBorder;
        let totalSpacing = this._list.spacing * (this._items.length - 1);

        // We just assume the whole screen here due to weirdness happening with the passed width
        let primary = Main.layoutManager.primaryMonitor;
        let parentPadding = this.get_parent().get_theme_node().get_horizontal_padding();
        let availWidth = primary.width - parentPadding - this.get_theme_node().get_horizontal_padding();

        let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
        let iconSizes = baseIconSizes.map(s => s * scaleFactor);
        let iconSize = baseIconSizes[0];

        if (this._items.length > 1) {
            for (let i = 0; i < baseIconSizes.length; i++) {
                iconSize = baseIconSizes[i];
                let height = iconSizes[i] + iconSpacing;
                let w = height * this._items.length + totalSpacing;
                if (w <= availWidth)
                    break;
            }
        }

        this._iconSize = iconSize;

        for (let i = 0; i < this.icons.length; i++) {
            // eslint-disable-next-line eqeqeq
            if (this.icons[i].icon != null)
                break;
            this.icons[i].set_size(iconSize);
        }
    }

    vfunc_get_preferred_height(forWidth) {
        if (!this._iconSize)
            this._setIconSize();

        return super.vfunc_get_preferred_height(forWidth);
    }

    vfunc_allocate(box) {
        // Allocate the main list items
        super.vfunc_allocate(box);

        let contentBox = this.get_theme_node().get_content_box(box);

        let arrowHeight = Math.floor(this.get_theme_node().get_padding(St.Side.BOTTOM) / 3);
        let arrowWidth = arrowHeight * 2;

        // Now allocate each arrow underneath its item
        let childBox = new Clutter.ActorBox();
        for (let i = 0; i < this._items.length; i++) {
            let itemBox = this._items[i].allocation;
            childBox.x1 = contentBox.x1 + Math.floor(itemBox.x1 + (itemBox.x2 - itemBox.x1 - arrowWidth) / 2);
            childBox.x2 = childBox.x1 + arrowWidth;
            childBox.y1 = contentBox.y1 + itemBox.y2 + arrowHeight;
            childBox.y2 = childBox.y1 + arrowHeight;
            this._arrows[i].allocate(childBox);
        }
    }

    // We override SwitcherList's _onItemMotion method to delay
    // activation when the thumbnail list is open
    _onItemMotion(item) {
        if (item === this._items[this._highlighted] ||
            item === this._items[this._delayedHighlighted])
            return Clutter.EVENT_PROPAGATE;

        const index = this._items.indexOf(item);

        if (this._mouseTimeOutId !== 0) {
            GLib.source_remove(this._mouseTimeOutId);
            this._delayedHighlighted = -1;
            this._mouseTimeOutId = 0;
        }

        if (this._altTabPopup.thumbnailsVisible) {
            this._delayedHighlighted = index;
            this._mouseTimeOutId = GLib.timeout_add(
                GLib.PRIORITY_DEFAULT,
                APP_ICON_HOVER_TIMEOUT,
                () => {
                    this._enterItem(index);
                    this._delayedHighlighted = -1;
                    this._mouseTimeOutId = 0;
                    return GLib.SOURCE_REMOVE;
                });
            GLib.Source.set_name_by_id(this._mouseTimeOutId, '[gnome-shell] this._enterItem');
        } else {
            this._itemEntered(index);
        }

        return Clutter.EVENT_PROPAGATE;
    }

    _enterItem(index) {
        let [x, y] = global.get_pointer();
        let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
        if (this._items[index].contains(pickedActor))
            this._itemEntered(index);
    }

    // We override SwitcherList's highlight() method to also deal with
    // the AppSwitcher->ThumbnailSwitcher arrows. Apps with only 1 window
    // will hide their arrows by default, but show them when their
    // thumbnails are visible (ie, when the app icon is supposed to be
    // in justOutline mode). Apps with multiple windows will normally
    // show a dim arrow, but show a bright arrow when they are
    // highlighted.
    highlight(n, justOutline) {
        if (this.icons[this._highlighted]) {
            if (this.icons[this._highlighted].cachedWindows.length === 1)
                this._arrows[this._highlighted].hide();
            else
                this._arrows[this._highlighted].remove_style_pseudo_class('highlighted');
        }

        super.highlight(n, justOutline);

        if (this._highlighted !== -1) {
            if (justOutline && this.icons[this._highlighted].cachedWindows.length === 1)
                this._arrows[this._highlighted].show();
            else
                this._arrows[this._highlighted].add_style_pseudo_class('highlighted');
        }
    }

    _addIcon(appIcon) {
        this.icons.push(appIcon);
        let item = this.addItem(appIcon, appIcon.label);

        appIcon.app.connectObject('notify::state', app => {
            if (app.state !== Shell.AppState.RUNNING)
                this._removeIcon(app);
        }, this);

        let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
        arrow.connect('repaint', () => SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM));
        this.add_child(arrow);
        this._arrows.push(arrow);

        if (appIcon.cachedWindows.length === 1)
            arrow.hide();
        else
            item.add_accessible_state(Atk.StateType.EXPANDABLE);
    }

    _removeIcon(item) {
        const index = this.icons.findIndex(i => i === item);
        if (index === -1)
            return;

        this._arrows[index].destroy();
        this._arrows.splice(index, 1);

        this.icons.splice(index, 1);
        this.removeItem(index);
    }
});

/**
 * Replace AltTab.AppIcon and insert this into the TilingAppSwitcher instead.
 * This may contain multiple AppIcons to represent a tileGroup with chain icons
 * between the AppIcons.
 */
const AppSwitcherItem = GObject.registerClass({
    Signals: { 'all-icons-removed': {} }
}, class AppSwitcherItem extends St.BoxLayout {
    _init(windows) {
        super._init({ vertical: false });

        // A tiled window in a tileGroup of length 1, doesn't get a separate
        // AppSwitcherItem. It gets added to the non-tiled windows' AppSwitcherItem
        const tileGroup = windows[0].isTiled && Twm.getTileGroupFor(windows[0]);
        this.isTileGroup = tileGroup && tileGroup.every(w => windows.includes(w)) && tileGroup?.length > 1;
        this.cachedWindows = windows;
        this.appIcons = [];
        this.chainIcons = [];

        // Compatibility with AltTab.AppIcon
        this.set_size = size => this.appIcons.forEach(i => i.set_size(size));
        this.label = null;
        this.app = {
            // Only raise the first window since we split up apps and tileGroups
            activate_window: (window, timestamp) => {
                Main.activateWindow(this.cachedWindows[0], timestamp);
            },
            // Listening to the app-stop now happens in the custom _init func
            // So prevent signal connection. here.. careful in case signal
            // connection in the future is used for more...
            connectObject: () => {}
        };

        this.updateAppIcons();
    }

    // Re/Create the AppIcons based on the cached window list
    updateAppIcons() {
        this.appIcons.forEach(i => i.destroy());
        this.appIcons = [];
        this.chainIcons.forEach(i => i.destroy());
        this.chainIcons = [];

        const winTracker = Shell.WindowTracker.get_default();
        const path = Extension.lookupByURL(import.meta.url)
            .dir.get_child('media/insert-link-symbolic.svg')
            .get_path();
        const icon = new Gio.FileIcon({ file: Gio.File.new_for_path(path) });

        const apps = this.isTileGroup
            // All apps (even duplicates)
            ? this.cachedWindows.map(w => winTracker.get_window_app(w))
            // Only unique apps
            : this.cachedWindows.reduce((allApps, w) => {
                const a = winTracker.get_window_app(w);
                !allApps.includes(a) && allApps.push(a);
                return allApps;
            }, []);

        apps.forEach((app, idx) => {
            // AppIcon
            const appIcon = new AppIcon(app);
            this.add_child(appIcon);
            this.appIcons.push(appIcon);

            // Add chain to the right AppIcon except for the last AppIcon
            if (idx >= apps.length - 1)
                return;

            // Chain
            const chain = new St.Icon({
                gicon: icon,
                icon_size: 18
            });
            this.add_child(chain);
            this.chainIcons.push(chain);
        });

        if (!this.appIcons.length) {
            this.emit('all-icons-removed');
            return;
        }

        this.label = this.appIcons[0].label;
    }

    // Remove an AppIcon to the corresponding app.
    // This doesn't update cached window list!
    removeApp(app) {
        for (let i = this.appIcons.length - 1; i >= 0; i--) {
            const appIcon = this.appIcons[i];
            if (appIcon.app !== app)
                continue;

            this.appIcons.splice(i, 1);
            appIcon.destroy();
            const chain = this.chainIcons.splice(Math.max(0, i - 1), 1)[0];
            chain?.destroy();
        }

        if (!this.appIcons.length)
            this.emit('all-icons-removed');
    }
});

const AppIcon = GObject.registerClass(
class AppIcon extends BaseAppIcon {
    // Don't make the SwitcherButtons squares since 1 SwitcherButton
    // may contain multiple AppIcons for a tileGroup.
    vfunc_get_preferred_width() {
        return this.get_preferred_height(-1);
    }
});

Filemanager

Name Type Size Permission Actions
altTab.js File 16.9 KB 0644
focusHint.js File 26.13 KB 0644
keybindingHandler.js File 23.24 KB 0644
layoutsManager.js File 20.88 KB 0644
moveHandler.js File 38.3 KB 0644
resizeHandler.js File 23.56 KB 0644
tileEditingMode.js File 26.93 KB 0644
tilingPopup.js File 13.64 KB 0644
tilingWindowManager.js File 60.7 KB 0644
utility.js File 26.39 KB 0644
Filemanager