From 83c0e3b598a0cfa8b13625473341f6ff540c5199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Thu, 10 Feb 2022 10:22:26 +0100 Subject: [PATCH 1/5] Remove unfinished web application It used Broadway as an easy "reuse the same code into web application" way for me, but Broadway is not very good for this. This feature should be made using some better dedicated framework for building websites (so it can work better and support different screen sizes). All the WebSocket functionality needed for this will remain (and be documented at a later point when expanded and stable), so if anyone would like to make such remote controlling app, will be free to do so (outside of Clapper code). --- bin/com.github.rafostar.Clapper.in | 2 +- bin/meson.build | 34 +++++------ src/appRemote.js | 25 --------- src/daemon.js | 70 ----------------------- src/headerbarRemote.js | 22 -------- src/mainDaemon.js | 6 -- src/mainRemote.js | 19 ------- src/player.js | 17 ------ src/playerRemote.js | 51 ----------------- src/webApp.js | 51 ----------------- src/webClient.js | 90 ------------------------------ src/widgetRemote.js | 72 ------------------------ ui/preferences-window.ui | 14 ----- 13 files changed, 15 insertions(+), 458 deletions(-) delete mode 100644 src/appRemote.js delete mode 100644 src/daemon.js delete mode 100644 src/headerbarRemote.js delete mode 100644 src/mainDaemon.js delete mode 100644 src/mainRemote.js delete mode 100644 src/playerRemote.js delete mode 100644 src/webApp.js delete mode 100644 src/webClient.js delete mode 100644 src/widgetRemote.js diff --git a/bin/com.github.rafostar.Clapper.in b/bin/com.github.rafostar.Clapper.in index 8be8c25d..c0c65aab 100644 --- a/bin/com.github.rafostar.Clapper.in +++ b/bin/com.github.rafostar.Clapper.in @@ -6,4 +6,4 @@ imports.package.init({ prefix: '@prefix@', libdir: '@libdir@', }); -imports.package.run(imports.src.main@ID_POSTFIX@); +imports.package.run(imports.src.main); diff --git a/bin/meson.build b/bin/meson.build index fe78611c..03558745 100644 --- a/bin/meson.build +++ b/bin/meson.build @@ -1,25 +1,19 @@ -clapper_apps = ['', 'Remote', 'Daemon'] +bin_conf = configuration_data() -foreach id_postfix : clapper_apps - app_postfix = (id_postfix != '') ? '.' + id_postfix : '' +bin_conf.set('GJS', find_program('gjs').path()) +bin_conf.set('PACKAGE_NAME', meson.project_name()) +bin_conf.set('PACKAGE_VERSION', meson.project_version()) +bin_conf.set('prefix', get_option('prefix')) +bin_conf.set('libdir', libdir) - bin_conf = configuration_data() - bin_conf.set('GJS', find_program('gjs').path()) - bin_conf.set('PACKAGE_NAME', meson.project_name()) - bin_conf.set('PACKAGE_VERSION', meson.project_version()) - bin_conf.set('ID_POSTFIX', id_postfix) - bin_conf.set('prefix', get_option('prefix')) - bin_conf.set('libdir', libdir) - - configure_file( - input: 'com.github.rafostar.Clapper.in', - output: 'com.github.rafostar.Clapper' + app_postfix, - configuration: bin_conf, - install: true, - install_dir: bindir, - install_mode: 'rwxr-xr-x' - ) -endforeach +configure_file( + input: 'com.github.rafostar.Clapper.in', + output: 'com.github.rafostar.Clapper', + configuration: bin_conf, + install: true, + install_dir: bindir, + install_mode: 'rwxr-xr-x' +) clapper_symlink_cmd = 'ln -fs @0@ $DESTDIR@1@'.format( 'com.github.rafostar.Clapper', diff --git a/src/appRemote.js b/src/appRemote.js deleted file mode 100644 index 80f0ba7f..00000000 --- a/src/appRemote.js +++ /dev/null @@ -1,25 +0,0 @@ -const { GObject } = imports.gi; -const { AppBase } = imports.src.appBase; -const { HeaderBarRemote } = imports.src.headerbarRemote; -const { WidgetRemote } = imports.src.widgetRemote; - -var AppRemote = GObject.registerClass({ - GTypeName: 'ClapperAppRemote', -}, -class ClapperAppRemote extends AppBase -{ - vfunc_startup() - { - super.vfunc_startup(); - - const window = this.active_window; - - const clapperWidget = new WidgetRemote(); - window.set_child(clapperWidget); - - const headerBar = new HeaderBarRemote(); - window.set_titlebar(headerBar); - - window.maximize(); - } -}); diff --git a/src/daemon.js b/src/daemon.js deleted file mode 100644 index e8b5cd42..00000000 --- a/src/daemon.js +++ /dev/null @@ -1,70 +0,0 @@ -const { Gio, GLib, GObject } = imports.gi; -const Debug = imports.src.debug; - -const { debug } = Debug; - -var Daemon = GObject.registerClass({ - GTypeName: 'ClapperDaemon', -}, -class ClapperDaemon extends Gio.SubprocessLauncher -{ - _init() - { - const port = ARGV[0] || 8080; - - /* FIXME: show output when debugging is on */ - const flags = Gio.SubprocessFlags.STDOUT_SILENCE - | Gio.SubprocessFlags.STDERR_SILENCE; - - super._init({ flags }); - - this.errMsg = 'exited with error or was forced to close'; - this.loop = GLib.MainLoop.new(null, false); - - this.broadwayd = this.spawnv(['gtk4-broadwayd', '--port=' + port]); - this.broadwayd.wait_async(null, this._onBroadwaydClosed.bind(this)); - - this.setenv('GDK_BACKEND', 'broadway', true); - - const remoteApp = this.spawnv(['com.github.rafostar.Clapper.Remote']); - remoteApp.wait_async(null, this._onRemoteClosed.bind(this)); - - this.loop.run(); - } - - _checkProcResult(proc, result) - { - let hadError = false; - - try { - hadError = proc.wait_finish(result); - } - catch(err) { - debug(err); - } - - return hadError; - } - - _onBroadwaydClosed(proc, result) - { - const hadError = this._checkProcResult(proc, result); - - if(hadError) - debug(`broadwayd ${this.errMsg}`); - - this.broadwayd = null; - this.loop.quit(); - } - - _onRemoteClosed(proc, result) - { - const hadError = this._checkProcResult(proc, result); - - if(hadError) - debug(`remote app ${this.errMsg}`); - - if(this.broadwayd) - this.broadwayd.force_exit(); - } -}); diff --git a/src/headerbarRemote.js b/src/headerbarRemote.js deleted file mode 100644 index 778eee27..00000000 --- a/src/headerbarRemote.js +++ /dev/null @@ -1,22 +0,0 @@ -const { GObject } = imports.gi; -const { HeaderBarBase } = imports.src.headerbarBase; - -var HeaderBarRemote = GObject.registerClass({ - GTypeName: 'ClapperHeaderBarRemote', -}, -class ClapperHeaderBarRemote extends HeaderBarBase -{ - _init() - { - super._init(); - this.extraButtonsBox.visible = false; - } - - _onWindowButtonActivate(action) - { - if(action === 'toggle-maximized') - action = 'toggle_maximized'; - - this.root.child.sendWs(action); - } -}); diff --git a/src/mainDaemon.js b/src/mainDaemon.js deleted file mode 100644 index 8e2f8c16..00000000 --- a/src/mainDaemon.js +++ /dev/null @@ -1,6 +0,0 @@ -const { Daemon } = imports.src.daemon; - -function main() -{ - new Daemon(); -} diff --git a/src/mainRemote.js b/src/mainRemote.js deleted file mode 100644 index 216af851..00000000 --- a/src/mainRemote.js +++ /dev/null @@ -1,19 +0,0 @@ -imports.gi.versions.Gdk = '4.0'; -imports.gi.versions.Gtk = '4.0'; -imports.gi.versions.Soup = '2.4'; - -pkg.initGettext(); - -const Misc = imports.src.misc; -Misc.appId += '.Remote'; - -const { Gtk, Adw } = imports.gi; -const { AppRemote } = imports.src.appRemote; - -function main(argv) -{ - Gtk.init(); - Adw.init(); - - new AppRemote().run(argv); -} diff --git a/src/player.js b/src/player.js index 3d78b0f9..f20eee86 100644 --- a/src/player.js +++ b/src/player.js @@ -3,7 +3,6 @@ const ByteArray = imports.byteArray; const Debug = imports.src.debug; const Misc = imports.src.misc; const { PlaylistWidget } = imports.src.playlist; -const { WebApp } = imports.src.webApp; const { debug, warn } = Debug; const { settings } = Misc; @@ -43,7 +42,6 @@ class ClapperPlayer extends GstClapper.Clapper this.visualization_enabled = false; this.webserver = null; - this.webapp = null; this.playlistWidget = new PlaylistWidget(); this.seekDone = true; @@ -675,7 +673,6 @@ class ClapperPlayer extends GstClapper.Clapper debug(`changed play flags: ${initialFlags} -> ${settingsFlags}`); break; case 'webserver-enabled': - case 'webapp-enabled': const webserverEnabled = settings.get_boolean('webserver-enabled'); if(webserverEnabled) { @@ -690,22 +687,8 @@ class ClapperPlayer extends GstClapper.Clapper this.webserver.passMsgData = this.receiveWs.bind(this); } this.webserver.startListening(); - - const webappEnabled = settings.get_boolean('webapp-enabled'); - - if(!this.webapp && !webappEnabled) - break; - - if(webappEnabled) { - if(!this.webapp) - this.webapp = new WebApp(); - - this.webapp.startDaemonApp(settings.get_int('webapp-port')); - } } else if(this.webserver) { - /* remote app will close when connection is lost - * which will cause the daemon to close too */ this.webserver.stopListening(); } break; diff --git a/src/playerRemote.js b/src/playerRemote.js deleted file mode 100644 index 91071d76..00000000 --- a/src/playerRemote.js +++ /dev/null @@ -1,51 +0,0 @@ -const { GObject } = imports.gi; -const { WebClient } = imports.src.webClient; - -var ClapperState = { - STOPPED: 0, - BUFFERING: 1, - PAUSED: 2, - PLAYING: 3, -}; - -var PlayerRemote = GObject.registerClass({ - GTypeName: 'ClapperPlayerRemote', -}, -class ClapperPlayerRemote extends GObject.Object -{ - _init() - { - super._init(); - - this.webclient = new WebClient(); - } - - set_playlist(playlist) - { - const uris = []; - - /* We can not send GioFiles via WebSocket */ - for(let source of playlist) - uris.push(this._getSourceUri(source)); - - this.webclient.sendMessage({ - action: 'set_playlist', - value: uris - }); - } - - set_subtitles(source) - { - this.webclient.sendMessage({ - action: 'set_subtitles', - value: this._getSourceUri(source) - }); - } - - _getSourceUri(source) - { - return (source.get_uri != null) - ? source.get_uri() - : source; - } -}); diff --git a/src/webApp.js b/src/webApp.js deleted file mode 100644 index 00a9abd0..00000000 --- a/src/webApp.js +++ /dev/null @@ -1,51 +0,0 @@ -const { Gio, GObject } = imports.gi; -const Debug = imports.src.debug; -const Misc = imports.src.misc; - -const { debug } = Debug; - -var WebApp = GObject.registerClass({ - GTypeName: 'ClapperWebApp', -}, -class ClapperWebApp extends Gio.SubprocessLauncher -{ - _init() - { - const flags = Gio.SubprocessFlags.STDOUT_SILENCE - | Gio.SubprocessFlags.STDERR_SILENCE; - - super._init({ flags }); - - this.daemonApp = null; - } - - startDaemonApp(port) - { - if(this.daemonApp) - return; - - this.daemonApp = this.spawnv([Misc.appId + '.Daemon', String(port)]); - this.daemonApp.wait_async(null, this._onDaemonClosed.bind(this)); - - debug('daemon app started'); - } - - _onDaemonClosed(proc, result) - { - let hadError; - - try { - hadError = proc.wait_finish(result); - } - catch(err) { - debug(err); - } - - this.daemonApp = null; - - if(hadError) - debug('daemon app exited with error or was forced to close'); - - debug('daemon app closed'); - } -}); diff --git a/src/webClient.js b/src/webClient.js deleted file mode 100644 index c3d86be1..00000000 --- a/src/webClient.js +++ /dev/null @@ -1,90 +0,0 @@ -const { Gio, GObject, Soup } = imports.gi; -const Debug = imports.src.debug; -const Misc = imports.src.misc; -const WebHelpers = imports.src.webHelpers; - -const { debug } = Debug; -const { settings } = Misc; - -var WebClient = GObject.registerClass({ - GTypeName: 'ClapperWebClient', -}, -class ClapperWebClient extends Soup.Session -{ - _init(port) - { - super._init({ - timeout: 3, - use_thread_context: true, - }); - - this.wsConn = null; - - this.connectWebsocket(); - } - - connectWebsocket() - { - if(this.wsConn) - return; - - const port = settings.get_int('webserver-port'); - const message = Soup.Message.new('GET', `ws://127.0.0.1:${port}/websocket`); - this.websocket_connect_async(message, null, null, null, this._onWsConnect.bind(this)); - - debug('connecting WebSocket to Clapper app'); - } - - sendMessage(data) - { - if( - !this.wsConn - || this.wsConn.state !== Soup.WebsocketState.OPEN - ) - return; - - this.wsConn.send_text(JSON.stringify(data)); - } - - passMsgData(action, value) - { - } - - _onWsConnect(session, result) - { - let connection = null; - - try { - connection = this.websocket_connect_finish(result); - } - catch(err) { - debug(err); - } - - if(!connection) - return this.passMsgData('close'); - - connection.connect('message', this._onWsMessage.bind(this)); - connection.connect('closed', this._onWsClosed.bind(this)); - - this.wsConn = connection; - - debug('successfully connected WebSocket'); - } - - _onWsMessage(connection, dataType, bytes) - { - const [success, parsedMsg] = WebHelpers.parseData(dataType, bytes); - - if(success) - this.passMsgData(parsedMsg.action, parsedMsg.value); - } - - _onWsClosed(connection) - { - debug('closed WebSocket connection'); - this.wsConn = null; - - this.passMsgData('close'); - } -}); diff --git a/src/widgetRemote.js b/src/widgetRemote.js deleted file mode 100644 index 72db165a..00000000 --- a/src/widgetRemote.js +++ /dev/null @@ -1,72 +0,0 @@ -const { GObject, Gtk } = imports.gi; -const Buttons = imports.src.buttons; -const Misc = imports.src.misc; -const { PlayerRemote, ClapperState } = imports.src.playerRemote; - -var WidgetRemote = GObject.registerClass({ - GTypeName: 'ClapperWidgetRemote', -}, -class ClapperWidgetRemote extends Gtk.Grid -{ - _init(opts) - { - super._init({ - halign: Gtk.Align.CENTER, - valign: Gtk.Align.CENTER, - }); - - Misc.loadCustomCss(); - - this.player = new PlayerRemote(); - this.player.webclient.passMsgData = this.receiveWs.bind(this); - - /* FIXME: create better way to add buttons for - * remote app without duplicating too much code */ - this.togglePlayButton = new Buttons.IconToggleButton( - 'media-playback-start-symbolic', - 'media-playback-pause-symbolic' - ); - this.togglePlayButton.remove_css_class('flat'); - this.togglePlayButton.connect( - 'clicked', () => this.sendWs('toggle_play') - ); - - this.attach(this.togglePlayButton, 0, 0, 1, 1); - } - - sendWs(action, value) - { - const data = { action }; - - /* do not send "null" or "undefined" - * for faster network data transfer */ - if(value != null) - data.value = value; - - this.player.webclient.sendMessage(data); - } - - receiveWs(action, value) - { - switch(action) { - case 'state_changed': - switch(value) { - case ClapperState.STOPPED: - case ClapperState.PAUSED: - this.togglePlayButton.setPrimaryIcon(); - break; - case ClapperState.PLAYING: - this.togglePlayButton.setSecondaryIcon(); - break; - default: - break; - } - break; - case 'close': - this.root.run_dispose(); - break; - default: - break; - } - } -}); diff --git a/ui/preferences-window.ui b/ui/preferences-window.ui index a560cbdc..4ea019c6 100644 --- a/ui/preferences-window.ui +++ b/ui/preferences-window.ui @@ -177,20 +177,6 @@ web_server_adjustment - - - Run web application in background - Requires GTK compiled with Broadway backend - webapp-enabled - - - - - Web application port - webapp-port - web_app_adjustment - - From c4bd604e17925fd2e9eda0f4c51393fcce745641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Thu, 10 Feb 2022 10:48:03 +0100 Subject: [PATCH 2/5] Port to libsoup3 With all apps and modules/plugins porting itself to libsoup3 we also need to do so. It would appear as a good idea to conditionally import "3.0" and fallback to "2.4" bindings here, but its not as loaded GStreamer plugins might use libsoup3 already and we cannot have both libsoup2 and libsoup3 in a single process. --- src/main.js | 2 +- src/webServer.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.js b/src/main.js index 71f8a554..29c7e4e0 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,6 @@ imports.gi.versions.Gdk = '4.0'; imports.gi.versions.Gtk = '4.0'; -imports.gi.versions.Soup = '2.4'; +imports.gi.versions.Soup = '3.0'; pkg.initGettext(); pkg.initFormat(); diff --git a/src/webServer.js b/src/webServer.js index 0cf3253c..2098dda7 100644 --- a/src/webServer.js +++ b/src/webServer.js @@ -107,7 +107,7 @@ class ClapperWebServer extends Soup.Server this.remove_handler('/'); } - _onWsConnection(server, connection) + _onWsConnection(server, msg, path, connection) { debug('new WebSocket connection'); From 40a1dc6960eac28ba7e74972e931f84a64c50ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Thu, 10 Feb 2022 11:10:16 +0100 Subject: [PATCH 3/5] flatpak: Build libsoup3 Now both Clapper and Gtuber lib require libsoup3, so build it until it will be available in runtime --- .../com.github.rafostar.Clapper-nightly.json | 1 + pkgs/flatpak/com.github.rafostar.Clapper.json | 1 + pkgs/flatpak/testing/libsoup3.json | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 pkgs/flatpak/testing/libsoup3.json diff --git a/pkgs/flatpak/com.github.rafostar.Clapper-nightly.json b/pkgs/flatpak/com.github.rafostar.Clapper-nightly.json index 8bfef6aa..6d754f19 100644 --- a/pkgs/flatpak/com.github.rafostar.Clapper-nightly.json +++ b/pkgs/flatpak/com.github.rafostar.Clapper-nightly.json @@ -32,6 +32,7 @@ "flathub/lib/libdvdnav.json", "flathub/lib/libass.json", "flathub/lib/ffmpeg.json", + "testing/libsoup3.json", "testing/gstreamer.json", "testing/gtuber.json", { diff --git a/pkgs/flatpak/com.github.rafostar.Clapper.json b/pkgs/flatpak/com.github.rafostar.Clapper.json index cd7f6fa5..d0d61240 100644 --- a/pkgs/flatpak/com.github.rafostar.Clapper.json +++ b/pkgs/flatpak/com.github.rafostar.Clapper.json @@ -33,6 +33,7 @@ "flathub/lib/libass.json", "flathub/lib/ffmpeg.json", "flathub/lib/uchardet.json", + "testing/libsoup3.json", "flathub/gstreamer-1.0/gstreamer.json", "flathub/lib/gtk4.json", "flathub/lib/libadwaita.json", diff --git a/pkgs/flatpak/testing/libsoup3.json b/pkgs/flatpak/testing/libsoup3.json new file mode 100644 index 00000000..384251f7 --- /dev/null +++ b/pkgs/flatpak/testing/libsoup3.json @@ -0,0 +1,24 @@ +{ + "name": "libsoup3", + "buildsystem": "meson", + "config-opts": [ + "-Dintrospection=enabled", + "-Dvapi=disabled", + "-Dtests=false", + "-Dsysprof=disabled", + "-Dhttp2_tests=disabled", + "-Dpkcs11_tests=disabled" + ], + "cleanup": [ + "/include", + "/lib/pkgconfig" + ], + "sources": [ + { + "type": "git", + "url": "https://gitlab.gnome.org/GNOME/libsoup.git", + "tag": "3.0.4", + "commit": "25a728020c4b53b5db4c4c675070e92f947fbd4d" + } + ] +} From b2e7bef8d4d0186d13634eac353ec7e4a1bf9fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Thu, 10 Feb 2022 11:39:30 +0100 Subject: [PATCH 4/5] flatpak: Update git actions runtime to 41 We need to update, so we can build libsoup3. Flathub ver will likely remain as 40 ver to avoid some problems and will be updated directly to 42 later. --- .github/workflows/flatpak.yml | 2 +- pkgs/flatpak/com.github.rafostar.Clapper.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index b1bd16bc..82340631 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -11,7 +11,7 @@ jobs: name: "Flatpak" runs-on: ubuntu-latest container: - image: bilelmoussaoui/flatpak-github-actions:gnome-40 + image: bilelmoussaoui/flatpak-github-actions:gnome-41 options: --privileged strategy: matrix: diff --git a/pkgs/flatpak/com.github.rafostar.Clapper.json b/pkgs/flatpak/com.github.rafostar.Clapper.json index d0d61240..8f6ad681 100644 --- a/pkgs/flatpak/com.github.rafostar.Clapper.json +++ b/pkgs/flatpak/com.github.rafostar.Clapper.json @@ -1,7 +1,7 @@ { "app-id": "com.github.rafostar.Clapper", "runtime": "org.gnome.Platform", - "runtime-version": "40", + "runtime-version": "41", "sdk": "org.gnome.Sdk", "command": "com.github.rafostar.Clapper", "finish-args": [ From 96ad4fa3dbd2bef0b0c72ab9a9b877090fa23637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Mon, 14 Feb 2022 17:36:57 +0100 Subject: [PATCH 5/5] RPM: Require libsoup3 --- pkgs/rpm/clapper.spec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkgs/rpm/clapper.spec b/pkgs/rpm/clapper.spec index 06354bb0..e97e7df7 100644 --- a/pkgs/rpm/clapper.spec +++ b/pkgs/rpm/clapper.spec @@ -24,6 +24,7 @@ %global gtk4_version 4.0.0 %global meson_version 0.50 %global glib2_version 2.56.0 +%global soup_version 3.0.0 Name: clapper Version: 0.4.1 @@ -59,6 +60,7 @@ BuildRequires: gstreamer-plugins-base-devel >= %{gst_version} BuildRequires: Mesa-libGLESv2-devel BuildRequires: Mesa-libGLESv3-devel +Requires: libsoup-devel >= %{soup_version} Requires: gstreamer >= %{gst_version} Requires: gstreamer-plugins-base >= %{gst_version} Requires: gstreamer-plugins-good >= %{gst_version} @@ -80,6 +82,7 @@ BuildRequires: mesa-libGLES-devel BuildRequires: mesa-libGLU-devel BuildRequires: mesa-libEGL-devel +Requires: libsoup3-devel Requires: gstreamer1 >= %{gst_version} Requires: gstreamer1-plugins-base >= %{gst_version} Requires: gstreamer1-plugins-good >= %{gst_version} @@ -129,6 +132,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libdir}/%{appname}/ %changelog +* Thu Feb 17 2022 Rafostar - 0.4.1-2 +- Require libsoup3 + * Mon Dec 20 2021 Rafostar - 0.4.1-1 - New version