diff options
author | Bartosz Jaroszewski <b.jarosze@gmail.com> | 2018-04-05 20:28:15 +0200 |
---|---|---|
committer | Bartosz Jaroszewski <b.jarosze@gmail.com> | 2018-04-05 20:43:49 +0200 |
commit | e5c57c2c8e54ac664f68eb0876aeaa77797c97f5 (patch) | |
tree | 0cecf19fd5e458cca968de98747b98ae4230d1fe | |
parent | 9777396dd3f4d5417bdbdad64a56dc1742629f84 (diff) |
added settings
-rw-r--r-- | Settings.ui | 243 | ||||
-rw-r--r-- | convenience.js | 93 | ||||
-rw-r--r-- | extension.js | 31 | ||||
-rw-r--r-- | metadata.json | 2 | ||||
-rw-r--r-- | prefs.js | 77 | ||||
-rw-r--r-- | schemas/gschemas.compiled | bin | 0 -> 476 bytes | |||
-rw-r--r-- | schemas/org.gnome.shell.extensions.bluetooth-quick-connect.gschema.xml | 17 |
7 files changed, 458 insertions, 5 deletions
diff --git a/Settings.ui b/Settings.ui new file mode 100644 index 0000000..b0a86ad --- /dev/null +++ b/Settings.ui @@ -0,0 +1,243 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.20.0 --> +<interface> + <requires lib="gtk+" version="3.12"/> + <object class="GtkAdjustment" id="auto_power_off_interval_adjustment"> + <property name="lower">1</property> + <property name="upper">3600</property> + <property name="step_increment">1</property> + <property name="page_increment">5</property> + </object> + <object class="GtkBox" id="auto_power_off_settings"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">24</property> + <property name="margin_right">24</property> + <property name="margin_top">24</property> + <property name="margin_bottom">24</property> + <property name="orientation">vertical</property> + <property name="spacing">24</property> + <child> + <object class="GtkFrame"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkListBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selection_mode">none</property> + <child> + <object class="GtkListBoxRow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">12</property> + <property name="margin_right">12</property> + <property name="margin_top">12</property> + <property name="margin_bottom">12</property> + <property name="column_spacing">32</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Checking idle inteval (seconds)</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="auto_power_off_interval"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="halign">end</property> + <property name="hexpand">True</property> + <property name="text">60</property> + <property name="adjustment">auto_power_off_interval_adjustment</property> + <property name="climb_rate">1</property> + <property name="snap_to_ticks">True</property> + <property name="numeric">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + </object> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + <object class="GtkBox" id="bluetooth_quick_connect_settings"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">24</property> + <property name="margin_right">24</property> + <property name="margin_top">24</property> + <property name="margin_bottom">24</property> + <property name="orientation">vertical</property> + <property name="spacing">24</property> + <child> + <object class="GtkFrame"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkListBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selection_mode">none</property> + <child> + <object class="GtkListBoxRow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">12</property> + <property name="margin_right">12</property> + <property name="margin_top">12</property> + <property name="margin_bottom">12</property> + <property name="column_spacing">32</property> + <child> + <object class="GtkSwitch" id="auto_power_on_switch"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="halign">end</property> + <property name="valign">center</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="auto_power_on_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="label" translatable="yes">Enable bluetooth when menu opened</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child> + <object class="GtkListBoxRow"> + <property name="width_request">100</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">12</property> + <property name="margin_right">12</property> + <property name="margin_top">12</property> + <property name="margin_bottom">12</property> + <property name="column_spacing">32</property> + <child> + <object class="GtkLabel" id="auto_power_off_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="label" translatable="yes">Disable bluetooth if idle</property> + <property name="use_markup">True</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkButton" id="auto_power_off_settings_button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="xalign">0.46000000834465027</property> + <child> + <object class="GtkImage" id="image_window_previews_options2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">emblem-system-symbolic</property> + </object> + </child> + <style> + <class name="circular"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkSwitch" id="auto_power_off_switch"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="halign">end</property> + <property name="valign">center</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + </object> + </child> + </object> + </child> + </object> + </child> + <child type="label_item"> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> +</interface> diff --git a/convenience.js b/convenience.js new file mode 100644 index 0000000..1c866b2 --- /dev/null +++ b/convenience.js @@ -0,0 +1,93 @@ +/* -*- mode: js; js-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (c) 2011-2012, Giovanni Campagna <scampa.giovanni@gmail.com> + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the GNOME nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +const Gettext = imports.gettext; +const Gio = imports.gi.Gio; + +const Config = imports.misc.config; +const ExtensionUtils = imports.misc.extensionUtils; + +/** + * initTranslations: + * @domain: (optional): the gettext domain to use + * + * Initialize Gettext to load translations from extensionsdir/locale. + * If @domain is not provided, it will be taken from metadata['gettext-domain'] + */ +function initTranslations(domain) { + let extension = ExtensionUtils.getCurrentExtension(); + + domain = domain || extension.metadata['gettext-domain']; + + // check if this extension was built with "make zip-file", and thus + // has the locale files in a subfolder + // otherwise assume that extension has been installed in the + // same prefix as gnome-shell + let localeDir = extension.dir.get_child('locale'); + if (localeDir.query_exists(null)) + Gettext.bindtextdomain(domain, localeDir.get_path()); + else + Gettext.bindtextdomain(domain, Config.LOCALEDIR); +} + +/** + * getSettings: + * @schema: (optional): the GSettings schema id + * + * Builds and return a GSettings schema for @schema, using schema files + * in extensionsdir/schemas. If @schema is not provided, it is taken from + * metadata['settings-schema']. + */ +function getSettings(schema) { + let extension = ExtensionUtils.getCurrentExtension(); + + schema = schema || extension.metadata['settings-schema']; + + const GioSSS = Gio.SettingsSchemaSource; + + // check if this extension was built with "make zip-file", and thus + // has the schema files in a subfolder + // otherwise assume that extension has been installed in the + // same prefix as gnome-shell (and therefore schemas are available + // in the standard folders) + let schemaDir = extension.dir.get_child('schemas'); + let schemaSource; + + if (schemaDir.query_exists(null)) + schemaSource = GioSSS.new_from_directory(schemaDir.get_path(), + GioSSS.get_default(), + false); + else + schemaSource = GioSSS.get_default(); + + let schemaObj = schemaSource.lookup(schema, true); + if (!schemaObj) + throw new Error('Schema ' + schema + ' could not be found for extension ' + + extension.metadata.uuid + '. Please check your installation.'); + + return new Gio.Settings({ settings_schema: schemaObj }); +} diff --git a/extension.js b/extension.js index 8a60547..a069481 100644 --- a/extension.js +++ b/extension.js @@ -4,6 +4,10 @@ const PopupMenu = imports.ui.popupMenu; const Util = imports.misc.util; const GLib = imports.gi.GLib; +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Convenience = Me.imports.convenience; + class BluetoothDevice { constructor(model, device) { this._name = model.get_value(device, GnomeBluetooth.Column.NAME); @@ -58,18 +62,19 @@ class BluetoothDevice { } class BluetoothQuickConnect { - constructor(bluetooth) { + constructor(bluetooth, settings) { this._model = bluetooth._model; this._getDefaultAdapter = bluetooth._getDefaultAdapter; this._menu = bluetooth._item.menu; this._proxy = bluetooth._proxy; + this._settings = settings; this._signals = []; } enable() { this._connectSignal(this._menu, 'open-state-changed', (menu, isOpen) => { - if (isOpen) + if (isOpen && this._autoPowerOnEnabled()) this._proxy.BluetoothAirplaneMode = false; }); @@ -79,6 +84,8 @@ class BluetoothQuickConnect { this._proxy.BluetoothAirplaneMode = false; this._idleMonitor(); + + this._sync(); } disable() { @@ -87,11 +94,11 @@ class BluetoothQuickConnect { _idleMonitor() { this._idleMonitorId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 60 * 1000, () => { - if (this._getConnectedDevices().length === 0) + if (this._autoPowerOffEnabled() && this._getConnectedDevices().length === 0) this._proxy.BluetoothAirplaneMode = true; return true; - }, null); + }); } _connectSignal(subject, signal_name, method) { @@ -159,12 +166,26 @@ class BluetoothQuickConnect { if (this._idleMonitorId) GLib.Source.remove(this._idleMonitorId); } + + _autoPowerOnEnabled() { + return this._settings.get_boolean('bluetooth-auto-power-on'); + } + + _autoPowerOffEnabled() { + return this._settings.get_boolean('bluetooth-auto-power-off'); + } + + _autoPowerOffCheckingInterval() { + return this._settings.get_int('bluetooth-auto-power-off-interval'); + } } +let bluetoothQuickConnect = null; function init() { let bluetooth = Main.panel.statusArea.aggregateMenu._bluetooth; - bluetoothQuickConnect = new BluetoothQuickConnect(bluetooth); + let settings = Convenience.getSettings(); + bluetoothQuickConnect = new BluetoothQuickConnect(bluetooth, settings); } function enable() { diff --git a/metadata.json b/metadata.json index 2230e23..ca65bed 100644 --- a/metadata.json +++ b/metadata.json @@ -3,6 +3,8 @@ "description": "Allow to connect to paired devices from gnome control panel.", "uuid": "bluetooth-quick-connect@bjarosze.gmail.com", "url": "https://github.com/bjarosze/gnome-bluetooth-quick-connect", + "settings-schema": "org.gnome.shell.extensions.bluetooth-quick-connect", + "gettext-domain": "bluetooth-quick-connect", "shell-version": [ "3.26.2" ] diff --git a/prefs.js b/prefs.js new file mode 100644 index 0000000..d7e51da --- /dev/null +++ b/prefs.js @@ -0,0 +1,77 @@ +const Gio = imports.gi.Gio; +const Gtk = imports.gi.Gtk; + +const Gettext = imports.gettext.domain('gnome-shell-extensions'); +const _ = Gettext.gettext; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Convenience = Me.imports.convenience; + + +class SettingsBuilder { + + constructor() { + this._settings = new Convenience.getSettings(); + this._builder = new Gtk.Builder(); + } + + build() { + this._builder.add_from_file(Me.path + '/Settings.ui'); + this._settingsBox = this._builder.get_object('bluetooth_quick_connect_settings'); + + + this._viewport = new Gtk.Viewport(); + this._viewport.add(this._settingsBox); + this._widget = new Gtk.ScrolledWindow(); + this._widget.add(this._viewport); + + + this._builder.get_object('auto_power_off_settings_button').connect('clicked', () => { + let dialog = new Gtk.Dialog({ title: 'Auto power off settings', + transient_for: this._widget.get_toplevel(), + use_header_bar: true, + modal: true }); + + + let box = this._builder.get_object('auto_power_off_settings'); + dialog.get_content_area().add(box); + + dialog.connect('response', (dialog) => { + dialog.get_content_area().remove(box); + dialog.destroy(); + }); + + dialog.show_all(); + }); + + + this._bind(); + + return this._widget; + } + + _bind() { + let autoPowerOnSwitch = this._builder.get_object('auto_power_on_switch'); + this._settings.bind('bluetooth-auto-power-on', autoPowerOnSwitch, 'active', Gio.SettingsBindFlags.DEFAULT); + + let autoPowerOffSwitch = this._builder.get_object('auto_power_off_switch'); + this._settings.bind('bluetooth-auto-power-off', autoPowerOffSwitch, 'active', Gio.SettingsBindFlags.DEFAULT); + + let autoPowerOffInterval = this._builder.get_object('auto_power_off_interval'); + this._settings.bind('bluetooth-auto-power-off-interval', autoPowerOffInterval, 'value', Gio.SettingsBindFlags.DEFAULT); + } + +} + +function init() { + // Convenience.initTranslations(); +} + +function buildPrefsWidget() { + let settings = new SettingsBuilder(); + let widget = settings.build(); + widget.show_all(); + + return widget; +}
\ No newline at end of file diff --git a/schemas/gschemas.compiled b/schemas/gschemas.compiled Binary files differnew file mode 100644 index 0000000..85560bc --- /dev/null +++ b/schemas/gschemas.compiled diff --git a/schemas/org.gnome.shell.extensions.bluetooth-quick-connect.gschema.xml b/schemas/org.gnome.shell.extensions.bluetooth-quick-connect.gschema.xml new file mode 100644 index 0000000..9acbd50 --- /dev/null +++ b/schemas/org.gnome.shell.extensions.bluetooth-quick-connect.gschema.xml @@ -0,0 +1,17 @@ +<schemalist gettext-domain="bluetooth-quick-connect"> + <schema id="org.gnome.shell.extensions.bluetooth-quick-connect" + path="/org/gnome/shell/extensions/bluetooth-quick-connect/"> + <key name="bluetooth-auto-power-on" type="b"> + <default>false</default> + <summary>Automatically powers on bluetooth when open menu</summary> + </key> + <key name="bluetooth-auto-power-off" type="b"> + <default>false</default> + <summary>Automatically powers off bluetooth if idle</summary> + </key> + <key name="bluetooth-auto-power-off-interval" type="i"> + <default>60</default> + <summary>Checking interval for power off idling bluetooth</summary> + </key> + </schema> +</schemalist> |