1
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
3
const Gio = imports.gi.Gio;
4
const GLib = imports.gi.GLib;
5
const GObject = imports.gi.GObject;
6
const Gtk = imports.gi.Gtk;
7
const Gdk = imports.gi.Gdk;
8
const Lang = imports.lang;
9
const Mainloop = imports.mainloop;
12
const Gettext = imports.gettext.domain('dashtodock');
13
const _ = Gettext.gettext;
14
const N_ = function(e) { return e };
16
const ExtensionUtils = imports.misc.extensionUtils;
17
const Me = ExtensionUtils.getCurrentExtension();
18
const Convenience = Me.imports.convenience;
20
const SCALE_UPDATE_TIMEOUT = 500;
21
const DEFAULT_ICONS_SIZES = [ 128, 96, 64, 48, 32, 24, 16 ];
23
const Settings = new Lang.Class({
24
Name: 'DashToDockSettings',
29
this._settings = Convenience.getSettings('org.gnome.shell.extensions.dash-to-dock');
31
this._rtl = Gtk.Widget.get_default_direction()==Gtk.TextDirection.RTL;
33
this._builder = new Gtk.Builder();
34
this._builder.set_translation_domain(Me.metadata['gettext-domain']);
35
this._builder.add_from_file(Me.path + '/Settings.ui');
37
this.widget = this._builder.get_object('settings_notebook');
39
// Timeout to delay the update of the settings
40
this._dock_size_timeout = 0;
41
this._icon_size_timeout = 0;
42
this._opacity_timeout = 0;
46
this._builder.connect_signals_full(Lang.bind(this, this._connector));
51
_connector: function(builder, object, signal, handler) {
52
object.connect(signal, Lang.bind(this, this._SignalHandler[handler]));
55
_bindSettings: function() {
57
/* Position and size panel */
62
// Build options based on the number of monitors and the current settings.
63
let n_monitors = Gdk.Screen.get_default().get_n_monitors();
64
let primary_monitor = Gdk.Screen.get_default().get_primary_monitor();
66
let monitor = this._settings.get_int('preferred-monitor');
68
// Add primary monitor with index 0, because in GNOME Shell the primary monitor is always 0
69
this._builder.get_object('dock_monitor_combo').append_text(_("Primary monitor"));
70
this._monitors.push(0);
72
// Add connected monitors
74
for (let i = 0; i < n_monitors; i++) {
75
if (i !== primary_monitor){
77
this._monitors.push(ctr);
78
this._builder.get_object('dock_monitor_combo').append_text(_("Secondary monitor ") + ctr);
82
// If one of the external monitor is set as preferred, show it even if not attached
83
if ( monitor >= n_monitors && monitor !== primary_monitor) {
84
this._monitors.push(monitor)
85
this._builder.get_object('dock_monitor_combo').append_text(_("Secondary monitor ") + ++ctr);
88
this._builder.get_object('dock_monitor_combo').set_active(this._monitors.indexOf(monitor));
91
let position = this._settings.get_enum('dock-position');
95
this._builder.get_object('position_top_button').set_active(true);
98
this._builder.get_object('position_right_button').set_active(true);
101
this._builder.get_object('position_bottom_button').set_active(true);
104
this._builder.get_object('position_left_button').set_active(true);
109
/* Left is Right in rtl as a setting */
110
this._builder.get_object('position_left_button').set_label(_("Right"));
111
this._builder.get_object('position_right_button').set_label(_("Left"));
114
// Intelligent autohide options
115
this._settings.bind('dock-fixed',
116
this._builder.get_object('intelligent_autohide_switch'),
118
Gio.SettingsBindFlags.INVERT_BOOLEAN);
119
this._settings.bind('dock-fixed',
120
this._builder.get_object('intelligent_autohide_button'),
122
Gio.SettingsBindFlags.INVERT_BOOLEAN);
123
this._settings.bind('autohide',
124
this._builder.get_object('autohide_switch'),
126
Gio.SettingsBindFlags.DEFAULT);
127
this._settings.bind('require-pressure-to-show',
128
this._builder.get_object('require_pressure_checkbutton'),
130
Gio.SettingsBindFlags.DEFAULT);
131
this._settings.bind('intellihide',
132
this._builder.get_object('intellihide_switch'),
134
Gio.SettingsBindFlags.DEFAULT);
135
this._settings.bind('intellihide-perapp',
136
this._builder.get_object('per_app_intellihide_checkbutton'),
138
Gio.SettingsBindFlags.DEFAULT);
139
this._settings.bind('animation-time',
140
this._builder.get_object('animation_duration_spinbutton'),
142
Gio.SettingsBindFlags.DEFAULT);
143
this._settings.bind('hide-delay',
144
this._builder.get_object('hide_timeout_spinbutton'),
146
Gio.SettingsBindFlags.DEFAULT);
147
this._settings.bind('show-delay',
148
this._builder.get_object('show_timeout_spinbutton'),
150
Gio.SettingsBindFlags.DEFAULT);
151
this._settings.bind('pressure-threshold',
152
this._builder.get_object('pressure_threshold_spinbutton'),
154
Gio.SettingsBindFlags.DEFAULT);
156
//this._builder.get_object('animation_duration_spinbutton').set_value(this._settings.get_double('animation-time'));
158
// Create dialog for intelligent autohide advanced settings
159
this._builder.get_object('intelligent_autohide_button').connect('clicked', Lang.bind(this, function() {
161
let dialog = new Gtk.Dialog({ title: _("Intelligent autohide customization"),
162
transient_for: this.widget.get_toplevel(),
163
use_header_bar: true,
166
// GTK+ leaves positive values for application-defined response ids.
167
// Use +1 for the reset action
168
dialog.add_button(_("Reset to defaults"), 1);
170
let box = this._builder.get_object('intelligent_autohide_advanced_settings_box');
171
dialog.get_content_area().add(box);
173
this._settings.bind('intellihide',
174
this._builder.get_object('per_app_intellihide_checkbutton'),
176
Gio.SettingsBindFlags.GET);
178
this._settings.bind('autohide',
179
this._builder.get_object('require_pressure_checkbutton'),
181
Gio.SettingsBindFlags.GET);
183
dialog.connect('response', Lang.bind(this, function(dialog, id) {
185
// restore default settings for the relevant keys
186
let keys = ['intellihide', 'autohide', 'intellihide-perapp', 'require-pressure-to-show',
187
'animation-time', 'show-delay', 'hide-delay'];
188
keys.forEach(function(val){
189
this._settings.set_value(val, this._settings.get_default_value(val));
192
// remove the settings box so it doesn't get destroyed;
193
dialog.get_content_area().remove(box);
204
this._builder.get_object('dock_size_scale').set_value(this._settings.get_double('height-fraction'));
205
this._builder.get_object('dock_size_scale').add_mark(0.9, Gtk.PositionType.TOP, null);
206
let icon_size_scale = this._builder.get_object('icon_size_scale');
207
icon_size_scale.set_range(DEFAULT_ICONS_SIZES[DEFAULT_ICONS_SIZES.length -1], DEFAULT_ICONS_SIZES[0]);
208
icon_size_scale.set_value(this._settings.get_int('dash-max-icon-size'));
209
DEFAULT_ICONS_SIZES.forEach(function(val){
210
icon_size_scale.add_mark(val, Gtk.PositionType.TOP, val.toString());
213
// Corrent for rtl languages
215
// Flip value position: this is not done automatically
216
this._builder.get_object('dock_size_scale').set_value_pos(Gtk.PositionType.LEFT);
217
icon_size_scale.set_value_pos(Gtk.PositionType.LEFT);
218
/* I suppose due to a bug, having a more than one mark and one above a value of 100
219
* makes the rendering of the marks wrong in rtl. This doesn't happen setting the scale as not flippable
220
* and then manually inverting it
222
icon_size_scale.set_flippable(false);
223
icon_size_scale.set_inverted(true);
226
this._settings.bind('icon-size-fixed', this._builder.get_object('icon_size_fixed_checkbutton'), 'active', Gio.SettingsBindFlags.DEFAULT);
227
this._settings.bind('extend-height', this._builder.get_object('dock_size_extend_checkbutton'), 'active', Gio.SettingsBindFlags.DEFAULT);
228
this._settings.bind('extend-height', this._builder.get_object('dock_size_scale'), 'sensitive', Gio.SettingsBindFlags.INVERT_BOOLEAN);
233
this._settings.bind('show-running',
234
this._builder.get_object('show_running_switch'),
236
Gio.SettingsBindFlags.DEFAULT);
237
this._settings.bind('show-favorites',
238
this._builder.get_object('show_favorite_switch'),
240
Gio.SettingsBindFlags.DEFAULT);
241
this._settings.bind('show-show-apps-button',
242
this._builder.get_object('show_applications_button_switch'),
244
Gio.SettingsBindFlags.DEFAULT);
245
this._settings.bind('show-apps-at-top',
246
this._builder.get_object('application_button_first_button'),
248
Gio.SettingsBindFlags.DEFAULT);
249
this._settings.bind('show-show-apps-button',
250
this._builder.get_object('application_button_first_button'),
252
Gio.SettingsBindFlags.DEFAULT);
254
this._builder.get_object('click_action_combo').set_active(this._settings.get_enum('click-action'));
255
this._builder.get_object('click_action_combo').connect('changed', Lang.bind (this, function(widget) {
256
this._settings.set_enum('click-action', widget.get_active());
259
this._builder.get_object('shift_click_action_combo').set_active(this._settings.get_boolean('minimize-shift')?0:1);
261
this._builder.get_object('shift_click_action_combo').connect('changed', Lang.bind (this, function(widget) {
262
this._settings.set_boolean('minimize-shift', widget.get_active()==1);
265
this._settings.bind('scroll-switch-workspace', this._builder.get_object('switch_workspace_switch'), 'active', Gio.SettingsBindFlags.DEFAULT);
267
/* Appearance Panel */
269
this._settings.bind('apply-custom-theme', this._builder.get_object('customize_theme'), 'sensitive', Gio.SettingsBindFlags.INVERT_BOOLEAN | Gio.SettingsBindFlags.GET);
270
this._settings.bind('apply-custom-theme', this._builder.get_object('builtin_theme_switch'), 'active', Gio.SettingsBindFlags.DEFAULT);
271
this._settings.bind('custom-theme-shrink', this._builder.get_object('shrink_dash_switch'), 'active', Gio.SettingsBindFlags.DEFAULT);
272
this._settings.bind('custom-theme-running-dots', this._builder.get_object('running_dots_switch'), 'active', Gio.SettingsBindFlags.DEFAULT);
273
this._settings.bind('opaque-background', this._builder.get_object('customize_opacity_switch'), 'active', Gio.SettingsBindFlags.DEFAULT);
274
this._builder.get_object('custom_opacity_scale').set_value(this._settings.get_double('background-opacity'));
275
this._settings.bind('opaque-background', this._builder.get_object('custom_opacity'), 'sensitive', Gio.SettingsBindFlags.DEFAULT);
279
this._builder.get_object('extension_version').set_label(Me.metadata.version.toString());
284
// Object containing all signals defined in the glade file
287
dock_display_combo_changed_cb: function (combo) {
288
this._settings.set_int('preferred-monitor', this._monitors[combo.get_active()]);
291
position_top_button_toggled_cb: function (button){
292
if (button.get_active())
293
this._settings.set_enum('dock-position', 0);
296
position_right_button_toggled_cb: function (button) {
297
if (button.get_active())
298
this._settings.set_enum('dock-position', 1);
301
position_bottom_button_toggled_cb: function (button) {
302
if (button.get_active())
303
this._settings.set_enum('dock-position', 2);
306
position_left_button_toggled_cb: function (button) {
307
if (button.get_active())
308
this._settings.set_enum('dock-position', 3);
311
icon_size_combo_changed_cb: function(combo) {
312
this._settings.set_int('dash-max-icon-size', this._allIconSizes[combo.get_active()]);
315
dock_size_scale_format_value_cb: function(scale, value) {
316
return Math.round(value*100)+ ' %';
319
dock_size_scale_value_changed_cb: function(scale){
320
// Avoid settings the size consinuosly
321
if (this._dock_size_timeout >0)
322
Mainloop.source_remove(this._dock_size_timeout);
324
this._dock_size_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function(){
325
this._settings.set_double('height-fraction', scale.get_value());
326
this._dock_size_timeout = 0;
327
return GLib.SOURCE_REMOVE;
331
icon_size_scale_format_value_cb: function(scale, value) {
335
icon_size_scale_value_changed_cb: function(scale){
336
// Avoid settings the size consinuosly
337
if (this._icon_size_timeout >0)
338
Mainloop.source_remove(this._icon_size_timeout);
340
this._icon_size_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function(){
341
this._settings.set_int('dash-max-icon-size', scale.get_value());
342
this._icon_size_timeout = 0;
343
return GLib.SOURCE_REMOVE;
347
custom_opacity_scale_value_changed_cb: function(scale){
348
// Avoid settings the opacity consinuosly as it's change is animated
349
if (this._opacity_timeout >0)
350
Mainloop.source_remove(this._opacity_timeout);
352
this._opacity_timeout = Mainloop.timeout_add(SCALE_UPDATE_TIMEOUT, Lang.bind(this, function(){
353
this._settings.set_double('background-opacity', scale.get_value());
354
this._opacity_timeout = 0;
355
return GLib.SOURCE_REMOVE;
359
custom_opacity_scale_format_value_cb: function(scale, value) {
360
return Math.round(value*100) + ' %';
366
Convenience.initTranslations();
369
function buildPrefsWidget() {
370
let settings = new Settings();
371
let widget = settings.widget;