Save this as a .js file and point CodeScript ToolKit to it as your “Startup script path.” It’ll make it so you can have a separate Quick Action when using two fingers to swipe down, essentially.
Related feature request: [Mobile] Add two-finger Swipe down gesture: 1 finger for command palette, 2 for quick switcher! - Feature requests - Obsidian Forum
Change const COMMAND_ID = "command-palette:open"; to whatever you want.
To get the command IDs for every command palette command, run
console.log(Object.keys(app.commands.commands))
in Obsidian’s DevTools console
OR
put this in some note. It’ll output without needing to open DevTools. Uses CodeScript Toolkit
```code-button
---
caption: 'All command IDs'
---
console.log(Object.keys(app.commands.commands))
```
JS
exports.invoke = async (app) => {
const thingsToHookInto = [app?.workspace, app?.workspace?.rootSplit, app?.workspace?.activeLeaf];
const COMMAND_ID = "command-palette:open";
function installDoubleSwipeDownHook(thing) {
const proto = Object.getPrototypeOf(thing);
if (!proto || typeof proto.trigger !== "function" || proto.__double_up_hooked) return;
const origTrigger = proto.trigger;
proto.trigger = function (eventName, data) {
try {
if (eventName === "swipe" && data?.direction === "y" && data.points === 2) {
const isDown = data.startY && data.y && data.y > data.startY;
if (isDown && thing.rootSplit?.containerEl?.contains(data.targetEl)) {
handleTwoSwipeDown(data);
return;
}
}
} catch (err) {
console.error(err);
}
return origTrigger.apply(this, arguments);
};
proto.__double_up_hooked = true;
}
function handleTwoSwipeDown(e) {
const cmd = app.commands.findCommand(COMMAND_ID);
if (!cmd) return;
const el = document.body.createDiv({
cls: "pull-action pull-down-action",
text: cmd.name,
});
const h = el.offsetHeight;
let progress = 0;
let activated = false;
e.registerCallback({
move: (_, y) => {
progress = Math.clamp((y - e.startY) / h, 0, 1);
const fullyPulled = progress === 1;
el.toggleClass("mod-activated", fullyPulled);
el.style.transform = `translateY(${progress * h}px)`;
if (fullyPulled && !activated) {
navigator.vibrate?.(100);
activated = true;
}
if (!fullyPulled && activated) {
activated = false;
}
},
cancel: () => el.detach(),
finish: () => {
el.detach();
if (progress === 1) {
app.commands.executeCommandById(COMMAND_ID);
}
},
});
}
if (app.isMobile && !window.__double_up_hook_installed) {
for (const thing of thingsToHookInto) installDoubleSwipeDownHook(thing);
window.__double_up_hook_installed = true;
}
}