* This PR added an undocumented function `ManifestDPIAwareness` and enable `PerMonitorV2` support (requires Win10 1703+)
691211035c/Docs/src/attributes.but (L290-L292)
* Remove `XPStyle` because this function do nothing on NSIS 3.x
PR #23426.
If a process is an orphan (without a parent) then the process won't exit when qbt exits and
the process will be still running. This is unwanted behavior.
PR #23422.
Previously, WebUI was using a HTTP Session Cookie. This type of cookie is tend to be dropped by
the browser on mobile platforms and gives a bad experience on the WebUI. Now the cookie is a
permanent one and is guaranteed to be persisted between browser restarts.
Closes#20993.
PR #23392.
Make the Web UI login more mobile friendly.
The main action is moving to a column layout for the logo and form. This way it's easier for mobile to view the page but it doesn't affect the desktop experience much.
Secondary it set the input font size to be default text size, this in turn makes it so the mobile ui doesn't zoom in when you focus the inputs. [You can read more about it here](https://wsform.com/knowledgebase/why-forms-zoom-on-some-mobile-devices-and-browsers-and-how-to-control-it/).
PR #23360.
macOS 26 uses new design for app icons, with a different corner radius for app icons, making the previous icon unfit for the new version. Hence I created a new icon with the project folder attached (AppIcon.icon).
I also updated the document icon to give it a more modern style. And an icon for temp files (!qB files), and I have edited the info.plist accordingly.
PR #23365.
---------
Co-authored-by: Chocobo1 <Chocobo1@users.noreply.github.com>
Qt >=6.8 can native compile on Windows ARM64 machine, and GitHub also provides windows-11-arm runner. so I think It's time to add support.
I've tested from my branch and Snapdragon 8cx gen3 computer. all ci build passed.
Closes#11465
PR #23328.
The result is shorter code and improves readability.
Note that `asConst()` is still required for non-const containers, otherwise the container will
detach.
PR #23342.
Adds a search bar for RSS items. It supports plain text search (no regex), applies only to the selected tab, updates results as you type, and shows all items when the field is empty.
PR #23278.
Resolves#14719, resolves#15538, resolves#18444, resolves#18183, resolves#22570.
---------
Co-authored-by: Vladimir Golovnev <glassez@yandex.ru>
Co-authored-by: Chocobo1 <Chocobo1@users.noreply.github.com>
When using virtual tables we can't rely on fetching the values from the DOM. We should always fetch values directly from the file tree.
PR #23263.
Closes#23241.
Multi-selection for default LMB action, as before 5.1 update.
Adds option to select grab as the default behavior, for users who don't have the Alt key available.
Holding the Alt key toggles between grab/multi-selection.
PR #23180.
Closes#22686.
`same-origin`
> Sends the full URL (stripped of parameters) for same-origin requests. Cross-origin requests will contain no referrer header.
This would be helpful for 3rd party WebUI that were forked from the
official one. The official WebUI is not affect by this change since the
request is blocked by CSP.
PR #23294.
This will be useful for development and debugging issues. The messages will be outputted to both console and qbt logger.
Note that having stderr messages does not always mean the operation failed but there might be some (non-fatal) issues.
PR #23293.
Closes#6553. Closes#22381. Closes#23052.
The CLI options should allow the `=` (equals) char as value so doing `--save-path="/home/test/mydir = somedir"` should parse properly with the `value` method returning `"/home/test/mydir = somedir"`.
Closes#23248.
PR #23251.
---------
Co-authored-by: Vladimir Golovnev <glassez@yandex.ru>
Co-authored-by: Chocobo1 <Chocobo1@users.noreply.github.com>
* Install `NSIS` via https://github.com/repolevedavaj/install-nsis
* `NSIS` is no longer installed on GitHub provided Runner Image as of `windows-2025`
* `NSIS: 3.10` was only available on `windows-2019 / windows-2022`
* We can use newer release now eg. `NSIS: 3.11`.
PR #23249.
This fixes an annoyance I've hit with the WebUI CI checks. If the linter fails, the GH Action immediately exits before the formatter has run. This can mean fixing the lint error and pushing up a change, only for the GH Action to then fail due to the formatter check.
This PR makes it so that all checks always run, with the job still failing if any of the checks failed. It should allow for a quicker feedback loop. For an example, see #23199
GitHub Action docs: https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#steps-context
PR #23198.
* WebAPI: return error message when endpoint not found
* WebAPI: send appropriate status code when logging in
* WebAPI: return more info when adding torrents
PR #23202.
Closes#375.
Closes#10688.
Closes#10747.
Closes#11464.
This provides a mechanism for persisting WebUI client preferences that are distinct from the broader qBittorrent preferences. These preferences apply exclusively to the WebUI.
PR #23088.
Firefox seems to have an issue where svgs loaded via background-url are not animated. Loading the svg directly as an img fixes this.
Related: #23074.
PR #23195.
The WebUI part of the changes for #23061. Now qBittorrent will display I2P peers in WebUI peers tab.
Fixes the second part of #19794 ("i2p peer list does not show in GUI").
PR #23185.
These `fetch` calls properly handle 4xx and 5xx errors, but don't handle network errors. In all cases, I've used the same logic as the `!response.ok` branch of each individual fetch function. This should ensure consistent behavior.
PR #23164.
This adds support for downloading a torrent via a search plugin's `download_torrent` function. This primarily affects torrents that use a private tracker requiring a login.
Closes#18334.
PR #23163.
Now it utilize type stub for PySocks library and all search engine python code are properly
type checked.
Note that a `cast` is required because there isn't enough hints in PySocks to let the type
checker understand that the classes are supposed to be compatible.
PR #23183.
This TODO has been in the code for 8 years since it was added in #6475 (commit b271fa9f00). It appears to have been related to the `skipChecking` variable, though what it actually means has been lost over time. Note that both the `savePath` and the `downloadPath` are recursively created if they don't yet exist.
PR #23165.
Implements a native macOS status bar item that displays the qBittorrent icon and provides a minimal menu showing live download and upload rates. This allows quick network activity checks without switching to the app window or relying on the Dock.
Closes#22545.
PR #23098.
Due to `allowSeparatedGroups = true`, the sorting is applied on a group of consecutive imports.
That means a new group of imports can be created by adding a blank line.
Parse HTTP headers using raw byte arrays instead of strings. This allows us to apply different encodings for different parts.
This change is backward compatible and should not affect any existing operation, so WebAPI version bump is not required.
PR #23083.
This PR adds the ability to direct modify a tracker's tier from the WebUI. This process is notably different than the GUI, which provides arrows for increasing/decreasing a tracker's tier.
Closes#12233.
PR #22963.
Implemented: Tracker endpoints in the list, missing "Tracker Error" and "Unreachable" status, "Next Announce" and "Min Announce" column and double click to edit tracker url.
PR #23045.
This PR uses the new APIs from #21015 to provide a WebUI Add Torrent experience more closely matching the GUI's.
New functionality:
- View torrent size, date, infohash, files, etc.
- Reprioritize and ignore files before adding
- Specify tags when adding torrent
- Specify save path for incomplete torrent
Closes#20557, closes#10997, closes#12499, closes#14201, closes#15071, closes#15718, closes#16207.
PR #21645.
The methods for checking if qBittorrent is set as the standard application for opening torrent files and magnet links and setting qBittorrent as the standard application for those is using deprecated methods now. For example `LSCopyDefaultHandlerForURLScheme` and `kUTTagClassFilenameExtension`.
The new methods have been moved to `macutilities.mm` because in `os.cpp` cocoa couldn't be imported.
PR #23059.
Currently the hardened runtime is enabled for code signing in the github workflow for macOS. However in this thread https://github.com/qbittorrent/qBittorrent/discussions/23041#discussioncomment-13969415 a user had a problem to open the nightly builds from github. Relevant part of the error:
```
Reason: tried: '/private/var/folders/y0/jmsflc717tn_tj2x9d1g3d9w0000gn/T/AppTranslocation/8B53E367-2E0C-42C1-A4D5-6787109EE46E/d/qbittorrent.app/Contents/Frameworks/QtWidgets.framework/Versions/A/QtWidgets' (code signature in '/private/var/folders/y0/jmsflc717tn_tj2x9d1g3d9w0000gn/T/AppTranslocation/8B53E367-2E0C-42C1-A4D5-6787109EE46E/d/qbittorrent.app/Contents/Frameworks/QtWidgets.framework/Versions/A/QtWidgets' not valid for use in process: mapping process and mapped file (non-platform) have different Team IDs), '/private/var/folders/y0/jmsflc717tn_tj2x9d1g3d9w0000gn/T/AppTranslocation/8B53E367-2E0C-42C1-A4D5-6787109EE46E/d/qbittorrent.app/Contents/Frameworks/QtWidgets.framework/Versions/
(terminated at launch; ignore backtrace)
```
Further investigation showed that when disabling the hardened runtime this won't occur any more. I haven't noticed this before because the error wouldn't occur when SIP (system integrity protection) is disabled and I have it disabled now.
PR #23058.
Currently `NSUserNotifications API` is used on MacOS to display notifications. However this is marked as deprecated and should be replaced with `UserNotifications.frameworks API`. With the new API it is required to ask for permission before notifications can be send. The program will ask for permission to send notifications on the start.
Related: #15630.
PR #23019.
The following message appears when using the outdated value:
>[@stylistic/eslint-plugin]: You are using deprecated value(boolean) for "allowTemplateLiterals"
>in "quotes", please use "always"/"never" instead.
Also prefer using double quotes over backticks for strings.
PR #23038.
Now when user specified 'help' or 'version' flag, the program will process them first and
ignore all other flags (even invalid flags).
This improves program usability since user will be able to consult the help description without
ensuring existing flags are all valid (or removing all flags). And user can refine the flags
after reading the help description.
PR #23037.
Currently `iconForFileType` is used on macOS to display the file icons in the content tab. However this is marked as deprecated and should be replaced with `iconForContentType`.
Related #15630.
PR #22992.
Currently when you delete or move a torrent sometimes an empty folder will stay. This is because hidden files will stay which didn't got deleted.
The reason that it is not working is that QDir::Files is used which doesn't lists hidden files. Adding QDir::Hidden will make the code work as expected. At least on Windows and macOS QDir::Files doesn't lists hidden files. I can't test on linux.
PR #22983.
When a category's download path option is set to "Default", its `downloadPath` is serialized into JSON as `undefined`. This results in the `downloadPath` field being omitted from `torrents/categories` and `torrents/maindata` payloads (as is expected with an `undefined` value).
The use of `undefined` here causes an issue in the WebUI. Specifically, when the category previously contained a value for this field (i.e. download path option set to either "Yes" or "No"), the `processMap` logic in `SyncController` does not detect the removal this field. This results in the category's new `downloadPath` not being properly sent to the client. By switching from `undefined` to `null`, we ensure that the `downloadPath` value is always included in the category's payload. This allows `processMap` to properly detect whenever the value changes.
This change is backwards compatible with existing categories.json files. Older qBittorrent versions should also be able to parse new categories.json files containing `null`.
More context: cd3fbfbf9b (r2173148696)
PR #22958.
This change makes the WebUI easier to use on small screens (e.g. mobile). In cases where the window's default size is larger than the user's screen, the window will be resized appropriate (see example below). Every window has been tested for compatibility. The only windows that don't support this are the multi file rename window and the RSS Downloader window.
Closes#19813.
PR #22919.
This change better handles resizing of elements on the search page to ensure no controls are hidden at typical mobile screen sizes.
Improvements seen below:
- "Search" button is now accessible
- Content no longer overflows w/ "Search plugins..." button pushed offscreen
- Tabs overflow horizontally and are scrollable, rather than pushing down the search results table
PR #22916.
The toolbar should be hidden when not on the "Transfers" tab. The hiding of this toolbar can result in resizing the panels, especially on mobile, so we should recompute panel heights.
PR #22915.
Previously, the tabs would overflow to the next line, often being hidden by other content. For example, the "Content" tab is now accessible on mobile.
PR #22914.
`m_torrentMetadataCache` previously used a torrent's InfoHash as its key. However, InfoHashes for hybrid torrents cannot be serialized and deserialized via their TorrentID (e.g. `InfoHash(TorrentID(infoHash.toTorrentID().toString())) != infoHash`). This is due to hybrid InfoHashes containing both a v1 and v2 hash, while the serialized TorrentID only contains a single truncated v2 hash. Thus we cannot expect an InfoHash serialized by its TorrentID to be able to construct an equivalent InfoHash. By switching to the TorrentID, we always have a single ID to use.
Follow up #21015.
PR #22926.
This brings a fallback version check to the update mechanism,
which should be as stable as it can be.
It will allow migrating to another primary mechanism without
having to have updated the older primary mechanism too.
Hacked qbt instances may contain malicious script placed in Run External Program and the script
will attempt to hide itself by adding a lot whitespaces at the start of the command string.
Users may mistake the field of being empty but is actually not.
So trim the leading whitespaces to easily expose the malicious script.
Note that GUI already trim the fields and only WebAPI doesn't trim them. This patch will unify
the behavior.
Related: https://github.com/qbittorrent/docker-qbittorrent-nox/issues/71#issuecomment-2993567440
PR #22939.
* WebUI: use defer when loading scripts
So that the HTML layout can be rendered earlier.
* WebUI: move scripts into <head> section
For consistency reasons.
This change drastically improves the performance of changing a table's sorted column. This performance is achieved through improved data structures, namely removing operations that repeatedly spliced an array. We also no longer iterate over a potentially large array.
On a torrent with ~50,000 files, re-rendering after a sort improves from ~20 seconds to 2 seconds.
PR #22827.
When double clicking on a filter, all other filters will be reset. For example, double clicking on a status filter will reset the categories, tags, and trackers filters to "All". This behavior can be disabled in WebUI options.
Closes#22449.
PR #22818.
This change ensures that the WebUI caches relevant server stats for immediate display once the statistics window is opened. Previously, all stats would remain blank until maindata was fetched. This could take a while if e.g. the user was on the search tab.
Closes#22764.
PR #22817.
The Language option now has its own layout since it is independent to other options (Style and Color scheme).
This avoids text in Language combobox to be left out and replaced by `...` due to Style Hint text being too long.
PR #22823.
## Description
Send file/folder metadata instead of just the name of a filesystem entry.
Currently the endpoint only sends a list of string, containing the path of each entry, without specifying its type (file or folder).
The optional `withMetadata` flag has been added to provide metadata and to prevent breaking changes with older versions.
If `true`, JSON response will be an array of objects instead of an array of strings.
This object contains:
- `name`: the name of the file system entry (without path)
- `type`: Whether the file system entry is a "file" or a "dir"
- `creation_date`: file system entry's creation date
- `last_access_date`: file system entry's last access date
- `last_modification_date`: file system entry's last modification date
If the entry is a file, a `size` field is present with the file size in bytes.
## Objective
Build a server file browser inside WebUIs, feature is currently being developed for VueTorrent.
It will include file metadata, filtering and sorting on the different fields.
PR #22813.
In #22567, I made it so the web UI wouldn't refresh the main data while the page is hidden. This causes the session to time out (after 1 hour by default).
This PR changes that to instead refresh every Preferences/WebUI/SessionTimeout / 2 instead of not at all, which should keep the session alive.
PR #22804.
See #22734, there is a memory leak in the MooTools .destroy(), this replaces all uses of that with the browser native .remove().
This also overrides the MooTools Document.id function, which is used by $(id). The original function always allocates an ID to elements it selects, the override doesn't, and is also a little more efficient.
Closes#22734.
PR #22754.
---------
Co-authored-by: Chocobo1 <Chocobo1@users.noreply.github.com>
Now it checks for all python installations and related procedures has been revised.
If the python version does not meet the minimum requirement, it will be logged.
PR #22729.
This PR improves the user experience on mobile devices by ensuring the username field in the login form does not automatically capitalize the first letter when the keyboard opens.
Mobile browsers tend to automatically capitalize the first letter of text inputs, which can lead to login failures if the username is case-sensitive. By explicitly disabling autocapitalization, the WebUI ensures a more predictable and user-friendly experience on mobile devices.
Tested on:
iOS (Safari)
Co-authored-by: Chocobo1 <Chocobo1@users.noreply.github.com>
PR #22725.
Before the release of 5.1.0 I believe these two fields both used monospace fonts and also had an increased font size, maybe 14px (I couldn't find in blame where/how this regressed). Ideally, I'd like to bring this back, as it makes elaborate regexes easier to grok. This PR currently just tells the browser to use its monospace font, but I could also add a similar in-line style for font size. I just don't know if this is the best way to solve this problem; if there's a better place for this sort of styling to happen let me know
PR #22719.
For windows environment the `--help` output will show :
```
set QBT_NO_SPLASH=1
C:\Program Files\qBittorrent\qbittorrent.exe
```
instead of
```
QBT_NO_SPLASH=1 C:\Program Files\qBittorrent\qbittorrent.exe
```
Fixes#22662.
PR #22695.
Memory working set limit is not effective on Linux at all. See [`getrlimit(2)`](https://man7.org/linux/man-pages/man2/getrlimit.2.html) → `RLIMIT_RSS`.
Introduced in #16874, disabled for macOS in #19805. This PR hides the option for Linux too.
Worth to mention that #19805 did not deliver the change for WebUI. So there is also a small fixup, I covered both cases.
Also removed pointless "This option is less effective on Linux" remark.
PR #22680.
Mootools is no longer used to create PiecesBar class (+ I cleaned it up a bit and turned into custom element but everything should work as before).
PR #22670.
Making General-tab text `unselectable` is not an improvement.
It begs to add a new `Copy -> Save path` feature, because using `Set location` to copy save path (*which requires a request*) is not faster than simply copying it from the `General` tab by double-left clicking and pressing `CTRL+C`.
I don't see a reason why its necessary to software-restrict people from copying details from the `General`-tab - there are several reasons why you would - incl. the above mentioned usecase for quickly copying save-path, but other than that its counterproductive to limit people from copying the details displayed.
PR #22663.
Convenience feature in the "Rename Files" menu in the WebUI.
If you click one file's checkbox, and then click another with Shift held, all the checkboxes between those two will be selected/unselected based on the state of the first checkbox.
It's based on what the Windows file explorer does when holding Ctrl and Shift
Closes#22455.
PR #22610.
Makes asynchronous logic to look more straightforward.
Allows caller to choose blocking or non-blocking way of obtaining asynchronous results via the same interface.
PR #22598.
Deferring the opening of the preview slightly gives the preview select
dialog time to close and for focus to shift back to the main window.
PR #22608.
Closes#22607.
---------
Co-authored-by: Vladimir Golovnev <glassez@yandex.ru>
Currently, there is unnecessary CPU/network usage by the web UI when it's running in the background, this PR prevents it from refreshing in the background.
Closes#22565.
PR #22567.
Adding virtual list support to dynamic tables to improve performance on large lists, I observed a 100x performance improvement on rendering on a torrent table with 5000 torrents.
This optimization is disabled by default and can be enabled in options.
PR #22502.
Add clamping for seeding and inactive seeding time limit on setting from dialog and loading from config.
Closes#21953.
PR #22558.
Signed-off-by: Kostiantyn <kos.chernenok@gmail.com>
Swap "Add torrent file" with "Add torrent link" button to be consistent with order in File menu.
Closes#22420.
PR #22557.
Signed-off-by: Kostiantyn <kos.chernenok@gmail.com>
Previously it require each plugin to import helpers.py to setup SOCKS proxy.
Now it is enforced by default for all plugins.
Also added a function for plugins to ignore/restore the socket to
default state.
PR #22554.
Pass 'Perform hostname lookup via proxy' setting along the way.
Also add underline to variables and functions that are private to the python module.
PR #22510.
Introduced Author, 'Open link' headers.
Note that the Author and 'Open link' are not mandatory fields in RSS/Atom feeds. So these
headers will only be displayed when the feed includes them.
PR #22503.
Fixup for #21145
To reproduce:
1. Select status filter with 0 torrents
2. Enable 'Auto hide zero status filters' and save settings. Hidden filter is still selected:
PR #22487.
Some people are still unhappy with "standalone window mode" of "Add new torrent dialog" so just provide them with an option to use old "modal dialog mode" in all the current qBittorrent branches.
PR #22492 (based on original PR #19874).
The affected options are not really incompatible with SOCKS4 but it is due to Qt missing
implementation. Therefore 'unavailable' is more suitable.
PR #22483.
Now the behavior is more intuitive for a few options when the client send in partial settings.
This change is backward compatible.
For example, now it is possible to have only one of `max_ratio_enabled` or `max_ratio` instead
of requiring both.
PR #22460.
1. Utilize string matcher
2. Remove split behavior parameter
Previously `KeepEmptyParts` behavior doesn't match Qt's
implementation and since our codebase doesn't really make use of it,
we can just remove the parameter.
3. Add tests.
PR #22352.
In Trackers table, moving the 'URL' column from its default (2) position caused the 'Tracker editing' dialog to display incorrect data.
Steps to reproduce:
1. Move 'URL' column in Trackers table to any position from default
2. Choose tracker URL and click 'Edit tracker URL'
PR #22338.
We can only edit one URL through the dialog, so there's no point in showing this context option when more than one tracker is selected in trackers table.
PR #22311.
This PR fixes a bug where the sort icon did not update correctly after reordering columns.
Steps to reproduce:
1. Sort a column
2. Move it to a different position
3. The sort icon remains in its original location
PR #22299.
The `round()` returning floating point number is not a good idea. This is due to floating point
representation is imprecise and sometimes it cannot faithfully represent a number, for example
`0.09 + 0.01 !== 0.1 `. Therefore, it should be avoided and/or utilize other function
to achieve the goal.
Also, improve `window.qBittorrent.Misc.toFixedPointString()` and add test cases.
PR #22281.
stale-pr-message: "This PR is stale because it has been 60 days with no activity. This PR will be automatically closed within 7 days if there is no further activity."
close-pr-message: "This PR was closed because it has been stalled for some time with no activity."
* WebAPI responds with the error message "Endpoint does not exist" when the endpoint does not exist, to better differentiate from unrelated Not Found (i.e. 404) responses
* `auth/login` endpoint responds to invalid credentials with a 401
* `torrents/add` endpoint responds with `success_count`, `pending_count`, `failure_count`, and `added_torrent_ids`
* When `pending_count` is non-zero, response code 202 is used
* When all torrents fail to be added, response code 409 is used
* `torrents/trackers` returns three new fields: `next_announce`, `min_announce` and `endpoints`
* `endpoints` is an array of tracker endpoints, each with `name`, `updating`, `status`, `msg`, `bt_version`, `num_peers`, `num_peers`, `num_leeches`, `num_downloaded`, `next_announce` and `min_announce` fields
* `torrents/trackers` now returns `5` and `6` in `status` field as possible values
* `5` for `Tracker error` and `6` for `Unreachable`
* `torrents/parseMetadata` now responds with an array of metadata in the same order as the files in the request. It previously responded with an object keyed off of the submitted file name.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.