From e78e1a69d7200da8012d9ef3a3b8fb25796d498e Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Fri, 14 Feb 2025 23:35:25 +0100 Subject: webtrayctl: add show --- flake.lock | 8 ++++---- flake.nix | 5 ++++- src/dbus.cpp | 7 +++++++ src/dbus.hpp | 24 ++++++++++++++++++++++++ src/main.cpp | 40 ++++++++++++++++++++++++--------------- src/permissionmanager.cpp | 39 +++++++++++++++++++------------------- src/permissionmanager.hpp | 4 ++-- src/tray.cpp | 46 ++++++++++++++++++++++----------------------- src/tray.hpp | 6 +++--- src/webwindow.cpp | 48 ++++++++++++++++++++--------------------------- src/webwindow.hpp | 2 +- webtray.pro | 5 +++-- webtrayctl | 36 +++++++++++++++++++++++++++-------- 13 files changed, 164 insertions(+), 106 deletions(-) create mode 100644 src/dbus.cpp create mode 100644 src/dbus.hpp diff --git a/flake.lock b/flake.lock index bdca2b2..9e70e85 100644 --- a/flake.lock +++ b/flake.lock @@ -2,16 +2,16 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1739446958, - "narHash": "sha256-+/bYK3DbPxMIvSL4zArkMX0LQvS7rzBKXnDXLfKyRVc=", + "lastModified": 1739357830, + "narHash": "sha256-9xim3nJJUFbVbJCz48UP4fGRStVW5nv4VdbimbKxJ3I=", "owner": "nixos", "repo": "nixpkgs", - "rev": "2ff53fe64443980e139eaa286017f53f88336dd0", + "rev": "0ff09db9d034a04acd4e8908820ba0b410d7a33a", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-unstable", + "ref": "nixos-24.11", "repo": "nixpkgs", "type": "github" } diff --git a/flake.nix b/flake.nix index df7ad4a..d0ab918 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,7 @@ description = "WebTray Flake"; inputs = { - nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-24.11"; }; outputs = @@ -27,6 +27,9 @@ pkgs.qt6.qtwebengine pkgs.qt6.qtbase pkgs.qt6.qtwayland + pkgs.qt6.qtmultimedia + pkgs.kdePackages.wayqt + pkgs.kdePackages.full ]; }; diff --git a/src/dbus.cpp b/src/dbus.cpp new file mode 100644 index 0000000..5e0ce6e --- /dev/null +++ b/src/dbus.cpp @@ -0,0 +1,7 @@ +#include "dbus.hpp" + +#include + +void DBusHandler::show() { + this->window->show(); +} diff --git a/src/dbus.hpp b/src/dbus.hpp new file mode 100644 index 0000000..ba0d558 --- /dev/null +++ b/src/dbus.hpp @@ -0,0 +1,24 @@ +#ifndef WEBTRAY_DBUS_HPP +#define WEBTRAY_DBUS_HPP + +#include + +#include "webwindow.hpp" + +static const char service_name[] = "xyz.nathanreiner.WebTray"; + +class DBusHandler : public QObject { + Q_OBJECT; + +private: + WebWindow *window; + +public slots: + void show(); + +public: + DBusHandler(WebWindow *window) : window(window) {} + virtual ~DBusHandler() {}; +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp index 385d3c3..1630680 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,21 +1,22 @@ #include +#include +#include #include -using namespace std::chrono_literals; - #include "permissionmanager.hpp" #include "tray.hpp" #include "webwindow.hpp" - -const QWebEnginePage::Feature features[] = { - QWebEnginePage::Feature::MouseLock, - QWebEnginePage::Feature::Notifications, - QWebEnginePage::Feature::Notifications, - QWebEnginePage::Feature::DesktopVideoCapture, - QWebEnginePage::Feature::DesktopAudioVideoCapture, - QWebEnginePage::Feature::MediaAudioCapture, - QWebEnginePage::Feature::MediaVideoCapture, +#include "dbus.hpp" + +const QWebEnginePermission::PermissionType permissions[] = { + QWebEnginePermission::PermissionType::MouseLock, + QWebEnginePermission::PermissionType::Notifications, + QWebEnginePermission::PermissionType::Notifications, + QWebEnginePermission::PermissionType::DesktopVideoCapture, + QWebEnginePermission::PermissionType::DesktopAudioVideoCapture, + QWebEnginePermission::PermissionType::MediaAudioCapture, + QWebEnginePermission::PermissionType::MediaVideoCapture, }; void @@ -54,8 +55,8 @@ main(int argc, char **argv) bool start_hidden = not app->arguments().contains("--open-at-startup"); - for (auto feature : features) { - tray->set_permission(feature, webwindow->permissions().get(feature)); + for (auto permission: permissions) { + tray->set_permission(permission, webwindow->permissions().get(permission)); } webwindow->connect_icon_changed([&](auto icon) { @@ -75,11 +76,20 @@ main(int argc, char **argv) tray->connect_toggle([&]() { webwindow->toggle_visibility(); }); tray->connect_quit([&]() { webwindow->quit(); }); - tray->connect_permission_changed([&](auto feature, auto value) { - webwindow->permissions().set(feature, value); + tray->connect_permission_changed([&](auto permission, auto value) { + webwindow->permissions().set(permission, value); }); tray->connect_reset_cookies([&]() { webwindow->reset_cookies(); }); + auto connection = QDBusConnection::sessionBus(); + DBusHandler dbus_handler = DBusHandler(webwindow); + + if (!connection.registerService(QString(service_name) + "." + QUrl(url).host())) { + std::cerr << "could not register ipc\n"; + } + + connection.registerObject("/", &dbus_handler, QDBusConnection::ExportAllSlots); + webwindow->show(); if (start_hidden) { webwindow->hide(); diff --git a/src/permissionmanager.cpp b/src/permissionmanager.cpp index 22a7110..78564c6 100644 --- a/src/permissionmanager.cpp +++ b/src/permissionmanager.cpp @@ -39,59 +39,60 @@ PermissionManager::save() } bool -PermissionManager::get(QWebEnginePage::Feature feature) +PermissionManager::get(QWebEnginePermission::PermissionType feature) { switch (feature) { - case QWebEnginePage::Feature::MouseLock: + case QWebEnginePermission::PermissionType::MouseLock: return this->lock_mouse; - case QWebEnginePage::Feature::Geolocation: + case QWebEnginePermission::PermissionType::Geolocation: return this->location; - case QWebEnginePage::Feature::Notifications: + case QWebEnginePermission::PermissionType::Notifications: return this->notification; - case QWebEnginePage::Feature::MediaAudioCapture: + case QWebEnginePermission::PermissionType::MediaAudioCapture: return this->media_audio_capture; - case QWebEnginePage::Feature::MediaVideoCapture: + case QWebEnginePermission::PermissionType::MediaVideoCapture: return this->media_video_capture; - case QWebEnginePage::Feature::MediaAudioVideoCapture: + case QWebEnginePermission::PermissionType::MediaAudioVideoCapture: return this->media_video_capture && this->media_audio_capture; - case QWebEnginePage::Feature::DesktopVideoCapture: + case QWebEnginePermission::PermissionType::DesktopVideoCapture: return this->desktop_audio_video_capture; - case QWebEnginePage::Feature::DesktopAudioVideoCapture: + case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture: return this->desktop_audio_video_capture; default: - /* unreachable except QWebEnginePage::Feature gets new entries */ + /* unreachable except QWebEnginePermission::PermissionType gets new entries */ return false; } } void -PermissionManager::set(QWebEnginePage::Feature feature, bool value) +PermissionManager::set(QWebEnginePermission::PermissionType feature, bool value) { switch (feature) { - case QWebEnginePage::Feature::MouseLock: + case QWebEnginePermission::PermissionType::MouseLock: this->lock_mouse = value; break; - case QWebEnginePage::Feature::Geolocation: + case QWebEnginePermission::PermissionType::Geolocation: this->location = value; break; - case QWebEnginePage::Feature::Notifications: + case QWebEnginePermission::PermissionType::Notifications: this->notification = value; break; - case QWebEnginePage::Feature::MediaAudioCapture: + case QWebEnginePermission::PermissionType::MediaAudioCapture: this->media_audio_capture = value; break; - case QWebEnginePage::Feature::MediaVideoCapture: + case QWebEnginePermission::PermissionType::MediaVideoCapture: this->media_video_capture = value; break; - case QWebEnginePage::Feature::MediaAudioVideoCapture: + case QWebEnginePermission::PermissionType::MediaAudioVideoCapture: this->media_audio_capture = value; this->media_video_capture = value; break; - case QWebEnginePage::Feature::DesktopVideoCapture: + case QWebEnginePermission::PermissionType::DesktopVideoCapture: this->desktop_audio_video_capture = value; break; - case QWebEnginePage::Feature::DesktopAudioVideoCapture: + case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture: this->desktop_audio_video_capture = value; break; + default: break; } } diff --git a/src/permissionmanager.hpp b/src/permissionmanager.hpp index 8d53597..d1ea720 100644 --- a/src/permissionmanager.hpp +++ b/src/permissionmanager.hpp @@ -20,8 +20,8 @@ public: PermissionManager(std::string path); ~PermissionManager(); void save(); - bool get(QWebEnginePage::Feature feature); - void set(QWebEnginePage::Feature feature, bool value); + bool get(QWebEnginePermission::PermissionType feature); + void set(QWebEnginePermission::PermissionType feature, bool value); }; #endif diff --git a/src/tray.cpp b/src/tray.cpp index 8503cb7..d0f091a 100644 --- a/src/tray.cpp +++ b/src/tray.cpp @@ -25,13 +25,12 @@ Tray::Tray() this->permissions.location->setCheckable(true); this->permissions.lock_mouse->setCheckable(true); - this->connect(this, - &QSystemTrayIcon::activated, - [&](QSystemTrayIcon::ActivationReason reason) { - if (reason == QSystemTrayIcon::ActivationReason::Trigger) { - this->toggle_signal(); - } - }); + this->connect(this, &QSystemTrayIcon::activated, + [&](QSystemTrayIcon::ActivationReason reason) { + if (reason == QSystemTrayIcon::ActivationReason::Trigger) { + this->toggle_signal(); + } + }); this->menu.connect(&this->menu, &QMenu::triggered, [&](QAction *action) { if (action == this->app_toggle) { @@ -48,32 +47,32 @@ Tray::Tray() } else if (action == this->permissions.camera) { this->permission_changed_signal( - QWebEnginePage::Feature::MediaVideoCapture, + QWebEnginePermission::PermissionType::MediaVideoCapture, this->permissions.camera->isChecked()); } else if (action == this->permissions.microphone) { this->permission_changed_signal( - QWebEnginePage::Feature::MediaAudioCapture, + QWebEnginePermission::PermissionType::MediaAudioCapture, this->permissions.microphone->isChecked()); } else if (action == this->permissions.screenshare) { this->permission_changed_signal( - QWebEnginePage::Feature::DesktopAudioVideoCapture, + QWebEnginePermission::PermissionType::DesktopAudioVideoCapture, this->permissions.screenshare->isChecked()); } else if (action == this->permissions.notifications) { this->permission_changed_signal( - QWebEnginePage::Feature::Notifications, + QWebEnginePermission::PermissionType::Notifications, this->permissions.notifications->isChecked()); } else if (action == this->permissions.location) { this->permission_changed_signal( - QWebEnginePage::Feature::Geolocation, + QWebEnginePermission::PermissionType::Geolocation, this->permissions.location->isChecked()); } else if (action == this->permissions.lock_mouse) { this->permission_changed_signal( - QWebEnginePage::Feature::MouseLock, + QWebEnginePermission::PermissionType::MouseLock, this->permissions.lock_mouse->isChecked()); } }); @@ -101,7 +100,7 @@ Tray::connect_reset_cookies(std::function fn) void Tray::connect_permission_changed( - std::function fn) + std::function fn) { this->permission_changed_signal = fn; } @@ -123,33 +122,34 @@ Tray::send_notification(std::unique_ptr notification) } void -Tray::set_permission(QWebEnginePage::Feature feature, bool value) +Tray::set_permission(QWebEnginePermission::PermissionType feature, bool value) { switch (feature) { - case QWebEnginePage::Feature::MouseLock: + case QWebEnginePermission::PermissionType::MouseLock: this->permissions.lock_mouse->setChecked(value); break; - case QWebEnginePage::Feature::Geolocation: + case QWebEnginePermission::PermissionType::Geolocation: this->permissions.location->setChecked(value); break; - case QWebEnginePage::Feature::Notifications: + case QWebEnginePermission::PermissionType::Notifications: this->permissions.notifications->setChecked(value); break; - case QWebEnginePage::Feature::MediaAudioCapture: + case QWebEnginePermission::PermissionType::MediaAudioCapture: this->permissions.microphone->setChecked(value); break; - case QWebEnginePage::Feature::MediaVideoCapture: + case QWebEnginePermission::PermissionType::MediaVideoCapture: this->permissions.camera->setChecked(value); break; - case QWebEnginePage::Feature::MediaAudioVideoCapture: + case QWebEnginePermission::PermissionType::MediaAudioVideoCapture: this->permissions.microphone->setChecked(value); this->permissions.camera->setChecked(value); break; - case QWebEnginePage::Feature::DesktopVideoCapture: + case QWebEnginePermission::PermissionType::DesktopVideoCapture: this->permissions.screenshare->setChecked(value); break; - case QWebEnginePage::Feature::DesktopAudioVideoCapture: + case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture: this->permissions.screenshare->setChecked(value); break; + default: break; } } diff --git a/src/tray.hpp b/src/tray.hpp index 865c586..280c191 100644 --- a/src/tray.hpp +++ b/src/tray.hpp @@ -28,7 +28,7 @@ private: std::function toggle_signal; std::function quit_signal; std::function reset_cookies_signal; - std::function permission_changed_signal; + std::function permission_changed_signal; public: Tray(); @@ -36,10 +36,10 @@ public: void connect_quit(std::function fn); void connect_reset_cookies(std::function fn); void connect_permission_changed( - std::function fn); + std::function fn); void set_title(const QString &title); void send_notification(std::unique_ptr notification); - void set_permission(QWebEnginePage::Feature feature, bool value); + void set_permission(QWebEnginePermission::PermissionType feature, bool value); }; #endif diff --git a/src/webwindow.cpp b/src/webwindow.cpp index 823eec7..54634ad 100644 --- a/src/webwindow.cpp +++ b/src/webwindow.cpp @@ -48,25 +48,22 @@ WebWindow::web_configure() this->profile->setPushServiceEnabled(true); - this->page->connect(this->page, - &QWebEnginePage::featurePermissionRequested, - [&](const QUrl origin, QWebEnginePage::Feature feature) { - this->permission_requested(origin, feature); - }); - - this->profile->connect(this->profile, - &QWebEngineProfile::downloadRequested, - [&](QWebEngineDownloadRequest *request) { - const QUrl url = QFileDialog::getSaveFileUrl( - this, - "", - QUrl(this->profile->downloadPath() + "/" + - request->downloadFileName())); - if (!url.isEmpty()) { - request->setDownloadFileName(url.path()); - request->accept(); - } - }); + this->page->connect(this->page, &QWebEnginePage::permissionRequested, + [&](QWebEnginePermission permission) { + this->permission_requested(permission); + } + ); + + this->profile->connect(this->profile, &QWebEngineProfile::downloadRequested, + [&](QWebEngineDownloadRequest *request) { + const QUrl path = QUrl(this->profile->downloadPath() + "/" + request->downloadFileName()); + const QUrl url = QFileDialog::getSaveFileUrl(this, "", path); + if (!url.isEmpty()) { + request->setDownloadFileName(url.path()); + request->accept(); + } + } + ); this->page->connect(this->page, &QWebEnginePage::newWindowRequested, @@ -87,18 +84,13 @@ WebWindow::web_configure() } void -WebWindow::permission_requested(const QUrl origin, - QWebEnginePage::Feature feature) +WebWindow::permission_requested(QWebEnginePermission permission) { - if (this->perm->get(feature)) { - this->page->setFeaturePermission( - origin, feature, QWebEnginePage::PermissionGrantedByUser); + if (this->perm->get(permission.permissionType())) { + permission.grant(); } else { - this->page->setFeaturePermission( - origin, feature, QWebEnginePage::PermissionDeniedByUser); + permission.deny(); } - this->page->setFeaturePermission( - origin, feature, QWebEnginePage::PermissionUnknown); } void diff --git a/src/webwindow.hpp b/src/webwindow.hpp index c29a953..a9183d7 100644 --- a/src/webwindow.hpp +++ b/src/webwindow.hpp @@ -20,7 +20,7 @@ private: PermissionManager *perm; void web_configure(); - void permission_requested(const QUrl origin, QWebEnginePage::Feature feature); + void permission_requested(QWebEnginePermission permission); void closeEvent(QCloseEvent *event); public: diff --git a/webtray.pro b/webtray.pro index 536d000..4c2bf41 100644 --- a/webtray.pro +++ b/webtray.pro @@ -1,2 +1,3 @@ -SOURCES = src/main.cpp src/permissionmanager.cpp src/tray.cpp src/webwindow.cpp -QT += core gui webenginecore webenginewidgets widgets +SOURCES = src/main.cpp src/permissionmanager.cpp src/tray.cpp src/webwindow.cpp src/dbus.cpp +QT += core multimedia gui webenginecore webenginewidgets widgets dbus +HEADERS += src/dbus.hpp diff --git a/webtrayctl b/webtrayctl index 3050a15..e20de40 100755 --- a/webtrayctl +++ b/webtrayctl @@ -65,38 +65,54 @@ remove_webapp() { exit } +show() { + host=$(echo "$1" | sed 's/^https\?:\/\/\([^/]*\).*$/\1/') + dbus-send \ + --dest="xyz.nathanreiner.WebTray.$host" \ + --type=method_call \ + --print-reply \ + '/' \ + local.webtray.DBusHandler.show > /dev/null \ + || setsid webtray "$1" --open-at-startup & +} + while true do case "$1" in install) action="install" - shift + shift 2>/dev/null url="$1" name="$2" - shift 2 + shift 2 2>/dev/null ;; uninstall) action="uninstall" - shift + shift 2>/dev/null toRemove="$1" - shift + shift 2>/dev/null ;; "--open-at-startup") open_at_startup="--open-at-startup" - shift + shift 2>/dev/null ;; "--icon") - shift + shift 2>/dev/null icon="$1" [ -z "$1" ] && help - shift + shift 2>/dev/null + ;; + show) + action="show" + shift 2>/dev/null + url="$1" + shift 2>/dev/null ;; *)help;; esac if [ -z "$1" ]; then break fi - #shift 1 || break done case "$action" in @@ -108,5 +124,9 @@ case "$action" in [ -z "$toRemove" ] && help remove_webapp "$toRemove" ;; + show) + [ -z "$url" ] && help + show "$url" + ;; *)help;; esac -- cgit v1.2.3-70-g09d2