improved (hopefully) handling of mouse events for Mac, repair for PR 5326

svn: r4944
This commit is contained in:
Matthew Flatt 2006-11-26 00:47:32 +00:00
parent 20ce8f7e61
commit 7d549762b1
7 changed files with 98 additions and 16 deletions

View File

@ -117,6 +117,7 @@ wxFrame *mred_real_main_frame;
static Scheme_Thread *user_main_thread;
extern void wxMediaIOCheckLSB(void);
extern void wxMouseEventHandled(void);
#include "mred.h"
@ -1681,6 +1682,9 @@ Scheme_Object *wxDispatchEventsUntilWaitable(wxDispatch_Check_Fun f, void *data,
Scheme_Object *result = scheme_void;
c = MrEdGetContext();
#ifdef wx_mac
wxMouseEventHandled();
#endif
if (c->ready_to_go
|| (c->handler_running != scheme_current_thread)) {

View File

@ -62,6 +62,7 @@ typedef struct EventFinderClosure {
} EventFinderClosure;
static int queue_size, max_queue_size;
static int mouse_down_in_flight;
Bool wx_ignore_key; /* used in wxItem */
@ -229,6 +230,11 @@ static void QueueTransferredEvent(EventRecord *e)
max_queue_size = queue_size;
}
if ((e->what == mouseDown)
|| (e->what == mouseMenuDown)) {
mouse_down_in_flight = 1;
}
q->rgn = NULL;
if (e->what == updateEvt) {
@ -421,6 +427,39 @@ int WNE(EventRecord *e, double sleep_secs)
{
int r;
if (mouse_down_in_flight) {
/* Try hard to handle a mouse-down event before calling
WaitNextEvent again. Otherwise, mouse events for tracking
(e.g., menu clicks, close-window clicks, window-drag clicks,
and button clicks) can get lost. We can't wait forever, though;
the target eventspace might be stuck for some reason. If MrEd
is idle enough to sleep, take that as a sign that it's ok to
get new events. Another sign is if there's a new mouse-down or
key-down event. Some other cases, such as a `yield' or waiting
on an AppleEvent, are handled by explicitly turning off
mouse_down_in_flight before we get here. */
EventRef eref;
EventTypeSpec poll_evts[2];
if (!sleep_secs) {
poll_evts[0].eventClass = kEventClassMouse;
poll_evts[0].eventKind = kEventMouseDown;
poll_evts[1].eventClass = kEventClassKeyboard;
poll_evts[1].eventKind = kEventRawKeyDown;
eref = AcquireFirstMatchingEventInQueue(GetCurrentEventQueue(),
2,
poll_evts,
kEventQueueOptionsNone);
if (eref) {
ReleaseEvent(eref);
} else {
/* Looks like we should wait... */
return 0;
}
}
}
wxResetCanvasBackgrounds();
if (!wne_handlersInstalled) {
@ -486,6 +525,8 @@ void WakeUpMrEd()
Application queue, sticks them in the MrEd queue, and returns 1,
unless it was called less than delay_time ago, in which case do
nothing and return 0. */
static unsigned long lastTime;
static int TransferQueue(int all)
{
@ -494,7 +535,6 @@ static int TransferQueue(int all)
int delay_time = 0;
/* Don't call WaitNextEvent() too often. */
static unsigned long lastTime;
if (TickCount() <= lastTime + delay_time)
return 0;
@ -607,6 +647,11 @@ void wxTracking()
cont_mouse_context_window = NULL;
}
void wxMouseEventHandled(void)
{
mouse_down_in_flight = 0;
}
#ifdef RECORD_HISTORY
FILE *history;
#endif
@ -948,7 +993,7 @@ int MrEdGetNextEvent(int check_only, int current_only,
if (check_only)
return TRUE;
MrDequeue(osq);
return TRUE;
@ -1937,6 +1982,7 @@ static void wait_for_reply(AppleEvent *ae, AppleEvent *reply)
AEGetAttributePtr(ae, keyReturnIDAttr, typeLongInteger, &rtype, &id, sizeof(long), &sz);
while (1) {
wxMouseEventHandled();
WNE(&e, 1.0);
if (e.what == kHighLevelEvent)
AEProcessAppleEvent(&e);

View File

@ -466,7 +466,7 @@ void wxMediaEdit::OnEvent(wxMouseEvent *event)
snip = NULL;
} else
snip = NULL;
sequenced = (PTRNE(snip, caretSnip));
sequenced = 0 && (PTRNE(snip, caretSnip));
if (sequenced)
BeginEditSequence();
SetCaretOwner(snip);

View File

@ -645,6 +645,7 @@ class wxMediaEdit : public wxMediaBuffer
void NeedRefresh(long start, long end = -1);
void NeedRefresh(double, double, double, double);
void RefreshByLineDemand(void);
void ContinueRefresh(void);
void RefreshBox(double x, double y, double w, double h);
void NeedCaretRefresh(void);

View File

@ -2394,8 +2394,8 @@ void wxMediaEdit::Redraw()
return;
if (admin->DelayRefresh()) {
/* Do we know the refresh box already? */
if (!delayedscroll && !delayedscrollbox && (refreshAll || refreshUnset)) {
/* Does the admin know the refresh box already? */
if ((delayedscroll != -1) && !delayedscrollbox && (refreshAll || refreshUnset)) {
/* Yes ... */
if (!refreshAll && refreshBoxUnset)
return; /* Nothing to do */
@ -2425,8 +2425,11 @@ void wxMediaEdit::Redraw()
dc = admin->GetDC(&x, &y);
if (!dc)
if (!dc) {
delayedscroll = -1;
delayedscrollbox = FALSE;
return;
}
origx = x;
origy = y;
@ -2691,10 +2694,7 @@ void wxMediaEdit::NeedRefresh(long start, long end)
drawCachedInBitmap = FALSE;
if (!delayRefresh && !printing && (!admin || !admin->DelayRefresh()))
Redraw();
else if (admin && !admin->standard)
admin->Resized(FALSE);
ContinueRefresh();
}
void wxMediaEdit::RefreshByLineDemand(void)
@ -2702,10 +2702,30 @@ void wxMediaEdit::RefreshByLineDemand(void)
if (!graphicMaybeInvalid)
graphicMaybeInvalid = TRUE;
ContinueRefresh();
}
void wxMediaEdit::ContinueRefresh(void)
{
if (!delayRefresh && !printing && (!admin || !admin->DelayRefresh()))
Redraw();
else if (admin && !admin->standard)
admin->Resized(FALSE);
else {
int rs = 1;
if (!delayRefresh && ((delayedscroll != -1)
|| delayedscrollbox)) {
if (!printing && admin) {
/* Although the administrator says to delay,
we can't just drop scroll requests. */
Redraw();
rs = 0;
} else {
delayedscroll = -1;
delayedscrollbox = NULL;
}
}
if (admin && !admin->standard)
admin->Resized(FALSE);
}
}
void wxMediaEdit::NeedCaretRefresh(void)

View File

@ -45,6 +45,7 @@ extern WindowPtr MrEdMouseWindow(Point where);
extern WindowPtr MrEdKeyWindow();
extern void wxCheckRootFrame(WindowPtr w);
extern void wxMouseEventHandled(void);
int wxTranslateRawKey(int key);
@ -329,6 +330,7 @@ void wxApp::doMacMouseDown(void)
#endif
if (modal) {
wxMouseEventHandled();
SysBeep(0);
return;
}
@ -336,6 +338,12 @@ void wxApp::doMacMouseDown(void)
}
}
if (windowPart != inContent) {
/* We've gotten far enough handling the mouse-down event that
mouse-up events are ok to receive again: */
wxMouseEventHandled();
}
switch (windowPart)
{
case inMenuBar:
@ -365,6 +373,7 @@ void wxApp::doMacMouseDown(void)
break;
case inContent:
doMacInContent(window);
wxMouseEventHandled();
break;
case inDrag:
doMacInDrag(window);
@ -1197,10 +1206,9 @@ void wxApp::doMacInContent(WindowPtr window)
{
wxFrame* theMacWxFrame;
theMacWxFrame = findMacWxFrame(window);
if (theMacWxFrame)
{
doMacContentClick(theMacWxFrame);
}
if (theMacWxFrame) {
doMacContentClick(theMacWxFrame);
}
}
//-----------------------------------------------------------------------------

View File

@ -18,6 +18,7 @@
#include "PSDC.h"
void wxCleanUp(void);
extern void wxMouseEventHandled(void);
///////////////////////////////////////////////////////////////////////////////
// The procedure CreateApp initializes the whole application.
@ -92,6 +93,8 @@ void wxCleanUp(void)
Bool wxYield(void)
{ // Yield to incoming messages
wxMouseEventHandled();
while (wxTheApp->Pending()) {
wxTheApp->Dispatch();
}