305 lines
11 KiB
JavaScript
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);
|
|
}
|
|
}
|