Note: The actual value is added during build time.
+ *
+ * @returns {string} the version
+ */
+function getFullVersion() {
+ return '1.9.0'; // FULL_VERSION
+}
+
+/**
+ * Loads an icon from the extension's subdirectory "images".
+ *
+ * @param {Gio.File} extensionDir dir of the extension
+ * @param {string} name filename of the image
+ * @returns {Gio.FileIcon} the icon
+ */
+function loadIcon(extensionDir, name) {
+ return new Gio.FileIcon({
+ file: Gio.File.new_for_path(
+ getImagePath(extensionDir, name)
+ ),
+ });
+}
+
+/**
+ * Gets the path to the image from the extension's subdirectory "images".
+ *
+ * @param {Gio.File} extensionDir dir of the extension
+ * @param {string} name filename of the image
+ * @returns {string} the path
+ */
+function getImagePath(extensionDir, name) {
+ return extensionDir.get_child(`images/${name}`).get_path();
+}
+
+export {TalkativeLog, getFullVersion, setDebugEnabled, loadIcon, getImagePath};
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/display_module.js b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/display_module.js
new file mode 100644
index 0000000..1f1702b
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/display_module.js
@@ -0,0 +1,40 @@
+'use strict';
+
+/**
+ * @type {{_display(): Meta_Display, number_of_displays(): int}}
+ */
+var DisplayApi = {
+ /**
+ * Returns the Wayland display or screen
+ *
+ * @returns {Meta.Display}
+ */
+ _display() {
+ return global.display || global.screen;
+ },
+
+ /**
+ * @returns {int}
+ * @public
+ */
+ number_displays() {
+ return this._display().get_n_monitors();
+ },
+
+ /**
+ * @param {number} displayIndex the monitor number
+ * @returns {Meta.Rectangle}
+ */
+ display_geometry_for_index(displayIndex) {
+ return this._display().get_monitor_geometry(displayIndex);
+ },
+
+ /**
+ * @param {Meta.Cursor} cursor the new cursor to set
+ */
+ set_cursor(cursor) {
+ this._display().set_cursor(cursor);
+ },
+};
+
+export {DisplayApi};
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/extension.js b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/extension.js
new file mode 100644
index 0000000..c151057
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/extension.js
@@ -0,0 +1,1034 @@
+/*
+ Copyright (C) 2013 Borsato Ivano
+
+ The JavaScript code in this page is free software: you can
+ redistribute it and/or modify it under the terms of the GNU
+ General Public License (GNU GPL) as published by the Free Software
+ Foundation, either version 3 of the License, or (at your option)
+ any later version. The code is distributed WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
+*/
+
+
+'use strict';
+
+import GObject from 'gi://GObject';
+import St from 'gi://St';
+import Meta from 'gi://Meta';
+import Shell from 'gi://Shell';
+// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/panelMenu.js
+import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
+import Clutter from 'gi://Clutter';
+import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
+import * as Slider from 'resource:///org/gnome/shell/ui/slider.js';
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+
+import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
+
+import * as Lib from './convenience.js';
+import * as Settings from './settings.js';
+import * as Time from './timer.js';
+import * as UtilRecorder from './utilrecorder.js';
+import * as UtilAudio from './utilaudio.js';
+import * as UtilWebcam from './utilwebcam.js';
+import * as UtilNotify from './utilnotify.js';
+import * as Selection from './selection.js';
+import * as UtilExeCmd from './utilexecmd.js';
+
+var Indicator;
+let timerD = null;
+let timerC = null;
+
+let isActive = false;
+let pathFile = '';
+
+let keybindingConfigured = false;
+
+/**
+ * @type {EasyScreenCastIndicator}
+ */
+const EasyScreenCastIndicator = GObject.registerClass({
+ GTypeName: 'EasyScreenCast_Indicator',
+}, class EasyScreenCastIndicator extends PanelMenu.Button {
+ constructor(extension) {
+ super(null, 'EasyScreenCast_Indicator');
+
+ this._extension = extension;
+ this._settings = new Settings.Settings(this._extension.getSettings());
+ Lib.setDebugEnabled(this._settings.getOption('b', Settings.VERBOSE_DEBUG_SETTING_KEY));
+ this._settings._settings.connect(
+ `changed::${Settings.VERBOSE_DEBUG_SETTING_KEY}`,
+ () => {
+ Lib.setDebugEnabled(this._settings.getOption('b', Settings.VERBOSE_DEBUG_SETTING_KEY));
+ }
+ );
+
+ this.CtrlAudio = new UtilAudio.MixerAudio();
+ this.CtrlWebcam = new UtilWebcam.HelperWebcam(_('Unspecified webcam'));
+
+ this.CtrlNotify = new UtilNotify.NotifyManager();
+ this.CtrlExe = new UtilExeCmd.ExecuteStuff(this);
+
+ // load indicator icons
+ this._icons = {
+ on: Lib.loadIcon(this._extension.dir, 'icon_recording.svg'),
+ onSel: Lib.loadIcon(this._extension.dir, 'icon_recordingSel.svg'),
+ off: Lib.loadIcon(this._extension.dir, 'icon_default.svg'),
+ offSel: Lib.loadIcon(this._extension.dir, 'icon_defaultSel.svg'),
+ };
+
+ // check audio
+ if (!this.CtrlAudio.checkAudio()) {
+ Lib.TalkativeLog('-*-disable audio recording');
+ this._settings.setOption(Settings.INPUT_AUDIO_SOURCE_SETTING_KEY, 0);
+ this._settings.setOption(
+ Settings.ACTIVE_CUSTOM_GSP_SETTING_KEY,
+ Settings.getGSPstd(false)
+ );
+ }
+
+ // add enter/leave/click event
+ this.connect('enter_event', () => this.refreshIndicator(true));
+ this.connect('leave_event', () => this.refreshIndicator(false));
+ this.connect('button_press_event', (actor, event) =>
+ this._onButtonPress(actor, event)
+ );
+
+ // prepare setting var
+ if (this._settings.getOption('i', Settings.TIME_DELAY_SETTING_KEY) > 0)
+ this.isDelayActive = true;
+ else
+ this.isDelayActive = false;
+
+
+ // Add the title bar icon and label for time display
+ this.indicatorBox = new St.BoxLayout();
+ this.indicatorIcon = new St.Icon({
+ gicon: this._icons.off,
+ icon_size: 16,
+ });
+ this.timeLabel = new St.Label({
+ text: '',
+ style_class: 'time-label',
+ y_expand: true,
+ y_align: Clutter.ActorAlign.CENTER,
+ });
+
+ this.indicatorBox.add_child(this.timeLabel);
+ this.indicatorBox.add_child(this.indicatorIcon);
+
+ // init var
+ this.recorder = new UtilRecorder.CaptureVideo();
+ this.AreaSelected = null;
+ this.TimeSlider = null;
+
+ this._initMainMenu();
+ }
+
+ /**
+ * @private
+ */
+ _initMainMenu() {
+ this._addStartStopMenuEntry();
+ this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+ this.sub_menu_audio_recording = new PopupMenu.PopupSubMenuMenuItem(_('No audio source'), true);
+ this.sub_menu_audio_recording.icon.icon_name = 'audio-input-microphone-symbolic';
+ this.menu.addMenuItem(this.sub_menu_audio_recording);
+ this._addAudioRecordingSubMenu();
+
+ // add sub menu webcam recording
+ this._addSubMenuWebCam();
+
+ this._addAreaRecordingSubMenu();
+ this._addRecordingDelaySubMenu();
+ this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+ this.menu_item_options = new PopupMenu.PopupMenuItem(_('Options'));
+ this.menu_item_options.actor.insert_child_at_index(
+ new St.Icon({
+ style_class: 'popup-menu-icon',
+ icon_name: 'preferences-other-symbolic',
+ }),
+ 1
+ );
+ this.menu.addMenuItem(this.menu_item_options);
+ this.menu_item_options.connect('activate', () => this._openExtensionPreferences());
+ }
+
+ /**
+ * Set a new value for the time label. Integers are
+ * converted to seconds, minutes, hours. All other
+ * values are converted to strings.
+ *
+ * @param {string|number} newValue new value of the label. if a number, then it's the seconds passed.
+ * @returns {string}
+ */
+ updateTimeLabel(newValue) {
+ /**
+ * @param {number} number a number
+ */
+ function padZeros(number) {
+ if (number < 10)
+ number = `0${number}`;
+
+ return number.toString();
+ }
+
+ if (typeof newValue === 'number') {
+ let hours = Math.floor(newValue / 3600);
+ newValue -= hours * 3600;
+
+ let minutes = Math.floor(newValue / 60);
+ newValue -= minutes * 60;
+
+ newValue = `${padZeros(hours)}:${padZeros(minutes)}:${padZeros(newValue)}`;
+ }
+
+ this.timeLabel.set_text(newValue.toString());
+ }
+
+ /**
+ * Left clicking on the icon toggles the recording
+ * options menu. Any other mouse button will start
+ * the recording.
+ * Some submenus are refreshed to account for new
+ * sources.
+ *
+ * @param {Clutter.Actor} actor the actor
+ * @param {Clutter.Event} event a Clutter.Event
+ */
+ _onButtonPress(actor, event) {
+ let button = event.get_button();
+
+ if (button === 1) {
+ Lib.TalkativeLog('-*-left click indicator');
+
+ this._setupExtensionMenu();
+ } else {
+ Lib.TalkativeLog('-*-right click indicator');
+
+ if (this.menu.isOpen)
+ this.menu.close();
+
+ this.isShowNotify = this._settings.getOption('b', Settings.SHOW_NOTIFY_ALERT_SETTING_KEY);
+ this._doRecording();
+ }
+ }
+
+ /**
+ * Sets up the menu when the user opens it.
+ */
+ _setupExtensionMenu() {
+ this._addAudioRecordingSubMenu();
+ this._addWebcamSubMenu();
+ }
+
+ /**
+ * Sets up all the options for web-cams. Should only run the
+ * first time the icon is clicked an the CtrlWebcam is still
+ * null.
+ */
+ _addWebcamSubMenu() {
+ if (this.CtrlWebcam === null)
+ this.CtrlWebcam = new UtilWebcam.HelperWebcam(_('Unspecified webcam'));
+
+ // add sub menu webcam recording
+ this._populateSubMenuWebcam();
+
+ // start monitoring inputvideo
+ this.CtrlWebcam.startMonitor();
+ }
+
+ /**
+ * Adds individual webcam items to the webcam menu.
+ */
+ _populateSubMenuWebcam() {
+ let arrMI = this._createMIWebCam();
+
+ this.smWebCam.menu.removeAll();
+ for (let element in arrMI)
+ this.smWebCam.menu.addMenuItem(arrMI[element]);
+
+ let i = this._settings.getOption('i', Settings.DEVICE_INDEX_WEBCAM_SETTING_KEY);
+ Lib.TalkativeLog(`-*-populated submenuwebcam. Settings i=${i}`);
+
+ this.smWebCam.label.text = this.WebCamDevice[i];
+ }
+
+ /**
+ * @private
+ */
+ _addStartStopMenuEntry() {
+ this.imRecordAction = new PopupMenu.PopupBaseMenuItem();
+ this.RecordingLabel = new St.Label({
+ text: _('Start recording'),
+ style_class: 'RecordAction-label',
+ content_gravity: Clutter.ContentGravity.CENTER,
+ x_expand: true,
+ x_align: Clutter.ActorAlign.CENTER,
+ });
+ this.imRecordAction.actor.add_child(this.RecordingLabel);
+ this.imRecordAction.x_expand = true;
+ this.imRecordAction.x_fill = true;
+ this.imRecordAction.x_align = Clutter.ActorAlign.CENTER;
+ this.imRecordAction.connect('activate', () => {
+ this.isShowNotify = this._settings.getOption('b', Settings.SHOW_NOTIFY_ALERT_SETTING_KEY);
+ this._doRecording();
+ });
+
+ this.menu.addMenuItem(this.imRecordAction);
+ }
+
+ /**
+ * Refreshes the submenu for audio recording sources.
+ */
+ _addAudioRecordingSubMenu() {
+ Lib.TalkativeLog('-*-reset the sub menu audio');
+ // remove old menu items
+ this.sub_menu_audio_recording.menu.removeAll();
+
+ Lib.TalkativeLog('-*-add new items to sub menu audio');
+ var arrMI = this._createMIAudioRec();
+ for (var ele in arrMI)
+ this.sub_menu_audio_recording.menu.addMenuItem(arrMI[ele]);
+ }
+
+ /**
+ * @private
+ */
+ _addSubMenuWebCam() {
+ this.smWebCam = new PopupMenu.PopupSubMenuMenuItem('', true);
+ this.smWebCam.icon.icon_name = 'camera-web-symbolic';
+
+ this.menu.addMenuItem(this.smWebCam);
+ }
+
+ /**
+ * @private
+ */
+ _addAreaRecordingSubMenu() {
+ this.sub_menu_area_recording = new PopupMenu.PopupSubMenuMenuItem('', true);
+ this.sub_menu_area_recording.icon.icon_name = 'view-fullscreen-symbolic';
+
+ var arrMI = this._createMIAreaRec();
+ for (var ele in arrMI)
+ this.sub_menu_area_recording.menu.addMenuItem(arrMI[ele]);
+
+ this.sub_menu_area_recording.label.text = this.AreaType[this._settings.getOption('i', Settings.AREA_SCREEN_SETTING_KEY)];
+ this.menu.addMenuItem(this.sub_menu_area_recording);
+ }
+
+ /**
+ * @private
+ */
+ _addRecordingDelaySubMenu() {
+ this.smDelayRec = new PopupMenu.PopupSubMenuMenuItem('', true);
+ this.smDelayRec.icon.icon_name = 'alarm-symbolic';
+
+ var arrMI = this._createMIInfoDelayRec();
+ for (var ele in arrMI)
+ this.smDelayRec.menu.addMenuItem(arrMI[ele]);
+
+ var secDelay = this._settings.getOption('i', Settings.TIME_DELAY_SETTING_KEY);
+ if (secDelay > 0) {
+ this.smDelayRec.label.text =
+ secDelay + _(' sec. delay before recording');
+ } else {
+ this.smDelayRec.label.text = _('Start recording immediately');
+ }
+
+ this.menu.addMenuItem(this.smDelayRec);
+ }
+
+ /**
+ * @returns {Array}
+ * @private
+ */
+ _createMIAreaRec() {
+ this.AreaType = [
+ _('Record all desktop'),
+ _('Record a selected monitor'),
+ _('Record a selected window'),
+ _('Record a selected area'),
+ ];
+
+ this.AreaMenuItem = new Array(this.AreaType.length);
+
+ for (var i = 0; i < this.AreaMenuItem.length; i++) {
+ this.AreaMenuItem[i] = new PopupMenu.PopupMenuItem(
+ this.AreaType[i],
+ {
+ reactive: true,
+ activate: true,
+ hover: true,
+ can_focus: true,
+ }
+ );
+
+ (function (areaSetting, arr, item, settings) {
+ this.connectMI = function () {
+ this.connect('activate', () => {
+ Lib.TalkativeLog(`-*-set area recording to ${areaSetting} ${arr[areaSetting]}`);
+ settings.setOption(Settings.AREA_SCREEN_SETTING_KEY, areaSetting);
+
+ item.label.text = arr[areaSetting];
+ });
+ };
+ this.connectMI();
+ }.call(
+ this.AreaMenuItem[i],
+ i,
+ this.AreaType,
+ this.sub_menu_area_recording,
+ this._settings
+ ));
+ }
+
+ return this.AreaMenuItem;
+ }
+
+ /**
+ * @returns {Array}
+ * @private
+ */
+ _createMIWebCam() {
+ this.WebCamDevice = [_('No WebCam recording')];
+ // add menu item webcam device from GST
+ const devices = this.CtrlWebcam.getDevicesIV();
+ this.WebCamDevice.push(...this.CtrlWebcam.getNameDevices());
+ Lib.TalkativeLog(`-*-webcam list: ${this.WebCamDevice}`);
+ this.AreaMenuItem = new Array(this.WebCamDevice.length);
+
+ for (var i = 0; i < this.AreaMenuItem.length; i++) {
+ let devicePath = '';
+
+ // i === 0 is "No Webcam selected"
+ if (i > 0) {
+ const device = devices[i - 1];
+ devicePath = device.get_properties().get_string('device.path');
+ Lib.TalkativeLog(`-*-webcam i=${i} devicePath: ${devicePath}`);
+ }
+
+ Lib.TalkativeLog(`-*-webcam i=${i} menu-item-text: ${this.WebCamDevice[i]}`);
+ this.AreaMenuItem[i] = new PopupMenu.PopupMenuItem(
+ this.WebCamDevice[i],
+ {
+ reactive: true,
+ activate: true,
+ hover: true,
+ can_focus: true,
+ }
+ );
+
+ (function (index, devPath, arr, item, settings) {
+ this.connectMI = function () {
+ this.connect('activate', () => {
+ Lib.TalkativeLog(`-*-set webcam device to ${index} ${arr[index]} devicePath=${devPath}`);
+ settings.setOption(Settings.DEVICE_INDEX_WEBCAM_SETTING_KEY, index);
+ settings.setOption(Settings.DEVICE_WEBCAM_SETTING_KEY, devPath);
+ item.label.text = arr[index];
+ });
+ };
+ this.connectMI();
+ }.call(
+ this.AreaMenuItem[i],
+ i,
+ devicePath,
+ this.WebCamDevice,
+ this.smWebCam,
+ this._settings
+ ));
+ }
+
+ return this.AreaMenuItem;
+ }
+
+ /**
+ * @returns {Array}
+ * @private
+ */
+ _createMIAudioRec() {
+ // add std menu item
+ this.AudioChoice = [
+ {
+ desc: _('No audio source'),
+ name: 'N/A',
+ port: 'N/A',
+ sortable: true,
+ resizeable: true,
+ },
+ {
+ desc: _('Default audio source'),
+ name: 'N/A',
+ port: 'N/A',
+ sortable: true,
+ resizeable: true,
+ },
+ ];
+ // add menu item audio source from PA
+ var audioList = this.CtrlAudio.getListInputAudio();
+ for (var index in audioList)
+ this.AudioChoice.push(audioList[index]);
+
+ this.AudioMenuItem = new Array(this.AudioChoice.length);
+
+ for (var i = 0; i < this.AudioChoice.length; i++) {
+ // create label menu
+ let labelMenu = this.AudioChoice[i].desc;
+ if (i >= 2) {
+ labelMenu +=
+ _('\n - Port: ') +
+ this.AudioChoice[i].port +
+ _('\n - Name: ') +
+ this.AudioChoice[i].name;
+ }
+ // create submenu
+ this.AudioMenuItem[i] = new PopupMenu.PopupMenuItem(labelMenu, {
+ reactive: true,
+ activate: true,
+ hover: true,
+ can_focus: true,
+ });
+ // add icon on submenu
+ this.AudioMenuItem[i].actor.insert_child_at_index(
+ new St.Icon({
+ style_class: 'popup-menu-icon',
+ icon_name: 'audio-card-symbolic',
+ }),
+ 1
+ );
+
+ // update choice audio from pref
+ if (i === this._settings.getOption('i', Settings.INPUT_AUDIO_SOURCE_SETTING_KEY)) {
+ Lib.TalkativeLog(`-*-get audio choice from pref ${i}`);
+ this.sub_menu_audio_recording.label.text = this.AudioChoice[i].desc;
+ }
+
+ // add action on menu item
+ (function (audioIndex, arr, item, settings) {
+ this.connectMI = function () {
+ this.connect('activate', () => {
+ Lib.TalkativeLog(`-*-set audio choice to ${audioIndex}`);
+ settings.setOption(Settings.INPUT_AUDIO_SOURCE_SETTING_KEY, audioIndex);
+ item.label.text = arr[audioIndex].desc;
+ });
+ };
+ this.connectMI();
+ }.call(
+ this.AudioMenuItem[i],
+ i,
+ this.AudioChoice,
+ this.sub_menu_audio_recording,
+ this._settings
+ ));
+ }
+ return this.AudioMenuItem;
+ }
+
+ /**
+ * @returns {Array}
+ * @private
+ */
+ _createMIInfoDelayRec() {
+ this.DelayTimeTitle = new PopupMenu.PopupMenuItem(_('Delay Time'), {
+ reactive: false,
+ });
+
+ this.DelayTimeLabel = new St.Label({
+ text:
+ Math.floor(
+ this._settings.getOption('i', Settings.TIME_DELAY_SETTING_KEY)
+ ).toString() + _(' Sec'),
+ });
+ this.DelayTimeTitle.actor.add_child(this.DelayTimeLabel);
+ // TODO this.DelayTimeTitle.align = St.Align.END;
+
+ this.imSliderDelay = new PopupMenu.PopupBaseMenuItem({
+ activate: false,
+ });
+ this.TimeSlider = new Slider.Slider(this._settings.getOption('i', Settings.TIME_DELAY_SETTING_KEY) / 100);
+ this.TimeSlider.x_expand = true;
+ this.TimeSlider.y_expand = true;
+
+ this.TimeSlider.connect('notify::value', item => {
+ this.DelayTimeLabel.set_text(
+ Math.floor(item.value * 100).toString() + _(' Sec')
+ );
+ });
+
+ this.TimeSlider.connect('drag-end', () => this._onDelayTimeChanged());
+ this.TimeSlider.connect('scroll-event', () =>
+ this._onDelayTimeChanged()
+ );
+
+ this.imSliderDelay.actor.add_child(this.TimeSlider);
+
+ return [this.DelayTimeTitle, this.imSliderDelay];
+ }
+
+ /**
+ * @private
+ */
+ _enable() {
+ // enable key binding
+ this._enableKeybindings();
+ // immediately activate/deactive shortcut on settings change
+ this._settings._settings.connect(
+ `changed::${Settings.ACTIVE_SHORTCUT_SETTING_KEY}`,
+ () => {
+ if (this._settings.getOption('b', Settings.ACTIVE_SHORTCUT_SETTING_KEY)) {
+ Lib.TalkativeLog('-^-shortcut changed - enabling');
+ this._enableKeybindings();
+ } else {
+ Lib.TalkativeLog('-^-shortcut changed - disabling');
+ this._removeKeybindings();
+ }
+ }
+ );
+
+ // start monitoring inputvideo
+ this.CtrlWebcam.startMonitor();
+
+ // add indicator
+ this.add_child(this.indicatorBox);
+ }
+
+ /**
+ * @private
+ */
+ _disable() {
+ // remove key binding
+ this._removeKeybindings();
+ // stop monitoring inputvideo
+ this.CtrlWebcam.stopMonitor();
+ // unregister mixer control
+ this.CtrlAudio.destroy();
+
+ // remove indicator
+ this.remove_child(this.indicatorBox);
+ }
+
+ /**
+ * @private
+ */
+ _doDelayAction() {
+ if (this.isDelayActive) {
+ Lib.TalkativeLog(`-*-delay recording called | delay= ${this.TimeSlider.value}`);
+ timerD = new Time.TimerDelay(
+ Math.floor(this.TimeSlider.value * 100),
+ this._doPreCommand,
+ this
+ );
+ timerD.begin();
+ } else {
+ Lib.TalkativeLog('-*-instant recording called');
+ // start recording
+ this._doPreCommand();
+ }
+ }
+
+ /**
+ * @private
+ */
+ _doPreCommand() {
+ if (this._settings.getOption('b', Settings.ACTIVE_PRE_CMD_SETTING_KEY)) {
+ Lib.TalkativeLog('-*-execute pre command');
+
+ const PreCmd = this._settings.getOption('s', Settings.PRE_CMD_SETTING_KEY);
+
+ this.CtrlExe.Execute(
+ PreCmd,
+ false,
+ res => {
+ Lib.TalkativeLog(`-*-pre command final: ${res}`);
+ if (res === true) {
+ Lib.TalkativeLog('-*-pre command OK');
+ this.recorder.start();
+ } else {
+ Lib.TalkativeLog('-*-pre command ERROR');
+ this.CtrlNotify.createNotify(
+ _('ERROR PRE COMMAND - See logs for more info'),
+ this._icons.off
+ );
+ }
+ },
+ line => {
+ Lib.TalkativeLog(`-*-pre command output: ${line}`);
+ }
+ );
+ } else {
+ this.recorder.start();
+ }
+ }
+
+ /**
+ * @private
+ */
+ _doRecording() {
+ // start/stop record screen
+ if (isActive === false) {
+ Lib.TalkativeLog('-*-start recording');
+
+ pathFile = '';
+
+ // get selected area
+ const optArea = this._settings.getOption('i', Settings.AREA_SCREEN_SETTING_KEY);
+ if (optArea > 0) {
+ Lib.TalkativeLog(`-*-type of selection of the area to record: ${optArea}`);
+ switch (optArea) {
+ case 3:
+ new Selection.SelectionArea();
+ break;
+ case 2:
+ new Selection.SelectionWindow();
+ break;
+ case 1:
+ new Selection.SelectionDesktop();
+ break;
+ }
+ } else {
+ Lib.TalkativeLog('-*-recording full area');
+ this._doDelayAction();
+ }
+ } else {
+ Lib.TalkativeLog('-*-stop recording');
+ isActive = false;
+
+ this.recorder.stop();
+
+ if (timerC !== null) {
+ // stop counting rec
+ timerC.halt();
+ timerC = null;
+ }
+
+ // execute post-command
+ this._doPostCommand();
+ }
+
+ this.refreshIndicator(false);
+ }
+
+ /**
+ * @private
+ */
+ _doPostCommand() {
+ if (this._settings.getOption('b', Settings.ACTIVE_POST_CMD_SETTING_KEY)) {
+ Lib.TalkativeLog('-*-execute post command');
+
+ // launch cmd after registration
+ const tmpCmd = `/usr/bin/sh -c "${this._settings.getOption('s', Settings.POST_CMD_SETTING_KEY)}"`;
+
+ const mapObj = {
+ _fpath: pathFile,
+ _dirpath: pathFile.substr(0, pathFile.lastIndexOf('/')),
+ _fname: pathFile.substr(
+ pathFile.lastIndexOf('/') + 1,
+ pathFile.length
+ ),
+ };
+
+ const Cmd = tmpCmd.replace(/_fpath|_dirpath|_fname/gi, match => {
+ return mapObj[match];
+ });
+
+ Lib.TalkativeLog(`-*-post command:${Cmd}`);
+
+ // execute post command
+ this.CtrlExe.Spawn(Cmd);
+ }
+ }
+
+ /**
+ * @param {boolean} result whether the recording was successful
+ * @param {string} file file path of the recorded file
+ */
+ doRecResult(result, file) {
+ if (result) {
+ isActive = true;
+
+ Lib.TalkativeLog('-*-record OK');
+ // update indicator
+ const indicators = this._settings.getOption('i', Settings.STATUS_INDICATORS_SETTING_KEY);
+ this._replaceStdIndicator(indicators === 1 || indicators === 3);
+
+ if (this.isShowNotify) {
+ Lib.TalkativeLog('-*-show notify');
+ // create counting notify
+ this.notifyCounting = this.CtrlNotify.createNotify(
+ _('Start Recording'),
+ this._icons.on
+ );
+ this.notifyCounting.connect('destroy', () => {
+ Lib.TalkativeLog('-*-notification destroyed');
+ this.notifyCounting = null;
+ });
+
+ // start counting rec
+ timerC = new Time.TimerCounting((secpassed, alertEnd) => {
+ this._refreshNotify(secpassed, alertEnd);
+ }, this);
+ timerC.begin();
+ }
+
+ // update path file video
+ pathFile = file;
+ Lib.TalkativeLog(`-*-update abs file path -> ${pathFile}`);
+ } else {
+ Lib.TalkativeLog('-*-record ERROR');
+
+ pathFile = '';
+
+ if (this.isShowNotify) {
+ Lib.TalkativeLog('-*-show error notify');
+ this.CtrlNotify.createNotify(
+ _('ERROR RECORDER - See logs for more info'),
+ this._icons.off
+ );
+ }
+ }
+ this.refreshIndicator(false);
+ }
+
+ /**
+ * @param {number} sec the seconds passed
+ * @param {boolean} alertEnd whether the timer is ending
+ */
+ _refreshNotify(sec, alertEnd) {
+ if (this.notifyCounting !== null && this.notifyCounting !== undefined && this.isShowNotify) {
+ if (alertEnd) {
+ this.CtrlNotify.updateNotify(
+ this.notifyCounting,
+ _(`Finish Recording / Seconds : ${sec}`),
+ this._icons.off,
+ true
+ );
+ } else {
+ this.CtrlNotify.updateNotify(
+ this.notifyCounting,
+ _('Recording ... / Seconds passed : ') + sec,
+ this._icons.on,
+ false
+ );
+ }
+ }
+ }
+
+ /**
+ * @private
+ */
+ _openExtensionPreferences() {
+ try {
+ this._extension.openPreferences();
+ } catch (e) {
+ Lib.TalkativeLog(`Failed to open preferences: ${e}`);
+ }
+ }
+
+ /**
+ * @private
+ */
+ _onDelayTimeChanged() {
+ const secDelay = Math.floor(this.TimeSlider.value * 100);
+ this._settings.setOption(Settings.TIME_DELAY_SETTING_KEY, secDelay);
+ if (secDelay > 0)
+ this.smDelayRec.label.text = secDelay + _(' sec. delay before recording');
+ else
+ this.smDelayRec.label.text = _('Start recording immediately');
+ }
+
+ /**
+ * @param {boolean} focus selects the correct icon depending on the focus state
+ */
+ refreshIndicator(focus) {
+ Lib.TalkativeLog(`-*-refresh indicator -A ${isActive} -F ${focus}`);
+
+ const indicators = this._settings.getOption('i', Settings.STATUS_INDICATORS_SETTING_KEY);
+
+ if (isActive === true) {
+ if (indicators === 0 || indicators === 1) {
+ if (focus === true)
+ this.indicatorIcon.set_gicon(this._icons.onSel);
+ else
+ this.indicatorIcon.set_gicon(this._icons.on);
+ } else if (this._settings.getOption('b', Settings.ACTIVE_SHORTCUT_SETTING_KEY)) {
+ this.indicatorIcon.set_gicon(null);
+ } else if (focus === true) {
+ this.indicatorIcon.set_gicon(this._icons.onSel);
+ } else {
+ this.indicatorIcon.set_gicon(this._icons.on);
+ }
+
+ this.RecordingLabel.set_text(_('Stop recording'));
+ } else {
+ if (focus === true)
+ this.indicatorIcon.set_gicon(this._icons.offSel);
+ else
+ this.indicatorIcon.set_gicon(this._icons.off);
+
+ this.RecordingLabel.set_text(_('Start recording'));
+ }
+ }
+
+ /**
+ * @param {boolean} OPTtemp whether to replace the standard indicator or use it
+ * @private
+ */
+ _replaceStdIndicator(OPTtemp) {
+ if (Main.panel.statusArea === undefined) {
+ Lib.TalkativeLog('-*-no Main.panel.statusArea found');
+ return;
+ }
+
+ var stdMenu = Main.panel.statusArea.quickSettings;
+ if (stdMenu === undefined) {
+ Lib.TalkativeLog('-*-no quickSettings or aggregateMenu in Main.panel.statusArea');
+ return;
+ }
+ if (stdMenu._remoteAccess === undefined) {
+ Lib.TalkativeLog('-*-no _remoteAccess indicator applet found');
+ return;
+ }
+ var indicator = stdMenu._remoteAccess._indicator;
+ if (indicator === undefined) {
+ Lib.TalkativeLog('-*-no _indicator or _recordingIndicator found');
+ return;
+ }
+
+ if (OPTtemp) {
+ Lib.TalkativeLog('-*-replace STD indicator');
+ indicator.visible = false;
+ } else {
+ Lib.TalkativeLog('-*-use STD indicator');
+ indicator.visible = isActive;
+ }
+ }
+
+ /**
+ * @private
+ */
+ _enableKeybindings() {
+ if (this._settings.getOption('b', Settings.ACTIVE_SHORTCUT_SETTING_KEY)) {
+ Lib.TalkativeLog('-*-enable keybinding');
+
+ Main.wm.addKeybinding(
+ Settings.SHORTCUT_KEY_SETTING_KEY,
+ this._settings._settings,
+ Meta.KeyBindingFlags.NONE,
+ // available modes: https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/src/shell-action-modes.h
+ Shell.ActionMode.NORMAL |
+ Shell.ActionMode.OVERVIEW |
+ Shell.ActionMode.POPUP |
+ Shell.ActionMode.SYSTEM_MODAL,
+ () => {
+ Lib.TalkativeLog('-*-intercept key combination');
+ this._doRecording();
+ }
+ );
+ keybindingConfigured = true;
+ }
+ }
+
+ /**
+ * @private
+ */
+ _removeKeybindings() {
+ if (keybindingConfigured) {
+ Lib.TalkativeLog('-*-remove keybinding');
+ Main.wm.removeKeybinding(Settings.SHORTCUT_KEY_SETTING_KEY);
+ keybindingConfigured = false;
+ }
+ }
+
+ getSelectedRect() {
+ var recX = this._settings.getOption('i', Settings.X_POS_SETTING_KEY);
+ var recY = this._settings.getOption('i', Settings.Y_POS_SETTING_KEY);
+ var recW = this._settings.getOption('i', Settings.WIDTH_SETTING_KEY);
+ var recH = this._settings.getOption('i', Settings.HEIGHT_SETTING_KEY);
+ return [recX, recY, recW, recH];
+ }
+
+ saveSelectedRect(x, y, h, w) {
+ this._settings.setOption(Settings.X_POS_SETTING_KEY, x);
+ this._settings.setOption(Settings.Y_POS_SETTING_KEY, y);
+ this._settings.setOption(Settings.HEIGHT_SETTING_KEY, h);
+ this._settings.setOption(Settings.WIDTH_SETTING_KEY, w);
+ }
+
+ getSettings() {
+ return this._settings;
+ }
+
+ getAudioSource() {
+ return this.CtrlAudio.getAudioSource();
+ }
+
+ /**
+ * Destroy indicator
+ */
+ destroy() {
+ Lib.TalkativeLog('-*-destroy indicator called');
+
+ if (isActive)
+ isActive = false;
+
+ if (this._settings) {
+ this._settings.destroy();
+ this._settings = null;
+ }
+
+ super.destroy();
+ }
+});
+
+export default class EasyScreenCast extends Extension {
+ /**
+ *
+ */
+ enable() {
+ Lib.TalkativeLog('-*-enableExtension called');
+ Lib.TalkativeLog(`-*-version: ${this.metadata.version}`);
+ Lib.TalkativeLog(`-*-install path: ${this.path}`);
+ Lib.TalkativeLog(`-*-version (package.json): ${Lib.getFullVersion()}`);
+
+ if (Indicator === null || Indicator === undefined) {
+ Lib.TalkativeLog('-*-create indicator');
+
+ Indicator = new EasyScreenCastIndicator(this);
+ Main.panel.addToStatusArea('EasyScreenCast-indicator', Indicator);
+ }
+
+ Indicator._enable();
+ }
+
+ /**
+ *
+ */
+ disable() {
+ Lib.TalkativeLog('-*-disableExtension called');
+
+ if (timerD !== null) {
+ Lib.TalkativeLog('-*-timerD stopped');
+ timerD.stop();
+ timerD = null;
+ }
+
+ // this might happen, if the extension is disabled during recording
+ if (timerC !== null) {
+ // stop counting rec
+ timerC.halt();
+ timerC = null;
+ }
+
+
+ if (Indicator !== null) {
+ Lib.TalkativeLog('-*-indicator call destroy');
+
+ Indicator._disable();
+ Indicator.destroy();
+ Indicator = null;
+ }
+ }
+}
+
+export {Indicator};
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/Icon_Info.png b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/Icon_Info.png
new file mode 100644
index 0000000..7f15ae8
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/Icon_Info.png differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/Icon_Performance.svg b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/Icon_Performance.svg
new file mode 100644
index 0000000..f23e320
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/Icon_Performance.svg
@@ -0,0 +1,45 @@
+
+
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/Icon_Quality.svg b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/Icon_Quality.svg
new file mode 100644
index 0000000..b7e8d3d
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/Icon_Quality.svg
@@ -0,0 +1,45 @@
+
+
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_default.svg b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_default.svg
new file mode 100644
index 0000000..ff59a8c
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_default.svg
@@ -0,0 +1,99 @@
+
+
+
+
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_defaultSel.svg b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_defaultSel.svg
new file mode 100644
index 0000000..7a57f9a
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_defaultSel.svg
@@ -0,0 +1,99 @@
+
+
+
+
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_recording.svg b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_recording.svg
new file mode 100644
index 0000000..0608982
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_recording.svg
@@ -0,0 +1,99 @@
+
+
+
+
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_recordingSel.svg b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_recordingSel.svg
new file mode 100644
index 0000000..453444c
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/images/icon_recordingSel.svg
@@ -0,0 +1,99 @@
+
+
+
+
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/ca/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/ca/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..1e565d3
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/ca/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/cs/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/cs/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..ef74169
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/cs/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/de/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/de/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..9f6db59
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/de/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/es/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/es/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..d40762a
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/es/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/fr/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/fr/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..546ca3c
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/fr/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/it/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/it/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..35411ef
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/it/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/ja/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/ja/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..7256b66
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/ja/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/pt_BR/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/pt_BR/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..c88a3bc
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/pt_BR/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/ru/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/ru/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..2392f4c
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/ru/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/uk/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/uk/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..21ae02f
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/uk/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/vi/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/vi/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..7526ab9
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/vi/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/zh/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/zh/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo
new file mode 100644
index 0000000..03ee607
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/locale/zh/LC_MESSAGES/EasyScreenCast@iacopodeenosee.gmail.com.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/metadata.json b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/metadata.json
new file mode 100644
index 0000000..5fb398b
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/metadata.json
@@ -0,0 +1,13 @@
+{
+ "_generated": "Generated by SweetTooth, do not edit",
+ "description": "This extension simplifies the use of the video recording function integrated in gnome shell, allows quickly to change the various settings of the desktop recording.\n\nSOURCE CODE -> https://github.com/EasyScreenCast/EasyScreenCast\n\nVIDEO -> https://youtu.be/81E9AruraKU\n\n**NOTICE**\nif an error occurs during the update is recommended to reload GNOME Shell (Alt + F2, 'r') and reload the extension's installation page.",
+ "gettext-domain": "EasyScreenCast@iacopodeenosee.gmail.com",
+ "name": "EasyScreenCast",
+ "settings-schema": "org.gnome.shell.extensions.EasyScreenCast",
+ "shell-version": [
+ "46"
+ ],
+ "url": "https://github.com/EasyScreenCast/EasyScreenCast",
+ "uuid": "EasyScreenCast@iacopodeenosee.gmail.com",
+ "version": 50
+}
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/prefs.css b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/prefs.css
new file mode 100644
index 0000000..4dc0f17
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/prefs.css
@@ -0,0 +1,7 @@
+.options-grid {
+ margin: 18px;
+}
+
+.borderless {
+ border: none;
+}
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/prefs.js b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/prefs.js
new file mode 100644
index 0000000..e0dd1a2
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/prefs.js
@@ -0,0 +1,1184 @@
+/*
+ Copyright (C) 2013 Borsato Ivano
+
+ The JavaScript code in this page is free software: you can
+ redistribute it and/or modify it under the terms of the GNU
+ General Public License (GNU GPL) as published by the Free Software
+ Foundation, either version 3 of the License, or (at your option)
+ any later version. The code is distributed WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
+*/
+
+'use strict';
+
+import GIRepository from 'gi://GIRepository';
+GIRepository.Repository.prepend_search_path('/usr/lib64/gnome-shell');
+GIRepository.Repository.prepend_library_path('/usr/lib64/gnome-shell');
+
+import Adw from 'gi://Adw';
+import GObject from 'gi://GObject';
+import Gio from 'gi://Gio';
+import Gtk from 'gi://Gtk';
+import Gdk from 'gi://Gdk';
+import Pango from 'gi://Pango';
+
+import {ExtensionPreferences, gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
+
+import * as Lib from './convenience.js';
+import * as UtilWebcam from './utilwebcam.js';
+import * as UtilGSP from './utilgsp.js';
+import * as Settings from './settings.js';
+import * as UtilExeCmd from './utilexecmd.js';
+
+const EasyScreenCastSettingsWidget = GObject.registerClass({
+ GTypeName: 'EasyScreenCast_SettingsWidget',
+}, class EasyScreenCastSettingsWidget extends Gtk.Box {
+ /**
+ * @param {ExtensionPreferences} prefs the prefs instance
+ */
+ constructor(prefs) {
+ super();
+
+ this._prefs = prefs;
+ this._settings = new Settings.Settings(this._prefs.getSettings());
+ Lib.setDebugEnabled(this._settings.getOption('b', Settings.VERBOSE_DEBUG_SETTING_KEY));
+ this.CtrlExe = new UtilExeCmd.ExecuteStuff(this);
+ this.CtrlWebcam = new UtilWebcam.HelperWebcam(_('Unspecified webcam'));
+
+ let cssProvider = new Gtk.CssProvider();
+ cssProvider.load_from_path(`${prefs.path}/prefs.css`);
+ Gtk.StyleContext.add_provider_for_display(
+ Gdk.Display.get_default(),
+ cssProvider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+ // creates the ui builder and add the main resource file
+ let uiFilePath = `${this._prefs.path}/Options_UI.glade`;
+ let builder = new Gtk.Builder();
+ builder.set_translation_domain(this._prefs.metadata['gettext-domain']);
+
+ if (builder.add_from_file(uiFilePath) === 0) {
+ Lib.TalkativeLog(`-^-could not load the ui file: ${uiFilePath}`);
+ let label = new Gtk.Label({
+ label: _('Could not load the preferences UI file'),
+ vexpand: true,
+ });
+
+ this.append(label);
+ } else {
+ Lib.TalkativeLog(`-^-UI file receive and load: ${uiFilePath}`);
+
+ // gets the interesting builder objects
+ let refBoxMainContainer = builder.get_object('Main_Container');
+ this.append(refBoxMainContainer);
+
+ // setup tab options
+ this._initTabOptions(this, builder, this._settings._settings);
+
+ // setup tab quality
+ this._initTabQuality(this, builder, this._settings._settings);
+
+ // setup tab webcam
+ this._initTabWebcam(this, builder, this._settings._settings);
+
+ // setup tab file
+ this._initTabFile(this, builder, this._settings._settings);
+
+ // setup tab support
+ this._initTabSupport(this, builder, this._settings._settings);
+
+ // setup tab info
+ this._initTabInfo(this, builder);
+
+ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+ // update GSP area
+ this._setStateGSP(
+ !this._settings.getOption('b', Settings.ACTIVE_CUSTOM_GSP_SETTING_KEY)
+ );
+
+ // update list view
+ this._updateRowShortcut(
+ this._settings.getOption('as', Settings.SHORTCUT_KEY_SETTING_KEY)[0]
+ );
+
+ // update webcam widget state
+ this._updateStateWebcamOptions();
+
+ // connect keywebcam signal
+ this._settings._settings.connect(
+ `changed::${Settings.DEVICE_INDEX_WEBCAM_SETTING_KEY}`,
+ () => {
+ Lib.TalkativeLog('-^-webcam device changed');
+
+ this._updateStateWebcamOptions();
+ }
+ );
+ }
+ }
+
+ /**
+ * @param {EasyScreenCastSettingsWidget} ctx the prefs/settings widget
+ * @param {Gtk.Builder} gtkDB the builder that loaded the UI glade file
+ * @param {Gio.Settings} tmpS the current settings
+ * @private
+ */
+ _initTabOptions(ctx, gtkDB, tmpS) {
+ // implements show timer option
+ let refSwitchShowNotifyAlert = gtkDB.get_object('swt_ShowNotifyAlert');
+ tmpS.bind(
+ Settings.SHOW_NOTIFY_ALERT_SETTING_KEY,
+ refSwitchShowNotifyAlert,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements show area option
+ let refSwitchShowAreaRec = gtkDB.get_object('swt_ShowAreaRec');
+ tmpS.bind(
+ Settings.SHOW_AREA_REC_SETTING_KEY,
+ refSwitchShowAreaRec,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements show indicator option
+ let refComboboxIndicatorsRec = gtkDB.get_object('cbt_StatusIndicatorsRec');
+ tmpS.bind(
+ Settings.STATUS_INDICATORS_SETTING_KEY,
+ refComboboxIndicatorsRec,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements draw cursor option
+ let refSwitchDrawCursorRec = gtkDB.get_object('swt_DrawCursorRec');
+ tmpS.bind(
+ Settings.DRAW_CURSOR_SETTING_KEY,
+ refSwitchDrawCursorRec,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements enable keybinding option
+ let refSwitchEnableShortcut = gtkDB.get_object('swt_KeyShortcut');
+ tmpS.bind(
+ Settings.ACTIVE_SHORTCUT_SETTING_KEY,
+ refSwitchEnableShortcut,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements selecting alternative key combo
+ let refTreeviewShortcut = gtkDB.get_object('treeview_KeyShortcut');
+ refTreeviewShortcut.set_sensitive(true);
+ ctx.Ref_liststore_Shortcut = gtkDB.get_object('liststore_KeyShortcut');
+ ctx.Iter_ShortcutRow = ctx.Ref_liststore_Shortcut.append();
+
+ let renderer = new Gtk.CellRendererAccel({
+ editable: true,
+ });
+ renderer.connect(
+ 'accel-edited',
+ (_0, _1, key, mods, _2) => {
+ Lib.TalkativeLog(`-^-edited key accel: key=${key} mods=${mods}`);
+
+ let accel = Gtk.accelerator_name(key, mods);
+
+ ctx._updateRowShortcut(accel);
+ this._settings.setOption(Settings.SHORTCUT_KEY_SETTING_KEY, [accel]);
+ }
+ );
+
+ renderer.connect('accel-cleared', () => {
+ Lib.TalkativeLog('-^-cleared key accel');
+
+ ctx._updateRowShortcut(null);
+ this._settings.setOption(Settings.SHORTCUT_KEY_SETTING_KEY, []);
+ });
+
+ let column = new Gtk.TreeViewColumn();
+ column.pack_start(renderer, true);
+ column.add_attribute(
+ renderer,
+ 'accel-key',
+ Settings.SHORTCUT_COLUMN_KEY
+ );
+ column.add_attribute(
+ renderer,
+ 'accel-mods',
+ Settings.SHORTCUT_COLUMN_MODS
+ );
+
+ refTreeviewShortcut.append_column(column);
+
+ // implements post execute command
+ let refSwitchExecutePostCmd = gtkDB.get_object('swt_executepostcmd');
+ tmpS.bind(
+ Settings.ACTIVE_POST_CMD_SETTING_KEY,
+ refSwitchExecutePostCmd,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ let refTexteditPostCmd = gtkDB.get_object('txe_postcmd');
+ tmpS.bind(
+ Settings.POST_CMD_SETTING_KEY,
+ refTexteditPostCmd,
+ 'text',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements pre execute command
+ let refSwitchExecutePreCmd = gtkDB.get_object('swt_executeprecmd');
+ tmpS.bind(
+ Settings.ACTIVE_PRE_CMD_SETTING_KEY,
+ refSwitchExecutePreCmd,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ let refTexteditPreCmd = gtkDB.get_object('txe_precmd');
+ tmpS.bind(
+ Settings.PRE_CMD_SETTING_KEY,
+ refTexteditPreCmd,
+ 'text',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ }
+
+ /**
+ * @param {EasyScreenCastSettingsWidget} ctx the prefs/settings widget
+ * @param {Gtk.Builder} gtkDB the builder that loaded the UI glade file
+ * @param {Gio.Settings} tmpS the current settings
+ * @private
+ */
+ _initTabQuality(ctx, gtkDB, tmpS) {
+ // implements FPS option
+ let refSpinnerFrameRateRec = gtkDB.get_object('spb_FrameRateRec');
+ // Create an adjustment to use for the second spinbutton
+ let adjustment1 = new Gtk.Adjustment({
+ value: 30,
+ lower: 1,
+ upper: 666,
+ step_increment: 1,
+ page_increment: 10,
+ });
+ refSpinnerFrameRateRec.configure(adjustment1, 10, 0);
+ tmpS.bind(
+ Settings.FPS_SETTING_KEY,
+ refSpinnerFrameRateRec,
+ 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements command string rec option
+ let refTexteditPipeline = gtkDB.get_object('txe_CommandStringRec');
+ let refBufferPipeline = refTexteditPipeline.get_buffer();
+ tmpS.bind(
+ Settings.PIPELINE_REC_SETTING_KEY,
+ refBufferPipeline,
+ 'text',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements label description GSP
+ let refLabelDescGSP = gtkDB.get_object('lbl_GSP_Description');
+ refLabelDescGSP.set_text(
+ UtilGSP.getDescr(
+ this._settings.getOption('i', Settings.QUALITY_SETTING_KEY),
+ this._settings.getOption('i', Settings.FILE_CONTAINER_SETTING_KEY)
+ )
+ );
+ // update label description when container selection changed
+ this._settings._settings.connect(`changed::${Settings.FILE_CONTAINER_SETTING_KEY}`, () => {
+ Lib.TalkativeLog('-^- new setting for file container, update gps description');
+ refLabelDescGSP.set_text(
+ UtilGSP.getDescr(
+ this._settings.getOption('i', Settings.QUALITY_SETTING_KEY),
+ this._settings.getOption('i', Settings.FILE_CONTAINER_SETTING_KEY)
+ )
+ );
+ });
+
+
+ // implements quality scale option
+ let refScaleQuality = gtkDB.get_object('scl_Quality');
+ refScaleQuality.set_valign(Gtk.Align.START);
+ let adjustment2 = new Gtk.Adjustment({
+ value: 1,
+ lower: 0,
+ upper: 3,
+ step_increment: 1,
+ page_increment: 1,
+ });
+ refScaleQuality.set_adjustment(adjustment2);
+ refScaleQuality.set_digits(1);
+ let ind = 0;
+ for (; ind < 4; ind++)
+ refScaleQuality.add_mark(ind, Gtk.PositionType.BOTTOM, '');
+
+
+ refScaleQuality.set_value(
+ this._settings.getOption('i', Settings.QUALITY_SETTING_KEY)
+ );
+
+ let oldQualityValue = refScaleQuality.get_value();
+ refScaleQuality.connect('value-changed', self => {
+ // not logging by default - it's too much
+ // Lib.TalkativeLog(`-^-value quality changed : ${self.get_value()}`);
+
+ // round the value
+ let roundTmp = parseInt(self.get_value().toFixed(0));
+ // not logging by default - it's too much
+ // Lib.TalkativeLog(`-^-value quality fixed : ${roundTmp}`);
+
+ self.set_value(roundTmp);
+
+ // only update labels for real changes
+ if (oldQualityValue !== roundTmp) {
+ oldQualityValue = roundTmp;
+ this._settings.setOption(Settings.QUALITY_SETTING_KEY, roundTmp);
+
+ // update label descr GSP
+ refLabelDescGSP.set_text(
+ UtilGSP.getDescr(
+ roundTmp,
+ this._settings.getOption('i', Settings.FILE_CONTAINER_SETTING_KEY)
+ )
+ );
+
+ // update fps
+ this._settings.setOption(
+ Settings.FPS_SETTING_KEY,
+ UtilGSP.getFps(
+ roundTmp,
+ this._settings.getOption('i', Settings.FILE_CONTAINER_SETTING_KEY)
+ )
+ );
+ }
+ });
+
+ // implements image for scale widget
+ let refImagePerformance = gtkDB.get_object('img_Performance');
+ refImagePerformance.set_from_file(Lib.getImagePath(this._prefs.dir, 'Icon_Performance.svg'));
+
+ let refImageQuality = gtkDB.get_object('img_Quality');
+ refImageQuality.set_from_file(Lib.getImagePath(this._prefs.dir, 'Icon_Quality.svg'));
+
+ // implements custom GSPipeline option
+ let refSwitchCustomGSP = gtkDB.get_object('swt_EnableCustomGSP');
+ tmpS.bind(
+ Settings.ACTIVE_CUSTOM_GSP_SETTING_KEY,
+ refSwitchCustomGSP,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ refSwitchCustomGSP.connect('state-set', () => {
+ // update GSP text area
+ ctx._setStateGSP(this._settings.getOption('b', Settings.ACTIVE_CUSTOM_GSP_SETTING_KEY));
+ });
+
+ ctx.Ref_stack_Quality = gtkDB.get_object('stk_Quality');
+ }
+
+ /**
+ * @param {EasyScreenCastSettingsWidget} ctx the prefs/settings widget
+ * @param {Gtk.Builder} gtkDB the builder that loaded the UI glade file
+ * @param {Gio.Settings} tmpS the current settings
+ * @private
+ */
+ _initTabWebcam(ctx, gtkDB, tmpS) {
+ // implements webcam quality option: Type: GtkListStore
+ ctx.Ref_ListStore_QualityWebCam = gtkDB.get_object(
+ 'liststore_QualityWebCam'
+ );
+ let refTreeViewQualityWebCam = gtkDB.get_object(
+ 'treeview_QualityWebam'
+ );
+ // create column data
+ let capsColumn = new Gtk.TreeViewColumn({
+ title: _('WebCam Caps'),
+ });
+ let normalColumn = new Gtk.CellRendererText();
+ capsColumn.pack_start(normalColumn, true);
+ capsColumn.add_attribute(normalColumn, 'text', 0);
+
+ // insert caps column into treeview
+ refTreeViewQualityWebCam.insert_column(capsColumn, 0);
+
+ // setup selection liststore
+ let capsSelection = refTreeViewQualityWebCam.get_selection();
+
+ // connect selection signal
+ capsSelection.connect('changed', self => {
+ let [isSelected,, iter] = self.get_selected();
+ if (isSelected) {
+ let Caps = ctx.Ref_ListStore_QualityWebCam.get_value(iter, 0);
+ Lib.TalkativeLog(`-^-treeview row selected : ${Caps}`);
+
+ this._settings.setOption(Settings.QUALITY_WEBCAM_SETTING_KEY, Caps);
+
+ // update label webcam caps
+ ctx.Ref_Label_WebCamCaps.set_ellipsize(Pango.EllipsizeMode.END);
+ ctx.Ref_Label_WebCamCaps.set_text(Caps);
+ }
+ });
+
+ // fill combobox with quality option webcam
+ ctx._updateWebCamCaps(this._settings.getOption('i', Settings.DEVICE_INDEX_WEBCAM_SETTING_KEY));
+
+ // implements webcam corner position option
+ let refComboboxCornerWebCam = gtkDB.get_object('cbt_WebCamCorner');
+ tmpS.bind(
+ Settings.CORNER_POSITION_WEBCAM_SETTING_KEY,
+ refComboboxCornerWebCam,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements webcam margin x position option
+ let refSpinnerMarginXWebCam = gtkDB.get_object('spb_WebCamMarginX');
+ let adjustmentMarginX = new Gtk.Adjustment({
+ value: 0,
+ lower: 0,
+ upper: 10000,
+ step_increment: 1,
+ page_increment: 10,
+ });
+ refSpinnerMarginXWebCam.configure(adjustmentMarginX, 10, 0);
+ tmpS.bind(
+ Settings.MARGIN_X_WEBCAM_SETTING_KEY,
+ refSpinnerMarginXWebCam,
+ 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements webcam margin y position option
+ let refSpinnerMarginYWebCam = gtkDB.get_object('spb_WebCamMarginY');
+ let adjustmentMarginY = new Gtk.Adjustment({
+ value: 0,
+ lower: 0,
+ upper: 10000,
+ step_increment: 1,
+ page_increment: 10,
+ });
+ refSpinnerMarginYWebCam.configure(adjustmentMarginY, 10, 0);
+ tmpS.bind(
+ Settings.MARGIN_Y_WEBCAM_SETTING_KEY,
+ refSpinnerMarginYWebCam,
+ 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements webcam aplha channel option
+ let refSpinnerAlphaWebCam = gtkDB.get_object('spb_WebCamAlpha');
+ let adjustmentAlpha = new Gtk.Adjustment({
+ value: 0.01,
+ lower: 0.0,
+ upper: 1.0,
+ step_increment: 0.05,
+ page_increment: 0.25,
+ });
+ refSpinnerAlphaWebCam.configure(adjustmentAlpha, 0.25, 2);
+ tmpS.bind(
+ Settings.ALPHA_CHANNEL_WEBCAM_SETTING_KEY,
+ refSpinnerAlphaWebCam,
+ 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements webcam type unit dimension option
+ let refComboboxTypeUnitWebCam = gtkDB.get_object('cbt_WebCamUnitMeasure');
+ tmpS.bind(
+ Settings.TYPE_UNIT_WEBCAM_SETTING_KEY,
+ refComboboxTypeUnitWebCam,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements webcam width option
+ let refSpinnerWidthWebCam = gtkDB.get_object('spb_WebCamWidth');
+ let adjustmentWidth = new Gtk.Adjustment({
+ value: 20,
+ lower: 0,
+ upper: 10000,
+ step_increment: 1,
+ page_increment: 10,
+ });
+ refSpinnerWidthWebCam.configure(adjustmentWidth, 10, 0);
+ tmpS.bind(
+ Settings.WIDTH_WEBCAM_SETTING_KEY,
+ refSpinnerWidthWebCam,
+ 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements webcam heigth option
+ let refSpinnerHeightWebCam = gtkDB.get_object('spb_WebCamHeight');
+ let adjustmentHeight = new Gtk.Adjustment({
+ value: 10,
+ lower: 0,
+ upper: 10000,
+ step_increment: 1,
+ page_increment: 10,
+ });
+ refSpinnerHeightWebCam.configure(adjustmentHeight, 10, 0);
+ tmpS.bind(
+ Settings.HEIGHT_WEBCAM_SETTING_KEY,
+ refSpinnerHeightWebCam,
+ 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements webcam stack menu chooser
+ ctx.Ref_StackSwitcher_WebCam = gtkDB.get_object('sts_Webcam');
+ // implements webcam stack obj
+ ctx.Ref_StackObj_WebCam = gtkDB.get_object('stk_Webcam');
+ // implements webcam stack menu chooser
+ ctx.Ref_Label_WebCam = gtkDB.get_object('lbl_Webcam');
+ // implements webcam caps stack menu chooser
+ ctx.Ref_Label_WebCamCaps = gtkDB.get_object('lbl_WebcamCaps');
+ }
+
+ /**
+ * @param {EasyScreenCastSettingsWidget} ctx the prefs/settings widget
+ * @param {Gtk.Builder} gtkDB the builder that loaded the UI glade file
+ * @param {Gio.Settings} tmpS the current settings
+ * @private
+ */
+ _initTabFile(ctx, gtkDB, tmpS) {
+ // implements file name string rec option
+ let refTexteditFileName = gtkDB.get_object('txe_FileNameRec');
+ tmpS.bind(
+ Settings.FILE_NAME_SETTING_KEY,
+ refTexteditFileName,
+ 'text',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements file container option
+ let refComboboxContainer = gtkDB.get_object('cbt_FileContainer');
+ tmpS.bind(
+ Settings.FILE_CONTAINER_SETTING_KEY,
+ refComboboxContainer,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements file container resolution
+ let refStackFileResolution = gtkDB.get_object('stk_FileResolution');
+
+ // implements file resolution preset spinner
+ let refComboboxResolution = gtkDB.get_object('cbt_FileResolution');
+ tmpS.bind(
+ Settings.FILE_RESOLUTION_TYPE_SETTING_KEY,
+ refComboboxResolution,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // intercept combobox res changed and update width/height value
+ refComboboxResolution.connect('changed', self => {
+ var activeRes = self.active;
+ Lib.TalkativeLog(`-^-preset combobox changed: ${activeRes}`);
+ if (activeRes >= 0 && activeRes < 15) {
+ var [h, w] = ctx._getResolutionPreset(activeRes);
+
+ // update width/height
+ this._settings.setOption(Settings.FILE_RESOLUTION_HEIGHT_SETTING_KEY, h);
+ this._settings.setOption(Settings.FILE_RESOLUTION_WIDTH_SETTING_KEY, w);
+ Lib.TalkativeLog(`-^-Res changed h: ${h} w: ${w}`);
+ }
+ });
+
+ // load file resolution pref and upadte UI
+ var tmpRes = this._settings.getOption('i', Settings.FILE_RESOLUTION_TYPE_SETTING_KEY);
+ if (tmpRes < 0)
+ refStackFileResolution.set_visible_child_name('native');
+ else if (tmpRes === 999)
+ refStackFileResolution.set_visible_child_name('custom');
+ else
+ refStackFileResolution.set_visible_child_name('preset');
+
+
+ // setup event on stack switcher
+ refStackFileResolution.connect('notify::visible-child-name', () => {
+ Lib.TalkativeLog('-^-stack_FR event grab');
+ var page = refStackFileResolution.get_visible_child_name();
+ Lib.TalkativeLog(`-^-active page -> ${page}`);
+
+ if (page === 'native') {
+ // set option to -1
+ this._settings.setOption(Settings.FILE_RESOLUTION_TYPE_SETTING_KEY, -1);
+ } else if (page === 'preset') {
+ // set option to fullHD 16:9
+ this._settings.setOption(Settings.FILE_RESOLUTION_TYPE_SETTING_KEY, 8);
+ } else if (page === 'custom') {
+ // set option to 99
+ this._settings.setOption(Settings.FILE_RESOLUTION_TYPE_SETTING_KEY, 999);
+ } else {
+ Lib.TalkativeLog('-^-page error');
+ }
+ });
+
+ // implements file width option
+ let refSpinnerWidthRes = gtkDB.get_object('spb_ResWidth');
+ let adjustmentResWidth = new Gtk.Adjustment({
+ value: 640,
+ lower: 640,
+ upper: 3840,
+ step_increment: 1,
+ page_increment: 100,
+ });
+ refSpinnerWidthRes.configure(adjustmentResWidth, 10, 0);
+ tmpS.bind(
+ Settings.FILE_RESOLUTION_WIDTH_SETTING_KEY,
+ refSpinnerWidthRes,
+ 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements file heigth option
+ let refSpinnerHeightRes = gtkDB.get_object('spb_ResHeight');
+ let adjustmentResHeight = new Gtk.Adjustment({
+ value: 480,
+ lower: 480,
+ upper: 2160,
+ step_increment: 1,
+ page_increment: 100,
+ });
+ refSpinnerHeightRes.configure(adjustmentResHeight, 10, 0);
+ tmpS.bind(
+ Settings.FILE_RESOLUTION_HEIGHT_SETTING_KEY,
+ refSpinnerHeightRes,
+ 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements keep aspect ratio check box
+ let refCheckboxKeepAspectRatio = gtkDB.get_object('chb_FileResolution_kar');
+ tmpS.bind(
+ Settings.FILE_RESOLUTION_KAR_SETTING_KEY,
+ refCheckboxKeepAspectRatio,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ // implements resolution width scale option
+ let refScaleWidthRes = gtkDB.get_object('scl_ResWidth');
+ refScaleWidthRes.set_valign(Gtk.Align.START);
+ refScaleWidthRes.set_adjustment(adjustmentResWidth);
+ refScaleWidthRes.set_digits(0);
+ refScaleWidthRes.set_value(this._settings.getOption('i', Settings.FILE_RESOLUTION_WIDTH_SETTING_KEY));
+
+ // implements resolution height scale option
+ let refScaleHeightRes = gtkDB.get_object('scl_ResHeight');
+ refScaleHeightRes.set_valign(Gtk.Align.START);
+ refScaleHeightRes.set_adjustment(adjustmentResHeight);
+ refScaleHeightRes.set_digits(0);
+ refScaleHeightRes.set_value(this._settings.getOption('i', Settings.FILE_RESOLUTION_HEIGHT_SETTING_KEY));
+
+ // add marks on width/height file resolution
+ let ind = 0;
+ for (; ind < 13; ind++) {
+ var [h, w] = ctx._getResolutionPreset(ind);
+ refScaleWidthRes.add_mark(w, Gtk.PositionType.BOTTOM, '');
+ refScaleHeightRes.add_mark(h, Gtk.PositionType.BOTTOM, '');
+ }
+
+ // implements file folder string rec option
+ let refFilechooserFileFolder = gtkDB.get_object('fcb_FilePathRec');
+ // check state initial value
+ var tmpFolder = this._settings.getOption('s', Settings.FILE_FOLDER_SETTING_KEY);
+ Lib.TalkativeLog(`-^-folder for screencast: ${tmpFolder}`);
+ if (tmpFolder === '' || tmpFolder === null || tmpFolder === undefined) {
+ let result = null;
+ ctx.CtrlExe.Execute(
+ 'xdg-user-dir VIDEOS',
+ true,
+ (success, out) => {
+ Lib.TalkativeLog(`-^-CALLBACK sync S: ${success} out: ${out}`);
+ if (success && out !== '' && out !== undefined)
+ result = out.replace(/(\n)/g, '');
+ },
+ null
+ );
+
+ if (result !== null) {
+ Lib.TalkativeLog(`-^-xdg-user video: ${result}`);
+ tmpFolder = result;
+ } else {
+ Lib.TalkativeLog('-^-NOT SET xdg-user video');
+
+ ctx.CtrlExe.Execute(
+ '/usr/bin/sh -c "echo $HOME"',
+ true,
+ (success, out) => {
+ Lib.TalkativeLog(`-^-CALLBACK sync S: ${success} out: ${out}`);
+ if (success && out !== '' && out !== undefined)
+ tmpFolder = out.replace(/(\n)/g, '');
+ },
+ null
+ );
+ }
+
+ // connect keywebcam signal
+ this._settings._settings.connect(
+ `changed::${Settings.DEVICE_INDEX_WEBCAM_SETTING_KEY}`,
+ () => {
+ Lib.TalkativeLog('-^-webcam device changed');
+ this._refreshWebcamOptions();
+ }
+ );
+ }
+
+ refFilechooserFileFolder.set_label(`Selected: ${tmpFolder}`);
+
+ refFilechooserFileFolder.connect('clicked', () => {
+ Lib.TalkativeLog('-^- file chooser button clicked...');
+
+ let dialog = new Gtk.FileChooserNative({
+ 'title': 'Select folder',
+ 'transient-for': refFilechooserFileFolder.get_root(),
+ 'action': Gtk.FileChooserAction.SELECT_FOLDER,
+ 'accept-label': 'Ok',
+ 'cancel-label': 'Cancel',
+ });
+ dialog.connect('response', (self, response) => {
+ if (response === Gtk.ResponseType.ACCEPT) {
+ var tmpPathFolder = self.get_file().get_path();
+ Lib.TalkativeLog(`-^-file path get from widget : ${tmpPathFolder}`);
+ this._settings.setOption(
+ Settings.FILE_FOLDER_SETTING_KEY,
+ tmpPathFolder
+ );
+ refFilechooserFileFolder.set_label(`Selected: ${tmpPathFolder}`);
+ }
+ ctx.fileChooserDialog = null;
+ });
+ dialog.show();
+ ctx.fileChooserDialog = dialog; // keep a reference to the dialog alive
+ });
+ }
+
+ /**
+ * @param {EasyScreenCastSettingsWidget} ctx the prefs/settings widget
+ * @param {Gtk.Builder} gtkDB the builder that loaded the UI glade file
+ * @param {Gio.Settings} tmpS the current settings
+ * @private
+ */
+ _initTabSupport(ctx, gtkDB, tmpS) {
+ // implements textentry log
+ let refTextViewEscLog = gtkDB.get_object('txe_ContainerLog');
+ let refBufferLog = refTextViewEscLog.get_buffer();
+
+ // implements verbose debug option
+ let refSwitchVerboseDebug = gtkDB.get_object('swt_VerboseDebug');
+ tmpS.bind(
+ Settings.VERBOSE_DEBUG_SETTING_KEY,
+ refSwitchVerboseDebug,
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this._settings._settings.connect(
+ `changed::${Settings.VERBOSE_DEBUG_SETTING_KEY}`,
+ () => {
+ Lib.setDebugEnabled(this._settings.getOption('b', Settings.VERBOSE_DEBUG_SETTING_KEY));
+ }
+ );
+
+ refSwitchVerboseDebug.connect('state-set', self => {
+ // update log display widgets
+ refTextViewEscLog.sensistive = self.active;
+ refComboboxLogChooser.sensitive = self.active;
+ });
+
+ // implements file resolution preset spinner
+ let refComboboxLogChooser = gtkDB.get_object('cbt_LogChooser');
+
+ // intercept combobox res changed and update width/height value
+ refComboboxLogChooser.connect('changed', self => {
+ const activeLog = self.active;
+ Lib.TalkativeLog(`-^-log combobox changed: ${activeLog}`);
+ switch (activeLog) {
+ case 0:
+ // clear buffer
+ refBufferLog.delete(
+ refBufferLog.get_start_iter(),
+ refBufferLog.get_end_iter()
+ );
+
+ ctx.CtrlExe.Execute(
+ 'journalctl --since "15 min ago" --output=cat --no-pager',
+ false,
+ success => {
+ Lib.TalkativeLog(`-^-CALLBACK async S= ${success}`);
+ },
+ line => {
+ let esc = line.indexOf('[ESC]');
+ if (
+ line !== '' &&
+ line !== undefined &&
+ esc !== -1
+ ) {
+ line += '\n';
+ refBufferLog.insert(
+ refBufferLog.get_end_iter(),
+ line,
+ line.length
+ );
+ }
+ }
+ );
+ break;
+ case 1:
+ // clear buffer
+ refBufferLog.delete(
+ refBufferLog.get_start_iter(),
+ refBufferLog.get_end_iter()
+ );
+
+ ctx.CtrlExe.Execute(
+ 'journalctl --since "15 min ago" --output=cat --no-pager',
+ false,
+ success => {
+ Lib.TalkativeLog(`-^-CALLBACK async S= ${success}`);
+ if (success) {
+ if (refBufferLog.get_line_count() > 0) {
+ let strNOgsp = _(
+ 'No Gstreamer pipeline found'
+ );
+ refBufferLog.insert(
+ refBufferLog.get_end_iter(),
+ strNOgsp,
+ strNOgsp.length
+ );
+ }
+ }
+ },
+ line => {
+ let esc = line.indexOf('-§-final GSP :');
+ if (
+ line !== '' &&
+ line !== undefined &&
+ esc !== -1
+ ) {
+ line += '\n';
+ refBufferLog.insert(
+ refBufferLog.get_end_iter(),
+ line,
+ line.length
+ );
+ }
+ }
+ );
+ break;
+ case 2:
+ // clear buffer
+ refBufferLog.delete(
+ refBufferLog.get_start_iter(),
+ refBufferLog.get_end_iter()
+ );
+
+ ctx.CtrlExe.Execute(
+ 'journalctl /usr/bin/gnome-shell --since "15 min ago" --output=cat --no-pager',
+ false,
+ success => {
+ Lib.TalkativeLog(`-^-CALLBACK async S= ${success}`);
+ },
+ line => {
+ if (line !== '' && line !== undefined) {
+ line += '\n';
+ refBufferLog.insert(
+ refBufferLog.get_end_iter(),
+ line,
+ line.length
+ );
+ }
+ }
+ );
+ break;
+ default:
+ break;
+ }
+ });
+
+ // update state of get log
+ refComboboxLogChooser.sensistive = this._settings.getOption('b', Settings.VERBOSE_DEBUG_SETTING_KEY);
+
+ // implements default button action
+ let refButtonSetDefaultSettings = gtkDB.get_object('btn_DefaultOption');
+ refButtonSetDefaultSettings.connect('clicked', () =>
+ ctx._setDefaultsettings()
+ );
+ }
+
+ /**
+ * @param {EasyScreenCastSettingsWidget} ctx the prefs/settings widget
+ * @param {Gtk.Builder} gtkDB the builder that loaded the UI glade file
+ * @private
+ */
+ _initTabInfo(ctx, gtkDB) {
+ // implements info img extension
+ let refImageEsc = gtkDB.get_object('img_ESC');
+ refImageEsc.set_from_file(Lib.getImagePath(this._prefs.dir, 'Icon_Info.png'));
+
+ // implements info version label
+ let refLabelVersion = gtkDB.get_object('lbl_Version');
+ refLabelVersion.set_markup(`${_('Version: ')}${this._prefs.metadata.version} (${Lib.getFullVersion()})`);
+ }
+
+ /**
+ * @param {number} device device index
+ * @private
+ */
+ _updateWebCamCaps(device) {
+ Lib.TalkativeLog(`-^-webcam device index: ${device}`);
+
+ if (device > 0) {
+ this._initializeWebcamHelper();
+ var listCaps = this.CtrlWebcam.getListCapsDevice(device - 1);
+ Lib.TalkativeLog(`-^-webcam caps: ${listCaps.length}`);
+ if (listCaps !== null && listCaps !== undefined) {
+ this.Ref_ListStore_QualityWebCam.clear();
+ for (var index in listCaps) {
+ this.Ref_ListStore_QualityWebCam.set(
+ this.Ref_ListStore_QualityWebCam.append(),
+ [0],
+ [listCaps[index]]
+ );
+ }
+ } else {
+ Lib.TalkativeLog('-^-NO List Caps Webcam');
+ this.Ref_ListStore_QualityWebCam.clear();
+ this._settings.setOption(Settings.QUALITY_WEBCAM_SETTING_KEY, '');
+ }
+ } else {
+ Lib.TalkativeLog('-^-NO Webcam recording');
+ this.Ref_ListStore_QualityWebCam.clear();
+ this._settings.setOption(Settings.QUALITY_WEBCAM_SETTING_KEY, '');
+ }
+ }
+
+ /**
+ * Refreshes the webcam settings.
+ *
+ * @private
+ */
+ _refreshWebcamOptions() {
+ Lib.TalkativeLog('-^-refresh webcam options');
+ this._initializeWebcamHelper();
+
+ // fill combobox with quality option webcam
+ this._updateWebCamCaps(this._settings.getOption('i', Settings.DEVICE_INDEX_WEBCAM_SETTING_KEY));
+
+ // update webcam widget state
+ this._updateStateWebcamOptions();
+ }
+
+ /**
+ * Initializes this.CtrlWebcam if it is null.
+ *
+ * @private
+ */
+ _initializeWebcamHelper() {
+ if (this.CtrlWebcam === null)
+ this.CtrlWebcam = new UtilWebcam.HelperWebcam(_('Unspecified webcam'));
+ }
+
+ /**
+ * @param {string} accel accelerator string parsable by Gtk.accelerator_parse, e.g. "<Super>E"
+ * @private
+ */
+ _updateRowShortcut(accel) {
+ Lib.TalkativeLog(`-^-update row combo key accel: ${accel}`);
+
+ let [key, mods] = [0, 0];
+
+ if (accel !== null && accel !== undefined) {
+ let ok;
+ [ok, key, mods] = Gtk.accelerator_parse(accel);
+
+ if (ok !== true) {
+ Lib.TalkativeLog('-^-couldn\'t parse accel');
+ key = 0;
+ mods = 0;
+ }
+ }
+
+ Lib.TalkativeLog(`-^-key: ${key} mods: ${mods}`);
+ this.Ref_liststore_Shortcut.set(
+ this.Iter_ShortcutRow,
+ [Settings.SHORTCUT_COLUMN_KEY, Settings.SHORTCUT_COLUMN_MODS],
+ [key, mods]
+ );
+ }
+
+ /**
+ * @param {boolean} active custom or not custom GStream pipeline
+ * @private
+ */
+ _setStateGSP(active) {
+ // update GSP text area
+ if (!active) {
+ Lib.TalkativeLog('-^-custom GSP');
+
+ this.Ref_stack_Quality.set_visible_child_name('pg_Custom');
+ } else {
+ Lib.TalkativeLog('-^-NOT custom GSP');
+
+ this.Ref_stack_Quality.set_visible_child_name('pg_Preset');
+
+ var audio = false;
+ if (this._settings.getOption('i', Settings.INPUT_AUDIO_SOURCE_SETTING_KEY) > 0)
+ audio = true;
+
+ this._settings.setOption(
+ Settings.PIPELINE_REC_SETTING_KEY,
+ Settings.getGSPstd(audio)
+ );
+ }
+ }
+
+ /**
+ * @private
+ */
+ _updateStateWebcamOptions() {
+ Lib.TalkativeLog('-^-update webcam option widgets');
+
+ var tmpDev = this._settings.getOption(
+ 'i',
+ Settings.DEVICE_INDEX_WEBCAM_SETTING_KEY
+ );
+ this._updateWebCamCaps(tmpDev);
+ if (tmpDev > 0) {
+ var arrDev = this.CtrlWebcam.getNameDevices();
+ this.Ref_Label_WebCam.set_text(arrDev[tmpDev - 1]);
+
+ // setup label webcam caps
+ var tmpCaps = this._settings.getOption(
+ 's',
+ Settings.QUALITY_WEBCAM_SETTING_KEY
+ );
+ if (tmpCaps === '') {
+ this.Ref_Label_WebCamCaps.use_markup = true;
+ this.Ref_Label_WebCamCaps.set_markup(
+ _(
+ 'No Caps selected, please select one from the caps list'
+ )
+ );
+ } else {
+ this.Ref_Label_WebCamCaps.set_text(tmpCaps);
+ }
+
+ // webcam recording show widget
+ this.Ref_StackSwitcher_WebCam.set_sensitive(true);
+ this.Ref_StackObj_WebCam.set_sensitive(true);
+ } else {
+ this.Ref_Label_WebCam.set_text(_('No webcam device selected'));
+ // setup label webcam caps
+ this.Ref_Label_WebCamCaps.set_text(_('-'));
+ // webcam NOT recording hide widget
+ this.Ref_StackSwitcher_WebCam.set_sensitive(false);
+ this.Ref_StackObj_WebCam.set_sensitive(false);
+ }
+ }
+
+ /**
+ * @param {number} index index of the predefined resolutions
+ * @returns {Array}
+ * @private
+ */
+ _getResolutionPreset(index) {
+ var arrRes = [
+ [480, 640],
+ [480, 854],
+ [600, 800],
+ [720, 960],
+ [720, 1280],
+ [768, 1024],
+ [768, 1366],
+ [1024, 1280],
+ [1080, 1920],
+ [1200, 1600],
+ [1440, 2560],
+ [2048, 2560],
+ [2160, 3840],
+ ];
+ if (index >= 0 && index < arrRes.length)
+ return arrRes[index];
+ else
+ return null;
+ }
+
+ /**
+ * function to restore default value of the settings
+ *
+ * @private
+ */
+ _setDefaultsettings() {
+ Lib.TalkativeLog('-^-restore default option');
+
+ this._settings.setOption(Settings.SHOW_NOTIFY_ALERT_SETTING_KEY, true);
+ this._settings.setOption(Settings.SHOW_AREA_REC_SETTING_KEY, false);
+ this._settings.setOption(Settings.STATUS_INDICATORS_SETTING_KEY, 1);
+ this._settings.setOption(Settings.DRAW_CURSOR_SETTING_KEY, true);
+ this._settings.setOption(Settings.VERBOSE_DEBUG_SETTING_KEY, false);
+ this._settings.setOption(Settings.ACTIVE_CUSTOM_GSP_SETTING_KEY, false);
+
+ this._settings.setOption(Settings.FPS_SETTING_KEY, 30);
+ this._settings.setOption(Settings.X_POS_SETTING_KEY, 0);
+ this._settings.setOption(Settings.Y_POS_SETTING_KEY, 0);
+ this._settings.setOption(Settings.WIDTH_SETTING_KEY, 600);
+ this._settings.setOption(Settings.HEIGHT_SETTING_KEY, 400);
+
+ this._settings.setOption(Settings.FILE_NAME_SETTING_KEY, 'Screencast_%d_%t');
+ this._settings.setOption(Settings.FILE_FOLDER_SETTING_KEY, '');
+ this._settings.setOption(Settings.ACTIVE_POST_CMD_SETTING_KEY, false);
+ this._settings.setOption(Settings.ACTIVE_PRE_CMD_SETTING_KEY, false);
+ this._settings.setOption(Settings.POST_CMD_SETTING_KEY, 'xdg-open _fpath &');
+ this._settings.setOption(Settings.INPUT_AUDIO_SOURCE_SETTING_KEY, 0);
+ this._settings.setOption(Settings.DEVICE_INDEX_WEBCAM_SETTING_KEY, 0);
+ this._settings.setOption(Settings.DEVICE_WEBCAM_SETTING_KEY, '');
+
+ this._settings.setOption(Settings.TIME_DELAY_SETTING_KEY, 0);
+ this._settings.setOption(Settings.FILE_CONTAINER_SETTING_KEY, 0);
+ this._settings.setOption(Settings.FILE_RESOLUTION_TYPE_SETTING_KEY, -1);
+ this._settings.setOption(Settings.QUALITY_SETTING_KEY, 1);
+ this._settings.setOption(Settings.QUALITY_WEBCAM_SETTING_KEY, '');
+ this._settings.setOption(Settings.WIDTH_WEBCAM_SETTING_KEY, 20);
+ this._settings.setOption(Settings.HEIGHT_WEBCAM_SETTING_KEY, 10);
+ this._settings.setOption(Settings.TYPE_UNIT_WEBCAM_SETTING_KEY, 0);
+ this._settings.setOption(Settings.MARGIN_X_WEBCAM_SETTING_KEY, 0);
+ this._settings.setOption(Settings.MARGIN_Y_WEBCAM_SETTING_KEY, 0);
+ this._settings.setOption(Settings.ALPHA_CHANNEL_WEBCAM_SETTING_KEY, 0.75);
+ this._settings.setOption(Settings.CORNER_POSITION_WEBCAM_SETTING_KEY, 0);
+ }
+});
+
+
+export default class EasyScreenCastPreferences extends ExtensionPreferences {
+ /**
+ * @param {Adw.PreferencesWindow} window preferences window?
+ * @returns {EasyScreenCastSettingsWidget}
+ */
+ fillPreferencesWindow(window) {
+ window._settings = this.getSettings();
+
+ Lib.TalkativeLog('-^-Init pref widget');
+
+ const page = new Adw.PreferencesPage();
+
+ const group = new Adw.PreferencesGroup({
+ title: _('EasyScreenCast'),
+ });
+ page.add(group);
+
+ const widget = new EasyScreenCastSettingsWidget(this);
+ group.add(widget);
+
+ window.add(page);
+ }
+}
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/schemas/gschemas.compiled b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/schemas/gschemas.compiled
new file mode 100644
index 0000000..362d39e
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/schemas/gschemas.compiled differ
diff --git a/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/schemas/org.gnome.shell.extensions.easyscreencast.gschema.xml b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/schemas/org.gnome.shell.extensions.easyscreencast.gschema.xml
new file mode 100644
index 0000000..51bbf18
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/EasyScreenCast@iacopodeenosee.gmail.com/schemas/org.gnome.shell.extensions.easyscreencast.gschema.xml
@@ -0,0 +1,200 @@
+video/x-raw, format=(string)YUY2, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1
+ * This encodes a single capability (fixed), but there might also be capabilities which represent options, e.g.
+ * video/x-raw, format=(string)YUY2, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction) { 30/1, 25/1, 20/1 }.
+ *
+ * The code here will take always the first option and unroll the options for framerate.
+ *
+ * @param {Gst.Caps} tmpCaps capabilities of a device
+ * @returns {string[]}
+ */
+ getCapsForIV(tmpCaps) {
+ Lib.TalkativeLog('-@-get all caps from a input video');
+ Lib.TalkativeLog(`-@-caps available before filtering for video/x-raw: ${tmpCaps.get_size()}`);
+
+ let cleanCaps = [];
+ for (let i = 0; i < tmpCaps.get_size(); i++) {
+ let capsStructure = tmpCaps.get_structure(i);
+
+ // only consider "video/x-raw"
+ if (capsStructure.get_name() === 'video/x-raw') {
+ Lib.TalkativeLog(`-@-cap : ${i} : original : ${capsStructure.to_string()}`);
+
+ let tmpStr = 'video/x-raw';
+ let result, number, fraction;
+ result = capsStructure.get_string('format');
+ if (result !== null)
+ tmpStr += `, format=(string)${result}`;
+ [result, number] = capsStructure.get_int('width');
+ if (result === true)
+ tmpStr += `, width=(int)${number}`;
+ [result, number] = capsStructure.get_int('height');
+ if (result === true)
+ tmpStr += `, height=(int)${number}`;
+ [result, number, fraction] = capsStructure.get_fraction('pixel-aspect-ratio');
+ if (result === true)
+ tmpStr += `, pixel-aspect-ratio=(fraction)${number}/${fraction}`;
+
+
+ if (capsStructure.has_field('framerate')) {
+ [result, number, fraction] = capsStructure.get_fraction('framerate');
+ if (result === true) {
+ // a single framerate
+ this._addAndLogCapability(cleanCaps, i, `${tmpStr}, framerate=(fraction)${number}/${fraction}`);
+ } else {
+ // multiple framerates
+
+ // unfortunately GstValueList is not supported in this gjs-binding
+ // "Error: Don't know how to convert GType GstValueList to JavaScript object"
+ // -> capsStructure.get_value('framerate') <- won't work
+ // -> capsStructure.get_list('framerate') <- only returns the numerator of the fraction
+ //
+ // therefore manually parsing the framerate values from the string representation
+ let framerates = capsStructure.to_string();
+ framerates = framerates.substring(framerates.indexOf('framerate=(fraction){') + 21);
+ framerates = framerates.substring(0, framerates.indexOf('}'));
+ framerates.split(',').forEach(element => {
+ let [numerator, denominator] = element.split('/', 2);
+ this._addAndLogCapability(cleanCaps, i, `${tmpStr}, framerate=(fraction)${numerator.trim()}/${denominator.trim()}`);
+ });
+ }
+ } else {
+ // no framerate at all
+ this._addAndLogCapability(cleanCaps, i, tmpStr);
+ }
+ } else {
+ Lib.TalkativeLog(`-@-cap : ${i} : skipped : ${capsStructure.to_string()}`);
+ }
+ }
+ return cleanCaps;
+ }
+
+ /**
+ * Adds the capability str to the array caps, if it is not already there. Avoids duplicates.
+ *
+ * @param {Array} caps the list of capabilities
+ * @param {int} originalIndex index of the original capabilities list from the device
+ * @param {string} str the capability string to add
+ */
+ _addAndLogCapability(caps, originalIndex, str) {
+ if (caps.indexOf(str) === -1) {
+ caps.push(str);
+ Lib.TalkativeLog(`-@-cap : ${originalIndex} : added cap : ${str}`);
+ } else {
+ Lib.TalkativeLog(`-@-cap : ${originalIndex} : ignore duplicated cap : ${str}`);
+ }
+ }
+
+ /**
+ * get devices IV
+ *
+ * @returns {Gst.Device[]}
+ */
+ getDevicesIV() {
+ Lib.TalkativeLog('-@-get devices');
+
+ var list = this.deviceMonitor.get_devices();
+ Lib.TalkativeLog(`-@-devices number: ${list.length}`);
+
+ // Note:
+ // Although the computer may have just one webcam connected to
+ // it, more than one GstDevice may be listed and all pointing to
+ // the same video device (for example /dev/video0. Each
+ // GstDevice is supposed to be used with a specific source, for
+ // example, a pipewiresrc or a v4l2src. For now, we are only
+ // using v4l2src.
+ // See also: Gst.DeviceMonitor.get_providers: pipewiredeviceprovider,decklinkdeviceprovider,v4l2deviceprovider
+ //
+ // So, here we filter the devices, that have a device.path property, which
+ // means, these are only v4l2 devices
+ var filtered = list.filter(device => device.get_properties().get_string('device.path') !== null);
+ Lib.TalkativeLog(`-@-devices number after filtering for v4l2: ${filtered.length}`);
+
+ return filtered;
+ }
+
+ /**
+ * get array name devices IV
+ *
+ * @returns {Array}
+ */
+ getNameDevices() {
+ Lib.TalkativeLog('-@-get name devices');
+ let tmpArray = [];
+
+ for (var index in this._listDevices) {
+ var wcName = this._unspecified_webcam_text;
+
+ if (this._listDevices[index].display_name !== '')
+ wcName = this._listDevices[index].display_name;
+
+ tmpArray.push(wcName);
+ }
+
+ Lib.TalkativeLog(`-@-list devices name: ${tmpArray}`);
+ return tmpArray;
+ }
+
+ /**
+ * get array caps
+ *
+ * @param {int} index device
+ * @returns {string[]}
+ */
+ getListCapsDevice(index) {
+ const tmpArray = this._listCaps[index];
+ Lib.TalkativeLog(`-@-list caps of device: ${tmpArray}`);
+ return tmpArray;
+ }
+
+ /**
+ * start listening
+ */
+ startMonitor() {
+ Lib.TalkativeLog('-@-start video devicemonitor');
+ this.deviceMonitor.start();
+ }
+
+ /**
+ * Stop listening
+ */
+ stopMonitor() {
+ Lib.TalkativeLog('-@-stop video devicemonitor');
+ this.disconnectSourceBus();
+ this.deviceMonitor.stop();
+ }
+
+ /**
+ * disconect bus
+ */
+ disconnectSourceBus() {
+ if (this.dmBusId) {
+ this.dmBus.disconnect(this.dmBusId);
+ this.dmBusId = 0;
+ }
+ }
+});
+
+export {HelperWebcam};
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/extension.js b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/extension.js
index ee5d735..d7f0daf 100644
--- a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/extension.js
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/extension.js
@@ -40,15 +40,23 @@ var VitalsMenuButton = GObject.registerClass({
'icon-rx': 'network-download-symbolic.svg',
'icon-tx': 'network-upload-symbolic.svg' },
'storage' : { 'icon': 'storage-symbolic.svg' },
- 'battery' : { 'icon': 'battery-symbolic.svg' }
+ 'battery' : { 'icon': 'battery-symbolic.svg' },
+ 'gpu' : { 'icon': 'gpu-symbolic.svg' }
}
+ // list with the prefixes for the according themes, the index of each
+ // item must match the index on the combo box
+ this._sensorsIconPathPrefix = ['/icons/original/', '/icons/gnome/'];
+
this._warnings = [];
this._sensorMenuItems = {};
this._hotLabels = {};
this._hotIcons = {};
this._groups = {};
this._widths = {};
+ this._numGpus = 1;
+ this._newGpuDetected = false;
+ this._newGpuDetectedCount = 0;
this._last_query = new Date().getTime();
this._sensors = new Sensors.Sensors(this._settings, this._sensorIcons);
@@ -64,15 +72,16 @@ var VitalsMenuButton = GObject.registerClass({
});
this._drawMenu();
- this.add_actor(this._menuLayout);
+ this.add_child(this._menuLayout);
this._settingChangedSignals = [];
this._refreshTimeoutId = null;
this._addSettingChangedSignal('update-time', this._updateTimeChanged.bind(this));
this._addSettingChangedSignal('position-in-panel', this._positionInPanelChanged.bind(this));
this._addSettingChangedSignal('menu-centered', this._positionInPanelChanged.bind(this));
+ this._addSettingChangedSignal('icon-style', this._iconStyleChanged.bind(this));
- let settings = [ 'use-higher-precision', 'alphabetize', 'hide-zeros', 'fixed-widths', 'hide-icons', 'unit', 'memory-measurement', 'include-public-ip', 'network-speed-format', 'storage-measurement', 'include-static-info' ];
+ let settings = [ 'use-higher-precision', 'alphabetize', 'hide-zeros', 'fixed-widths', 'hide-icons', 'unit', 'memory-measurement', 'include-public-ip', 'network-speed-format', 'storage-measurement', 'include-static-info', 'include-static-gpu-info' ];
for (let setting of Object.values(settings))
this._addSettingChangedSignal(setting, this._redrawMenu.bind(this));
@@ -95,21 +104,14 @@ var VitalsMenuButton = GObject.registerClass({
// groups associated sensors under accordion menu
if (sensor in this._groups) continue;
- this._groups[sensor] = new PopupMenu.PopupSubMenuMenuItem(_(this._ucFirst(sensor)), true);
- this._groups[sensor].icon.gicon = Gio.icon_new_for_string(this._extensionObject.path + '/icons/' + this._sensorIcons[sensor]['icon']);
+ //handle gpus separately.
+ if (sensor === 'gpu') continue;
- // hide menu items that user has requested to not include
- if (!this._settings.get_boolean('show-' + sensor))
- this._groups[sensor].actor.hide();
-
- if (!this._groups[sensor].status) {
- this._groups[sensor].status = this._defaultLabel();
- this._groups[sensor].actor.insert_child_at_index(this._groups[sensor].status, 4);
- this._groups[sensor].status.text = _('No Data');
- }
-
- this.menu.addMenuItem(this._groups[sensor]);
+ this._initializeMenuGroup(sensor, sensor);
}
+
+ for (let i = 1; i <= this._numGpus; i++)
+ this._initializeMenuGroup('gpu#' + i, 'gpu', (this._numGpus > 1 ? ' ' + i : ''));
// add separator
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@@ -135,7 +137,7 @@ var VitalsMenuButton = GObject.registerClass({
refreshButton.connect('clicked', (self) => {
// force refresh by clearing history
this._sensors.resetHistory();
- this._values.resetHistory();
+ this._values.resetHistory(this._numGpus);
// make sure timer fires at next full interval
this._updateTimeChanged();
@@ -143,7 +145,7 @@ var VitalsMenuButton = GObject.registerClass({
// refresh sensors now
this._querySensors();
});
- customButtonBox.add_actor(refreshButton);
+ customButtonBox.add_child(refreshButton);
// custom round monitor button
let monitorButton = this._createRoundButton('org.gnome.SystemMonitor-symbolic', _('System Monitor'));
@@ -151,7 +153,7 @@ var VitalsMenuButton = GObject.registerClass({
this.menu._getTopMenu().close();
Util.spawn(this._settings.get_string('monitor-cmd').split(" "));
});
- customButtonBox.add_actor(monitorButton);
+ customButtonBox.add_child(monitorButton);
// custom round preferences button
let prefsButton = this._createRoundButton('preferences-system-symbolic', _('Preferences'));
@@ -159,10 +161,10 @@ var VitalsMenuButton = GObject.registerClass({
this.menu._getTopMenu().close();
this._extensionObject.openPreferences();
});
- customButtonBox.add_actor(prefsButton);
+ customButtonBox.add_child(prefsButton);
// now add the buttons to the top bar
- item.actor.add_actor(customButtonBox);
+ item.actor.add_child(customButtonBox);
// add buttons
this.menu.addMenuItem(item);
@@ -179,6 +181,24 @@ var VitalsMenuButton = GObject.registerClass({
});
}
+ _initializeMenuGroup(groupName, optionName, menuSuffix = '', position = -1) {
+ this._groups[groupName] = new PopupMenu.PopupSubMenuMenuItem(_(this._ucFirst(groupName) + menuSuffix), true);
+ this._groups[groupName].icon.gicon = Gio.icon_new_for_string(this._sensorIconPath(groupName));
+
+ // hide menu items that user has requested to not include
+ if (!this._settings.get_boolean('show-' + optionName))
+ this._groups[groupName].actor.hide();
+
+ if (!this._groups[groupName].status) {
+ this._groups[groupName].status = this._defaultLabel();
+ this._groups[groupName].actor.insert_child_at_index(this._groups[groupName].status, 4);
+ this._groups[groupName].status.text = _('No Data');
+ }
+
+ if(position == -1) this.menu.addMenuItem(this._groups[groupName]);
+ else this.menu.addMenuItem(this._groups[groupName], position);
+ }
+
_createRoundButton(iconName) {
let button = new St.Button({
style_class: 'message-list-clear-button button vitals-button-action'
@@ -239,7 +259,7 @@ var VitalsMenuButton = GObject.registerClass({
_createHotItem(key, value) {
let icon = this._defaultIcon(key);
this._hotIcons[key] = icon;
- this._menuLayout.add_actor(icon)
+ this._menuLayout.add_child(icon)
// don't add a label when no sensors are in the panel
if (key == '_default_icon_') return;
@@ -248,7 +268,7 @@ var VitalsMenuButton = GObject.registerClass({
style_class: 'vitals-panel-label',
text: (value)?value:'\u2026', // ...
y_expand: true,
- y_align: Clutter.ActorAlign.START
+ y_align: Clutter.ActorAlign.CENTER
});
// attempt to prevent ellipsizes
@@ -258,7 +278,7 @@ var VitalsMenuButton = GObject.registerClass({
this._hotLabels[key] = label;
// prevent "called on the widget" "which is not in the stage" errors by adding before width below
- this._menuLayout.add_actor(label);
+ this._menuLayout.add_child(label);
// support for fixed widths #55, save label (text) width
this._widths[key] = label.width;
@@ -266,11 +286,17 @@ var VitalsMenuButton = GObject.registerClass({
_showHideSensorsChanged(self, sensor) {
this._sensors.resetHistory();
- this._groups[sensor.substr(5)].visible = this._settings.get_boolean(sensor);
+
+ const sensorName = sensor.substr(5);
+ if(sensorName === 'gpu') {
+ for(let i = 1; i <= this._numGpus; i++)
+ this._groups[sensorName + '#' + i].visible = this._settings.get_boolean(sensor);
+ } else
+ this._groups[sensorName].visible = this._settings.get_boolean(sensor);
}
_positionInPanelChanged() {
- this.container.get_parent().remove_actor(this.container);
+ this.container.get_parent().remove_child(this.container);
let position = this._positionInPanel();
// allows easily addressable boxes
@@ -284,6 +310,27 @@ var VitalsMenuButton = GObject.registerClass({
boxes[position[0]].insert_child_at_index(this.container, position[1]);
}
+ _redrawDetailsMenuIcons() {
+ // updates the icons on the 'details' menu, the one
+ // you have to click to appear
+ this._sensors.resetHistory();
+ for (const sensor in this._sensorIcons) {
+ if (sensor == "gpu") continue;
+ this._groups[sensor].icon.gicon = Gio.icon_new_for_string(this._sensorIconPath(sensor));
+ }
+
+ // gpu's are indexed differently, handle them here
+ const gpuKeys = Object.keys(this._groups).filter(key => key.startsWith("gpu#"));
+ gpuKeys.forEach((gpuKey) => {
+ this._groups[gpuKey].icon.gicon = Gio.icon_new_for_string(this._sensorIconPath("gpu"));
+ });
+ }
+
+ _iconStyleChanged() {
+ this._redrawDetailsMenuIcons();
+ this._redrawMenu();
+ }
+
_removeHotLabel(key) {
if (key in this._hotLabels) {
let label = this._hotLabels[key];
@@ -322,7 +369,7 @@ var VitalsMenuButton = GObject.registerClass({
this._drawMenu();
this._sensors.resetHistory();
- this._values.resetHistory();
+ this._values.resetHistory(this._numGpus);
this._querySensors();
}
@@ -370,7 +417,8 @@ var VitalsMenuButton = GObject.registerClass({
}
}
}
-
+ if(key === "_gpu#1_domain_number_")
+ console.error('UPDATING: ', key);
// have we added this sensor before?
let item = this._sensorMenuItems[key];
if (item) {
@@ -394,7 +442,7 @@ var VitalsMenuButton = GObject.registerClass({
let split = sensor.type.split('-');
let type = split[0];
let icon = (split.length == 2)?'icon-' + split[1]:'icon';
- let gicon = Gio.icon_new_for_string(this._extensionObject.path + '/icons/' + this._sensorIcons[type][icon]);
+ let gicon = Gio.icon_new_for_string(this._sensorIconPath(type, icon));
let item = new MenuItem.MenuItem(gicon, key, sensor.label, sensor.value, this._hotLabels[key]);
item.connect('toggle', (self) => {
@@ -460,17 +508,28 @@ var VitalsMenuButton = GObject.registerClass({
});
// second condition prevents crash due to issue #225, which started when _max_ was moved to the end
- if (type == 'default' || !(type in this._sensorIcons)) {
- icon.gicon = Gio.icon_new_for_string(this._extensionObject.path + '/icons/' + this._sensorIcons['system']['icon']);
+ // don't use the default system icon if the type is a gpu; use the universal gpu icon instead
+ if (type == 'default' || (!(type in this._sensorIcons) && !type.startsWith('gpu'))) {
+ icon.gicon = Gio.icon_new_for_string(this._sensorIconPath('system'));
} else if (!this._settings.get_boolean('hide-icons')) { // support for hide icons #80
let iconObj = (split.length == 2)?'icon-' + split[1]:'icon';
- icon.gicon = Gio.icon_new_for_string(this._extensionObject.path + '/icons/' + this._sensorIcons[type][iconObj]);
+ icon.gicon = Gio.icon_new_for_string(this._sensorIconPath(type, iconObj));
}
return icon;
}
+ _sensorIconPath(sensor, icon = 'icon') {
+ // If the sensor is a numbered gpu, use the gpu icon. Otherwise use whatever icon associated with the sensor name.
+ let sensorKey = sensor;
+ if(sensor.startsWith('gpu')) sensorKey = 'gpu';
+
+ const iconPathPrefixIndex = this._settings.get_int('icon-style');
+ return this._extensionObject.path + this._sensorsIconPathPrefix[iconPathPrefixIndex] + this._sensorIcons[sensorKey][icon];
+ }
+
_ucFirst(string) {
+ if(string.startsWith('gpu')) return 'Graphics';
return string.charAt(0).toUpperCase() + string.slice(1);
}
@@ -524,7 +583,8 @@ var VitalsMenuButton = GObject.registerClass({
this._last_query = now;
this._sensors.query((label, value, type, format) => {
- let key = '_' + type.replace('-group', '') + '_' + label.replace(' ', '_').toLowerCase() + '_';
+ const typeKey = type.replace('-group', '');
+ let key = '_' + typeKey + '_' + label.replace(' ', '_').toLowerCase() + '_';
// if a sensor is disabled, gray it out
if (key in this._sensorMenuItems) {
@@ -534,11 +594,39 @@ var VitalsMenuButton = GObject.registerClass({
if (value == 'disabled') return;
}
+ // add/initialize any gpu groups that we haven't added yet
+ if(typeKey.startsWith('gpu') && typeKey !== 'gpu#1') {
+ const split = typeKey.split('#');
+ if(split.length == 2 && this._numGpus < parseInt(split[1])) {
+ // occasionally two lines from nvidia-smi will be read at once
+ // so we only actually update the number of gpus if we have recieved multiple lines at least 3 times in a row
+ // i.e. we make sure that mutiple queries have detected a new gpu back-to-back
+ if(this._newGpuDetectedCount < 2) {
+ this._newGpuDetected = true;
+ return;
+ }
+
+ this._numGpus = parseInt(split[1]);
+ this._newGpuDetectedCount = 0;
+ this._newGpuDetected = false;
+ // change label for gpu 1 from "Graphics" to "Graphics 1" since we have multiple gpus now
+ this._groups['gpu#1'].label.text = this._ucFirst('gpu#1') + ' 1';
+ for(let i = 2; i <= this._numGpus; i++)
+ if(!('gpu#' + i in this._groups))
+ this._initializeMenuGroup('gpu#' + i, 'gpu', ' ' + i, Object.keys(this._groups).length);
+ }
+ }
+
let items = this._values.returnIfDifferent(dwell, label, value, type, format, key);
for (let item of Object.values(items))
this._updateDisplay(_(item[0]), item[1], item[2], item[3]);
}, dwell);
+ //if a new gpu has been detected during the last query, then increment the amount of times we've detected a new gpu
+ if(this._newGpuDetected) this._newGpuDetectedCount++;
+ else this._newGpuDetectedCount = 0;
+ this._newGpuDetected = false;
+
if (this._warnings.length > 0) {
this._notify('Vitals', this._warnings.join("\n"), 'folder-symbolic');
this._warnings = [];
@@ -555,6 +643,7 @@ var VitalsMenuButton = GObject.registerClass({
destroy() {
this._destroyTimer();
+ this._sensors.destroy();
for (let signal of Object.values(this._settingChangedSignals))
this._settings.disconnect(signal);
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/helpers/subprocess.js b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/helpers/subprocess.js
new file mode 100644
index 0000000..df0bf49
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/helpers/subprocess.js
@@ -0,0 +1,54 @@
+import GLib from 'gi://GLib';
+import Gio from 'gi://Gio';
+
+// convert Uint8Array into a literal string
+function convertUint8ArrayToString(contents) {
+ const decoder = new TextDecoder('utf-8');
+ return decoder.decode(contents).trim();
+}
+
+export function SubProcess(command) {
+ this.sub_process = Gio.Subprocess.new(command, Gio.SubprocessFlags.STDOUT_PIPE);
+ this.stdout = this.sub_process.get_stdout_pipe();
+}
+
+SubProcess.prototype.read = function(delimiter = '') {
+ return new Promise((resolve, reject) => {
+ this.stdout.read_bytes_async(512, GLib.PRIORITY_LOW, null, function(stdout, res) {
+ try {
+ let read_bytes = stdout.read_bytes_finish(res).get_data();
+
+ // convert contents to string
+ let read_str = convertUint8ArrayToString(read_bytes);
+
+ // split read_str by delimiter if passed in
+ if (delimiter) {
+ if (read_str == '')
+ read_str = []; // EOF, ''.split(delimiter) would return ['']
+ else
+ read_str = read_str.split(delimiter);
+ }
+
+ // return results
+ resolve(read_str);
+ } catch (e) {
+ if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.PENDING)) {
+ // previous read attempt is still waiting for something from stdout
+ // ignore second attempt, return empty data (like EOF)
+ if (delimiter) resolve([]);
+ else resolve('');
+ } else {
+ reject(e.message);
+ }
+ }
+ });
+ });
+};
+
+SubProcess.prototype.terminate = function() {
+ const SIGINT = 2;
+ this.sub_process.send_signal(SIGINT);
+ this.sub_process = null;
+ this.stdout.close_async(GLib.PRIORITY_LOW, null, null);
+ this.stdout = null;
+};
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/battery-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/battery-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/battery-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/battery-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/cpu-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/cpu-symbolic.svg
new file mode 100644
index 0000000..86ca8bf
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/cpu-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/fan-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/fan-symbolic.svg
new file mode 100644
index 0000000..ea2b44f
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/fan-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/gpu-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/gpu-symbolic.svg
new file mode 100644
index 0000000..d5cf157
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/gpu-symbolic.svg
@@ -0,0 +1,15 @@
+
+
+
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/memory-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/memory-symbolic.svg
new file mode 100644
index 0000000..1946901
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/memory-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/network-download-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/network-download-symbolic.svg
new file mode 100644
index 0000000..4fc170b
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/network-download-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/network-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/network-symbolic.svg
new file mode 100644
index 0000000..2ff9778
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/network-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/network-upload-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/network-upload-symbolic.svg
new file mode 100644
index 0000000..0d67f65
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/network-upload-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/storage-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/storage-symbolic.svg
new file mode 100644
index 0000000..30d9007
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/storage-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/system-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/system-symbolic.svg
new file mode 100644
index 0000000..bfbf1bd
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/system-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/temperature-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/temperature-symbolic.svg
new file mode 100644
index 0000000..e00a2eb
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/temperature-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/voltage-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/voltage-symbolic.svg
new file mode 100644
index 0000000..1aa2210
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/gnome/voltage-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/battery-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/battery-symbolic.svg
new file mode 100644
index 0000000..70df9ee
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/battery-symbolic.svg
@@ -0,0 +1,8 @@
+
+
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/cpu-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/cpu-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/cpu-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/cpu-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/fan-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/fan-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/fan-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/fan-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/gpu-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/gpu-symbolic.svg
new file mode 100644
index 0000000..d5cf157
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/gpu-symbolic.svg
@@ -0,0 +1,15 @@
+
+
+
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/memory-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/memory-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/memory-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/memory-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/network-download-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/network-download-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/network-download-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/network-download-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/network-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/network-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/network-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/network-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/network-upload-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/network-upload-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/network-upload-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/network-upload-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/storage-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/storage-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/storage-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/storage-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/system-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/system-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/system-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/system-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/temperature-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/temperature-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/temperature-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/temperature-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/voltage-symbolic.svg b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/voltage-symbolic.svg
similarity index 100%
rename from gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/voltage-symbolic.svg
rename to gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/icons/original/voltage-symbolic.svg
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/be/LC_MESSAGES/vitals.mo b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/be/LC_MESSAGES/vitals.mo
new file mode 100644
index 0000000..1001254
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/be/LC_MESSAGES/vitals.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/de/LC_MESSAGES/vitals.mo b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/de/LC_MESSAGES/vitals.mo
index fdc9849..f374b84 100644
Binary files a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/de/LC_MESSAGES/vitals.mo and b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/de/LC_MESSAGES/vitals.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/pt_BR/LC_MESSAGES/vitals.mo b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/pt_BR/LC_MESSAGES/vitals.mo
index ddcca6d..986cf6d 100644
Binary files a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/pt_BR/LC_MESSAGES/vitals.mo and b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/locale/pt_BR/LC_MESSAGES/vitals.mo differ
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/menuItem.js b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/menuItem.js
index 47a60fb..cf112ab 100644
--- a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/menuItem.js
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/menuItem.js
@@ -21,18 +21,18 @@ export const MenuItem = GObject.registerClass({
this._gIcon = icon;
// add icon
- this.add(new St.Icon({ style_class: 'popup-menu-icon', gicon : this._gIcon }));
+ this.add_child(new St.Icon({ style_class: 'popup-menu-icon', gicon : this._gIcon }));
// add label
this._labelActor = new St.Label({ text: label });
- this.add(this._labelActor);
+ this.add_child(this._labelActor);
// add value
this._valueLabel = new St.Label({ text: value });
this._valueLabel.set_x_align(Clutter.ActorAlign.END);
this._valueLabel.set_x_expand(true);
this._valueLabel.set_y_expand(true);
- this.add(this._valueLabel);
+ this.add_child(this._valueLabel);
this.actor._delegate = this;
}
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/metadata.json b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/metadata.json
index 400c547..4c78f3a 100644
--- a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/metadata.json
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/metadata.json
@@ -1,13 +1,17 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "A glimpse into your computer's temperature, voltage, fan speed, memory usage, processor load, system resources, network speed and storage stats. This is a one stop shop to monitor all of your vital sensors. Uses asynchronous polling to provide a smooth user experience. Feature requests or bugs? Please use GitHub.",
+ "donations": {
+ "paypal": "corecoding"
+ },
"gettext-domain": "vitals",
"name": "Vitals",
"settings-schema": "org.gnome.shell.extensions.vitals",
"shell-version": [
- "45"
+ "45",
+ "46"
],
"url": "https://github.com/corecoding/Vitals",
"uuid": "Vitals@CoreCoding.com",
- "version": 63
+ "version": 66
}
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/prefs.js b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/prefs.js
index 8cace02..07916bd 100644
--- a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/prefs.js
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/prefs.js
@@ -48,7 +48,8 @@ const Settings = new GObject.Class({
'show-network', 'show-storage', 'use-higher-precision',
'alphabetize', 'hide-zeros', 'include-public-ip',
'show-battery', 'fixed-widths', 'hide-icons',
- 'menu-centered', 'include-static-info' ];
+ 'menu-centered', 'include-static-info',
+ 'show-gpu', 'include-static-gpu-info' ];
for (let key in sensors) {
let sensor = sensors[key];
@@ -61,7 +62,7 @@ const Settings = new GObject.Class({
}
// process individual drop down sensor preferences
- sensors = [ 'position-in-panel', 'unit', 'network-speed-format', 'memory-measurement', 'storage-measurement', 'battery-slot' ];
+ sensors = [ 'position-in-panel', 'unit', 'network-speed-format', 'memory-measurement', 'storage-measurement', 'battery-slot', 'icon-style' ];
for (let key in sensors) {
let sensor = sensors[key];
@@ -90,7 +91,7 @@ const Settings = new GObject.Class({
}
// makes individual sensor preference boxes appear
- sensors = [ 'temperature', 'network', 'storage', 'memory', 'battery', 'system', 'processor' ];
+ sensors = [ 'temperature', 'network', 'storage', 'memory', 'battery', 'system', 'processor', 'gpu' ];
for (let key in sensors) {
let sensor = sensors[key];
diff --git a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/prefs.ui b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/prefs.ui
index 76d1473..ab07185 100644
--- a/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/prefs.ui
+++ b/gnome/.local/share/gnome-shell/extensions/Vitals@CoreCoding.com/prefs.ui
@@ -45,6 +45,7 @@