Take control of your web.
Weaver is a qt6-webengine browser focused on displaying web pages and offering customizable and scriptable user control mechanisms. There is no gui (or "user chrome") other than the windows that display web content and a few qt6 dialog windows. All behavior is controlled by commands via the comand line and users scripts (example scripts include extensive key bindings, hinting, and styling).
Below is a reference list of all currently available commands. Arguments in brackets are optional. Below the table are notes on a few of the commands that may require further explanation.
||action name||Run the specified WebAction in the target window|
||N/A||Close the currently targetted window|
||N/A||Open this README on the project webpage|
||[format]||Provide information about the focused window following format|
||N/A||Launch a devtools / inspector page for the target window|
||[script content]||Alias for
||[script content]||W/ args, send script to target to run; w/o, check for results|
||[format]||List every open window with it's index and
||url / search||Open the provided url, or send provided text to the search page|
||name||Create a new profile named name in the targetted window|
||N/A||Close all windows and exit|
||index||Target the window by index or create a new window if 0|
||user-agent-string||Sets a new user-agent-string for the targetted window|
The list of available actions and their names can be found
here. For example
//action/Back would navigate back one step in the history. Action names are
Either of these commands can be used without arguments and will provide a useful
default. But a format string can be provided to customize the output. Format
specifiers for this string are in the table below. The default for
//list just prepends a window number (this window number can
be used for
|%3||All selected text on the page|
the script you provide, then you can use just one call to this command. For
example, to popup an alert in the currently targetted window you'd use
//js/alert('Hello World');. This would need to be quoted appropriately to be
used on the command line to prevent shell interpretation of the parentheses:
weaver "//js/alert('Hello World');"
If you want to get the result of the script (i.e., the value of the last line
of the script), you need to make a second call to the
//js command but with no
//js command will either return a message that no data is
available (which means the script is still running) or it will return the
result (which may be an empty string).
For trivial js calls like
//js/location.href you could pass both commands at
once and likely have success:
weaver //js/location.href //js
However for any substantial script, there is potential that the results might not be available yet for the second command. It's recommended to either wait a moment between entering the two, or use a sleep command:
weaver "//js/longFunction()" sleep 0.5 weaver //js
The above assumes
longFunction() was already defined on the page, perhaps by a
The profile command should be provided with a name as a parameter. This name
will identify the alternative profile to be used in the target window. It will
also define the on-disk name of the profile. If this is an empty string, it
will result in a RAM-only profile in which no content is stored to disk. This
is often called private mode or incognito mode (thus the
//icognito alias for
Note, however, that this change in profile applies only to the targetted window. Any subsequently created windows will revert to using the default profile.
Target must be passed an integer parameter and this must either match the index
//list output to identify a target window, or it must be 0 to
specify that a new window should be created and targetted for subsequent
Note that window indices are dynamic. Internally a list of open windows is
maintained. The order of this list can be changed explicitly by //target/
commands, but it will also change every time a window is focused or brought to
the front. In these cases, the focused / targetted window is popped from it's
previous position in the list and prepended to be at the first position. So if
you check a window's index from the
//list command, then cycle through
windows, that index may no longer point to the same window.
If no target is explicitly specified, most commands will act on the first window in the list (generally the most-recently focused weaver window). Some commands (those that will change window content like close, open, action, etc) will only act on either the currently focused or explicilty targetted windows.
Please see the well commented config.conf in the examples directory. Copy this
file (or create your own) under
Examples of some of what can be done with userscripts are provided in the *.js files in the examples directory. These include key bindings, hinting, image viewing, and some custom CSS. User submissions of other interesting scripts are most welcome on the ticketting system.
Google services' sign in page actively blocks connections from browsers with QtWebEngine in their user agent string. You can quite easily use google services (calendar, gmail, etc) in weaver, but you need to do the following steps just once to get started.
- Set the user agent to a non-webengine string
- Log in to a google service
- Reset the user agent or just close the ua-spoofing window
- From then on you will be able to access google services with out any spoofing
The following command will do step 1 and allow you to do step 2:
weaver //target/0 "//ua/Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0" calendar.google.com
There most definitely are some, and there will be more. If you see them before I do, feel free to submit detailed descriptions via the ticketting system.
Current issues under investigation
Shift+Insert pastes clipboard rather than primary selection in Qt. This is far from ideal. Options under consideration:
- Override event handler to catch this key and ... still not sure how to paste primary
2+helper: add weaver://selection type command that returns primary selection content. Then in keys.js handle S+insert ...
Note: middle-click still pastes the primary selection. Perhaps a workaround for shift-insert is not worth the effort.