untoldwind Posted September 24, 2013 Share Posted September 24, 2013 (edited) I was not very happy with the existing solutions, so I just created my own. The workflow itself is quite simple just typ in the keyword "lay" (or chose another of your liking) followed by: full = Maximize left, right, top, bottom = Halves of screen topleft, topright, bottomleft, bottomright = Quaters of screen 11,12,13,21,22,23,31,32,33 = Thrids of screen 11-12,11-13,11-21,11-22 ... = Some other sizes based on thrids ... well the script is quite flexible, so I'm waiting for suggestions For MacOS 10.8 (Mountain Lion): The workflow itself can be found here: https://github.com/untoldwind/alfred2-layout/raw/1.0_Mountain_Lion/Layout.alfredworkflow and (obviously) its sources here: https://github.com/untoldwind/alfred2-layout For MacOS 10.9 (Mavericks): The version above does not work (unluckily). An alternative (though somewhat experimental) version can be found here: Release: https://github.com/untoldwind/alfred2-layout/raw/1.1_Mavericks/Layout.alfredworkflow Experimental (Bleeding edge): https://github.com/untoldwind/alfred2-layout/raw/master/Layout.alfredworkflow By the way: It is multi-screen-able. Even though you cannot move windows from one screen to another (yet?) the scripts tries to figure out with screen you mean (depending on the size of the visible area). A short note about the implementation: The script is written in python using PyObjC and the ScriptingBridge. This should be no problem as both is shiped as part of MacOS since 10.5. It the application supports scripting, the window is moved "directly". Unluckily some Applications do not support this, so there is a fallback using "SystemEvents". This only works if you have UI scripting enabled: http://www.macosxautomation.com/applescript/uiscripting/For 10.9 (Mavericks) this has slightly changed. A more detailed description can be found here: http://www.tekrevue.com/2013/06/25/how-to-enable-access-for-assistive-devices-in-os-x-mavericks/ In our case "Alfred 2" requires UIScripting access At the moment there are no hotkeys defined, which should be straight forward though Edited November 26, 2013 by untoldwind Benzi, thec13, homever and 3 others 6 Link to comment
anazimok Posted September 24, 2013 Share Posted September 24, 2013 (edited) Let me be the first one to say, INCREDIBLE workflow. Thank you. Edited September 24, 2013 by anazimok Link to comment
GoOz Posted September 25, 2013 Share Posted September 25, 2013 Wow. AWESOME ! Just have one tiny feedback : I use the full black theme "Minimalist Dark" by Hannes Egler and your icons are confusing because i only can see the white part of them. For example, i can't see the "full" icon xD And that's it. Link to comment
untoldwind Posted September 25, 2013 Author Share Posted September 25, 2013 Well, that should be rather easy to fix. I just added a white (non-transparent) background to all icons in the current version. Link to comment
GoOz Posted September 25, 2013 Share Posted September 25, 2013 And now it's perfect… but i found another issue. When an app has multiple windows, for example Adium (Contact list and messages), it seems that, even if i focus the message window, it resizes the contact list. :/ Link to comment
untoldwind Posted September 26, 2013 Author Share Posted September 26, 2013 Ok, that one was/is more tricky ... In short: Adium should work now (I checked the 1.5.7 version) Longer story: As said before I try to move the window directly if the application supports scripting. Adium actually does support scripting, but - to my understanding - the "windows" array is supposed to be ordered by z-index (i.e. the top-most window should be at first position). For some reason Adium thinks differently and always reports the "Contacts" window first, regardless which window actually has focus. I'm a bit new to this MacOS-scripting business, so I'm not entirely sure if this is a bug in Adium or not. Anyway: I solved this by putting Adium on a blacklist, so that its windows are moved by SystemEvents as well, which seems to produce the correct results. Maybe there is a better solution ... Link to comment
Benzi Posted September 27, 2013 Share Posted September 27, 2013 Pretty neat! Any possibility of extending this to support Full Screen apps (e.g. Chrome on OS X Lion)? Perhaps options to enter/exit/toggle full screen mode? Link to comment
untoldwind Posted September 28, 2013 Author Share Posted September 28, 2013 To my knowledge there is not generic way to toggle the full screen mode via scripting, at least I've found no such property/action so far. Of course it should be possible to trigger a menu-item event, which would be application-specific though and quite cumbersome to maintain. At the moment I'm taking a look at Atomac (https://pypi.python.org/pypi/atomac/1.1.0). Even though it is a testing framework, it circumvents some of the restrictions I've encountered with the scripting bridge. Not sure though if I can (or should) include this in an Alfred workflow Link to comment
raguay.customct Posted September 28, 2013 Share Posted September 28, 2013 (edited) You might want to check out http://spectacleapp.com/. It is full open source, so you can get ideas from it. I use it all the time. I been toying with the idea to take that base and open it all up to scripting with AAppleScript. Then making workflows like this from it's core would be a synch. But, alas, I am not finding enough time for that project. Edited September 28, 2013 by raguay.customct Link to comment
jdq Posted September 28, 2013 Share Posted September 28, 2013 The following Applescript might help for turning applications fullscreen: tell application "System Events" try tell front window of (first process whose frontmost is true) set isFullScreen to get value of attribute "AXFullScreen" set value of attribute "AXFullScreen" to not isFullScreen end tell end try end tell Link to comment
zhaowu Posted September 28, 2013 Share Posted September 28, 2013 I experience long delay ( > 3 second ) for any action. Sometimes, the `Python Launcher.app` show up briefly. Does anyone have the same issue? Link to comment
rice.shawn Posted September 29, 2013 Share Posted September 29, 2013 I ran into that same issue with the delays, but I never noticed the Python Launcher.app showing up. The delays made me go back to using one that I wrote with Applescript that is sometimes wonky (I never ironed out certain bugs) but doesn't have those delays. Link to comment
untoldwind Posted September 29, 2013 Author Share Posted September 29, 2013 Thanks for all the feedback. Lets focus on the most pressing issue first: I also noted this short flicker of the "python.app", I just did not realized that it might be *that* slow. This seems to related to PyObjC and/or the ScriptingBridge. As an experiment I reimplemented the main script in ruby, which seems to run much more smoothly (as I can tell). You can find this in a separate branch on github: https://github.com/untoldwind/alfred2-layout/raw/ruby/Layout.alfredworkflow (Hopefully this helps...) As for the full-screen mode: Thanks for the short script, I'll experiment with it and figure out how to integrate it into the workflow. And thanks for the hint to Spectacle, so far I was just aware for several Shareware (closed-source) applications in this regard. I did a short code-dive there, at its core Spectacle seems to use the ZeroKit, which is a small Objective-C wrapper around the Accessibility-API. This is quite informative, but I'm not sure if it is possible to do any of this from within a python,ruby,whatever-script ... without the use of some native wrapper like the already mentions atomac. Link to comment
rice.shawn Posted September 29, 2013 Share Posted September 29, 2013 Sounds great. I'll check out the Ruby Version. There are a couple of very inelegant hacks that you could do with Applescript in order to put it into Fullscreen Mode. The first would just be to place the clicker in that upper right hand corner of the window that has that little fullscreen icon, send a mouse click, then reposition the cursor where it started. But, that's awkward. Another thing you could do is to have it send a ctrl+cmd+F keypress, which seems to be the hotkey for at least a few programs to enter into Fullscreen (often in View->Enter Full Screen). But that just seems unnecessary as it already has a hotkey, so you could also consider the Full Screen as an unnecessary feature... Shawn Link to comment
justmytwospence Posted October 2, 2013 Share Posted October 2, 2013 Great workflow! I do have about a 2 second delay, however. Also, could you add a "center" keyword? Link to comment
untoldwind Posted October 8, 2013 Author Share Posted October 8, 2013 (edited) Sure another keyword is no biggy. My current version of the workflow is kind of messed up since I was experimenting a bit, which let me in the ugly depths of MacOS accessibility ... or hell, depending on the point of view Anyway, the list of keywords is in the "layout_select.py" file: layouts = [ Layout("full", "Full", "0,0,1,1"), Layout("left", "Left", "0,0,0.5,1"), Layout("top", "Top", "0,0,1,0.5"), Just add a line there, like: layouts = [ Layout("center", "Center", "0.1,0.1,0.9,0.9"), Layout("full", "Full", "0,0,1,1"), Layout("left", "Left", "0,0,0.5,1"), Layout("top", "Top", "0,0,1,0.5"), And it should to the trick. The format of the last part is "<left>,<top>,<right>,<bottom>" in relative coordinates, i.e. "0.1,0.1,0.9,0.9" means "center with 10% border", "0.2,0.2,0.8.0.8" would be 20% and so on. I'll include this in the next "release" sometime this week, once I've mopped up a bit. Edited October 8, 2013 by untoldwind daehn 1 Link to comment
untoldwind Posted October 10, 2013 Author Share Posted October 10, 2013 (edited) I just pushed a new version to github. The ruby-variant is now "official" (its still not really performant, but smoother than python) New keywords: center: Move a window to center of screen with 10% border (see previous post) togglefullscreen: Toggles full screen mode. Thanks for the little Apple-Script once again. I also added an example how to add hotkeys to the workflow. As for the performance issues: I somewhat gave up on atomac and kind of wait for 10.9 if there are any changes/improvements to the scripting bridge. To my understanding multi-screen support will change, so I'll most likely have to tweak the scripts anyway. Edited October 10, 2013 by untoldwind Benzi 1 Link to comment
Florian Posted October 10, 2013 Share Posted October 10, 2013 That's cool. But it'd be cooler to display them all when the query is empty so that 1.we can learn what exists, 2.the ones we use the most end up showing up up top without typing a query. Link to comment
untoldwind Posted October 11, 2013 Author Share Posted October 11, 2013 Hmm... that's funny, obviously I misinterpreted the "Argument required"/"Argument optional" switch in the Alfreds Script-Filter. Now there should be a full list if you just type the keyword. There "Order by frequency" is tougher though. I was kind of hoping that Alfred would do that on itself, I think there is already a Feature-Request for this. Link to comment
Florian Posted October 11, 2013 Share Posted October 11, 2013 Alfred does do that by itself. That's why I wanted the list to appear without arguments Link to comment
untoldwind Posted October 11, 2013 Author Share Posted October 11, 2013 (edited) During a (quite loooong) train ride I found some time to dig more deeply into the ScriptingBridge again. I thing I found the biggest time-consumer: Finding the main window of the frontmost application. Sounds simple enough, but if you do it the naive way (like me) it can result in lots of events being fired. I just update the workflow once again with a variant that should minimize the overhead and works quite nicely (and fast) for me. Would be nice to know if this eventually fixes the performance issues. For interested coders out there: The magic is now done in the following 4 lines of ruby code: systemevents = OSX::SBApplication.applicationWithBundleIdentifier_("com.apple.systemevents") frontmostPredicate = OSX::NSPredicate.predicateWithFormat("frontmost == true") frontmost = systemevents.processes().filteredArrayUsingPredicate_(frontmostPredicate).first window = frontmost.attributes().objectWithName_("AXMainWindow").value().get() Edited October 11, 2013 by untoldwind Link to comment
Benzi Posted October 12, 2013 Share Posted October 12, 2013 (edited) During a (quite loooong) train ride I found some time to dig more deeply into the ScriptingBridge again. I thing I found the biggest time-consumer: Finding the main window of the frontmost application. Sounds simple enough, but if you do it the naive way (like me) it can result in lots of events being fired. I just update the workflow once again with a variant that should minimize the overhead and works quite nicely (and fast) for me. Would be nice to know if this eventually fixes the performance issues. The latest version is much faster compared to the previous versions (at least on my system), so that's great (...and yay for adding togglefullscreen). If you need Alfred to learn about the most frequently used options, you need to set a uniquely identifiable "uid" attribute for each of the item nodes in the generated xml in layout_select.py. I have sent a pull request via GitHub so that you can get an idea of what I mean. This will enable you to type "lay" in Alfred and have the most used items listed as the first results. E.g I happen to use toggle full screen a lot for some reason, and now I can just key in "lay" and the first option is "Toggle full screen mode" by default. Edited October 12, 2013 by Benzi Link to comment
raguay.customct Posted October 14, 2013 Share Posted October 14, 2013 This new version is fast enough for me to partially quit using spectacle. But, I love Spectacle's nudge feature. I use <ctrl><alt>leftarrow to nudge the current window a little bit wider in that direction. Same with right arrow. If you can implement that, I will dump using Spectacles! Thanks! Link to comment
untoldwind Posted October 14, 2013 Author Share Posted October 14, 2013 (edited) @Benzi: Cool, thanks for that - I was wondering a bit by myself. Just merged it to the current version. Hurray for social coding @raguary: I fear, I have to take a closer look at Spectacles first, to fully understand this feature. What about this: If you use the keyword "left", the window is move to the left-half (obviously), butif the window already is in the left-half, it will be increased to 2/3-left same for "right" and maybe "top", "bottom" as well The only problem is that its not that easy to detect if a window is actually in the left-half. E.g. "iterm" sets its height always according to the font-size of the terminal, so it might be a little smaller than "left-half of available screen" ... I'll try to figure something out. Edited October 14, 2013 by untoldwind daehn 1 Link to comment
drchentao Posted October 14, 2013 Share Posted October 14, 2013 it seems not work on 10.9 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