.dotfiles/.local/share/gnome-shell/extensions/tiling-assistant@leleat-on-.../prefs.js

305 lines
11 KiB
JavaScript

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);
}
}