winemac: Add a delivery limit to events.

Some events are application-wide, not specific to a thread.  Such an event
needs to be broadcast to all GUI-attached threads because we don't know which
are handling events, but we don't want the event to be processed in each.
Often it should only be processed by the first to pull it from its queue.
This commit is contained in:
Ken Thomases 2013-04-03 18:56:41 -05:00 committed by Alexandre Julliard
parent 1ee93853c2
commit ca2d7140fb
3 changed files with 25 additions and 11 deletions

View File

@ -413,6 +413,13 @@ - (void) sendDisplaysChanged:(BOOL)activating
event->displays_changed.activating = activating; event->displays_changed.activating = activating;
[eventQueuesLock lock]; [eventQueuesLock lock];
// If we're activating, then we just need one of our threads to get the
// event, so it can send it directly to the desktop window. Otherwise,
// we need all of the threads to get it because we don't know which owns
// the desktop window and only that one will do anything with it.
if (activating) event->deliver = 1;
for (queue in eventQueues) for (queue in eventQueues)
[queue postEvent:event]; [queue postEvent:event];
[eventQueuesLock unlock]; [eventQueuesLock unlock];

View File

@ -198,7 +198,7 @@ - (MacDrvEvent*) getEventMatchingMask:(macdrv_event_mask)mask
char buf[512]; char buf[512];
int rc; int rc;
NSUInteger index; NSUInteger index;
MacDrvEvent* event; MacDrvEvent* ret = nil;
/* Clear the pipe which signals there are pending events. */ /* Clear the pipe which signals there are pending events. */
do do
@ -217,22 +217,27 @@ - (MacDrvEvent*) getEventMatchingMask:(macdrv_event_mask)mask
[eventsLock lock]; [eventsLock lock];
index = 0; index = 0;
for (event in events) while (index < [events count])
{ {
MacDrvEvent* event = [events objectAtIndex:index];
if (event_mask_for_type(event->event->type) & mask) if (event_mask_for_type(event->event->type) & mask)
break; {
[[event retain] autorelease];
[events removeObjectAtIndex:index];
index++; if (event->event->deliver == INT_MAX ||
} OSAtomicDecrement32Barrier(&event->event->deliver) >= 0)
{
if (event) ret = event;
{ break;
[event retain]; }
[events removeObjectAtIndex:index]; }
else
index++;
} }
[eventsLock unlock]; [eventsLock unlock];
return [event autorelease]; return ret;
} }
- (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)window - (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)window
@ -416,6 +421,7 @@ int macdrv_copy_event_from_queue(macdrv_event_queue queue,
event = calloc(1, sizeof(*event)); event = calloc(1, sizeof(*event));
event->refs = 1; event->refs = 1;
event->deliver = INT_MAX;
event->type = type; event->type = type;
event->window = (macdrv_window)[window retain]; event->window = (macdrv_window)[window retain];
return event; return event;

View File

@ -176,6 +176,7 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
typedef struct macdrv_event { typedef struct macdrv_event {
int refs; int refs;
int deliver;
int type; int type;
macdrv_window window; macdrv_window window;
union { union {