Files
dash-to-panel/prefs.js
MarkS bbd3a20fe5 Move length and anchor to Styles tab
* Moved length and anchor setting to Styles tab, as it is
  an all-monitor setting currently.
* Changed length from spinbox to slider, and shortened label.
* Turned off anchor combobox sensitivity if length is 100%.
* Set anchor labels to the more intuitive "Left, Center, Right" and
  "Top, Middle, Bottom" if all monitor panels are horizontal or
  vertical. If monitors have panels in a mix of orientations, use
  "Start, Middle, End". The schema retains the generic START, MIDDLE,
  END.
* Changed "Panel Size" label to "Panel thickness" to more precisely
  describe what is being set now that the panel can be changed in two
  dimensions. "Panel thickness" and "Panel length" can
  describe the sizing of the panel for either horizontal or vertical
  orientations.
* Changed now-shortened Position label to "Anchor", to reduce
  confusion with other Position setting, regarding which edge of the
  screen.
2020-08-03 20:47:22 -06:00

2246 lines
112 KiB
JavaScript

/*
* This file is part of the Dash-To-Panel extension for Gnome 3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* Credits:
* This file is based on code from the Dash to Dock extension by micheleg.
* Some code was also adapted from the upstream Gnome Shell source code.
*/
const GdkPixbuf = imports.gi.GdkPixbuf;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Gdk = imports.gi.Gdk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
const N_ = function(e) { return e };
const Update = Me.imports.update;
const Pos = Me.imports.panelPositions;
const SCALE_UPDATE_TIMEOUT = 500;
const DEFAULT_PANEL_SIZES = [ 128, 96, 64, 48, 32, 24, 16 ];
const DEFAULT_FONT_SIZES = [ 96, 64, 48, 32, 24, 16, 0 ];
const DEFAULT_MARGIN_SIZES = [ 32, 24, 16, 12, 8, 4, 0 ];
const DEFAULT_PADDING_SIZES = [ 32, 24, 16, 12, 8, 4, 0, -1 ];
// Minimum length could be 0, but a higher value may help prevent confusion about where the panel went.
const LENGTH_MARKS = [ 100, 90, 80, 70, 60, 50, 40, 30, 20, 10 ];
const MAX_WINDOW_INDICATOR = 4;
const SCHEMA_PATH = '/org/gnome/shell/extensions/dash-to-panel/';
const GSET = 'gnome-shell-extension-tool';
/**
* This function was copied from the activities-config extension
* https://github.com/nls1729/acme-code/tree/master/activities-config
* by Norman L. Smith.
*/
function cssHexString(css) {
let rrggbb = '#';
let start;
for (let loop = 0; loop < 3; loop++) {
let end = 0;
let xx = '';
for (let loop = 0; loop < 2; loop++) {
while (true) {
let x = css.slice(end, end + 1);
if ((x == '(') || (x == ',') || (x == ')'))
break;
end++;
}
if (loop == 0) {
end++;
start = end;
}
}
xx = parseInt(css.slice(start, end)).toString(16);
if (xx.length == 1)
xx = '0' + xx;
rrggbb += xx;
css = css.slice(end);
}
return rrggbb;
}
function setShortcut(settings, shortcutName) {
let shortcut_text = settings.get_string(shortcutName + '-text');
let [key, mods] = Gtk.accelerator_parse(shortcut_text);
if (Gtk.accelerator_valid(key, mods)) {
let shortcut = Gtk.accelerator_name(key, mods);
settings.set_strv(shortcutName, [shortcut]);
}
else {
settings.set_strv(shortcutName, []);
}
}
function checkHotkeyPrefix(settings) {
settings.delay();
let hotkeyPrefix = settings.get_string('hotkey-prefix-text');
if (hotkeyPrefix == 'Super')
hotkeyPrefix = '<Super>';
else if (hotkeyPrefix == 'SuperAlt')
hotkeyPrefix = '<Super><Alt>';
let [, mods] = Gtk.accelerator_parse(hotkeyPrefix);
let [, shift_mods] = Gtk.accelerator_parse('<Shift>' + hotkeyPrefix);
let [, ctrl_mods] = Gtk.accelerator_parse('<Ctrl>' + hotkeyPrefix);
let numHotkeys = 10;
for (let i = 1; i <= numHotkeys; i++) {
let number = i;
if (number == 10)
number = 0;
let key = Gdk.keyval_from_name(number.toString());
let key_kp = Gdk.keyval_from_name('KP_' + number.toString());
if (Gtk.accelerator_valid(key, mods)) {
let shortcut = Gtk.accelerator_name(key, mods);
let shortcut_kp = Gtk.accelerator_name(key_kp, mods);
// Setup shortcut strings
settings.set_strv('app-hotkey-' + i, [shortcut]);
settings.set_strv('app-hotkey-kp-' + i, [shortcut_kp]);
// With <Shift>
shortcut = Gtk.accelerator_name(key, shift_mods);
shortcut_kp = Gtk.accelerator_name(key_kp, shift_mods);
settings.set_strv('app-shift-hotkey-' + i, [shortcut]);
settings.set_strv('app-shift-hotkey-kp-' + i, [shortcut_kp]);
// With <Control>
shortcut = Gtk.accelerator_name(key, ctrl_mods);
shortcut_kp = Gtk.accelerator_name(key_kp, ctrl_mods);
settings.set_strv('app-ctrl-hotkey-' + i, [shortcut]);
settings.set_strv('app-ctrl-hotkey-kp-' + i, [shortcut_kp]);
}
else {
// Reset default settings for the relevant keys if the
// accelerators are invalid
let keys = ['app-hotkey-' + i, 'app-shift-hotkey-' + i, 'app-ctrl-hotkey-' + i, // Regular numbers
'app-hotkey-kp-' + i, 'app-shift-hotkey-kp-' + i, 'app-ctrl-hotkey-kp-' + i]; // Key-pad numbers
keys.forEach(function(val) {
settings.set_value(val, settings.get_default_value(val));
}, this);
}
}
settings.apply();
}
function mergeObjects(main, bck) {
for (var prop in bck) {
if (!main.hasOwnProperty(prop) && bck.hasOwnProperty(prop)) {
main[prop] = bck[prop];
}
}
return main;
};
const Settings = new Lang.Class({
Name: 'DashToPanel.Settings',
_init: function() {
this._settings = Convenience.getSettings('org.gnome.shell.extensions.dash-to-panel');
this._rtl = (Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL);
this._builder = new Gtk.Builder();
this._builder.set_translation_domain(Me.metadata['gettext-domain']);
this._builder.add_from_file(Me.path + '/Settings.ui');
this.notebook = this._builder.get_object('settings_notebook');
this.viewport = new Gtk.Viewport();
this.viewport.add(this.notebook);
this.widget = new Gtk.ScrolledWindow();
this.widget.add(this.viewport);
// Timeout to delay the update of the settings
this._panel_size_timeout = 0;
this._dot_height_timeout = 0;
this._tray_size_timeout = 0;
this._leftbox_size_timeout = 0;
this._appicon_margin_timeout = 0;
this._appicon_padding_timeout = 0;
this._opacity_timeout = 0;
this._tray_padding_timeout = 0;
this._statusicon_padding_timeout = 0;
this._leftbox_padding_timeout = 0;
this._bindSettings();
this._builder.connect_signals_full(Lang.bind(this, this._connector));
},
/**
* Connect signals
*/
_connector: function(builder, object, signal, handler) {
object.connect(signal, Lang.bind(this, this._SignalHandler[handler]));
},
_updateVerticalRelatedOptions: function() {
let position = this._getPanelPosition(this._currentMonitorIndex);
let isVertical = position == Pos.LEFT || position == Pos.RIGHT;
let showDesktopWidthLabel = this._builder.get_object('show_showdesktop_width_label');
showDesktopWidthLabel.set_text(isVertical ? _('Show Desktop button height (px)') : _('Show Desktop button width (px)'));
this._displayPanelPositionsForMonitor(this._currentMonitorIndex);
},
_maybeDisableTopPosition: function() {
let keepTopPanel = this._settings.get_boolean('stockgs-keep-top-panel');
let monitorSync = this._settings.get_boolean('panel-element-positions-monitors-sync');
let topAvailable = !keepTopPanel || (!monitorSync && this._currentMonitorIndex != this.monitors[0]);
let topRadio = this._builder.get_object('position_top_button');
topRadio.set_sensitive(topAvailable);
topRadio.set_tooltip_text(!topAvailable ? _('Unavailable when gnome-shell top panel is present') : '');
},
/**
* Returns an object, with monitor index string keys to values that are Pos.TOP, Pos.BOTTOM, Pos.LEFT,
* or Pos.RIGHT.
*/
_getPanelPositions: function() {
return Pos.getSettingsPositions(this._settings, 'panel-positions');
},
_getPanelPosition: function(monitorIndex) {
let panelPositionsSettings = this._getPanelPositions();
return panelPositionsSettings[monitorIndex] || this._settings.get_string('panel-position');
},
_setPanelPosition: function(position) {
let panelPositionsSettings = this._getPanelPositions();
let preventTop = this._settings.get_boolean('stockgs-keep-top-panel') && position == Pos.TOP;
let monitorSync = this._settings.get_boolean('panel-element-positions-monitors-sync');
let monitors = monitorSync ? this.monitors : [this._currentMonitorIndex];
monitors.forEach(m => panelPositionsSettings[m] = preventTop && this.monitors[0] == m ? Pos.BOTTOM : position);
this._settings.set_string('panel-positions', JSON.stringify(panelPositionsSettings));
this._setAnchorLabels();
},
_setPositionRadios: function(position) {
this._ignorePositionRadios = true;
switch (position) {
case Pos.BOTTOM:
this._builder.get_object('position_bottom_button').set_active(true);
break;
case Pos.TOP:
this._builder.get_object('position_top_button').set_active(true);
break;
case Pos.LEFT:
this._builder.get_object('position_left_button').set_active(true);
break;
case Pos.RIGHT:
this._builder.get_object('position_right_button').set_active(true);
break;
}
this._ignorePositionRadios = false;
},
/**
* Set panel anchor combo labels according to whether panel is vertical, horizontal, or a mix.
*/
_setAnchorLabels: function() {
const positions = this._getPanelPositions();
const monitorIndices = Object.getOwnPropertyNames(positions);
const allVertical = monitorIndices.every(i => positions[i] === Pos.LEFT || positions[i] === Pos.RIGHT);
const allHorizontal = monitorIndices.every(i => positions[i] === Pos.TOP || positions[i] === Pos.BOTTOM);
const anchor_combo = this._builder.get_object('panel_anchor_combo');
const anchor = this._settings.get_string('panel-anchor');
anchor_combo.remove_all();
if (allHorizontal) {
anchor_combo.append(Pos.START, _('Left'));
anchor_combo.append(Pos.MIDDLE, _('Center'));
anchor_combo.append(Pos.END, _('Right'));
} else if (allVertical) {
anchor_combo.append(Pos.START, _('Top'));
anchor_combo.append(Pos.MIDDLE, _('Middle'));
anchor_combo.append(Pos.END, _('Bottom'));
} else {
// Mix of horizontal and vertical panels on different monitors.
anchor_combo.append(Pos.START, _('Start'));
anchor_combo.append(Pos.MIDDLE, _('Middle'));
anchor_combo.append(Pos.END, _('End'));
}
anchor_combo.set_active_id(anchor);
},
_displayPanelPositionsForMonitor: function(monitorIndex) {
let taskbarListBox = this._builder.get_object('taskbar_display_listbox');
taskbarListBox.get_children().forEach(c => c.destroy());
let labels = {};
let panelPosition = this._getPanelPosition(monitorIndex);
let isVertical = panelPosition == Pos.LEFT || panelPosition == Pos.RIGHT;
let panelElementPositionsSettings = Pos.getSettingsPositions(this._settings, 'panel-element-positions');
let panelElementPositions = panelElementPositionsSettings[monitorIndex] || Pos.defaults;
let updateElementsSettings = () => {
let newPanelElementPositions = [];
let monitorSync = this._settings.get_boolean('panel-element-positions-monitors-sync');
let monitors = monitorSync ? this.monitors : [monitorIndex];
taskbarListBox.get_children().forEach(c => {
newPanelElementPositions.push({
element: c.id,
visible: c.visibleToggleBtn.get_active(),
position: c.positionCombo.get_active_id()
});
});
monitors.forEach(m => panelElementPositionsSettings[m] = newPanelElementPositions);
this._settings.set_string('panel-element-positions', JSON.stringify(panelElementPositionsSettings));
};
this._maybeDisableTopPosition();
this._setPositionRadios(panelPosition);
labels[Pos.SHOW_APPS_BTN] = _('Show Applications button');
labels[Pos.ACTIVITIES_BTN] = _('Activities button');
labels[Pos.TASKBAR] = _('Taskbar');
labels[Pos.DATE_MENU] = _('Date menu');
labels[Pos.SYSTEM_MENU] = _('System menu');
labels[Pos.LEFT_BOX] = _('Left box');
labels[Pos.CENTER_BOX] = _('Center box');
labels[Pos.RIGHT_BOX] = _('Right box');
labels[Pos.DESKTOP_BTN] = _('Desktop button');
panelElementPositions.forEach(el => {
let row = new Gtk.ListBoxRow();
let grid = new Gtk.Grid({ margin: 2, margin_left: 12, margin_right: 12, column_spacing: 8 });
let upDownGrid = new Gtk.Grid({ column_spacing: 2 });
let upBtn = new Gtk.Button({ tooltip_text: _('Move up') });
let upImg = new Gtk.Image({ icon_name: 'go-up-symbolic', pixel_size: 12 });
let downBtn = new Gtk.Button({ tooltip_text: _('Move down') });
let downImg = new Gtk.Image({ icon_name: 'go-down-symbolic', pixel_size: 12 });
let visibleToggleBtn = new Gtk.ToggleButton({ label: _('Visible'), active: el.visible });
let positionCombo = new Gtk.ComboBoxText({ tooltip_text: _('Select element position') });
let upDownClickHandler = limit => {
let index = row.get_index();
if (index != limit) {
taskbarListBox.remove(row);
taskbarListBox.insert(row, index + (!limit ? -1 : 1));
updateElementsSettings();
}
};
positionCombo.append(Pos.STACKED_TL, isVertical ? _('Stacked to top') : _('Stacked to left'));
positionCombo.append(Pos.STACKED_BR, isVertical ? _('Stacked to bottom') :_('Stacked to right'));
positionCombo.append(Pos.CENTERED, _('Centered'));
positionCombo.append(Pos.CENTERED_MONITOR, _('Monitor Center'));
positionCombo.set_active_id(el.position);
upBtn.connect('clicked', () => upDownClickHandler(0));
downBtn.connect('clicked', () => upDownClickHandler(panelElementPositions.length - 1));
visibleToggleBtn.connect('toggled', () => updateElementsSettings());
positionCombo.connect('changed', () => updateElementsSettings());
upBtn.add(upImg);
downBtn.add(downImg);
upDownGrid.add(upBtn);
upDownGrid.add(downBtn);
grid.add(upDownGrid);
grid.add(new Gtk.Label({ label: labels[el.element], xalign: 0, hexpand: true }));
if (Pos.optionDialogFunctions[el.element]) {
let cogImg = new Gtk.Image({ icon_name: 'emblem-system-symbolic' });
let optionsBtn = new Gtk.Button({ tooltip_text: _('More options') });
optionsBtn.get_style_context().add_class('circular');
optionsBtn.add(cogImg);
grid.add(optionsBtn);
optionsBtn.connect('clicked', () => this[Pos.optionDialogFunctions[el.element]]());
}
grid.add(visibleToggleBtn);
grid.add(positionCombo);
row.id = el.element;
row.visibleToggleBtn = visibleToggleBtn;
row.positionCombo = positionCombo;
row.add(grid);
taskbarListBox.add(row);
});
taskbarListBox.show_all();
},
_showShowAppsButtonOptions: function() {
let dialog = new Gtk.Dialog({ title: _('Show Applications options'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('show_applications_options');
dialog.get_content_area().add(box);
let fileChooser = this._builder.get_object('show_applications_icon_file_filebutton');
let fileImage = this._builder.get_object('show_applications_current_icon_image');
let fileFilter = new Gtk.FileFilter();
let handleIconChange = function(newIconPath) {
if (newIconPath && GLib.file_test(newIconPath, GLib.FileTest.EXISTS)) {
let file = Gio.File.new_for_path(newIconPath)
let pixbuf = GdkPixbuf.Pixbuf.new_from_stream_at_scale(file.read(null), 32, 32, true, null);
fileImage.set_from_pixbuf(pixbuf);
fileChooser.set_filename(newIconPath);
} else {
newIconPath = '';
fileImage.set_from_icon_name('view-app-grid-symbolic', 32);
fileChooser.unselect_all();
fileChooser.set_current_folder(GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES));
}
this._settings.set_string('show-apps-icon-file', newIconPath || '');
};
fileFilter.add_pixbuf_formats();
fileChooser.filter = fileFilter;
fileChooser.connect('file-set', widget => handleIconChange.call(this, widget.get_filename()));
handleIconChange.call(this, this._settings.get_string('show-apps-icon-file'));
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('show-apps-icon-side-padding', this._settings.get_default_value('show-apps-icon-side-padding'));
this._builder.get_object('show_applications_side_padding_spinbutton').set_value(this._settings.get_int('show-apps-icon-side-padding'));
this._settings.set_value('show-apps-override-escape', this._settings.get_default_value('show-apps-override-escape'));
handleIconChange.call(this, null);
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
},
_showDesktopButtonOptions: function() {
let dialog = new Gtk.Dialog({ title: _('Show Desktop options'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('box_show_showdesktop_options');
dialog.get_content_area().add(box);
this._builder.get_object('show_showdesktop_width_spinbutton').set_value(this._settings.get_int('showdesktop-button-width'));
this._builder.get_object('show_showdesktop_width_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('showdesktop-button-width', widget.get_value());
}));
this._builder.get_object('show_showdesktop_delay_spinbutton').set_value(this._settings.get_int('show-showdesktop-delay'));
this._builder.get_object('show_showdesktop_delay_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('show-showdesktop-delay', widget.get_value());
}));
this._builder.get_object('show_showdesktop_time_spinbutton').set_value(this._settings.get_int('show-showdesktop-time'));
this._builder.get_object('show_showdesktop_time_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('show-showdesktop-time', widget.get_value());
}));
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('showdesktop-button-width', this._settings.get_default_value('showdesktop-button-width'));
this._builder.get_object('show_showdesktop_width_spinbutton').set_value(this._settings.get_int('showdesktop-button-width'));
this._settings.set_value('show-showdesktop-hover', this._settings.get_default_value('show-showdesktop-hover'));
this._settings.set_value('show-showdesktop-delay', this._settings.get_default_value('show-showdesktop-delay'));
this._builder.get_object('show_showdesktop_delay_spinbutton').set_value(this._settings.get_int('show-showdesktop-delay'));
this._settings.set_value('show-showdesktop-time', this._settings.get_default_value('show-showdesktop-time'));
this._builder.get_object('show_showdesktop_time_spinbutton').set_value(this._settings.get_int('show-showdesktop-time'));
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
},
_bindSettings: function() {
// size options
let panel_size_scale = this._builder.get_object('panel_size_scale');
panel_size_scale.set_range(DEFAULT_PANEL_SIZES[DEFAULT_PANEL_SIZES.length-1], DEFAULT_PANEL_SIZES[0]);
panel_size_scale.set_value(this._settings.get_int('panel-size'));
DEFAULT_PANEL_SIZES.slice(1, -1).forEach(function(val) {
panel_size_scale.add_mark(val, Gtk.PositionType.TOP, val.toString());
});
// Corrent for rtl languages
if (this._rtl) {
// Flip value position: this is not done automatically
panel_size_scale.set_value_pos(Gtk.PositionType.LEFT);
// I suppose due to a bug, having a more than one mark and one above a value of 100
// makes the rendering of the marks wrong in rtl. This doesn't happen setting the scale as not flippable
// and then manually inverting it
panel_size_scale.set_flippable(false);
panel_size_scale.set_inverted(true);
}
// Dots Position option
let dotPosition = this._settings.get_string('dot-position');
switch (dotPosition) {
case 'BOTTOM':
this._builder.get_object('dots_bottom_button').set_active(true);
break;
case 'TOP':
this._builder.get_object('dots_top_button').set_active(true);
break;
case 'LEFT':
this._builder.get_object('dots_left_button').set_active(true);
break;
case 'RIGHT':
this._builder.get_object('dots_right_button').set_active(true);
break;
}
this._builder.get_object('dot_style_focused_combo').set_active_id(this._settings.get_string('dot-style-focused'));
this._builder.get_object('dot_style_focused_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('dot-style-focused', widget.get_active_id());
}));
this._builder.get_object('dot_style_unfocused_combo').set_active_id(this._settings.get_string('dot-style-unfocused'));
this._builder.get_object('dot_style_unfocused_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('dot-style-unfocused', widget.get_active_id());
}));
for (let i = 1; i <= MAX_WINDOW_INDICATOR; i++) {
let idx = i;
this._builder.get_object('dot_color_' + idx + '_colorbutton').connect('notify::color', Lang.bind(this, function(button) {
let rgba = button.get_rgba();
let css = rgba.to_string();
let hexString = cssHexString(css);
this._settings.set_string('dot-color-' + idx, hexString);
}));
this._builder.get_object('dot_color_unfocused_' + idx + '_colorbutton').connect('notify::color', Lang.bind(this, function(button) {
let rgba = button.get_rgba();
let css = rgba.to_string();
let hexString = cssHexString(css);
this._settings.set_string('dot-color-unfocused-' + idx, hexString);
}));
}
this._builder.get_object('dot_color_apply_all_button').connect('clicked', Lang.bind(this, function() {
for (let i = 2; i <= MAX_WINDOW_INDICATOR; i++) {
this._settings.set_value('dot-color-' + i, this._settings.get_value('dot-color-1'));
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('dot-color-' + i));
this._builder.get_object('dot_color_' + i + '_colorbutton').set_rgba(rgba);
}
}));
this._builder.get_object('dot_color_unfocused_apply_all_button').connect('clicked', Lang.bind(this, function() {
for (let i = 2; i <= MAX_WINDOW_INDICATOR; i++) {
this._settings.set_value('dot-color-unfocused-' + i, this._settings.get_value('dot-color-unfocused-1'));
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('dot-color-unfocused-' + i));
this._builder.get_object('dot_color_unfocused_' + i + '_colorbutton').set_rgba(rgba);
}
}));
this._builder.get_object('focus_highlight_color_colorbutton').connect('notify::color', Lang.bind(this, function(button) {
let rgba = button.get_rgba();
let css = rgba.to_string();
let hexString = cssHexString(css);
this._settings.set_string('focus-highlight-color', hexString);
}));
this._builder.get_object('dot_style_options_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Running Indicator Options'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('box_dots_options');
dialog.get_content_area().add(box);
this._settings.bind('dot-color-dominant',
this._builder.get_object('dot_color_dominant_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('dot-color-override',
this._builder.get_object('dot_color_override_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
// when either becomes active, turn the other off
this._builder.get_object('dot_color_dominant_switch').connect('state-set', Lang.bind (this, function(widget) {
if (widget.get_active()) this._settings.set_boolean('dot-color-override', false);
}));
this._builder.get_object('dot_color_override_switch').connect('state-set', Lang.bind (this, function(widget) {
if (widget.get_active()) this._settings.set_boolean('dot-color-dominant', false);
}));
this._settings.bind('dot-color-unfocused-different',
this._builder.get_object('dot_color_unfocused_different_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('dot-color-override',
this._builder.get_object('grid_dot_color'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('dot-color-override',
this._builder.get_object('dot_color_unfocused_box'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('dot-color-unfocused-different',
this._builder.get_object('grid_dot_color_unfocused'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
for (let i = 1; i <= MAX_WINDOW_INDICATOR; i++) {
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('dot-color-' + i));
this._builder.get_object('dot_color_' + i + '_colorbutton').set_rgba(rgba);
rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('dot-color-unfocused-' + i));
this._builder.get_object('dot_color_unfocused_' + i + '_colorbutton').set_rgba(rgba);
}
this._settings.bind('focus-highlight',
this._builder.get_object('focus_highlight_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('focus-highlight',
this._builder.get_object('grid_focus_highlight_options'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('focus-highlight-dominant',
this._builder.get_object('focus_highlight_dominant_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('focus-highlight-dominant',
this._builder.get_object('focus_highlight_color_label'),
'sensitive',
Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._settings.bind('focus-highlight-dominant',
this._builder.get_object('focus_highlight_color_colorbutton'),
'sensitive',
Gio.SettingsBindFlags.INVERT_BOOLEAN);
(function() {
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('focus-highlight-color'));
this._builder.get_object('focus_highlight_color_colorbutton').set_rgba(rgba);
}).apply(this);
this._builder.get_object('focus_highlight_opacity_spinbutton').set_value(this._settings.get_int('focus-highlight-opacity'));
this._builder.get_object('focus_highlight_opacity_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('focus-highlight-opacity', widget.get_value());
}));
this._builder.get_object('dot_size_spinbutton').set_value(this._settings.get_int('dot-size'));
this._builder.get_object('dot_size_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('dot-size', widget.get_value());
}));
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('dot-color-dominant', this._settings.get_default_value('dot-color-dominant'));
this._settings.set_value('dot-color-override', this._settings.get_default_value('dot-color-override'));
this._settings.set_value('dot-color-unfocused-different', this._settings.get_default_value('dot-color-unfocused-different'));
this._settings.set_value('focus-highlight-color', this._settings.get_default_value('focus-highlight-color'));
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('focus-highlight-color'));
this._builder.get_object('focus_highlight_color_colorbutton').set_rgba(rgba);
this._settings.set_value('focus-highlight-opacity', this._settings.get_default_value('focus-highlight-opacity'));
this._builder.get_object('focus_highlight_opacity_spinbutton').set_value(this._settings.get_int('focus-highlight-opacity'));
for (let i = 1; i <= MAX_WINDOW_INDICATOR; i++) {
this._settings.set_value('dot-color-' + i, this._settings.get_default_value('dot-color-' + i));
rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('dot-color-' + i));
this._builder.get_object('dot_color_' + i + '_colorbutton').set_rgba(rgba);
this._settings.set_value('dot-color-unfocused-' + i, this._settings.get_default_value('dot-color-unfocused-' + i));
rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('dot-color-unfocused-' + i));
this._builder.get_object('dot_color_unfocused_' + i + '_colorbutton').set_rgba(rgba);
}
this._settings.set_value('dot-size', this._settings.get_default_value('dot-size'));
this._builder.get_object('dot_size_spinbutton').set_value(this._settings.get_int('dot-size'));
this._settings.set_value('focus-highlight', this._settings.get_default_value('focus-highlight'));
this._settings.set_value('focus-highlight-dominant', this._settings.get_default_value('focus-highlight-dominant'));
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
//multi-monitor
this.monitors = this._settings.get_value('available-monitors').deep_unpack();
let dtpPrimaryMonitorIndex = this.monitors.indexOf(this._settings.get_int('primary-monitor'));
if (dtpPrimaryMonitorIndex < 0) {
dtpPrimaryMonitorIndex = 0;
}
this._currentMonitorIndex = this.monitors[dtpPrimaryMonitorIndex];
this._settings.connect('changed::panel-positions', () => this._updateVerticalRelatedOptions());
this._updateVerticalRelatedOptions();
for (let i = 0; i < this.monitors.length; ++i) {
//the primary index is the first one in the "available-monitors" setting
let label = !i ? _('Primary monitor') : _('Monitor ') + (i + 1);
this._builder.get_object('multimon_primary_combo').append_text(label);
this._builder.get_object('taskbar_position_monitor_combo').append_text(label);
}
this._builder.get_object('multimon_primary_combo').set_active(dtpPrimaryMonitorIndex);
this._builder.get_object('taskbar_position_monitor_combo').set_active(dtpPrimaryMonitorIndex);
this._settings.bind('panel-element-positions-monitors-sync',
this._builder.get_object('taskbar_position_sync_button'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('panel-element-positions-monitors-sync',
this._builder.get_object('taskbar_position_monitor_combo'),
'sensitive',
Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._settings.connect('changed::panel-element-positions-monitors-sync', () => this._maybeDisableTopPosition());
this._builder.get_object('multimon_primary_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_int('primary-monitor', this.monitors[widget.get_active()]);
}));
this._builder.get_object('taskbar_position_monitor_combo').connect('changed', Lang.bind (this, function(widget) {
this._currentMonitorIndex = this.monitors[widget.get_active()];
this._displayPanelPositionsForMonitor(this._currentMonitorIndex);
}));
//panel positions
this._displayPanelPositionsForMonitor(this._currentMonitorIndex);
this._settings.bind('multi-monitors',
this._builder.get_object('multimon_multi_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
if (this.monitors.length === 1) {
this._builder.get_object('multimon_multi_switch').set_sensitive(false);
}
// Length and anchoring along screen edge
// Anchor is only relevant if panel length is less than 100%.
const setAnchorWidgetSensitivity = (panelLength) => {
const isPartialLength = panelLength < 100;
this._builder.get_object('panel_anchor_label').set_sensitive(isPartialLength);
this._builder.get_object('panel_anchor_combo').set_sensitive(isPartialLength);
}
const panel_length_scale = this._builder.get_object('panel_length_scale');
const length = this._settings.get_int('panel-length');
panel_length_scale.set_value(length);
setAnchorWidgetSensitivity(length);
panel_length_scale.connect('value-changed', Lang.bind (this, function(widget) {
const value = widget.get_value();
this._settings.set_int('panel-length', value);
setAnchorWidgetSensitivity(value);
}));
this._builder.get_object('panel_anchor_combo').set_active_id(this._settings.get_string('panel-anchor'));
this._builder.get_object('panel_anchor_combo').connect('changed', Lang.bind (this, function(widget) {
const value = widget.get_active_id();
// Value can be null while anchor labels are being swapped out
if (value !== null) {
this._settings.set_string('panel-anchor', value);
}
}));
this._setAnchorLabels();
//dynamic opacity
this._settings.bind('trans-use-custom-bg',
this._builder.get_object('trans_bg_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('trans-use-custom-bg',
this._builder.get_object('trans_bg_color_colorbutton'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('trans-bg-color'));
this._builder.get_object('trans_bg_color_colorbutton').set_rgba(rgba);
this._builder.get_object('trans_bg_color_colorbutton').connect('notify::color', Lang.bind(this, function (button) {
let rgba = button.get_rgba();
let css = rgba.to_string();
let hexString = cssHexString(css);
this._settings.set_string('trans-bg-color', hexString);
}));
this._settings.bind('trans-use-custom-opacity',
this._builder.get_object('trans_opacity_override_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('trans-use-custom-opacity',
this._builder.get_object('trans_opacity_box'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('trans_opacity_override_switch').connect('notify::active', (widget) => {
if (!widget.get_active())
this._builder.get_object('trans_dyn_switch').set_active(false);
});
this._builder.get_object('trans_opacity_spinbutton').set_value(this._settings.get_double('trans-panel-opacity') * 100);
this._builder.get_object('trans_opacity_spinbutton').connect('value-changed', Lang.bind(this, function (widget) {
this._settings.set_double('trans-panel-opacity', widget.get_value() * 0.01);
}));
this._settings.bind('trans-use-dynamic-opacity',
this._builder.get_object('trans_dyn_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('trans-use-dynamic-opacity',
this._builder.get_object('trans_dyn_options_button'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('trans-dynamic-behavior',
this._builder.get_object('trans_options_window_type_combo'),
'active-id',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('trans-use-custom-gradient',
this._builder.get_object('trans_gradient_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('trans-use-custom-gradient',
this._builder.get_object('trans_gradient_box'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
rgba.parse(this._settings.get_string('trans-gradient-top-color'));
this._builder.get_object('trans_gradient_color1_colorbutton').set_rgba(rgba);
this._builder.get_object('trans_gradient_color1_colorbutton').connect('notify::color', Lang.bind(this, function (button) {
let rgba = button.get_rgba();
let css = rgba.to_string();
let hexString = cssHexString(css);
this._settings.set_string('trans-gradient-top-color', hexString);
}));
this._builder.get_object('trans_gradient_color1_spinbutton').set_value(this._settings.get_double('trans-gradient-top-opacity') * 100);
this._builder.get_object('trans_gradient_color1_spinbutton').connect('value-changed', Lang.bind(this, function (widget) {
this._settings.set_double('trans-gradient-top-opacity', widget.get_value() * 0.01);
}));
rgba.parse(this._settings.get_string('trans-gradient-bottom-color'));
this._builder.get_object('trans_gradient_color2_colorbutton').set_rgba(rgba);
this._builder.get_object('trans_gradient_color2_colorbutton').connect('notify::color', Lang.bind(this, function (button) {
let rgba = button.get_rgba();
let css = rgba.to_string();
let hexString = cssHexString(css);
this._settings.set_string('trans-gradient-bottom-color', hexString);
}));
this._builder.get_object('trans_gradient_color2_spinbutton').set_value(this._settings.get_double('trans-gradient-bottom-opacity') * 100);
this._builder.get_object('trans_gradient_color2_spinbutton').connect('value-changed', Lang.bind(this, function (widget) {
this._settings.set_double('trans-gradient-bottom-opacity', widget.get_value() * 0.01);
}));
this._builder.get_object('trans_options_distance_spinbutton').set_value(this._settings.get_int('trans-dynamic-distance'));
this._builder.get_object('trans_options_distance_spinbutton').connect('value-changed', Lang.bind(this, function (widget) {
this._settings.set_int('trans-dynamic-distance', widget.get_value());
}));
this._builder.get_object('trans_options_min_opacity_spinbutton').set_value(this._settings.get_double('trans-dynamic-anim-target') * 100);
this._builder.get_object('trans_options_min_opacity_spinbutton').connect('value-changed', Lang.bind(this, function (widget) {
this._settings.set_double('trans-dynamic-anim-target', widget.get_value() * 0.01);
}));
this._builder.get_object('trans_options_anim_time_spinbutton').set_value(this._settings.get_int('trans-dynamic-anim-time'));
this._builder.get_object('trans_options_anim_time_spinbutton').connect('value-changed', Lang.bind(this, function (widget) {
this._settings.set_int('trans-dynamic-anim-time', widget.get_value());
}));
this._builder.get_object('trans_dyn_options_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Dynamic opacity options'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('box_dynamic_opacity_options');
dialog.get_content_area().add(box);
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('trans-dynamic-behavior', this._settings.get_default_value('trans-dynamic-behavior'));
this._settings.set_value('trans-dynamic-distance', this._settings.get_default_value('trans-dynamic-distance'));
this._builder.get_object('trans_options_distance_spinbutton').set_value(this._settings.get_int('trans-dynamic-distance'));
this._settings.set_value('trans-dynamic-anim-target', this._settings.get_default_value('trans-dynamic-anim-target'));
this._builder.get_object('trans_options_min_opacity_spinbutton').set_value(this._settings.get_double('trans-dynamic-anim-target') * 100);
this._settings.set_value('trans-dynamic-anim-time', this._settings.get_default_value('trans-dynamic-anim-time'));
this._builder.get_object('trans_options_anim_time_spinbutton').set_value(this._settings.get_int('trans-dynamic-anim-time'));
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
this._settings.bind('intellihide',
this._builder.get_object('intellihide_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('intellihide',
this._builder.get_object('intellihide_options_button'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('intellihide-hide-from-windows',
this._builder.get_object('intellihide_window_hide_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('intellihide-hide-from-windows',
this._builder.get_object('intellihide_behaviour_options'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('intellihide-behaviour',
this._builder.get_object('intellihide_behaviour_combo'),
'active-id',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('intellihide-use-pressure',
this._builder.get_object('intellihide_use_pressure_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('intellihide-use-pressure',
this._builder.get_object('intellihide_use_pressure_options'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('intellihide-show-in-fullscreen',
this._builder.get_object('intellihide_show_in_fullscreen_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('intellihide-only-secondary',
this._builder.get_object('intellihide_only_secondary_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('multi-monitors',
this._builder.get_object('grid_intellihide_only_secondary'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('multimon_multi_switch').connect('notify::active', (widget) => {
if (!widget.get_active())
this._builder.get_object('intellihide_only_secondary_switch').set_active(false);
});
this._builder.get_object('intellihide_pressure_threshold_spinbutton').set_value(this._settings.get_int('intellihide-pressure-threshold'));
this._builder.get_object('intellihide_pressure_threshold_spinbutton').connect('value-changed', Lang.bind(this, function (widget) {
this._settings.set_int('intellihide-pressure-threshold', widget.get_value());
}));
this._builder.get_object('intellihide_pressure_time_spinbutton').set_value(this._settings.get_int('intellihide-pressure-time'));
this._builder.get_object('intellihide_pressure_time_spinbutton').connect('value-changed', Lang.bind(this, function (widget) {
this._settings.set_int('intellihide-pressure-time', widget.get_value());
}));
this._settings.bind('intellihide-key-toggle-text',
this._builder.get_object('intellihide_toggle_entry'),
'text',
Gio.SettingsBindFlags.DEFAULT);
this._settings.connect('changed::intellihide-key-toggle-text', () => setShortcut(this._settings, 'intellihide-key-toggle'));
this._builder.get_object('intellihide_animation_time_spinbutton').set_value(this._settings.get_int('intellihide-animation-time'));
this._builder.get_object('intellihide_animation_time_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('intellihide-animation-time', widget.get_value());
}));
this._builder.get_object('intellihide_close_delay_spinbutton').set_value(this._settings.get_int('intellihide-close-delay'));
this._builder.get_object('intellihide_close_delay_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('intellihide-close-delay', widget.get_value());
}));
this._builder.get_object('intellihide_enable_start_delay_spinbutton').set_value(this._settings.get_int('intellihide-enable-start-delay'));
this._builder.get_object('intellihide_enable_start_delay_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('intellihide-enable-start-delay', widget.get_value());
}));
this._builder.get_object('intellihide_options_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Intellihide options'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('box_intellihide_options');
dialog.get_content_area().add(box);
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('intellihide-hide-from-windows', this._settings.get_default_value('intellihide-hide-from-windows'));
this._settings.set_value('intellihide-behaviour', this._settings.get_default_value('intellihide-behaviour'));
this._settings.set_value('intellihide-use-pressure', this._settings.get_default_value('intellihide-use-pressure'));
this._settings.set_value('intellihide-show-in-fullscreen', this._settings.get_default_value('intellihide-show-in-fullscreen'));
this._settings.set_value('intellihide-only-secondary', this._settings.get_default_value('intellihide-only-secondary'));
this._settings.set_value('intellihide-pressure-threshold', this._settings.get_default_value('intellihide-pressure-threshold'));
this._builder.get_object('intellihide_pressure_threshold_spinbutton').set_value(this._settings.get_int('intellihide-pressure-threshold'));
this._settings.set_value('intellihide-pressure-time', this._settings.get_default_value('intellihide-pressure-time'));
this._builder.get_object('intellihide_pressure_time_spinbutton').set_value(this._settings.get_int('intellihide-pressure-time'));
this._settings.set_value('intellihide-key-toggle-text', this._settings.get_default_value('intellihide-key-toggle-text'));
this._settings.set_value('intellihide-animation-time', this._settings.get_default_value('intellihide-animation-time'));
this._builder.get_object('intellihide_animation_time_spinbutton').set_value(this._settings.get_int('intellihide-animation-time'));
this._settings.set_value('intellihide-close-delay', this._settings.get_default_value('intellihide-close-delay'));
this._builder.get_object('intellihide_close_delay_spinbutton').set_value(this._settings.get_int('intellihide-close-delay'));
this._settings.set_value('intellihide-enable-start-delay', this._settings.get_default_value('intellihide-enable-start-delay'));
this._builder.get_object('intellihide_enable_start_delay_spinbutton').set_value(this._settings.get_int('intellihide-enable-start-delay'));
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
// Behavior panel
this._builder.get_object('show_applications_side_padding_spinbutton').set_value(this._settings.get_int('show-apps-icon-side-padding'));
this._builder.get_object('show_applications_side_padding_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('show-apps-icon-side-padding', widget.get_value());
}));
this._settings.bind('animate-show-apps',
this._builder.get_object('application_button_animation_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-apps-override-escape',
this._builder.get_object('show_applications_esc_key_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-showdesktop-hover',
this._builder.get_object('show_showdesktop_hide_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-showdesktop-hover',
this._builder.get_object('grid_show_showdesktop_hide_options'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-appmenu',
this._builder.get_object('show_appmenu_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-window-previews',
this._builder.get_object('show_window_previews_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-window-previews',
this._builder.get_object('show_window_previews_button'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-tooltip',
this._builder.get_object('show_tooltip_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-favorites',
this._builder.get_object('show_favorite_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-favorites-all-monitors',
this._builder.get_object('multimon_multi_show_favorites_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-favorites',
this._builder.get_object('multimon_multi_show_favorites_switch'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('show-running-apps',
this._builder.get_object('show_runnning_apps_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._setPreviewTitlePosition();
this._builder.get_object('grid_preview_title_font_color_colorbutton').connect('notify::color', Lang.bind(this, function (button) {
let rgba = button.get_rgba();
let css = rgba.to_string();
let hexString = cssHexString(css);
this._settings.set_string('window-preview-title-font-color', hexString);
}));
this._builder.get_object('show_window_previews_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Window preview options'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let scrolledWindow = this._builder.get_object('box_window_preview_options');
adjustScrollableHeight(this._builder.get_object('viewport_window_preview_options'), scrolledWindow);
dialog.get_content_area().add(scrolledWindow);
this._builder.get_object('preview_timeout_spinbutton').set_value(this._settings.get_int('show-window-previews-timeout'));
this._builder.get_object('preview_timeout_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('show-window-previews-timeout', widget.get_value());
}));
this._settings.bind('preview-middle-click-close',
this._builder.get_object('preview_middle_click_close_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-fixed-x',
this._builder.get_object('preview_aspect_ratio_x_fixed_togglebutton'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-fixed-y',
this._builder.get_object('preview_aspect_ratio_y_fixed_togglebutton'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('preview-use-custom-opacity',
this._builder.get_object('preview_custom_opacity_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('preview-use-custom-opacity',
this._builder.get_object('preview_custom_opacity_spinbutton'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('preview_custom_opacity_spinbutton').set_value(this._settings.get_int('preview-custom-opacity'));
this._builder.get_object('preview_custom_opacity_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('preview-custom-opacity', widget.get_value());
}));
this._settings.bind('peek-mode',
this._builder.get_object('peek_mode_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('peek-mode',
this._builder.get_object('grid_enter_peek_mode_timeout'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('peek-mode',
this._builder.get_object('grid_peek_mode_opacity'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-show-title',
this._builder.get_object('preview_show_title_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-show-title',
this._builder.get_object('grid_preview_title_size'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-show-title',
this._builder.get_object('grid_preview_title_weight'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-show-title',
this._builder.get_object('grid_preview_title_font_color'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('enter_peek_mode_timeout_spinbutton').set_value(this._settings.get_int('enter-peek-mode-timeout'));
this._builder.get_object('enter_peek_mode_timeout_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('enter-peek-mode-timeout', widget.get_value());
}));
this._builder.get_object('leave_timeout_spinbutton').set_value(this._settings.get_int('leave-timeout'));
this._builder.get_object('leave_timeout_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('leave-timeout', widget.get_value());
}));
this._settings.bind('window-preview-hide-immediate-click',
this._builder.get_object('preview_immediate_click_button'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('animation_time_spinbutton').set_value(this._settings.get_int('window-preview-animation-time'));
this._builder.get_object('animation_time_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-animation-time', widget.get_value());
}));
this._builder.get_object('peek_mode_opacity_spinbutton').set_value(this._settings.get_int('peek-mode-opacity'));
this._builder.get_object('peek_mode_opacity_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('peek-mode-opacity', widget.get_value());
}));
this._builder.get_object('preview_size_spinbutton').set_value(this._settings.get_int('window-preview-size'));
this._builder.get_object('preview_size_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-size', widget.get_value());
}));
this._builder.get_object('preview_aspect_ratio_x_combo').set_active_id(this._settings.get_int('window-preview-aspect-ratio-x').toString());
this._builder.get_object('preview_aspect_ratio_x_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-aspect-ratio-x', parseInt(widget.get_active_id(), 10));
}));
this._builder.get_object('preview_aspect_ratio_y_combo').set_active_id(this._settings.get_int('window-preview-aspect-ratio-y').toString());
this._builder.get_object('preview_aspect_ratio_y_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-aspect-ratio-y', parseInt(widget.get_active_id(), 10));
}));
this._builder.get_object('preview_padding_spinbutton').set_value(this._settings.get_int('window-preview-padding'));
this._builder.get_object('preview_padding_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-padding', widget.get_value());
}));
this._builder.get_object('preview_title_size_spinbutton').set_value(this._settings.get_int('window-preview-title-font-size'));
this._builder.get_object('preview_title_size_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-title-font-size', widget.get_value());
}));
this._builder.get_object('grid_preview_title_weight_combo').set_active_id(this._settings.get_string('window-preview-title-font-weight'));
this._builder.get_object('grid_preview_title_weight_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('window-preview-title-font-weight', widget.get_active_id());
}));
(function() {
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('window-preview-title-font-color'));
this._builder.get_object('grid_preview_title_font_color_colorbutton').set_rgba(rgba);
}).apply(this);
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('show-window-previews-timeout', this._settings.get_default_value('show-window-previews-timeout'));
this._builder.get_object('preview_timeout_spinbutton').set_value(this._settings.get_int('show-window-previews-timeout'));
this._settings.set_value('leave-timeout', this._settings.get_default_value('leave-timeout'));
this._builder.get_object('leave_timeout_spinbutton').set_value(this._settings.get_int('leave-timeout'));
this._settings.set_value('window-preview-hide-immediate-click', this._settings.get_default_value('window-preview-hide-immediate-click'));
this._settings.set_value('window-preview-animation-time', this._settings.get_default_value('window-preview-animation-time'));
this._builder.get_object('animation_time_spinbutton').set_value(this._settings.get_int('window-preview-animation-time'));
this._settings.set_value('preview-use-custom-opacity', this._settings.get_default_value('preview-use-custom-opacity'));
this._settings.set_value('preview-custom-opacity', this._settings.get_default_value('preview-custom-opacity'));
this._builder.get_object('preview_custom_opacity_spinbutton').set_value(this._settings.get_int('preview-custom-opacity'));
this._settings.set_value('window-preview-title-position', this._settings.get_default_value('window-preview-title-position'));
this._setPreviewTitlePosition();
this._settings.set_value('peek-mode', this._settings.get_default_value('peek-mode'));
this._settings.set_value('window-preview-show-title', this._settings.get_default_value('window-preview-show-title'));
this._settings.set_value('enter-peek-mode-timeout', this._settings.get_default_value('enter-peek-mode-timeout'));
this._builder.get_object('enter_peek_mode_timeout_spinbutton').set_value(this._settings.get_int('enter-peek-mode-timeout'));
this._settings.set_value('peek-mode-opacity', this._settings.get_default_value('peek-mode-opacity'));
this._builder.get_object('peek_mode_opacity_spinbutton').set_value(this._settings.get_int('peek-mode-opacity'));
this._settings.set_value('window-preview-size', this._settings.get_default_value('window-preview-size'));
this._builder.get_object('preview_size_spinbutton').set_value(this._settings.get_int('window-preview-size'));
this._settings.set_value('window-preview-fixed-x', this._settings.get_default_value('window-preview-fixed-x'));
this._settings.set_value('window-preview-fixed-y', this._settings.get_default_value('window-preview-fixed-y'));
this._settings.set_value('window-preview-aspect-ratio-x', this._settings.get_default_value('window-preview-aspect-ratio-x'));
this._builder.get_object('preview_aspect_ratio_x_combo').set_active_id(this._settings.get_int('window-preview-aspect-ratio-x').toString());
this._settings.set_value('window-preview-aspect-ratio-y', this._settings.get_default_value('window-preview-aspect-ratio-y'));
this._builder.get_object('preview_aspect_ratio_y_combo').set_active_id(this._settings.get_int('window-preview-aspect-ratio-y').toString());
this._settings.set_value('window-preview-padding', this._settings.get_default_value('window-preview-padding'));
this._builder.get_object('preview_padding_spinbutton').set_value(this._settings.get_int('window-preview-padding'));
this._settings.set_value('preview-middle-click-close', this._settings.get_default_value('preview-middle-click-close'));
this._settings.set_value('window-preview-title-font-size', this._settings.get_default_value('window-preview-title-font-size'));
this._builder.get_object('preview_title_size_spinbutton').set_value(this._settings.get_int('window-preview-title-font-size'));
this._settings.set_value('window-preview-title-font-weight', this._settings.get_default_value('window-preview-title-font-weight'));
this._builder.get_object('grid_preview_title_weight_combo').set_active_id(this._settings.get_string('window-preview-title-font-weight'));
this._settings.set_value('window-preview-title-font-color', this._settings.get_default_value('window-preview-title-font-color'));
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('window-preview-title-font-color'));
this._builder.get_object('grid_preview_title_font_color_colorbutton').set_rgba(rgba);
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(scrolledWindow);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
this._settings.bind('isolate-workspaces',
this._builder.get_object('isolate_workspaces_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('isolate-monitors',
this._builder.get_object('multimon_multi_isolate_monitor_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('group-apps',
this._builder.get_object('group_apps_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT | Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._settings.bind('group-apps',
this._builder.get_object('show_group_apps_options_button'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT | Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._builder.get_object('group_apps_label_font_color_colorbutton').connect('notify::color', Lang.bind(this, function (button) {
let rgba = button.get_rgba();
let css = rgba.to_string();
let hexString = cssHexString(css);
this._settings.set_string('group-apps-label-font-color', hexString);
}));
this._builder.get_object('group_apps_label_font_color_minimized_colorbutton').connect('notify::color', Lang.bind(this, function (button) {
let rgba = button.get_rgba();
let css = rgba.to_string();
let hexString = cssHexString(css);
this._settings.set_string('group-apps-label-font-color-minimized', hexString);
}));
this._settings.bind('group-apps-use-fixed-width',
this._builder.get_object('group_apps_use_fixed_width_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('group-apps-underline-unfocused',
this._builder.get_object('group_apps_underline_unfocused_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('group-apps-use-launchers',
this._builder.get_object('group_apps_use_launchers_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('show_group_apps_options_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Ungrouped application options'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('box_group_apps_options');
dialog.get_content_area().add(box);
this._builder.get_object('group_apps_label_font_size_spinbutton').set_value(this._settings.get_int('group-apps-label-font-size'));
this._builder.get_object('group_apps_label_font_size_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('group-apps-label-font-size', widget.get_value());
}));
this._builder.get_object('group_apps_label_font_weight_combo').set_active_id(this._settings.get_string('group-apps-label-font-weight'));
this._builder.get_object('group_apps_label_font_weight_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('group-apps-label-font-weight', widget.get_active_id());
}));
(function() {
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('group-apps-label-font-color'));
this._builder.get_object('group_apps_label_font_color_colorbutton').set_rgba(rgba);
}).apply(this);
(function() {
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('group-apps-label-font-color-minimized'));
this._builder.get_object('group_apps_label_font_color_minimized_colorbutton').set_rgba(rgba);
}).apply(this);
this._builder.get_object('group_apps_label_max_width_spinbutton').set_value(this._settings.get_int('group-apps-label-max-width'));
this._builder.get_object('group_apps_label_max_width_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('group-apps-label-max-width', widget.get_value());
}));
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('group-apps-label-font-size', this._settings.get_default_value('group-apps-label-font-size'));
this._builder.get_object('group_apps_label_font_size_spinbutton').set_value(this._settings.get_int('group-apps-label-font-size'));
this._settings.set_value('group-apps-label-font-weight', this._settings.get_default_value('group-apps-label-font-weight'));
this._builder.get_object('group_apps_label_font_weight_combo').set_active_id(this._settings.get_string('group-apps-label-font-weight'));
this._settings.set_value('group-apps-label-font-color', this._settings.get_default_value('group-apps-label-font-color'));
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('group-apps-label-font-color'));
this._builder.get_object('group_apps_label_font_color_colorbutton').set_rgba(rgba);
this._settings.set_value('group-apps-label-font-color-minimized', this._settings.get_default_value('group-apps-label-font-color-minimized'));
let minimizedFontColor = new Gdk.RGBA();
minimizedFontColor.parse(this._settings.get_string('group-apps-label-font-color-minimized'));
this._builder.get_object('group_apps_label_font_color_minimized_colorbutton').set_rgba(minimizedFontColor);
this._settings.set_value('group-apps-label-max-width', this._settings.get_default_value('group-apps-label-max-width'));
this._builder.get_object('group_apps_label_max_width_spinbutton').set_value(this._settings.get_int('group-apps-label-max-width'));
this._settings.set_value('group-apps-use-fixed-width', this._settings.get_default_value('group-apps-use-fixed-width'));
this._settings.set_value('group-apps-underline-unfocused', this._settings.get_default_value('group-apps-underline-unfocused'));
this._settings.set_value('group-apps-use-launchers', this._settings.get_default_value('group-apps-use-launchers'));
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
this._builder.get_object('click_action_combo').set_active_id(this._settings.get_string('click-action'));
this._builder.get_object('click_action_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('click-action', widget.get_active_id());
}));
this._builder.get_object('shift_click_action_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('shift-click-action', widget.get_active_id());
}));
this._builder.get_object('middle_click_action_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('middle-click-action', widget.get_active_id());
}));
this._builder.get_object('shift_middle_click_action_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('shift-middle-click-action', widget.get_active_id());
}));
// Create dialog for middle-click options
this._builder.get_object('middle_click_options_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Customize middle-click behavior'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('box_middle_click_options');
dialog.get_content_area().add(box);
this._builder.get_object('shift_click_action_combo').set_active_id(this._settings.get_string('shift-click-action'));
this._builder.get_object('middle_click_action_combo').set_active_id(this._settings.get_string('middle-click-action'));
this._builder.get_object('shift_middle_click_action_combo').set_active_id(this._settings.get_string('shift-middle-click-action'));
this._settings.bind('shift-click-action',
this._builder.get_object('shift_click_action_combo'),
'active-id',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('middle-click-action',
this._builder.get_object('middle_click_action_combo'),
'active-id',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('shift-middle-click-action',
this._builder.get_object('shift_middle_click_action_combo'),
'active-id',
Gio.SettingsBindFlags.DEFAULT);
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings for the relevant keys
let keys = ['shift-click-action', 'middle-click-action', 'shift-middle-click-action'];
keys.forEach(function(val) {
this._settings.set_value(val, this._settings.get_default_value(val));
}, this);
this._builder.get_object('shift_click_action_combo').set_active_id(this._settings.get_string('shift-click-action'));
this._builder.get_object('middle_click_action_combo').set_active_id(this._settings.get_string('middle-click-action'));
this._builder.get_object('shift_middle_click_action_combo').set_active_id(this._settings.get_string('shift-middle-click-action'));
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
this._builder.get_object('scroll_panel_combo').set_active_id(this._settings.get_string('scroll-panel-action'));
this._builder.get_object('scroll_panel_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('scroll-panel-action', widget.get_active_id());
}));
this._builder.get_object('scroll_icon_combo').set_active_id(this._settings.get_string('scroll-icon-action'));
this._builder.get_object('scroll_icon_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('scroll-icon-action', widget.get_active_id());
}));
// Create dialog for panel scroll options
this._builder.get_object('scroll_panel_options_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Customize panel scroll behavior'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('scroll_panel_options_box');
dialog.get_content_area().add(box);
this._builder.get_object('scroll_panel_options_delay_spinbutton').set_value(this._settings.get_int('scroll-panel-delay'));
this._builder.get_object('scroll_panel_options_delay_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('scroll-panel-delay', widget.get_value());
}));
this._settings.bind('scroll-panel-show-ws-popup',
this._builder.get_object('scroll_panel_options_show_ws_popup_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('scroll-panel-delay', this._settings.get_default_value('scroll-panel-delay'));
this._builder.get_object('scroll_panel_options_delay_spinbutton').set_value(this._settings.get_int('scroll-panel-delay'));
this._settings.set_value('scroll-panel-show-ws-popup', this._settings.get_default_value('scroll-panel-show-ws-popup'));
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
// Create dialog for icon scroll options
this._builder.get_object('scroll_icon_options_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Customize icon scroll behavior'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('scroll_icon_options_box');
dialog.get_content_area().add(box);
this._builder.get_object('scroll_icon_options_delay_spinbutton').set_value(this._settings.get_int('scroll-icon-delay'));
this._builder.get_object('scroll_icon_options_delay_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('scroll-icon-delay', widget.get_value());
}));
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('scroll-icon-delay', this._settings.get_default_value('scroll-icon-delay'));
this._builder.get_object('scroll_icon_options_delay_spinbutton').set_value(this._settings.get_int('scroll-icon-delay'));
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
this._settings.bind('hot-keys',
this._builder.get_object('hot_keys_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('hot-keys',
this._builder.get_object('overlay_button'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('overlay_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('hotkeys-overlay-combo', widget.get_active_id());
}));
this._settings.bind('shortcut-previews',
this._builder.get_object('shortcut_preview_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('shortcut_num_keys_combo').set_active_id(this._settings.get_string('shortcut-num-keys'));
this._builder.get_object('shortcut_num_keys_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('shortcut-num-keys', widget.get_active_id());
}));
this._settings.connect('changed::hotkey-prefix-text', Lang.bind(this, function() {checkHotkeyPrefix(this._settings);}));
this._builder.get_object('hotkey_prefix_combo').set_active_id(this._settings.get_string('hotkey-prefix-text'));
this._settings.bind('hotkey-prefix-text',
this._builder.get_object('hotkey_prefix_combo'),
'active-id',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('overlay_combo').set_active_id(this._settings.get_string('hotkeys-overlay-combo'));
this._settings.bind('hotkeys-overlay-combo',
this._builder.get_object('overlay_combo'),
'active-id',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('overlay-timeout',
this._builder.get_object('timeout_spinbutton'),
'value',
Gio.SettingsBindFlags.DEFAULT);
if (this._settings.get_string('hotkeys-overlay-combo') !== 'TEMPORARILY') {
this._builder.get_object('timeout_spinbutton').set_sensitive(false);
}
this._settings.connect('changed::hotkeys-overlay-combo', Lang.bind(this, function() {
if (this._settings.get_string('hotkeys-overlay-combo') !== 'TEMPORARILY')
this._builder.get_object('timeout_spinbutton').set_sensitive(false);
else
this._builder.get_object('timeout_spinbutton').set_sensitive(true);
}));
this._settings.bind('shortcut-text',
this._builder.get_object('shortcut_entry'),
'text',
Gio.SettingsBindFlags.DEFAULT);
this._settings.connect('changed::shortcut-text', Lang.bind(this, function() {setShortcut(this._settings, 'shortcut');}));
// Create dialog for number overlay options
this._builder.get_object('overlay_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Advanced hotkeys options'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('box_overlay_shortcut');
dialog.get_content_area().add(box);
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings for the relevant keys
let keys = ['hotkey-prefix-text', 'shortcut-text', 'hotkeys-overlay-combo', 'overlay-timeout', 'shortcut-previews'];
keys.forEach(function(val) {
this._settings.set_value(val, this._settings.get_default_value(val));
}, this);
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
// setup dialog for secondary menu options
this._builder.get_object('secondarymenu_options_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Secondary Menu Options'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('box_secondarymenu_options');
dialog.get_content_area().add(box);
this._settings.bind('secondarymenu-contains-appmenu',
this._builder.get_object('secondarymenu_appmenu_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('secondarymenu-contains-showdetails',
this._builder.get_object('secondarymenu_showdetails_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('secondarymenu-contains-appmenu', this._settings.get_default_value('secondarymenu-contains-appmenu'));
this._settings.set_value('secondarymenu-contains-showdetails', this._settings.get_default_value('secondarymenu-contains-showdetails'));
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
// setup dialog for advanced options
this._builder.get_object('button_advanced_options').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Advanced Options'),
transient_for: this.widget.get_toplevel(),
use_header_bar: true,
modal: true });
// GTK+ leaves positive values for application-defined response ids.
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('box_advanced_options');
dialog.get_content_area().add(box);
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.destroy();
}
return;
}));
dialog.show_all();
}));
// Fine-tune panel
let sizeScales = [
{objectName: 'tray_size_scale', valueName: 'tray-size', range: DEFAULT_FONT_SIZES },
{objectName: 'leftbox_size_scale', valueName: 'leftbox-size', range: DEFAULT_FONT_SIZES },
{objectName: 'appicon_margin_scale', valueName: 'appicon-margin', range: DEFAULT_MARGIN_SIZES },
{objectName: 'appicon_padding_scale', valueName: 'appicon-padding', range: DEFAULT_MARGIN_SIZES },
{objectName: 'tray_padding_scale', valueName: 'tray-padding', range: DEFAULT_PADDING_SIZES },
{objectName: 'leftbox_padding_scale', valueName: 'leftbox-padding', range: DEFAULT_PADDING_SIZES },
{objectName: 'statusicon_padding_scale', valueName: 'status-icon-padding', range: DEFAULT_PADDING_SIZES },
{objectName: 'panel_length_scale', valueName: 'panel-length', range: LENGTH_MARKS }
];
for(var idx in sizeScales) {
let size_scale = this._builder.get_object(sizeScales[idx].objectName);
let range = sizeScales[idx].range;
size_scale.set_range(range[range.length-1], range[0]);
size_scale.set_value(this._settings.get_int(sizeScales[idx].valueName));
// Add marks from range arrays, omitting the first and last values.
range.slice(1, -1).forEach(function(val) {
size_scale.add_mark(val, Gtk.PositionType.TOP, val.toString());
});
// Corrent for rtl languages
if (this._rtl) {
// Flip value position: this is not done automatically
size_scale.set_value_pos(Gtk.PositionType.LEFT);
// I suppose due to a bug, having a more than one mark and one above a value of 100
// makes the rendering of the marks wrong in rtl. This doesn't happen setting the scale as not flippable
// and then manually inverting it
size_scale.set_flippable(false);
size_scale.set_inverted(true);
}
}
this._settings.bind('animate-app-switch',
this._builder.get_object('animate_app_switch_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('animate-window-launch',
this._builder.get_object('animate_window_launch_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('stockgs-keep-dash',
this._builder.get_object('stockgs_dash_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('stockgs-keep-top-panel',
this._builder.get_object('stockgs_top_panel_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.connect('changed::stockgs-keep-top-panel', () => this._maybeDisableTopPosition());
this._maybeDisableTopPosition();
this._settings.bind('stockgs-panelbtn-click-only',
this._builder.get_object('stockgs_panelbtn_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('stockgs-force-hotcorner',
this._builder.get_object('stockgs_hotcorner_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
// About Panel
this._builder.get_object('extension_version').set_label(Me.metadata.version.toString() + (Me.metadata.commit ? ' (' + Me.metadata.commit + ')' : ''));
this._builder.get_object('importexport_export_button').connect('clicked', widget => {
this._showFileChooser(
_('Export settings'),
{ action: Gtk.FileChooserAction.SAVE,
do_overwrite_confirmation: true },
Gtk.STOCK_SAVE,
filename => {
let file = Gio.file_new_for_path(filename);
let raw = file.replace(null, false, Gio.FileCreateFlags.NONE, null);
let out = Gio.BufferedOutputStream.new_sized(raw, 4096);
out.write_all(GLib.spawn_command_line_sync('dconf dump ' + SCHEMA_PATH)[1], null);
out.close(null);
}
);
});
this._builder.get_object('importexport_import_button').connect('clicked', widget => {
this._showFileChooser(
_('Import settings'),
{ action: Gtk.FileChooserAction.OPEN },
Gtk.STOCK_OPEN,
filename => {
let settingsFile = Gio.File.new_for_path(filename);
let [ , pid, stdin, stdout, stderr] =
GLib.spawn_async_with_pipes(
null,
['dconf', 'load', SCHEMA_PATH],
null,
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
null
);
stdin = new Gio.UnixOutputStream({ fd: stdin, close_fd: true });
GLib.close(stdout);
GLib.close(stderr);
let [ , , , retCode] = GLib.spawn_command_line_sync(GSET + ' -d ' + Me.uuid);
if (retCode == 0) {
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, () => GLib.spawn_command_line_sync(GSET + ' -e ' + Me.uuid));
}
stdin.splice(settingsFile.read(null), Gio.OutputStreamSpliceFlags.CLOSE_SOURCE | Gio.OutputStreamSpliceFlags.CLOSE_TARGET, null);
}
);
});
let updateCheckSwitch = this._builder.get_object('updates_check_switch');
updateCheckSwitch.set_sensitive(false);
this._builder.get_object('updates_check_now_button').connect('clicked', widget => {
this._settings.set_boolean('force-check-update', true);
});
//!start-update
updateCheckSwitch.set_sensitive(true);
this._settings.bind('check-update',
updateCheckSwitch,
'active',
Gio.SettingsBindFlags.DEFAULT);
//!end-update
},
_setPreviewTitlePosition: function() {
switch (this._settings.get_string('window-preview-title-position')) {
case 'BOTTOM':
this._builder.get_object('preview_title_position_bottom_button').set_active(true);
break;
case 'TOP':
this._builder.get_object('preview_title_position_top_button').set_active(true);
break;
}
},
_showFileChooser: function(title, params, acceptBtn, acceptHandler) {
let dialog = new Gtk.FileChooserDialog(mergeObjects({ title: title, transient_for: this.widget.get_toplevel() }, params));
dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL);
dialog.add_button(acceptBtn, Gtk.ResponseType.ACCEPT);
if (dialog.run() == Gtk.ResponseType.ACCEPT) {
try {
acceptHandler(dialog.get_filename());
} catch(e) {
log('error from dash-to-panel filechooser: ' + e);
}
}
dialog.destroy();
},
/**
* Object containing all signals defined in the glade file
*/
_SignalHandler: {
position_bottom_button_clicked_cb: function(button) {
if (!this._ignorePositionRadios && button.get_active()) this._setPanelPosition(Pos.BOTTOM);
},
position_top_button_clicked_cb: function(button) {
if (!this._ignorePositionRadios && button.get_active()) this._setPanelPosition(Pos.TOP);
},
position_left_button_clicked_cb: function(button) {
if (!this._ignorePositionRadios && button.get_active()) this._setPanelPosition(Pos.LEFT);
},
position_right_button_clicked_cb: function(button) {
if (!this._ignorePositionRadios && button.get_active()) this._setPanelPosition(Pos.RIGHT);
},
dots_bottom_button_toggled_cb: function(button) {
if (button.get_active())
this._settings.set_string('dot-position', "BOTTOM");
},
dots_top_button_toggled_cb: function(button) {
if (button.get_active())
this._settings.set_string('dot-position', "TOP");
},
dots_left_button_toggled_cb: function(button) {
if (button.get_active())
this._settings.set_string('dot-position', "LEFT");
},
dots_right_button_toggled_cb: function(button) {
if (button.get_active())
this._settings.set_string('dot-position', "RIGHT");
},
preview_title_position_bottom_button_toggled_cb: function(button) {
if (button.get_active())
this._settings.set_string('window-preview-title-position', 'BOTTOM');
},
preview_title_position_top_button_toggled_cb: function(button) {
if (button.get_active())
this._settings.set_string('window-preview-title-position', 'TOP');
},
panel_length_scale_format_value_cb: function(scale, value) {
return value+ '%';
},
panel_size_scale_format_value_cb: function(scale, value) {
return value+ ' px';
},
panel_size_scale_value_changed_cb: function(scale) {
// Avoid settings the size consinuosly
if (this._panel_size_timeout > 0)
Mainloop.source_remove(this._panel_size_timeout);
this._panel_size_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function() {
this._settings.set_int('panel-size', scale.get_value());
this._panel_size_timeout = 0;
return GLib.SOURCE_REMOVE;
}));
},
tray_size_scale_format_value_cb: function(scale, value) {
return value+ ' px';
},
tray_size_scale_value_changed_cb: function(scale) {
// Avoid settings the size consinuosly
if (this._tray_size_timeout > 0)
Mainloop.source_remove(this._tray_size_timeout);
this._tray_size_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function() {
this._settings.set_int('tray-size', scale.get_value());
this._tray_size_timeout = 0;
return GLib.SOURCE_REMOVE;
}));
},
leftbox_size_scale_format_value_cb: function(scale, value) {
return value+ ' px';
},
leftbox_size_scale_value_changed_cb: function(scale) {
// Avoid settings the size consinuosly
if (this._leftbox_size_timeout > 0)
Mainloop.source_remove(this._leftbox_size_timeout);
this._leftbox_size_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function() {
this._settings.set_int('leftbox-size', scale.get_value());
this._leftbox_size_timeout = 0;
return GLib.SOURCE_REMOVE;
}));
},
appicon_margin_scale_format_value_cb: function(scale, value) {
return value+ ' px';
},
appicon_margin_scale_value_changed_cb: function(scale) {
// Avoid settings the size consinuosly
if (this._appicon_margin_timeout > 0)
Mainloop.source_remove(this._appicon_margin_timeout);
this._appicon_margin_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function() {
this._settings.set_int('appicon-margin', scale.get_value());
this._appicon_margin_timeout = 0;
return GLib.SOURCE_REMOVE;
}));
},
appicon_padding_scale_format_value_cb: function(scale, value) {
return value + ' px';
},
appicon_padding_scale_value_changed_cb: function(scale) {
// Avoid settings the size consinuosly
if (this._appicon_padding_timeout > 0)
Mainloop.source_remove(this._appicon_padding_timeout);
this._appicon_padding_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function() {
this._settings.set_int('appicon-padding', scale.get_value());
this._appicon_padding_timeout = 0;
return GLib.SOURCE_REMOVE;
}));
},
tray_padding_scale_format_value_cb: function(scale, value) {
return value+ ' px';
},
tray_padding_scale_value_changed_cb: function(scale) {
// Avoid settings the size consinuosly
if (this._tray_padding_timeout > 0)
Mainloop.source_remove(this._tray_padding_timeout);
this._tray_padding_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function() {
this._settings.set_int('tray-padding', scale.get_value());
this._tray_padding_timeout = 0;
return GLib.SOURCE_REMOVE;
}));
},
statusicon_padding_scale_format_value_cb: function(scale, value) {
return value+ ' px';
},
statusicon_padding_scale_value_changed_cb: function(scale) {
// Avoid settings the size consinuosly
if (this._statusicon_padding_timeout > 0)
Mainloop.source_remove(this._statusicon_padding_timeout);
this._statusicon_padding_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function() {
this._settings.set_int('status-icon-padding', scale.get_value());
this._statusicon_padding_timeout = 0;
return GLib.SOURCE_REMOVE;
}));
},
leftbox_padding_scale_format_value_cb: function(scale, value) {
return value+ ' px';
},
leftbox_padding_scale_value_changed_cb: function(scale) {
// Avoid settings the size consinuosly
if (this._leftbox_padding_timeout > 0)
Mainloop.source_remove(this._leftbox_padding_timeout);
this._leftbox_padding_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function() {
this._settings.set_int('leftbox-padding', scale.get_value());
this._leftbox_padding_timeout = 0;
return GLib.SOURCE_REMOVE;
}));
}
}
});
function init() {
Convenience.initTranslations();
}
function buildPrefsWidget() {
let settings = new Settings();
let widget = settings.widget;
// I'd like the scrolled window to default to a size large enough to show all without scrolling, if it fits on the screen
// But, it doesn't seem possible, so I'm setting a minimum size if there seems to be enough screen real estate
widget.show_all();
adjustScrollableHeight(settings.viewport, widget);
return widget;
}
function adjustScrollableHeight(viewport, scrollableWindow) {
let viewportSize = viewport.size_request();
let screenHeight = scrollableWindow.get_screen().get_height() - 120;
scrollableWindow.set_size_request(viewportSize.width, viewportSize.height > screenHeight ? screenHeight : viewportSize.height);
}