ParticleG/dms-webview-plugins

★ 0Forks 0QMLGitHub ↗Compare

README

DMS Webview Plugins

Three DankMaterialShell plugins that render web content with Qt WebEngine and expose a small Qt WebChannel bridge to page JavaScript:

  • webviewBar: a DankBar widget whose popout hosts a webview.
  • webviewControlCenter: a Control Center widget/detail panel that hosts a webview.
  • webviewDesktop: a Desktop widget that hosts a webview.

Each plugin can render either a remote http:///https:// URL or one of the local HTML files shipped under that plugin's own html/ directory.

Runtime model

DankMaterialShell discovers plugins from QML directories under:

~/.config/DankMaterialShell/plugins/

Each direct child directory must contain a plugin.json manifest. This repository deliberately repeats the support QML files inside each plugin directory instead of creating a shared sibling directory under plugins/, because DMS scans each direct child and tries to load <dir>/plugin.json.

The manifests use the DMS documentation/schema fields:

  • id
  • name
  • description
  • version
  • author
  • type
  • capabilities
  • component
  • optional settings
  • optional requires_dms
  • optional permissions

These plugin manifests also include a human-readable requires array for runtime prerequisites.

Why Qt WebEngine and Qt WebChannel

The renderer is WebEngineView from Qt WebEngine. Qt documents the QML import and APIs used here:

  • import QtWebEngine
  • WebEngineView.url
  • WebEngineView.loadHtml()
  • WebEngineView.newWindowRequested
  • WebEngineView.webChannel

The JavaScript bridge is WebChannel from Qt WebChannel. Qt documents:

  • import QtWebChannel 1.11
  • registeredObjects
  • WebChannel.id
  • HTML clients can access QML object properties, signals, and public methods through qwebchannel.js.

The bridge intentionally exposes only a narrow plugin API: context lookup, web popout open/close, close-self, runtime source changes, and selected DMS popout actions where the host injects a supported service.

Required runtime prerequisites

These plugins are real WebEngine/WebChannel plugins. They do not implement a fake fallback webview.

The runtime needs Qt QML modules:

  • QtWebEngine
  • QtWebChannel

On the current Arch workstation, the package names to try are:

sudo pacman -S qt6-webengine qt6-webchannel

The runtime also needs a Quickshell build equivalent to Quickshell PR #351, or a future Quickshell release containing the same initialization behavior. The original PR discussion used //@ pragma EnableQtWebEngineQuick; the tested mecattaf/quickshellX fork uses //@ pragma UseWebEngine instead, dynamically loads Qt6WebEngineQuick, and calls QtWebEngineQuick::initialize() before constructing QGuiApplication.

Putting either pragma in these plugin QML files is not enough. DMS plugins are loaded after Quickshell has already started, so WebEngineQuick initialization must be done by the host root shell.qml before application construction.

If the host crashes because of the PR #351 jemalloc issue after reporting successful QtWebEngineQuick initialization, the fix point is not plugin code. Build/test Quickshell without jemalloc, use a Quickshell build where Qt WebEngine works, or disable these plugins.

Side-by-side quickshellX test

The repository includes a no-system-mutation test harness for the fork mentioned in PR #351:

./scripts/quickshellx-webengine-test.sh all

On Arch, the build/test preflight checks for git, cmake, ninja, qt6-base, qt6-declarative, qt6-wayland, qt6-webengine, qt6-webchannel, qt6-shadertools, cli11, and vulkan-headers. The script reports missing packages and exits; it never runs sudo.

The harness:

  • clones https://github.com/mecattaf/quickshellX.git under .quickshellx-test/;
  • builds it with -DUSE_JEMALLOC=OFF;
  • installs it under .quickshellx-test/prefix/;
  • copies /usr/share/quickshell/dms to .quickshellx-test/dms-root/;
  • inserts //@ pragma UseWebEngine only in that copied root shell.qml;
  • copies these plugins to an isolated XDG_CONFIG_HOME;
  • writes isolated DMS settings that enable the webview plugins for the test session;
  • runs both a standalone WebEngine smoke config and the patched DMS root for a short duration.

It does not modify /usr/bin/qs, /usr/bin/quickshell, /usr/share/quickshell/dms, pacman state, or the normal user config. Logs are written under .quickshellx-test/logs/.

Cleanup:

./scripts/cleanup-quickshellx-webengine-test.sh

Useful overrides:

DMS_WEBVIEW_TEST_SECONDS=30 ./scripts/quickshellx-webengine-test.sh run-dms
QUICKSHELLX_REF=<branch-or-commit> ./scripts/quickshellx-webengine-test.sh all

Installation

From this repository root:

./install.sh

The installer only copies these exact plugin directories into ${XDG_CONFIG_HOME:-$HOME/.config}/DankMaterialShell/plugins:

  • plugins/WebviewBar
  • plugins/WebviewControlCenter
  • plugins/WebviewDesktop

It does not modify Quickshell, DMS root QML, shell configuration, package manager state, or the user's bar layout.

After installation:

  1. Open DMS Settings -> Plugins.
  2. Scan for plugins.
  3. Enable webviewBar, webviewControlCenter, and webviewDesktop.
  4. Add webviewBar to DankBar.
  5. Add or enable the Control Center and Desktop surfaces through the DMS UI.
  6. Restart DMS or reload plugins.

Optional IPC reload commands:

dms ipc call plugins reload webviewBar
dms ipc call plugins reload webviewControlCenter
dms ipc call plugins reload webviewDesktop
dms ipc call plugins list

Security constraints

Remote rendering accepts only http:// and https:// URLs.

Local rendering accepts only relative .html files under each plugin's own html/ directory, using paths such as ./html/bar.html or html/popup.html. Absolute paths, parent-directory traversal, file:, data:, javascript:, empty strings, and non-HTML files are rejected.

Page JavaScript cannot:

  • run shell commands;
  • write DMS settings;
  • load arbitrary local files;
  • access pluginService;
  • access popoutService directly;
  • call arbitrary QML properties or methods.

Unknown or unavailable bridge actions return false or an empty string instead of throwing uncaught QML exceptions. Empty, missing, invalid, or failed sources show an in-plugin error panel instead of a blank webview.

Local examples

Each plugin ships HTML examples that load:

<script src="qrc:///qtwebchannel/qwebchannel.js"></script>

The examples create window.dmsPluginReady, bind window.dmsPlugin = channel.objects.dmsPlugin, and then demonstrate local popouts, remote popouts, selected DMS popout actions, bridge context, and close-self behavior.

Remote pages are rendered as ordinary web pages. Their ability to call window.dmsPlugin depends on their own JavaScript and Content Security Policy.

Contributors

ParticleG

Issues