destroy windows via finalization outside of the event loop
This commit is contained in:
parent
9eabda614c
commit
af6cad4913
|
@ -775,6 +775,11 @@
|
||||||
(super-tell #:type _void dealloc)))]
|
(super-tell #:type _void dealloc)))]
|
||||||
[_ (error "oops")])
|
[_ (error "oops")])
|
||||||
'())]
|
'())]
|
||||||
|
[(async ...)
|
||||||
|
(if (eq? (syntax-e id) 'dealloc)
|
||||||
|
;; so that objects can be destroyed in foreign threads:
|
||||||
|
#'(#:async-apply apply-directly)
|
||||||
|
#'())]
|
||||||
[in-cls (if in-class?
|
[in-cls (if in-class?
|
||||||
#'(object-get-class cls)
|
#'(object-get-class cls)
|
||||||
#'cls)]
|
#'cls)]
|
||||||
|
@ -792,13 +797,16 @@
|
||||||
[super-tell do-super-tell])
|
[super-tell do-super-tell])
|
||||||
body0 body ...
|
body0 body ...
|
||||||
dealloc-body ...)))
|
dealloc-body ...)))
|
||||||
(_fun #:atomic? atomic? #:keep save-method! _id _id arg-type ... -> rt)
|
(_fun #:atomic? atomic? #:keep save-method! async ...
|
||||||
|
_id _id arg-type ... -> rt)
|
||||||
(generate-layout rt (list arg-id ...)))))))))]
|
(generate-layout rt (list arg-id ...)))))))))]
|
||||||
[else (raise-syntax-error #f
|
[else (raise-syntax-error #f
|
||||||
"bad method form"
|
"bad method form"
|
||||||
stx
|
stx
|
||||||
#'m)]))]))
|
#'m)]))]))
|
||||||
|
|
||||||
|
(define (apply-directly f) (f))
|
||||||
|
|
||||||
(define methods (make-hasheq))
|
(define methods (make-hasheq))
|
||||||
(define (save-method! m)
|
(define (save-method! m)
|
||||||
;; Methods are never GCed, since classes are never unregistered
|
;; Methods are never GCed, since classes are never unregistered
|
||||||
|
|
|
@ -31,10 +31,9 @@
|
||||||
(inherit get-cocoa)
|
(inherit get-cocoa)
|
||||||
|
|
||||||
(super-new [parent parent]
|
(super-new [parent parent]
|
||||||
[cocoa (let ([cocoa (values ; as-objc-allocation
|
[cocoa (let ([cocoa (as-objc-allocation
|
||||||
;; We're leaving guages for now. There's some problem
|
;; Beware that a guage may be finally deallocated in
|
||||||
;; releasing gauges through a finalizer. My guess is that
|
;; a seperate OS-level thread
|
||||||
;; it has something to do with animation in a separate thread.
|
|
||||||
(tell (tell MyProgressIndicator alloc) init))])
|
(tell (tell MyProgressIndicator alloc) init))])
|
||||||
(tellv cocoa setIndeterminate: #:type _BOOL #f)
|
(tellv cocoa setIndeterminate: #:type _BOOL #f)
|
||||||
(tellv cocoa setMaxValue: #:type _double* rng)
|
(tellv cocoa setMaxValue: #:type _double* rng)
|
||||||
|
|
|
@ -37,18 +37,12 @@
|
||||||
(define delete-me null)
|
(define delete-me null)
|
||||||
|
|
||||||
(define (objc-delete o)
|
(define (objc-delete o)
|
||||||
(atomically
|
(tellv o release))
|
||||||
(set! delete-me (cons o delete-me))))
|
|
||||||
|
|
||||||
(define (clean-up-deleted)
|
(define (clean-up-deleted)
|
||||||
;; called outside the event loop to actually delete objects
|
(free-remembered-now objc-delete))
|
||||||
;; that might otherwise be in use during a callback
|
|
||||||
(for ([o (in-list (begin0
|
|
||||||
delete-me
|
|
||||||
(set! delete-me null)))])
|
|
||||||
(tellv o release)))
|
|
||||||
|
|
||||||
(define objc-allocator (allocator objc-delete))
|
(define objc-allocator (allocator remember-to-free-later))
|
||||||
|
|
||||||
(define-syntax-rule (as-objc-allocation expr)
|
(define-syntax-rule (as-objc-allocation expr)
|
||||||
((objc-allocator (lambda () expr))))
|
((objc-allocator (lambda () expr))))
|
||||||
|
|
|
@ -1,8 +1,33 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
(require ffi/unsafe
|
(require ffi/unsafe
|
||||||
ffi/unsafe/define
|
ffi/unsafe/define
|
||||||
|
ffi/unsafe/atomic
|
||||||
"once.rkt")
|
"once.rkt")
|
||||||
|
|
||||||
(provide (protect-out define-mz))
|
(provide (protect-out define-mz
|
||||||
|
|
||||||
|
remember-to-free-later
|
||||||
|
free-remembered-now))
|
||||||
|
|
||||||
(define-ffi-definer define-mz #f)
|
(define-ffi-definer define-mz #f)
|
||||||
|
|
||||||
|
;; ----------------------------------------
|
||||||
|
|
||||||
|
(define to-free null)
|
||||||
|
|
||||||
|
;; Remember to free an object that might currently be in use during a
|
||||||
|
;; callback:
|
||||||
|
(define (remember-to-free-later o)
|
||||||
|
(start-atomic)
|
||||||
|
(set! to-free (cons o to-free))
|
||||||
|
(end-atomic))
|
||||||
|
|
||||||
|
;; Called outside the event loop to actually free objects that might
|
||||||
|
;; otherwise be in use during a callback:
|
||||||
|
(define (free-remembered-now free)
|
||||||
|
(start-atomic)
|
||||||
|
(for ([o (in-list (begin0
|
||||||
|
to-free
|
||||||
|
(set! to-free null)))])
|
||||||
|
(free o))
|
||||||
|
(end-atomic))
|
||||||
|
|
|
@ -183,6 +183,7 @@
|
||||||
|
|
||||||
(define (dispatch-all-ready)
|
(define (dispatch-all-ready)
|
||||||
(pre-event-sync #f)
|
(pre-event-sync #f)
|
||||||
|
(clean-up-destroyed)
|
||||||
(when (gtk_events_pending)
|
(when (gtk_events_pending)
|
||||||
(gtk_main_iteration_do #f)
|
(gtk_main_iteration_do #f)
|
||||||
(dispatch-all-ready)))
|
(dispatch-all-ready)))
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
as-gtk-allocation
|
as-gtk-allocation
|
||||||
as-gtk-window-allocation
|
as-gtk-window-allocation
|
||||||
|
clean-up-destroyed
|
||||||
|
|
||||||
g_free
|
g_free
|
||||||
_gpath/free
|
_gpath/free
|
||||||
|
@ -113,7 +114,10 @@
|
||||||
(define gtk-destroy ((deallocator) (lambda (v)
|
(define gtk-destroy ((deallocator) (lambda (v)
|
||||||
(gtk_widget_destroy v)
|
(gtk_widget_destroy v)
|
||||||
(g_object_unref v))))
|
(g_object_unref v))))
|
||||||
(define gtk-allocator (allocator gtk-destroy))
|
|
||||||
|
(define gtk-allocator (allocator remember-to-free-later))
|
||||||
|
(define (clean-up-destroyed)
|
||||||
|
(free-remembered-now gtk-destroy))
|
||||||
|
|
||||||
(define-syntax-rule (as-gtk-allocation expr)
|
(define-syntax-rule (as-gtk-allocation expr)
|
||||||
((gtk-allocator (lambda () (let ([v expr])
|
((gtk-allocator (lambda () (let ([v expr])
|
||||||
|
|
|
@ -127,6 +127,7 @@
|
||||||
(define (dispatch-all-ready)
|
(define (dispatch-all-ready)
|
||||||
;; in atomic mode
|
;; in atomic mode
|
||||||
(pre-event-sync #f)
|
(pre-event-sync #f)
|
||||||
|
(clean-up-destroyed)
|
||||||
|
|
||||||
;; Windows uses messages above #x4000 to hilite items in the task bar,
|
;; Windows uses messages above #x4000 to hilite items in the task bar,
|
||||||
;; etc. In any case, these messages won't be handled by us, so they
|
;; etc. In any case, these messages won't be handled by us, so they
|
||||||
|
|
|
@ -18,9 +18,12 @@
|
||||||
failed
|
failed
|
||||||
|
|
||||||
GetLastError
|
GetLastError
|
||||||
|
|
||||||
DestroyWindow
|
DestroyWindow
|
||||||
NotifyWindowDestroy
|
NotifyWindowDestroy
|
||||||
CreateWindowExW
|
CreateWindowExW
|
||||||
|
clean-up-destroyed
|
||||||
|
|
||||||
GetWindowLongW
|
GetWindowLongW
|
||||||
SetWindowLongW
|
SetWindowLongW
|
||||||
SendMessageW SendMessageW/str
|
SendMessageW SendMessageW/str
|
||||||
|
@ -73,6 +76,9 @@
|
||||||
#:wrap (deallocator))
|
#:wrap (deallocator))
|
||||||
(define NotifyWindowDestroy ((deallocator) void))
|
(define NotifyWindowDestroy ((deallocator) void))
|
||||||
|
|
||||||
|
(define (clean-up-destroyed)
|
||||||
|
(free-remembered-now DestroyWindow))
|
||||||
|
|
||||||
(define-user32 CreateWindowExW (_wfun _DWORD
|
(define-user32 CreateWindowExW (_wfun _DWORD
|
||||||
_string/utf-16
|
_string/utf-16
|
||||||
_string/utf-16
|
_string/utf-16
|
||||||
|
@ -80,7 +86,7 @@
|
||||||
_int _int _int _int
|
_int _int _int _int
|
||||||
_HWND _HMENU _HINSTANCE _pointer
|
_HWND _HMENU _HINSTANCE _pointer
|
||||||
-> _HWND)
|
-> _HWND)
|
||||||
#:wrap (allocator DestroyWindow))
|
#:wrap (allocator remember-to-free-later))
|
||||||
|
|
||||||
(define-user32 GetWindowLongW (_wfun _HWND _int -> _pointer))
|
(define-user32 GetWindowLongW (_wfun _HWND _int -> _pointer))
|
||||||
(define-user32 SetWindowLongW (_wfun _HWND _int _pointer -> _pointer))
|
(define-user32 SetWindowLongW (_wfun _HWND _int _pointer -> _pointer))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user