From 1bd891f30aa15452a1e10f27d0e295623c047273 Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Fri, 1 Nov 2024 09:35:38 -0400 Subject: [PATCH] [gnome] Fix version for gjsosk and gsconnect, add impatience --- .../gjsosk@vishram1123.com/metadata.json | 6 +- .../gsconnect@andyholmes.github.io/config.js | 32 +- .../gsconnect@andyholmes.github.io/config.mjs | 12 - .../extension.js | 6 +- .../gsconnect-preferences | 61 +-- .../org.gnome.Shell.Extensions.GSConnect.mo | Bin 20859 -> 20573 bytes .../org.gnome.Shell.Extensions.GSConnect.mo | Bin 23921 -> 23676 bytes .../org.gnome.Shell.Extensions.GSConnect.mo | Bin 16896 -> 17085 bytes .../org.gnome.Shell.Extensions.GSConnect.mo | Bin 18231 -> 18476 bytes .../org.gnome.Shell.Extensions.GSConnect.mo | Bin 16871 -> 18071 bytes .../org.gnome.Shell.Extensions.GSConnect.mo | Bin 15574 -> 17871 bytes .../metadata.json | 18 +- ...gnome.Shell.Extensions.GSConnect.gresource | Bin 60052 -> 60268 bytes .../preferences/device.js | 31 +- .../preferences/keybindings.js | 20 +- .../preferences/service.js | 32 +- .../gsconnect@andyholmes.github.io/prefs.js | 2 +- .../service/backends/lan.js | 34 +- .../service/components/__init__.js | 71 --- .../service/components/atspi.js | 12 +- .../service/components/clipboard.js | 25 +- .../service/components/contacts.js | 32 +- .../service/components/input.js | 23 +- .../service/components/mpris.js | 14 +- .../service/components/notification.js | 14 +- .../service/components/pulseaudio.js | 53 ++- .../service/components/session.js | 8 +- .../service/components/sound.js | 44 +- .../service/components/upower.js | 12 +- .../service/components/ydotool.js | 15 +- .../service/core.js | 30 +- .../service/daemon.js | 55 +-- .../service/device.js | 29 +- .../service/init.js | 17 +- .../service/manager.js | 63 ++- .../service/nativeMessagingHost.js | 30 +- .../service/plugin.js | 17 +- .../service/plugins/battery.js | 20 +- .../service/plugins/clipboard.js | 16 +- .../service/plugins/connectivity_report.js | 19 +- .../service/plugins/contacts.js | 27 +- .../service/plugins/findmyphone.js | 22 +- .../service/plugins/mousepad.js | 20 +- .../service/plugins/mpris.js | 45 +- .../service/plugins/notification.js | 28 +- .../service/plugins/ping.js | 18 +- .../service/plugins/presenter.js | 16 +- .../service/plugins/runcommand.js | 18 +- .../service/plugins/sftp.js | 23 +- .../service/plugins/share.js | 32 +- .../service/plugins/sms.js | 34 +- .../service/plugins/systemvolume.js | 18 +- .../service/plugins/telephony.js | 22 +- .../service/ui/contacts.js | 22 +- .../service/ui/legacyMessaging.js | 19 +- .../service/ui/messaging.js | 34 +- .../service/ui/mousepad.js | 18 +- .../service/ui/notification.js | 15 +- .../service/ui/service.js | 18 +- .../service/utils/dbus.js | 20 +- .../service/utils/setup.js | 427 ------------------ .../service/utils/ui.js | 12 +- .../service/utils/uri.js | 12 +- .../shell/input.js | 2 +- .../shell/notification.js | 9 +- .../shell/tooltip.js | 8 +- .../shell/utils.js | 2 +- .../utils/remote.js | 13 +- .../utils/remote.mjs | 12 - .../utils/setup.js | 12 +- .../utils/setup.mjs | 12 - .../wl_clipboard.js | 20 +- .../impatience@gfxmonk.net/extension.js | 52 +++ .../impatience@gfxmonk.net/metadata.json | 14 + .../impatience@gfxmonk.net/prefs.js | 61 +++ .../schemas/gschemas.compiled | Bin 0 -> 332 bytes ...ensions.net.gfxmonk.impatience.gschema.xml | 10 + .../impatience@gfxmonk.net/settings.js | 10 + 78 files changed, 804 insertions(+), 1226 deletions(-) delete mode 100644 gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/config.mjs mode change 100644 => 100755 gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/gsconnect-preferences delete mode 100644 gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/__init__.js mode change 100644 => 100755 gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/daemon.js mode change 100644 => 100755 gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/nativeMessagingHost.js delete mode 100644 gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/setup.js delete mode 100644 gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/remote.mjs delete mode 100644 gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/setup.mjs create mode 100644 gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/extension.js create mode 100644 gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/metadata.json create mode 100644 gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/prefs.js create mode 100644 gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/schemas/gschemas.compiled create mode 100644 gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/schemas/org.gnome.shell.extensions.net.gfxmonk.impatience.gschema.xml create mode 100644 gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/settings.js diff --git a/gnome/.local/share/gnome-shell/extensions/gjsosk@vishram1123.com/metadata.json b/gnome/.local/share/gnome-shell/extensions/gjsosk@vishram1123.com/metadata.json index 5a9dc1b..5ca4bef 100644 --- a/gnome/.local/share/gnome-shell/extensions/gjsosk@vishram1123.com/metadata.json +++ b/gnome/.local/share/gnome-shell/extensions/gjsosk@vishram1123.com/metadata.json @@ -5,9 +5,11 @@ "name": "GJS OSK", "settings-schema": "org.gnome.shell.extensions.gjsosk", "shell-version": [ - "45" + "45", + "46", + "47" ], "url": "https://github.com/Vishram1123/gjs-osk", "uuid": "gjsosk@vishram1123.com", "version": 10 -} \ No newline at end of file +} diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/config.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/config.js index 6a88a81..ae3aa53 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/config.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/config.js @@ -2,21 +2,23 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -var PACKAGE_VERSION = 56; -var PACKAGE_URL = 'https://github.com/GSConnect/gnome-shell-extension-gsconnect'; -var PACKAGE_BUGREPORT = 'https://github.com/GSConnect/gnome-shell-extension-gsconnect/issues/new'; -var PACKAGE_DATADIR = '/usr/share/gnome-shell/extensions/gsconnect@andyholmes.github.io'; -var PACKAGE_LOCALEDIR = '/usr/share/locale'; -var GSETTINGS_SCHEMA_DIR = '/usr/share/glib-2.0/schemas'; -var GNOME_SHELL_LIBDIR = '/usr/lib64/'; +export default { + PACKAGE_VERSION: 58, + PACKAGE_URL: 'https://github.com/GSConnect/gnome-shell-extension-gsconnect', + PACKAGE_BUGREPORT: 'https://github.com/GSConnect/gnome-shell-extension-gsconnect/issues/new', + PACKAGE_DATADIR: '/usr/local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io', + PACKAGE_LOCALEDIR: '/usr/local/share/locale', + GSETTINGS_SCHEMA_DIR: '/usr/local/share/glib-2.0/schemas', + GNOME_SHELL_LIBDIR: '/usr/local/lib64', -var APP_ID = 'org.gnome.Shell.Extensions.GSConnect'; -var APP_PATH = '/org/gnome/Shell/Extensions/GSConnect'; + APP_ID: 'org.gnome.Shell.Extensions.GSConnect', + APP_PATH: '/org/gnome/Shell/Extensions/GSConnect', -var IS_USER = false; + IS_USER: false, -// External binary paths -var OPENSSL_PATH = 'openssl'; -var SSHADD_PATH = 'ssh-add'; -var SSHKEYGEN_PATH = 'ssh-keygen'; -var FFMPEG_PATH = 'ffmpeg'; + // External binary paths + OPENSSL_PATH: 'openssl', + SSHADD_PATH: 'ssh-add', + SSHKEYGEN_PATH: 'ssh-keygen', + FFMPEG_PATH: 'ffmpeg', +}; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/config.mjs b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/config.mjs deleted file mode 100644 index 7295c97..0000000 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/config.mjs +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: GSConnect Developers https://github.com/GSConnect -// -// SPDX-License-Identifier: GPL-2.0-or-later - -import GLib from 'gi://GLib'; - -const [filename] = GLib.filename_from_uri(import.meta.url); -const dirname = GLib.path_get_dirname(filename); -imports.searchPath.unshift(dirname); - -const Config = imports.config; -export default Config; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/extension.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/extension.js index 53ecd5f..9d960ac 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/extension.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/extension.js @@ -16,15 +16,15 @@ import { ngettext } from 'resource:///org/gnome/shell/extensions/extension.js'; -import Config from './config.mjs'; +import Config from './config.js'; import * as Clipboard from './shell/clipboard.js'; import * as Device from './shell/device.js'; import * as Keybindings from './shell/keybindings.js'; import * as Notification from './shell/notification.js'; import * as Input from './shell/input.js'; import * as Utils from './shell/utils.js'; -import Remote from './utils/remote.mjs'; -import setup from './utils/setup.mjs'; +import * as Remote from './utils/remote.js'; +import setup from './utils/setup.js'; const QuickSettingsMenu = Main.panel.statusArea.quickSettings; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/gsconnect-preferences b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/gsconnect-preferences old mode 100644 new mode 100755 index f9dad23..b16ddc7 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/gsconnect-preferences +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/gsconnect-preferences @@ -1,4 +1,4 @@ -#!/usr/bin/env gjs +#!/usr/bin/env -S gjs -m // SPDX-FileCopyrightText: GSConnect Developers https://github.com/GSConnect // @@ -6,43 +6,20 @@ // -*- mode: js; -*- -'use strict'; +import Gdk from 'gi://Gdk?version=3.0'; +import 'gi://GdkPixbuf?version=2.0'; +import Gio from 'gi://Gio?version=2.0'; +import GLib from 'gi://GLib?version=2.0'; +import GObject from 'gi://GObject?version=2.0'; +import Gtk from 'gi://Gtk?version=3.0'; -imports.gi.versions.Gdk = '3.0'; -imports.gi.versions.GdkPixbuf = '2.0'; -imports.gi.versions.Gio = '2.0'; -imports.gi.versions.GLib = '2.0'; -imports.gi.versions.GObject = '2.0'; -imports.gi.versions.Gtk = '3.0'; +import system from 'system'; -const Gdk = imports.gi.Gdk; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; +import './preferences/init.js'; +import {Window} from './preferences/service.js'; +import Config from './config.js'; - -// Bootstrap -function get_datadir() { - let [, path] = /@([^:]+):\d+/.exec(new Error().stack.split('\n')[1]); - const info = Gio.File.new_for_path(path) - .query_info('standard::*', Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null); - path = info.get_is_symlink() ? info.get_symlink_target() : path; - - return Gio.File.new_for_path(path).get_parent().get_path(); -} - -imports.searchPath.unshift(get_datadir()); -imports.config.PACKAGE_DATADIR = imports.searchPath[0]; - -// Bootstrap -const {setup, setupGettext} = imports.utils.setup; -setup(imports.config.PACKAGE_DATADIR); -setupGettext(); - -// Local Imports -const Config = imports.config; -const Settings = imports.preferences.service; +import('gi://GioUnix?version=2.0').catch(() => {}); // Set version for optional dependency /** @@ -65,7 +42,7 @@ const Preferences = GObject.registerClass({ vfunc_activate() { if (this._window === undefined) { - this._window = new Settings.Window({ + this._window = new Window({ application: this, }); } @@ -77,7 +54,7 @@ const Preferences = GObject.registerClass({ super.vfunc_startup(); // Init some resources - let provider = new Gtk.CssProvider(); + const provider = new Gtk.CssProvider(); provider.load_from_resource(`${Config.APP_PATH}/application.css`); Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), @@ -85,13 +62,13 @@ const Preferences = GObject.registerClass({ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION ); - let actions = [ + const actions = [ ['refresh', null], ['connect', GLib.VariantType.new('s')], ]; - for (let [name, type] of actions) { - let action = new Gio.SimpleAction({ + for (const [name, type] of actions) { + const action = new Gio.SimpleAction({ name: name, parameter_type: type, }); @@ -101,7 +78,7 @@ const Preferences = GObject.registerClass({ vfunc_activate_action(action_name, parameter) { try { - let paramArray = []; + const paramArray = []; if (parameter instanceof GLib.Variant) paramArray[0] = parameter; @@ -124,4 +101,4 @@ const Preferences = GObject.registerClass({ } }); -(new Preferences()).run([imports.system.programInvocationName].concat(ARGV)); +await (new Preferences()).runAsync([system.programInvocationName].concat(ARGV)); diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/locale/ar/LC_MESSAGES/org.gnome.Shell.Extensions.GSConnect.mo b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/locale/ar/LC_MESSAGES/org.gnome.Shell.Extensions.GSConnect.mo index 78e91a6f75e90c3a857590fd6cec7fb914828be9..e286cbe589be5b26f6a87d40ceaf86ad35e6e947 100644 GIT binary patch delta 5786 zcmY+|30Rd?9>?(mvJ-BA=0aQ*6;T!uWK0uqLBUMZQFAFRvP>@bh&Z%s zG=pe}&Q)s4OtVaS&8grm3T8i<-^%$9w2`=6#+YpL5QA@B5zff0t`rdo|$b zngH*yra`5KEik~C*4QP?n6b2bHP)yx>tc;*ft478yRaoX*b0BJ?p&6E96uyKy&<5>*TTv_CZash#>7PM; zZzyNi3GYH3_(4=acCTxK3+VNee((XZBnnS3GUO-jyN7M@{B*8sSd(`oh zP?gO>uS%6qL)UPa{a_O2(w~j0$Trm7dI)u|oI|bPh8+)Y@0QquIzfi*=VAl;BQO|8 zqrNxZI=Mad*R^?q0hMeq>I5Zrhu2UutwzpecB0-Br?3|Wc3?G_jT)bfD)9o;@m8QN zNg3*%*?^kB4phZH>OlRq!V?T=g*Q+ojqT`uu^p=P-BIKHF$9O({utB*C!tO_8+C#r zJN_(op}*FCUW+yK9n>Xy)|=>-?iJL5e5ezCfXu}lK&|W=hGO$h?ib@x{Z!P1vM>yL zqbfB3!*MEVD12`3y6MYmtxExifji?E~fjZ%C)Pzo= z7Wfk;VssDcA5NoJ5BILl!zJ`bqX$pmc?`bQ7@FoX>Vzph-O>-j#`FtOmu@=7;7ZiJ zQ-RHKFKPl`+wmVz3ybw~hp03;$c<@6qVD1as2NsT_oGUA4f|pUcT_7ZKwY{Aum#RW zt$Y=#Qst=qHld#Xk5R|{9Ccprb^Afn-tJ6WU>qNGMV)Yn9Up_b1dm~BTx0w1pjLVo zb>OIMcOu&;@L)=l=!`Jr<2}-4gZ1Liz=$YqSwHAwQ~Q z7pZSfV)_YXJ4vH58r2qMxCTbJmVW400=#gxYT)>co>U0%xK2 zFY?mhJEk0UP0nL_0ROVN-CbekV0Xtss29j&)P8f2SAi);O>m$6{1UdOA9ROX(InIa zyP>{67HL_j%i>L6vkr>VT(FrH&fHb;nfH%-_IBd=E!ptsPGoYVUs3<6MBO zqwc@^{((Ko2BIy155kd~c$oQ&Mx{pC#*jwjH}XBvru$<)(GB-^vX9hnAJN!JSajW{ zmEI`X858Zj&yJ`Tyy5D8pgnk$XbW;NTd|*Qx5f9!HS#uDM}o--vYKeQm&q?go0j<{ z8BNki{pQna?H=1(hLplk&bsXxtNwq>&N>LvXu(M8j?inJuJkOO3a>QwS+Opy03db-3>q<+)AqRnxs`qFU*lqHR1GMxG=6$qVE>IZSvS ze%}_;DzUw%aky<)<3#cn>1)R};Tt61_Saj(@Tt1Cm){&3TgW-WE93vRhV+gTJ^t^K zhsg}0EuM5D{BxpiyJAhjEYimIJ7S`3*KuWOIj=Y3Z z$YyfVj(uwt^GG!LMjf^?@+f(S{752+w$6lyS3iOLYns%MKM}o{dXsy}b&^T+EdLn_ z$Rd(XCXqZ+Og<+wiM9%oN}eFQ$SG1zUMCYs717p}EYf}uZIFw3 z5T7J3+x{V(O_q}n$OY1aj3raaRif>0reIPL+S2^QPg0ivIU!R5%-*_0DFGf4)=2m#du(PNl~w z_b>9$TSvd#<6lIxie{y8%AL)Q&(}RKBQVU_!tiGQGrk!EcZ4*q;GkRmMeO0u*Ef1d H+ra+;6Hu`z delta 6016 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 B6T|=j diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/locale/el/LC_MESSAGES/org.gnome.Shell.Extensions.GSConnect.mo b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/locale/el/LC_MESSAGES/org.gnome.Shell.Extensions.GSConnect.mo index 4a067cac612298ed905a2e8fcf46791422674b3c..aa446e31be29eec479b56c84576f3e430191ad32 100644 GIT binary patch delta 5883 zcmYk=3w+M?0>|;+uC}?vZiw+<#5TLIA!Hk7XDYNsE=O6jY&M&0A*IKy#Yu5`Qo2kj zC#2GPkhEG4yc&;S2fS$8uZlIM1@(Arg=yFh zv#<+JK%IXNCgMtrGRAG{DMZq+A5-uoUWHL@jS0nW7>^04K8;51X{KOvoQ?F^EW)n% zplyEz)uA2O3_rjdu@TjQIC>Y${Y@T)ZZu3m-FOM=#*ZRBG*96*xEVEq!>AFS#ZLGe zYDTVRn!+&y^?jywlyx#{pyjBJxiO6Uo8=VL!&TT4Yf%^4q#xi`)QI1<9>ikmXHe&j z;qJQOc+`cbp=PGqy1=>|HNe%#B%2NBR*xDe=t7^MPW%jYt(1Vnv0sjWtf30F%x&AIuOc6>xr=)nSX7%Og{L|{1tWKxu_f7k6P2!7>93S z5FW)4JdT>NlcbyME?+Z}v?jj00p#*iqyKVge z)DKsqrgj6WqgznF+lSgS$55N|B(}j{QRg-1p;x^F>i4~^gHQv?LptC#<0zjuP&Y`o^=u5HJ{Ci8 z0_wcmtkb(Q|5}^7XwZ}`L*2k*f3ObK)6K}e%udvM;xrD%z#fbSGg0l+QBz!ly57U6 zC0UKyGn-Hycn39OANOGXHNvlH&QH|S z!y%}d%EfRjM~!?o>UR&KuKx&X!0xpa#!%Rf!5Geb>Ibb*J&!}(XrwhCHKh}AM1V0f zFoXJ*M5m)?kSEK8a&ijxL>G=n&Gg-Zk*~~j zY=_TZ%lg++sHfotoH)?=GaN98mjv|;)N{THv+xtt1*2%x1rv}#nlY#g*PwQJ18Qb= zqxQf7)GPfWcEDEG@sh%X>zMy=3b)aqsV&8GxYYh&4hx>iRKA3F(tb9RKdE?YmUE#e zQF~zbXb={~OV^~$=!frSTd0>nidF8lG9R+QMW2li_ zLM=t~2xn^hVjT6M$f}qrsK;v!cEt}-BRPv&ip$s?gL9n$B%sdEz+fyu{eC>Q=KiLT zf_gLyHAU-i8NPwK(6GNaGf;}!JPU2T7BwSVt-Dc6cNhyXD9`!6*g6}pq5T2WeKun& z?r+|spb;NHt?>oaZVutC5r#vM{bzDfOH+g2;Re)*9=YDWa4?AaF4PTnV^2JWJuvtN zr$dRT`e1bH!bKD`ba&!V2+{mAT^?@=?6KE`=bjl-$b zS0Z1T%jm(JoA_@EJc^9L^vicP>ta*~pU7wa6DYh!Loyymb*M#wvn1_tIQ0QI7UyGM zJb>Da&2Dz~NDit)Wf+PNp?3SDsF~c3k@$u6BI-J!Zmz1H55$i644w(#jfmRa>u+%` z{1NKuIE$&+V!U(SbvTjwbJz-hM?JSIyur%)HXgq7HWd1oB{|L%JM2a!!gM*v@h<7@iE z`A-TP)yly={Qp|?C!SRUhdOmXd4&9f>?2Lb#}sxF_MiV~&*vYWozYS5+ii;;U@cS< zagpOhN3et0idtYDn(tlYH}WRgKtjmZr=bw zITAs1JW8%6&ya(pM)Ty^A06yw%a{j9OVV_-v4tZ|4VX=a5-oEhd582SO~;S6&>D-# zDl(n06U=t9gftz$Q}~eFr@4x=t+!!5d4lASr^q?-8M%Qp9m^om2gqEaV?9YB zcae9=Y4SXIiA*6c6CG*fLEXQeLOeN2bnGU3$uU(pu6Hog@E)?p)(_!4@(_8SoF~_k zNu-?ohv;~md_mqIe-65K z{FCNNO&^%nFEO>RCns@VaC&l|2v2HKdv8k8{$Our+Q0yBO`ow5@oO9J_igvp`!+W& z_HFgO(YVOv+uFFm_p)zC;}TyTjjuN@@*W+$CTP$)UxO?6e?8ut#18RA`)yD-puc;w>9?iGbq ll~u`Qg|iBaN(#$MDOXh&PAe;{%9=T=vbwS&c}DRN^Izn=)q(&3 delta 6056 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 diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/locale/ko/LC_MESSAGES/org.gnome.Shell.Extensions.GSConnect.mo b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/locale/ko/LC_MESSAGES/org.gnome.Shell.Extensions.GSConnect.mo index 16bb28ebca6643354acf99015bee95a2e92cbf72..973a851eccf5cec4f5bc606405bde9478c9c2aaa 100644 GIT binary patch delta 5887 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 O)Ya7yflsgL+3deZspwY# delta 5725 zcmZA5cYIdW9mnw#5)(`qAqbHXxF|tZG%>^gVaX6np$t)h7BNBskr76uiozp^KxG=1 zQX)lUOA#N2VTe^!z^Vli6kCkJC?$^sWJ*!{`9AlT{?YsLoA){Ajx+8^aNqM0&(4ep zoJxpV>ez0OhBC&v{t?dov!+^|^XfQP51ZgEn1%JRA2z_z);=4nQD2EQa3kJ|Z($QW zg0=A?CSXim=k9VY;ObLQU%fCIhhS68#(12Coa2^b9B#p?Sd6#fyVhQY8o&i)4(=E1 zgVBl3-HroM{XB{4XHM9Fa|8c-qXI%_e!f*4*w4CsRIQqX~)qUxm>g%wu6gt`?GEQ6LV0W+{3cE-M_ju&Ec zT!ng;4x*lsGSqb=sOXl}z$8p-!2OS;(3ggr@B!2k4MvT0q}3-O*KpHOOSclWBI__8 zcOZ-9lIgVsJE3l6V|vl`+Mp)X)$EC})O#nf{<_e^c3>`QX$nve;Z)Shyo#Fn4y*4) zt;naSr7l4Y;3{e&@jN)PE@}V`Q7h2W>Y1pC^axPUh5MqG@FCQRxu_1tpawJ*HG^5G z6X&9iUux}ZQO9pWb-2gshfv3zM6Kvq)IhJGjtkUm>^~eysE05aYhf1Z#6DIZiaH_R zoQj&!T-3l`LJh14b>4c^%I-p4?*r7tzCay+3b{oAciMJbLyhnktH*l&f$^vnsDpZn z8=+p;W~c$Q$1d0tb@#s1@ynI&Tna=|@}p zlw{UlOFYLK7NSO2gz9iBs)J%{KY*>NAGiIH&A89htD|nw0n`c{LtW<#s>AEZf9~cx z{E4NaCe}MZK_?Ehh7lM|eGKYePC_Qfl4vjE`eK`~jn|Q*(cR zH`KrfUkZq^|97lCrj(TmcBa7mqTlv2O zS|hjFJ%}DYg(iCW^r<~LZK`Zd&m zqwn-PNHiOn$*6(1Ht#`xO}H+YsQ3R73TZeQ)!_!z1$Ur2_`p17mZAo9-s(|zIoE=E z0^W@sP&3U(U2ihhz~@ls6{04x4g>079|fK85vqO^b3^tN;85xvuraPcO<*^wgM+9QIEy+znkQESsf{|WKBi*xa69*ZupRKI9WWBL0#8`` zEYyc(J|^OEYd?p&;APanBis4kj~G<@U8qlRN34TgQ7bVBHK4~ZUhjV%1zmWG?I=WD z;AQl1J?g}Rs3ks%8sK+Uzl!?O#kKdJp=Q{RdPh|I0@S_Uh;?xf*2JTz-#@ODfmC=Q?)?eWy(>jMwH2rfMRoMs8=?l@0@ZPUOv1-dEA*_jFR}Vss~4kI@-S*5$2zk9 zx{E1P{hr zsgFV(H$7m5Le$9DU<&R+9Z-h)c3(ja@TPnH4y$1j_4+sf+oJZ*Ma{4fGjSzqLdQ@8 zK7sYI3?ne`7k+4a*~fLm8{~6RLJpD2t&~DKd5iS7#wW2aIcasl^BDevvo*dz;z;Gj zg1D)b6}|rzROS%f=dXxnuWg%;dmLwyzZ3p&bw@}aQn`I$h54x0@DuWlwY`IXCJAH` z8BQv7+WL`sM1KuM zksP9J8ks`ARE6zdWDEU=@9#()Le7!~o+JMzOUWss=jA%l z{hvkj#_S;Pk$h6Q>AC4bR+7Mee(3AAk32)3Cod9xDC!YyjmU4vYH}ypK-!Z*L|Yr5 z@ZWoNC=ayyA8;92L*BQxhwzVNwqFmptG455tYzg)+)YN2gVt6X@3Zn&e8tNDL63Y$ zs*$hB14P>x5(=02A6j^voVNNooT&TXgo0iXZQuEX|E5>*QSulWOk#<)vE-w0iGL?x zRdSweC*z4;#|*NFRBo*(T(HVGY-{CPb^q@mf3k*}_#;vK333m4jr1TNlgh2S6<)%H z0C}BUA=)mJXGsisn`nEAyi4YiT%v85k1Jf9Ql~VS zRd;Sg{Mej{*{)mmxZyct!UV4-7DNW8HAtuuJdjjgC2CZDL4I(H*FB=^geP()6?g@s za=h``c@uL+cq4Kq=MB&C3i7>z?9n-1wl`h}d)ebgcm)%)$4$!3nds$l2Kz_lP4fD6 z3!ZE8a7^{|l+=ur)HE+GqkWsy;D8p{Rf0dZS|5>AyuEzmlJcUxF0^YyXx2OzS~{ib;lMC;9{i3U&ui(+H?H+NIe2v=Y;d<50ddR>5xHQuS${orxqR@Qxe3+qJXD9bqxQ50 zJK;;1fJd+a9z(6z3Dm&9w)G#8v6?2_q?PP}TA^$#!(3$7%*IZv|3?(|abf_jV?(va z$50KQLCw%~aczLfRFhE+rl79thFY;4)WbRqHG!F^l?d5-6>5c+p|;@BC-$=Vp(d1v3?OQzP|(Px zqi*z}mNtTFU=eC&51>Z;Flvid+w)sc1Kei6--nv{e$)UDp%zmMl)-Is)FFBSC+ zb;d;cHyIT8Q8HPm3&-INSfC4VJ!(as!vx%E&%caX+I^_4IfNSMSE!Xdhx&nP*v)OH zJF5NOsFfXpQ7u&-1?^$J{h|m*QLjR+$Trl|dIB8GgbE&F~UxNmF{dH+DrW{b1DjvDgp`Y<(JPfJLYd zt56**vghx`OzNxc_Xltb^~0zwx;NU(UAo6m4b`GL+=Gn897N6R0ye_78Saf;Q1yPO z0S&>%I0Cg&<1q;XsF_!wuDc7>{(YzkM^{srL}4o?ViN1A3!0-w-U-#w)z*B}l1{_? zcw69C1KWYRaW85B@1h29619|PP%C#4^*fT9!yABEsP;Ca?t9I895wJW7*$7& z2e=PId(;=%s1c4sJ$xS202ZK@aw)3g8tW6Nj-J7ZxEs}OOZG)ul#Z%rptgD_YGP9d zvi?IT%;LlZT!nfnPvRAL347v@LGBXHz!uaOV;g(`)!=&M*Vep-ddg2*zeQbl0X6WJ zJgK_B3-a8WeuG(m&14!UE<-QgiWR7azsE1I9i!BM68X?pU4@#_bks}&*Z?D_t(lLl zaWS^SRj8HNfEl4_jR6K6Dw#A1E^pv#|)(@JduiYfue8joPB^s1A>y zCUP1zv7ay%lZLu=2el%-F$JT!_KV4=24>g`La04of?Bfsu^q0l_3hY!`hHtKg&N3r z*c96ga|fD^`a$Z6dYdL-GxQ?^h?=<+)X_53NLQjp_#A4<_MrA|zdio}wx|9zYG6(H zL!cE&L(MoH)36U}YsRA{Hp%KmE&V)9*89Jlf@by*Y9O0%A?`vg@u;iZ8C{PWpa)|O zpq6?$YM@V`I(i!W;11LPKDT~@y6+;YzcwQnu-^Z^6x7iWR6|#zF3d;Ga1QF}u0lO@ zkKh7)7WI>znd>fXf7GAbiKvyxM-AvERD0#9XJ`p(@2fGYy;(;=9Unk-a0qqdNz{s5 zKnEL*bXTAk-bg(cwG}m}cAiIV-Fv8xzC?Y0-g+7TsL+J^pspJ>iuKn>CviefLk+-- zT9F89$(L9kLyde3YU$sw=Z|AH^|RO=dyF<_3Qj=%bU%rm@om(E{(~Ce#nDlBrj35( zc9e!1Sq|!<8;@OZ3U$16ctuSC z>a|#go#S{IQ4PE}*4?|eQ1w%&6}p5>!n7FY{xasHR8jg2w=!|NhC#u8YSb_Q20AEGT@J+k|kD@wi{cCq=J7NO$UdTLR|G)1q z$lGex6CH7Up}{_{_y27Q>vWc58quhJB3}|68ujhuKJsU>pVS|(Q`k+ewI}qjU9#n$ zGs{-GBX3{qA2tpi)BCR@(Zy^=Rz7xI&gb9B1@aPEOSA%?kO#vWV0lKT>#={DE|`Cud+jSxLr{hxDZUo5E2tfz%&MDOB6a ztyo~o8_`EzB)o&M<2gQGAbD=pJZ)`^3vBrV+(b?jp5UJy?38{HPLLjCCn+I%H*|C% z8AR`djve%wiXuTeJz1)NT&3ELVBm7bNc18fgNR=1xo|aELUKqE z8Aq0rcgZ}W<0;aQM99nJGx8*PhRh@zh>rf`F0zeuBS(miSI8UWeeJ)FYhs`LH!hq{ z9<}vDSVfkRJ>)BLC7DhF#7%|wC(#jr5z-NB#?K=%|yo;a-RHyG$LiS zyHn1_*KTh&AgT6T`sldY1zis$M$00FMdcoER`QsjXSP#T>V%8@A;%N+d7N;WQ&Lvp z<0BICIfap6s4SS3JSpf4g`7ZH>1?`@7lan(vXK-z__lgF!Y1vJh)@BcXH?Gz*!rQPqZfHt0 zD|vL#6DjtGeNMSA=uVHrIAp%C*rMJ`AfI@0=^Qa7YWhi{~F1r6@MfvnP$p^o>15mazf>i zP*_*Y@t07Y#SI~Uq_l3C-$T86!-)2yvXZZ1fht4(P^MGi_eO&LQn%vuF@adwDXE+t djud|<5vJe_;h%I=rB(@+4p-62}%GlddqV3bXkfxG&Nvt(5gHlE@LOX*N zt8N+2xG=mPOq(2V~*B0rV$>)dUzEZ<6UfmQPEC&Cyb(r^nqVQ2$mYGE=~!T#6^2cyQ6i}Y=Z@Bw@o8MApETj1Na z{RC=2z-P22c|{fPPlpoTQ);eSx~sJ=BFRHdq6zfx2Nd>b#ct2&UNfA`GMc zlC7^mZPhx|N^ZlhxEp)pH>d$5#IXKtD5Ub_>EX-dAAU3QP#vyAb+{F^w+FB(UcpdQ zB^<&~D^?vf@P@YD3Ym*ZLapRb)C!HkT+D3B`m>GZ91WN7CMM%4HdK2Y*4(*qBh(Dz ztsSsB^+ePSd!Ys}1hryMpdQ+Zs0l1Yt;A|u-+)@7oqh`1f-=-VDo``JZM~1WvCHkO zNG()71~sF0s2g`dEoo2G^+Qk{j6@A+B5DHJsO$1j=lf?-&<~4I7c4_{u-?|+L7jL2 zwX`Qu1HFJc?+4T~6T(ZbhqF4?K{x8UBwO!?I{#7YL}ZKoCXa#!Fb6fVxu^@5pq6$m z>V|KlX0{J?{$bP>9kuNjQ3Jec>o-y7-A1jzPpE;0@*wGTegGr&{x_%4hlUQQ8%{xu zbT0CSndPX5Xbb8FWvC@Tj(SMXqP`!OZF@Ks4Kxz9_jOSdYmK_D6Q*Gb2H*eL6m;Vk zQ4iH})X3K$A1kvS)zN!62FvX4Oez!?*~zF6)(rHA zQFw)dI#`QZ>dmMn+l$)MQrljReW~9-txU((&cizh_3S)_nn0dypN(4T6{!1fvh@IJ zz(-oM{^1lpp+Og(wpO4n{1UZv_fZ{$$2sRkqXrs_jKw6Qz8hn)7ZzYU+-}<|P%C^F zbw7Q_wKdh_*?;YMQyMgYB-E0nqGtFw>h;V+E$Kqkg{x2x=UcXYH&&ruX6v7#23U^j z@CNGscWk?>4bL0(C_e?A&f48cm;78?8ijbQt+4nseA0 z@1Q0S&q*3k3U^3+s)}|NoXT@aO_C>aR9mdhWIYB{RuG^>&jf>ti!x+?s zy-<5L4r^mBYJf$k>lUE~vI;eT&8QXKiCV$^sPD*mT!6Pw_nV%?{_Dae6y$o;$akVT z`WW?0T(Irmp#~U{?CfPr)Bt*;mUIZJ<8jsuR7W{D4CkTldj_>tSCd(PHC(4bd;T+O zW=+_@ZrBQchv}$+Y{u?*5aaP4#$jw%=Pek7^{9_U-ERu=RW?gdTU27*g*tCvSJq!6 zKSM(;yo@}+=3CTEVtAD6U>wfH?x-8@#p_s(8qi0KR$KKeYC=tE)I>UBICevAO)5s= zAgqh&ehONOTx^TeQG2z)`aWt8Poo~b>&PE66Y-$)^tVIZcs#13Ow^5^L%nW(REKL& z6DdJW>_d#!@1NL)E2t&8f%VbV!#S}5>ISi>-@Bsrd@yRo9><25Y3qJ$OnsTHZ$S-Y z4@TlS)IhHyA11%~ih^cVv#0YKwnq)%K~zV>Q6n9X8h{VAVhd4Qx6HP`hK;BPPy;)T z>gXbB##gZkeuLVYYW$&y()(YRf=-AFHn6OyEl5KxZ8~a(lTZUH!XjLPTIw39&dl7X zfhJ(^deoAqqXwLVTFGhH9v5ST-v3=H-~rTyM^PPKLJjO5PQcKIoDMyx8y29>e;zgC zm8hqEBkCbMf^+aZ>QnxBZ)c^)qyGHPK)*V8o`OcU0CmIFsG09TZN)xhugqttj_;y6 zFnyfs>Y!GpHM%howGyLnEM}p$<`C*W6{xLr^=19lQ8fQmp%Y@QJyA1y40WOxHPBhs z`KSRbMQy=4REImP$4~>mgxZ2TwmqVs^VT%S*0hi4=Vw_cOrt^H^yAnJ@1thaxWBU! zai|qaM0GR(HL!HlLpT+iV-dE*^{6c@#m0CMHITd3>S@k>WBe2}(s*mC{b98ANmR#K z$eU^Ap#E6xMqO8i+Oi9_{yl1CstquPIhe+%FXRN&3eHCjd@1Ug^S?nsGun!JKM!MP zJcZf<*TYT+bx;?yMcp6?HGqLQ4JTkYo<(hGId;cusOy>ybXGJTL#ZdDOYeUlDsK_q zCi4!_5y~$b?YrbG*-CVbC&5AS`+tKi&Y%}iE+%i1Q?^~4Af;rODja&o)a(Bb_Fu;{ z4#B13Z3#XLv3SY0hgsi47AAPKTdN$^nr zyU0^c)x3lw$#7erZ`J=jQ$YDP=}SJb?ax}p>*O0UirgT4=*%0W@_3CxS2C8YC8tT- zR{XPq#E^|dd#7U+(UZG@{DUkk-d;PZ_+ag@@F%FfSnR6X!2b%R%EL{eKheW@h8!jx zN#*gqE$HFQATN__q7U0%@&c(mex>j!(c(0>l6@qN=m?NKWUwk6e{%>vu)nwEf8lO&lRRSE92j0rN?(w8a){)R=|o3! z(vIl0)$yZ4@c-n}o6*A7+hAK;uEa}W4*A$N`~feJ$H*Yt7F?d6sQjB0+QxPG9N9_! zW81#Ain%0;TvLUkADK!HlDkA7Jslm$h+v8TErIV7A8AH2A=*=&17fklL^E_ETZ-zU=J1y%Oue%`E zUEs;~x;^eZo$U7HWVj1_o}Bzlug{&u75qLqE8jh$e;}ge>9D}^Ht``fk`p?2Pe@8} zCnfht>>Ma+{wxipCGN5f{F9wK XB`>S6!0Rh538XyatrFNXz!&lxx44GZ diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/locale/pt_BR/LC_MESSAGES/org.gnome.Shell.Extensions.GSConnect.mo b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/locale/pt_BR/LC_MESSAGES/org.gnome.Shell.Extensions.GSConnect.mo index bc26e36159f6964c53a2f9fe6bb6c0e37159ec67..86e64f22ef7129e5dcf65a0562ee6a50abbee458 100644 GIT binary patch delta 6875 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 ay^x|8QU_^ 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 diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/metadata.json b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/metadata.json index a2b73c2..16a0772 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/metadata.json +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/metadata.json @@ -1,8 +1,12 @@ { - "uuid": "gsconnect@andyholmes.github.io", - "name": "GSConnect", - "description": "GSConnect is a complete implementation of KDE Connect especially for GNOME Shell with Nautilus, Chrome and Firefox integration. It does not rely on the KDE Connect desktop application and will not work with it installed.\n\nKDE Connect allows devices to securely share content like notifications or files and other features like SMS messaging and remote control. The KDE Connect team has applications for Linux, BSD, Android, Sailfish, iOS, macOS and Windows.\n\nPlease report issues on Github!", - "version": 56, - "shell-version": [ "46" ], - "url": "https://github.com/GSConnect/gnome-shell-extension-gsconnect/wiki" -} + "_generated": "Generated by SweetTooth, do not edit", + "description": "GSConnect is a complete implementation of KDE Connect especially for GNOME Shell with Nautilus, Chrome and Firefox integration. It does not rely on the KDE Connect desktop application and will not work with it installed.\n\nKDE Connect allows devices to securely share content like notifications or files and other features like SMS messaging and remote control. The KDE Connect team has applications for Linux, BSD, Android, Sailfish, iOS, macOS and Windows.\n\nPlease report issues on Github!", + "name": "GSConnect", + "shell-version": [ + "46", + "47" + ], + "url": "https://github.com/GSConnect/gnome-shell-extension-gsconnect/wiki", + "uuid": "gsconnect@andyholmes.github.io", + "version": 58 +} \ No newline at end of file diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/org.gnome.Shell.Extensions.GSConnect.gresource b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/org.gnome.Shell.Extensions.GSConnect.gresource index 17fe48519fa929d45ffb39d22bd253d9a46333ad..f4f8a05f4a81a027e355ecb10339e01649cac502 100644 GIT binary patch delta 27712 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 delta 27497 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 OX=7zBX>PM{*8CJc{1rd| diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/device.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/device.js index d518353..76fc0c7 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/device.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/device.js @@ -2,24 +2,23 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import Pango from 'gi://Pango'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Pango = imports.gi.Pango; - -const Config = imports.config; -const Keybindings = imports.preferences.keybindings; +import Config from '../config.js'; +import plugins from '../service/plugins/index.js'; +import * as Keybindings from './keybindings.js'; // Build a list of plugins and shortcuts for devices const DEVICE_PLUGINS = []; const DEVICE_SHORTCUTS = {}; -for (const name in imports.service.plugins) { - const module = imports.service.plugins[name]; +for (const name in plugins) { + const module = plugins[name]; if (module.Metadata === undefined) continue; @@ -41,7 +40,7 @@ for (const name in imports.service.plugins) { * @param {Gtk.ListBoxRow} row - The current row * @param {Gtk.ListBoxRow} before - The previous row */ -function rowSeparators(row, before) { +export function rowSeparators(row, before) { const header = row.get_header(); if (before === null) { @@ -63,7 +62,7 @@ function rowSeparators(row, before) { * @param {Gtk.ListBoxRow} row2 - The second row * @return {number} -1, 0 or 1 */ -function titleSortFunc(row1, row2) { +export function titleSortFunc(row1, row2) { if (!row1.title || !row2.title) return 0; @@ -249,7 +248,7 @@ const CommandEditor = GObject.registerClass({ /** * A widget for configuring a remote device. */ -var Panel = GObject.registerClass({ +export const Panel = GObject.registerClass({ GTypeName: 'GSConnectPreferencesDevicePanel', Properties: { 'device': GObject.ParamSpec.object( @@ -424,7 +423,7 @@ var Panel = GObject.registerClass({ this._pluginSettings = {}; if (!this._pluginSettings.hasOwnProperty(name)) { - const meta = imports.service.plugins[name].Metadata; + const meta = plugins[name].Metadata; this._pluginSettings[name] = new Gio.Settings({ settings_schema: Config.GSCHEMA.lookup(meta.id, -1), @@ -1058,7 +1057,7 @@ var Panel = GObject.registerClass({ } _addPlugin(name) { - const plugin = imports.service.plugins[name]; + const plugin = plugins[name]; const row = new SectionRow({ height_request: 48, diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/keybindings.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/keybindings.js index b93c936..be80dfe 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/keybindings.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/keybindings.js @@ -2,13 +2,11 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const Gdk = imports.gi.Gdk; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; +import Gdk from 'gi://Gdk'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; /* @@ -32,7 +30,7 @@ const _MODIFIERS = [ /** * Response enum for ShortcutChooserDialog */ -var ResponseType = { +export const ResponseType = { CANCEL: Gtk.ResponseType.CANCEL, SET: Gtk.ResponseType.APPLY, UNSET: 2, @@ -42,7 +40,7 @@ var ResponseType = { /** * A simplified version of the shortcut editor from GNOME Control Center */ -var ShortcutChooserDialog = GObject.registerClass({ +export const ShortcutChooserDialog = GObject.registerClass({ GTypeName: 'GSConnectPreferencesShortcutEditor', Template: 'resource:///org/gnome/Shell/Extensions/GSConnect/ui/preferences-shortcut-editor.ui', Children: [ @@ -209,7 +207,7 @@ var ShortcutChooserDialog = GObject.registerClass({ * @param {number} [grabFlags] - Grab Flags * @param {boolean} %true if available, %false on error or unavailable */ -async function checkAccelerator(accelerator, modeFlags = 0, grabFlags = 0) { +export async function checkAccelerator(accelerator, modeFlags = 0, grabFlags = 0) { try { let result = false; @@ -276,7 +274,7 @@ async function checkAccelerator(accelerator, modeFlags = 0, grabFlags = 0) { * @param {string} accelerator - An accelerator as taken by Gtk.ShortcutLabel * @return {string} An accelerator or %null if it should be unset. */ -async function getAccelerator(summary, accelerator = null) { +export async function getAccelerator(summary, accelerator = null) { try { const dialog = new ShortcutChooserDialog({ summary: summary, diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/service.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/service.js index d9bc97f..e258f22 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/service.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/preferences/service.js @@ -2,18 +2,18 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gdk from 'gi://Gdk'; +import GdkPixbuf from 'gi://GdkPixbuf'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; -const Gdk = imports.gi.Gdk; -const GdkPixbuf = imports.gi.GdkPixbuf; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; +import system from 'system'; -const Config = imports.config; -const Device = imports.preferences.device; -const Remote = imports.utils.remote; +import Config from '../config.js'; +import {Panel, rowSeparators} from './device.js'; +import {Service} from '../utils/remote.js'; /* @@ -21,7 +21,7 @@ const Remote = imports.utils.remote; */ const LOG_HEADER = new GLib.Bytes(` GSConnect: ${Config.PACKAGE_VERSION} (${Config.IS_USER ? 'user' : 'system'}) -GJS: ${imports.system.version} +GJS: ${system.version} Session: ${GLib.getenv('XDG_SESSION_TYPE')} OS: ${GLib.get_os_info('PRETTY_NAME')} -------------------------------------------------------------------------------- @@ -91,7 +91,7 @@ async function generateSupportLog(time) { /** * "Connect to..." Dialog */ -var ConnectDialog = GObject.registerClass({ +const ConnectDialog = GObject.registerClass({ GTypeName: 'GSConnectConnectDialog', Template: 'resource:///org/gnome/Shell/Extensions/GSConnect/ui/connect-dialog.ui', Children: [ @@ -132,7 +132,7 @@ var ConnectDialog = GObject.registerClass({ }); -var Window = GObject.registerClass({ +export const Window = GObject.registerClass({ GTypeName: 'GSConnectPreferencesWindow', Properties: { 'display-mode': GObject.ParamSpec.string( @@ -173,7 +173,7 @@ var Window = GObject.registerClass({ }); // Service Proxy - this.service = new Remote.Service(); + this.service = new Service(); this._deviceAddedId = this.service.connect( 'device-added', @@ -198,7 +198,7 @@ var Window = GObject.registerClass({ this.service_box.set_focus_vadjustment(this.service_window.vadjustment); // Device List - this.device_list.set_header_func(Device.rowSeparators); + this.device_list.set_header_func(rowSeparators); // Discoverable InfoBar this.settings.bind( @@ -580,7 +580,7 @@ var Window = GObject.registerClass({ try { if (!this.stack.get_child_by_name(device.id)) { // Add the device preferences - const prefs = new Device.Panel(device); + const prefs = new Panel(device); this.stack.add_titled(prefs, device.id, device.name); // Add a row to the device list diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/prefs.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/prefs.js index dd20fd2..4a94ca7 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/prefs.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/prefs.js @@ -8,7 +8,7 @@ import Adw from 'gi://Adw'; // Bootstrap import * as Utils from './shell/utils.js'; -import setup from './utils/setup.mjs'; +import setup from './utils/setup.js'; import {ExtensionPreferences} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; export default class GSConnectExtensionPreferences extends ExtensionPreferences { diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/backends/lan.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/backends/lan.js index a5357bf..758e24b 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/backends/lan.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/backends/lan.js @@ -2,15 +2,23 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const Config = imports.config; -const Core = imports.service.core; +import Config from '../../config.js'; +import * as Core from '../core.js'; +// Retain compatibility with GLib < 2.80, which lacks GioUnix +let GioUnix; +try { + GioUnix = (await import('gi://GioUnix')).default; +} catch (e) { + GioUnix = { + InputStream: Gio.UnixInputStream, + OutputStream: Gio.UnixOutputStream, + }; +} /** * TCP Port Constants @@ -25,7 +33,7 @@ const TRANSFER_MAX = 1764; /* * One-time check for Linux/FreeBSD socket options */ -var _LINUX_SOCKETS = true; +export let _LINUX_SOCKETS = true; try { // This should throw on FreeBSD @@ -44,7 +52,7 @@ try { * * @param {Gio.SocketConnection} connection - The connection to configure */ -function _configureSocket(connection) { +export function _configureSocket(connection) { try { if (_LINUX_SOCKETS) { connection.socket.set_option(6, 4, 10); // TCP_KEEPIDLE @@ -78,7 +86,7 @@ function _configureSocket(connection) { * include the TCP port, while the IP address is taken from the UDP packet * itself. We respond by opening a TCP connection to that address. */ -var ChannelService = GObject.registerClass({ +export const ChannelService = GObject.registerClass({ GTypeName: 'GSConnectLanChannelService', Properties: { 'certificate': GObject.ParamSpec.object( @@ -264,7 +272,7 @@ var ChannelService = GObject.registerClass({ // Input stream this._udp6_stream = new Gio.DataInputStream({ - base_stream: new Gio.UnixInputStream({ + base_stream: new GioUnix.InputStream({ fd: this._udp6.fd, close_fd: false, }), @@ -296,7 +304,7 @@ var ChannelService = GObject.registerClass({ // Input stream this._udp4_stream = new Gio.DataInputStream({ - base_stream: new Gio.UnixInputStream({ + base_stream: new GioUnix.InputStream({ fd: this._udp4.fd, close_fd: false, }), @@ -527,7 +535,7 @@ var ChannelService = GObject.registerClass({ * This class essentially just extends Core.Channel to set TCP socket options * and negotiate TLS encrypted connections. */ -var Channel = GObject.registerClass({ +export const Channel = GObject.registerClass({ GTypeName: 'GSConnectLanChannel', }, class LanChannel extends Core.Channel { diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/__init__.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/__init__.js deleted file mode 100644 index 1ed8cf6..0000000 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/__init__.js +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-FileCopyrightText: GSConnect Developers https://github.com/GSConnect -// -// SPDX-License-Identifier: GPL-2.0-or-later - -'use strict'; - - -/* - * Singleton Tracker - */ -const Default = new Map(); - - -/** - * Acquire a reference to a component. Calls to this function should always be - * followed by a call to `release()`. - * - * @param {string} name - The module name - * @return {*} The default instance of a component - */ -function acquire(name) { - let component; - - try { - let info = Default.get(name); - - if (info === undefined) { - const module = imports.service.components[name]; - - info = { - instance: new module.Component(), - refcount: 0, - }; - - Default.set(name, info); - } - - info.refcount++; - component = info.instance; - } catch (e) { - debug(e, name); - } - - return component; -} - - -/** - * Release a reference on a component. If the caller was the last reference - * holder, the component will be freed. - * - * @param {string} name - The module name - * @return {null} A %null value, useful for overriding a traced variable - */ -function release(name) { - try { - const info = Default.get(name); - - if (info.refcount === 1) { - info.instance.destroy(); - Default.delete(name); - } - - info.refcount--; - } catch (e) { - debug(e, name); - } - - return null; -} - diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/atspi.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/atspi.js index 33034e6..97581d7 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/atspi.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/atspi.js @@ -2,12 +2,8 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -imports.gi.versions.Atspi = '2.0'; - -const Atspi = imports.gi.Atspi; -const Gdk = imports.gi.Gdk; +import Atspi from 'gi://Atspi?version=2.0'; +import Gdk from 'gi://Gdk'; /** @@ -30,7 +26,7 @@ const XKeycode = { /** * A thin wrapper around Atspi for X11 sessions without Pipewire support. */ -var Controller = class { +export default class Controller { constructor() { // Atspi.init() return 2 on fail, but still marks itself as inited. We // uninit before throwing an error otherwise any future call to init() @@ -312,5 +308,5 @@ var Controller = class { // Silence errors } } -}; +} diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/clipboard.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/clipboard.js index d51b9f7..dc8e5d8 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/clipboard.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/clipboard.js @@ -2,20 +2,21 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const Gdk = imports.gi.Gdk; -const GLib = imports.gi.GLib; -const Gtk = imports.gi.Gtk; -const Gio = imports.gi.Gio; -const GObject = imports.gi.GObject; +import Gdk from 'gi://Gdk'; +import GLib from 'gi://GLib'; +import Gtk from 'gi://Gtk'; +import Gio from 'gi://Gio'; +import GObject from 'gi://GObject'; const DBUS_NAME = 'org.gnome.Shell.Extensions.GSConnect.Clipboard'; const DBUS_PATH = '/org/gnome/Shell/Extensions/GSConnect/Clipboard'; -var Clipboard = GObject.registerClass({ +/** + * The service class for this component + */ +const Clipboard = GObject.registerClass({ GTypeName: 'GSConnectClipboard', Properties: { 'text': GObject.ParamSpec.string( @@ -98,7 +99,7 @@ var Clipboard = GObject.registerClass({ if (!globalThis.HAVE_GNOME) { // Directly subscrible signal this.signalHandler = Gio.DBus.session.signal_subscribe( - DBUS_NAME, + null, DBUS_NAME, 'OwnerChange', DBUS_PATH, @@ -219,10 +220,6 @@ var Clipboard = GObject.registerClass({ } }); - -/** - * The service class for this component - */ -var Component = Clipboard; +export default Clipboard; // vim:tabstop=2:shiftwidth=2:expandtab diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/contacts.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/contacts.js index 9668596..3070f40 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/contacts.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/contacts.js @@ -2,23 +2,21 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; +import Config from '../../config.js'; -const Config = imports.config; - -var HAVE_EDS = true; -var EBook = null; -var EBookContacts = null; -var EDataServer = null; +let HAVE_EDS = true; +let EBook = null; +let EBookContacts = null; +let EDataServer = null; try { - EBook = imports.gi.EBook; - EBookContacts = imports.gi.EBookContacts; - EDataServer = imports.gi.EDataServer; + EBook = (await import('gi://EBook')).default; + EBookContacts = (await import('gi://EBookContacts')).default; + EDataServer = (await import('gi://EDataServer')).default; } catch (e) { HAVE_EDS = false; } @@ -27,7 +25,7 @@ try { /** * A store for contacts */ -var Store = GObject.registerClass({ +const Store = GObject.registerClass({ GTypeName: 'GSConnectContactsStore', Properties: { 'context': GObject.ParamSpec.string( @@ -611,9 +609,5 @@ var Store = GObject.registerClass({ } }); - -/** - * The service class for this component - */ -var Component = Store; +export default Store; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/input.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/input.js index 121c4d9..0675af3 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/input.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/input.js @@ -2,15 +2,15 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gdk from 'gi://Gdk'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gdk = imports.gi.Gdk; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; +import AtspiController from './atspi.js'; -const SESSION_TIMEOUT = 15; +const SESSION_TIMEOUT = 300; const RemoteSession = GObject.registerClass({ @@ -229,7 +229,7 @@ const RemoteSession = GObject.registerClass({ }); -class Controller { +export default class Controller { constructor() { this._nameAppearedId = 0; this._session = null; @@ -339,8 +339,7 @@ class Controller { if (this.connection === null) { debug('Falling back to Atspi'); - const fallback = imports.service.components.atspi; - this._session = new fallback.Controller(); + this._session = new AtspiController(); // Mutter is available and there isn't another session starting } else if (this._sessionStarting === false) { @@ -513,9 +512,3 @@ class Controller { } } } - - -/** - * The service class for this component - */ -var Component = Controller; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/mpris.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/mpris.js index df9adaf..70c4225 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/mpris.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/mpris.js @@ -2,14 +2,12 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -var Player = GObject.registerClass({ +export const Player = GObject.registerClass({ GTypeName: 'GSConnectMediaPlayerInterface', Properties: { // Application Properties @@ -790,7 +788,7 @@ const PlayerProxy = GObject.registerClass({ /** * A manager for media players */ -var Manager = GObject.registerClass({ +const Manager = GObject.registerClass({ GTypeName: 'GSConnectMPRISManager', Signals: { 'player-added': { @@ -1001,5 +999,5 @@ var Manager = GObject.registerClass({ /** * The service class for this component */ -var Component = Manager; +export default Manager; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/notification.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/notification.js index 17b31d6..0566a25 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/notification.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/notification.js @@ -2,14 +2,12 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GjsPrivate from 'gi://GjsPrivate'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GjsPrivate = imports.gi.GjsPrivate; -const GObject = imports.gi.GObject; - -const DBus = imports.service.utils.dbus; +import * as DBus from '../utils/dbus.js'; const _nodeInfo = Gio.DBusNodeInfo.new_for_xml(` @@ -408,4 +406,4 @@ const Listener = GObject.registerClass({ /** * The service class for this component */ -var Component = Listener; +export default Listener; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/pulseaudio.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/pulseaudio.js index 1e09fdb..1165fc0 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/pulseaudio.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/pulseaudio.js @@ -2,40 +2,43 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import GIRepository from 'gi://GIRepository'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; + +import Config from '../../config.js'; const Tweener = imports.tweener.tweener; -const GIRepository = imports.gi.GIRepository; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Config = imports.config; +let Gvc = null; +try { + // Add gnome-shell's typelib dir to the search path + const typelibDir = GLib.build_filenamev([Config.GNOME_SHELL_LIBDIR, 'gnome-shell']); + GIRepository.Repository.prepend_search_path(typelibDir); + GIRepository.Repository.prepend_library_path(typelibDir); - -// Add gnome-shell's typelib dir to the search path -const typelibDir = GLib.build_filenamev([Config.GNOME_SHELL_LIBDIR, 'gnome-shell']); -GIRepository.Repository.prepend_search_path(typelibDir); -GIRepository.Repository.prepend_library_path(typelibDir); - -const Gvc = imports.gi.Gvc; + Gvc = (await import('gi://Gvc')).default; +} catch (e) {} /** * Extend Gvc.MixerStream with a property for returning a user-visible name */ -Object.defineProperty(Gvc.MixerStream.prototype, 'display_name', { - get: function () { - try { - if (!this.get_ports().length) - return this.description; +if (Gvc) { + Object.defineProperty(Gvc.MixerStream.prototype, 'display_name', { + get: function () { + try { + if (!this.get_ports().length) + return this.description; - return `${this.get_port().human_port} (${this.description})`; - } catch (e) { - return this.description; - } - }, -}); + return `${this.get_port().human_port} (${this.description})`; + } catch (e) { + return this.description; + } + }, + }); +} /** @@ -110,7 +113,7 @@ class Stream { * The Mixer class uses GNOME Shell's Gvc library to control the system volume * and offers a few convenience functions. */ -const Mixer = GObject.registerClass({ +const Mixer = !Gvc ? null : GObject.registerClass({ GTypeName: 'GSConnectAudioMixer', }, class Mixer extends Gvc.MixerControl { _init(params) { @@ -265,4 +268,4 @@ const Mixer = GObject.registerClass({ /** * The service class for this component */ -var Component = Mixer; +export default Mixer; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/session.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/session.js index 512ace2..5d57450 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/session.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/session.js @@ -2,10 +2,8 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; const Session = class { @@ -82,5 +80,5 @@ const Session = class { /** * The service class for this component */ -var Component = Session; +export default Session; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/sound.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/sound.js index 4634d50..0845acf 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/sound.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/sound.js @@ -2,23 +2,17 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gdk from 'gi://Gdk'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; -const Gdk = imports.gi.Gdk; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; +let GSound = null; +try { + GSound = (await import('gi://GSound')).default; +} catch (e) {} -/* - * Used to ensure 'audible-bell' is enabled for fallback - */ -const WM_SETTINGS = new Gio.Settings({ - schema_id: 'org.gnome.desktop.wm.preferences', - path: '/org/gnome/desktop/wm/preferences/', -}); - - -var Player = class Player { +const Player = class Player { constructor() { this._playing = new Set(); @@ -27,22 +21,20 @@ var Player = class Player { get backend() { if (this._backend === undefined) { // Prefer GSound - try { - this._gsound = new imports.gi.GSound.Context(); + if (GSound !== null) { + this._gsound = new GSound.Context(); this._gsound.init(null); this._backend = 'gsound'; // Try falling back to libcanberra, otherwise just re-run the test // in case one or the other is installed later - } catch (e) { - if (GLib.find_program_in_path('canberra-gtk-play') !== null) { - this._canberra = new Gio.SubprocessLauncher({ - flags: Gio.SubprocessFlags.NONE, - }); - this._backend = 'libcanberra'; - } else { - return null; - } + } else if (GLib.find_program_in_path('canberra-gtk-play') !== null) { + this._canberra = new Gio.SubprocessLauncher({ + flags: Gio.SubprocessFlags.NONE, + }); + this._backend = 'libcanberra'; + } else { + return null; } } @@ -176,5 +168,5 @@ var Player = class Player { /** * The service class for this component */ -var Component = Player; +export default Player; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/upower.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/upower.js index f090a92..722387b 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/upower.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/upower.js @@ -2,11 +2,9 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; /** @@ -49,7 +47,7 @@ const DeviceState = { /** * A class representing the system battery. */ -var Battery = GObject.registerClass({ +const Battery = GObject.registerClass({ GTypeName: 'GSConnectSystemBattery', Signals: { 'changed': { @@ -213,5 +211,5 @@ var Battery = GObject.registerClass({ /** * The service class for this component */ -var Component = Battery; +export default Battery; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/ydotool.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/ydotool.js index c2a7f5d..de04418 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/ydotool.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/components/ydotool.js @@ -2,10 +2,8 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const Gio = imports.gi.Gio; -const Gdk = imports.gi.Gdk; +import Gio from 'gi://Gio'; +import Gdk from 'gi://Gdk'; const keyCodes = new Map([ ['1', 2], @@ -55,7 +53,7 @@ const keyCodes = new Map([ ['/', 53], ['\\', 43], ]); -class Controller { +export default class Controller { constructor() { // laucher for wl-clipboard this._launcher = new Gio.SubprocessLauncher({ @@ -137,7 +135,7 @@ class Controller { modifiers_codes.push(input); } else if (typeof input === 'string') { input = input.toUpperCase(); - for (var i = 0; i < input.length; i++) { + for (let i = 0; i < input.length; i++) { if (keyCodes.get(input[i])) { modifiers_codes.push(keyCodes.get(input[i])); } else { @@ -160,8 +158,3 @@ class Controller { this._args = []; } } - -/** - * The service class for this component - */ -var Component = Controller; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/core.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/core.js index e3406bf..43788ce 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/core.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/core.js @@ -2,11 +2,11 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; +import plugins from './plugins/index.js'; /** @@ -14,13 +14,16 @@ const GObject = imports.gi.GObject; * * @return {string} A device type string */ -function _getDeviceType() { +export function _getDeviceType() { try { let type = GLib.file_get_contents('/sys/class/dmi/id/chassis_type')[1]; type = Number(new TextDecoder().decode(type)); - if ([8, 9, 10, 14].includes(type)) + if ([30, 32].includes(type)) + return 'tablet'; + + if ([8, 9, 10, 14, 31].includes(type)) return 'laptop'; return 'desktop'; @@ -34,7 +37,7 @@ function _getDeviceType() { * The packet class is a simple Object-derived class, offering some conveniences * for working with KDE Connect packets. */ -var Packet = class Packet { +export class Packet { constructor(data = null) { this.id = 0; @@ -114,7 +117,7 @@ var Packet = class Packet { return (Object.keys(this.payloadTransferInfo).length > 0); } -}; +} /** @@ -122,7 +125,7 @@ var Packet = class Packet { * devices. The implementation is responsible for all negotiation of the * underlying protocol. */ -var Channel = GObject.registerClass({ +export const Channel = GObject.registerClass({ GTypeName: 'GSConnectChannel', Properties: { 'closed': GObject.ParamSpec.boolean( @@ -297,7 +300,7 @@ var Channel = GObject.registerClass({ * ChannelService implementations provide Channel objects, emitting the * ChannelService::channel signal when a new connection has been accepted. */ -var ChannelService = GObject.registerClass({ +export const ChannelService = GObject.registerClass({ GTypeName: 'GSConnectChannelService', Properties: { 'active': GObject.ParamSpec.boolean( @@ -409,8 +412,8 @@ var ChannelService = GObject.registerClass({ }, }); - for (const name in imports.service.plugins) { - const meta = imports.service.plugins[name].Metadata; + for (const name in plugins) { + const meta = plugins[name].Metadata; if (meta === undefined) continue; @@ -460,7 +463,7 @@ var ChannelService = GObject.registerClass({ /** * A class representing a file transfer. */ -var Transfer = GObject.registerClass({ +export const Transfer = GObject.registerClass({ GTypeName: 'GSConnectTransfer', Properties: { 'channel': GObject.ParamSpec.object( @@ -691,4 +694,3 @@ var Transfer = GObject.registerClass({ this._cancellable.cancel(); } }); - diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/daemon.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/daemon.js old mode 100644 new mode 100755 index 0d51748..1ddb356 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/daemon.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/daemon.js @@ -1,46 +1,27 @@ -#!/usr/bin/env gjs +#!/usr/bin/env -S gjs -m // SPDX-FileCopyrightText: GSConnect Developers https://github.com/GSConnect // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gdk from 'gi://Gdk?version=3.0'; +import 'gi://GdkPixbuf?version=2.0'; +import Gio from 'gi://Gio?version=2.0'; +import 'gi://GIRepository?version=2.0'; +import GLib from 'gi://GLib?version=2.0'; +import GObject from 'gi://GObject?version=2.0'; +import Gtk from 'gi://Gtk?version=3.0'; +import 'gi://Pango?version=1.0'; -imports.gi.versions.Gdk = '3.0'; -imports.gi.versions.GdkPixbuf = '2.0'; -imports.gi.versions.Gio = '2.0'; -imports.gi.versions.GIRepository = '2.0'; -imports.gi.versions.GLib = '2.0'; -imports.gi.versions.GObject = '2.0'; -imports.gi.versions.Gtk = '3.0'; -imports.gi.versions.Pango = '1.0'; +import system from 'system'; -const Gdk = imports.gi.Gdk; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; +import './init.js'; -// Bootstrap -function get_datadir() { - let [, path] = /@([^:]+):\d+/.exec(new Error().stack.split('\n')[1]); - const info = Gio.File.new_for_path(path) - .query_info('standard::*', Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null); - path = info.get_is_symlink() ? info.get_symlink_target() : path; +import Config from '../config.js'; +import Manager from './manager.js'; +import * as ServiceUI from './ui/service.js'; - return Gio.File.new_for_path(path).get_parent().get_parent().get_path(); -} - -imports.searchPath.unshift(get_datadir()); -imports.config.PACKAGE_DATADIR = imports.searchPath[0]; - -const _setup = imports.service.utils.setup; - - -// Local Imports -const Config = imports.config; -const Manager = imports.service.manager; -const ServiceUI = imports.service.ui.service; +import('gi://GioUnix?version=2.0').catch(() => {}); // Set version for optional dependency /** @@ -267,7 +248,7 @@ const Service = GObject.registerClass({ if (!super.vfunc_dbus_register(connection, object_path)) return false; - this.manager = new Manager.Manager({ + this.manager = new Manager({ connection: connection, object_path: object_path, }); @@ -337,7 +318,7 @@ const Service = GObject.registerClass({ continue; // Force a GC to prevent any more calls back into JS, then chain-up - imports.system.gc(); + system.gc(); super.vfunc_shutdown(); } @@ -717,5 +698,5 @@ const Service = GObject.registerClass({ } }); -(new Service()).run([imports.system.programInvocationName].concat(ARGV)); +await (new Service()).runAsync([system.programInvocationName].concat(ARGV)); diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/device.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/device.js index b0d24de..aef96a2 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/device.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/device.js @@ -2,16 +2,14 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const Config = imports.config; -const Components = imports.service.components; -const Core = imports.service.core; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Config from '../config.js'; +import * as Components from './components/index.js'; +import * as Core from './core.js'; +import plugins from './plugins/index.js'; /** * An object representing a remote device. @@ -20,7 +18,7 @@ const Core = imports.service.core; * GActionGroup and GActionMap interfaces, like Gio.Application. * */ -var Device = GObject.registerClass({ +const Device = GObject.registerClass({ GTypeName: 'GSConnectDevice', Properties: { 'connected': GObject.ParamSpec.boolean( @@ -297,8 +295,8 @@ var Device = GObject.registerClass({ // Determine supported plugins by matching incoming to outgoing types const supported = []; - for (const name in imports.service.plugins) { - const meta = imports.service.plugins[name].Metadata; + for (const name in plugins) { + const meta = plugins[name].Metadata; if (meta === undefined) continue; @@ -1011,8 +1009,8 @@ var Device = GObject.registerClass({ try { if (this.paired && !this._plugins.has(name)) { // Instantiate the handler - handler = imports.service.plugins[name]; - plugin = new handler.Plugin(this); + handler = plugins[name]; + plugin = new handler.default(this); // Register packet handlers for (const packetType of handler.Metadata.incomingCapabilities) @@ -1053,7 +1051,7 @@ var Device = GObject.registerClass({ try { if (this._plugins.has(name)) { // Unregister packet handlers - handler = imports.service.plugins[name]; + handler = plugins[name]; for (const type of handler.Metadata.incomingCapabilities) this._handlers.delete(type); @@ -1104,3 +1102,4 @@ var Device = GObject.registerClass({ } }); +export default Device; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/init.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/init.js index 313c70b..e54d87c 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/init.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/init.js @@ -138,20 +138,17 @@ const _debugFunc = function (error, prefix = null) { }); }; -// Swap the function out for a no-op anonymous function for speed +globalThis._debugFunc = _debugFunc; + const settings = new Gio.Settings({ settings_schema: Config.GSCHEMA.lookup(Config.APP_ID, true), }); - -settings.connect('changed::debug', (settings, key) => { - globalThis.debug = settings.get_boolean(key) ? _debugFunc : () => {}; -}); - -if (settings.get_boolean('debug')) - globalThis.debug = _debugFunc; -else +if (settings.get_boolean('debug')) { + globalThis.debug = globalThis._debugFunc; +} else { + // Swap the function out for a no-op anonymous function for speed globalThis.debug = () => {}; - +} /** * Start wl_clipboard if not under Gnome diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/manager.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/manager.js index 9d86268f..ce9dca6 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/manager.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/manager.js @@ -2,25 +2,30 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; +import Config from '../config.js'; +import * as DBus from './utils/dbus.js'; +import Device from './device.js'; -const Config = imports.config; -const DBus = imports.service.utils.dbus; -const Device = imports.service.device; +import * as LanBackend from './backends/lan.js'; const DEVICE_NAME = 'org.gnome.Shell.Extensions.GSConnect.Device'; const DEVICE_PATH = '/org/gnome/Shell/Extensions/GSConnect/Device'; const DEVICE_IFACE = Config.DBUS.lookup_interface(DEVICE_NAME); +const backends = { + lan: LanBackend, +}; + + /** * A manager for devices. */ -var Manager = GObject.registerClass({ +const Manager = GObject.registerClass({ GTypeName: 'GSConnectManager', Properties: { 'active': GObject.ParamSpec.boolean( @@ -30,6 +35,13 @@ var Manager = GObject.registerClass({ GObject.ParamFlags.READABLE, false ), + 'debug': GObject.ParamSpec.boolean( + 'debug', + 'Debug', + 'Whether debug logging is enabled in GSConnect', + GObject.ParamFlags.READWRITE, + false + ), 'discoverable': GObject.ParamSpec.boolean( 'discoverable', 'Discoverable', @@ -80,6 +92,21 @@ var Manager = GObject.registerClass({ return this._backends; } + get debug() { + if (this._debug === undefined) + this._debug = this.settings.get_boolean('debug'); + + return this._debug; + } + + set debug(value) { + if (this._debug === value) + return; + + this._debug = value; + this._onDebugChanged(this._debug); + } + get devices() { if (this._devices === undefined) this._devices = new Map(); @@ -198,11 +225,20 @@ var Manager = GObject.registerClass({ this.settings.set_string('name', GLib.get_host_name()); // Bound Properties + this.settings.bind('debug', this, 'debug', 0); this.settings.bind('discoverable', this, 'discoverable', 0); this.settings.bind('id', this, 'id', 0); this.settings.bind('name', this, 'name', 0); } + _onDebugChanged(debug = false) { + // If debugging is disabled, install a no-op for speed + if (debug && globalThis._debugFunc !== undefined) + globalThis.debug = globalThis._debugFunc; + else + globalThis.debug = () => {}; + } + /* * Backends */ @@ -235,9 +271,9 @@ var Manager = GObject.registerClass({ } _loadBackends() { - for (const name in imports.service.backends) { + for (const name in backends) { try { - const module = imports.service.backends[name]; + const module = backends[name]; if (module.ChannelService === undefined) continue; @@ -270,7 +306,7 @@ var Manager = GObject.registerClass({ _loadDevices() { // Load cached devices for (const id of this.settings.get_strv('devices')) { - const device = new Device.Device({body: {deviceId: id}}); + const device = new Device({body: {deviceId: id}}); this._exportDevice(device); this.devices.set(id, device); } @@ -346,7 +382,7 @@ var Manager = GObject.registerClass({ * of known devices if it doesn't exist. * * @param {Core.Packet} packet - An identity packet for the device - * @return {Device.Device} A device object + * @return {Device} A device object */ _ensureDevice(packet) { let device = this.devices.get(packet.body.deviceId); @@ -365,7 +401,7 @@ var Manager = GObject.registerClass({ if (unpaired.length === 3) this.discoverable = false; - device = new Device.Device(packet); + device = new Device(packet); this._exportDevice(device); this.devices.set(device.id, device); @@ -506,3 +542,4 @@ var Manager = GObject.registerClass({ } }); +export default Manager; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/nativeMessagingHost.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/nativeMessagingHost.js old mode 100644 new mode 100755 index d83fc7f..297d180 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/nativeMessagingHost.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/nativeMessagingHost.js @@ -1,19 +1,25 @@ -#!/usr/bin/env gjs +#!/usr/bin/env -S gjs -m // SPDX-FileCopyrightText: GSConnect Developers https://github.com/GSConnect // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio?version=2.0'; +import GLib from 'gi://GLib?version=2.0'; +import GObject from 'gi://GObject?version=2.0'; -imports.gi.versions.Gio = '2.0'; -imports.gi.versions.GLib = '2.0'; -imports.gi.versions.GObject = '2.0'; +import system from 'system'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const System = imports.system; +// Retain compatibility with GLib < 2.80, which lacks GioUnix +let GioUnix; +try { + GioUnix = (await import('gi://GioUnix?version=2.0')).default; +} catch (e) { + GioUnix = { + InputStream: Gio.UnixInputStream, + OutputStream: Gio.UnixOutputStream, + }; +} const NativeMessagingHost = GObject.registerClass({ @@ -44,12 +50,12 @@ const NativeMessagingHost = GObject.registerClass({ // IO Channels this._stdin = new Gio.DataInputStream({ - base_stream: new Gio.UnixInputStream({fd: 0}), + base_stream: new GioUnix.InputStream({fd: 0}), byte_order: Gio.DataStreamByteOrder.HOST_ENDIAN, }); this._stdout = new Gio.DataOutputStream({ - base_stream: new Gio.UnixOutputStream({fd: 1}), + base_stream: new GioUnix.OutputStream({fd: 1}), byte_order: Gio.DataStreamByteOrder.HOST_ENDIAN, }); @@ -215,5 +221,5 @@ const NativeMessagingHost = GObject.registerClass({ }); // NOTE: must not pass ARGV -(new NativeMessagingHost()).run([System.programInvocationName]); +await (new NativeMessagingHost()).runAsync([system.programInvocationName]); diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugin.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugin.js index f096c16..ed2a5ef 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugin.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugin.js @@ -2,19 +2,18 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const Config = imports.config; +import Config from '../config.js'; +import plugins from './plugins/index.js'; /** * Base class for device plugins. */ -var Plugin = GObject.registerClass({ +const Plugin = GObject.registerClass({ GTypeName: 'GSConnectPlugin', Properties: { 'device': GObject.ParamSpec.object( @@ -42,7 +41,7 @@ var Plugin = GObject.registerClass({ this._meta = meta; if (this._meta === null) - this._meta = imports.service.plugins[name].Metadata; + this._meta = plugins[name].Metadata; // GSettings const schema = Config.GSCHEMA.lookup(this._meta.id, false); @@ -248,3 +247,5 @@ var Plugin = GObject.registerClass({ } }); +export default Plugin; + diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/battery.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/battery.js index 7727013..c7dbe04 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/battery.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/battery.js @@ -2,17 +2,15 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const Components = imports.service.components; -const PluginBase = imports.service.plugin; +import * as Components from '../components/index.js'; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('Battery'), description: _('Exchange battery information'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.Battery', @@ -32,9 +30,9 @@ var Metadata = { * Battery Plugin * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/battery */ -var Plugin = GObject.registerClass({ +const BatteryPlugin = GObject.registerClass({ GTypeName: 'GSConnectBatteryPlugin', -}, class Plugin extends PluginBase.Plugin { +}, class BatteryPlugin extends Plugin { _init(device) { super._init(device, 'battery'); @@ -431,3 +429,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default BatteryPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/clipboard.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/clipboard.js index a08125e..7a06574 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/clipboard.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/clipboard.js @@ -2,15 +2,13 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import GObject from 'gi://GObject'; -const GObject = imports.gi.GObject; - -const Components = imports.service.components; -const PluginBase = imports.service.plugin; +import * as Components from '../components/index.js'; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('Clipboard'), description: _('Share the clipboard content'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.Clipboard', @@ -47,9 +45,9 @@ var Metadata = { * Clipboard Plugin * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/clipboard */ -var Plugin = GObject.registerClass({ +const ClipboardPlugin = GObject.registerClass({ GTypeName: 'GSConnectClipboardPlugin', -}, class Plugin extends PluginBase.Plugin { +}, class ClipboardPlugin extends Plugin { _init(device) { super._init(device, 'clipboard'); @@ -180,3 +178,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default ClipboardPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/connectivity_report.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/connectivity_report.js index 9aaddb2..7107ff7 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/connectivity_report.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/connectivity_report.js @@ -2,17 +2,14 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const Components = imports.service.components; -const PluginBase = imports.service.plugin; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('Connectivity Report'), description: _('Display connectivity status'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.ConnectivityReport', @@ -30,9 +27,9 @@ var Metadata = { * Connectivity Report Plugin * https://invent.kde.org/network/kdeconnect-kde/-/tree/master/plugins/connectivity_report */ -var Plugin = GObject.registerClass({ +const ConnectivityReportPlugin = GObject.registerClass({ GTypeName: 'GSConnectConnectivityReportPlugin', -}, class Plugin extends PluginBase.Plugin { +}, class ConnectivityReportPlugin extends Plugin { _init(device) { super._init(device, 'connectivity_report'); @@ -162,3 +159,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default ConnectivityReportPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/contacts.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/contacts.js index f439961..2168712 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/contacts.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/contacts.js @@ -2,27 +2,28 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const PluginBase = imports.service.plugin; -const Contacts = imports.service.components.contacts; +import Plugin from '../plugin.js'; +import Contacts from '../components/contacts.js'; /* * We prefer libebook's vCard parser if it's available */ -var EBookContacts; +let EBookContacts; +export const setEBookContacts = (ebook) => { // This function is only for tests to call! + EBookContacts = ebook; +}; try { - EBookContacts = imports.gi.EBookContacts; + EBookContacts = (await import('gi://EBookContacts')).default; } catch (e) { EBookContacts = null; } -var Metadata = { +export const Metadata = { label: _('Contacts'), description: _('Access contacts of the paired device'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.Contacts', @@ -53,14 +54,14 @@ const VCARD_TYPED_META = /([a-z]+)=(.*)/i; * Contacts Plugin * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/contacts */ -var Plugin = GObject.registerClass({ +const ContactsPlugin = GObject.registerClass({ GTypeName: 'GSConnectContactsPlugin', -}, class Plugin extends PluginBase.Plugin { +}, class ContactsPlugin extends Plugin { _init(device) { super._init(device, 'contacts'); - this._store = new Contacts.Store(device.id); + this._store = new Contacts(device.id); this._store.fetch = this._requestUids.bind(this); // Notify when the store is ready @@ -458,3 +459,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default ContactsPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/findmyphone.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/findmyphone.js index 87514de..b5226bb 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/findmyphone.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/findmyphone.js @@ -2,18 +2,16 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gdk from 'gi://Gdk'; +import Gio from 'gi://Gio'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; -const Gdk = imports.gi.Gdk; -const Gio = imports.gi.Gio; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; - -const Components = imports.service.components; -const PluginBase = imports.service.plugin; +import * as Components from '../components/index.js'; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('Find My Phone'), description: _('Ring your paired device'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.FindMyPhone', @@ -36,9 +34,9 @@ var Metadata = { * FindMyPhone Plugin * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/findmyphone */ -var Plugin = GObject.registerClass({ +const FindMyPhonePlugin = GObject.registerClass({ GTypeName: 'GSConnectFindMyPhonePlugin', -}, class Plugin extends PluginBase.Plugin { +}, class FindMyPhonePlugin extends Plugin { _init(device) { super._init(device, 'findmyphone'); @@ -247,3 +245,5 @@ const Dialog = GObject.registerClass({ this._plugin = plugin; } }); + +export default FindMyPhonePlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/mousepad.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/mousepad.js index 969eb06..a4e40ae 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/mousepad.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/mousepad.js @@ -2,17 +2,15 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gdk from 'gi://Gdk'; +import GObject from 'gi://GObject'; -const Gdk = imports.gi.Gdk; -const GObject = imports.gi.GObject; - -const Components = imports.service.components; -const {InputDialog} = imports.service.ui.mousepad; -const PluginBase = imports.service.plugin; +import * as Components from '../components/index.js'; +import {InputDialog} from '../ui/mousepad.js'; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('Mousepad'), description: _('Enables the paired device to act as a remote mouse and keyboard'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.Mousepad', @@ -120,7 +118,7 @@ const KeyMapCodes = new Map([ * * TODO: support outgoing mouse events? */ -var Plugin = GObject.registerClass({ +const MousepadPlugin = GObject.registerClass({ GTypeName: 'GSConnectMousepadPlugin', Properties: { 'state': GObject.ParamSpec.boolean( @@ -131,7 +129,7 @@ var Plugin = GObject.registerClass({ false ), }, -}, class Plugin extends PluginBase.Plugin { +}, class MousepadPlugin extends Plugin { _init(device) { super._init(device, 'mousepad'); @@ -379,3 +377,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default MousepadPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/mpris.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/mpris.js index 04651e1..2fd6a50 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/mpris.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/mpris.js @@ -2,20 +2,18 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const Components = imports.service.components; -const Config = imports.config; -const DBus = imports.service.utils.dbus; -const MPRIS = imports.service.components.mpris; -const PluginBase = imports.service.plugin; +import * as Components from '../components/index.js'; +import Config from '../../config.js'; +import * as DBus from '../utils/dbus.js'; +import {Player} from '../components/mpris.js'; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('MPRIS'), description: _('Bidirectional remote media playback control'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.MPRIS', @@ -33,9 +31,9 @@ var Metadata = { * https://specifications.freedesktop.org/mpris-spec/latest/ * https://github.com/GNOME/gnome-shell/blob/master/js/ui/mpris.js */ -var Plugin = GObject.registerClass({ +const MPRISPlugin = GObject.registerClass({ GTypeName: 'GSConnectMPRISPlugin', -}, class Plugin extends PluginBase.Plugin { +}, class MPRISPlugin extends Plugin { _init(device) { super._init(device, 'mpris'); @@ -242,11 +240,22 @@ var Plugin = GObject.registerClass({ player.Volume = packet.body.setVolume / 100; if (packet.body.hasOwnProperty('Seek')) - await player.Seek(packet.body.Seek * 1000); + await player.Seek(packet.body.Seek); if (packet.body.hasOwnProperty('SetPosition')) { - const offset = (packet.body.SetPosition * 1000) - player.Position; - await player.Seek(offset); + // We want to avoid implementing this as a seek operation, + // because some players seek a fixed amount for every + // seek request, only respecting the sign of the parameter. + // (Chrome, for example, will only seek ±5 seconds, regardless + // what value is passed to Seek().) + const position = packet.body.SetPosition; + const metadata = player.Metadata; + if (metadata.hasOwnProperty('mpris:trackid')) { + const trackId = metadata['mpris:trackid']; + await player.SetPosition(trackId, position * 1000); + } else { + await player.Seek(position * 1000 - player.Position); + } } // Information Request @@ -448,7 +457,7 @@ var Plugin = GObject.registerClass({ */ const PlayerRemote = GObject.registerClass({ GTypeName: 'GSConnectMPRISPlayerRemote', -}, class PlayerRemote extends MPRIS.Player { +}, class PlayerRemote extends Player { _init(device, identity) { super._init(); @@ -904,3 +913,5 @@ const PlayerRemote = GObject.registerClass({ } } }); + +export default MPRISPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/notification.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/notification.js index 3697615..bb317db 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/notification.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/notification.js @@ -2,20 +2,18 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; - -const Components = imports.service.components; -const Config = imports.config; -const PluginBase = imports.service.plugin; -const NotificationUI = imports.service.ui.notification; +import * as Components from '../components/index.js'; +import Config from '../../config.js'; +import Plugin from '../plugin.js'; +import ReplyDialog from '../ui/notification.js'; -var Metadata = { +export const Metadata = { label: _('Notifications'), description: _('Share notifications with the paired device'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.Notification', @@ -162,9 +160,9 @@ function _removeNotification(id, application = null) { * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/notifications * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/sendnotifications */ -var Plugin = GObject.registerClass({ +const NotificationPlugin = GObject.registerClass({ GTypeName: 'GSConnectNotificationPlugin', -}, class Plugin extends PluginBase.Plugin { +}, class NotificationPlugin extends Plugin { _init(device) { super._init(device, 'notification'); @@ -642,7 +640,7 @@ var Plugin = GObject.registerClass({ // If the message has no content, open a dialog for the user to add one if (!message) { - const dialog = new NotificationUI.ReplyDialog({ + const dialog = new ReplyDialog({ device: this.device, uuid: uuid, notification: notification, @@ -692,3 +690,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default NotificationPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/ping.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/ping.js index 3eb194b..011ecf0 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/ping.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/ping.js @@ -2,16 +2,14 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const PluginBase = imports.service.plugin; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('Ping'), description: _('Send and receive pings'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.Ping', @@ -34,9 +32,9 @@ var Metadata = { * Ping Plugin * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/ping */ -var Plugin = GObject.registerClass({ +const PingPlugin = GObject.registerClass({ GTypeName: 'GSConnectPingPlugin', -}, class Plugin extends PluginBase.Plugin { +}, class PingPlugin extends Plugin { _init(device) { super._init(device, 'ping'); @@ -71,3 +69,5 @@ var Plugin = GObject.registerClass({ this.device.sendPacket(packet); } }); + +export default PingPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/presenter.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/presenter.js index 7d9cf94..3cccab0 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/presenter.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/presenter.js @@ -2,15 +2,13 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import GObject from 'gi://GObject'; -const GObject = imports.gi.GObject; - -const Components = imports.service.components; -const PluginBase = imports.service.plugin; +import * as Components from '../components/index.js'; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('Presentation'), description: _('Use the paired device as a presenter'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.Presenter', @@ -25,9 +23,9 @@ var Metadata = { * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/presenter * https://github.com/KDE/kdeconnect-android/tree/master/src/org/kde/kdeconnect/Plugins/PresenterPlugin/ */ -var Plugin = GObject.registerClass({ +const PresenterPlugin = GObject.registerClass({ GTypeName: 'GSConnectPresenterPlugin', -}, class Plugin extends PluginBase.Plugin { +}, class PresenterPlugin extends Plugin { _init(device) { super._init(device, 'presenter'); @@ -61,3 +59,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default PresenterPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/runcommand.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/runcommand.js index 44f0005..c57c6c0 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/runcommand.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/runcommand.js @@ -2,16 +2,14 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const PluginBase = imports.service.plugin; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('Run Commands'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.RunCommand', description: _('Run commands on your paired device or let the device run predefined commands on this PC'), @@ -49,7 +47,7 @@ var Metadata = { * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/remotecommands * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/runcommand */ -var Plugin = GObject.registerClass({ +const RunCommandPlugin = GObject.registerClass({ GTypeName: 'GSConnectRunCommandPlugin', Properties: { 'remote-commands': GObject.param_spec_variant( @@ -61,7 +59,7 @@ var Plugin = GObject.registerClass({ GObject.ParamFlags.READABLE ), }, -}, class Plugin extends PluginBase.Plugin { +}, class RunCommandPlugin extends Plugin { _init(device) { super._init(device, 'runcommand'); @@ -252,3 +250,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default RunCommandPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/sftp.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/sftp.js index 100749c..2789ff3 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/sftp.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/sftp.js @@ -2,18 +2,15 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const Config = imports.config; -const Lan = imports.service.backends.lan; -const PluginBase = imports.service.plugin; +import Config from '../../config.js'; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('SFTP'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.SFTP', description: _('Browse the paired device filesystem'), @@ -48,9 +45,9 @@ const MAX_MOUNT_DIRS = 12; * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/sftp * https://github.com/KDE/kdeconnect-android/tree/master/src/org/kde/kdeconnect/Plugins/SftpPlugin */ -var Plugin = GObject.registerClass({ +const SFTPPlugin = GObject.registerClass({ GTypeName: 'GSConnectSFTPPlugin', -}, class Plugin extends PluginBase.Plugin { +}, class SFTPPlugin extends Plugin { _init(device) { super._init(device, 'sftp'); @@ -106,7 +103,7 @@ var Plugin = GObject.registerClass({ super.connected(); // Only enable for Lan connections - if (this.device.channel instanceof Lan.Channel) { + if (this.device.channel.constructor.name === 'LanChannel') { // FIXME: Circular import workaround if (this.settings.get_boolean('automount')) this.mount(); } else { @@ -486,3 +483,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default SFTPPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/share.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/share.js index af0eae6..5e382b4 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/share.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/share.js @@ -2,19 +2,17 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import GdkPixbuf from 'gi://GdkPixbuf'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; -const GdkPixbuf = imports.gi.GdkPixbuf; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; - -const PluginBase = imports.service.plugin; -const URI = imports.service.utils.uri; +import Plugin from '../plugin.js'; +import * as URI from '../utils/uri.js'; -var Metadata = { +export const Metadata = { label: _('Share'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.Share', description: _('Share files and URLs between devices'), @@ -64,9 +62,9 @@ var Metadata = { * TODO: receiving 'text' TODO: Window with textview & 'Copy to Clipboard.. * https://github.com/KDE/kdeconnect-kde/commit/28f11bd5c9a717fb9fbb3f02ddd6cea62021d055 */ -var Plugin = GObject.registerClass({ +const SharePlugin = GObject.registerClass({ GTypeName: 'GSConnectSharePlugin', -}, class Plugin extends PluginBase.Plugin { +}, class SharePlugin extends Plugin { _init(device) { super._init(device, 'share'); @@ -198,6 +196,9 @@ var Plugin = GObject.registerClass({ ]; iconName = 'document-save-symbolic'; + const gtk_recent_manager = Gtk.RecentManager.get_default(); + gtk_recent_manager.add_item(file.get_uri()); + if (packet.body.open) { const uri = file.get_uri(); Gio.AppInfo.launch_default_for_uri_async(uri, null, null, null); @@ -369,7 +370,7 @@ var Plugin = GObject.registerClass({ /** A simple FileChooserDialog for sharing files */ -var FileChooserDialog = GObject.registerClass({ +const FileChooserDialog = GObject.registerClass({ GTypeName: 'GSConnectShareFileChooserDialog', }, class FileChooserDialog extends Gtk.FileChooserDialog { @@ -451,10 +452,11 @@ var FileChooserDialog = GObject.registerClass({ _onUriButtonToggled(button) { const header = this.get_header_bar(); - // Show the URL entry + // Show and focus the URL entry if (button.active) { this.extra_widget.sensitive = false; header.set_custom_title(this._uriEntry); + this._uriEntry.grab_focus(); this.set_response_sensitive(Gtk.ResponseType.OK, true); // Hide the URL entry @@ -490,3 +492,5 @@ var FileChooserDialog = GObject.registerClass({ this.destroy(); } }); + +export default SharePlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/sms.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/sms.js index 5473209..4a359fd 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/sms.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/sms.js @@ -2,19 +2,17 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const PluginBase = imports.service.plugin; -const LegacyMessaging = imports.service.ui.legacyMessaging; -const Messaging = imports.service.ui.messaging; -const URI = imports.service.utils.uri; +import Plugin from '../plugin.js'; +import LegacyMessagingDialog from '../ui/legacyMessaging.js'; +import * as Messaging from '../ui/messaging.js'; +import SmsURI from '../utils/uri.js'; -var Metadata = { +export const Metadata = { label: _('SMS'), description: _('Send and read SMS of the paired device and be notified of new SMS'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.SMS', @@ -85,7 +83,7 @@ var Metadata = { * * TEXT_MESSAGE: Has a "body" field which contains pure, human-readable text */ -var MessageEventType = { +export const MessageEventType = { TEXT_MESSAGE: 0x1, }; @@ -97,7 +95,7 @@ var MessageEventType = { * UNREAD: A message not marked as read * READ: A message marked as read */ -var MessageStatus = { +export const MessageStatus = { UNREAD: 0, READ: 1, }; @@ -117,7 +115,7 @@ var MessageStatus = { * FAILED: Failed outgoing messages * QUEUED: Messages queued to send later */ -var MessageBox = { +export const MessageBox = { ALL: 0, INBOX: 1, SENT: 2, @@ -133,7 +131,7 @@ var MessageBox = { * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/sms * https://github.com/KDE/kdeconnect-android/tree/master/src/org/kde/kdeconnect/Plugins/SMSPlugin/ */ -var Plugin = GObject.registerClass({ +const SMSPlugin = GObject.registerClass({ GTypeName: 'GSConnectSMSPlugin', Properties: { 'threads': GObject.param_spec_variant( @@ -145,7 +143,7 @@ var Plugin = GObject.registerClass({ GObject.ParamFlags.READABLE ), }, -}, class Plugin extends PluginBase.Plugin { +}, class SMSPlugin extends Plugin { _init(device) { super._init(device, 'sms'); @@ -162,7 +160,7 @@ var Plugin = GObject.registerClass({ get window() { if (this.settings.get_boolean('legacy-sms')) { - return new LegacyMessaging.Dialog({ + return new LegacyMessagingDialog({ device: this.device, plugin: this, }); @@ -473,7 +471,7 @@ var Plugin = GObject.registerClass({ */ uriSms(uri) { try { - uri = new URI.SmsURI(uri); + uri = new SmsURI(uri); // Lookup contacts const addresses = uri.recipients.map(number => { @@ -534,3 +532,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default SMSPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/systemvolume.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/systemvolume.js index bf1783c..9db02d1 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/systemvolume.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/systemvolume.js @@ -2,16 +2,14 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import GObject from 'gi://GObject'; -const GObject = imports.gi.GObject; - -const Components = imports.service.components; -const Config = imports.config; -const PluginBase = imports.service.plugin; +import * as Components from '../components/index.js'; +import Config from '../../config.js'; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('System Volume'), description: _('Enable the paired device to control the system volume'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.SystemVolume', @@ -26,9 +24,9 @@ var Metadata = { * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/systemvolume * https://github.com/KDE/kdeconnect-android/tree/master/src/org/kde/kdeconnect/Plugins/SystemvolumePlugin/ */ -var Plugin = GObject.registerClass({ +const SystemVolumePlugin = GObject.registerClass({ GTypeName: 'GSConnectSystemVolumePlugin', -}, class Plugin extends PluginBase.Plugin { +}, class SystemVolumePlugin extends Plugin { _init(device) { super._init(device, 'systemvolume'); @@ -202,3 +200,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default SystemVolumePlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/telephony.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/telephony.js index 9fe683a..af1dae1 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/telephony.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/telephony.js @@ -2,18 +2,16 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import GdkPixbuf from 'gi://GdkPixbuf'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; -const GdkPixbuf = imports.gi.GdkPixbuf; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; - -const Components = imports.service.components; -const PluginBase = imports.service.plugin; +import * as Components from '../components/index.js'; +import Plugin from '../plugin.js'; -var Metadata = { +export const Metadata = { label: _('Telephony'), description: _('Be notified about calls and adjust system volume during ringing/ongoing calls'), id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.Telephony', @@ -43,9 +41,9 @@ var Metadata = { * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/telephony * https://github.com/KDE/kdeconnect-android/tree/master/src/org/kde/kdeconnect/Plugins/TelephonyPlugin */ -var Plugin = GObject.registerClass({ +const TelephonyPlugin = GObject.registerClass({ GTypeName: 'GSConnectTelephonyPlugin', -}, class Plugin extends PluginBase.Plugin { +}, class TelephonyPlugin extends Plugin { _init(device) { super._init(device, 'telephony'); @@ -243,3 +241,5 @@ var Plugin = GObject.registerClass({ super.destroy(); } }); + +export default TelephonyPlugin; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/contacts.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/contacts.js index 090eac5..3ead960 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/contacts.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/contacts.js @@ -2,13 +2,13 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gdk from 'gi://Gdk'; +import GdkPixbuf from 'gi://GdkPixbuf'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; -const Gdk = imports.gi.Gdk; -const GdkPixbuf = imports.gi.GdkPixbuf; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; +import system from 'system'; /** @@ -156,7 +156,7 @@ function getNumberTypeLabel(type) { * @param {string} address - A phone number * @return {string} A (possibly) better display number for the address */ -function getDisplayNumber(contact, address) { +export function getDisplayNumber(contact, address) { const number = address.toPhoneNumber(); for (const contactNumber of contact.numbers) { @@ -175,7 +175,7 @@ function getDisplayNumber(contact, address) { */ const AvatarCache = new WeakMap(); -var Avatar = GObject.registerClass({ +export const Avatar = GObject.registerClass({ GTypeName: 'GSConnectContactAvatar', }, class ContactAvatar extends Gtk.DrawingArea { @@ -363,7 +363,7 @@ const AddressRow = GObject.registerClass({ /** * A widget for selecting contact addresses (usually phone numbers) */ -var ContactChooser = GObject.registerClass({ +export const ContactChooser = GObject.registerClass({ GTypeName: 'GSConnectContactChooser', Properties: { 'device': GObject.ParamSpec.object( @@ -435,7 +435,7 @@ var ContactChooser = GObject.registerClass({ for (let i = 0, len = rows.length; i < len; i++) { rows[i].destroy(); // HACK: temporary mitigator for mysterious GtkListBox leak - imports.system.gc(); + system.gc(); } } @@ -482,7 +482,7 @@ var ContactChooser = GObject.registerClass({ if (row.contact.id === id) { row.destroy(); // HACK: temporary mitigator for mysterious GtkListBox leak - imports.system.gc(); + system.gc(); } } } diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/legacyMessaging.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/legacyMessaging.js index dd4fde6..bda1ab3 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/legacyMessaging.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/legacyMessaging.js @@ -2,19 +2,17 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; -const Gio = imports.gi.Gio; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; - -const Contacts = imports.service.ui.contacts; -const Messaging = imports.service.ui.messaging; -const URI = imports.service.utils.uri; -const _ui = imports.service.utils.ui; +import * as Contacts from '../ui/contacts.js'; +import * as Messaging from '../ui/messaging.js'; +import * as URI from '../utils/uri.js'; +import '../utils/ui.js'; -var Dialog = GObject.registerClass({ +const Dialog = GObject.registerClass({ GTypeName: 'GSConnectLegacyMessagingDialog', Properties: { 'device': GObject.ParamSpec.object( @@ -226,3 +224,4 @@ var Dialog = GObject.registerClass({ } }); +export default Dialog; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/messaging.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/messaging.js index 60c0376..6f53584 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/messaging.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/messaging.js @@ -2,21 +2,21 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gdk from 'gi://Gdk'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import Pango from 'gi://Pango'; + +import system from 'system'; + +import * as Contacts from './contacts.js'; +import * as Sms from '../plugins/sms.js'; +import * as URI from '../utils/uri.js'; +import '../utils/ui.js'; const Tweener = imports.tweener.tweener; -const Gdk = imports.gi.Gdk; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Pango = imports.gi.Pango; - -const Contacts = imports.service.ui.contacts; -const Sms = imports.service.plugins.sms; -const URI = imports.service.utils.uri; -const _ui = imports.service.utils.ui; - /* * Useful time constants @@ -460,7 +460,7 @@ const Conversation = GObject.registerClass({ conversation.list.foreach(message => { // HACK: temporary mitigator for mysterious GtkListBox leak message.destroy(); - imports.system.gc(); + system.gc(); }); } @@ -800,7 +800,7 @@ const ConversationSummary = GObject.registerClass({ /** * A Gtk.ApplicationWindow for SMS conversations */ -var Window = GObject.registerClass({ +export const Window = GObject.registerClass({ GTypeName: 'GSConnectMessagingWindow', Properties: { 'device': GObject.ParamSpec.object( @@ -1025,13 +1025,13 @@ var Window = GObject.registerClass({ if (conversation) { conversation.destroy(); - imports.system.gc(); + system.gc(); } // Then the summary widget row.destroy(); // HACK: temporary mitigator for mysterious GtkListBox leak - imports.system.gc(); + system.gc(); } } @@ -1219,7 +1219,7 @@ var Window = GObject.registerClass({ /** * A Gtk.ApplicationWindow for selecting from open conversations */ -var ConversationChooser = GObject.registerClass({ +export const ConversationChooser = GObject.registerClass({ GTypeName: 'GSConnectConversationChooser', Properties: { 'device': GObject.ParamSpec.object( diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/mousepad.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/mousepad.js index 3ef0fef..5c28603 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/mousepad.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/mousepad.js @@ -2,12 +2,10 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const GLib = imports.gi.GLib; -const Gdk = imports.gi.Gdk; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; +import GLib from 'gi://GLib'; +import Gdk from 'gi://Gdk'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; /** @@ -73,7 +71,7 @@ const isShift = (key) => [Gdk.KEY_Shift_L, Gdk.KEY_Shift_R].includes(key); const isSuper = (key) => [Gdk.KEY_Super_L, Gdk.KEY_Super_R].includes(key); -var InputDialog = GObject.registerClass({ +export const InputDialog = GObject.registerClass({ GTypeName: 'GSConnectMousepadInputDialog', Properties: { 'device': GObject.ParamSpec.object( @@ -390,7 +388,7 @@ var InputDialog = GObject.registerClass({ (Math.abs(this.touchpad_motion_y) < 4); if (is_click) { - var click_body = {}; + const click_body = {}; switch (gesture_button) { case 1: click_body.singleclick = true; @@ -444,8 +442,8 @@ var InputDialog = GObject.registerClass({ } _onTouchpadMotionTimeout() { - var diff_x = this.touchpad_motion_x - this.touchpad_motion_prev_x; - var diff_y = this.touchpad_motion_y - this.touchpad_motion_prev_y; + const diff_x = this.touchpad_motion_x - this.touchpad_motion_prev_x; + const diff_y = this.touchpad_motion_y - this.touchpad_motion_prev_y; this.device.sendPacket({ type: 'kdeconnect.mousepad.request', diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/notification.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/notification.js index 8cffda1..654e465 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/notification.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/notification.js @@ -2,20 +2,18 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gio from 'gi://Gio'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; -const Gio = imports.gi.Gio; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; - -const URI = imports.service.utils.uri; -const _ui = imports.service.utils.ui; +import * as URI from '../utils/uri.js'; +import '../utils/ui.js'; /** * A dialog for repliable notifications. */ -var ReplyDialog = GObject.registerClass({ +const ReplyDialog = GObject.registerClass({ GTypeName: 'GSConnectNotificationReplyDialog', Properties: { 'device': GObject.ParamSpec.object( @@ -177,3 +175,4 @@ var ReplyDialog = GObject.registerClass({ } }); +export default ReplyDialog; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/service.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/service.js index a3dd81a..b84bb3d 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/service.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/ui/service.js @@ -2,14 +2,14 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import GLib from 'gi://GLib'; +import Gio from 'gi://Gio'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; -const GLib = imports.gi.GLib; -const Gio = imports.gi.Gio; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; +import system from 'system'; -const Config = imports.config; +import Config from '../../config.js'; /* @@ -17,7 +17,7 @@ const Config = imports.config; */ const ISSUE_HEADER = ` GSConnect: ${Config.PACKAGE_VERSION} (${Config.IS_USER ? 'user' : 'system'}) -GJS: ${imports.system.version} +GJS: ${system.version} Session: ${GLib.getenv('XDG_SESSION_TYPE')} OS: ${GLib.get_os_info('PRETTY_NAME')} `; @@ -26,7 +26,7 @@ OS: ${GLib.get_os_info('PRETTY_NAME')} /** * A dialog for selecting a device */ -var DeviceChooser = GObject.registerClass({ +export const DeviceChooser = GObject.registerClass({ GTypeName: 'GSConnectServiceDeviceChooser', Properties: { 'action-name': GObject.ParamSpec.string( @@ -192,7 +192,7 @@ var DeviceChooser = GObject.registerClass({ /** * A dialog for reporting an error. */ -var ErrorDialog = GObject.registerClass({ +export const ErrorDialog = GObject.registerClass({ GTypeName: 'GSConnectServiceErrorDialog', Template: 'resource:///org/gnome/Shell/Extensions/GSConnect/ui/service-error-dialog.ui', Children: [ diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/dbus.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/dbus.js index 954f7ce..f4a9d67 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/dbus.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/dbus.js @@ -2,12 +2,10 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const Gio = imports.gi.Gio; -const GjsPrivate = imports.gi.GjsPrivate; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; +import Gio from 'gi://Gio'; +import GjsPrivate from 'gi://GjsPrivate'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; /* @@ -19,12 +17,6 @@ function toDBusCase(string) { }).replace(/[\s_-]+/g, ''); } -function toHyphenCase(string) { - return string.replace(/(?:[A-Z])/g, (ltr, offset) => { - return (offset > 0) ? `-${ltr.toLowerCase()}` : ltr.toLowerCase(); - }).replace(/[\s_]+/g, ''); -} - function toUnderscoreCase(string) { return string.replace(/(?:^\w|[A-Z]|_|\b\w)/g, (ltr, offset) => { if (ltr === '_') @@ -39,7 +31,7 @@ function toUnderscoreCase(string) { * DBus.Interface represents a DBus interface bound to an object instance, meant * to be exported over DBus. */ -var Interface = GObject.registerClass({ +export const Interface = GObject.registerClass({ GTypeName: 'GSConnectDBusInterface', Implements: [Gio.DBusInterface], Properties: { @@ -241,7 +233,7 @@ var Interface = GObject.registerClass({ * @param {Gio.Cancellable} [cancellable] - an optional Gio.Cancellable * @return {Promise} A new DBus connection */ -function newConnection(busType = Gio.BusType.SESSION, cancellable = null) { +export function newConnection(busType = Gio.BusType.SESSION, cancellable = null) { return new Promise((resolve, reject) => { Gio.DBusConnection.new_for_address( Gio.dbus_address_get_for_bus_sync(busType, cancellable), diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/setup.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/setup.js deleted file mode 100644 index 04449dd..0000000 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/setup.js +++ /dev/null @@ -1,427 +0,0 @@ -// SPDX-FileCopyrightText: GSConnect Developers https://github.com/GSConnect -// -// SPDX-License-Identifier: GPL-2.0-or-later - -'use strict'; - -const Gio = imports.gi.Gio; -const GIRepository = imports.gi.GIRepository; -const GLib = imports.gi.GLib; - -const Config = imports.config; -const {setup, setupGettext} = imports.utils.setup; - - -// Promise Wrappers -try { - const {EBook, EDataServer} = imports.gi; - - Gio._promisify(EBook.BookClient, 'connect'); - Gio._promisify(EBook.BookClient.prototype, 'get_view'); - Gio._promisify(EBook.BookClient.prototype, 'get_contacts'); - Gio._promisify(EDataServer.SourceRegistry, 'new'); -} catch (e) { - // Silence import errors -} - -Gio._promisify(Gio.AsyncInitable.prototype, 'init_async'); -Gio._promisify(Gio.DBusConnection.prototype, 'call'); -Gio._promisify(Gio.DBusProxy.prototype, 'call'); -Gio._promisify(Gio.DataInputStream.prototype, 'read_line_async', - 'read_line_finish_utf8'); -Gio._promisify(Gio.File.prototype, 'delete_async'); -Gio._promisify(Gio.File.prototype, 'enumerate_children_async'); -Gio._promisify(Gio.File.prototype, 'load_contents_async'); -Gio._promisify(Gio.File.prototype, 'mount_enclosing_volume'); -Gio._promisify(Gio.File.prototype, 'query_info_async'); -Gio._promisify(Gio.File.prototype, 'read_async'); -Gio._promisify(Gio.File.prototype, 'replace_async'); -Gio._promisify(Gio.File.prototype, 'replace_contents_bytes_async', - 'replace_contents_finish'); -Gio._promisify(Gio.FileEnumerator.prototype, 'next_files_async'); -Gio._promisify(Gio.Mount.prototype, 'unmount_with_operation'); -Gio._promisify(Gio.InputStream.prototype, 'close_async'); -Gio._promisify(Gio.OutputStream.prototype, 'close_async'); -Gio._promisify(Gio.OutputStream.prototype, 'splice_async'); -Gio._promisify(Gio.OutputStream.prototype, 'write_all_async'); -Gio._promisify(Gio.SocketClient.prototype, 'connect_async'); -Gio._promisify(Gio.SocketListener.prototype, 'accept_async'); -Gio._promisify(Gio.Subprocess.prototype, 'communicate_utf8_async'); -Gio._promisify(Gio.Subprocess.prototype, 'wait_check_async'); -Gio._promisify(Gio.TlsConnection.prototype, 'handshake_async'); -Gio._promisify(Gio.DtlsConnection.prototype, 'handshake_async'); - - -// User Directories -Config.CACHEDIR = GLib.build_filenamev([GLib.get_user_cache_dir(), 'gsconnect']); -Config.CONFIGDIR = GLib.build_filenamev([GLib.get_user_config_dir(), 'gsconnect']); -Config.RUNTIMEDIR = GLib.build_filenamev([GLib.get_user_runtime_dir(), 'gsconnect']); - -// Bootstrap -setup(Config.PACKAGE_DATADIR); -setupGettext(); - -if (Config.IS_USER) { - // Infer libdir by assuming gnome-shell shares a common prefix with gjs; - // assume the parent directory if it's not there - let libdir = GIRepository.Repository.get_search_path().find(path => { - return path.endsWith('/gjs/girepository-1.0'); - }).replace('/gjs/girepository-1.0', ''); - - const gsdir = GLib.build_filenamev([libdir, 'gnome-shell']); - - if (!GLib.file_test(gsdir, GLib.FileTest.IS_DIR)) { - const currentDir = `/${GLib.path_get_basename(libdir)}`; - libdir = libdir.replace(currentDir, ''); - } - - Config.GNOME_SHELL_LIBDIR = libdir; -} - - -// Load DBus interfaces -Config.DBUS = (() => { - const bytes = Gio.resources_lookup_data( - GLib.build_filenamev([Config.APP_PATH, `${Config.APP_ID}.xml`]), - Gio.ResourceLookupFlags.NONE - ); - - const xml = new TextDecoder().decode(bytes.toArray()); - const dbus = Gio.DBusNodeInfo.new_for_xml(xml); - dbus.nodes.forEach(info => info.cache_build()); - - return dbus; -})(); - - -// Init User Directories -for (const path of [Config.CACHEDIR, Config.CONFIGDIR, Config.RUNTIMEDIR]) - GLib.mkdir_with_parents(path, 0o755); - - -globalThis.HAVE_GNOME = GLib.getenv('GSCONNECT_MODE')?.toLowerCase() !== 'cli' && (GLib.getenv('GNOME_SETUP_DISPLAY') !== null || GLib.getenv('XDG_CURRENT_DESKTOP')?.toUpperCase()?.includes('GNOME') || GLib.getenv('XDG_SESSION_DESKTOP')?.toLowerCase() === 'gnome'); - - -/** - * A custom debug function that logs at LEVEL_MESSAGE to avoid the need for env - * variables to be set. - * - * @param {Error|string} message - A string or Error to log - * @param {string} [prefix] - An optional prefix for the warning - */ -const _debugCallerMatch = new RegExp(/([^@]*)@([^:]*):([^:]*)/); -// eslint-disable-next-line func-style -const _debugFunc = function (error, prefix = null) { - let caller, message; - - if (error.stack) { - caller = error.stack.split('\n')[0]; - message = `${error.message}\n${error.stack}`; - } else { - caller = (new Error()).stack.split('\n')[1]; - message = JSON.stringify(error, null, 2); - } - - if (prefix) - message = `${prefix}: ${message}`; - - const [, func, file, line] = _debugCallerMatch.exec(caller); - const script = file.replace(Config.PACKAGE_DATADIR, ''); - - GLib.log_structured('GSConnect', GLib.LogLevelFlags.LEVEL_MESSAGE, { - 'MESSAGE': `[${script}:${func}:${line}]: ${message}`, - 'SYSLOG_IDENTIFIER': 'org.gnome.Shell.Extensions.GSConnect', - 'CODE_FILE': file, - 'CODE_FUNC': func, - 'CODE_LINE': line, - }); -}; - -// Swap the function out for a no-op anonymous function for speed -const settings = new Gio.Settings({ - settings_schema: Config.GSCHEMA.lookup(Config.APP_ID, true), -}); - -settings.connect('changed::debug', (settings, key) => { - globalThis.debug = settings.get_boolean(key) ? _debugFunc : () => {}; -}); - -if (settings.get_boolean('debug')) - globalThis.debug = _debugFunc; -else - globalThis.debug = () => {}; - - -/** - * Start wl_clipboard if not under Gnome - */ -if (!globalThis.HAVE_GNOME) { - debug('Not running as a Gnome extension'); - imports.wl_clipboard.watchService(); -} - - -/** - * A simple (for now) pre-comparison sanitizer for phone numbers - * See: https://github.com/KDE/kdeconnect-kde/blob/master/smsapp/conversationlistmodel.cpp#L200-L210 - * - * @return {string} Return the string stripped of leading 0, and ' ()-+' - */ -String.prototype.toPhoneNumber = function () { - const strippedNumber = this.replace(/^0*|[ ()+-]/g, ''); - - if (strippedNumber.length) - return strippedNumber; - - return this; -}; - - -/** - * A simple equality check for phone numbers based on `toPhoneNumber()` - * - * @param {string} number - A phone number string to compare - * @return {boolean} If `this` and @number are equivalent phone numbers - */ -String.prototype.equalsPhoneNumber = function (number) { - const a = this.toPhoneNumber(); - const b = number.toPhoneNumber(); - - return (a.length && b.length && (a.endsWith(b) || b.endsWith(a))); -}; - - -/** - * An implementation of `rm -rf` in Gio - * - * @param {Gio.File|string} file - a GFile or filepath - */ -Gio.File.rm_rf = function (file) { - try { - if (typeof file === 'string') - file = Gio.File.new_for_path(file); - - try { - const iter = file.enumerate_children( - 'standard::name', - Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, - null - ); - - let info; - - while ((info = iter.next_file(null))) - Gio.File.rm_rf(iter.get_child(info)); - - iter.close(null); - } catch (e) { - // Silence errors - } - - file.delete(null); - } catch (e) { - // Silence errors - } -}; - - -/** - * Extend GLib.Variant with a static method to recursively pack a variant - * - * @param {*} [obj] - May be a GLib.Variant, Array, standard Object or literal. - * @return {GLib.Variant} The resulting GVariant - */ -function _full_pack(obj) { - let packed; - const type = typeof obj; - - switch (true) { - case (obj instanceof GLib.Variant): - return obj; - - case (type === 'string'): - return GLib.Variant.new('s', obj); - - case (type === 'number'): - return GLib.Variant.new('d', obj); - - case (type === 'boolean'): - return GLib.Variant.new('b', obj); - - case (obj instanceof Uint8Array): - return GLib.Variant.new('ay', obj); - - case (obj === null): - return GLib.Variant.new('mv', null); - - case (typeof obj.map === 'function'): - return GLib.Variant.new( - 'av', - obj.filter(e => e !== undefined).map(e => _full_pack(e)) - ); - - case (obj instanceof Gio.Icon): - return obj.serialize(); - - case (type === 'object'): - packed = {}; - - for (const [key, val] of Object.entries(obj)) { - if (val !== undefined) - packed[key] = _full_pack(val); - } - - return GLib.Variant.new('a{sv}', packed); - - default: - throw Error(`Unsupported type '${type}': ${obj}`); - } -} - -GLib.Variant.full_pack = _full_pack; - - -/** - * Extend GLib.Variant with a method to recursively deepUnpack() a variant - * - * @param {*} [obj] - May be a GLib.Variant, Array, standard Object or literal. - * @return {*} The resulting object - */ -function _full_unpack(obj) { - obj = (obj === undefined) ? this : obj; - const unpacked = {}; - - switch (true) { - case (obj === null): - return obj; - - case (obj instanceof GLib.Variant): - return _full_unpack(obj.deepUnpack()); - - case (obj instanceof Uint8Array): - return obj; - - case (typeof obj.map === 'function'): - return obj.map(e => _full_unpack(e)); - - case (typeof obj === 'object'): - for (const [key, value] of Object.entries(obj)) { - // Try to detect and deserialize GIcons - try { - if (key === 'icon' && value.get_type_string() === '(sv)') - unpacked[key] = Gio.Icon.deserialize(value); - else - unpacked[key] = _full_unpack(value); - } catch (e) { - unpacked[key] = _full_unpack(value); - } - } - - return unpacked; - - default: - return obj; - } -} - -GLib.Variant.prototype.full_unpack = _full_unpack; - - -/** - * Creates a GTlsCertificate from the PEM-encoded data in @cert_path and - * @key_path. If either are missing a new pair will be generated. - * - * Additionally, the private key will be added using ssh-add to allow sftp - * connections using Gio. - * - * See: https://github.com/KDE/kdeconnect-kde/blob/master/core/kdeconnectconfig.cpp#L119 - * - * @param {string} certPath - Absolute path to a x509 certificate in PEM format - * @param {string} keyPath - Absolute path to a private key in PEM format - * @param {string} commonName - A unique common name for the certificate - * @return {Gio.TlsCertificate} A TLS certificate - */ -Gio.TlsCertificate.new_for_paths = function (certPath, keyPath, commonName = null) { - // Check if the certificate/key pair already exists - const certExists = GLib.file_test(certPath, GLib.FileTest.EXISTS); - const keyExists = GLib.file_test(keyPath, GLib.FileTest.EXISTS); - - // Create a new certificate and private key if necessary - if (!certExists || !keyExists) { - // If we weren't passed a common name, generate a random one - if (!commonName) - commonName = GLib.uuid_string_random(); - - const proc = new Gio.Subprocess({ - argv: [ - Config.OPENSSL_PATH, 'req', - '-new', '-x509', '-sha256', - '-out', certPath, - '-newkey', 'rsa:4096', '-nodes', - '-keyout', keyPath, - '-days', '3650', - '-subj', `/O=andyholmes.github.io/OU=GSConnect/CN=${commonName}`, - ], - flags: (Gio.SubprocessFlags.STDOUT_SILENCE | - Gio.SubprocessFlags.STDERR_SILENCE), - }); - proc.init(null); - proc.wait_check(null); - } - - return Gio.TlsCertificate.new_from_files(certPath, keyPath); -}; - -Object.defineProperties(Gio.TlsCertificate.prototype, { - /** - * The common name of the certificate. - */ - 'common_name': { - get: function () { - if (!this.__common_name) { - const proc = new Gio.Subprocess({ - argv: [Config.OPENSSL_PATH, 'x509', '-noout', '-subject', '-inform', 'pem'], - flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE, - }); - proc.init(null); - - const stdout = proc.communicate_utf8(this.certificate_pem, null)[1]; - this.__common_name = /(?:cn|CN) ?= ?([^,\n]*)/.exec(stdout)[1]; - } - - return this.__common_name; - }, - configurable: true, - enumerable: true, - }, - - /** - * Get just the pubkey as a DER ByteArray of a certificate. - * - * @return {GLib.Bytes} The pubkey as DER of the certificate. - */ - 'pubkey_der': { - value: function () { - if (!this.__pubkey_der) { - let proc = new Gio.Subprocess({ - argv: [Config.OPENSSL_PATH, 'x509', '-noout', '-pubkey', '-inform', 'pem'], - flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE, - }); - proc.init(null); - - const pubkey = proc.communicate_utf8(this.certificate_pem, null)[1]; - proc = new Gio.Subprocess({ - argv: [Config.OPENSSL_PATH, 'pkey', '-pubin', '-inform', 'pem', '-outform', 'der'], - flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE, - }); - proc.init(null); - this.__pubkey_der = proc.communicate(new TextEncoder().encode(pubkey), null)[1]; - } - - return this.__pubkey_der; - }, - configurable: true, - enumerable: false, - }, - -}); diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/ui.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/ui.js index 35922d3..d0f31aa 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/ui.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/ui.js @@ -2,14 +2,12 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; +import Gdk from 'gi://Gdk'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import Gtk from 'gi://Gtk'; -const Gdk = imports.gi.Gdk; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const Gtk = imports.gi.Gtk; - -const Config = imports.config; +import Config from '../../config.js'; /* diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/uri.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/uri.js index 6104ed9..e7fca2c 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/uri.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/utils/uri.js @@ -2,9 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const GLib = imports.gi.GLib; +import GLib from 'gi://GLib'; /** @@ -83,7 +81,7 @@ const _numberRegex = new RegExp( * @param {string} str - the string to search * @return {Object[]} the list of match objects, as described above */ -function findUrls(str) { +export function findUrls(str) { _urlRegexp.lastIndex = 0; const res = []; @@ -107,7 +105,7 @@ function findUrls(str) { * @param {string} [title] - An optional title (eg. alt text, tooltip) * @return {string} the modified text */ -function linkify(str, title = null) { +export function linkify(str, title = null) { const text = GLib.markup_escape_text(str, -1); _urlRegexp.lastIndex = 0; @@ -126,7 +124,7 @@ function linkify(str, title = null) { /** * A simple parsing class for sms: URI's (https://tools.ietf.org/html/rfc5724) */ -var SmsURI = class URI { +export default class URI { constructor(uri) { _smsRegex.lastIndex = 0; const [, recipients, query] = _smsRegex.exec(uri); @@ -167,5 +165,5 @@ var SmsURI = class URI { return this.body ? `${uri}?body=${escape(this.body)}` : uri; } -}; +} diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/input.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/input.js index 86fea67..b2ef07e 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/input.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/input.js @@ -4,7 +4,7 @@ import Gio from 'gi://Gio'; -import Config from '../config.mjs'; +import Config from '../config.js'; export class LockscreenRemoteAccess { diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/notification.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/notification.js index 78b7f54..a6940d2 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/notification.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/notification.js @@ -239,19 +239,20 @@ const Source = GObject.registerClass({ if (cachedNotification) { cachedNotification.requestReplyId = requestReplyId; - // Bail early If @notificationParams represents an exact repeat const title = notification.title; const body = notification.body ? notification.body : null; + // Bail early If @notification represents an exact repeat if (cachedNotification.title === title && cachedNotification.body === body) return cachedNotification; + // If the details have changed, flag as an update cachedNotification.title = title; cachedNotification.body = body; - + cachedNotification.acknowledged = false; return cachedNotification; } @@ -304,10 +305,8 @@ const Source = GObject.registerClass({ * notification limit (3) */ _addNotificationToMessageTray(notification) { - if (this.notifications.includes(notification)) { - notification.acknowledged = false; + if (this.notifications.includes(notification)) return; - } while (this.notifications.length >= 10) { const [oldest] = this.notifications; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/tooltip.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/tooltip.js index 2996ce8..319621d 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/tooltip.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/tooltip.js @@ -170,8 +170,7 @@ export default class Tooltip { this._bin.child.add_child(this.label); } - Main.layoutManager.uiGroup.add_child(this._bin); - Main.layoutManager.uiGroup.set_child_above_sibling(this._bin, null); + Main.layoutManager.addTopChrome(this._bin); } else if (this.custom) { this._bin.child = this.custom; } else { @@ -234,7 +233,7 @@ export default class Tooltip { time: 0.10, transition: Clutter.AnimationMode.EASE_OUT_QUAD, onComplete: () => { - Main.layoutManager.uiGroup.remove_actor(this._bin); + Main.layoutManager.removeChrome(this._bin); if (this.custom) this._bin.remove_child(this.custom); @@ -291,7 +290,7 @@ export default class Tooltip { this.custom.destroy(); if (this._bin) { - Main.layoutManager.uiGroup.remove_actor(this._bin); + Main.layoutManager.removeChrome(this._bin); this._bin.destroy(); } @@ -306,4 +305,3 @@ export default class Tooltip { } } } - diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/utils.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/utils.js index 8db091f..beea462 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/utils.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/shell/utils.js @@ -6,7 +6,7 @@ import Gio from 'gi://Gio'; import GLib from 'gi://GLib'; import Gtk from 'gi://Gtk'; -import Config from '../config.mjs'; +import Config from '../config.js'; let St = null; // St is not available for prefs.js importing this file. try { diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/remote.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/remote.js index 232dc8c..44760cd 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/remote.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/remote.js @@ -2,16 +2,13 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; const SERVICE_NAME = 'org.gnome.Shell.Extensions.GSConnect'; const SERVICE_PATH = '/org/gnome/Shell/Extensions/GSConnect'; const DEVICE_NAME = 'org.gnome.Shell.Extensions.GSConnect.Device'; -const DEVICE_PATH = '/org/gnome/Shell/Extensions/GSConnect/Device'; const _PROPERTIES = { @@ -51,7 +48,7 @@ function _proxyInit(proxy, cancellable = null) { /** * A simple proxy wrapper for devices exported over DBus. */ -var Device = GObject.registerClass({ +export const Device = GObject.registerClass({ GTypeName: 'GSConnectRemoteDevice', Implements: [Gio.DBusInterface], Properties: { @@ -222,7 +219,7 @@ var Device = GObject.registerClass({ /** * A simple proxy wrapper for the GSConnect service. */ -var Service = GObject.registerClass({ +export const Service = GObject.registerClass({ GTypeName: 'GSConnectRemoteService', Implements: [Gio.DBusInterface], Properties: { diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/remote.mjs b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/remote.mjs deleted file mode 100644 index 90eb351..0000000 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/remote.mjs +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: GSConnect Developers https://github.com/GSConnect -// -// SPDX-License-Identifier: GPL-2.0-or-later - -import GLib from 'gi://GLib'; - -const [filename] = GLib.filename_from_uri(import.meta.url); -const dirname = GLib.path_get_dirname(filename); -imports.searchPath.unshift(dirname); - -const Remote = imports.remote; -export default Remote; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/setup.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/setup.js index d17963d..eef58dc 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/setup.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/setup.js @@ -2,18 +2,18 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; -const Gettext = imports.gettext; +import Gettext from 'gettext'; -const Config = imports.config; +import Config from '../config.js'; /** * Initialise and setup Gettext. */ -function setupGettext() { +export function setupGettext() { // Init Gettext String.prototype.format = imports.format.format; Gettext.bindtextdomain(Config.APP_ID, Config.PACKAGE_LOCALEDIR); @@ -25,7 +25,7 @@ function setupGettext() { * Initialise and setup Config, GResources and GSchema. * @param {string} extensionPath - The absolute path to the extension directory */ -function setup(extensionPath) { +export default function setup(extensionPath) { // Ensure config.js is setup properly Config.PACKAGE_DATADIR = extensionPath; const userDir = GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell']); diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/setup.mjs b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/setup.mjs deleted file mode 100644 index 7a14f19..0000000 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/utils/setup.mjs +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: GSConnect Developers https://github.com/GSConnect -// -// SPDX-License-Identifier: GPL-2.0-or-later - -import GLib from 'gi://GLib'; - -const [filename] = GLib.filename_from_uri(import.meta.url); -const dirname = GLib.path_get_dirname(filename); -imports.searchPath.unshift(dirname); - -export const {setup, setupGettext} = imports.setup; -export default setup; diff --git a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/wl_clipboard.js b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/wl_clipboard.js index 2a11de5..8e1dedd 100644 --- a/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/wl_clipboard.js +++ b/gnome/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/wl_clipboard.js @@ -2,12 +2,10 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -'use strict'; - -const Gio = imports.gi.Gio; -const GjsPrivate = imports.gi.GjsPrivate; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; +import Gio from 'gi://Gio'; +import GjsPrivate from 'gi://GjsPrivate'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; // laucher for wl-clipboard const launcher = new Gio.SubprocessLauncher({ @@ -55,7 +53,7 @@ const TEXT_MIMETYPES = [ * A simple clipboard portal, especially useful on Wayland where GtkClipboard * doesn't work in the background. */ -var Clipboard = GObject.registerClass( +export const Clipboard = GObject.registerClass( { GTypeName: 'GSConnectShellClipboard', }, @@ -258,13 +256,13 @@ var Clipboard = GObject.registerClass( } ); -var _portal = null; -var _portalId = 0; +let _portal = null; +let _portalId = 0; /** * Watch for the service to start and export the clipboard portal when it does. */ -function watchService() { +export function watchService() { if (_portalId > 0) return; @@ -288,7 +286,7 @@ function watchService() { /** * Stop watching the service and export the portal if currently running. */ -function unwatchService() { +export function unwatchService() { if (_portalId > 0) { Gio.bus_unwatch_name(_portalId); _portalId = 0; diff --git a/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/extension.js b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/extension.js new file mode 100644 index 0000000..61ed3e6 --- /dev/null +++ b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/extension.js @@ -0,0 +1,52 @@ +import St from 'gi://St'; +const DEFAULT_SPEED = 0.75; +import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js'; +import * as Settings from './settings.js'; + +function LOG(m){ + console.log("[impatience] " + m); +}; + +var noop = function() {}; + +export default class Impatience extends Extension { + constructor(metadata) { + super(metadata); + this.enabled = false; + this.original_speed = St.Settings.get().slow_down_factor; + this.modified_speed = DEFAULT_SPEED; + this.unbind = noop; + }; + + enable() { + this.enabled = true; + var pref = (new Settings.Prefs(this)).SPEED; + LOG("enabled"); + var binding = pref.changed(() => { + this.set_speed(pref.get()); + }); + this.unbind = () => { + pref.disconnect(binding); + this.unbind = noop; + }; + this.set_speed(pref.get()); + }; + + disable() { + this.enabled = false; + this.unbind(); + St.Settings.get().slow_down_factor = this.original_speed; + }; + + set_speed(new_speed) { + if(!this.enabled) { + LOG("NOT setting new speed, since the extension is disabled."); + return; + } + if(new_speed !== undefined) { + this.modified_speed = new_speed; + } + LOG("setting new speed: " + this.modified_speed); + St.Settings.get().slow_down_factor = this.modified_speed; + }; +} diff --git a/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/metadata.json b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/metadata.json new file mode 100644 index 0000000..66f450c --- /dev/null +++ b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/metadata.json @@ -0,0 +1,14 @@ +{ + "_generated": "Generated by SweetTooth, do not edit", + "description": "Speed up the gnome-shell animation speed", + "name": "Impatience", + "settings-schema": "org.gnome.shell.extensions.net.gfxmonk.impatience", + "shell-version": [ + "45", + "46", + "47" + ], + "url": "http://gfxmonk.net/dist/0install/gnome-shell-impatience.xml", + "uuid": "impatience@gfxmonk.net", + "version": 27 +} \ No newline at end of file diff --git a/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/prefs.js b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/prefs.js new file mode 100644 index 0000000..e55867a --- /dev/null +++ b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/prefs.js @@ -0,0 +1,61 @@ +import Gtk from 'gi://Gtk'; + +import { ExtensionPreferences } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; +import * as Settings from './settings.js'; + +export default class ImpatiencePrefs extends ExtensionPreferences { + getPreferencesWidget() { + let config = new Settings.Prefs(this); + let frame = new Gtk.Box({ + orientation: Gtk.Orientation.VERTICAL, + 'margin-top': 20, + 'margin-bottom': 20, + 'margin-start': 20, + 'margin-end': 20 + }); + + (function() { + let hbox = new Gtk.Box({ + orientation: Gtk.Orientation.HORIZONTAL, + spacing: 20 + }); + + let label = new Gtk.Label({ + label: "Speed scaling\n(1 = normal, 0.5 = twice as fast)", + use_markup: true, + }); + let adjustment = new Gtk.Adjustment({ + lower: 0, + upper: 2, + step_increment: 0.05 + }); + let scale = new Gtk.Scale({ + orientation: Gtk.Orientation.HORIZONTAL, + digits:2, + adjustment: adjustment, + hexpand: true, + value_pos: Gtk.PositionType.RIGHT + }); + + hbox.append(label); + hbox.append(scale); + frame.append(hbox); + + var pref = config.SPEED; + scale.set_value(pref.get()); + [0.25, 0.5, 1.0, 2.0].forEach( + mark => scale.add_mark(mark, Gtk.PositionType.TOP, "" + mark + "") + ); + scale.connect('value-changed', function(sw) { + var oldval = pref.get(); + var newval = sw.get_value(); + if (newval != pref.get()) { + pref.set(newval); + } + }); + })(); + + frame.show(); + return frame; + } +} diff --git a/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/schemas/gschemas.compiled b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/schemas/gschemas.compiled new file mode 100644 index 0000000000000000000000000000000000000000..8be15e0d5016b23928fd4e5b2b23b0970294a322 GIT binary patch literal 332 zcmYL@Jqp4=5QWFTN(&poBgDd8Jb|5Bq!tUCpkop=yOJzoqlG81^E#eJEIfdnzR5-$ z7~W%kzv(>6)5tigq7PkoAJl(EXsbu`LHJ%+&MZ;?G;a?X6F;IEU7;^z4QcaO#l~i= ziiCGN#Ye}cNUbT9VW;BFF|%f?(rh2Ol+B8!@u*<3nA&oKq-fx`d97f1tIm(aR|)_-UXXk9_; KKeWbSzx)NU7fqW0 literal 0 HcmV?d00001 diff --git a/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/schemas/org.gnome.shell.extensions.net.gfxmonk.impatience.gschema.xml b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/schemas/org.gnome.shell.extensions.net.gfxmonk.impatience.gschema.xml new file mode 100644 index 0000000..ffd0c93 --- /dev/null +++ b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/schemas/org.gnome.shell.extensions.net.gfxmonk.impatience.gschema.xml @@ -0,0 +1,10 @@ + + + + + 0.75 + speed factor + + + + diff --git a/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/settings.js b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/settings.js new file mode 100644 index 0000000..5f25f97 --- /dev/null +++ b/gnome/.local/share/gnome-shell/extensions/impatience@gfxmonk.net/settings.js @@ -0,0 +1,10 @@ +export function Prefs(extension) { + var settings = this.settings = extension.getSettings(); + this.SPEED = { + key: 'speed-factor', + get: function() { return settings.get_double(this.key); }, + set: function(v) { settings.set_double(this.key, v); }, + changed: function(cb) { return settings.connect('changed::' + this.key, cb); }, + disconnect: function() { return settings.disconnect.apply(settings, arguments); }, + }; +};