From f1e13a7921d7a8890376773f2705feb02bb165e8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 10 Jan 2011 07:53:03 -0700 Subject: [PATCH] modial dialog don't disable mouse motion, enter, and leave events Closes PR 11599 This is an API change relative to gr1, but it seems sensible, and it makes enter and leave events more reliable and easier to implement. --- collects/mred/private/wx/cocoa/window.rkt | 2 +- collects/mred/private/wx/common/queue.rkt | 29 ++++++++++++++------- collects/mred/private/wx/gtk/window.rkt | 2 +- collects/mred/private/wx/win32/window.rkt | 2 +- collects/scribblings/gui/dialog-class.scrbl | 7 ++--- collects/scribblings/gui/win-overview.scrbl | 8 +++--- 6 files changed, 28 insertions(+), 22 deletions(-) diff --git a/collects/mred/private/wx/cocoa/window.rkt b/collects/mred/private/wx/cocoa/window.rkt index 9ac7418efa..55d2031dad 100644 --- a/collects/mred/private/wx/cocoa/window.rkt +++ b/collects/mred/private/wx/cocoa/window.rkt @@ -675,7 +675,7 @@ (dispatch-on-event e #f)) (define/public (dispatch-on-event e just-pre?) (cond - [(other-modal? this) #t] + [(other-modal? this e) #t] [(call-pre-on-event this e) #t] [just-pre? block-all-mouse-events?] [else (when enabled? (on-event e)) #t])) diff --git a/collects/mred/private/wx/common/queue.rkt b/collects/mred/private/wx/common/queue.rkt index dd3372a25d..ecd847a5f3 100644 --- a/collects/mred/private/wx/common/queue.rkt +++ b/collects/mred/private/wx/common/queue.rkt @@ -462,17 +462,26 @@ (hash-map (eventspace-frames-hash e) (lambda (k v) k))) -(define (other-modal? win) +(define (other-modal? win [e #f]) ;; called in atomic mode in eventspace's thread - (let ([es (send win get-eventspace)]) - (or (positive? (eventspace-external-modal es)) - (let loop ([frames (get-top-level-windows es)]) - (and (pair? frames) - (let ([status (send (car frames) frame-relative-dialog-status win)]) - (case status - [(#f) (loop (cdr frames))] - [(same) #f] - [(other) #t]))))))) + (and + ;; deliver mouse-motion events even if a modal window + ;; is open + (or (not e) + (not (or (send e leaving?) + (send e entering?) + (send e moving?)))) + ;; for any other kind of mouse or key event, deliver only + ;; if no model dialog is open + (let ([es (send win get-eventspace)]) + (or (positive? (eventspace-external-modal es)) + (let loop ([frames (get-top-level-windows es)]) + (and (pair? frames) + (let ([status (send (car frames) frame-relative-dialog-status win)]) + (case status + [(#f) (loop (cdr frames))] + [(same) #f] + [(other) #t])))))))) (define (eventspace-adjust-external-modal! es amt) (atomically diff --git a/collects/mred/private/wx/gtk/window.rkt b/collects/mred/private/wx/gtk/window.rkt index ac71b3aa2f..8de24f6020 100644 --- a/collects/mred/private/wx/gtk/window.rkt +++ b/collects/mred/private/wx/gtk/window.rkt @@ -581,7 +581,7 @@ (define/public (dispatch-on-event e just-pre?) (pre-event-refresh) (cond - [(other-modal? this) #t] + [(other-modal? this e) #t] [(call-pre-on-event this e) #t] [just-pre? #f] [else (when enabled? (on-event e)) #t])) diff --git a/collects/mred/private/wx/win32/window.rkt b/collects/mred/private/wx/win32/window.rkt index f5eade66f1..3fcfd2ffa2 100644 --- a/collects/mred/private/wx/win32/window.rkt +++ b/collects/mred/private/wx/win32/window.rkt @@ -637,7 +637,7 @@ (dispatch-on-event e #f)) (define/public (dispatch-on-event e just-pre?) (cond - [(other-modal? this) #t] + [(other-modal? this e) #t] [(call-pre-on-event this e) #t] [just-pre? #f] [else (when (is-enabled-to-root?) (on-event e)) #t])) diff --git a/collects/scribblings/gui/dialog-class.scrbl b/collects/scribblings/gui/dialog-class.scrbl index 983ffd2912..c846e83dd4 100644 --- a/collects/scribblings/gui/dialog-class.scrbl +++ b/collects/scribblings/gui/dialog-class.scrbl @@ -4,11 +4,8 @@ @defclass/title[dialog% object% (top-level-window<%>)]{ A dialog is a top-level window that is @defterm{modal}: while the - dialog is shown, all other top-level windows in the dialog's - eventspace are disabled. - - - + dialog is shown, key and mouse press/release events are disabled for + all other top-level windows in the dialog's eventspace. @defconstructor[([label label-string?] [parent (or/c (is-a?/c frame%) (is-a?/c dialog%) false/c) #f] diff --git a/collects/scribblings/gui/win-overview.scrbl b/collects/scribblings/gui/win-overview.scrbl index 45ad0a0aa7..13208dd048 100644 --- a/collects/scribblings/gui/win-overview.scrbl +++ b/collects/scribblings/gui/win-overview.scrbl @@ -809,11 +809,11 @@ An @deftech{eventspace} is a context for processing GUI handle events while the dialog is shown. (See also @secref["espacethreads"] for information about threads and modal dialogs.) Furthermore, when a modal dialog is shown, the system - disables all other top-level windows in the dialog's eventspace, but + disables key and mouse press/release events to other top-level + windows in the dialog's eventspace, but windows in other eventspaces are unaffected by the modal dialog. - (Disabling a window prevents mouse and keyboard events from reaching - the window, but other kinds of events, such as update events, are - still delivered.) + (Mouse motion, enter, and leave events are still delivered to + all windows when a modal dialog is shown.) @subsection{Event Types and Priorities}