diff options
author | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-03-03 18:19:14 +0100 |
---|---|---|
committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-03-03 18:19:14 +0100 |
commit | f51d5537826ac8a1bc691055fd4b5879f2795aaa (patch) | |
tree | 41befd89934b5225a7dc18b83cacf95b6647f709 |
create first version of webtray
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 40 | ||||
-rw-r--r-- | config.mk | 4 | ||||
-rw-r--r-- | src/main.cpp | 167 |
4 files changed, 213 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..beed059 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target/ +compile_commands.json diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..30a7b88 --- /dev/null +++ b/Makefile @@ -0,0 +1,40 @@ +SOURCE=$(shell find src -name "*.cpp") +OBJECT=$(SOURCE:src/%.cpp=${TARGET_DIRECTORY}/%.o) +DEPENDENCIES=$(SOURCE:src/%.cpp=${TARGET_DIRECTORY}/%.d) + +include config.mk + +default_target: all + +option: + @echo WebTray build options: + @echo SOURCE = ${SOURCE} + @echo OBJECT = ${OBJECT} + @echo DEPENDENCIES = ${DEPENDENCIES} + @echo CPPFLAGS = ${CPPFLAGS} + @echo LDFLAGS = ${LDFLAGS} + +${TARGET_DIRECTORY}: + @printf "create target directory\n" + @mkdir ${TARGET_DIRECTORY} + +-include ${DEPENDENCIES} + +${TARGET_DIRECTORY}/%.o: src/%.cpp Makefile + @printf "build $<\n" + @mkdir -p "$$(dirname $@)" + @${CC} ${CPPFLAGS} ${LDFLAGS} -MMD -MP -c $< -o $@ + +${OBJECT}: | ${TARGET_DIRECTORY} + +webtray: ${TARGET_DIRECTORY} ${OBJECT} + @printf "build $@\n" + @${CC} -o ${TARGET_DIRECTORY}/$@ ${OBJECT} ${LDFLAGS} ${CPPFLAGS} + +all: | ${TARGET_DIRECTORY} webtray + +clean: + @printf "cleaning up\n" + @rm -rf ${TARGET_DIRECTORY} + +.PHONY: clean diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..4f04f30 --- /dev/null +++ b/config.mk @@ -0,0 +1,4 @@ +TARGET_DIRECTORY=target +CPPFLAGS=`pkg-config --cflags Qt6WebEngineWidgets Qt6WebEngineCore Qt6Core Qt6Gui` +LDFLAGS=`pkg-config --libs Qt6WebEngineWidgets Qt6WebEngineCore Qt6Core Qt6Gui Qt6Multimedia` -fPIC +CC=g++ diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..56c20eb --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,167 @@ +#include <QtGui/QCloseEvent> +#include <QtWebEngineCore/QWebEngineNotification> +#include <QtWebEngineCore/QWebEnginePage> +#include <QtWebEngineCore/QWebEngineProfile> +#include <QtWebEngineCore/QWebEngineSettings> +#include <QtWebEngineWidgets/QWebEngineView> +#include <QtWidgets/QApplication> +#include <QtWidgets/QLayout> +#include <QtWidgets/QMainWindow> +#include <QtWidgets/QMenu> +#include <QtWidgets/QMessageBox> +#include <QtWidgets/QSystemTrayIcon> +#include <QtWidgets/QWidget> +#include <iostream> + +class MainWindow : public QMainWindow +{ +public: + void closeEvent(QCloseEvent *event) + { + this->hide(); + event->ignore(); + } +}; + +int +main(int argc, char **argv) +{ + QApplication app(argc, argv); + bool start_hidden = false; + QUrl url; + + for (auto argument : app.arguments()) { + if (argument == "--hidden") { + start_hidden = true; + } else { + url = argument; + } + } + + if (url.url().toStdString() == argv[0]) { + std::cerr << "webtray <url> [--hidden]\n"; + return -1; + } + + MainWindow main_window; + + QSystemTrayIcon tray; + QMenu menu; + + QWebEngineProfile profile(url.host().toStdString().c_str()); + QWebEnginePage page(&profile); + QWebEngineView view; + + QAction *app_action = menu.addAction("Element"); + menu.addSeparator(); + QAction *quit_action = menu.addAction("Quit"); + + menu.connect(&menu, &QMenu::triggered, [&](QAction *action) { + if (action == app_action) { + main_window.setVisible(!main_window.isVisible()); + } else if (action == quit_action) { + main_window.close(); + page.windowCloseRequested(); + app.quit(); + } + }); + + view.setPage(&page); + view.setUrl(url); + + tray.setContextMenu(&menu); + + tray.connect(&tray, + &QSystemTrayIcon::activated, + [&](const QSystemTrayIcon::ActivationReason reason) { + switch (reason) { + case QSystemTrayIcon::Trigger: + main_window.setVisible(!main_window.isVisible()); + break; + default: + break; + } + }); + + view.connect(&view, &QWebEngineView::iconChanged, [&](const QIcon icon) { + tray.setIcon(icon); + tray.show(); + }); + + view.connect(&view, &QWebEngineView::titleChanged, [&](const QString title) { + tray.setToolTip(title); + app_action->setText(title); + }); + + page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true); + page.settings()->setAttribute(QWebEngineSettings::WebRTCPublicInterfacesOnly, + false); + page.settings()->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, + false); + + profile.setPushServiceEnabled(true); + profile.setNotificationPresenter( + [&](std::unique_ptr<QWebEngineNotification> notification) { + tray.showMessage(notification->title(), + notification->message(), + QSystemTrayIcon::MessageIcon::Information, + 3000); + }); + + page.connect(&page, + &QWebEnginePage::featurePermissionRequested, + [&](const QUrl origin, QWebEnginePage::Feature feature) { + QString feature_name; + + switch (feature) { + case QWebEnginePage::Feature::MouseLock: + feature_name = "lock the mouse"; + break; + case QWebEnginePage::Feature::Geolocation: + feature_name = "your location information"; + break; + case QWebEnginePage::Feature::Notifications: + feature_name = "send notifications"; + break; + case QWebEnginePage::Feature::MediaAudioCapture: + feature_name = "capture audio"; + break; + case QWebEnginePage::Feature::MediaVideoCapture: + feature_name = "capture video"; + break; + case QWebEnginePage::Feature::MediaAudioVideoCapture: + feature_name = "capture audio and video"; + break; + case QWebEnginePage::Feature::DesktopVideoCapture: + feature_name = "capture video from your desktop"; + break; + case QWebEnginePage::Feature::DesktopAudioVideoCapture: + feature_name = "capture audio and video from your desktop"; + break; + } + + QMessageBox dialog(QMessageBox::Icon::Question, + "Permission", + "Do you want to grant permission to " + + feature_name + "?", + QMessageBox::StandardButton::Yes | + QMessageBox::StandardButton::No); + int res = dialog.exec(); + + if (res == QMessageBox::Yes) { + page.setFeaturePermission( + origin, feature, QWebEnginePage::PermissionGrantedByUser); + } else { + page.setFeaturePermission( + origin, feature, QWebEnginePage::PermissionDeniedByUser); + } + }); + + main_window.setCentralWidget(&view); + if (!start_hidden) { + main_window.show(); + } else { + tray.show(); + } + return app.exec(); +} |