gandalfsaxe Posted October 8, 2015 Share Posted October 8, 2015 Hi everyone, I would like to make a script that does the following: IF current tab of Safari is not tab 1, bring Safari to forefront and switch to tab 1. IF (Safari is currently in focus) AND (tab 1 is the current tab) THEN hide window Also to start Safari if it is not running at all. I would then also make a similar script for tab 2 and tab 3. The idea is that I can make a webapp "feel" almost as a desktop app by opening op when I press hotkey, hiding when I press hotkey again (Like Alfred's "Toggle visibility for app"), BUT if I already have Safari in focus but I just want to switch from tab A to tab B, not hide Safari. What I got so far form various googling: on alfred_script(q) set appName to "Safari" set startIt to false tell application "System Events" tell window 1 of application "Safari" to set current tab to tab 1 if not (exists process appName) then set startIt to true else if frontmost of process appName then set visible of process appName to false else set frontmost of process appName to true end if end tell if startIt then tell application appName to activate end if end alfred_script It works. All I'm missing is to change this line: else if frontmost of process appName then Into something like this: else if frontmost of process appName AND if current tab is 1 then How do I do this? So close now! Link to comment
deanishe Posted October 8, 2015 Share Posted October 8, 2015 (edited) I think what you were missing is index of current tab. That's how you get a number, not a tab object. If I've understood you correctly, this should do what you want. I've rewritten the script extensively because the behaviour you want is a little complicated, and it's easier to reason about if you separate the "business logic" from the actual actions. This way, my toggleActiveTab() function, which is the bit that implements the behaviour you want, is fairly simple. (* This function is called when you run the script from the command line, e.g.: osascript "Safari Tabs.scpt" 2 will activate tab 2 of the frontmost Safari window. *) on run (argv) set tabIndex to item 1 of argv as integer my toggleActiveTab(tabIndex) end run (* This function is called when the script is run from within an Alfred Run NSAppleScript Action. q is the query you entered in Alred's query box. It is a string. Convert it to a number and run the script. *) on alfred_script(q) set tabIndex to q as integer my toggleActiveTab(tabIndex) end alfred_script (* If Safari is the active application and the specified tab is the current one, hide Safari. Otherwise, activate Safari and make the specified tab the current one. *) on toggleActiveTab(tabIndex) set activeAppName to my getActiveApp() log activeAppName & " is the active application" -- First we want to hide Safari if it is currently active and current tab is tabIndex if activeAppName = "Safari" then set activeTab to my getActiveSafariTab() if activeTab = tabIndex then my hideApplication("Safari") -- Our job is done; exit script return end if end if -- Safari isn't active and/or tabIndex isn't the current tab, so -- activate Safari (if necessary) and set current tab to tabIndex activate application "Safari" my setActiveSafariTab(tabIndex) end toggleActiveTab -- Return the name of the active application on getActiveApp() tell application "System Events" to set activeApp to first process where it is frontmost return name of activeApp end getActiveApp -- Return the index of the current tab in Safari's frontmost window on getActiveSafariTab() tell application "Safari" to return index of current tab of front window end getActiveSafariTab -- Set the active tab of Safari's frontmost window on setActiveSafariTab(tabIndex) tell front window of application "Safari" to set current tab to tab tabIndex end setActiveSafariTab -- Hide the specified application on hideApplication(appName) tell application "Finder" to set visible of process appName to false end hideApplication Edited October 8, 2015 by deanishe Link to comment
gandalfsaxe Posted October 8, 2015 Author Share Posted October 8, 2015 deanishe, thanks for all the work you put into it! I'm going to use the script together with a hotkey trigger - not a keyword input (perhaps I should've been more clear about that. How do I use the script with a hotkey and just hardcoding q as e.g. 1? I tried putting q = 1 at the top of the script and running it, but that didn't do it. So how? Sorry I'm not so familiar with AppleScript Link to comment
deanishe Posted October 8, 2015 Share Posted October 8, 2015 (edited) AppleScript sucks, tbh. Really sucks. The way Alfred runs NSAppleScripts is that it calls the alfred_script(q) function, passing in its query as q. So if you're running it from within Alfred, change the line within alfred_script(q) from: set tabIndex to q as integer to: set tabIndex to 1 Similarly, if you're running it from the command line, change the corresponding line in run(argv) (which is the normal entry point when you run a script) from: set tabIndex to item 1 of argv as integer to: set tabIndex to 1 Or in either cases, just use: my toggleActiveTab(1) That said, I deliberately wrote it so it takes an argument because you said you were planning to do the same for tabs 2 and 3.It's rather bad form to create multiple copies of a script if you can avoid it: if you find a bug or want to change/improve something, you have to edit multiple, effectively identical scripts.A better idea would be to open your workflow in Finder and save this script in there as, say, safari_tabs.scpt. Then in Alfred, instead of a Run NSAppleScript Action, create a Run Script Action with Language = /bin/bash. Then you can use a super simple script, which can't really go wrong: osascript safari_tabs.scpt 1 Then just make a copy of that and change the number to activate tab 2 or 3. You can connect Hotkey triggers to each of these. Edited October 8, 2015 by deanishe Link to comment
gandalfsaxe Posted October 8, 2015 Author Share Posted October 8, 2015 (edited) Thanks! it's working just as I wanted to perfectly as far as I can tell! At least the dummy way I completely got what you're saying about bad form, I was just thinking there would be the risk of either a very small delay or perhaps a terminal window poping up briefly if I didn't invoke everything from Alfred using NSAppleScript. But perhaps that is not the case? EDIT: And yeah I find Apple Script a mix of really nice, almost Pythonic, notation that's almost as intuitive as python list comprehension, but then when I need to write something up myself I'm completely lost It'd be nice to be good at though. Edited October 8, 2015 by Fnantier Link to comment
deanishe Posted October 9, 2015 Share Posted October 9, 2015 Python, you say? Now we're talking Anything you put in a Run Script action should be run silently in the background. Sometimes weird things happen on OS X if you try to run, say, git, but it isn't installed (instead of your script silently failing, you'll get a pop-up asking you to install Xcode). There is a small delay when you start running extra processes, but running a bash process takes a few hundredths of a second. That can really add up if you're writing a complex script in bash (which is largely based on running other processes), but when you're combining it with AppleScript calls to applications (which are insanely slow), bash will never be the problem. Getting data from an application via AppleScript is often many thousands of times slower than accessing the datastore directly (if that's possible). Don't break your head over AppleScript. It's a truly demented language. It's simple to the point of broken, but the first-class option for interacting with very complicated application object models. It's two kinds of bad rolled in to one… Link to comment
gandalfsaxe Posted October 22, 2015 Author Share Posted October 22, 2015 deanishe I have a favor to ask. I think you know enough Apple Script to be able to help me out one more time, and I would be very grateful! The problem: Chrome apps such as Google Keep mapped to a global hotkey with Alfred opens just fine, but "Toggle visibility for apps" does not work. I.e. it's not possible to hide the app by pressing the hotkey again. What's worse is that pressing Cmd+H to hide the window again hides it, but then also switches focus to Google Chrome, which is a very big annoyance. However Chrome is not put into focus if minimizing Google Keep (Cmd+M) instead of hiding it (Cmd+H). My proposed solution: An Applescript that does the following when hotkey is pressed: if (app is in focus): then minimize app else: focus on app Can you do this? Anyone else is also more than welcome to pitch in of course. As a bonus you'd also be solving a general problem of Chrome apps on Mac. Thanks! Link to comment
gandalfsaxe Posted October 22, 2015 Author Share Posted October 22, 2015 Oh wait.. forget it. It always focuses back on Chrome no matter if Keep is hidden or minimized. I don't see an easy solution then. Damn window management of Chrome Apps is a nightmare :/ Link to comment
deanishe Posted October 22, 2015 Share Posted October 22, 2015 Like Andrew says, you're going to have problems with Chrome Apps because they're still Chrome windows. Try something like Epichrome to make proper site-specific browsers with Chrome. They exist in their own applications, so they behave like proper applications, not Chrome windows. Link to comment
gandalfsaxe Posted October 25, 2015 Author Share Posted October 25, 2015 Thanks for the tip. If I wanted to make a global hotkey for opening a new chrome window, then opening a URL (https://inbox.google.com for example), what's the best/fastest/easiest way to do that? Right now I use a "Hotkey -> Open URL" workflow, but it'd be nice to have it open the URL in a new Chrome browser window as well. Link to comment
deanishe Posted October 26, 2015 Share Posted October 26, 2015 Like I said, try Epichrome. It lets you build standalone apps for webpages (using Chrome). Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now