Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extension (plugin) support #30

Open
The-Compiler opened this issue Oct 1, 2014 · 83 comments
Open

Extension (plugin) support #30

The-Compiler opened this issue Oct 1, 2014 · 83 comments

Comments

@The-Compiler
Copy link
Member

@The-Compiler The-Compiler commented Oct 1, 2014

There should be support for writing plugins which are more complex than the simple (non-js) userscripts. Python plugins are the way to go.

FAQ

What's the current state of this issue?

September 2018: I'm working on this as a student research project. The main focus is designing a clean plugin API which can then be used to move internal qutebrowser parts to "plugins". As soon as this work is done (late 2018), the next step is gradually opening up the plugin API to third-party plugins.

March 2019: The research project went quite well (paper), but also was quite academic - not that much time was actually spent on implementation. As a result, there's now an initial extension API used internally in qutebrowser, but it's far from finished and not open to third-party extensions yet.

I likely won't have much time to continue working on extensions until my bachelor thesis is finished in mid-June (see the announcement mail for details), but after that I plan to launch another crowdfunding focused on long-term donations (Patreon/OpenCollective). This should allow me to work 2-3 days per week on qutebrowser for a longer time, primarly focused on finishing extensions.

September 2019: See this announcement mail for a longer recap of how the research project went. I finished my Bachelor thesis and had my final exams in late August. This means my studies are now finished and I finally have more time for qutebrowser on my hands again. Like outlined in that announcement mail, I'm now employed around 16h/week, while I plan to spend the rest of the time on qutebrowser and some freelancing work. At the moment, I'm planning the next crowdfunding campaign (also see the related survey) and getting things set up. After things are rolling, there are some things which are currently more urgent than plugin support: Making sure things continue to work with the latest Qt 5.13/5.14 versions and taking care of a lot of contributions. Once that backlog is down and some other work I started is finished, I finally plan to get back to extension support again, this time with enough resources to get things to a working state!

October 2019: See the recent roadmap mail for more details on what's going on in qutebrowser development - this definitely isn't forgotten, there are just some more important things to look at first. I also launched the next crowdfunding which will allow me to work on qutebrowser part-time (without having to write a research paper this time 😆) and hopefully accelerate things a lot.

How can I get updates?

Subscribe to this issue. You might also want to subscribe to the qutebrowser-plugins repository and the qutebrowser-hsr-sa repository where the related university documentation will land (also check the releases if you're curious).

What about JavaScript plugins / WebExtensions?

Support for WebExtensions is currently out-of-scope for qutebrowser. It's hard to even evaluate to which extend support for them would be possible, but if possible, it's going to be a lot of work. Partial support for often used plugin APIs (i.e. some WebExtensions) might happen some day, but currently it's too early to say if/when. The main focus is on a Python plugin API right now. Related QtWebEngine issues which might make this easier: QTBUG-51185, QTBUG-61676.

Also, a Python plugin API will allow for more freedom, since we treat plugins as trusted code.

Why don't you just allow people to inject Python code into qutebrowser?

Firefox had the issue of having a plugin API which tightly integrates with its internals, and had to drop it because it made further Firefox development harder, and bigger changes impossible. Also, every Firefox update broke a lot of plugins. This is not what I want things to end up like with qutebrowser.

In theory, you can do some things via a config.py file, like done in the qutenyan project. However, this is entirely unsupported and discouraged.

Do you call them plugins or extensions?

They used to be called plugins - however, since that term is often used to refer to NPAPI/PPAPI plugins (like Flash) in the context of web browsers, they were later renamed to extensions.

Plugin ideas

  • uMatrix: #28
  • More sophisticated adblocking: #29 (host-blacklist based adblocking is implemented in qutebrowser's core)
  • HTTPS everywhere: #335
  • Ghostery/Disconnect
  • Certificate Patrol
  • (random) user agent switcher
  • Mouse gestures (can be done via easystroke to some degree)
  • Remove google redirects
  • Integration with LanguageTool
  • Filling forms (e.g. password management with KeePassX/gnome keyring/passwordstore/... - as in #180, also form filling as in #695)
  • HoverZoom
  • speed dial
  • periodic auto-reload
  • detailed page loading bar (like otter/opera)
  • automatically spawn mpv on video pages
  • Find video URLs on a page, like Media Sniffer or Video DownloadHelper
  • copy URLs of all pages or write them to a file
  • DownThemAll
  • Google Cloud Print (devguide)
  • Rewriting URLs to their .onion equivalents based on a list
  • Chromecast integration? (#1319)
  • autoscroll
  • decentraleyes
  • URL rewriting like PureURL for Firefox (removing things like utm_foo)
  • Open certain links (like youtube) in a handler application automatically instead of following it
  • Adding a "real" address bar
  • Adding a bookmarks bar
  • Yanking a short URL (e.g. youtube has a shortlink ref for youtu.be links)
  • Restarting failed downloads after a timeout (with bad internet connection)
  • alternative stylesheet selector
  • A way to show md5/sha/etc. for downloads or even enter the correct one.
  • Plasma Shell browser integration (#3996)
  • Exposing the plugin API as an RPC interface usable from other languages
  • Integrating Wallabag or other bookmark managers
  • Back/Forward by domain instead of page
  • Controlling Spotify/Youtube via MPRIS: #5023
  • Middle-click scrolling (like on Windows)
  • Noiszy (Background tab creating "browsing noise")
  • also see existing dwb userscripts
  • Hooking into notifications
  • Showing the current mode in something like i3bar
  • Prompting for redirects (?), see #4534

Abilities that plugins should have

  • Interact with the WebElements on the page (e.g. make non-clickable links clickable) - or maybe only do this via JS, e.g. Linkify.
  • Add widgets to the statusbar. (e.g. RSS or search engine symbol)
  • Register new commands (with capital letter, like vim)
  • Register new settings (in a special [plugin.foo] section probably)
  • Subscribe to Qt signals (QWebPage/QWebView)
  • Add new completions, e.g. with an external bookmark manager like cym13/bookmark
  • Create widget-tabs when #724 is done, so someone could theoretically write an RSS reader or mail client or whatever
  • Adjust page content, like Detox (and many others)
  • Maybe make it possible to interact with the command input so that adding www. and .com to an URL like in #1749 would be possible.
  • Maybe bind keys with prefixes, e.g. g# with any number
  • Use acceptNavigationRequest, e.g. to automatically open mpv if a YouTube link is opened.
  • Custom URL schemes
  • Custom completions (see #3376)

Libraries

Resources

Javascript plugins

  • Javascript: QJSEngine
  • PyV8 would probably work as well for javascript extensions (and maybe be easier/more pythonic), but it's another dependency and a different javascript engine.

It's probably not possible to directly use QtWebEngine's JavaScript engine, as that's tightly connected to QWebEnginePage actually showing a website.

Possible API inspirations

Other interesting links

First ideas

Separate namespace for plugins

There should be a new qutebrowser.pluginapi namespace. Everything outside of that namespace is to be considered to be "private" for plugins, and will likely break at some point.

Only some stuff (like possibly utils.urlutils) will be exposed directly - everything else will be exposed through a wrapper, for various reasons:

  • I can change stuff without breaking plugins, if I update the wrappers accordingly.
  • The wrappers will be easier to expose to a javascript plugin API
  • They will be less complex than the qutebrowser internals, so it should be easier to get started

If something is missing from the wrappers, it should be trivial for a plugin author to open a feature request to have it added - this should be encouraged in the docs.

Qt signal based workflow

I don't think using something like pluggy will be neccessary (especially because pluggy is still expected to undergo changes, and is not packaged).

Instead of that, there's a simple function (say, plugin_init) which gets called when a plugin is loaded. The plugin gets a PluginContext object with some version information and a signals attribute.

The signals object then has many signals (perhaps also in sub-objects), like started, cmd.entered, etc. etc. Such a signals object also exists per-tab and per-window. The plugin will get the window-specific object with a global new_window signal (and something similar for new tabs).

Those events/signals are the main entry point for plugins. There will also be APIs for certain tasks (like adding an icon to the statusbar), but the majority of tasks should be possible using those signals.

For most actions, an API to call commands nicely (i.e. as functions rather than as strings) would probably already suffice.

Exposing plugin signals to userscripts

This is related to #902 - the signals mentioned above should be written to userscript FIFOs so those can react on the events - similar to herbstluftwm's hooks and herbstclient --idle.

This could possibly be implemented as a plugin by itself, which binds to all available signals - some layer to transform the signal arguments to strings will be needed either way.

A line written to the FIFO could look like this:

category sender signalname arg1 arg2 ...
  • category: For extensibility - currently always signal
  • sender: A dotted path of the sender of the signal, i.e. which signal object from above emitted the signal:
    • global: A global signal, like started
    • win0: A signal from the window with win ID 0
    • win0.tab1: A signal from the tab 1 in window 0
  • signalname: A dotted path of the signal, e.g. started or cmd.entered, etc.
  • arg1, arg2: Arguments which were passed to the signal, which need to be converted to a string in some way. Either there's a plugin which handles this argument for argument, or there's type-checking:
    • str: passed through
    • int, float: str() called on them
    • QUrl: url.toString() called on them
    • window objects -> win0
    • tab objects -> win0.tab1

Resources from BPL

resources

libraries & apps

@noctuid

This comment has been hidden.

@cwmke

This comment has been hidden.

@lamarpavel

This comment has been hidden.

@The-Compiler

This comment has been hidden.

@The-Compiler The-Compiler removed their assignment Oct 1, 2015
@traverseda

This comment has been hidden.

@The-Compiler

This comment has been hidden.

@traverseda

This comment has been hidden.

@The-Compiler

This comment has been hidden.

@traverseda

This comment has been hidden.

@btall

This comment was marked as off-topic.

@RomanSC

This comment was marked as off-topic.

@The-Compiler

This comment was marked as off-topic.

@lamarpavel

This comment has been hidden.

@The-Compiler

This comment has been hidden.

@Yodzorah

This comment has been hidden.

@ghost

This comment has been hidden.

@The-Compiler

This comment has been hidden.

@ghost

This comment was marked as off-topic.

@The-Compiler

This comment was marked as off-topic.

@kepi

This comment was marked as off-topic.

@ghost

This comment was marked as off-topic.

@The-Compiler
Copy link
Member Author

@The-Compiler The-Compiler commented Nov 2, 2018

I'm not usually in favor of shutting down discussions, as people who follow qutebrowser development might know - however, after talking to some other contributors, I'm now locking this issue.

I just went through the ~80 comments here again, and condensed everything that has been said into the first post (including a small FAQ) or into related issues. There was a lot of reappearing discussion which was already discussed earlier in the issue, and frankly, I'm tired of people acting like I owe them a plugin API ASAP (hint: there's a difference between "Please" and "PLEASE").

The best way to get updates about work on the plugin API is to subscribe to this issue, same like with other issues. Comments which aren't actually related to how the plugin API should look just mean dozens (hundreds?) of people interested in this issue get yet another mail - kind of defeating the purpose of subscribing to it to get updates.

If you have something useful to contribute which isn't mentioned in any of the still visible comments, feel free to reach out via other means, and I'll update the comments with further ideas.

@qutebrowser qutebrowser locked as off topic and limited conversation to collaborators Nov 2, 2018
@The-Compiler The-Compiler moved this from Backlog to In Progress in Extensions Nov 30, 2018
@The-Compiler The-Compiler changed the title Plugin support Extension (plugin) support Dec 10, 2018
@The-Compiler
Copy link
Member Author

@The-Compiler The-Compiler commented Mar 18, 2019

I just posted a roadmap mail to the announcement mailinglist - here's the gist of it related to extensions:

The research project went quite well (paper), but also was quite academic - not that much time was actually spent on implementation. As a result, there's now an initial extension API used internally in qutebrowser, but it's far from finished and not open to third-party extensions yet.

I likely won't have much time to continue working on extensions until my bachelor thesis is finished in mid-June (see the announcement mail for details), but after that I plan to launch another crowdfunding focused on long-term donations (Patreon/OpenCollective). This should allow me to work 2-3 days per week on qutebrowser for a longer time, primarly focused on finishing extensions.

@The-Compiler
Copy link
Member Author

@The-Compiler The-Compiler commented Sep 14, 2019

I just added an update: See this announcement mail for a longer recap of how the research project went. I finished my Bachelor thesis and had my final exams in late August. This means my studies are now finished and I finally have more time for qutebrowser on my hands again. Like outlined in that announcement mail, I'm now employed around 16h/week, while I plan to spend the rest of the time on qutebrowser and some freelancing work. At the moment, I'm planning the next crowdfunding campaign (also see the related survey) and getting things set up. After things are rolling, there are some things which are currently more urgent than plugin support: Making sure things continue to work with the latest Qt 5.13/5.14 versions and taking care of a lot of contributions. Once that backlog is down and some other work I started is finished, I finally plan to get back to extension support again, this time with enough resources to get things to a working state!

@The-Compiler
Copy link
Member Author

@The-Compiler The-Compiler commented Oct 30, 2019

See the recent roadmap mail for more details on what's going on in qutebrowser development - this definitely isn't forgotten, there are just some more important things to look at first. I also launched the next crowdfunding which will allow me to work on qutebrowser part-time (without having to write a research paper this time 😆) and hopefully accelerate things a lot.

@The-Compiler The-Compiler added this to the v2.0.0 milestone Dec 31, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Extensions
  
In Progress
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.