%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /usr/share/gnome-shell/extensions/tiling-assistant@ubuntu.com/
Upload File :
Create Path :
Current File : //usr/share/gnome-shell/extensions/tiling-assistant@ubuntu.com/prefs.js

import { Gdk, Gio, GLib, Gtk } from './src/dependencies/prefs/gi.js';
import { ExtensionPreferences } from './src/dependencies/prefs.js';

import LayoutPrefs from './src/prefs/layoutsPrefs.js';
import { Settings, Shortcuts } from './src/common.js';
// eslint-disable-next-line no-unused-vars
import { ShortcutListener } from './src/prefs/shortcutListener.js';

export default class Prefs extends ExtensionPreferences {
    fillPreferencesWindow(window) {
        // Load css file
        const provider = new Gtk.CssProvider();
        const path = GLib.build_filenamev([this.path, 'stylesheet.css']);
        provider.load_from_path(path);
        Gtk.StyleContext.add_provider_for_display(
            Gdk.Display.get_default(),
            provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
        );

        window.set_can_navigate_back(true);

        const settings = this.getSettings();
        const builder = new Gtk.Builder();
        builder.set_translation_domain(this.uuid);
        builder.add_from_file(`${this.path}/src/ui/prefs.ui`);

        // Add general preference page
        window.add(builder.get_object('general'));

        // Add keybindings preference page
        window.add(builder.get_object('keybindings'));

        // Add layouts preference page on condition of advanced setting
        const layoutsPage = builder.get_object('layouts');
        settings.connect(`changed::${Settings.ENABLE_ADV_EXP_SETTINGS}`, () => {
            settings.get_boolean(Settings.ENABLE_ADV_EXP_SETTINGS)
                ? window.add(layoutsPage)
                : window.remove(layoutsPage);
        });

        if (settings.get_boolean(Settings.ENABLE_ADV_EXP_SETTINGS))
            window.add(layoutsPage);

        // Bind settings to GUI
        this._bindSwitches(settings, builder);
        this._bindSpinbuttons(settings, builder);
        this._bindComboRows(settings, builder);
        this._bindRadioButtons(settings, builder);
        this._bindKeybindings(settings, builder);
        this._bindColorButtons(settings, builder);

        // LayoutPrefs manages everything related to layouts on the
        // prefs side (including the keyboard shortcuts)
        new LayoutPrefs(settings, builder, this.path);

        // Set visibility for deprecated settings
        this._setDeprecatedSettings(settings, builder);

        // Add a button into the headerbar with info
        this._addHeaderBarInfoButton(window, settings, builder);
    }

    /*
    * Bind GUI switches to settings.
    */
    _bindSwitches(settings, builder) {
        const switches = [
            Settings.ENABLE_TILING_POPUP,
            Settings.POPUP_ALL_WORKSPACES,
            Settings.RAISE_TILE_GROUPS,
            Settings.TILEGROUPS_IN_APP_SWITCHER,
            Settings.MAXIMIZE_WITH_GAPS,
            Settings.SHOW_LAYOUT_INDICATOR,
            Settings.ENABLE_ADV_EXP_SETTINGS,
            Settings.DISABLE_TILE_GROUPS,
            Settings.LOW_PERFORMANCE_MOVE_MODE,
            Settings.MONITOR_SWITCH_GRACE_PERIOD,
            Settings.ADAPT_EDGE_TILING_TO_FAVORITE_LAYOUT,
            Settings.ENABLE_TILE_ANIMATIONS,
            Settings.ENABLE_UNTILE_ANIMATIONS,
            Settings.ENABLE_HOLD_INVERSE_LANDSCAPE,
            Settings.ENABLE_HOLD_INVERSE_PORTRAIT
        ];

        switches.forEach(key => {
            const widget = builder.get_object(key.replaceAll('-', '_'));
            settings.bind(key, widget, 'active', Gio.SettingsBindFlags.DEFAULT);
        });
    }

    /*
    * Bind GUI spinbuttons to settings.
    */
    _bindSpinbuttons(settings, builder) {
        const spinButtons = [
            Settings.WINDOW_GAP,
            Settings.SINGLE_SCREEN_GAP,
            Settings.SCREEN_TOP_GAP,
            Settings.SCREEN_LEFT_GAP,
            Settings.SCREEN_RIGHT_GAP,
            Settings.SCREEN_BOTTOM_GAP,
            Settings.ACTIVE_WINDOW_HINT_BORDER_SIZE,
            Settings.ACTIVE_WINDOW_HINT_INNER_BORDER_SIZE,
            Settings.INVERSE_TOP_MAXIMIZE_TIMER,
            Settings.VERTICAL_PREVIEW_AREA,
            Settings.HORIZONTAL_PREVIEW_AREA
        ];

        spinButtons.forEach(key => {
            const widget = builder.get_object(key.replaceAll('-', '_'));
            settings.bind(key, widget, 'value', Gio.SettingsBindFlags.DEFAULT);
        });
    }

    /*
    * Bind GUI AdwComboRows to settings.
    */
    _bindComboRows(settings, builder) {
        const comboRows = [
            Settings.ADAPTIVE_TILING_MOD,
            Settings.FAVORITE_LAYOUT_MOD,
            Settings.IGNORE_TA_MOD,
            Settings.RESTORE_SIZE_ON
        ];

        comboRows.forEach(key => {
            const widget = builder.get_object(key.replaceAll('-', '_'));
            settings.bind(key, widget, 'selected', Gio.SettingsBindFlags.DEFAULT);
            widget.set_selected(settings.get_int(key));
        });
    }

    /*
    * Bind GUI color buttons to settings.
    */
    _bindColorButtons(settings, builder) {
        const switches = [
            Settings.ACTIVE_WINDOW_HINT_COLOR
        ];

        switches.forEach(key => {
            const widget = builder.get_object(`${key.replaceAll('-', '_')}_button`);
            widget.connect('color-set', () => {
                settings.set_string(key, widget.get_rgba().to_string());
            });

            // initilaize color
            const rgba = new Gdk.RGBA();
            rgba.parse(settings.get_string(key));
            widget.set_rgba(rgba);
        });
    }

    /*
    * Bind radioButtons to settings.
    */
    _bindRadioButtons(settings, builder) {
        // These 'radioButtons' are basically just used as a 'fake ComboBox' with
        // explanations for the different options. So there is just *one* gsetting
        // (an int) which saves the current 'selection'.
        const radioButtons = [
            {
                key: Settings.DYNAMIC_KEYBINDINGS,
                rowNames: [
                    'dynamic_keybinding_disabled_row',
                    'dynamic_keybinding_window_focus_row',
                    'dynamic_keybinding_tiling_state_row',
                    'dynamic_keybinding_tiling_state_windows_row',
                    'dynamic_keybinding_favorite_layout_row'
                ]
            },
            {
                key: Settings.ACTIVE_WINDOW_HINT,
                rowNames: [
                    'active_window_hint_disabled_row',
                    'active_window_hint_minimal_row',
                    'active_window_hint_always_row'
                ]
            },
            {
                key: Settings.DEFAULT_MOVE_MODE,
                rowNames: [
                    'edge_tiling_row',
                    'adaptive_tiling_row',
                    'favorite_layout_row',
                    'ignore_ta_row'
                ]
            }
        ];

        radioButtons.forEach(({ key, rowNames }) => {
            const currActive = settings.get_int(key);

            rowNames.forEach((name, idx) => {
                const row = builder.get_object(name.replaceAll('-', '_'));
                const checkButton = row.activatable_widget;
                checkButton.connect('toggled', () => settings.set_int(key, idx));

                // Set initial state
                if (idx === currActive)
                    checkButton.activate();
            });
        });
    }

    /*
    * Bind keybinding widgets to settings.
    */
    _bindKeybindings(settings, builder) {
        const shortcuts = Shortcuts.getAllKeys();
        shortcuts.forEach(key => {
            const shortcut = builder.get_object(key.replaceAll('-', '_'));
            shortcut.initialize(key, settings);
        });
    }

    /**
     * Sets the visibility of deprecated settings. Those setting aren't visible
     * in the GUI unless they have a user set value. That means they aren't
     * discoverable through the GUI and need to first be set with the gsetting.
     * The normal rows should have the id of: GSETTING_WITH_UNDERSCORES_row.
     * ShortcutListeners have the format of GSETTING_WITH_UNDERSCORES.
     */
    _setDeprecatedSettings(settings, builder) {
        // Keybindings
        ['toggle-tiling-popup', 'auto-tile'].forEach(s => {
            const isNonDefault = settings.get_strv(s)[0] !== settings.get_default_value(s).get_strv()[0];
            builder.get_object(s.replaceAll('-', '_')).set_visible(isNonDefault);
        });

        // Switches
        ['tilegroups-in-app-switcher'].forEach(s => {
            const isNonDefault = settings.get_boolean(s) !== settings.get_default_value(s).get_boolean();
            builder.get_object(`${s.replaceAll('-', '_')}_row`).set_visible(isNonDefault);
        });
    }

    _addHeaderBarInfoButton(window, settings, builder) {
        // Add headerBar button for menu
        // TODO: is this a 'reliable' method to access the headerbar?
        const page = builder.get_object('general');
        const gtkStack = page
            .get_parent()
            .get_parent()
            .get_parent();
        const adwHeaderBar = gtkStack
            .get_next_sibling()
            .get_first_child()
            .get_first_child()
            .get_first_child();

        adwHeaderBar.pack_start(builder.get_object('info_menu'));

        // Setup menu actions
        const actionGroup = new Gio.SimpleActionGroup();
        window.insert_action_group('prefs', actionGroup);

        const bugReportAction = new Gio.SimpleAction({ name: 'open-bug-report' });
        bugReportAction.connect('activate', this._openBugReport.bind(this, window));
        actionGroup.add_action(bugReportAction);

        const userGuideAction = new Gio.SimpleAction({ name: 'open-user-guide' });
        userGuideAction.connect('activate', this._openUserGuide.bind(this, window));
        actionGroup.add_action(userGuideAction);

        const changelogAction = new Gio.SimpleAction({ name: 'open-changelog' });
        changelogAction.connect('activate', this._openChangelog.bind(this, window));
        actionGroup.add_action(changelogAction);

        const licenseAction = new Gio.SimpleAction({ name: 'open-license' });
        licenseAction.connect('activate', this._openLicense.bind(this, window));
        actionGroup.add_action(licenseAction);

        const hiddenSettingsAction = new Gio.SimpleAction({ name: 'open-hidden-settings' });
        hiddenSettingsAction.connect('activate', this._openHiddenSettings.bind(this, window, builder));
        actionGroup.add_action(hiddenSettingsAction);

        // Button to return to main settings page
        const returnButton = builder.get_object('hidden_settings_return_button');
        returnButton.connect('clicked', () => window.close_subpage());
    }

    _openBugReport(window) {
        Gtk.show_uri(window, 'https://github.com/Leleat/Tiling-Assistant/issues', Gdk.CURRENT_TIME);
    }

    _openUserGuide(window) {
        Gtk.show_uri(window, 'https://github.com/Leleat/Tiling-Assistant/wiki', Gdk.CURRENT_TIME);
    }

    _openChangelog(window) {
        Gtk.show_uri(window, 'https://github.com/Leleat/Tiling-Assistant/blob/main/CHANGELOG.md', Gdk.CURRENT_TIME);
    }

    _openLicense(window) {
        Gtk.show_uri(window, 'https://github.com/Leleat/Tiling-Assistant/blob/main/LICENSE', Gdk.CURRENT_TIME);
    }

    _openHiddenSettings(window, builder) {
        const hiddenSettingsPage = builder.get_object('hidden_settings');
        window.present_subpage(hiddenSettingsPage);
    }
}

Zerion Mini Shell 1.0