gui/gui-lib/mred/private/wx/cocoa/frame.rkt
Matthew Flatt a964f3effb fix refresh on El Capitan
When restoring autodisplay, need to check whether a display was
lost since display was suspended.

(cherry picked from commit 9bf18505d5)
2015-11-07 06:48:28 -07:00

776 lines
30 KiB
Racket

#lang racket/base
(require ffi/unsafe/objc
ffi/unsafe
racket/class
"pool.rkt"
"utils.rkt"
"const.rkt"
"types.rkt"
"window.rkt"
"queue.rkt"
"menu-bar.rkt"
"cursor.rkt"
"../../syntax.rkt"
"../common/queue.rkt"
"../common/freeze.rkt"
"../../lock.rkt")
(provide
(protect-out frame%
location->window
get-front
RacketEventspaceMethods
install-RacketGCWindow!))
;; ----------------------------------------
(import-class NSWindow NSGraphicsContext NSMenu NSPanel
NSApplication NSAutoreleasePool NSScreen
NSToolbar NSArray)
(define NSWindowCloseButton 0)
(define NSWindowToolbarButton 3)
(define front #f)
(define (get-front) front)
(define empty-mb (new menu-bar%))
(define root-fake-frame #f)
;; Maps window numbers to weak boxes of frame objects;
;; the weak-box layer is needed to avoid GC-accounting
;; problems.
(define all-windows (make-hash))
;; called in atomic mode
(define (send-screen-change-notifications flags)
(when (zero? (bitwise-and flags 1)) ;; discard the "about to change" notifications
(for ([b (in-hash-values all-windows)])
(define f (weak-box-value b))
(when f
(define e (send f get-eventspace))
(unless (eventspace-shutdown? e)
(parameterize ([current-eventspace e])
(queue-callback
(λ ()
(send f display-changed)))))))))
(set-screen-changed-callback! send-screen-change-notifications)
(define RacketGCWindow #f)
(define (install-RacketGCWindow! c) (set! RacketGCWindow c))
(define-objc-mixin (RacketEventspaceMethods Superclass)
[wxb]
[-a _scheme (getEventspace)
(let ([wx (->wx wxb)])
(and wx (send wx get-eventspace)))])
(define-objc-mixin (RacketWindowMethods Superclass)
#:mixins (RacketEventspaceMethods)
[wxb]
[-a _BOOL (canBecomeKeyWindow)
(let ([wx (->wx wxb)])
(and wx
(not (other-modal? wx))))]
[-a _BOOL (canBecomeMainWindow)
(let ([wx (->wx wxb)])
(or (not wx)
(not (send wx floating?))))]
[-a _BOOL (windowShouldClose: [_id win])
(queue-window*-event wxb (lambda (wx)
(unless (other-modal? wx)
(when (send wx on-close)
(atomically
(send wx direct-show #f))))))
#f]
[-a _void (windowDidResize: [_id notification])
(when wxb
(let ([wx (->wx wxb)])
(when wx
(queue-window-event wx (lambda ()
(send wx queue-on-size)
(send wx clean-up)))
;; Live resize:
(constrained-reply (send wx get-eventspace)
(lambda ()
(pre-event-sync #t)
(let loop () (when (yield/no-sync) (loop))))
(void)))))]
[-a _void (windowDidMove: [_id notification])
(when wxb
(queue-window*-event wxb (lambda (wx)
(send wx queue-on-size))))]
[-a _void (windowDidBecomeMain: [_id notification])
;; We check whether the window is visible because
;; clicking the dock item tries to resurrect a hidden
;; frame. See also `setOneShot' below.
(when (tell #:type _BOOL self isVisible)
(when wxb
(let ([wx (->wx wxb)])
(when wx
;; Sometimes, a sheet becomes the main window and the parent
;; still thinks that the parent is the main window. Tell
;; the parent otherwise.
(let ([p (send wx get-parent)])
(when p
(let ([s (send p get-sheet)])
(when (eq? s wx)
(let ([parent (send p get-cocoa)])
(when (tell #:type _BOOL parent isMainWindow)
;; The Cocoa docs say never to call this method directly,
;; but we're trying to fix up a case where Cocoa seems
;; to be confused:
(tellv parent resignMainWindow)))))))
(set! front wx)
(send wx install-wait-cursor)
(send wx install-mb)
(queue-window-event wx (lambda ()
(send wx on-activate #t)))))))]
[-a _void (windowDidBecomeKey: [_id notification])
(when (tell #:type _BOOL self isVisible)
(when wxb
(let ([wx (->wx wxb)])
(when wx
(send wx notify-responder #t)))))]
[-a _void (windowDidResignMain: [_id notification])
(when wxb
(let ([wx (->wx wxb)])
(when wx
(when (eq? front wx)
(set! front #f)
(send wx uninstall-wait-cursor))
(if root-fake-frame
(send root-fake-frame install-mb)
(send empty-mb install))
(queue-window-event wx (lambda ()
(send wx on-activate #f))))))]
[-a _void (windowDidResignKey: [_id notification])
(when wxb
(let ([wx (->wx wxb)])
(when wx
(send wx notify-responder #f))))]
[-a _void (windowDidMiniaturize: [_id notification])
(when wxb
(let ([wx (->wx wxb)])
(when wx
(send wx force-window-focus))))]
[-a _void (windowDidEndSheet: [_id notification])
;; In some cases, the window that has a sheet
;; stays main even as its sheet becomes main, so
;; we need to make the containing window become main
;; when the sheet goes away.
(when (equal? self (tell app mainWindow))
(tell self windowDidBecomeMain: notification))]
[-a _void (toggleToolbarShown: [_id sender])
(when wxb
(let ([wx (->wx wxb)])
(when wx
(queue-window-event wx
(lambda () (send wx on-toolbar-click))))))
(void)])
(define-objc-class RacketWindow NSWindow
#:mixins (FocusResponder KeyMouseResponder RacketWindowMethods)
[wxb])
(define-objc-class RacketPanel NSPanel
#:mixins (FocusResponder KeyMouseResponder RacketWindowMethods)
[wxb])
(set-front-hook! (lambda ()
(let ([f (or front
root-fake-frame)])
(values f
(and f (send f get-eventspace))))))
(set-eventspace-hook! (lambda (evt w)
(define (is-mouse-or-key?)
(bitwise-bit-set? MouseAndKeyEventMask
(tell #:type _NSInteger evt type)))
(cond
[w
(and (or (not root-fake-frame)
;; only mouse and key events in the root
;; frame need to be dispatched in the root
;; eventspace:
(not (ptr-equal? w (send root-fake-frame get-cocoa)))
(is-mouse-or-key?))
(or (objc-is-a? w RacketWindow)
(objc-is-a? w RacketPanel)
(and RacketGCWindow
(objc-is-a? w RacketGCWindow)))
(tell #:type _scheme w getEventspace))]
[front (send front get-eventspace)]
[root-fake-frame
(and (is-mouse-or-key?)
(send root-fake-frame get-eventspace))]
[else #f])))
(define frame%
(class window%
(init parent
label
x y w h
style)
(init [is-dialog? #f])
(inherit get-cocoa get-parent
get-eventspace
pre-on-char pre-on-event
get-x
on-new-child
is-window-enabled?)
(super-new [parent parent]
[cocoa
(let ([is-sheet? (and #f
is-dialog?
parent
(not (send parent frame-is-dialog?)))]
[init-rect (make-NSRect (make-init-point x y)
(make-NSSize (max 30 w)
(max (if (memq 'no-caption style)
1
22)
h)))])
(let ([c (as-objc-allocation
(tell (tell (if (or is-sheet? (memq 'float style))
RacketPanel
RacketWindow)
alloc)
initWithContentRect: #:type _NSRect init-rect
styleMask: #:type _int (if (memq 'no-caption style)
NSBorderlessWindowMask
(bitwise-ior
NSTitledWindowMask
(if is-sheet? NSUtilityWindowMask 0)
(if is-dialog?
(bitwise-ior
(if (memq 'close-button style)
NSClosableWindowMask
0)
(if (memq 'resize-border style)
NSResizableWindowMask
0))
(bitwise-ior
NSClosableWindowMask
NSMiniaturizableWindowMask
(if (memq 'no-resize-border style)
0
NSResizableWindowMask)))))
backing: #:type _int NSBackingStoreBuffered
defer: #:type _BOOL NO))])
;; use init rect as frame size, not content size
(tellv c setFrame: #:type _NSRect init-rect display: #:type _BOOL #f)
;; fullscreen variants:
(when (version-10.7-or-later?)
(cond
[(memq 'fullscreen-button style)
(tellv c setCollectionBehavior: #:type _int NSWindowCollectionBehaviorFullScreenPrimary)]
[(memq 'fullscreen-aux style)
(tellv c setCollectionBehavior: #:type _int NSWindowCollectionBehaviorFullScreenAuxiliary)]
[else (void)]))
c))]
[no-show? #t])
(define cocoa (get-cocoa))
(tellv cocoa setDelegate: cocoa)
(unless (version-10.7-or-later?)
(when (memq 'toolbar-button style)
(atomically
(let ([tb (tell (tell NSToolbar alloc) initWithIdentifier: #:type _NSString "Ok")])
(tellv cocoa setToolbar: tb)
(tellv tb setVisible: #:type _BOOL #f)
(tellv tb release)))))
(internal-move #f (or y 0))
(tellv cocoa setAcceptsMouseMovedEvents: #:type _BOOL #t)
;; Setting the window in one-shot mode helps prevent the
;; frame from being resurrected by a click on the dock icon.
(tellv cocoa setOneShot: #:type _BOOL #t)
(define/override (get-cocoa-content)
(tell cocoa contentView))
(define/override (get-cocoa-window) cocoa)
(define/override (get-wx-window) this)
(define/override (make-graphics-context)
(tell cocoa graphicsContext)
#;
(as-objc-allocation
(tell NSGraphicsContext graphicsContextWithWindow: cocoa)))
(define is-a-dialog? is-dialog?)
(define/public (frame-is-dialog?) is-a-dialog?)
(define not-sheet? (and (memq 'no-sheet style) #t))
(define/public (frame-relative-dialog-status win) #f)
(define/override (get-dialog-level) 0)
(define/public (clean-up)
;; When a window is resized, then any drawing that is in flight
;; might draw outside the canvas boundaries. Just refresh everything.
(tellv cocoa display))
(when label
(tellv cocoa setTitle: #:type _NSString label))
(define child-sheet #f)
(define/public (get-sheet) child-sheet)
(define/public (set-sheet s) (set! child-sheet s))
(define caption? (not (memq 'no-caption style)))
(define float? (memq 'float style))
(define/public (can-have-sheet?) caption?)
(define/public (floating?) float?)
(when float?
(tell cocoa setFloatingPanel: #:type _BOOL #t))
(define/public (direct-show on?)
;; in atomic mode
(when on? (promote-to-gui!))
(when (and (not on?)
(eq? front this))
(set! front #f)
(send empty-mb install))
(if on?
(show-children)
(hide-children))
(if on?
(if (and is-a-dialog?
(not not-sheet?)
(let ([p (get-parent)])
(and p
(send p can-have-sheet?)
(not (send p get-sheet)))))
(let ([p (get-parent)])
(send p set-sheet this)
(tellv (tell NSApplication sharedApplication)
beginSheet: cocoa
modalForWindow: (send p get-cocoa)
modalDelegate: #f
didEndSelector: #:type _SEL #f
contextInfo: #f))
(if float?
(tellv cocoa orderFront: #f)
(begin
(tellv cocoa makeKeyAndOrderFront: #f)
(when unshown-fullscreen?
(set! unshown-fullscreen? #f)
(tellv cocoa toggleFullScreen: #f)))))
(begin
(when is-a-dialog?
(let ([p (get-parent)])
(when (and p
(eq? this (send p get-sheet)))
(send p set-sheet #f)
(tell (tell NSApplication sharedApplication)
endSheet: cocoa))))
(when (is-shown?) ; otherwise, `deminiaturize' can show the window
(tellv cocoa deminiaturize: #f)
(define fs? (fullscreened?))
(set! unshown-fullscreen? fs?)
(tellv cocoa orderOut: #f)
(when fs?
;; Need to select another window to get rid of
;; the window's screen:
(tellv (get-app-front-window) orderFront: #f)))
(force-window-focus)))
(register-frame-shown this on?)
(let ([num (tell #:type _NSInteger cocoa windowNumber)])
(if on?
(hash-set! all-windows num (make-weak-box this))
(hash-remove! all-windows num)))
(when on?
(let ([b (eventspace-wait-cursor-count (get-eventspace))])
(set-wait-cursor-mode (not (zero? b))))))
(define/override (show on?)
(let ([es (get-eventspace)])
(when on?
(when (eventspace-shutdown? es)
(error (string->symbol
(format "show method in ~a" (if is-a-dialog? 'dialog% 'frame%)))
"the eventspace hash been shutdown"))
(when (version-10.11-or-later?)
;; Ensure that the basic window background is drawn before
;; we potentially suspend redrawing. Otherwise, the window
;; can start black and end up with a too-dark titlebar.
(tellv cocoa display))
(when saved-child
(if (eq? (current-thread) (eventspace-handler-thread es))
(do-paint-children)
(let ([s (make-semaphore)])
(queue-callback (lambda ()
(do-paint-children)
(semaphore-post s)))
(sync/timeout 1 s))))))
(atomically
(direct-show on?)))
(define flush-disabled 0)
(define/public (disable-flush-window)
(when (zero? flush-disabled)
(when (version-10.11-or-later?)
(tellv cocoa setAutodisplay: #:type _BOOL #f))
(tellv cocoa disableFlushWindow))
(set! flush-disabled (add1 flush-disabled)))
(define/public (enable-flush-window)
(set! flush-disabled (sub1 flush-disabled))
(when (zero? flush-disabled)
(tellv cocoa enableFlushWindow)
(when (version-10.11-or-later?)
(tellv cocoa setAutodisplay: #:type _BOOL #t)
(tellv cocoa displayIfNeeded))))
(define/public (force-window-focus)
(let ([next (get-app-front-window)])
(cond
[next
(tellv next makeKeyWindow)]
[root-fake-frame
;; Make key focus shift to root frame:
(let ([root-cocoa (send root-fake-frame get-cocoa)])
(tellv root-cocoa orderFront: #f)
(tellv root-cocoa makeKeyWindow)
(tellv root-cocoa orderOut: #f))
;; Install root frame's menu bar:
(send root-fake-frame install-mb)]
[else (void)])))
(define/private (do-paint-children)
(when saved-child
(send saved-child paint-children))
(yield-refresh)
(try-to-sync-refresh))
(define/public (destroy)
(when child-sheet (send child-sheet destroy))
(atomically
(direct-show #f)))
(define/override (hide-children)
(when saved-child
(send saved-child hide-children)))
(define/override (show-children)
(when saved-child
(send saved-child show-children)))
(define/override (fixup-locations-children)
(when saved-child
(send saved-child fixup-locations-children)))
(define/override (children-accept-drag on?)
(when saved-child
(send saved-child child-accept-drag on?)))
(define/override (enable-window on?)
(when saved-child
(send saved-child enable-window (and on? (is-window-enabled?)))))
(define/override (is-shown?)
(or (tell #:type _bool cocoa isVisible)
(tell #:type _bool cocoa isMiniaturized)))
(define/override (is-shown-to-root?)
(is-shown?))
(define/override (is-shown-to-before-root?) #t)
(define/override (is-parent-enabled-to-root?)
#t)
(define/override (is-view?) #f)
(define is-main? #f)
(define first-responder #f)
(define saved-child #f)
(define/override (register-child child on?)
(unless on? (error 'register-child-in-frame "did not expect #f"))
(unless (or (not saved-child) (eq? child saved-child))
(error 'register-child-in-frame "expected only one child"))
(set! saved-child child)
(on-new-child child #t))
(define/override (refresh-all-children)
(when saved-child
(send saved-child refresh)))
(define/override (set-cursor c)
(when saved-child
(send saved-child set-cursor c)))
(define/public (notify-responder on?)
(set! is-main? on?)
(when first-responder
(do-notify-responder first-responder on?)))
(define/private (do-notify-responder wx on?)
(send wx focus-is-on on?)
(queue-window-event wx
(if on?
(lambda () (send wx on-set-focus))
(lambda () (send wx on-kill-focus)))))
(define/override (is-responder wx on?)
(unless (and (not on?)
(not (eq? first-responder wx)))
(if on?
(set! first-responder wx)
(set! first-responder #f))
(unless on?
(tellv cocoa makeFirstResponder: #f))
(when is-main?
(do-notify-responder wx on?))))
(define/public (get-focus-window [even-if-not-active? #f])
(let ([f-cocoa (tell cocoa firstResponder)])
(and f-cocoa
(or even-if-not-active?
(tell #:type _BOOL cocoa isKeyWindow))
(->wx (get-ivar f-cocoa wxb)))))
(define/public (install-wait-cursor)
(when (positive? (eventspace-wait-cursor-count (get-eventspace)))
(tellv (get-wait-cursor-handle) set)))
(define/public (uninstall-wait-cursor)
(when (positive? (eventspace-wait-cursor-count (get-eventspace)))
(tellv arrow-cursor-handle set)))
(define/public (set-wait-cursor-mode on?)
(if on?
(tell cocoa disableCursorRects)
(tell cocoa enableCursorRects))
(when (eq? this front)
(if on?
(install-wait-cursor)
(uninstall-wait-cursor))))
(define/override (start-no-cursor-rects)
(tell cocoa disableCursorRects))
(define/override (end-no-cursor-rects)
(unless (positive? (eventspace-wait-cursor-count (get-eventspace)))
(tell cocoa enableCursorRects)))
(define/public (flip-screen y)
(let ([f (tell #:type _NSRect (tell NSScreen mainScreen) frame)])
(- (NSSize-height (NSRect-size f)) y)))
(define/override (flip y h) (flip-screen (+ y h)))
(define/override (get-y)
(- (super get-y) (get-menu-bar-height)))
(define/override (set-size x y w h)
(unless (and (equal? x -1) (equal? y -1))
(internal-move x y))
(let ([f (tell #:type _NSRect cocoa frame)])
(tellv cocoa setFrame:
#:type _NSRect (make-NSRect
(make-NSPoint (if (and is-a-dialog?
(let ([p (get-parent)])
(and p
(eq? this (send p get-sheet)))))
;; need to re-center sheet:
(let* ([p (get-parent)]
[px (send p get-x)]
[pw (send p get-width)])
(+ px (/ (- pw w) 2)))
;; keep current x position:
(NSPoint-x (NSRect-origin f)))
;; keep current y position:
(- (NSPoint-y (NSRect-origin f))
(- h
(NSSize-height (NSRect-size f)))))
(make-NSSize w h))
display: #:type _BOOL #t)))
(define/override (internal-move x y)
(let ([x (if (not x) (get-x) x)]
[y (if (not y) (get-y) y)])
(tellv cocoa setFrameTopLeftPoint: #:type _NSPoint (make-NSPoint x (- (flip-screen y)
(get-menu-bar-height))))))
(define/override (center dir wrt)
(let ([f (tell #:type _NSRect cocoa frame)]
[w (if wrt
(tell #:type _NSRect (send wrt get-cocoa) frame)
(tell #:type _NSRect (tell cocoa screen) frame))])
(tellv cocoa setFrame:
#:type _NSRect (make-NSRect (make-NSPoint
(if (or (eq? dir 'both)
(eq? dir 'horizontal))
(+ (quotient (- (NSSize-width (NSRect-size w))
(NSSize-width (NSRect-size f)))
2)
(NSPoint-x (NSRect-origin w)))
(NSPoint-x (NSRect-origin f)))
(if (or (eq? dir 'both)
(eq? dir 'vertical))
(+ (quotient (- (NSSize-height (NSRect-size w))
(NSSize-height (NSRect-size f)))
2)
(NSPoint-y (NSRect-origin w)))
(NSPoint-x (NSRect-origin f))))
(NSRect-size f))
display: #:type _BOOL #t)))
(define/public (enforce-size min-x min-y max-x max-y inc-x inc-y)
(define (adj v) (if (negative? v) 32000 v))
(tellv cocoa setMinSize: #:type _NSSize (make-NSSize (max min-x 1)
(max min-y 1)))
(tellv cocoa setMaxSize: #:type _NSSize (make-NSSize (adj max-x)
(adj max-y)))
(tellv cocoa setResizeIncrements: #:type _NSSize (make-NSSize inc-x inc-y)))
(define hide-mb? (and (memq 'hide-menu-bar style) #t))
(define mb #f)
(define/public (get-menu-bar) mb)
(define/public (set-menu-bar _mb)
(set! mb _mb)
(send mb set-top-window this)
(when (or (tell #:type _BOOL cocoa isMainWindow)
(and (eq? this root-fake-frame)
(not (get-app-front-window))))
(promote-to-gui!)
(install-mb)))
(define/public (install-mb)
(tellv NSMenu setMenuBarVisible: #:type _BOOL (not hide-mb?))
(if mb
(send mb install)
(send empty-mb install)))
(define/public (on-activate on?) (void))
(define/public (set-icon bm1 [bm2 #f] [mode 'both]) (void)) ;; FIXME
(define default-buttons (make-hasheq))
(define checking-default? #f)
(define/public (add-possible-default button)
(hash-set! default-buttons button #t)
(queue-default-button-check))
(define/public (remove-possible-default button)
(hash-remove! default-buttons button)
(queue-default-button-check))
(define/public (queue-default-button-check)
(when (atomically
(if checking-default?
#f
(begin
(set! checking-default? #t)
#t)))
(queue-window-event
this
(lambda ()
(set! checking-default? #f)
(for/or ([button (in-hash-keys default-buttons)])
(send button be-default))))))
(define/override (call-pre-on-event w e)
(pre-on-event w e))
(define/override (call-pre-on-char w e)
(pre-on-char w e))
(define/public (on-menu-click) (void))
(define/public (on-toolbar-click) (void))
(define/public (on-menu-command c) (void))
(def/public-unimplemented on-mdi-activate)
(define/public (on-close) #t)
(define/public (designate-root-frame)
(set! root-fake-frame this)
;; The first window shown is somehow sticky, so that it becomes
;; the main window if no windows are shown:
(tellv cocoa orderFront: #f)
(tellv cocoa orderOut: #f)
(sync-cocoa-events))
(def/public-unimplemented system-menu)
(define/public (set-modified on?)
(let ([b (tell cocoa standardWindowButton: #:type _NSInteger NSWindowCloseButton)])
(tellv b setDocumentEdited: #:type _BOOL on?)))
(define/public (is-maximized?)
(tell #:type _BOOL cocoa isZoomed))
(define/public (maximize on?)
(unless (eq? (tell #:type _BOOL cocoa isZoomed)
(and on? #t))
(tellv cocoa zoom: cocoa)))
(define/public (iconized?)
(tell #:type _BOOL cocoa isMiniaturized))
(define/public (iconize on?)
(if on?
(tellv cocoa miniaturize: cocoa)
(tellv cocoa deminiaturize: cocoa)))
(define unshown-fullscreen? #f)
(define/public (fullscreened?)
(and (version-10.7-or-later?)
(if (tell #:type _bool cocoa isVisible)
(positive? (bitwise-and (tell #:type _NSUInteger cocoa styleMask) NSFullScreenWindowMask))
unshown-fullscreen?)))
(define/public (fullscreen on?)
(when (version-10.7-or-later?)
(unless (eq? (and on? #t) (fullscreened?))
(if (tell #:type _bool cocoa isVisible)
(tellv cocoa toggleFullScreen: #f)
(set! unshown-fullscreen? (and on? #t))))))
(define/public (set-title s)
(tellv cocoa setTitle: #:type _NSString s))
(define color-callback void)
(define/public (set-color-callback cb)
(set! color-callback cb))
(define/override (on-color-change)
(queue-window-event this (lambda () (color-callback))))
(define/public (display-changed) (void))))
;; ----------------------------------------
(define (get-app-front-window)
(atomically
(with-autorelease
(let ([wins (tell (tell NSApplication sharedApplication) orderedWindows)])
(begin0
(for/or ([i (in-range (tell #:type _NSUInteger wins count))])
(let ([win (tell wins objectAtIndex: #:type _NSUInteger i)])
(and (tell #:type _BOOL win isVisible)
(tell #:type _BOOL win canBecomeMainWindow)
(not (tell win parentWindow))
(or (not root-fake-frame)
(not (ptr-equal? win (send root-fake-frame get-cocoa))))
win))))))))
(define (location->window x y)
(let ([n (tell #:type _NSInteger NSWindow
windowNumberAtPoint: #:type _NSPoint
(let ([f (tell #:type _NSRect (tell NSScreen mainScreen) frame)])
(make-NSPoint x (- (NSSize-height (NSRect-size f)) y)))
belowWindowWithWindowNumber: #:type _NSInteger 0)])
(atomically (let ([b (hash-ref all-windows n #f)])
(and b (weak-box-value b))))))
(set-fixup-window-locations!
(lambda ()
;; in atomic mode
(for ([b (in-hash-values all-windows)])
(let ([f (weak-box-value b)])
(when f
(send f fixup-locations-children))))))