2 Commits
Author SHA1 Message Date
andwati 6ed564f802 Bump version to 1.0.4 2026-08-12 14:36:25 +03:00
andwati a46226a0db Fix right-click download landing in home folder with wrong filename
Route context-menu captures through chrome.downloads so they resolve
Chrome's real filename (Content-Disposition, extension, etc.) via the
same onDeterminingFilename path auto-capture already uses, and harden
the native host against the bare-directory destDir KGet was misparsing
as a filename.
2026-08-12 14:36:17 +03:00
4 changed files with 30 additions and 11 deletions
-7
View File
@@ -97,13 +97,6 @@ git push origin v1.0.0
only skips its interactive "New Download" dialog when given a real
destination path up front, so instant capture and an editable prompt are
mutually exclusive given KGet's D-Bus API.
- **The context-menu capture can't always get the correct filename.**
Auto-capture gets the real filename for free from Chrome's own
`Content-Disposition` resolution. Right-click captures don't have that —
the extension only has the raw URL — so KGet falls back to guessing from
the URL path, which is wrong for opaque/signed URLs (e.g. cloud storage
links). Fixing this would require broad host permissions and an extra HTTP
request per right-click, which isn't worth it for now.
- **Chrome may still show its own "Save As" dialog** if you skipped step 5 of
Install above — see there for why and how to fix it.
- **KGet must already be running.** If it's not, captures fail silently from
+23 -2
View File
@@ -52,6 +52,11 @@ chrome.runtime.onInstalled.addListener(async (details) => {
refreshBadge();
});
// Downloads started from the context menu, tracked so captureDownload()
// still resolves/forwards their real filename even when auto-capture is
// toggled off -- a right-click "Download with KGet" should always work.
const pendingContextMenuDownloads = new Set();
chrome.contextMenus.onClicked.addListener((info) => {
if (info.menuItemId !== MENU_ID) return;
const url = info.linkUrl || info.srcUrl;
@@ -60,7 +65,22 @@ chrome.contextMenus.onClicked.addListener((info) => {
console.warn("[kget-capture] cannot hand a local/embedded URL to KGet:", url);
return;
}
sendToKGet(url, null);
// Route through chrome.downloads instead of sending the raw URL straight
// to KGet -- this reuses onDeterminingFilename/captureDownload below to
// get Chrome's real resolved filename (Content-Disposition, etc.) instead
// of leaving KGet to guess one from the bare URL, which drops query
// strings and gets opaque/signed URLs wrong.
chrome.downloads.download({ url }, (downloadId) => {
if (chrome.runtime.lastError || downloadId === undefined) {
console.error(
"[kget-capture] couldn't start download to resolve filename, falling back to raw URL:",
chrome.runtime.lastError && chrome.runtime.lastError.message
);
sendToKGet(url, null);
return;
}
pendingContextMenuDownloads.add(downloadId);
});
});
// onDeterminingFilename (rather than onCreated) fires once Chrome has
@@ -75,8 +95,9 @@ chrome.downloads.onDeterminingFilename.addListener((item, suggest) => {
});
async function captureDownload(item) {
const isContextMenuCapture = pendingContextMenuDownloads.delete(item.id);
const { autoCaptureEnabled } = await chrome.storage.local.get({ autoCaptureEnabled: true });
if (!autoCaptureEnabled) return;
if (!autoCaptureEnabled && !isContextMenuCapture) return;
const url = item.finalUrl || item.url;
if (!isCapturableUrl(url)) {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "KGet Capture",
"version": "1.0.3",
"version": "1.0.4",
"description": "Send browser downloads to KGet (KDE Download Manager) on Linux.",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtM1nFg5pPd3UBzynUJHj6aUy7bjudZaX9AQTWGMqAX3fXylw1lubSzP1/BaS9ivvgOJg/loyEgzEZlcNPzblFVlg8BqEJ3tntdk2OzYvUs0pUdcPzzyjso9TykCkUUTI7ev8JkreW/FYlinfvNwSYN4/c1s3h8/I6XHtxOdmO1G3bS98+BQaXPldbDmxoKwyWR8u1f8gTO2Mg3GY4BHau3RWf1kgtNzh20p9wE3sEFdWkFu7ArgRCIrWLh6m3O6lolnHQSCWPwtOTx893Qkp9Eu6FwUnoWc8rsYx8sqa0eNCTCS6Kjr1Iu3yEJ5y9390jUiDZTQ/c62ueCTQaYv2bwIDAQAB",
"permissions": ["downloads", "contextMenus", "storage", "nativeMessaging"],
+6 -1
View File
@@ -49,7 +49,12 @@ def add_transfer(url, filename):
# sidesteps KGet's own filename guess, which is derived purely from the
# URL path and gets it wrong for opaque/signed URLs.
dest_dir = default_download_dir()
dest = os.path.join(dest_dir, filename) if filename else dest_dir
# A bare directory path with no trailing slash (e.g. "/home/ian/Downloads")
# gets misparsed by KGet's addTransfer as dir="/home/ian" + filename=
# "Downloads" -- the same split it applies to a real dir/filename path --
# landing the transfer in the parent directory instead. A trailing slash
# keeps it unambiguous when we don't have a real filename to append.
dest = os.path.join(dest_dir, filename) if filename else dest_dir.rstrip("/") + "/"
cmd = [
"dbus-send",
"--print-reply",