enforce modality; more on-subwindow- callbacks; Cocoa font tweaks

original commit: e9e180847a72ba91ea817fc3b5fc1a457e676747
This commit is contained in:
Matthew Flatt 2010-08-04 19:39:43 -06:00
parent 26dd281012
commit 992d32134c
17 changed files with 146 additions and 39 deletions

View File

@ -24,7 +24,7 @@
(define MIN-BUTTON-WIDTH 72) (define MIN-BUTTON-WIDTH 72)
(define-objc-class MyButton NSButton (define-objc-class MyButton NSButton
#:mixins (FocusResponder) #:mixins (FocusResponder KeyMouseResponder)
[wx] [wx]
(-a _void (clicked: [_id sender]) (-a _void (clicked: [_id sender])
(queue-window-event wx (lambda () (send wx clicked))))) (queue-window-event wx (lambda () (send wx clicked)))))

View File

@ -19,7 +19,7 @@
(import-class NSPopUpButton) (import-class NSPopUpButton)
(define-objc-class MyPopUpButton NSPopUpButton (define-objc-class MyPopUpButton NSPopUpButton
#:mixins (FocusResponder) #:mixins (FocusResponder KeyMouseResponder)
[wx] [wx]
(-a _void (clicked: [_id sender]) (-a _void (clicked: [_id sender])
(queue-window-event wx (lambda () (send wx clicked))))) (queue-window-event wx (lambda () (send wx clicked)))))

View File

@ -27,16 +27,20 @@
(define empty-mb (new menu-bar%)) (define empty-mb (new menu-bar%))
(define root-fake-frame #f) (define root-fake-frame #f)
(define dialog-level-counter 0)
(define-objc-mixin (MyWindowMethods Superclass) (define-objc-mixin (MyWindowMethods Superclass)
[wx] [wx]
[-a _scheme (getEventspace) [-a _scheme (getEventspace)
(send wx get-eventspace)] (send wx get-eventspace)]
[-a _BOOL (canBecomeKeyWindow) #t] [-a _BOOL (canBecomeKeyWindow)
(not (other-modal? wx))]
[-a _BOOL (canBecomeMainWindow) #t] [-a _BOOL (canBecomeMainWindow) #t]
[-a _BOOL (windowShouldClose: [_id win]) [-a _BOOL (windowShouldClose: [_id win])
(queue-window-event wx (lambda () (queue-window-event wx (lambda ()
(when (send wx on-close) (unless (other-modal? wx)
(send wx direct-show #f)))) (when (send wx on-close)
(send wx direct-show #f)))))
#f] #f]
[-a _void (windowDidResize: [_id notification]) [-a _void (windowDidResize: [_id notification])
(when wx (when wx
@ -149,7 +153,21 @@
(tell NSGraphicsContext graphicsContextWithWindow: cocoa))) (tell NSGraphicsContext graphicsContextWithWindow: cocoa)))
(define is-a-dialog? is-dialog?) (define is-a-dialog? is-dialog?)
(define dialog-level 0)
(define/public (frame-is-dialog?) is-a-dialog?) (define/public (frame-is-dialog?) is-a-dialog?)
(define/public (frame-relative-dialog-status win)
;; called in event-pump thread
(cond
[is-a-dialog? (let ([dl (send win get-dialog-level)])
(cond
[(= dl dialog-level) 'same]
[(dl . > . dialog-level) #f]
[else 'other]))]
[else #f]))
(define/override (get-dialog-level)
;; called in event-pump thread
dialog-level)
(define/public (clean-up) (define/public (clean-up)
;; When a window is resized, then any drawing that is in flight ;; When a window is resized, then any drawing that is in flight
@ -171,25 +189,32 @@
(set! front #f) (set! front #f)
(send empty-mb install)) (send empty-mb install))
(if on? (if on?
(if (and is-a-dialog?
(let ([p (get-parent)])
(and p
(not (send p get-sheet)))))
(let ([p (get-parent)])
(send p set-sheet this)
(tell (tell NSApplication sharedApplication)
beginSheet: cocoa
modalForWindow: (send p get-cocoa)
modalDelegate: #f
didEndSelector: #:type _SEL #f
contextInfo: #f))
(tellv cocoa makeKeyAndOrderFront: #f))
(begin (begin
(when is-a-dialog? (when is-a-dialog?
(set! dialog-level-counter (add1 dialog-level-counter))
(set! dialog-level dialog-level-counter))
(if (and is-a-dialog?
(let ([p (get-parent)])
(and p
(not (send p get-sheet)))))
(let ([p (get-parent)])
(send p set-sheet this)
(tell (tell NSApplication sharedApplication)
beginSheet: cocoa
modalForWindow: (send p get-cocoa)
modalDelegate: #f
didEndSelector: #:type _SEL #f
contextInfo: #f))
(tellv cocoa makeKeyAndOrderFront: #f)))
(begin
(when is-a-dialog?
(set! dialog-level 0)
(let ([p (get-parent)]) (let ([p (get-parent)])
(when (and p (when (and p
(eq? this (send p get-sheet))) (eq? this (send p get-sheet)))
(send p set-sheet #f)))) (send p set-sheet #f)
(tell (tell NSApplication sharedApplication)
endSheet: cocoa))))
(tellv cocoa orderOut: #f) (tellv cocoa orderOut: #f)
(let ([next (let ([next
(let* ([pool (tell (tell NSAutoreleasePool alloc) init)] (let* ([pool (tell (tell NSAutoreleasePool alloc) init)]
@ -316,7 +341,7 @@
(define/public (set-modified on?) (define/public (set-modified on?)
;; Use standardWindowButton: ... ;; Use standardWindowButton: ...
(void)) (void))
(define/public (create-status-line) (void)) (define/public (create-status-line) (void))
(define/public (set-status-text s) (void)) (define/public (set-status-text s) (void))
(def/public-unimplemented status-line-exists?) (def/public-unimplemented status-line-exists?)

View File

@ -14,6 +14,10 @@
(import-class NSBox) (import-class NSBox)
(define-objc-class MyBox NSBox
#:mixins (FocusResponder KeyMouseResponder)
[wx])
(defclass group-panel% (panel-mixin window%) (defclass group-panel% (panel-mixin window%)
(init parent (init parent
x y w h x y w h
@ -24,7 +28,7 @@
(super-new [parent parent] (super-new [parent parent]
[cocoa [cocoa
(let ([cocoa (as-objc-allocation (let ([cocoa (as-objc-allocation
(tell (tell NSBox alloc) init))]) (tell (tell MyBox alloc) init))])
(when label (when label
(tellv cocoa setTitle: #:type _NSString label) (tellv cocoa setTitle: #:type _NSString label)
(tellv cocoa sizeToFit)) (tellv cocoa sizeToFit))

View File

@ -22,6 +22,7 @@
(import-protocol NSTableViewDataSource) (import-protocol NSTableViewDataSource)
(define-objc-class MyTableView NSTableView (define-objc-class MyTableView NSTableView
#:mixins (FocusResponder KeyMouseResponder)
[wx] [wx]
[-a _id (preparedCellAtColumn: [_NSInteger column] row: [_NSInteger row]) [-a _id (preparedCellAtColumn: [_NSInteger column] row: [_NSInteger row])
(tell (tell NSCell alloc) initTextCell: #:type _NSString (send wx get-row row))] (tell (tell NSCell alloc) initTextCell: #:type _NSString (send wx get-row row))]

View File

@ -4,10 +4,11 @@
ffi/objc ffi/objc
racket/draw/bitmap racket/draw/bitmap
"../../syntax.rkt" "../../syntax.rkt"
"item.rkt" "window.rkt"
"utils.rkt" "item.rkt"
"types.rkt" "utils.rkt"
"image.rkt") "types.rkt"
"image.rkt")
(unsafe!) (unsafe!)
(objc-unsafe!) (objc-unsafe!)
@ -30,6 +31,14 @@
#:type _NSString #:type _NSString
"NSApplicationPath"))) "NSApplicationPath")))
(define-objc-class MyTextField NSTextField
#:mixins (FocusResponder KeyMouseResponder)
[wx])
(define-objc-class MyImageView NSImageView
#:mixins (FocusResponder KeyMouseResponder)
[wx])
(defclass message% item% (defclass message% item%
(init parent label (init parent label
x y x y
@ -59,9 +68,9 @@
[cocoa [cocoa
(if (string? label) (if (string? label)
(as-objc-allocation (as-objc-allocation
(tell (tell NSTextField alloc) init)) (tell (tell MyTextField alloc) init))
(as-objc-allocation (as-objc-allocation
(tell (tell NSImageView alloc) init)))]) (tell (tell MyImageView alloc) init)))])
(cond (cond
[(string? label) [(string? label)
(init-font cocoa font) (init-font cocoa font)

View File

@ -24,7 +24,7 @@
(define NSListModeMatrix 2) (define NSListModeMatrix 2)
(define-objc-class MyMatrix NSMatrix (define-objc-class MyMatrix NSMatrix
#:mixins (FocusResponder) #:mixins (FocusResponder KeyMouseResponder)
[wx] [wx]
(-a _void (clicked: [_id sender]) (-a _void (clicked: [_id sender])
(queue-window-event wx (lambda () (send wx clicked))))) (queue-window-event wx (lambda () (send wx clicked)))))

View File

@ -22,7 +22,7 @@
(import-class NSSlider) (import-class NSSlider)
(define-objc-class MySlider NSSlider (define-objc-class MySlider NSSlider
#:mixins (FocusResponder) #:mixins (FocusResponder KeyMouseResponder)
[wx] [wx]
(-a _void (changed: [_id sender]) (-a _void (changed: [_id sender])
(queue-window-event wx (lambda () (send wx changed))) (queue-window-event wx (lambda () (send wx changed)))

View File

@ -18,6 +18,7 @@
(import-protocol NSTabViewDelegate) (import-protocol NSTabViewDelegate)
(define-objc-class MyTabView NSTabView (define-objc-class MyTabView NSTabView
#:mixins (FocusResponder KeyMouseResponder)
#:protocols (NSTabViewDelegate) #:protocols (NSTabViewDelegate)
[wx] [wx]
(-a _void (tabView: [_id cocoa] didSelectTabViewItem: [_id item-cocoa]) (-a _void (tabView: [_id cocoa] didSelectTabViewItem: [_id item-cocoa])

View File

@ -8,6 +8,7 @@
"types.rkt" "types.rkt"
"keycode.rkt" "keycode.rkt"
"../common/event.rkt" "../common/event.rkt"
"../common/queue.rkt"
"../../syntax.rkt" "../../syntax.rkt"
"../common/freeze.rkt") "../common/freeze.rkt")
(unsafe!) (unsafe!)
@ -180,6 +181,10 @@
(define/public (get-cocoa-window) (send parent get-cocoa-window)) (define/public (get-cocoa-window) (send parent get-cocoa-window))
(define/public (get-wx-window) (send parent get-wx-window)) (define/public (get-wx-window) (send parent get-wx-window))
(define/public (get-dialog-level)
;; called in event-pump thread
(send parent get-dialog-level))
(define/public (make-graphics-context) (define/public (make-graphics-context)
(and parent (and parent
(send parent make-graphics-context))) (send parent make-graphics-context)))
@ -294,11 +299,13 @@
(define/public (dispatch-on-char e just-pre?) (define/public (dispatch-on-char e just-pre?)
(cond (cond
[(other-modal? this) #t]
[(call-pre-on-char this e) #t] [(call-pre-on-char this e) #t]
[just-pre? #f] [just-pre? #f]
[else (when enabled? (on-char e)) #t])) [else (when enabled? (on-char e)) #t]))
(define/public (dispatch-on-event e just-pre?) (define/public (dispatch-on-event e just-pre?)
(cond (cond
[(other-modal? this) #t]
[(call-pre-on-event this e) #t] [(call-pre-on-event this e) #t]
[just-pre? #f] [just-pre? #f]
[else (when enabled? (on-event e)) #t])) [else (when enabled? (on-event e)) #t]))

View File

@ -2,6 +2,7 @@
(require ffi/unsafe (require ffi/unsafe
racket/draw/utils racket/draw/utils
ffi/unsafe/atomic ffi/unsafe/atomic
racket/class
"rbtree.rkt" "rbtree.rkt"
"../../lock.rkt" "../../lock.rkt"
"handlers.rkt") "handlers.rkt")
@ -35,6 +36,7 @@
register-frame-shown register-frame-shown
get-top-level-windows get-top-level-windows
other-modal?
queue-quit-event) queue-quit-event)
@ -329,9 +331,20 @@
'frame-remove))) 'frame-remove)))
(define (get-top-level-windows) (define (get-top-level-windows)
;; called in event-pump thread
(hash-map (eventspace-frames-hash (current-eventspace)) (hash-map (eventspace-frames-hash (current-eventspace))
(lambda (k v) k))) (lambda (k v) k)))
(define (other-modal? win)
;; called in event-pump thread
(let loop ([frames (get-top-level-windows)])
(and (pair? frames)
(let ([status (send (car frames) frame-relative-dialog-status win)])
(case status
[(#f) (loop (cdr frames))]
[(same) #f]
[(other) #t])))))
(define (queue-quit-event) (define (queue-quit-event)
;; called in event-pump thread ;; called in event-pump thread
(queue-event main-eventspace (application-quit-handler) 'med)) (queue-event main-eventspace (application-quit-handler) 'med))

View File

@ -62,6 +62,8 @@
[callback cb] [callback cb]
[no-show? (memq 'deleted style)]) [no-show? (memq 'deleted style)])
(connect-key-and-mouse button-gtk)
(gtk_combo_box_set_active gtk 0) (gtk_combo_box_set_active gtk 0)
(set-auto-size) (set-auto-size)

View File

@ -18,6 +18,8 @@
(define-gtk gtk_window_set_transient_for (_fun _GtkWidget _GtkWidget -> _void)) (define-gtk gtk_window_set_transient_for (_fun _GtkWidget _GtkWidget -> _void))
(define-gtk gtk_window_set_type_hint (_fun _GtkWidget _int -> _void)) (define-gtk gtk_window_set_type_hint (_fun _GtkWidget _int -> _void))
(define dialog-level-counter 0)
(defclass dialog% frame% (defclass dialog% frame%
(inherit get-gtk (inherit get-gtk
get-parent) get-parent)
@ -32,7 +34,22 @@
(when p (when p
(gtk_window_set_transient_for (get-gtk) (send p get-gtk)))) (gtk_window_set_transient_for (get-gtk) (send p get-gtk))))
(define dialog-level 0)
(define/override (get-dialog-level) dialog-level)
(define/override (frame-relative-dialog-status win)
(let ([dl (send win get-dialog-level)])
(cond
[(= dl dialog-level) 'same]
[(dl . > . dialog-level) #f]
[else 'other])))
(define/override (direct-show on?) (define/override (direct-show on?)
(when on?
(set! dialog-level-counter (add1 dialog-level-counter))
(set! dialog-level dialog-level-counter))
(unless on?
(set! dialog-level 0))
(unless on? (unless on?
(when close-sema (when close-sema
(semaphore-post close-sema) (semaphore-post close-sema)

View File

@ -52,14 +52,14 @@
(define-gtk gtk_window_set_geometry_hints (_fun _GtkWindow _GtkWidget _GdkGeometry-pointer _int -> _void)) (define-gtk gtk_window_set_geometry_hints (_fun _GtkWindow _GtkWidget _GdkGeometry-pointer _int -> _void))
(define (handle-delete gtk) (define-signal-handler connect-delete "delete-event"
(let ([wx (gtk->wx gtk)]) (_fun _GtkWidget -> _gboolean)
(queue-window-event wx (lambda () (lambda (gtk)
(when (send wx on-close) (let ([wx (gtk->wx gtk)])
(send wx direct-show #f)))))) (queue-window-event wx (lambda ()
(define handle_delete (unless (other-modal? wx)
(function-ptr handle-delete (when (send wx on-close)
(_fun #:atomic? #t _GtkWidget -> _gboolean))) (send wx direct-show #f))))))))
(define-signal-handler connect-configure "configure-event" (define-signal-handler connect-configure "configure-event"
(_fun _GtkWidget _GdkEventConfigure-pointer -> _gboolean) (_fun _GtkWidget _GdkEventConfigure-pointer -> _gboolean)
@ -121,7 +121,7 @@
(set-size x y w h) (set-size x y w h)
(g_signal_connect gtk "delete_event" handle_delete) (connect-delete gtk)
(connect-configure gtk) (connect-configure gtk)
(when label (when label
@ -159,6 +159,9 @@
(define dc-lock (and (eq? 'windows (system-type)) (make-semaphore 1))) (define dc-lock (and (eq? 'windows (system-type)) (make-semaphore 1)))
(define/public (get-dc-lock) dc-lock) (define/public (get-dc-lock) dc-lock)
(define/override (get-dialog-level) 0)
(define/public (frame-relative-dialog-status win) #f)
(define/override (center dir wrt) (define/override (center dir wrt)
(let ([w-box (box 0)] (let ([w-box (box 0)]
[h-box (box 0)] [h-box (box 0)]

View File

@ -3,6 +3,7 @@
scheme/foreign scheme/foreign
"../../syntax.rkt" "../../syntax.rkt"
"../common/freeze.rkt" "../common/freeze.rkt"
"../common/queue.rkt"
"widget.rkt" "widget.rkt"
"utils.rkt" "utils.rkt"
"types.rkt") "types.rkt")
@ -49,7 +50,17 @@
(define/public (get-top-window) (send parent get-top-window)) (define/public (get-top-window) (send parent get-top-window))
(super-new))) (super-new)))
(define-signal-handler connect-menu-key-press "key-press-event"
(_fun _GtkWidget _GdkEventKey-pointer -> _gboolean)
(lambda (gtk event)
(let ([wx (gtk->wx gtk)])
(other-modal? wx))))
(define-signal-handler connect-menu-button-press "button-press-event"
(_fun _GtkWidget _GdkEventButton-pointer -> _gboolean)
(lambda (gtk event)
(let ([wx (gtk->wx gtk)])
(other-modal? wx))))
(defclass menu-bar% widget% (defclass menu-bar% widget%
(define menus null) (define menus null)
@ -59,12 +70,18 @@
(define/public (get-gtk) gtk) (define/public (get-gtk) gtk)
(connect-menu-key-press gtk)
(connect-menu-button-press gtk)
(define top-wx #f) (define top-wx #f)
(define/public (set-top-window top) (define/public (set-top-window top)
(set! top-wx top)) (set! top-wx top))
(define/public (get-top-window) (define/public (get-top-window)
top-wx) top-wx)
(define/public (get-dialog-level)
(send top-wx get-dialog-level))
(define/public (set-label-top pos str) (define/public (set-label-top pos str)
(let ([l (list-ref menus pos)]) (let ([l (list-ref menus pos)])
(let ([item-gtk (car l)]) (let ([item-gtk (car l)])

View File

@ -86,6 +86,8 @@
[extra-gtks (list client-gtk)] [extra-gtks (list client-gtk)]
[no-show? (memq 'deleted style)]) [no-show? (memq 'deleted style)])
(connect-key-and-mouse gtk)
(set-auto-size) (set-auto-size)
(define callback void) (define callback void)

View File

@ -5,6 +5,7 @@
"../../syntax.rkt" "../../syntax.rkt"
"../common/event.rkt" "../common/event.rkt"
"../common/freeze.rkt" "../common/freeze.rkt"
"../common/queue.rkt"
"keycode.rkt" "keycode.rkt"
"queue.rkt" "queue.rkt"
"utils.rkt" "utils.rkt"
@ -107,7 +108,8 @@
(_fun _GtkWidget _GdkEventButton-pointer -> _gboolean) (_fun _GtkWidget _GdkEventButton-pointer -> _gboolean)
(lambda (gtk event) (lambda (gtk event)
(unless (gtk_widget_is_focus gtk) (unless (gtk_widget_is_focus gtk)
(gtk_widget_grab_focus gtk)) (unless (other-modal? (gtk->wx gtk))
(gtk_widget_grab_focus gtk)))
(do-button-event gtk event #f #f))) (do-button-event gtk event #f #f)))
(define-signal-handler connect-button-release "button-release-event" (define-signal-handler connect-button-release "button-release-event"
@ -335,6 +337,8 @@
(define/public (get-top-win) (send parent get-top-win)) (define/public (get-top-win) (send parent get-top-win))
(define/public (get-dialog-level) (send parent get-dialog-level))
(define/public (get-size xb yb) (define/public (get-size xb yb)
(set-box! xb save-w) (set-box! xb save-w)
(set-box! yb save-h)) (set-box! yb save-h))
@ -365,11 +369,13 @@
(define/public (handles-events?) #f) (define/public (handles-events?) #f)
(define/public (dispatch-on-char e just-pre?) (define/public (dispatch-on-char e just-pre?)
(cond (cond
[(other-modal? this) #t]
[(call-pre-on-char this e) #t] [(call-pre-on-char this e) #t]
[just-pre? #f] [just-pre? #f]
[else (when enabled? (on-char e)) #t])) [else (when enabled? (on-char e)) #t]))
(define/public (dispatch-on-event e just-pre?) (define/public (dispatch-on-event e just-pre?)
(cond (cond
[(other-modal? this) #t]
[(call-pre-on-event this e) #t] [(call-pre-on-event this e) #t]
[just-pre? #f] [just-pre? #f]
[else (when enabled? (on-event e)) #t])) [else (when enabled? (on-event e)) #t]))