mirror of
https://github.com/BreizhHardware/multi-monitors-add-on.git
synced 2026-01-18 16:47:26 +01:00
414 lines
14 KiB
JavaScript
414 lines
14 KiB
JavaScript
/*
|
|
Copyright (C) 2014 spin83
|
|
|
|
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, visit https://www.gnu.org/licenses/.
|
|
*/
|
|
|
|
import * as Lang from "resource:///org/gnome/shell/Extensions/js/lang.js";
|
|
|
|
import GObject from "gi://GObject";
|
|
import Gdk from "gi://Gdk";
|
|
import Gtk from "gi://Gtk";
|
|
import Gio from "gi://Gio";
|
|
import GLib from "gi://GLib";
|
|
|
|
import { gettext as _ } from "resource:///org/gnome/shell/extensions/extension.js";
|
|
|
|
import * as MultiMonitors from "./extension.js";
|
|
const Convenience = MultiMonitors.imports.convenience;
|
|
|
|
const SHOW_INDICATOR_ID = "show-indicator";
|
|
const SHOW_PANEL_ID = "show-panel";
|
|
const SHOW_ACTIVITIES_ID = "show-activities";
|
|
const SHOW_APP_MENU_ID = "show-app-menu";
|
|
const SHOW_DATE_TIME_ID = "show-date-time";
|
|
const THUMBNAILS_SLIDER_POSITION_ID = "thumbnails-slider-position";
|
|
const AVAILABLE_INDICATORS_ID = "available-indicators";
|
|
const TRANSFER_INDICATORS_ID = "transfer-indicators";
|
|
const ENABLE_HOT_CORNERS = "enable-hot-corners";
|
|
|
|
const Columns = {
|
|
INDICATOR_NAME: 0,
|
|
MONITOR_NUMBER: 1,
|
|
};
|
|
|
|
var MultiMonitorsPrefsWidget = GObject.registerClass(
|
|
class MultiMonitorsPrefsWidget extends Gtk.Grid {
|
|
_init() {
|
|
super._init({
|
|
margin_top: 6,
|
|
margin_end: 6,
|
|
margin_bottom: 6,
|
|
margin_start: 6,
|
|
});
|
|
|
|
this._numRows = 0;
|
|
|
|
this.set_orientation(Gtk.Orientation.VERTICAL);
|
|
|
|
this._settings = Convenience.getSettings();
|
|
this._desktopSettings = Convenience.getSettings(
|
|
"org.gnome.desktop.interface",
|
|
);
|
|
|
|
this._display = Gdk.Display.get_default();
|
|
this._monitors = this._display.get_monitors();
|
|
|
|
this._addBooleanSwitch(
|
|
_("Show Multi Monitors indicator on Top Panel."),
|
|
SHOW_INDICATOR_ID,
|
|
);
|
|
this._addBooleanSwitch(
|
|
_("Show Panel on additional monitors."),
|
|
SHOW_PANEL_ID,
|
|
);
|
|
this._addBooleanSwitch(
|
|
_("Show Activities-Button on additional monitors."),
|
|
SHOW_ACTIVITIES_ID,
|
|
);
|
|
this._addBooleanSwitch(
|
|
_("Show AppMenu-Button on additional monitors."),
|
|
SHOW_APP_MENU_ID,
|
|
);
|
|
this._addBooleanSwitch(
|
|
_("Show DateTime-Button on additional monitors."),
|
|
SHOW_DATE_TIME_ID,
|
|
);
|
|
this._addComboBoxSwitch(
|
|
_("Show Thumbnails-Slider on additional monitors."),
|
|
THUMBNAILS_SLIDER_POSITION_ID,
|
|
{
|
|
none: _("No"),
|
|
right: _("On the right"),
|
|
left: _("On the left"),
|
|
auto: _("Auto"),
|
|
},
|
|
);
|
|
this._addSettingsBooleanSwitch(
|
|
_("Enable hot corners."),
|
|
this._desktopSettings,
|
|
ENABLE_HOT_CORNERS,
|
|
);
|
|
|
|
this._store = new Gtk.ListStore();
|
|
this._store.set_column_types([GObject.TYPE_STRING, GObject.TYPE_INT]);
|
|
|
|
this._treeView = new Gtk.TreeView({
|
|
model: this._store,
|
|
hexpand: true,
|
|
vexpand: true,
|
|
});
|
|
this._treeView.get_selection().set_mode(Gtk.SelectionMode.SINGLE);
|
|
|
|
let appColumn = new Gtk.TreeViewColumn({
|
|
expand: true,
|
|
sort_column_id: Columns.INDICATOR_NAME,
|
|
title: _("A list of indicators for transfer to additional monitors."),
|
|
});
|
|
|
|
let nameRenderer = new Gtk.CellRendererText();
|
|
appColumn.pack_start(nameRenderer, true);
|
|
appColumn.add_attribute(nameRenderer, "text", Columns.INDICATOR_NAME);
|
|
|
|
nameRenderer = new Gtk.CellRendererText();
|
|
appColumn.pack_start(nameRenderer, true);
|
|
appColumn.add_attribute(nameRenderer, "text", Columns.MONITOR_NUMBER);
|
|
|
|
this._treeView.append_column(appColumn);
|
|
this.add(this._treeView);
|
|
|
|
let toolbar = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL });
|
|
toolbar.get_style_context().add_class("inline-toolbar");
|
|
|
|
this._settings.connect(
|
|
"changed::" + TRANSFER_INDICATORS_ID,
|
|
Lang.bind(this, this._updateIndicators),
|
|
);
|
|
this._updateIndicators();
|
|
|
|
let addTButton = new Gtk.Button({ icon_name: "list-add" });
|
|
addTButton.connect("clicked", Lang.bind(this, this._addIndicator));
|
|
toolbar.append(addTButton);
|
|
|
|
let removeTButton = new Gtk.Button({ icon_name: "list-remove" });
|
|
removeTButton.connect("clicked", Lang.bind(this, this._removeIndicator));
|
|
toolbar.append(removeTButton);
|
|
|
|
this.add(toolbar);
|
|
}
|
|
|
|
add(child) {
|
|
this.attach(child, 0, this._numRows++, 1, 1);
|
|
}
|
|
|
|
_updateIndicators() {
|
|
this._store.clear();
|
|
|
|
let transfers = this._settings
|
|
.get_value(TRANSFER_INDICATORS_ID)
|
|
.deep_unpack();
|
|
|
|
for (let indicator in transfers) {
|
|
if (transfers.hasOwnProperty(indicator)) {
|
|
let monitor = transfers[indicator];
|
|
let iter = this._store.append();
|
|
this._store.set(
|
|
iter,
|
|
[Columns.INDICATOR_NAME, Columns.MONITOR_NUMBER],
|
|
[indicator, monitor],
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
_addIndicator() {
|
|
let dialog = new Gtk.Dialog({
|
|
title: _("Select indicator"),
|
|
transient_for: this.get_toplevel(),
|
|
modal: true,
|
|
});
|
|
dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL);
|
|
dialog.add_button(_("Add"), Gtk.ResponseType.OK);
|
|
dialog.set_default_response(Gtk.ResponseType.OK);
|
|
|
|
let grid = new Gtk.Grid({
|
|
column_spacing: 10,
|
|
row_spacing: 15,
|
|
margin_top: 10,
|
|
margin_end: 10,
|
|
margin_bottom: 10,
|
|
margin_start: 10,
|
|
});
|
|
|
|
grid.set_orientation(Gtk.Orientation.VERTICAL);
|
|
|
|
dialog._store = new Gtk.ListStore();
|
|
dialog._store.set_column_types([GObject.TYPE_STRING]);
|
|
|
|
dialog._treeView = new Gtk.TreeView({
|
|
model: dialog._store,
|
|
hexpand: true,
|
|
vexpand: true,
|
|
});
|
|
dialog._treeView.get_selection().set_mode(Gtk.SelectionMode.SINGLE);
|
|
|
|
let appColumn = new Gtk.TreeViewColumn({
|
|
expand: true,
|
|
sort_column_id: Columns.INDICATOR_NAME,
|
|
title: _("Indicators on Top Panel"),
|
|
});
|
|
|
|
let nameRenderer = new Gtk.CellRendererText();
|
|
appColumn.pack_start(nameRenderer, true);
|
|
appColumn.add_attribute(nameRenderer, "text", Columns.INDICATOR_NAME);
|
|
|
|
dialog._treeView.append_column(appColumn);
|
|
|
|
let availableIndicators = () => {
|
|
let transfers = this._settings
|
|
.get_value(TRANSFER_INDICATORS_ID)
|
|
.unpack();
|
|
dialog._store.clear();
|
|
this._settings
|
|
.get_strv(AVAILABLE_INDICATORS_ID)
|
|
.forEach((indicator) => {
|
|
if (!transfers.hasOwnProperty(indicator)) {
|
|
let iter = dialog._store.append();
|
|
dialog._store.set(iter, [Columns.INDICATOR_NAME], [indicator]);
|
|
}
|
|
});
|
|
};
|
|
|
|
let availableIndicatorsId = this._settings.connect(
|
|
"changed::" + AVAILABLE_INDICATORS_ID,
|
|
availableIndicators,
|
|
);
|
|
let transferIndicatorsId = this._settings.connect(
|
|
"changed::" + TRANSFER_INDICATORS_ID,
|
|
availableIndicators,
|
|
);
|
|
|
|
availableIndicators.apply(this);
|
|
grid.attach(dialog._treeView, 0, 0, 2, 1);
|
|
|
|
let gHBox = new Gtk.Box({
|
|
orientation: Gtk.Orientation.HORIZONTAL,
|
|
margin_top: 10,
|
|
margin_end: 10,
|
|
margin_bottom: 10,
|
|
margin_start: 10,
|
|
spacing: 20,
|
|
hexpand: true,
|
|
});
|
|
let gLabel = new Gtk.Label({
|
|
label: _("Monitor index:"),
|
|
halign: Gtk.Align.START,
|
|
});
|
|
gHBox.append(gLabel);
|
|
dialog._adjustment = new Gtk.Adjustment({
|
|
lower: 0.0,
|
|
upper: 0.0,
|
|
step_increment: 1.0,
|
|
});
|
|
let spinButton = new Gtk.SpinButton({
|
|
halign: Gtk.Align.END,
|
|
adjustment: dialog._adjustment,
|
|
numeric: 1,
|
|
});
|
|
gHBox.append(spinButton);
|
|
|
|
let monitorsChanged = () => {
|
|
let n_monitors = this._monitors.get_n_items() - 1;
|
|
dialog._adjustment.set_upper(n_monitors);
|
|
dialog._adjustment.set_value(n_monitors);
|
|
};
|
|
|
|
let monitorsChangedId = this._monitors.connect(
|
|
"items-changed",
|
|
monitorsChanged,
|
|
);
|
|
|
|
monitorsChanged.apply(this);
|
|
grid.append(gHBox);
|
|
|
|
dialog.get_content_area().append(grid);
|
|
|
|
dialog.connect("response", (dialog, id) => {
|
|
this._monitors.disconnect(monitorsChangedId);
|
|
this._settings.disconnect(availableIndicatorsId);
|
|
this._settings.disconnect(transferIndicatorsId);
|
|
if (id != Gtk.ResponseType.OK) {
|
|
dialog.destroy();
|
|
return;
|
|
}
|
|
|
|
let [any, model, iter] = dialog._treeView
|
|
.get_selection()
|
|
.get_selected();
|
|
if (any) {
|
|
let indicator = model.get_value(iter, Columns.INDICATOR_NAME);
|
|
|
|
let transfers = this._settings
|
|
.get_value(TRANSFER_INDICATORS_ID)
|
|
.deep_unpack();
|
|
if (!transfers.hasOwnProperty(indicator)) {
|
|
transfers[indicator] = dialog._adjustment.get_value();
|
|
this._settings.set_value(
|
|
TRANSFER_INDICATORS_ID,
|
|
new GLib.Variant("a{si}", transfers),
|
|
);
|
|
}
|
|
}
|
|
|
|
dialog.destroy();
|
|
});
|
|
}
|
|
|
|
_removeIndicator() {
|
|
let [any, model, iter] = this._treeView.get_selection().get_selected();
|
|
if (any) {
|
|
let indicator = model.get_value(iter, Columns.INDICATOR_NAME);
|
|
|
|
let transfers = this._settings
|
|
.get_value(TRANSFER_INDICATORS_ID)
|
|
.deep_unpack();
|
|
if (transfers.hasOwnProperty(indicator)) {
|
|
delete transfers[indicator];
|
|
this._settings.set_value(
|
|
TRANSFER_INDICATORS_ID,
|
|
new GLib.Variant("a{si}", transfers),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
_addComboBoxSwitch(label, schema_id, options) {
|
|
this._addSettingsComboBoxSwitch(
|
|
label,
|
|
this._settings,
|
|
schema_id,
|
|
options,
|
|
);
|
|
}
|
|
|
|
_addSettingsComboBoxSwitch(label, settings, schema_id, options) {
|
|
let gHBox = new Gtk.Box({
|
|
orientation: Gtk.Orientation.HORIZONTAL,
|
|
margin_top: 10,
|
|
margin_end: 10,
|
|
margin_bottom: 10,
|
|
margin_start: 10,
|
|
spacing: 20,
|
|
hexpand: true,
|
|
});
|
|
let gLabel = new Gtk.Label({ label: _(label), halign: Gtk.Align.START });
|
|
gHBox.append(gLabel);
|
|
|
|
let gCBox = new Gtk.ComboBoxText({ halign: Gtk.Align.END });
|
|
Object.entries(options).forEach(function (entry) {
|
|
const [key, val] = entry;
|
|
gCBox.append(key, val);
|
|
});
|
|
gHBox.append(gCBox);
|
|
|
|
this.add(gHBox);
|
|
|
|
settings.bind(
|
|
schema_id,
|
|
gCBox,
|
|
"active-id",
|
|
Gio.SettingsBindFlags.DEFAULT,
|
|
);
|
|
}
|
|
|
|
_addBooleanSwitch(label, schema_id) {
|
|
this._addSettingsBooleanSwitch(label, this._settings, schema_id);
|
|
}
|
|
|
|
_addSettingsBooleanSwitch(label, settings, schema_id) {
|
|
let gHBox = new Gtk.Box({
|
|
orientation: Gtk.Orientation.HORIZONTAL,
|
|
margin_top: 10,
|
|
margin_end: 10,
|
|
margin_bottom: 10,
|
|
margin_start: 10,
|
|
spacing: 20,
|
|
hexpand: true,
|
|
});
|
|
let gLabel = new Gtk.Label({ label: _(label), halign: Gtk.Align.START });
|
|
gHBox.append(gLabel);
|
|
let gSwitch = new Gtk.Switch({ halign: Gtk.Align.END });
|
|
gHBox.append(gSwitch);
|
|
this.add(gHBox);
|
|
|
|
settings.bind(
|
|
schema_id,
|
|
gSwitch,
|
|
"active",
|
|
Gio.SettingsBindFlags.DEFAULT,
|
|
);
|
|
}
|
|
},
|
|
);
|
|
|
|
export function init() {
|
|
Convenience.initTranslations();
|
|
}
|
|
|
|
export function buildPrefsWidget() {
|
|
let widget = new MultiMonitorsPrefsWidget();
|
|
|
|
return widget;
|
|
}
|