AppleScript to move Safari windows up as much as the window closest to the top of the screen will allow.
There’s a bug in Safari 15.0 where it sometimes re-positions open windows when waking from sleep by moving all the windows down an amount such that the bottom of the lowest one is at the bottom of the monitor (or something like that? They all move down a lot).
If happen to place your Safari windows up enough so that another app’s window can be visible on-screen under them (chat in my case), and you have a few too many windows open in Safari (ahem!), then you might be very annoyed to have to over a hundred windows all back up again.
Now, you could go through your heap of open Safari windows, but if you’re a programmer than you might (likely incorrectly ;)) think it’d be faster to write an AppleScript to move them all back up again. Not that I’d do such a thing, you understand, but, purely for educational purposes, here’s the kind of script one might write (or the second version if the first one took 6 minutes process the > 100 Safari windows you had open) :). This one moves all Safari windows up the same amount to keep their relative positioning and moves them up as much as possible while still keeping the window positioned highest on the screen below the menu bar.
Disclaimer: I write zero to two AppleScripts a year and never really learned AppleScript. There’s almost certainly better ways to do this. But it works for me and fixes my windows after Safari munges them again. So GoodEnough™ 🙂
-- Put in the public domain with zero warranty of any kind
-- only tested on macOS 11.6, with Safari 13.0; ymmv
use scripting additions
tell application "Safari"
set windlist to windows
log "Examining " & length of windlist & " windows..."
set lowestYWindow to first item of windlist
set lowestYValue to get second item of (get bounds of lowestYWindow)
repeat with wind in windlist
set curValue to second item of (get bounds of wind)
if curValue < lowestYValue then
copy wind to lowestYWindow
set lowestYValue to curValue
-- subtract out the title bar height (hard coded - bad dog!)
set yOffset to lowestYValue - 25
if yOffset > 0 then
log "moving " & length of windlist & " windows up " & yOffset & " pixels"
repeat with aWind in windlist
set aBounds to (get the bounds of aWind)
set the second item of aBounds to ((get the second item of aBounds as integer) - yOffset)
set the fourth item of aBounds to ((get the fourth item of aBounds as integer) - yOffset)
set the bounds of aWind to aBounds
display alert ("The highest window already at the top! Not moving any windows!")
Trinkets – the roguelike game I’ve spent the past week creating for the 7DRL competition – is finished, about 20 hours before the deadline! It’s a game about wandering an extra dimensional vault, acquiring trinkets and trying to get back home.
A build for mac is available here. Unfortunately, there’s no windows/linux build, but if you’re on one of those operating systems and want to play, the source is available here.
My high score is 59 – can you beat it? If so, let me know in the comments below!
One day remains, and I’m actually almost done. It would be nice to redo the map generator, and game balance can always be tweaked some more, but the plot and endgame are implemented, the boss-fights are done with basic AI, and there’s even a score feature. Shown below is the second of four boss fights:
Today was very productive; I finished the procedural generation of trinkets (for now, at least), improved the magic system, procedurally generated strangely worded descriptions of said trinkets, added new effects including knock-back and circular slide, and added all of the non-boss enemies, including the Abberant visible below:
Shown above is the non-procedurally-generated description of one of the coolest shoe types in the game (thus far, at least). These shoes allow you to run along walls, moving faster than enemies or even jumping over them.
I still have two more days left to go, and quite a bit still to do, including:
So, I’m about halfway through the week, but days 2-4 were all mostly occupied by other things, so the real productivity is just beginning. I’ve reworked the combat system to use the same generalized targeting/effect model as the spells. I’ve also changed trinket abilities to work on that model, divided trinkets into six types (hats, orbs, wands, cloaks, weapons, and shoes), which can be equipped and used for various nefarious purposes. I’ve started work on the procedural generation of trinkets, but there’s still a lot to do on that front, which will occupy the next day and a half, leaving me with a day and a half for enemies, plot, game balance, and a dungeon generator that isn’t stolen from the libtcod tutorial. That’s plenty of time, right?
This year I’m participating in the Seven Day Roguelike Competition, a contest to make a game in the roguelike genre in a week. (For those not familiar with it, roguelikes tend to be dungeon-crawlers with procedurally generated words, permanent character death, and often old-school graphics. There are frequently some variations from this rough description.)
I’m making a game known as ‘Trinkets’ until I think of a better name. It is a game in which a wizard strapped for cash loots a pocket dimension, and everything goes horribly wrong. It will experiment with a nontraditional power progression; you become weaker, then strong again, rather than a constant power level or steady increase. There will be a plot and randomly generated Trinkets.
My time will be somewhat limited, as I am currently a college student, but after spending most of today programming I produced the following:
I’ve used some code from some past projects, specifically most of the data structures and UI code. I’m using python, with the libtcod library.
…on a procedurally generated map…
…and hit things…
…which hit you back, and can kill you if you’re not careful.
Look for trinkets…
…which have magic powers…
…which are simply not as powerful (at least for now) as your spells.
Speaking of spells, you have five (and will have six), which in combination make you nearly unstoppable…
…at least until I implement the ‘everything goes horribly wrong’ part.
Using NSURLConnection combined with GCD for the first time and noticed that if you invoke NSURLConnection on anything other than the main queue it seems to lock up and nothing happens. Actually something happens but your delegate never gets called. Easy fix though; you just need to set the delegate queue (or run loop) before starting the download.
Here’s some sample code setting the delegate queue for you to play with if you like. Just make a sample cocoa app from the standard template and then setup the application delegate like this
@interface AppDelegate ()
@property (strong) NSURLConnection* connection;
@property (strong) NSMutableData * downloadedData;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
// Insert code here to initialize your application
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),
self.downloadedData = [NSMutableData new];
NSURLRequest * request = [NSURLRequest requestWithURL:
[NSURL URLWithString: @"http://wp.me/av6Bm-pZ"]];
self.connection = [[NSURLConnection alloc] initWithRequest: request
startImmediately: NO]; // This *must* be "NO".
// Can't switch delegate queue
// after download starts
[self.connection setDelegateQueue: [NSOperationQueue mainQueue]]; // *** set queue
[self.connection start]; // *now* you can start the fetch
// delegate calls just so let us know when it's working or when it isn't
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
NSLog( @"download failed with an error: %@, %@",
error, [error description] );
// release this stuff, test is done.
self.connection = nil;
self.downloadedData = nil;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
NSLog( @"connection did receive response: %@", response );
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
NSLog(@"download data received %lu", [data length] );
[self.downloadedData appendData: data];
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
NSLog(@"didFinishLoading. total data is: %lu", [self.downloadedData length] );
// release this stuff, test is done.
self.connection = nil;
self.downloadedData = nil;
Line 22 is the key (the setDelegateQueue: call). If you leave that line out then you’ll wonder why it’s not downloading your data. If you change the queue passed to line 12 with dispatch_get_main_queue() then it’ll work without the setDelegateQueue: call).
Obvious once you see it but maybe this’ll save someone a bit of time.
P.S. This was done with Xcode 5 under 10.8.5 fwiw.