Last active
March 5, 2025 14:36
-
-
Save danielrotaermel/201f549d5755ea886eb78bb660133722 to your computer and use it in GitHub Desktop.
Applescript to toggle picture-in-picture globally - I assign this to a keyboard shortcut with better touch tool (cmd+ctrl+p). Make sure "Developer > Allow JavaScript from Apple Events" is enabled in Safari. Download BTT preset -> https://share.folivora.ai/sP/3dd264e3-5d16-425f-8ab3-ce14877ec04f
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
Description: Applescript to open/close picture-in-picture in Safari | |
Supported Applications: Safari, IINA | |
Author: Daniel Rotärmel | |
Source: https://gist.github.com/danielrotaermel/201f549d5755ea886eb78bb660133722 | |
Instructions: | |
Assign this to a global keyboard shortcut with better touch tool / hammerspoon etc. - suggested: cmd+ctrl+p. | |
Make sure "Developer > Allow JavaScript from Apple Events" is enabled in Safari. | |
Download the BTT preset here -> https://share.folivora.ai/sP/3dd264e3-5d16-425f-8ab3-ce14877ec04f | |
*) | |
set jsStartPip to "document.querySelector('video').webkitSetPresentationMode('picture-in-picture')" | |
set jsVideoExistsAndInline to "document.querySelector('video') !== null ? (document.querySelector('video').webkitPresentationMode === 'inline' ? 'true' : 'false') : 'false';" | |
on closePip() | |
tell application "System Events" | |
if exists (window 1 of process "PIPAgent") then | |
-- display dialog "Found window 1" | |
-- get every UI element of (window 1 of process "PIPAgent") | |
click button 3 of (window 1 of process "PIPAgent") | |
-- click button 1 of (window 1 of process "PIPAgent") | |
end if | |
end tell | |
end closePip | |
-- tell application "Safari" to activate | |
-- tell application "IINA" to activate | |
tell application "System Events" to set frontApp to name of first process whose frontmost is true | |
if frontApp = "Safari" then | |
tell application "Safari" | |
set isVideoInline to do JavaScript jsVideoExistsAndInline in front document | |
if isVideoInline is "true" then | |
do JavaScript jsStartPip in front document | |
else | |
tell application "System Events" | |
if exists (window 1 of process "PIPAgent") then | |
-- display dialog "Found window 1" | |
-- get every UI element of (window 1 of process "PIPAgent") | |
click button 3 of (window 1 of process "PIPAgent") | |
-- click button 1 of (window 1 of process "PIPAgent") | |
end if | |
end tell | |
end if | |
end tell | |
else if (frontApp = "IINA") then | |
tell application "System Events" | |
tell process "IINA" | |
try | |
click menu item "Enter Picture-in-Picture" of menu "Video" of menu bar 1 | |
on error | |
click menu item "Exit Picture-in-Picture" of menu "Video" of menu bar 1 | |
end try | |
end tell | |
end tell | |
else | |
closePip() | |
end if |
@danielrotaermel I'm using Automator to trigger the apple script as a Quick Action.
This does not work on Ventura anymore since isVideoInline is undefined. Seems like the jsVideoExistsAndInline cannot be set as the procedure doesn't return a value. Do JavaScript seems to expect certain types of values to return. I'm still puzzled on what works.
I am still running Monterey. Once I‘ll update I can try to debug.
No need, this is the one I use: https://gist.github.com/ybbond/47d6fce6ce500748a0cfb7841cd0c64b.
Just updated the script and btt preset to work with macOS Sonoma
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi @doseofding, I am using Safari 15.3 so I don’t think that’s an issue. I really can’t really think of why the variable wouldn’t be defined. Are you using the btt preset or automator to trigger the apple script?
Maybe you can debug the apple script from script editor just make sure to uncomment line 27 for that, so it activates safari beforehand.